From bc8a67b00cde3ea03b72507176a5abc136eb7cef Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 18 May 2024 14:02:28 -0400 Subject: [PATCH 01/27] update to node-fetch@3, do bare minimum to get it building. most tests pass, not all. abused the type system to make it build and run. --- .vscode/launch.json | 14 +- package-lock.json | 210 +++++++++++++-------- package.json | 3 +- src/classes/response.ts | 7 +- src/helpers/cache_keys.ts | 6 +- src/helpers/shim_response_to_snipe_body.ts | 9 +- src/index.ts | 4 +- test/tests.ts | 13 +- 8 files changed, 165 insertions(+), 101 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index e711502..ffcf29c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,19 @@ { "type": "node", "request": "launch", - "name": "Debug Tests", + "name": "Debug Tests Local Server", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "test:debug"], + "console": "integratedTerminal", + "env": { + "HTTP_BIN_BASE_URL": "http://localhost:3000" + }, + "runtimeVersion": "20" + }, + { + "type": "node", + "request": "launch", + "name": "Debug Tests Remote Server", "runtimeExecutable": "npm", "runtimeArgs": ["run", "test:debug"], "console": "integratedTerminal", diff --git a/package-lock.json b/package-lock.json index f851e70..c5f4af1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,10 @@ "version": "4.1.1", "license": "MIT", "dependencies": { - "@types/node-fetch": "2.6.11", "cacache": "^18.0.1", "form-data": "^4.0.0", "locko": "^1.1.0", - "node-fetch": "2.7.0" + "node-fetch": "3.3.2" }, "devDependencies": { "@types/cacache": "^17.0.2", @@ -569,19 +568,11 @@ "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, "node_modules/@types/semver": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", @@ -1329,6 +1320,15 @@ "node": ">= 8" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1421,7 +1421,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "devOptional": true, + "dev": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -1655,6 +1655,29 @@ "reusify": "^1.0.4" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -1769,6 +1792,18 @@ "node": ">= 6" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -1926,7 +1961,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, + "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -2497,23 +2532,41 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", "dependencies": { - "whatwg-url": "^5.0.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" }, "engines": { - "node": "4.x || >=6.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "node_modules/normalize-path": { @@ -2940,7 +2993,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "devOptional": true + "dev": true }, "node_modules/semver": { "version": "7.5.4", @@ -3149,11 +3202,6 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, "node_modules/ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -3260,7 +3308,8 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/unique-filename": { "version": "3.0.0", @@ -3320,18 +3369,13 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" } }, "node_modules/which": { @@ -3869,19 +3913,11 @@ "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", + "dev": true, "requires": { "undici-types": "~5.26.4" } }, - "@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "requires": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, "@types/semver": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", @@ -4389,6 +4425,11 @@ "which": "^2.0.1" } }, + "data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4455,7 +4496,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "devOptional": true, + "dev": true, "requires": { "iconv-lite": "^0.6.2" } @@ -4637,6 +4678,15 @@ "reusify": "^1.0.4" } }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -4723,6 +4773,14 @@ "mime-types": "^2.1.12" } }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -4831,7 +4889,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } @@ -5254,12 +5312,19 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "requires": { - "whatwg-url": "^5.0.0" + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" } }, "normalize-path": { @@ -5532,7 +5597,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "devOptional": true + "dev": true }, "semver": { "version": "7.5.4", @@ -5689,11 +5754,6 @@ "is-number": "^7.0.0" } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, "ts-api-utils": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", @@ -5756,7 +5816,8 @@ "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "unique-filename": { "version": "3.0.0", @@ -5809,19 +5870,10 @@ } } }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } + "web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" }, "which": { "version": "2.0.2", diff --git a/package.json b/package.json index d04de9e..429c4fb 100644 --- a/package.json +++ b/package.json @@ -55,11 +55,10 @@ "typescript": "^5.3.3" }, "dependencies": { - "@types/node-fetch": "2.6.11", "cacache": "^18.0.1", "form-data": "^4.0.0", "locko": "^1.1.0", - "node-fetch": "2.7.0" + "node-fetch": "3.3.2" }, "husky": { "hooks": { diff --git a/src/classes/response.ts b/src/classes/response.ts index bc0dbcc..98b3eed 100644 --- a/src/classes/response.ts +++ b/src/classes/response.ts @@ -15,7 +15,7 @@ export class NFCResponse extends NodeFetchResponse { statusText: response.statusText, headers: response.headers.raw(), size: response.size, - timeout: response.timeout, + timeout: (response as any).timeout, // eslint-disable-line @typescript-eslint/no-unsafe-assignment counter: (response as any)[responseInternalSymbol!].counter as number, }; @@ -45,6 +45,9 @@ export class NFCResponse extends NodeFetchResponse { constructor( bodyStream: NodeJS.ReadableStream, metaData: Omit & { + url: string; + size: number; + timeout: number; counter: number; headers: Record; }, @@ -54,7 +57,7 @@ export class NFCResponse extends NodeFetchResponse { ) { super( bodyStream, - metaData, + metaData as any, // eslint-disable-line @typescript-eslint/no-unsafe-argument ); } } diff --git a/src/helpers/cache_keys.ts b/src/helpers/cache_keys.ts index fa1ea78..f41a004 100644 --- a/src/helpers/cache_keys.ts +++ b/src/helpers/cache_keys.ts @@ -5,7 +5,7 @@ import { Request as NodeFetchRequest } from 'node-fetch'; import type { FetchInit, FetchResource, FormDataInternal } from '../types.js'; import { FormData } from '../types.js'; -export const CACHE_VERSION = 5; +export const CACHE_VERSION = 6; function md5(string_: string) { return crypto.createHash('md5').update(string_).digest('hex'); @@ -73,8 +73,8 @@ function getRequestCacheKeyJson(request: NodeFetchRequest) { referrer: request.referrer, url: request.url, body: getBodyCacheKeyJson(request.body), - follow: request.follow, - compress: request.compress, + follow: (request as any).follow, // eslint-disable-line @typescript-eslint/no-unsafe-assignment + compress: (request as any).compress, // eslint-disable-line @typescript-eslint/no-unsafe-assignment size: request.size, }; } diff --git a/src/helpers/shim_response_to_snipe_body.ts b/src/helpers/shim_response_to_snipe_body.ts index 4527f54..b1ae205 100644 --- a/src/helpers/shim_response_to_snipe_body.ts +++ b/src/helpers/shim_response_to_snipe_body.ts @@ -31,7 +31,7 @@ export function shimResponseToSnipeBody( const origJson = response.json; response.json = async function () { - const json = await origJson.call(this) as unknown; + const json = await origJson.call(this); replaceBodyStream(Readable.from(Buffer.from(JSON.stringify(json)))); return json; }; @@ -49,11 +49,4 @@ export function shimResponseToSnipeBody( replaceBodyStream(Readable.from(Buffer.from(await blob.text()))); return blob; }; - - const origTextConverted = response.textConverted; - response.textConverted = async function () { - const textConverted = await origTextConverted.call(this); - replaceBodyStream(Readable.from(Buffer.from(textConverted))); - return textConverted; - }; } diff --git a/src/index.ts b/src/index.ts index 7f49cc6..2d98454 100644 --- a/src/index.ts +++ b/src/index.ts @@ -88,7 +88,7 @@ async function getResponse( if (shouldCache) { const cacheSetResult = await fetchCustomization.cache.set( cacheKey, - bodyStream, + bodyStream!, serializedMeta, ); @@ -96,7 +96,7 @@ async function getResponse( } return new NFCResponse( - bodyStream, + bodyStream!, serializedMeta, ejectSelfFromCache, false, diff --git a/test/tests.ts b/test/tests.ts index e9330c7..fc92e38 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -384,7 +384,6 @@ describe('Cache tests', () => { return resource.url; } - // eslint-disable-next-line @typescript-eslint/no-base-to-string return resource.toString(); }; @@ -468,7 +467,7 @@ describe('Data tests', () => { response = await defaultCachedFetch(TEXT_BODY_URL); let body = ''; - for await (const chunk of response.body) { + for await (const chunk of response.body!) { body += chunk.toString(); } @@ -478,7 +477,7 @@ describe('Data tests', () => { response = await defaultCachedFetch(TEXT_BODY_URL); body = ''; - for await (const chunk of response.body) { + for await (const chunk of response.body!) { body += chunk.toString(); } @@ -744,7 +743,13 @@ describe('Cache strategy tests', () => { }); it('Can use a custom cache strategy that uses the response for all response types', async () => { - const functionsThatUseResponse = ['arrayBuffer', 'blob', 'buffer', 'json', 'text', 'textConverted'] as const; + const functionsThatUseResponse = [ + 'arrayBuffer', + 'blob', + 'buffer', + 'json', + 'text', + ] as const; await Promise.all( functionsThatUseResponse.map(async functionName => { From 4f304b976800d568da9891c2a2a293b2dc4f39a8 Mon Sep 17 00:00:00 2001 From: mistval Date: Sun, 19 May 2024 19:26:42 -0400 Subject: [PATCH 02/27] get all ESM tests passing (CJS doesnt work) --- src/classes/response.ts | 2 +- src/helpers/cache_keys.ts | 10 ++++++++-- src/types.ts | 3 ++- test/tests.ts | 8 ++++---- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/classes/response.ts b/src/classes/response.ts index 98b3eed..f90909b 100644 --- a/src/classes/response.ts +++ b/src/classes/response.ts @@ -56,7 +56,7 @@ export class NFCResponse extends NodeFetchResponse { public readonly isCacheMiss = false, ) { super( - bodyStream, + Readable.from(bodyStream), metaData as any, // eslint-disable-line @typescript-eslint/no-unsafe-argument ); } diff --git a/src/helpers/cache_keys.ts b/src/helpers/cache_keys.ts index f41a004..37a47a7 100644 --- a/src/helpers/cache_keys.ts +++ b/src/helpers/cache_keys.ts @@ -1,5 +1,6 @@ import fs from 'fs'; import crypto from 'crypto'; +import assert from 'assert'; import { Buffer } from 'buffer'; import { Request as NodeFetchRequest } from 'node-fetch'; import type { FetchInit, FetchResource, FormDataInternal } from '../types.js'; @@ -7,6 +8,9 @@ import { FormData } from '../types.js'; export const CACHE_VERSION = 6; +const bodyInternalsSymbol = Object.getOwnPropertySymbols(new NodeFetchRequest('http://url.com'))[0]; +assert(bodyInternalsSymbol, 'Failed to get node-fetch bodyInternalsSymbol'); + function md5(string_: string) { return crypto.createHash('md5').update(string_).digest('hex'); } @@ -37,7 +41,7 @@ function getHeadersCacheKeyJson(headers: string[][]): string[][] { .filter(([key, value]) => key !== 'cache-control' || value !== 'only-if-cached'); } -function getBodyCacheKeyJson(body: any): string | FormDataInternal | undefined { +function getBodyCacheKeyJson(body: unknown): string | FormDataInternal | undefined { if (!body) { return undefined; } @@ -72,8 +76,10 @@ function getRequestCacheKeyJson(request: NodeFetchRequest) { redirect: request.redirect, referrer: request.referrer, url: request.url, - body: getBodyCacheKeyJson(request.body), + body: getBodyCacheKeyJson((request as any)[bodyInternalsSymbol!].body), + // Confirmed that this property exists, but it's not in the types follow: (request as any).follow, // eslint-disable-line @typescript-eslint/no-unsafe-assignment + // Confirmed that this property exists, but it's not in the types compress: (request as any).compress, // eslint-disable-line @typescript-eslint/no-unsafe-assignment size: request.size, }; diff --git a/src/types.ts b/src/types.ts index a14e89c..b155054 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,6 @@ import type fs from 'fs'; -import fetch, { Response as NodeFetchResponse } from 'node-fetch'; +import type { Response as NodeFetchResponse } from 'node-fetch'; +import type fetch from 'node-fetch'; import FormData from 'form-data'; export type FetchResource = Parameters[0]; diff --git a/test/tests.ts b/test/tests.ts index fc92e38..5785f50 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -537,15 +537,15 @@ describe('Data tests', () => { assert(initialResponse.ok); assert(!initialResponse.returnedFromCache); - const initialResponseBuffer = await initialResponse.buffer(); - assert.equal(initialResponseBuffer.length, 100_000); + const initialResponseBuffer = await initialResponse.arrayBuffer(); + assert.equal(initialResponseBuffer.byteLength, 100_000); const secondResponse = await defaultCachedFetch(HUNDRED_THOUSAND_BYTES_URL); assert(secondResponse.ok); assert(secondResponse.returnedFromCache); - const secondResponseBuffer = await secondResponse.buffer(); - assert.equal(secondResponseBuffer.length, 100_000); + const secondResponseBuffer = await secondResponse.arrayBuffer(); + assert.equal(secondResponseBuffer.byteLength, 100_000); }); }).timeout(10_000); From 59e214045eaab3b5dd3bfac792be062751914320 Mon Sep 17 00:00:00 2001 From: mistval Date: Sun, 19 May 2024 19:31:03 -0400 Subject: [PATCH 03/27] remove timeout which was removed in node-fetch v3 --- src/classes/response.ts | 3 --- src/types.ts | 1 - 2 files changed, 4 deletions(-) diff --git a/src/classes/response.ts b/src/classes/response.ts index f90909b..c0842b0 100644 --- a/src/classes/response.ts +++ b/src/classes/response.ts @@ -15,7 +15,6 @@ export class NFCResponse extends NodeFetchResponse { statusText: response.statusText, headers: response.headers.raw(), size: response.size, - timeout: (response as any).timeout, // eslint-disable-line @typescript-eslint/no-unsafe-assignment counter: (response as any)[responseInternalSymbol!].counter as number, }; @@ -33,7 +32,6 @@ export class NFCResponse extends NodeFetchResponse { statusText: 'Gateway Timeout', headers: {}, size: 0, - timeout: 0, counter: 0, }, async () => undefined, @@ -47,7 +45,6 @@ export class NFCResponse extends NodeFetchResponse { metaData: Omit & { url: string; size: number; - timeout: number; counter: number; headers: Record; }, diff --git a/src/types.ts b/src/types.ts index b155054..f72263d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,7 +20,6 @@ export type NFCResponseMetadata = { statusText: string; headers: Record; size: number; - timeout: number; counter: any; }; From 3bf0c131e81c688298d593e68fa419d9214172dc Mon Sep 17 00:00:00 2001 From: mistval Date: Sun, 19 May 2024 19:31:35 -0400 Subject: [PATCH 04/27] fix type --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index f72263d..33c7d7f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,7 +20,7 @@ export type NFCResponseMetadata = { statusText: string; headers: Record; size: number; - counter: any; + counter: number; }; export type INodeFetchCacheCache = { From ad69f273ddcd58b58570015948940ad432070077 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:02:06 -0400 Subject: [PATCH 05/27] dynamic import node-fetch --- src/classes/response.ts | 107 +++++++++++---------- src/helpers/cache_keys.ts | 16 +-- src/helpers/headers.ts | 5 +- src/helpers/shim_response_to_snipe_body.ts | 2 +- src/index.ts | 19 ++-- test/tests.ts | 6 +- 6 files changed, 85 insertions(+), 70 deletions(-) diff --git a/src/classes/response.ts b/src/classes/response.ts index c0842b0..9cc6764 100644 --- a/src/classes/response.ts +++ b/src/classes/response.ts @@ -1,60 +1,67 @@ import assert from 'assert'; import { Buffer } from 'buffer'; import { Readable } from 'stream'; -import { Response as NodeFetchResponse, ResponseInit as NodeFetchResponseInit } from 'node-fetch'; +import type { Response as NodeFetchResponseType, ResponseInit as NodeFetchResponseInit } from 'node-fetch'; import { NFCResponseMetadata } from '../types.js'; -const responseInternalSymbol = Object.getOwnPropertySymbols(new NodeFetchResponse())[1]; -assert(responseInternalSymbol, 'Failed to get node-fetch responseInternalSymbol'); - -export class NFCResponse extends NodeFetchResponse { - static serializeMetaFromNodeFetchResponse(response: NodeFetchResponse): NFCResponseMetadata { - const metaData = { - url: response.url, - status: response.status, - statusText: response.statusText, - headers: response.headers.raw(), - size: response.size, - counter: (response as any)[responseInternalSymbol!].counter as number, - }; - - return metaData; - } +export async function createNFCResponseClass() { + const { Response: NodeFetchResponse } = await import('node-fetch'); + + const responseInternalSymbol = Object.getOwnPropertySymbols(new NodeFetchResponse())[1]; + assert(responseInternalSymbol, 'Failed to get node-fetch responseInternalSymbol'); + + return class NFCResponse extends NodeFetchResponse { + static serializeMetaFromNodeFetchResponse(response: NodeFetchResponseType): NFCResponseMetadata { + const metaData = { + url: response.url, + status: response.status, + statusText: response.statusText, + headers: response.headers.raw(), + size: response.size, + counter: (response as any)[responseInternalSymbol!].counter as number, + }; + + return metaData; + } - static cacheMissResponse( - url: string, - ) { - return new NFCResponse( - Readable.from(Buffer.alloc(0)), - { - url, - status: 504, - statusText: 'Gateway Timeout', - headers: {}, - size: 0, - counter: 0, + static cacheMissResponse( + url: string, + ) { + return new NFCResponse( + Readable.from(Buffer.alloc(0)), + { + url, + status: 504, + statusText: 'Gateway Timeout', + headers: {}, + size: 0, + counter: 0, + }, + async () => undefined, + false, + true, + ); + } + + constructor( + bodyStream: NodeJS.ReadableStream, + metaData: Omit & { + url: string; + size: number; + counter: number; + headers: Record; }, - async () => undefined, - false, - true, - ); + public readonly ejectFromCache: () => Promise, + public readonly returnedFromCache: boolean, + public readonly isCacheMiss = false, + ) { + super( + Readable.from(bodyStream), + metaData as any, // eslint-disable-line @typescript-eslint/no-unsafe-argument + ); + } } - constructor( - bodyStream: NodeJS.ReadableStream, - metaData: Omit & { - url: string; - size: number; - counter: number; - headers: Record; - }, - public readonly ejectFromCache: () => Promise, - public readonly returnedFromCache: boolean, - public readonly isCacheMiss = false, - ) { - super( - Readable.from(bodyStream), - metaData as any, // eslint-disable-line @typescript-eslint/no-unsafe-argument - ); - } } + +export type NFCResponse = InstanceType>>; diff --git a/src/helpers/cache_keys.ts b/src/helpers/cache_keys.ts index 37a47a7..3761bba 100644 --- a/src/helpers/cache_keys.ts +++ b/src/helpers/cache_keys.ts @@ -2,15 +2,12 @@ import fs from 'fs'; import crypto from 'crypto'; import assert from 'assert'; import { Buffer } from 'buffer'; -import { Request as NodeFetchRequest } from 'node-fetch'; +import type { Request as NodeFetchRequestType } from 'node-fetch'; import type { FetchInit, FetchResource, FormDataInternal } from '../types.js'; import { FormData } from '../types.js'; export const CACHE_VERSION = 6; -const bodyInternalsSymbol = Object.getOwnPropertySymbols(new NodeFetchRequest('http://url.com'))[0]; -assert(bodyInternalsSymbol, 'Failed to get node-fetch bodyInternalsSymbol'); - function md5(string_: string) { return crypto.createHash('md5').update(string_).digest('hex'); } @@ -69,7 +66,11 @@ function getBodyCacheKeyJson(body: unknown): string | FormDataInternal | undefin throw new Error('Unsupported body type. Supported body types are: string, number, undefined, null, url.URLSearchParams, fs.ReadStream, FormData'); } -function getRequestCacheKeyJson(request: NodeFetchRequest) { +async function getRequestCacheKeyJson(request: NodeFetchRequestType) { + const { Request: NodeFetchRequest } = await import('node-fetch'); + const bodyInternalsSymbol = Object.getOwnPropertySymbols(new NodeFetchRequest('http://url.com'))[0]; + assert(bodyInternalsSymbol, 'Failed to get node-fetch bodyInternalsSymbol'); + return { headers: getHeadersCacheKeyJson([...request.headers.entries()]), method: request.method, @@ -85,9 +86,10 @@ function getRequestCacheKeyJson(request: NodeFetchRequest) { }; } -export function calculateCacheKey(resource: FetchResource, init?: FetchInit) { +export async function calculateCacheKey(resource: FetchResource, init?: FetchInit) { + const { Request: NodeFetchRequest } = await import('node-fetch'); const resourceCacheKeyJson = resource instanceof NodeFetchRequest - ? getRequestCacheKeyJson(resource) + ? await getRequestCacheKeyJson(resource) : { url: resource, body: undefined }; const initCacheKeyJson = { diff --git a/src/helpers/headers.ts b/src/helpers/headers.ts index 0bc731a..c64eb37 100644 --- a/src/helpers/headers.ts +++ b/src/helpers/headers.ts @@ -1,4 +1,3 @@ -import { Request as NodeFetchRequest } from 'node-fetch'; import { FetchInit, FetchResource } from '../types.js'; function headerKeyIsCacheControl(key: string) { @@ -16,7 +15,7 @@ function headerEntryIsCacheControlOnlyIfCached(pair: [string, string]) { return headerKeyIsCacheControl(pair[0]) && headerValueContainsOnlyIfCached(pair[1]); } -export function hasOnlyIfCachedOption(resource: FetchResource, init: FetchInit) { +export async function hasOnlyIfCachedOption(resource: FetchResource, init: FetchInit) { const initHeaderEntries = Object.entries(init?.headers ?? {}); const initHeaderEntriesContainsCacheControlOnlyIfCached = initHeaderEntries.some( pair => headerEntryIsCacheControlOnlyIfCached(pair as [string, string]), @@ -26,6 +25,8 @@ export function hasOnlyIfCachedOption(resource: FetchResource, init: FetchInit) return true; } + const { Request: NodeFetchRequest } = await import('node-fetch'); + if ( resource instanceof NodeFetchRequest && headerValueContainsOnlyIfCached(resource.headers.get('Cache-Control') ?? undefined) diff --git a/src/helpers/shim_response_to_snipe_body.ts b/src/helpers/shim_response_to_snipe_body.ts index b1ae205..42be9b0 100644 --- a/src/helpers/shim_response_to_snipe_body.ts +++ b/src/helpers/shim_response_to_snipe_body.ts @@ -1,6 +1,6 @@ import { Buffer } from 'buffer'; import { Readable } from 'stream'; -import { Response as NodeFetchResponse } from 'node-fetch'; +import type { Response as NodeFetchResponse } from 'node-fetch'; /* This is a bit of a hack to deal with the case when the user * consumes the response body in their `shouldCacheResponse` delegate. diff --git a/src/index.ts b/src/index.ts index 2d98454..e9a2a4c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ -import fetch, { Request as NodeFetchRequest } from 'node-fetch'; +import type { Request as NodeFetchRequestType } from 'node-fetch'; import FormData from 'form-data'; -import { NFCResponse } from './classes/response.js'; +import { createNFCResponseClass } from './classes/response.js'; import { MemoryCache } from './classes/caching/memory_cache.js'; import { calculateCacheKey } from './helpers/cache_keys.js'; import { cacheNon5xxOnly, cacheOkayOnly } from './helpers/cache_strategies.js'; @@ -26,7 +26,9 @@ type NFCCustomizations = { type NFCOptions = Partial; -function getUrlFromRequestArguments(resource: NodeFetchRequest | string) { +async function getUrlFromRequestArguments(resource: NodeFetchRequestType | string) { + const { Request: NodeFetchRequest } = await import('node-fetch'); + if (resource instanceof NodeFetchRequest) { return resource.url; } @@ -39,13 +41,16 @@ async function getResponse( resource: FetchResource, init: FetchInit, ) { + const { Request: NodeFetchRequest, default: fetch } = await import('node-fetch'); + const NFCResponse = await createNFCResponseClass(); + if (typeof resource !== 'string' && !(resource instanceof NodeFetchRequest)) { throw new TypeError( 'The first argument to fetch must be either a string or a node-fetch Request instance', ); } - const cacheKey = fetchCustomization.calculateCacheKey(resource, init); + const cacheKey = await fetchCustomization.calculateCacheKey(resource, init); const ejectSelfFromCache = async () => fetchCustomization.cache.remove(cacheKey); const cachedValue = await fetchCustomization.cache.get(cacheKey); @@ -58,9 +63,9 @@ async function getResponse( ); } - if (hasOnlyIfCachedOption(resource, init)) { + if (await hasOnlyIfCachedOption(resource, init)) { return NFCResponse.cacheMissResponse( - getUrlFromRequestArguments(resource), + await getUrlFromRequestArguments(resource), ); } @@ -148,7 +153,7 @@ export { calculateCacheKey as getCacheKey, calculateCacheKey, FormData, - NodeFetchRequest, + type NodeFetchRequestType as NodeFetchRequest, type NFCOptions, type CacheKeyCalculator, type INodeFetchCacheCache, diff --git a/test/tests.ts b/test/tests.ts index 5785f50..d84c33d 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -379,7 +379,7 @@ describe('Cache tests', () => { }); it('Can use a client-provided custom cache key', async () => { - const cacheFunction = (resource: FetchResource) => { + const cacheFunction = async (resource: FetchResource) => { if (resource instanceof StandardFetchRequest) { return resource.url; } @@ -654,8 +654,8 @@ describe('Cache key tests', () => { it('Can calculate a cache key and check that it exists', async () => { await defaultCachedFetch(TWO_HUNDRED_URL); - const cacheKey = calculateCacheKey(TWO_HUNDRED_URL); - const nonExistentCacheKey = calculateCacheKey(TEXT_BODY_URL); + const cacheKey = await calculateCacheKey(TWO_HUNDRED_URL); + const nonExistentCacheKey = await calculateCacheKey(TEXT_BODY_URL); const cacheKeyResult = await defaultCache.get(cacheKey); const nonExistentCacheKeyResult = await defaultCache.get(nonExistentCacheKey); From 4be7cf91478f441bf92f98ba39cdd56e9be06262 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:12:24 -0400 Subject: [PATCH 06/27] cleanup --- src/classes/response.ts | 4 +++- src/helpers/cache_keys.ts | 5 +++-- src/helpers/headers.ts | 3 ++- src/helpers/node_fetch_imports.ts | 4 ++++ src/index.ts | 5 +++-- 5 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 src/helpers/node_fetch_imports.ts diff --git a/src/classes/response.ts b/src/classes/response.ts index 9cc6764..aeab945 100644 --- a/src/classes/response.ts +++ b/src/classes/response.ts @@ -3,9 +3,10 @@ import { Buffer } from 'buffer'; import { Readable } from 'stream'; import type { Response as NodeFetchResponseType, ResponseInit as NodeFetchResponseInit } from 'node-fetch'; import { NFCResponseMetadata } from '../types.js'; +import { getNodeFetch } from '../helpers/node_fetch_imports.js'; export async function createNFCResponseClass() { - const { Response: NodeFetchResponse } = await import('node-fetch'); + const { NodeFetchResponse } = await getNodeFetch(); const responseInternalSymbol = Object.getOwnPropertySymbols(new NodeFetchResponse())[1]; assert(responseInternalSymbol, 'Failed to get node-fetch responseInternalSymbol'); @@ -64,4 +65,5 @@ export async function createNFCResponseClass() { } +export type NFCResponseClass = Awaited>; export type NFCResponse = InstanceType>>; diff --git a/src/helpers/cache_keys.ts b/src/helpers/cache_keys.ts index 3761bba..1d8eebc 100644 --- a/src/helpers/cache_keys.ts +++ b/src/helpers/cache_keys.ts @@ -5,6 +5,7 @@ import { Buffer } from 'buffer'; import type { Request as NodeFetchRequestType } from 'node-fetch'; import type { FetchInit, FetchResource, FormDataInternal } from '../types.js'; import { FormData } from '../types.js'; +import { getNodeFetch } from './node_fetch_imports.js'; export const CACHE_VERSION = 6; @@ -67,7 +68,7 @@ function getBodyCacheKeyJson(body: unknown): string | FormDataInternal | undefin } async function getRequestCacheKeyJson(request: NodeFetchRequestType) { - const { Request: NodeFetchRequest } = await import('node-fetch'); + const { NodeFetchRequest } = await getNodeFetch(); const bodyInternalsSymbol = Object.getOwnPropertySymbols(new NodeFetchRequest('http://url.com'))[0]; assert(bodyInternalsSymbol, 'Failed to get node-fetch bodyInternalsSymbol'); @@ -87,7 +88,7 @@ async function getRequestCacheKeyJson(request: NodeFetchRequestType) { } export async function calculateCacheKey(resource: FetchResource, init?: FetchInit) { - const { Request: NodeFetchRequest } = await import('node-fetch'); + const { NodeFetchRequest } = await getNodeFetch(); const resourceCacheKeyJson = resource instanceof NodeFetchRequest ? await getRequestCacheKeyJson(resource) : { url: resource, body: undefined }; diff --git a/src/helpers/headers.ts b/src/helpers/headers.ts index c64eb37..0a17dba 100644 --- a/src/helpers/headers.ts +++ b/src/helpers/headers.ts @@ -1,4 +1,5 @@ import { FetchInit, FetchResource } from '../types.js'; +import { getNodeFetch } from './node_fetch_imports.js'; function headerKeyIsCacheControl(key: string) { return key.trim().toLowerCase() === 'cache-control'; @@ -25,7 +26,7 @@ export async function hasOnlyIfCachedOption(resource: FetchResource, init: Fetch return true; } - const { Request: NodeFetchRequest } = await import('node-fetch'); + const { NodeFetchRequest } = await getNodeFetch(); if ( resource instanceof NodeFetchRequest diff --git a/src/helpers/node_fetch_imports.ts b/src/helpers/node_fetch_imports.ts new file mode 100644 index 0000000..6cbcf94 --- /dev/null +++ b/src/helpers/node_fetch_imports.ts @@ -0,0 +1,4 @@ +export async function getNodeFetch() { + const { default: fetch, Request: NodeFetchRequest, Response: NodeFetchResponse } = await import('node-fetch'); + return { fetch, NodeFetchRequest, NodeFetchResponse }; +} diff --git a/src/index.ts b/src/index.ts index e9a2a4c..e14820d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ import type { INodeFetchCacheCache, ISynchronizationStrategy, } from './types.js'; +import { getNodeFetch } from './helpers/node_fetch_imports.js'; type CacheKeyCalculator = typeof calculateCacheKey; @@ -27,7 +28,7 @@ type NFCCustomizations = { type NFCOptions = Partial; async function getUrlFromRequestArguments(resource: NodeFetchRequestType | string) { - const { Request: NodeFetchRequest } = await import('node-fetch'); + const { NodeFetchRequest } = await getNodeFetch(); if (resource instanceof NodeFetchRequest) { return resource.url; @@ -41,7 +42,7 @@ async function getResponse( resource: FetchResource, init: FetchInit, ) { - const { Request: NodeFetchRequest, default: fetch } = await import('node-fetch'); + const { NodeFetchRequest, fetch } = await getNodeFetch(); const NFCResponse = await createNFCResponseClass(); if (typeof resource !== 'string' && !(resource instanceof NodeFetchRequest)) { From aa75309288a4939528100e4ccb713f140b9ffb99 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:17:40 -0400 Subject: [PATCH 07/27] cleanup --- src/classes/response.ts | 15 ++++++++++++--- src/index.ts | 4 ++-- test/tests.ts | 5 +++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/classes/response.ts b/src/classes/response.ts index aeab945..d38b5a1 100644 --- a/src/classes/response.ts +++ b/src/classes/response.ts @@ -5,7 +5,7 @@ import type { Response as NodeFetchResponseType, ResponseInit as NodeFetchRespon import { NFCResponseMetadata } from '../types.js'; import { getNodeFetch } from '../helpers/node_fetch_imports.js'; -export async function createNFCResponseClass() { +async function createNFCResponseClass() { const { NodeFetchResponse } = await getNodeFetch(); const responseInternalSymbol = Object.getOwnPropertySymbols(new NodeFetchResponse())[1]; @@ -62,8 +62,17 @@ export async function createNFCResponseClass() { ); } } - } export type NFCResponseClass = Awaited>; -export type NFCResponse = InstanceType>>; +export type NFCResponse = InstanceType; + +let cachedClass: NFCResponseClass | undefined; + +export async function getNFCResponseClass() { + if (!cachedClass) { + cachedClass = await createNFCResponseClass(); + } + + return cachedClass; +} diff --git a/src/index.ts b/src/index.ts index e14820d..285d8aa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import type { Request as NodeFetchRequestType } from 'node-fetch'; import FormData from 'form-data'; -import { createNFCResponseClass } from './classes/response.js'; +import { getNFCResponseClass as getNFCResponseClass } from './classes/response.js'; import { MemoryCache } from './classes/caching/memory_cache.js'; import { calculateCacheKey } from './helpers/cache_keys.js'; import { cacheNon5xxOnly, cacheOkayOnly } from './helpers/cache_strategies.js'; @@ -43,7 +43,7 @@ async function getResponse( init: FetchInit, ) { const { NodeFetchRequest, fetch } = await getNodeFetch(); - const NFCResponse = await createNFCResponseClass(); + const NFCResponse = await getNFCResponseClass(); if (typeof resource !== 'string' && !(resource instanceof NodeFetchRequest)) { throw new TypeError( diff --git a/test/tests.ts b/test/tests.ts index d84c33d..ecda250 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -526,8 +526,9 @@ describe('Data tests', () => { ); // Since our bogus synchronization strategy doesn't actually synchronize, - // both requests should be cache misses. - assert(responses.every(response => !response.returnedFromCache)); + // at least five responses should be cache misses (this depends on random + // timing and might be a little flaky). + assert(responses.filter(response => !response.returnedFromCache).length > 5); }); it('Can stream a hundred thousand bytes to a file in ten chunks', async () => { From 49e4229317b3a2783c5f1ee14c44fbbefc253056 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:24:45 -0400 Subject: [PATCH 08/27] add an upgrade guide doc --- docs/upgrade_guide.md | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 docs/upgrade_guide.md diff --git a/docs/upgrade_guide.md b/docs/upgrade_guide.md new file mode 100644 index 0000000..ed8360f --- /dev/null +++ b/docs/upgrade_guide.md @@ -0,0 +1,98 @@ +# Upgrade Guide + +## Upgrading node-fetch-cache v4 -> v5 + +The v5 version of node-fetch-cache upgrades `node-fetch` from v2 to v3. + +Please consult the [node-fetch v2 -> v3 upgrade guide](https://github.com/node-fetch/node-fetch/blob/main/docs/v3-UPGRADE-GUIDE.md) and follow the instructions there, except regarding the following: + +1. The minimum supported node version for `node-fetch-cache` is v16.0.0 +2. Unlike `node-fetch` v3, `node-fetch-cache` v5 still supports CommonJS. + +## Upgrading node-fetch-cache v3 -> v4 + +The v4 version of node-fetch-cache has several breaking changes and new features. + +### Node.js v14.14.0 is now the lowest supported Node.js version + +v4 will not work at all on Node.js versions below v14.14.0. + +### Specifying a Cache + +The syntax to specify a non-default cache has changed. You should rewrite code like this: + +```js +import { fetchBuilder, FileSystemCache } from 'node-fetch-cache'; +const fetch = fetchBuilder.withCache(new FileSystemCache(options)); +``` + +To this: + +```js +import NodeFetchCache, { FileSystemCache } from 'node-fetch-cache'; + +const fetch = NodeFetchCache.create({ + cache: new FileSystemCache(options), +}); +``` + +### Cache-Control: only-if-cached + +If you are relying on the `Cache-Control: only-if-cached` header feature, that has been changed to better align with the browser fetch API. It no longer returns `undefined`, but instead returns a `504 Gateway Timeout` response if no cached response is available. The response will also have an `isCacheMiss` property set to true to help you distinguish it from a regular 504 response. You should rewrite code like this: + +```js +import fetch from 'node-fetch-cache'; + +const response = await fetch('https://google.com', { + headers: { 'Cache-Control': 'only-if-cached' } +}); + +if (response === undefined) { + console.log('No response was found in the cache!'); +} +``` + +To this: + +```js +import fetch from 'node-fetch-cache'; + +const response = await fetch('https://google.com', { + headers: { 'Cache-Control': 'only-if-cached' } +}); + +if (response.isCacheMiss) { + console.log('No response was found in the cache!'); +} +``` + +### TypeScript + +If you were using the `@types/node-fetch-cache` package, that is no longer necessary as v4 includes its own TypeScript definitions, which may be somewhat different. + +### ejectFromCache() + +While the `ejectFromCache()` function still exists and functions the same way as in v3, you may find the new `shouldCacheResponse` option to be cleaner for many use cases, and it also allows you to keep the response from being cached in the first place which will reduce writes to the cache. So consider rewriting code like this: + +```js +fetch('http://google.com') + .then(async response => { + if (!response.ok) { + await response.ejectFromCache(); + } else { + return response.text(); + } + }).then(text => console.log(text)); +``` + +To this: + +```js +fetch( + 'http://google.com', + undefined, + { shouldCacheResponse: response => response.ok }, +).then(response => { + return response.text(); +}).then(text => console.log(text)); +``` From e39389595dbe3a12fb0686ae5bc80fd2e37e89ff Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:26:09 -0400 Subject: [PATCH 09/27] increase oldest supported node version to v16 --- .github/workflows/ci.yml | 28 ------------- README.md | 88 ---------------------------------------- package-lock.json | 15 +++---- package.json | 4 +- 4 files changed, 10 insertions(+), 125 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76a5a8e..51085c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,34 +32,6 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - test_node_14_14_0: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [14.14.0] - - services: - httpbin: - image: kennethreitz/httpbin - ports: - - 3000:80 - - steps: - - uses: actions/checkout@v2 - - name: Use Node.js 20.x - uses: actions/setup-node@v1 - with: - node-version: 20.x - - run: npm ci - - run: npm run tsc - - run: npm run buildcjs - - name: Use Node.js Version Under Test - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm run test:core - test_node_other: runs-on: ubuntu-latest diff --git a/README.md b/README.md index e35d49f..48fa18c 100644 --- a/README.md +++ b/README.md @@ -249,94 +249,6 @@ const fetch = NodeFetchCache.create({ }); ``` -## Upgrading node-fetch-cache v3 -> v4 - -The v4 version of node-fetch-cache has several breaking changes and new features. Please review the below details if you are upgrading from v3. - -### Node.js v14.14.0 is now the lowest supported Node.js version - -v4 will not work at all on Node.js versions below v14.14.0. - -### Specifying a Cache - -The syntax to specify a non-default cache has changed. You should rewrite code like this: - -```js -import { fetchBuilder, FileSystemCache } from 'node-fetch-cache'; -const fetch = fetchBuilder.withCache(new FileSystemCache(options)); -``` - -To this: - -```js -import NodeFetchCache, { FileSystemCache } from 'node-fetch-cache'; - -const fetch = NodeFetchCache.create({ - cache: new FileSystemCache(options), -}); -``` - -### Cache-Control: only-if-cached - -If you are relying on the `Cache-Control: only-if-cached` header feature, that has been changed to better align with the browser fetch API. It no longer returns `undefined`, but instead returns a `504 Gateway Timeout` response if no cached response is available. The response will also have an `isCacheMiss` property set to true to help you distinguish it from a regular 504 response. You should rewrite code like this: - -```js -import fetch from 'node-fetch-cache'; - -const response = await fetch('https://google.com', { - headers: { 'Cache-Control': 'only-if-cached' } -}); - -if (response === undefined) { - console.log('No response was found in the cache!'); -} -``` - -To this: - -```js -import fetch from 'node-fetch-cache'; - -const response = await fetch('https://google.com', { - headers: { 'Cache-Control': 'only-if-cached' } -}); - -if (response.isCacheMiss) { - console.log('No response was found in the cache!'); -} -``` - -### TypeScript - -If you were using the `@types/node-fetch-cache` package, that is no longer necessary as v4 includes its own TypeScript definitions, which may be somewhat different. - -### ejectFromCache() - -While the `ejectFromCache()` function still exists and functions the same way as in v3, you may find the new `shouldCacheResponse` option to be cleaner for many use cases, and it also allows you to keep the response from being cached in the first place which will reduce writes to the cache. So consider rewriting code like this: - -```js -fetch('http://google.com') - .then(async response => { - if (!response.ok) { - await response.ejectFromCache(); - } else { - return response.text(); - } - }).then(text => console.log(text)); -``` - -To this: - -```js -fetch( - 'http://google.com', - undefined, - { shouldCacheResponse: response => response.ok }, -).then(response => { - return response.text(); -}).then(text => console.log(text)); -``` - ## Misc ### Streams diff --git a/package-lock.json b/package-lock.json index c5f4af1..149945c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "rimraf": "^5.0.5", "rollup": "^4.9.1", "ts-node": "^10.9.2", - "typescript": "^5.3.3" + "typescript": "^5.5.4" }, "engines": { "node": ">=14.14.0" @@ -3293,10 +3293,11 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5808,9 +5809,9 @@ "peer": true }, "typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true }, "undici-types": { diff --git a/package.json b/package.json index 429c4fb..21e2ead 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "rimraf": "^5.0.5", "rollup": "^4.9.1", "ts-node": "^10.9.2", - "typescript": "^5.3.3" + "typescript": "^5.5.4" }, "dependencies": { "cacache": "^18.0.1", @@ -66,6 +66,6 @@ } }, "engines": { - "node": ">=14.14.0" + "node": ">=16.0.0" } } From f629007814a1bface7e225bbed4d3f21e7a78902 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:28:10 -0400 Subject: [PATCH 10/27] bump ts target --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index a41e0e0..6809003 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "ES2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ From 8863ece8d744e7d8588a30ac486b9d5a2b7fc942 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:53:16 -0400 Subject: [PATCH 11/27] switch ts-node for tsx, update redis plugin --- .vscode/launch.json | 9 - README.md | 8 +- package-lock.json | 946 ++++++++++++++++++++++-------- package.json | 7 +- plugins/redis/test_redis_cache.ts | 23 +- 5 files changed, 729 insertions(+), 264 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ffcf29c..1aecf9e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,15 +15,6 @@ "HTTP_BIN_BASE_URL": "http://localhost:3000" }, "runtimeVersion": "20" - }, - { - "type": "node", - "request": "launch", - "name": "Debug Tests Remote Server", - "runtimeExecutable": "npm", - "runtimeArgs": ["run", "test:debug"], - "console": "integratedTerminal", - "runtimeVersion": "20" } ] } diff --git a/README.md b/README.md index 48fa18c..c7ad3de 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The first fetch with any given arguments will result in an HTTP request and any subsequent fetch with the same arguments will read the response from the cache. -By default responses are cached in memory, but you can also cache to files on disk, or implement your own cache. +By default responses are cached in memory, but you can also cache to files on disk, cache in Redis, or implement your own cache. ## Usage @@ -27,7 +27,7 @@ This module's API is a superset of `node-fetch`'s. You can consult [the node-fet ### Control what's cached -By default node-fetch-cache caches all responses, regardless of the status code or any other response characteristics. +By default node-fetch-cache caches all responses, regardless of the response status or any other response characteristics. There are two main ways to customize which responses are cached and which are not. @@ -265,6 +265,10 @@ node-fetch-cache supports both ESM and CommonJS. If you are using CommonJS, you const fetch = require('node-fetch-cache'); ``` +### Upgrading + +Upgrading from an older major version? Check the [upgrade guide](https://github.com/mistval/node-fetch-cache/tree/master/docs/upgrade_guide.md). + ### Node.js Support Policy node-fetch-cache will support: diff --git a/package-lock.json b/package-lock.json index 149945c..ced601b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,11 +27,11 @@ "mocha": "^10.2.0", "rimraf": "^5.0.5", "rollup": "^4.9.1", - "ts-node": "^10.9.2", + "tsx": "^4.17.0", "typescript": "^5.5.4" }, "engines": { - "node": ">=14.14.0" + "node": ">=16.0.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -50,26 +50,412 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -513,30 +899,6 @@ "win32" ] }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@types/cacache": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/@types/cacache/-/cacache-17.0.2.tgz", @@ -780,6 +1142,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -797,15 +1160,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -879,12 +1233,6 @@ "node": ">= 8" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1283,12 +1631,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -1426,6 +1768,46 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1822,11 +2204,12 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1844,6 +2227,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-tsconfig": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", + "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -2292,12 +2688,6 @@ "node": ">=10" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2806,6 +3196,16 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3214,56 +3614,24 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "node_modules/tsx": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.17.0.tgz", + "integrity": "sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==", "dev": true, + "license": "MIT", "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" + "esbuild": "~0.23.0", + "get-tsconfig": "^4.7.5" }, "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" + "tsx": "dist/cli.mjs" }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, "engines": { - "node": ">=0.3.1" + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" } }, "node_modules/type-check": { @@ -3344,12 +3712,6 @@ "punycode": "^2.1.0" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -3519,15 +3881,6 @@ "node": ">=10" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -3555,26 +3908,173 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "dev": true, + "optional": true }, "@eslint-community/eslint-utils": { "version": "4.4.0", @@ -3859,30 +4359,6 @@ "dev": true, "optional": true }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "@types/cacache": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/@types/cacache/-/cacache-17.0.2.tgz", @@ -4036,7 +4512,8 @@ "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "dev": true + "dev": true, + "peer": true }, "acorn-jsx": { "version": "5.3.2", @@ -4046,12 +4523,6 @@ "peer": true, "requires": {} }, - "acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", - "dev": true - }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -4103,12 +4574,6 @@ "picomatch": "^2.0.4" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -4401,12 +4866,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -4502,6 +4961,38 @@ "iconv-lite": "^0.6.2" } }, + "esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -4797,9 +5288,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -4809,6 +5300,15 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-tsconfig": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", + "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -5134,12 +5634,6 @@ "yallist": "^4.0.0" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5487,6 +5981,12 @@ "dev": true, "peer": true }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -5762,33 +6262,15 @@ "dev": true, "requires": {} }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "tsx": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.17.0.tgz", + "integrity": "sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==", "dev": true, "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } + "esbuild": "~0.23.0", + "fsevents": "~2.3.3", + "get-tsconfig": "^4.7.5" } }, "type-check": { @@ -5846,12 +6328,6 @@ "punycode": "^2.1.0" } }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -5977,12 +6453,6 @@ } } }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 21e2ead..f2ba6c8 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,9 @@ "scripts": { "tsc": "tsc", "buildcjs": "cross-env rollup ./dist/index.js --file ./dist/index.cjs --format cjs && cp ./commonjs/wrapper.cjs ./dist/wrapper.cjs", - "test": "cross-env NODE_OPTIONS=\"--loader ts-node/esm\" mocha --require ts-node/register --spec test/tests.ts --spec plugins/redis/test_redis_cache.ts --extensions ts --timeout 10000 --exit && mocha --timeout 10000 --exit test/tests.cjs", - "test:debug": "cross-env NODE_OPTIONS=\"--loader ts-node/esm\" mocha --inspect --inspect-brk --require ts-node/register --spec test/tests.ts --extensions ts --timeout 10000 --exit", - "test:core": "cross-env NODE_OPTIONS=\"--loader ts-node/esm\" mocha --require ts-node/register --spec test/tests.ts --extensions ts --timeout 10000 --exit && mocha --timeout 10000 --exit test/tests.cjs", + "test": "cross-env NODE_OPTIONS=\"--import tsx\" mocha --spec test/tests.ts --spec plugins/redis/test_redis_cache.ts --extensions ts --timeout 10000 --exit && mocha --timeout 10000 --exit test/tests.cjs", + "test:debug": "cross-env NODE_OPTIONS=\"--import tsx\" mocha --inspect --inspect-brk --spec test/tests.ts --spec plugins/redis/test_redis_cache.ts --extensions ts --timeout 10000 --exit", + "test:core": "cross-env NODE_OPTIONS=\"--import tsx\" mocha --spec test/tests.ts --extensions ts --timeout 10000 --exit && mocha --timeout 10000 --exit test/tests.cjs", "coverage": "c8 --reporter=lcov --reporter=text --reporter=html --exclude=dist --exclude=test --exclude=plugins/redis/test_redis_cache.ts npm test", "lint": "xo .", "lintfix": "xo . --fix", @@ -51,7 +51,6 @@ "mocha": "^10.2.0", "rimraf": "^5.0.5", "rollup": "^4.9.1", - "ts-node": "^10.9.2", "typescript": "^5.5.4" }, "dependencies": { diff --git a/plugins/redis/test_redis_cache.ts b/plugins/redis/test_redis_cache.ts index c28ab5c..5f688af 100644 --- a/plugins/redis/test_redis_cache.ts +++ b/plugins/redis/test_redis_cache.ts @@ -14,7 +14,7 @@ import FetchCache, { NFCResponse, calculateCacheKey, ISynchronizationStrategy, -} from 'node-fetch-cache'; +} from '../../src/index.js'; import { RedisCache } from './redis_cache.js'; import { Redis } from 'ioredis'; @@ -366,7 +366,7 @@ describe('REDIS Plugin Tests', function() { }); it('Can use a client-provided custom cache key', async () => { - const cacheFunction = (resource: FetchResource) => { + const cacheFunction = async (resource: FetchResource) => { if (resource instanceof StandardFetchRequest) { return resource.url; } @@ -375,7 +375,7 @@ describe('REDIS Plugin Tests', function() { return resource.toString(); }; - const cachedFetch = FetchCache.create({ calculateCacheKey: cacheFunction }); + const cachedFetch = FetchCache.create({ cache: defaultCache, calculateCacheKey: cacheFunction }); const response1 = await cachedFetch(TWO_HUNDRED_URL, { headers: { XXX: 'YYY' } }); const response2 = await cachedFetch(TWO_HUNDRED_URL, { headers: { XXX: 'ZZZ' } }); @@ -499,7 +499,7 @@ describe('REDIS Plugin Tests', function() { response = await defaultCachedFetch(TEXT_BODY_URL); let body = ''; - for await (const chunk of response.body) { + for await (const chunk of response.body ?? []) { body += chunk.toString(); } @@ -509,7 +509,7 @@ describe('REDIS Plugin Tests', function() { response = await defaultCachedFetch(TEXT_BODY_URL); body = ''; - for await (const chunk of response.body) { + for await (const chunk of response.body ?? []) { body += chunk.toString(); } @@ -556,10 +556,11 @@ describe('REDIS Plugin Tests', function() { .fill(0) .map(async () => defaultCachedFetch(TWO_HUNDRED_URL)), ); - + // Since our bogus synchronization strategy doesn't actually synchronize, - // both requests should be cache misses. - assert(responses.every(response => !response.returnedFromCache)); + // at least five responses should be cache misses (this depends on random + // timing and might be a little flaky). + assert(responses.filter(response => !response.returnedFromCache).length > 5); }); it('Can stream a hundred thousand bytes to a file in ten chunks', async () => { @@ -625,8 +626,8 @@ describe('REDIS Plugin Tests', function() { it('Can calculate a cache key and check that it exists', async () => { await defaultCachedFetch(TWO_HUNDRED_URL); - const cacheKey = calculateCacheKey(TWO_HUNDRED_URL); - const nonExistentCacheKey = calculateCacheKey(TEXT_BODY_URL); + const cacheKey = await calculateCacheKey(TWO_HUNDRED_URL); + const nonExistentCacheKey = await calculateCacheKey(TEXT_BODY_URL); const cacheKeyResult = await defaultCache.get(cacheKey); const nonExistentCacheKeyResult = await defaultCache.get(nonExistentCacheKey); @@ -714,7 +715,7 @@ describe('REDIS Plugin Tests', function() { }); it('Can use a custom cache strategy that uses the response for all response types', async () => { - const functionsThatUseResponse = ['arrayBuffer', 'blob', 'buffer', 'json', 'text', 'textConverted'] as const; + const functionsThatUseResponse = ['arrayBuffer', 'blob', 'buffer', 'json', 'text'] as const; for (const functionName of functionsThatUseResponse) { await redisClient.flushall(); From beef68b708ca00b12ed5ad3731ef080c8c24a473 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:54:48 -0400 Subject: [PATCH 12/27] bump version to v5 --- package-lock.json | 4 ++-- package.json | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ced601b..1009f5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node-fetch-cache", - "version": "4.1.1", + "version": "5.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "node-fetch-cache", - "version": "4.1.1", + "version": "5.0.0", "license": "MIT", "dependencies": { "cacache": "^18.0.1", diff --git a/package.json b/package.json index f2ba6c8..5a871d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-fetch-cache", - "version": "4.1.1", + "version": "5.0.0", "description": "node-fetch with caching.", "main": "src/index.js", "type": "module", @@ -51,6 +51,7 @@ "mocha": "^10.2.0", "rimraf": "^5.0.5", "rollup": "^4.9.1", + "tsx": "^4.17.0", "typescript": "^5.5.4" }, "dependencies": { From 889ed656ccaa5704f536029508e4636784f40f58 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 09:56:26 -0400 Subject: [PATCH 13/27] update upgrade guide --- docs/upgrade_guide.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/upgrade_guide.md b/docs/upgrade_guide.md index ed8360f..53e6ae4 100644 --- a/docs/upgrade_guide.md +++ b/docs/upgrade_guide.md @@ -9,6 +9,10 @@ Please consult the [node-fetch v2 -> v3 upgrade guide](https://github.com/node-f 1. The minimum supported node version for `node-fetch-cache` is v16.0.0 2. Unlike `node-fetch` v3, `node-fetch-cache` v5 still supports CommonJS. +In addition node-fetch-cache specifics have changed in the following ways: + +1. If you are providing a custom `calculateCacheKey` function, it must now be async (returns a promise). + ## Upgrading node-fetch-cache v3 -> v4 The v4 version of node-fetch-cache has several breaking changes and new features. From 78603430206e3a6743d4afe38319ca12a1e2845b Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:14:31 -0400 Subject: [PATCH 14/27] replace form-data with formdata-node --- docs/upgrade_guide.md | 7 +- package-lock.json | 105 ++++-------------------------- package.json | 2 +- plugins/redis/test_redis_cache.ts | 2 +- src/helpers/cache_keys.ts | 24 ++----- src/index.ts | 2 +- src/types.ts | 8 +-- test/tests.ts | 2 +- 8 files changed, 27 insertions(+), 125 deletions(-) diff --git a/docs/upgrade_guide.md b/docs/upgrade_guide.md index 53e6ae4..44659e2 100644 --- a/docs/upgrade_guide.md +++ b/docs/upgrade_guide.md @@ -2,20 +2,21 @@ ## Upgrading node-fetch-cache v4 -> v5 -The v5 version of node-fetch-cache upgrades `node-fetch` from v2 to v3. +The v5 version of `node-fetch-cache` upgrades `node-fetch` from v2 to v3. Please consult the [node-fetch v2 -> v3 upgrade guide](https://github.com/node-fetch/node-fetch/blob/main/docs/v3-UPGRADE-GUIDE.md) and follow the instructions there, except regarding the following: 1. The minimum supported node version for `node-fetch-cache` is v16.0.0 2. Unlike `node-fetch` v3, `node-fetch-cache` v5 still supports CommonJS. -In addition node-fetch-cache specifics have changed in the following ways: +In addition, `node-fetch-cache` specifics have changed in the following breaking ways, which will affect a minority of use cases: 1. If you are providing a custom `calculateCacheKey` function, it must now be async (returns a promise). +2. `node-fetch-cache` now uses [formdata-node](https://www.npmjs.com/package/formdata-node) instead of [form-data](https://www.npmjs.com/package/form-data) (which has been deprecated in `node-fetch` v3). This may affect you if you are sending request bodies of type FormData. ## Upgrading node-fetch-cache v3 -> v4 -The v4 version of node-fetch-cache has several breaking changes and new features. +The v4 version of `node-fetch-cache` has several breaking changes and new features. ### Node.js v14.14.0 is now the lowest supported Node.js version diff --git a/package-lock.json b/package-lock.json index 1009f5d..6cbcbf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "cacache": "^18.0.1", - "form-data": "^4.0.0", + "formdata-node": "^6.0.3", "locko": "^1.1.0", "node-fetch": "3.3.2" }, @@ -1248,11 +1248,6 @@ "node": ">=8" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1614,17 +1609,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1695,14 +1679,6 @@ "dev": true, "peer": true }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -2161,17 +2137,13 @@ "node": ">=8.0.0" } }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, + "node_modules/formdata-node": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", + "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==", + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">= 18" } }, "node_modules/formdata-polyfill": { @@ -2710,25 +2682,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dependencies": { - "mime-db": "1.44.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4586,11 +4539,6 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -4852,14 +4800,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4906,11 +4846,6 @@ "dev": true, "peer": true }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -5255,15 +5190,10 @@ "signal-exit": "^3.0.2" } }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } + "formdata-node": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", + "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==" }, "formdata-polyfill": { "version": "4.0.10", @@ -5650,19 +5580,6 @@ "picomatch": "^2.3.1" } }, - "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" - }, - "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "requires": { - "mime-db": "1.44.0" - } - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", diff --git a/package.json b/package.json index 5a871d6..9b15c99 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ }, "dependencies": { "cacache": "^18.0.1", - "form-data": "^4.0.0", + "formdata-node": "^6.0.3", "locko": "^1.1.0", "node-fetch": "3.3.2" }, diff --git a/plugins/redis/test_redis_cache.ts b/plugins/redis/test_redis_cache.ts index 5f688af..d13a96b 100644 --- a/plugins/redis/test_redis_cache.ts +++ b/plugins/redis/test_redis_cache.ts @@ -6,7 +6,7 @@ import { fileURLToPath } from 'url'; import fs from 'fs'; import assert from 'assert'; import { Agent } from 'http'; -import FormData from 'form-data'; +import { FormData} from 'formdata-node'; import standardFetch, { Request as StandardFetchRequest } from 'node-fetch'; import FetchCache, { cacheStrategies, diff --git a/src/helpers/cache_keys.ts b/src/helpers/cache_keys.ts index 1d8eebc..287198d 100644 --- a/src/helpers/cache_keys.ts +++ b/src/helpers/cache_keys.ts @@ -3,7 +3,7 @@ import crypto from 'crypto'; import assert from 'assert'; import { Buffer } from 'buffer'; import type { Request as NodeFetchRequestType } from 'node-fetch'; -import type { FetchInit, FetchResource, FormDataInternal } from '../types.js'; +import type { FetchInit, FetchResource } from '../types.js'; import { FormData } from '../types.js'; import { getNodeFetch } from './node_fetch_imports.js'; @@ -15,20 +15,10 @@ function md5(string_: string) { function getFormDataCacheKeyJson(formData: FormData) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - const cacheKey = { ...formData } as FormDataInternal; - const boundary = formData.getBoundary(); - - delete cacheKey._boundary; - - const boundaryReplaceRegex = new RegExp(boundary, 'g'); - - cacheKey._streams = cacheKey._streams.map(s => { - if (typeof s === 'string') { - return s.replace(boundaryReplaceRegex, ''); - } - - return s; - }); + const cacheKey = { + type: 'FormData', + entries: Array.from(formData.entries()), + }; return cacheKey; } @@ -39,7 +29,7 @@ function getHeadersCacheKeyJson(headers: string[][]): string[][] { .filter(([key, value]) => key !== 'cache-control' || value !== 'only-if-cached'); } -function getBodyCacheKeyJson(body: unknown): string | FormDataInternal | undefined { +function getBodyCacheKeyJson(body: unknown): string | object | undefined { if (!body) { return undefined; } @@ -94,7 +84,7 @@ export async function calculateCacheKey(resource: FetchResource, init?: FetchIni : { url: resource, body: undefined }; const initCacheKeyJson = { - body: undefined as (undefined | string | FormDataInternal), + body: undefined as (undefined | string | object), ...init, headers: getHeadersCacheKeyJson(Object.entries(init?.headers ?? {})), }; diff --git a/src/index.ts b/src/index.ts index 285d8aa..2f52f82 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import type { Request as NodeFetchRequestType } from 'node-fetch'; -import FormData from 'form-data'; +import { FormData } from 'formdata-node'; import { getNFCResponseClass as getNFCResponseClass } from './classes/response.js'; import { MemoryCache } from './classes/caching/memory_cache.js'; import { calculateCacheKey } from './helpers/cache_keys.js'; diff --git a/src/types.ts b/src/types.ts index 33c7d7f..68d6209 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,17 +1,11 @@ -import type fs from 'fs'; import type { Response as NodeFetchResponse } from 'node-fetch'; import type fetch from 'node-fetch'; -import FormData from 'form-data'; +import { FormData } from 'formdata-node'; export type FetchResource = Parameters[0]; export type FetchInit = Parameters[1]; export type CacheStrategy = (response: NodeFetchResponse) => Promise | boolean; -export type FormDataInternal = { - _boundary?: string; - _streams: Array; -} & FormData; - export { FormData }; export type NFCResponseMetadata = { diff --git a/test/tests.ts b/test/tests.ts index ecda250..23b778f 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -7,7 +7,7 @@ import fs from 'fs'; import assert from 'assert'; import { Agent } from 'http'; import { rimraf } from 'rimraf'; -import FormData from 'form-data'; +import { FormData } from 'formdata-node'; import standardFetch, { Request as StandardFetchRequest } from 'node-fetch'; import FetchCache, { MemoryCache, From a6f24198f9d59679a6e8ba5ed39f8b9314312569 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:16:44 -0400 Subject: [PATCH 15/27] stop testing on node v14 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51085c6..241ff66 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x, 18.x, 22.x] + node-version: [16.x, 18.x, 22.x] services: httpbin: From 8dc8a53a0ad3241f0ee5796335f7d258262c39de Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:19:06 -0400 Subject: [PATCH 16/27] run tests on node 18 and up only --- .github/workflows/ci.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 241ff66..6e0ba13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: strategy: matrix: - node-version: [16.x, 18.x, 22.x] + node-version: [18.18.0, 18.x, 22.x] services: httpbin: diff --git a/README.md b/README.md index c7ad3de..a2b13c7 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,7 @@ node-fetch-cache will support: * All non-EOL LTS Node.js versions * In addition, as far back as is technically easy -Currently the oldest supported Node.js version is v14.14.0, which adds `fs.rmSync()` which is used by a dependency. +Currently the oldest supported Node.js version is v18.18.0. Automated tests will be run on the current Node.js version, the oldest supported Node.js version, and the latest release of all even-numbered Node.js versions between those two. From 45ff15af36914b4e15bfc81e14f5463f995d2f59 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:23:17 -0400 Subject: [PATCH 17/27] npm link node-fetch-cache into the redis plugin for tests --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e0ba13..f3ea83e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,8 @@ jobs: - run: npm ci - run: npm run tsc - run: npm run buildcjs + - run: npm link + - run: npm link node-fetch-cache --prefix plugins/redis - run: npm run coverage - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 @@ -59,6 +61,8 @@ jobs: - run: npm ci - run: npm run tsc - run: npm run buildcjs + - run: npm link + - run: npm link node-fetch-cache --prefix plugins/redis - name: Use Node.js Version Under Test uses: actions/setup-node@v1 with: From 8e94379d1edf9c2a1fe29df326d4c20e68b654cd Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:23:58 -0400 Subject: [PATCH 18/27] update upgrade guide --- docs/upgrade_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/upgrade_guide.md b/docs/upgrade_guide.md index 44659e2..194786f 100644 --- a/docs/upgrade_guide.md +++ b/docs/upgrade_guide.md @@ -6,7 +6,7 @@ The v5 version of `node-fetch-cache` upgrades `node-fetch` from v2 to v3. Please consult the [node-fetch v2 -> v3 upgrade guide](https://github.com/node-fetch/node-fetch/blob/main/docs/v3-UPGRADE-GUIDE.md) and follow the instructions there, except regarding the following: -1. The minimum supported node version for `node-fetch-cache` is v16.0.0 +1. The minimum supported node version for `node-fetch-cache` is v18.18.0 2. Unlike `node-fetch` v3, `node-fetch-cache` v5 still supports CommonJS. In addition, `node-fetch-cache` specifics have changed in the following breaking ways, which will affect a minority of use cases: From 2d23f69114c9358bb91c2dadada7aa15bcfdf749 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:26:10 -0400 Subject: [PATCH 19/27] update upgrade guide --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3ea83e..2d094b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,8 @@ jobs: - run: npm run tsc - run: npm run buildcjs - run: npm link - - run: npm link node-fetch-cache --prefix plugins/redis + - run: npm link node-fetch-cache + working-directory: plugins/redis - run: npm run coverage - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 @@ -62,7 +63,8 @@ jobs: - run: npm run tsc - run: npm run buildcjs - run: npm link - - run: npm link node-fetch-cache --prefix plugins/redis + - run: npm link node-fetch-cache + working-directory: plugins/redis - name: Use Node.js Version Under Test uses: actions/setup-node@v1 with: From 3c2a6146b6f5bd64deed8acc13b4ce1e2c1be51c Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:29:20 -0400 Subject: [PATCH 20/27] try to fix flaky test --- plugins/redis/test_redis_cache.ts | 4 ++-- test/tests.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/redis/test_redis_cache.ts b/plugins/redis/test_redis_cache.ts index d13a96b..78905a4 100644 --- a/plugins/redis/test_redis_cache.ts +++ b/plugins/redis/test_redis_cache.ts @@ -558,9 +558,9 @@ describe('REDIS Plugin Tests', function() { ); // Since our bogus synchronization strategy doesn't actually synchronize, - // at least five responses should be cache misses (this depends on random + // at least two responses should be cache misses (this depends on random // timing and might be a little flaky). - assert(responses.filter(response => !response.returnedFromCache).length > 5); + assert(responses.filter(response => !response.returnedFromCache).length > 1); }); it('Can stream a hundred thousand bytes to a file in ten chunks', async () => { diff --git a/test/tests.ts b/test/tests.ts index 23b778f..b07a1f0 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -526,9 +526,9 @@ describe('Data tests', () => { ); // Since our bogus synchronization strategy doesn't actually synchronize, - // at least five responses should be cache misses (this depends on random + // at least two responses should be cache misses (this depends on random // timing and might be a little flaky). - assert(responses.filter(response => !response.returnedFromCache).length > 5); + assert(responses.filter(response => !response.returnedFromCache).length > 1); }); it('Can stream a hundred thousand bytes to a file in ten chunks', async () => { From a2ddb12f93891871cb720e257cc32d60c2e7f31a Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:33:07 -0400 Subject: [PATCH 21/27] try to fix flaky test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d094b1..90c340e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: strategy: matrix: - node-version: [18.18.0, 18.x, 22.x] + node-version: [18.18.0, 22.x] services: httpbin: From 13498898af26257ddf971af848eae3214a1ff4ca Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:33:26 -0400 Subject: [PATCH 22/27] try to fix flaky test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90c340e..2d094b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: strategy: matrix: - node-version: [18.18.0, 22.x] + node-version: [18.18.0, 18.x, 22.x] services: httpbin: From a00b1ffe3a91b24ca6f166cc256c875b550abefd Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:34:48 -0400 Subject: [PATCH 23/27] try to fix flaky test --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d094b1..5182075 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,10 +54,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 20.x + - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: - node-version: 20.x + node-version: ${{ matrix.node-version }} - run: npm ci --prefix plugins/redis - run: npm ci - run: npm run tsc From 3125eb3a1eeda1cac7ed116fbb27ed672da3f952 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 10:59:13 -0400 Subject: [PATCH 24/27] lowest supported version to 18.19.0 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/upgrade_guide.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5182075..2a596f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: strategy: matrix: - node-version: [18.18.0, 18.x, 22.x] + node-version: [18.19.0, 18.x, 22.x] services: httpbin: diff --git a/README.md b/README.md index a2b13c7..e5f498a 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,7 @@ node-fetch-cache will support: * All non-EOL LTS Node.js versions * In addition, as far back as is technically easy -Currently the oldest supported Node.js version is v18.18.0. +Currently the oldest supported Node.js version is v18.19.0. Automated tests will be run on the current Node.js version, the oldest supported Node.js version, and the latest release of all even-numbered Node.js versions between those two. diff --git a/docs/upgrade_guide.md b/docs/upgrade_guide.md index 194786f..50b8d77 100644 --- a/docs/upgrade_guide.md +++ b/docs/upgrade_guide.md @@ -6,7 +6,7 @@ The v5 version of `node-fetch-cache` upgrades `node-fetch` from v2 to v3. Please consult the [node-fetch v2 -> v3 upgrade guide](https://github.com/node-fetch/node-fetch/blob/main/docs/v3-UPGRADE-GUIDE.md) and follow the instructions there, except regarding the following: -1. The minimum supported node version for `node-fetch-cache` is v18.18.0 +1. The minimum supported node version for `node-fetch-cache` is v18.19.0 2. Unlike `node-fetch` v3, `node-fetch-cache` v5 still supports CommonJS. In addition, `node-fetch-cache` specifics have changed in the following breaking ways, which will affect a minority of use cases: From 385b756497b2e12a22a5fc04ee1e3bf82d277b38 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 11:06:16 -0400 Subject: [PATCH 25/27] increase TS target --- package.json | 2 +- plugins/redis/test_redis_cache.ts | 2 +- tsconfig.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 9b15c99..613d0bf 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,6 @@ } }, "engines": { - "node": ">=16.0.0" + "node": ">=18.19.0" } } diff --git a/plugins/redis/test_redis_cache.ts b/plugins/redis/test_redis_cache.ts index 78905a4..f0dd8b1 100644 --- a/plugins/redis/test_redis_cache.ts +++ b/plugins/redis/test_redis_cache.ts @@ -6,7 +6,7 @@ import { fileURLToPath } from 'url'; import fs from 'fs'; import assert from 'assert'; import { Agent } from 'http'; -import { FormData} from 'formdata-node'; +import { FormData } from 'formdata-node'; import standardFetch, { Request as StandardFetchRequest } from 'node-fetch'; import FetchCache, { cacheStrategies, diff --git a/tsconfig.json b/tsconfig.json index 6809003..d74dbf7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "ES2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ From dd50ad615957b91cd36aef6da2b3f9ed278f9160 Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 11:13:07 -0400 Subject: [PATCH 26/27] default null body to empty stream --- src/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2f52f82..cfc03ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import type { Request as NodeFetchRequestType } from 'node-fetch'; +import { Readable } from 'stream'; import { FormData } from 'formdata-node'; import { getNFCResponseClass as getNFCResponseClass } from './classes/response.js'; import { MemoryCache } from './classes/caching/memory_cache.js'; @@ -94,7 +95,7 @@ async function getResponse( if (shouldCache) { const cacheSetResult = await fetchCustomization.cache.set( cacheKey, - bodyStream!, + bodyStream ?? Readable.from(Buffer.alloc(0)), serializedMeta, ); @@ -102,7 +103,7 @@ async function getResponse( } return new NFCResponse( - bodyStream!, + bodyStream ?? Readable.from(Buffer.alloc(0)), serializedMeta, ejectSelfFromCache, false, From 4fc7f6ad98cc9d391d54f50b937082e5d56b3d3c Mon Sep 17 00:00:00 2001 From: mistval Date: Sat, 17 Aug 2024 11:20:30 -0400 Subject: [PATCH 27/27] empty commit