From 0f14d7dcc681e731fc912e0464e38b5007ddf62e Mon Sep 17 00:00:00 2001 From: Alex Klarfeld Date: Thu, 28 Sep 2023 16:13:20 -0700 Subject: [PATCH 1/2] Remove fetch as a dependency as use https instead --- package.json | 2 -- src/api.ts | 34 ++++++++++++------------------ src/utils.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++-- yarn.lock | 19 +---------------- 4 files changed, 71 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 7352c3b..baa0850 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "devDependencies": { "@jest/globals": "^29.4.1", "@types/json-server": "^0.14.4", - "@types/node-fetch": "^2.6.2", "@types/signal-exit": "^3.0.1", "@types/superagent": "^4.1.16", "@types/uuid": "^9.0.1", @@ -44,7 +43,6 @@ "got": "^12.5.3", "jest": "^29.2.1", "json-server": "^0.17.0", - "node-fetch": "2", "openai": "^4.10.0", "postgres": "^3.3.4", "prettier": "^2.8.1", diff --git a/src/api.ts b/src/api.ts index 0776728..91d7910 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,5 +1,5 @@ import { HeaderOptionType, EventRequestType, ErrorPayloadType } from './types'; -import { errors } from './constants'; +import { post } from './utils'; const postError = async ( errorSinkUrl: string, @@ -7,13 +7,12 @@ const postError = async ( options: HeaderOptionType ) => { try { - const response = await fetch(errorSinkUrl, { - method: 'POST', - body: JSON.stringify(errorPayload), - headers: options.headers - }); - const data = await response.json(); - return data; + const response = await post( + errorSinkUrl, + errorPayload, + options.headers.Authorization + ); + return response; } catch (e) { console.warn(`Failed to report error to ${errorSinkUrl}`); return null; @@ -25,20 +24,13 @@ const postEvents = async ( data: Array, options: HeaderOptionType ) => { - const response = await fetch(eventSinkUrl, { - method: 'POST', - body: JSON.stringify(data), - headers: options.headers - }); - const responseData = await response.json(); + const response = await post( + eventSinkUrl, + data, + options.headers.Authorization + ); - if (response.status === 401) { - throw new Error(errors.UNAUTHORIZED); - } - if (!response.ok) { - throw new Error(errors.POSTING_EVENTS); - } - return responseData; + return response; }; export { postError, postEvents }; diff --git a/src/utils.ts b/src/utils.ts index fb99079..abd8949 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,11 +4,14 @@ import { RequestType, ResponseType, EventRequestType, - ConfigType + ConfigType, + ErrorPayloadType } from './types'; import crypto from 'crypto'; import { postError } from './api'; import { name, version } from '../package.json'; +import https from 'https'; +import { errors } from './constants'; import set from 'lodash.set'; import get from 'lodash.get'; @@ -166,6 +169,57 @@ const shouldCachePayload = ( return true; }; +function post( + url: string, + data: Array | ErrorPayloadType, + authorization: string +): Promise { + const dataString = JSON.stringify(data); + + const options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': dataString.length, + Authorization: authorization + }, + timeout: 5000 // in ms + }; + + return new Promise((resolve, reject) => { + const req = https.request(url, options, (res) => { + if (res && res.statusCode) { + if (res.statusCode === 401) { + return reject(new Error(errors.UNAUTHORIZED)); + } + + if (res.statusCode < 200 || res.statusCode > 299) { + return reject(new Error(`HTTP status code ${res.statusCode}`)); + } + } + + const body = [] as Buffer[]; + res.on('data', (chunk) => body.push(chunk)); + res.on('end', () => { + const resString = Buffer.concat(body).toString(); + resolve(resString); + }); + }); + + req.on('error', (err) => { + reject(err); + }); + + req.on('timeout', () => { + req.destroy(); + reject(new Error('Request time out')); + }); + + req.write(dataString); + req.end(); + }); +} + const sleep = (ms: number) => { return new Promise((resolve) => setTimeout(resolve, ms)); }; @@ -178,5 +232,6 @@ export { safeParseJson, prepareData, shouldCachePayload, - sleep + sleep, + post }; diff --git a/yarn.lock b/yarn.lock index 08c033e..5ee6c79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -827,14 +827,6 @@ resolved "https://registry.npmjs.org/@types/node-cleanup/-/node-cleanup-2.1.2.tgz" integrity sha512-HTksao/sZs9nqxKD/vWOR3WxSrQsyJlBPEFFCgq9lMmhRsuQF+2p6hy+7FaCYn6lOeiDc3ywI8jDQ2bz5y6m8w== -"@types/node-fetch@^2.6.2": - version "2.6.2" - resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz" - integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - "@types/node-fetch@^2.6.4": version "2.6.6" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.6.tgz#b72f3f4bc0c0afee1c0bc9cff68e041d01e3e779" @@ -2359,15 +2351,6 @@ form-data-encoder@^2.1.2: resolved "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz" integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" @@ -3821,7 +3804,7 @@ node-domexception@1.0.0: resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== -node-fetch@2, node-fetch@^2.6.7: +node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== From 2e3b88540282b85d9c946a93709eda3d743eaf95 Mon Sep 17 00:00:00 2001 From: Alex Klarfeld Date: Thu, 28 Sep 2023 18:39:14 -0700 Subject: [PATCH 2/2] Fixed issue with error reporting --- src/constants.ts | 2 +- src/index.ts | 6 +++--- src/utils.ts | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index a2e266f..48fdffb 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -27,7 +27,7 @@ const errors = { 'No Client Secret Provided, set SUPERGOOD_CLIENT_SECRET or pass it as an argument' }; -const TestErrorPath = '/supergood-test-error'; +const TestErrorPath = '/api/supergood-test-error'; const LocalClientId = 'local-client-id'; const LocalClientSecret = 'local-client-secret'; diff --git a/src/index.ts b/src/index.ts index 92a1f7b..de04802 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,6 +83,9 @@ const Supergood = () => { stdTTL: 0 }); + errorSinkUrl = `${baseUrl}${supergoodConfig.errorSinkEndpoint}`; + eventSinkUrl = `${baseUrl}${supergoodConfig.eventSinkEndpoint}`; + headerOptions = getHeaderOptions(clientId, clientSecret); log = logger({ errorSinkUrl, headerOptions }); @@ -149,9 +152,6 @@ const Supergood = () => { } }); - errorSinkUrl = `${baseUrl}${supergoodConfig.errorSinkEndpoint}`; - eventSinkUrl = `${baseUrl}${supergoodConfig.eventSinkEndpoint}`; - // Flushes the cache every milliseconds interval = setInterval(flushCache, supergoodConfig.flushInterval); interval.unref(); diff --git a/src/utils.ts b/src/utils.ts index abd8949..a4731fa 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -38,6 +38,7 @@ const logger = ({ JSON.stringify(payload, null, 2), error ); + console.log({ reportOut, errorSinkUrl }); if (reportOut && errorSinkUrl) { postError( errorSinkUrl,