diff --git a/.pnp.cjs b/.pnp.cjs index 8673e9c6..d0e107d3 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -28,7 +28,7 @@ const RAW_RUNTIME_STATE = "packageLocation": "./",\ "packageDependencies": [\ ["@awell-health/awell-sdk", "npm:0.1.20"],\ - ["@awell-health/extensions-core", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.20"],\ + ["@awell-health/extensions-core", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.18"],\ ["@awell-health/healthie-sdk", "npm:0.1.1"],\ ["@dropbox/sign", "npm:1.8.0"],\ ["@faker-js/faker", "npm:8.4.1"],\ @@ -66,7 +66,6 @@ const RAW_RUNTIME_STATE = ["@types/uuid", "npm:10.0.0"],\ ["@types/xml2js", "npm:0.4.14"],\ ["@typescript-eslint/eslint-plugin", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:5.62.0"],\ - ["@upstash/ratelimit", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:2.0.5"],\ ["@yarnpkg/sdks", "npm:3.2.0"],\ ["api", "npm:6.1.2"],\ ["axios", "npm:1.7.7"],\ @@ -222,7 +221,7 @@ const RAW_RUNTIME_STATE = "packageDependencies": [\ ["@awell-health/awell-extensions", "workspace:."],\ ["@awell-health/awell-sdk", "npm:0.1.20"],\ - ["@awell-health/extensions-core", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.20"],\ + ["@awell-health/extensions-core", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.18"],\ ["@awell-health/healthie-sdk", "npm:0.1.1"],\ ["@dropbox/sign", "npm:1.8.0"],\ ["@faker-js/faker", "npm:8.4.1"],\ @@ -260,7 +259,6 @@ const RAW_RUNTIME_STATE = ["@types/uuid", "npm:10.0.0"],\ ["@types/xml2js", "npm:0.4.14"],\ ["@typescript-eslint/eslint-plugin", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:5.62.0"],\ - ["@upstash/ratelimit", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:2.0.5"],\ ["@yarnpkg/sdks", "npm:3.2.0"],\ ["api", "npm:6.1.2"],\ ["axios", "npm:1.7.7"],\ @@ -332,21 +330,20 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["@awell-health/extensions-core", [\ - ["npm:1.0.20", {\ - "packageLocation": "./.yarn/cache/@awell-health-extensions-core-npm-1.0.20-9f25e5c3ea-fd829c1ced.zip/node_modules/@awell-health/extensions-core/",\ + ["npm:1.0.18", {\ + "packageLocation": "./.yarn/cache/@awell-health-extensions-core-npm-1.0.18-682857dd76-f65aaf1c89.zip/node_modules/@awell-health/extensions-core/",\ "packageDependencies": [\ - ["@awell-health/extensions-core", "npm:1.0.20"]\ + ["@awell-health/extensions-core", "npm:1.0.18"]\ ],\ "linkType": "SOFT"\ }],\ - ["virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.20", {\ - "packageLocation": "./.yarn/__virtual__/@awell-health-extensions-core-virtual-03d9179995/0/cache/@awell-health-extensions-core-npm-1.0.20-9f25e5c3ea-fd829c1ced.zip/node_modules/@awell-health/extensions-core/",\ + ["virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.18", {\ + "packageLocation": "./.yarn/__virtual__/@awell-health-extensions-core-virtual-f615837ce5/0/cache/@awell-health-extensions-core-npm-1.0.18-682857dd76-f65aaf1c89.zip/node_modules/@awell-health/extensions-core/",\ "packageDependencies": [\ - ["@awell-health/extensions-core", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.20"],\ + ["@awell-health/extensions-core", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:1.0.18"],\ ["@awell-health/awell-sdk", "npm:0.1.20"],\ ["@types/awell-health__awell-sdk", null],\ ["@types/json-schema", "npm:7.0.15"],\ - ["@upstash/ratelimit", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:2.0.5"],\ ["axios", "npm:1.7.7"],\ ["date-fns", "npm:3.6.0"],\ ["libphonenumber-js", "npm:1.11.8"],\ @@ -5071,49 +5068,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["@upstash/core-analytics", [\ - ["npm:0.0.10", {\ - "packageLocation": "./.yarn/cache/@upstash-core-analytics-npm-0.0.10-2a5fe69bd4-945ed44fa0.zip/node_modules/@upstash/core-analytics/",\ - "packageDependencies": [\ - ["@upstash/core-analytics", "npm:0.0.10"],\ - ["@upstash/redis", "npm:1.34.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@upstash/ratelimit", [\ - ["npm:2.0.5", {\ - "packageLocation": "./.yarn/cache/@upstash-ratelimit-npm-2.0.5-ef72e1a253-b3f50b7320.zip/node_modules/@upstash/ratelimit/",\ - "packageDependencies": [\ - ["@upstash/ratelimit", "npm:2.0.5"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:2.0.5", {\ - "packageLocation": "./.yarn/__virtual__/@upstash-ratelimit-virtual-ce0074d2f2/0/cache/@upstash-ratelimit-npm-2.0.5-ef72e1a253-b3f50b7320.zip/node_modules/@upstash/ratelimit/",\ - "packageDependencies": [\ - ["@upstash/ratelimit", "virtual:6d1931a4340173b37cf492f77cb803dda2f92958adb6847175388be3c73eb24be6f6bfd25e0fc0b7ad8dba815a972ad5e9d1f18e67fb58466bb7c99205a9d42e#npm:2.0.5"],\ - ["@types/upstash__redis", null],\ - ["@upstash/core-analytics", "npm:0.0.10"],\ - ["@upstash/redis", null]\ - ],\ - "packagePeers": [\ - "@types/upstash__redis",\ - "@upstash/redis"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@upstash/redis", [\ - ["npm:1.34.4", {\ - "packageLocation": "./.yarn/cache/@upstash-redis-npm-1.34.4-45d02d8fd5-20ace4e0ac.zip/node_modules/@upstash/redis/",\ - "packageDependencies": [\ - ["@upstash/redis", "npm:1.34.4"],\ - ["crypto-js", "npm:4.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["@whatwg-node/events", [\ ["npm:0.0.3", {\ "packageLocation": "./.yarn/cache/@whatwg-node-events-npm-0.0.3-697fe4b65f-af26f40d4d.zip/node_modules/@whatwg-node/events/",\ @@ -7003,15 +6957,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["crypto-js", [\ - ["npm:4.2.0", {\ - "packageLocation": "./.yarn/cache/crypto-js-npm-4.2.0-d6f7744e63-c7bcc56a6e.zip/node_modules/crypto-js/",\ - "packageDependencies": [\ - ["crypto-js", "npm:4.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["css-select", [\ ["npm:5.1.0", {\ "packageLocation": "./.yarn/cache/css-select-npm-5.1.0-9365a79de5-d486b1e7eb.zip/node_modules/css-select/",\ diff --git a/.yarn/cache/@awell-health-extensions-core-npm-1.0.20-9f25e5c3ea-fd829c1ced.zip b/.yarn/cache/@awell-health-extensions-core-npm-1.0.18-682857dd76-f65aaf1c89.zip similarity index 84% rename from .yarn/cache/@awell-health-extensions-core-npm-1.0.20-9f25e5c3ea-fd829c1ced.zip rename to .yarn/cache/@awell-health-extensions-core-npm-1.0.18-682857dd76-f65aaf1c89.zip index e73fc981..7d169cc4 100644 Binary files a/.yarn/cache/@awell-health-extensions-core-npm-1.0.20-9f25e5c3ea-fd829c1ced.zip and b/.yarn/cache/@awell-health-extensions-core-npm-1.0.18-682857dd76-f65aaf1c89.zip differ diff --git a/.yarn/cache/@upstash-core-analytics-npm-0.0.10-2a5fe69bd4-945ed44fa0.zip b/.yarn/cache/@upstash-core-analytics-npm-0.0.10-2a5fe69bd4-945ed44fa0.zip deleted file mode 100644 index 108e695d..00000000 Binary files a/.yarn/cache/@upstash-core-analytics-npm-0.0.10-2a5fe69bd4-945ed44fa0.zip and /dev/null differ diff --git a/.yarn/cache/@upstash-ratelimit-npm-2.0.5-ef72e1a253-b3f50b7320.zip b/.yarn/cache/@upstash-ratelimit-npm-2.0.5-ef72e1a253-b3f50b7320.zip deleted file mode 100644 index b59b952c..00000000 Binary files a/.yarn/cache/@upstash-ratelimit-npm-2.0.5-ef72e1a253-b3f50b7320.zip and /dev/null differ diff --git a/.yarn/cache/@upstash-redis-npm-1.34.4-45d02d8fd5-20ace4e0ac.zip b/.yarn/cache/@upstash-redis-npm-1.34.4-45d02d8fd5-20ace4e0ac.zip deleted file mode 100644 index 82ae0772..00000000 Binary files a/.yarn/cache/@upstash-redis-npm-1.34.4-45d02d8fd5-20ace4e0ac.zip and /dev/null differ diff --git a/.yarn/cache/crypto-js-npm-4.2.0-d6f7744e63-c7bcc56a6e.zip b/.yarn/cache/crypto-js-npm-4.2.0-d6f7744e63-c7bcc56a6e.zip deleted file mode 100644 index 8fcc0793..00000000 Binary files a/.yarn/cache/crypto-js-npm-4.2.0-d6f7744e63-c7bcc56a6e.zip and /dev/null differ diff --git a/extensions/elation/webhooks/appointmentCreatedOrUpdated.ts b/extensions/elation/webhooks/appointmentCreatedOrUpdated.ts index ceeeee87..52a76fd6 100644 --- a/extensions/elation/webhooks/appointmentCreatedOrUpdated.ts +++ b/extensions/elation/webhooks/appointmentCreatedOrUpdated.ts @@ -26,12 +26,7 @@ export const appointmentCreatedOrUpdated: Webhook< > = { key: 'appointmentCreatedOrUpdated', dataPoints, - onEvent: async ({ - payload: { payload, settings }, - onSuccess, - onError, - helpers, - }) => { + onEvent: async ({ payload: { payload, settings }, onSuccess, onError }) => { const { action, resource, data } = payload const { id: appointmentId, patient: patientId } = data @@ -40,31 +35,6 @@ export const appointmentCreatedOrUpdated: Webhook< return } - const rateLimitDuration = rateLimitDurationSchema.parse( - settings.rateLimitDuration, - ) - - if (!isNil(rateLimitDuration)) { - const rateLimiter = helpers.rateLimit(1, rateLimitDuration as Duration) - const strAppt = JSON.stringify(data) - const uniqueHash = createHash('sha256').update(strAppt).digest('hex') - // i'd rather use the unique hash here, but instead using an appointment ID - const { success } = await rateLimiter.limit( - `elation-appointment-${appointmentId}`, - ) - if (!success) { - console.log(`ELATION: Rate limited for appointment_id=${appointmentId}`) - // we're sending a 200 response to elation to avoid them retrying the request - await onError({ - response: { - statusCode: 200, - message: 'Rate limit exceeded', - }, - }) - return - } - } - if (resource !== 'appointments') { await onError({ response: { diff --git a/extensions/elation/webhooks/patientCreatedOrUpdated.ts b/extensions/elation/webhooks/patientCreatedOrUpdated.ts index fe52d888..dd217451 100644 --- a/extensions/elation/webhooks/patientCreatedOrUpdated.ts +++ b/extensions/elation/webhooks/patientCreatedOrUpdated.ts @@ -25,12 +25,7 @@ export const patientCreatedOrUpdated: Webhook< > = { key: 'patientCreatedOrUpdated', dataPoints, - onEvent: async ({ - payload: { payload, settings }, - onSuccess, - onError, - helpers, - }) => { + onEvent: async ({ payload: { payload, settings }, onSuccess, onError }) => { const { data, resource, action } = payload const { id: patientId } = data @@ -39,31 +34,6 @@ export const patientCreatedOrUpdated: Webhook< return } - const rateLimitDuration = rateLimitDurationSchema.parse( - settings.rateLimitDuration, - ) - - if (!isNil(rateLimitDuration)) { - const rateLimiter = helpers.rateLimit(1, rateLimitDuration as Duration) - const strPatient = JSON.stringify(data) - const uniqueHash = createHash('sha256').update(strPatient).digest('hex') - // i'd rather use the unique hash here, but instead using a patient ID - const { success } = await rateLimiter.limit( - `elation-patient-${patientId}`, - ) - if (!success) { - console.log(`ELATION: Rate limited for patient_id=${patientId}`) - // we're sending a 200 response to elation to avoid them retrying the request - await onError({ - response: { - statusCode: 200, - message: 'Rate limit exceeded', - }, - }) - return - } - } - if (resource !== 'patients') { await onError({ response: { diff --git a/package.json b/package.json index 146dee87..1602b9e3 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ }, "dependencies": { "@awell-health/awell-sdk": "^0.1.20", - "@awell-health/extensions-core": "1.0.20", + "@awell-health/extensions-core": "1.0.18", "@awell-health/healthie-sdk": "^0.1.1", "@dropbox/sign": "^1.8.0", "@hubspot/api-client": "^11.2.0", @@ -91,7 +91,6 @@ "@sendgrid/helpers": "^7.7.0", "@sendgrid/mail": "^7.7.0", "@types/json-schema": "^7.0.15", - "@upstash/ratelimit": "^2.0.5", "api": "^6.0.0", "axios": "^1.6.8", "body-parser": "^1.20.2", diff --git a/src/test-server.ts b/src/test-server.ts index 5ca7544e..3d460ee4 100644 --- a/src/test-server.ts +++ b/src/test-server.ts @@ -8,21 +8,36 @@ import { AwellError, } from '@awell-health/extensions-core' import { extensions } from '../extensions' +import { Ratelimit } from '@upstash/ratelimit' +import { Redis } from 'ioredis' const app = express() const port = 3000 -// type QueueInput = ( -// | Parameters[0] -// | Parameters[0] -// ) & { response: 'success' | 'failure' } - -// const queue: QueueInput[] = [] - app.use(bodyParser.json()) +const limiter = Ratelimit.fixedWindow(1, '1m') +const rateLimit = new Ratelimit({ + redis: new Redis({ + host: 'localhost', + port: 6379, + password: + 'VRmODJzStDXW0I0fr0G5UXd8v7Az5nJ4MvOMoGVR0iGhQEDuiACJLlNpBkBoyY8RUFhSW8tqt0ojoHIkqCJnLUeLRrmFHO47Og0DYv4wDv1pIfHCVU1uzFZOORNLDRp5', + }), + limiter, +}) + app.post('/', async (req, res) => { console.log(req.body) + try { + const { success } = await rateLimit.limit('test') + if (!success) { + res.status(429).send('Too many requests') + return + } + } catch (error) { + console.error(error) + } res.send('ok') }) @@ -45,7 +60,7 @@ app.post('/:extension/:action', async (req, res) => { return } const action = Object.values(extension.actions).find( - ({ key }) => key === actionKey + ({ key }) => key === actionKey, ) if (action === undefined) { res @@ -76,7 +91,7 @@ app.post('/:extension/:action', async (req, res) => { }, ], }) - } + }, ) // const result = queue.shift() // res.send(result) @@ -88,7 +103,7 @@ app.listen(port, () => { const createOnCompleteCallback = ( // payload: NewActivityPayload, - res: express.Response + res: express.Response, ): OnCompleteCallback => { return async (params = {}) => { console.log({ ...params, response: 'success' }) @@ -98,7 +113,7 @@ const createOnCompleteCallback = ( } const createOnErrorCallback = ( // payload: NewActivityPayload, - res: express.Response + res: express.Response, ): OnErrorCallback => { return async (params = {}) => { console.error({ ...params, response: 'failure' }) diff --git a/yarn.lock b/yarn.lock index e009b43f..5c74ed22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -87,7 +87,7 @@ __metadata: resolution: "@awell-health/awell-extensions@workspace:." dependencies: "@awell-health/awell-sdk": "npm:^0.1.20" - "@awell-health/extensions-core": "npm:1.0.20" + "@awell-health/extensions-core": "npm:1.0.18" "@awell-health/healthie-sdk": "npm:^0.1.1" "@dropbox/sign": "npm:^1.8.0" "@faker-js/faker": "npm:^8.0.2" @@ -125,7 +125,6 @@ __metadata: "@types/uuid": "npm:^10.0.0" "@types/xml2js": "npm:^0.4.12" "@typescript-eslint/eslint-plugin": "npm:^5.52.0" - "@upstash/ratelimit": "npm:^2.0.5" "@yarnpkg/sdks": "npm:^3.2.0" api: "npm:^6.0.0" axios: "npm:^1.6.8" @@ -194,12 +193,11 @@ __metadata: languageName: node linkType: hard -"@awell-health/extensions-core@npm:1.0.20": - version: 1.0.20 - resolution: "@awell-health/extensions-core@npm:1.0.20" +"@awell-health/extensions-core@npm:1.0.18": + version: 1.0.18 + resolution: "@awell-health/extensions-core@npm:1.0.18" dependencies: "@types/json-schema": "npm:^7.0.15" - "@upstash/ratelimit": "npm:^2.0.5" axios: "npm:^1.7.4" date-fns: "npm:^3.6.0" libphonenumber-js: "npm:^1.10.61" @@ -208,7 +206,7 @@ __metadata: zod-validation-error: "npm:^3.2.0" peerDependencies: "@awell-health/awell-sdk": "*" - checksum: 10/fd829c1ced8c44dfbc9775b31ad3d96bf1afc5082b835ea06948514d66e6665efea2b5578f150efadcd80c347f240f6d3f850c8db7d484c0b264dff97f42112e + checksum: 10/f65aaf1c891b828d92cdf89d9fb2d61c00862d5ed3ef57c836d41039a845834e535bf39462c7e3fea870beb5d9f93c38709c16b639aad2971ad3d8287b6d22e0 languageName: node linkType: hard @@ -3259,35 +3257,6 @@ __metadata: languageName: node linkType: hard -"@upstash/core-analytics@npm:^0.0.10": - version: 0.0.10 - resolution: "@upstash/core-analytics@npm:0.0.10" - dependencies: - "@upstash/redis": "npm:^1.28.3" - checksum: 10/945ed44fa02915a37a2ceaa254f38b3e1b305daede520164b8887681bb1bfbe722f4b90b41c6ca5a87f50b9a22bfe48367f7b5ff9b2a8feb1b467ab803663354 - languageName: node - linkType: hard - -"@upstash/ratelimit@npm:^2.0.5": - version: 2.0.5 - resolution: "@upstash/ratelimit@npm:2.0.5" - dependencies: - "@upstash/core-analytics": "npm:^0.0.10" - peerDependencies: - "@upstash/redis": ^1.34.3 - checksum: 10/b3f50b73201da66af555a45c25df2d2bed9890b507dfdc96b5792f7513a688c8ccfedcdfc7a699b685124d5f1321715006353a3ec72900cca364c0698ed60ba6 - languageName: node - linkType: hard - -"@upstash/redis@npm:^1.28.3": - version: 1.34.4 - resolution: "@upstash/redis@npm:1.34.4" - dependencies: - crypto-js: "npm:^4.2.0" - checksum: 10/20ace4e0ac9f6703da67e6bd324980a49a33d7312205ca37ecfef961482e74848171af1c22a6e39e73bcdab83c8f435458562c605d57abaee4add3ee66ccd4c4 - languageName: node - linkType: hard - "@whatwg-node/events@npm:^0.0.3": version: 0.0.3 resolution: "@whatwg-node/events@npm:0.0.3" @@ -4905,13 +4874,6 @@ __metadata: languageName: node linkType: hard -"crypto-js@npm:^4.2.0": - version: 4.2.0 - resolution: "crypto-js@npm:4.2.0" - checksum: 10/c7bcc56a6e01c3c397e95aa4a74e4241321f04677f9a618a8f48a63b5781617248afb9adb0629824792e7ec20ca0d4241a49b6b2938ae6f973ec4efc5c53c924 - languageName: node - linkType: hard - "crypto@npm:^1.0.1": version: 1.0.1 resolution: "crypto@npm:1.0.1"