From d14de795f03f1c48072f2131d26bca3f45828a9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 29 Mar 2025 18:11:04 -0500 Subject: [PATCH 01/52] chore(deps): bump ossf/scorecard-action from 2.3.1 to 2.4.1 (#40) --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a51340d..06f452b 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -35,7 +35,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: results_file: results.sarif results_format: sarif From 8d8ceb6e9573afa42634991f50294c0ccd057fae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 29 Mar 2025 18:11:47 -0500 Subject: [PATCH 02/52] chore(deps): bump actions/upload-artifact from 4.3.1 to 4.6.2 (#36) --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 06f452b..974d640 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -57,7 +57,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: SARIF file path: results.sarif From 48fc7e0d5634d368bb7b1c681ae4ae9d92352f89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:30:44 -0500 Subject: [PATCH 03/52] chore(deps): bump github/codeql-action from 2.23.2 to 3.28.13 (#41) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.23.2 to 3.28.13. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2.23.2...1b549b9259bda1cb5ddde3b41741a82a2d15a841) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b48ce9e..20040de 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/init@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/analyze@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 974d640..3bd13c5 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,6 +65,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@2f93e4319b2f04a2efc38fa7f78bd681bc3f7b2f # v2.23.2 + uses: github/codeql-action/upload-sarif@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 with: sarif_file: results.sarif \ No newline at end of file From 0905c70dc54b5a31880118bd607b4b62beee1c38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:30:42 -0500 Subject: [PATCH 04/52] chore(deps-dev): bump ts-jest from 29.2.5 to 29.3.1 (#46) --- package-lock.json | 34 ++++++++++++++++++++++++---------- package.json | 2 +- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 834e48b..d7191b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@expressjs/codemod", - "version": "0.0.1", + "version": "0.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@expressjs/codemod", - "version": "0.0.1", + "version": "0.0.4", "license": "MIT", "dependencies": { "commander": "^12.1.0", @@ -25,7 +25,7 @@ "@types/node": "^22.8.1", "@types/prompts": "2.4.9", "jest": "29.7.0", - "ts-jest": "29.2.5", + "ts-jest": "29.3.1", "typescript": "5.6.3" }, "engines": { @@ -4512,9 +4512,9 @@ } }, "node_modules/ts-jest": { - "version": "29.2.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", - "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.1.tgz", + "integrity": "sha512-FT2PIRtZABwl6+ZCry8IY7JZ3xMuppsEV9qFVHOVe8jDzggwUZ9TsM4chyJxL9yi6LvkqcZYU3LmapEE454zBQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4525,7 +4525,8 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.6.3", + "semver": "^7.7.1", + "type-fest": "^4.38.0", "yargs-parser": "^21.1.1" }, "bin": { @@ -4561,9 +4562,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { @@ -4573,6 +4574,19 @@ "node": ">=10" } }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.0.tgz", + "integrity": "sha512-w2IGJU1tIgcrepg9ZJ82d8UmItNQtOFJG0HCUE3SzMokKkTsruVDALl2fAdiEzJlfduoU+VyXJWIIUZ+6jV+nw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", diff --git a/package.json b/package.json index 5a19c72..7c3fe7b 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@types/node": "^22.8.1", "@types/prompts": "2.4.9", "jest": "29.7.0", - "ts-jest": "29.2.5", + "ts-jest": "29.3.1", "typescript": "5.6.3" }, "engines": { From 543b9e2162a7231bbfa0bba68d073d8e0c45ab59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:33:45 -0500 Subject: [PATCH 05/52] chore(deps-dev): bump typescript from 5.6.3 to 5.8.2 (#38) --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d7191b8..6d8c50e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", - "typescript": "5.6.3" + "typescript": "5.8.2" }, "engines": { "node": ">=18" @@ -4617,9 +4617,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 7c3fe7b..0e633ae 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", - "typescript": "5.6.3" + "typescript": "5.8.2" }, "engines": { "node": ">=18" From 489f8fd47e5e03a57bd6e621f4efd0795fb673ab Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sat, 5 Apr 2025 09:58:22 -0500 Subject: [PATCH 06/52] set version strategy to increase - dependabot (#48) --- .github/dependabot.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a6096a4..a17d7dc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,6 +7,7 @@ updates: - package-ecosystem: npm directory: / + versioning-strategy: increase schedule: interval: monthly time: "23:00" @@ -14,4 +15,4 @@ updates: open-pull-requests-limit: 10 ignore: - dependency-name: "*" - update-types: ["version-update:semver-major"] \ No newline at end of file + update-types: ["version-update:semver-major"] From b530005851f8bcce0c5443fee5aa6775adafc887 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 6 Apr 2025 14:28:00 -0500 Subject: [PATCH 07/52] chore(deps-dev): bump typescript from 5.8.2 to 5.8.3 (#50) Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.8.2 to 5.8.3. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml) - [Commits](https://github.com/microsoft/TypeScript/commits) --- updated-dependencies: - dependency-name: typescript dependency-version: 5.8.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d8c50e..66c9a07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", - "typescript": "5.8.2" + "typescript": "5.8.3" }, "engines": { "node": ">=18" @@ -4617,9 +4617,9 @@ } }, "node_modules/typescript": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 0e633ae..9d24846 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", - "typescript": "5.8.2" + "typescript": "5.8.3" }, "engines": { "node": ">=18" From a48901e3895ab88958aa095be7d11e072028ce7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 6 Apr 2025 14:32:19 -0500 Subject: [PATCH 08/52] chore(deps-dev): bump @types/node from 22.10.1 to 22.14.0 (#51) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.1 to 22.14.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.14.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 66c9a07..b5a7917 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.8.1", + "@types/node": "^22.14.0", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", @@ -1515,13 +1515,13 @@ } }, "node_modules/@types/node": { - "version": "22.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", - "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "version": "22.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", + "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.20.0" + "undici-types": "~6.21.0" } }, "node_modules/@types/prompts": { @@ -4631,9 +4631,9 @@ } }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index 9d24846..0da9b61 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.8.1", + "@types/node": "^22.14.0", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", From dae760bd8b842d3afe235d70cf4a5c18817ce6df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Sun, 18 May 2025 17:25:23 +0200 Subject: [PATCH 09/52] ci: harden GH Actions (#55) Co-authored-by: StepSecurity Bot --- .github/workflows/ci.yml | 3 +++ .github/workflows/generate-readme.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d15384..0d8bd8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,9 @@ concurrency: group: "${{ github.workflow }} ✨ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" cancel-in-progress: true +permissions: + contents: read + jobs: lint: name: Lint diff --git a/.github/workflows/generate-readme.yml b/.github/workflows/generate-readme.yml index 4a09bfb..b2c8414 100644 --- a/.github/workflows/generate-readme.yml +++ b/.github/workflows/generate-readme.yml @@ -9,6 +9,9 @@ on: - index.ts - config.ts +permissions: + contents: read + jobs: generate-readme: runs-on: ubuntu-latest From 56ceeb2e80f8ac77f3036b8b7aa07bb735f030c8 Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Sun, 1 Jun 2025 20:18:54 +0200 Subject: [PATCH 10/52] fix: conversion of LF to CRLF (#56) * fix: conversion of LF to CRLF * fix lint error Signed-off-by: Sebastian Beltran * Add test for EOL detection * lint * fix lint Signed-off-by: Sebastian Beltran --------- Signed-off-by: Sebastian Beltran Co-authored-by: Sebastian Beltran --- transforms/magic-redirect.ts | 3 +- transforms/pluralized-methods.ts | 3 +- transforms/req-param.ts | 3 +- transforms/v4-deprecated-signatures.ts | 3 +- utils/__test__/recastOptions.spec.ts | 68 ++++++++++++++++++++++++++ utils/recastOptions.ts | 17 +++++++ 6 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 utils/__test__/recastOptions.spec.ts create mode 100644 utils/recastOptions.ts diff --git a/transforms/magic-redirect.ts b/transforms/magic-redirect.ts index 0463158..7333352 100644 --- a/transforms/magic-redirect.ts +++ b/transforms/magic-redirect.ts @@ -10,6 +10,7 @@ import { memberExpression, } from 'jscodeshift' import { getParsedFile } from '../utils/parse' +import { getOptions } from '../utils/recastOptions' import { recursiveParent } from '../utils/recursiveParent' const unifiedMagicString = (path: ASTPath, projectRequestName: string) => { @@ -51,5 +52,5 @@ export default function transformer(file: FileInfo, _api: API) { }) .map((path) => unifiedMagicString(path, recursiveParent(path.parentPath) || 'req')) - return parsedFile.toSource() + return parsedFile.toSource(getOptions(file.source)) } diff --git a/transforms/pluralized-methods.ts b/transforms/pluralized-methods.ts index e2ed072..14a295b 100644 --- a/transforms/pluralized-methods.ts +++ b/transforms/pluralized-methods.ts @@ -1,6 +1,7 @@ import type { API, FileInfo } from 'jscodeshift' import { Identifier, identifier } from 'jscodeshift' import { getParsedFile } from '../utils/parse' +import { getOptions } from '../utils/recastOptions' export default function transformer(file: FileInfo, _api: API): string { const parsedFile = getParsedFile(file) @@ -17,5 +18,5 @@ export default function transformer(file: FileInfo, _api: API): string { .replaceWith(() => identifier(plural)) } - return parsedFile.toSource() + return parsedFile.toSource(getOptions(file.source)) } diff --git a/transforms/req-param.ts b/transforms/req-param.ts index 2eb9d72..96d52ae 100644 --- a/transforms/req-param.ts +++ b/transforms/req-param.ts @@ -1,5 +1,6 @@ import type { API, FileInfo } from 'jscodeshift' import { CallExpression, identifier, memberExpression, withParser } from 'jscodeshift' +import { getOptions } from '../utils/recastOptions' import { recursiveParent } from '../utils/recursiveParent' export default function transformer(file: FileInfo, _api: API): string { @@ -40,5 +41,5 @@ export default function transformer(file: FileInfo, _api: API): string { return path }) - .toSource() + .toSource(getOptions(file.source)) } diff --git a/transforms/v4-deprecated-signatures.ts b/transforms/v4-deprecated-signatures.ts index 5800729..842b22c 100644 --- a/transforms/v4-deprecated-signatures.ts +++ b/transforms/v4-deprecated-signatures.ts @@ -1,5 +1,6 @@ import type { API, ASTPath, FileInfo } from 'jscodeshift' import { CallExpression, callExpression, identifier, memberExpression, withParser } from 'jscodeshift' +import { getOptions } from '../utils/recastOptions' import { recursiveParent } from '../utils/recursiveParent' const separateStatusAndBody = (path: ASTPath, calleePropertyName: string) => { @@ -153,5 +154,5 @@ export default function transformer(file: FileInfo, _api: API): string { return path }) - return parsedFile.toSource() + return parsedFile.toSource(getOptions(file.source)) } diff --git a/utils/__test__/recastOptions.spec.ts b/utils/__test__/recastOptions.spec.ts new file mode 100644 index 0000000..7047b87 --- /dev/null +++ b/utils/__test__/recastOptions.spec.ts @@ -0,0 +1,68 @@ +import { getOptions } from '../recastOptions' + +describe('recastOptions', () => { + describe('getOptions', () => { + it('should return Unix line terminator for code with only LF', () => { + const code = 'const a = 1\nconst b = 2\n' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\n' }) + }) + + it('should return Windows line terminator for code with only CRLF', () => { + const code = 'const a = 1\r\nconst b = 2\r\n' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\r\n' }) + }) + + it('should return Unix line terminator for code with mixed line terminators', () => { + const code = 'const a = 1\r\nconst b = 2\nconst c = 3\r\n' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\n' }) + }) + + it('should return Unix line terminator for code with no line terminators', () => { + const code = 'const a = 1' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\n' }) + }) + + it('should return Unix line terminator for empty string', () => { + const code = '' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\n' }) + }) + + it('should handle code with LF at beginning after CR', () => { + const code = '\r\nconst a = 1\nconst b = 2' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\n' }) + }) + + it('should handle single CRLF without other line breaks', () => { + const code = 'const a = 1\r\nconst b = 2' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\r\n' }) + }) + + it('should handle multiple CRLF without LF', () => { + const code = 'line1\r\nline2\r\nline3\r\n' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\r\n' }) + }) + + it('should detect LF even when preceded by CR in different context', () => { + const code = 'const str = "\\r"\nconst a = 1\r\n' + const result = getOptions(code) + + expect(result).toEqual({ lineTerminator: '\n' }) + }) + }) +}) diff --git a/utils/recastOptions.ts b/utils/recastOptions.ts new file mode 100644 index 0000000..f0c9130 --- /dev/null +++ b/utils/recastOptions.ts @@ -0,0 +1,17 @@ +/** + * By default, jscodeshift(recast) uses the line terminator of the OS the code runs on. + * This is often not desired, so we instead try to detect it from the input. + * If there is at least one Windows-style linebreak (CRLF) in the input and + * no Unix-style linebreak (LF), use that. In all other cases, use Unix-style (LF). + * @return '\n' or '\r\n' + */ +export function getOptions(code: string) { + return { lineTerminator: detectLineTerminator(code) } +} + +function detectLineTerminator(code: string) { + const hasCRLF = /\r\n/.test(code) + const hasLF = /[^\r]\n/.test(code) + + return hasCRLF && !hasLF ? '\r\n' : '\n' +} From b9a8c569b4ba94cefdc8f3ec956e3547cc976d1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:21:40 -0500 Subject: [PATCH 11/52] chore(deps-dev): bump @types/node from 22.14.0 to 22.15.3 (#53) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.14.0 to 22.15.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.15.3 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b5a7917..97cd784 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.14.0", + "@types/node": "^22.15.3", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", @@ -1515,9 +1515,9 @@ } }, "node_modules/@types/node": { - "version": "22.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", - "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==", + "version": "22.15.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", + "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 0da9b61..968a719 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.14.0", + "@types/node": "^22.15.3", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.1", From 0244f9a5767742670279054d05b194f2023e2c0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jun 2025 13:23:49 -0500 Subject: [PATCH 12/52] chore(deps-dev): bump ts-jest from 29.3.1 to 29.3.2 (#54) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.3.1 to 29.3.2. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.3.1...v29.3.2) --- updated-dependencies: - dependency-name: ts-jest dependency-version: 29.3.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 97cd784..89ad7dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@types/node": "^22.15.3", "@types/prompts": "2.4.9", "jest": "29.7.0", - "ts-jest": "29.3.1", + "ts-jest": "29.3.4", "typescript": "5.8.3" }, "engines": { @@ -4512,9 +4512,9 @@ } }, "node_modules/ts-jest": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.1.tgz", - "integrity": "sha512-FT2PIRtZABwl6+ZCry8IY7JZ3xMuppsEV9qFVHOVe8jDzggwUZ9TsM4chyJxL9yi6LvkqcZYU3LmapEE454zBQ==", + "version": "29.3.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.4.tgz", + "integrity": "sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==", "dev": true, "license": "MIT", "dependencies": { @@ -4525,8 +4525,8 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.1", - "type-fest": "^4.38.0", + "semver": "^7.7.2", + "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, "bin": { @@ -4562,9 +4562,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, "license": "ISC", "bin": { @@ -4575,9 +4575,9 @@ } }, "node_modules/ts-jest/node_modules/type-fest": { - "version": "4.39.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.0.tgz", - "integrity": "sha512-w2IGJU1tIgcrepg9ZJ82d8UmItNQtOFJG0HCUE3SzMokKkTsruVDALl2fAdiEzJlfduoU+VyXJWIIUZ+6jV+nw==", + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { diff --git a/package.json b/package.json index 968a719..043f14f 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@types/node": "^22.15.3", "@types/prompts": "2.4.9", "jest": "29.7.0", - "ts-jest": "29.3.1", + "ts-jest": "29.3.4", "typescript": "5.8.3" }, "engines": { From df7e3b3c6c736225e88a99d86931224149f52fd9 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sun, 1 Jun 2025 16:20:42 -0500 Subject: [PATCH 13/52] release: 0.0.5 (#59) Signed-off-by: Sebastian Beltran --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 043f14f..0ed9599 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@expressjs/codemod", - "version": "0.0.4", + "version": "0.0.5", "description": "Codemods for updating express servers.", "contributors": ["Sebastian Beltran ", "Filip Kudla "], "license": "MIT", From 02fa472bf2d05652ee0ff5e97123e143f734247e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 17:20:31 -0500 Subject: [PATCH 14/52] chore(deps-dev): bump @types/node from 22.15.3 to 22.15.29 (#60) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.3 to 22.15.29. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.15.29 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 89ad7dd..dc492f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@expressjs/codemod", - "version": "0.0.4", + "version": "0.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@expressjs/codemod", - "version": "0.0.4", + "version": "0.0.5", "license": "MIT", "dependencies": { "commander": "^12.1.0", @@ -22,7 +22,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.15.3", + "@types/node": "^22.15.29", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.4", @@ -1515,9 +1515,9 @@ } }, "node_modules/@types/node": { - "version": "22.15.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.3.tgz", - "integrity": "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw==", + "version": "22.15.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.29.tgz", + "integrity": "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 0ed9599..3baf921 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.15.3", + "@types/node": "^22.15.29", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.4", From 09cfedaa179dea18b4c55aa9de34b23147c95f2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 17:20:46 -0500 Subject: [PATCH 15/52] chore(deps): bump ossf/scorecard-action from 2.4.1 to 2.4.2 (#58) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.1 to 2.4.2. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/f49aabe0b5af0936a0987cfb85d86b75731b0186...05b42c624433fc40578a4040d5cf5e36ddca8cde) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-version: 2.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3bd13c5..20dc111 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -35,7 +35,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 + uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 with: results_file: results.sarif results_format: sarif From fc6c1a70448fbcaec807b933e6cdc646e1a877e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 17:20:53 -0500 Subject: [PATCH 16/52] chore(deps): bump github/codeql-action from 3.28.13 to 3.28.18 (#57) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.13 to 3.28.18. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/1b549b9259bda1cb5ddde3b41741a82a2d15a841...ff0a06e83cb2de871e5a09832bc6a81e7276941f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 3.28.18 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 20040de..72817ba 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 + uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 + uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 20dc111..870aaff 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,6 +65,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@1b549b9259bda1cb5ddde3b41741a82a2d15a841 # v3.28.13 + uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 with: sarif_file: results.sarif \ No newline at end of file From 1c27679d7a3b41df497b181a85ecf5555deff2f7 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Wed, 23 Jul 2025 07:26:53 -0500 Subject: [PATCH 17/52] chore: add funding to package.json (#64) --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 3baf921..5c1c94a 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,10 @@ "type": "git", "url": "git+https://github.com/expressjs/codemod.git" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + }, "keywords": ["codemods", "express"], "files": ["build"], "scripts": { From 409866c64206ea65f854dbb966334de3a18fd7b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Nov 2025 10:51:32 +0100 Subject: [PATCH 18/52] chore(deps): bump github/codeql-action from 3.28.18 to 4.31.2 (#78) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 72817ba..1db6a7f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 870aaff..9288142 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,6 +65,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 + uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 with: sarif_file: results.sarif \ No newline at end of file From 46e7fc5d33b789a354f3ce7ea30eaf719601cf31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Nov 2025 10:52:24 +0100 Subject: [PATCH 19/52] chore(deps): bump actions/setup-node from 4 to 6 (#77) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/generate-readme.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d8bd8b..27537c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Node.js {{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 'lts/*' @@ -54,7 +54,7 @@ jobs: persist-credentials: false - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/generate-readme.yml b/.github/workflows/generate-readme.yml index b2c8414..68ffa7e 100644 --- a/.github/workflows/generate-readme.yml +++ b/.github/workflows/generate-readme.yml @@ -23,7 +23,7 @@ jobs: with: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: '22' From f6fcd0d3e24c4209c1f64c0c3d0875f3b9a45767 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Fri, 7 Nov 2025 18:53:52 -0500 Subject: [PATCH 20/52] ci: publish to codemod (#76) Signed-off-by: Sebastian Beltran --- .github/workflows/publish.yml | 127 ++++++++++++++++++++++++++++++++++ recipes/.gitkeep | 0 2 files changed, 127 insertions(+) create mode 100644 .github/workflows/publish.yml create mode 100644 recipes/.gitkeep diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..88353f7 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,127 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +# For more information see: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow + +name: Publish Codemod + +on: + push: + tags: + - "v*@*" # eg: v1.0.0@codemod-name + workflow_dispatch: + inputs: + tag: + description: "Tag to publish (format: v1.0.0@codemod-name)" + required: true + type: string + +jobs: + validate-and-publish: + name: Validate and Publish Codemod + environment: publish + runs-on: ubuntu-latest + + outputs: + version: ${{ steps.parse-tag.outputs.version }} + codemod-name: ${{ steps.parse-tag.outputs.codemod-name }} + codemod-path: ${{ steps.parse-tag.outputs.codemod-path }} + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + + - name: Parse tag and extract metadata + id: parse-tag + env: + EVENT_NAME: ${{ github.event_name }} + INPUT_TAG: ${{ github.event.inputs.tag }} + GITHUB_REF: ${{ github.ref }} + run: | + # Determine the tag based on trigger type + if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then + TAG="$INPUT_TAG" + echo "Using manually provided tag: $TAG" + else + TAG="${GITHUB_REF#refs/tags/}" + echo "Using pushed tag: $TAG" + fi + + # Validate tag format + if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+@[a-zA-Z0-9_-]+$ ]]; then + echo "❌ Invalid tag format: $TAG" + echo "Expected format: v1.0.0@codemod-name" + exit 1 + fi + + # Extract components + VERSION="${TAG%@*}" # Everything before @ + VERSION="${VERSION#v}" # Remove v prefix + CODEMOD_NAME="${TAG#*@}" # Everything after @ + CODEMOD_PATH="recipes/$CODEMOD_NAME" + + # Set outputs + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "codemod-name=$CODEMOD_NAME" >> $GITHUB_OUTPUT + echo "codemod-path=$CODEMOD_PATH" >> $GITHUB_OUTPUT + + - name: Verify codemod directory + env: + CODEMOD_PATH: ${{ steps.parse-tag.outputs.codemod-path }} + run: | + if [[ ! -d "$CODEMOD_PATH" ]]; then + echo "❌ Codemod directory not found: $CODEMOD_PATH" + echo "Available directories in recipes/:" + ls -lah recipes/ || echo "No recipes directory found" + exit 1 + fi + + echo "✓ Found codemod directory: $CODEMOD_PATH" + echo "Directory contents:" + ls -lah "$CODEMOD_PATH" + + - name: Setup Node.js environment + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + cache: npm + cache-dependency-path: package-lock.json + + # We don't use dev dependencies + # But we need npm to put local workspace in `node_modules` + # so codemod can bundle workspaces in the codemod tarball correctly + - name: Install project dependencies + run: npm ci + + # Run test before login to not waste time if it fails + - name: Run codemod Tests + working-directory: ${{ steps.parse-tag.outputs.codemod-path }} + run: node --run test + + - name: Authenticate with Codemod registry + env: + CODEMOD_TOKEN: ${{ secrets.CODEMOD_TOKEN }} + run: npx codemod login --api-key "$CODEMOD_TOKEN" + + - name: Publish codemod + working-directory: ${{ steps.parse-tag.outputs.codemod-path }} + run: npx codemod publish + + - name: Create release summary + env: + CODEMOD_NAME: ${{ steps.parse-tag.outputs.codemod-name }} + VERSION: ${{ steps.parse-tag.outputs.version }} + TAG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref_name }} + TRIGGER: ${{ github.event_name == 'workflow_dispatch' && 'Manual' || 'Tag Push' }} + ACTOR: ${{ github.triggering_actor }} + run: | + cat >> $GITHUB_STEP_SUMMARY << EOF + # 🚀 Codemod Publication Summary + + **Codemod:** \`$CODEMOD_NAME\` + **Version:** \`$VERSION\` + **Tag:** \`$TAG\` + **Trigger:** $TRIGGER by $ACTOR + + ✅ Codemod has been successfully published to the registry! + EOF \ No newline at end of file diff --git a/recipes/.gitkeep b/recipes/.gitkeep new file mode 100644 index 0000000..e69de29 From 31602e27934582bb4ed3f0096c2006b660914f1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:50:35 +0100 Subject: [PATCH 21/52] chore(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 (#88) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 9288142..3ce1639 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -57,7 +57,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: SARIF file path: results.sarif From 798ec7e0db915cdcfee502791db5d6cc5515c92d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Dec 2025 13:02:24 -0500 Subject: [PATCH 22/52] chore(deps): bump actions/checkout from 4 to 6 (#86) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: bjohansebas <103585995+bjohansebas@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql.yml | 2 +- .github/workflows/generate-readme.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27537c1..f0f8f4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js {{ matrix.node-version }} uses: actions/setup-node@v6 with: @@ -49,7 +49,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1db6a7f..c0ba433 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/generate-readme.yml b/.github/workflows/generate-readme.yml index 68ffa7e..d2037f4 100644 --- a/.github/workflows/generate-readme.yml +++ b/.github/workflows/generate-readme.yml @@ -19,7 +19,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Setup Node.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 88353f7..2836a63 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: fetch-depth: 0 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3ce1639..b114d8d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -30,7 +30,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.1.2 with: persist-credentials: false From 69a6e9a98923a44c720c198f07912c04b510d8be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Dec 2025 14:44:39 -0500 Subject: [PATCH 23/52] chore(deps): bump actions/setup-node from 5.0.0 to 6.0.0 (#85) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5.0.0 to 6.0.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/generate-readme.yml | 2 +- .github/workflows/publish.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0f8f4c..563fbce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Setup Node.js {{ matrix.node-version }} - uses: actions/setup-node@v6 + uses: actions/setup-node@v6.1.0 with: node-version: 'lts/*' @@ -54,7 +54,7 @@ jobs: persist-credentials: false - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v6 + uses: actions/setup-node@v6.1.0 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/generate-readme.yml b/.github/workflows/generate-readme.yml index d2037f4..bb7c3fd 100644 --- a/.github/workflows/generate-readme.yml +++ b/.github/workflows/generate-readme.yml @@ -23,7 +23,7 @@ jobs: with: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v6 + uses: actions/setup-node@v6.1.0 with: node-version: '22' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2836a63..58127bf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -82,7 +82,7 @@ jobs: ls -lah "$CODEMOD_PATH" - name: Setup Node.js environment - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 with: cache: npm cache-dependency-path: package-lock.json From 9603b62849bad7e89492ef55e80021cb29375d80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Dec 2025 14:55:55 -0500 Subject: [PATCH 24/52] chore(deps): bump ossf/scorecard-action from 2.4.2 to 2.4.3 (#69) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.2 to 2.4.3. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/05b42c624433fc40578a4040d5cf5e36ddca8cde...4eaacf0543bb3f2c246792bd56e8cdeffafb205a) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-version: 2.4.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index b114d8d..edc77a8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -35,7 +35,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif From 51a7c6551f1408c9fd7cb5493f733a04080e42d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Dec 2025 18:51:26 -0500 Subject: [PATCH 25/52] chore(deps): bump github/codeql-action from 4.31.2 to 4.31.5 (#87) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.2 to 4.31.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/0499de31b99561a6d14a36a5f662c2a54f91beee...fdbfb4d2750291e159f0156def62b853c2798ca2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.31.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: bjohansebas <103585995+bjohansebas@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c0ba433..9afb58e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index edc77a8..ad7b831 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,6 +65,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: sarif_file: results.sarif \ No newline at end of file From ba25f2f3a1fce7c48e0a6ca3c4b29a0544bcbecc Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 23 Dec 2025 21:59:57 -0500 Subject: [PATCH 26/52] feat(magic-redirect): migrate magic-redirect to codemod.com (#91) * feat(magic-redirect): migrate magic-redirect to codemod.com * fix lint * feat(tests): update test commands and add legacy test support * feat(redirect): enhance redirect handlers with additional test cases * refactor: refactor the magic-redirect-codemod (#92) * refactor: refactor the express codemod * fix lint Signed-off-by: Sebastian Beltran --------- Signed-off-by: Sebastian Beltran Co-authored-by: Sebastian Beltran * docs: improve documentation * chore: rename folder to codemods * rename codemod * fix: update workspace paths to use codemods directory * rename folder --------- Signed-off-by: Sebastian Beltran Co-authored-by: Mohamad Mohebifar --- .github/workflows/ci.yml | 9 ++- .github/workflows/publish.yml | 6 +- biome.json | 5 +- {recipes => codemods}/.gitkeep | 0 codemods/back-redirect-deprecated/README.md | 37 +++++++++++ .../back-redirect-deprecated/codemod.yaml | 24 +++++++ .../back-redirect-deprecated/package.json | 22 +++++++ .../back-redirect-deprecated/src/workflow.ts | 66 +++++++++++++++++++ .../tests/expected/location.ts | 33 ++++++++++ .../tests/expected/redirect.ts | 41 ++++++++++++ .../tests/input/location.ts | 33 ++++++++++ .../tests/input/redirect.ts | 41 ++++++++++++ .../back-redirect-deprecated/workflow.yaml | 28 ++++++++ package-lock.json | 39 +++++++++++ package.json | 8 ++- tsconfig.json | 2 +- 16 files changed, 384 insertions(+), 10 deletions(-) rename {recipes => codemods}/.gitkeep (100%) create mode 100644 codemods/back-redirect-deprecated/README.md create mode 100644 codemods/back-redirect-deprecated/codemod.yaml create mode 100644 codemods/back-redirect-deprecated/package.json create mode 100644 codemods/back-redirect-deprecated/src/workflow.ts create mode 100644 codemods/back-redirect-deprecated/tests/expected/location.ts create mode 100644 codemods/back-redirect-deprecated/tests/expected/redirect.ts create mode 100644 codemods/back-redirect-deprecated/tests/input/location.ts create mode 100644 codemods/back-redirect-deprecated/tests/input/redirect.ts create mode 100644 codemods/back-redirect-deprecated/workflow.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 563fbce..276d55a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,7 +71,12 @@ jobs: echo "Node.js version: $(node -v)" echo "NPM version: $(npm -v)" - - name: Run tests + - name: Run tests-legacy cli shell: bash run: | - npm run test:ci \ No newline at end of file + npm run test-legacy:ci + + - name: Run test + shell: bash + run: | + npm run test \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 58127bf..e91b445 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -59,7 +59,7 @@ jobs: VERSION="${TAG%@*}" # Everything before @ VERSION="${VERSION#v}" # Remove v prefix CODEMOD_NAME="${TAG#*@}" # Everything after @ - CODEMOD_PATH="recipes/$CODEMOD_NAME" + CODEMOD_PATH="codemods/$CODEMOD_NAME" # Set outputs echo "version=$VERSION" >> $GITHUB_OUTPUT @@ -72,8 +72,8 @@ jobs: run: | if [[ ! -d "$CODEMOD_PATH" ]]; then echo "❌ Codemod directory not found: $CODEMOD_PATH" - echo "Available directories in recipes/:" - ls -lah recipes/ || echo "No recipes directory found" + echo "Available directories in codemods/:" + ls -lah codemods/ || echo "No codemods directory found" exit 1 fi diff --git a/biome.json b/biome.json index 5531f5c..9aee26d 100644 --- a/biome.json +++ b/biome.json @@ -6,7 +6,7 @@ "useIgnoreFile": true }, "files": { - "ignore": ["__testfixtures__"] + "ignore": ["__testfixtures__", "tests"] }, "linter": { "enabled": true, @@ -15,6 +15,9 @@ "correctness": { "noUnusedImports": "error", "useExhaustiveDependencies": "off" + }, + "suspicious": { + "noExplicitAny": "off" } } }, diff --git a/recipes/.gitkeep b/codemods/.gitkeep similarity index 100% rename from recipes/.gitkeep rename to codemods/.gitkeep diff --git a/codemods/back-redirect-deprecated/README.md b/codemods/back-redirect-deprecated/README.md new file mode 100644 index 0000000..26892ba --- /dev/null +++ b/codemods/back-redirect-deprecated/README.md @@ -0,0 +1,37 @@ +# Migrate legacy `res.redirect('back')` and `res.location('back')` + +Migrates usage of the legacy APIs `res.redirect('back')` and `res.location('back')` +to use the recommended approach of accessing the `Referer` header directly from +the request object. Versions of Express before 5 allowed the use of the string +"back" as a shortcut to redirect to the referring page, but this has been +deprecated. + +## Example + +### Migrating `res.redirect('back')` + +The migration involves replacing instances of `res.redirect('back')` with `res.redirect(req.get('Referer') || '/')`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.redirect('back'); ++ res.redirect(req.get('Referer') || '/'); +}); +``` + +### Migrating `res.location('back')` + +The migration involves replacing instances of `res.location('back')` with `res.location(req.get('Referer') || '/')`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.location('back'); ++ res.location(req.get('Referer') || '/'); +}); +``` + +## References + +- [Migration of res.redirect('back') and res.location('back')](https://expressjs.com/en/guide/migrating-5.html#magic-redirect) diff --git a/codemods/back-redirect-deprecated/codemod.yaml b/codemods/back-redirect-deprecated/codemod.yaml new file mode 100644 index 0000000..5f606d3 --- /dev/null +++ b/codemods/back-redirect-deprecated/codemod.yaml @@ -0,0 +1,24 @@ +schema_version: "1.0" +name: "@expressjs/back-redirect-deprecated" +version: "1.0.0" +description: Migrates usage of the legacy APIs `res.redirect('back')` and `res.location('back')` to the current recommended approaches +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - redirect + - location + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/back-redirect-deprecated/package.json b/codemods/back-redirect-deprecated/package.json new file mode 100644 index 0000000..83d8feb --- /dev/null +++ b/codemods/back-redirect-deprecated/package.json @@ -0,0 +1,22 @@ +{ + "name": "@expressjs/back-redirect-deprecated", + "private": true, + "version": "1.0.0", + "description": "Migrates usage of the legacy APIs `res.redirect('back')` and `res.location('back')`.", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/back-redirect-deprecated", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/back-redirect-deprecated/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/back-redirect-deprecated/src/workflow.ts b/codemods/back-redirect-deprecated/src/workflow.ts new file mode 100644 index 0000000..1364b5c --- /dev/null +++ b/codemods/back-redirect-deprecated/src/workflow.ts @@ -0,0 +1,66 @@ +import type Js from '@codemod.com/jssg-types/src/langs/javascript' +import type { Edit, SgNode, SgRoot } from '@codemod.com/jssg-types/src/main' + +function getStringLiteralValue(node: SgNode): string | null { + if (!node.is('string')) return null + + const fragments = node.findAll({ rule: { kind: 'string_fragment' } }) + if (fragments.length !== 1) return null + return fragments[0]?.text() ?? null +} + +function findParentFunctionParameters(node: SgNode): SgNode | null { + let parent = node.parent() + while (parent) { + if (parent.is('formal_parameters')) return parent + parent = parent.parent() + } + return null +} + +async function transform(root: SgRoot): Promise { + const rootNode = root.root() + + const nodes = rootNode.findAll({ + rule: { + pattern: '$OBJ.$METHOD($ARG)', + }, + constraints: { + METHOD: { regex: '^(redirect|location)$' }, + ARG: { pattern: { context: "'back'", strictness: 'relaxed' } }, + }, + }) + + const edits: Edit[] = [] + + for (const call of nodes) { + const arg = call.getMatch('ARG') + const obj = call.getMatch('OBJ') + if (!arg || !obj) continue + + if (getStringLiteralValue(arg) !== 'back') continue + + const objDef = obj.definition({ resolveExternal: false }) + if (!objDef) continue + + const isParameter = objDef.node.matches({ + rule: { inside: { kind: 'formal_parameters', stopBy: 'end' } }, + }) + if (!isParameter) continue + + const parameters = findParentFunctionParameters(objDef.node) + if (!parameters) continue + + const firstParameter = parameters.find({ rule: { kind: 'identifier' } }) + if (!firstParameter) continue + + const requestName = firstParameter.text() + + edits.push(arg.replace(`${requestName}.get("Referrer") || "/"`)) + } + + if (edits.length === 0) return null + return rootNode.commitEdits(edits) +} + +export default transform diff --git a/codemods/back-redirect-deprecated/tests/expected/location.ts b/codemods/back-redirect-deprecated/tests/expected/location.ts new file mode 100644 index 0000000..569856e --- /dev/null +++ b/codemods/back-redirect-deprecated/tests/expected/location.ts @@ -0,0 +1,33 @@ +import express from "express"; +import { location } from "somelibrary"; + +const app = express(); + +app.get("/", function (req, res) { + res.location(req.get("Referrer") || "/"); +}); +app.get("/", (req, res) => { + res.location(req.get("Referrer") || "/"); +}); +app.get("/", (req, res) => { + res.location("testing"); +}); +app.get("/", (req, res) => { + res.location(); +}); +app.get("/articles", function (request, response) { + response.location(request.get("Referrer") || "/"); +}); +app.get("/articles", function (request, response) { + response.location("testing"); +}); +app.get("/articles", (request, response) => { + response.location(request.get("Referrer") || "/"); +}); +app.get("/articles", function (_req, _res) { + location("back"); +}); + +export function handleLocation(req, res) { + res.location(req.get("Referrer") || "/"); +} \ No newline at end of file diff --git a/codemods/back-redirect-deprecated/tests/expected/redirect.ts b/codemods/back-redirect-deprecated/tests/expected/redirect.ts new file mode 100644 index 0000000..18386c0 --- /dev/null +++ b/codemods/back-redirect-deprecated/tests/expected/redirect.ts @@ -0,0 +1,41 @@ +import express from "express"; +import { redirect } from "somelibrary"; + +const app = express(); + +app.get("/", function (req, res) { + res.redirect(req.get("Referrer") || "/"); +}); +app.get("/", (req, res) => { + res.redirect(req.get("Referrer") || "/"); +}); +app.get("/", (req, res) => { + res.redirect("testing"); +}); +app.get("/", (req, res) => { + res.redirect(); +}); +app.get("/articles", function (request, response) { + response.redirect(request.get("Referrer") || "/"); +}); +app.get("/articles", (request, response) => { + response.redirect(request.get("Referrer") || "/"); +}); +app.get("/articles", function (request, response) { + response.redirect("testing"); +}); +app.get("/articles", function (_req, _res) { + redirect("back"); +}); + +export function handler(requests, response) { + response.redirect(requests.get("Referrer") || "/"); +} + +export function handleRedirect(req: any) { + req.redirect(req.get("Referrer") || "/"); +} + +export function handlerWith(req: any, res: any) { + res.redirect(req.get("Referrer") || "/"); +} \ No newline at end of file diff --git a/codemods/back-redirect-deprecated/tests/input/location.ts b/codemods/back-redirect-deprecated/tests/input/location.ts new file mode 100644 index 0000000..0c69ddf --- /dev/null +++ b/codemods/back-redirect-deprecated/tests/input/location.ts @@ -0,0 +1,33 @@ +import express from "express"; +import { location } from "somelibrary"; + +const app = express(); + +app.get("/", function (req, res) { + res.location('back'); +}); +app.get("/", (req, res) => { + res.location("back"); +}); +app.get("/", (req, res) => { + res.location("testing"); +}); +app.get("/", (req, res) => { + res.location(); +}); +app.get("/articles", function (request, response) { + response.location("back"); +}); +app.get("/articles", function (request, response) { + response.location("testing"); +}); +app.get("/articles", (request, response) => { + response.location("back"); +}); +app.get("/articles", function (_req, _res) { + location("back"); +}); + +export function handleLocation(req, res) { + res.location('back'); +} \ No newline at end of file diff --git a/codemods/back-redirect-deprecated/tests/input/redirect.ts b/codemods/back-redirect-deprecated/tests/input/redirect.ts new file mode 100644 index 0000000..650ec7c --- /dev/null +++ b/codemods/back-redirect-deprecated/tests/input/redirect.ts @@ -0,0 +1,41 @@ +import express from "express"; +import { redirect } from "somelibrary"; + +const app = express(); + +app.get("/", function (req, res) { + res.redirect("back"); +}); +app.get("/", (req, res) => { + res.redirect("back"); +}); +app.get("/", (req, res) => { + res.redirect("testing"); +}); +app.get("/", (req, res) => { + res.redirect(); +}); +app.get("/articles", function (request, response) { + response.redirect("back"); +}); +app.get("/articles", (request, response) => { + response.redirect("back"); +}); +app.get("/articles", function (request, response) { + response.redirect("testing"); +}); +app.get("/articles", function (_req, _res) { + redirect("back"); +}); + +export function handler(requests, response) { + response.redirect('back'); +} + +export function handleRedirect(req: any) { + req.redirect('back'); +} + +export function handlerWith(req: any, res: any) { + res.redirect('back'); +} \ No newline at end of file diff --git a/codemods/back-redirect-deprecated/workflow.yaml b/codemods/back-redirect-deprecated/workflow.yaml new file mode 100644 index 0000000..15bb5c2 --- /dev/null +++ b/codemods/back-redirect-deprecated/workflow.yaml @@ -0,0 +1,28 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of the legacy APIs `res.redirect('back')` and `res.location('back')` to the current recommended approaches + js-ast-grep: + js_file: src/workflow.ts + base_path: . + semantic_analysis: file + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index dc492f1..01fc31c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "@expressjs/codemod", "version": "0.0.5", "license": "MIT", + "workspaces": [ + "./codemods/*" + ], "dependencies": { "commander": "^12.1.0", "fast-glob": "^3.3.2", @@ -30,6 +33,18 @@ }, "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "codemods/magic-redirect": { + "name": "@expressjs/back-redirect-deprecated", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" } }, "node_modules/@ampproject/remapping": { @@ -73,6 +88,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", @@ -981,6 +997,17 @@ "node": ">=14.21.3" } }, + "node_modules/@codemod.com/jssg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@codemod.com/jssg-types/-/jssg-types-1.3.1.tgz", + "integrity": "sha512-poYNa8mfr8+4+kBPc3bAKBTaUtOQdg5z3voeGGAAr0tiTBvC4cmmoY/dyHXEWT8F+p8A1tWUnhmJZ4WQXV3HVA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@expressjs/back-redirect-deprecated": { + "resolved": "codemods/magic-redirect", + "link": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1810,6 +1837,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -2923,6 +2951,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -4622,6 +4651,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4804,6 +4834,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "recipes/magic-redirect": { + "name": "@expressjs/magic-redirect", + "version": "1.0.0", + "extraneous": true, + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } } } } diff --git a/package.json b/package.json index 5c1c94a..6ea09fd 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,9 @@ "build": "tsc -d -p tsconfig.json", "lint": "biome check", "lint:fix": "biome check --fix", - "test": "jest", - "test:ci": "jest --ci", + "test": "npm run test --workspaces --if-present", + "test-legacy": "jest", + "test-legacy:ci": "jest --ci", "prepublishOnly": "npm run clean && npm run build" }, "dependencies": { @@ -46,5 +47,6 @@ }, "engines": { "node": ">=18" - } + }, + "workspaces": ["./codemods/*"] } diff --git a/tsconfig.json b/tsconfig.json index 8e54036..fbdb66a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,6 @@ "strictNullChecks": true, "outDir": "build" }, - "include": ["**/*.ts"], + "include": ["**/*.ts", "./codemods/"], "exclude": ["node_modules", "build", "**/__testfixtures__", "**/__test__", "**/*.spec.ts"] } From 54363e9d97c4ca80c50057c142b2f84ca0a7c725 Mon Sep 17 00:00:00 2001 From: Akshay Date: Wed, 24 Dec 2025 09:16:19 +0530 Subject: [PATCH 27/52] Fix broken Contributing Guide link in README (#93) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5849a89..77f28e6 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,8 @@ The Express.js project welcomes all constructive contributions. Contributions ta from code for bug fixes and enhancements, to additions and fixes to documentation, additional tests, triaging incoming pull requests and issues, and more! -See the [Contributing Guide](https://github.com/expressjs/express/blob/master/Contributing.md) for more technical details on contributing. +See the [Contributing Guide](https://github.com/expressjs/codemod/blob/main/CONTRIBUTING.md) for more technical details on contributing. + ## License From fc70381b9473113567917fa1ee67496f4b9d6a2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 22:50:19 -0500 Subject: [PATCH 28/52] chore(deps-dev): bump typescript from 5.8.3 to 5.9.3 (#73) Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.8.3 to 5.9.3. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.8.3...v5.9.3) --- updated-dependencies: - dependency-name: typescript dependency-version: 5.9.3 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 19 ++++++++++++++----- package.json | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 01fc31c..b9c0464 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.4", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "engines": { "node": ">=18" @@ -39,9 +39,18 @@ "url": "https://opencollective.com/express" } }, + "codemods/back-redirect-deprecated": { + "name": "@expressjs/back-redirect-deprecated", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "codemods/magic-redirect": { "name": "@expressjs/back-redirect-deprecated", "version": "1.0.0", + "extraneous": true, "license": "MIT", "devDependencies": { "@codemod.com/jssg-types": "^1.3.1" @@ -1005,7 +1014,7 @@ "license": "Apache-2.0" }, "node_modules/@expressjs/back-redirect-deprecated": { - "resolved": "codemods/magic-redirect", + "resolved": "codemods/back-redirect-deprecated", "link": true }, "node_modules/@istanbuljs/load-nyc-config": { @@ -4646,9 +4655,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "peer": true, diff --git a/package.json b/package.json index 6ea09fd..51ec91b 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.4", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "engines": { "node": ">=18" From 35e5d273b5530b4a1e2352cc849612ee39d929b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 22:52:42 -0500 Subject: [PATCH 29/52] chore(deps-dev): bump @types/node from 22.15.29 to 22.19.1 (#90) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.29 to 22.19.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.19.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b9c0464..aeac2ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.15.29", + "@types/node": "^22.19.3", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.4", @@ -1551,9 +1551,9 @@ } }, "node_modules/@types/node": { - "version": "22.15.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.29.tgz", - "integrity": "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==", + "version": "22.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 51ec91b..c4101d9 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "@biomejs/biome": "1.9.4", "@types/jest": "29.5.14", "@types/jscodeshift": "^0.12.0", - "@types/node": "^22.15.29", + "@types/node": "^22.19.3", "@types/prompts": "2.4.9", "jest": "29.7.0", "ts-jest": "29.3.4", From 3c1c9b02a1d5181e44d26cce127050fa95985567 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 6 Jan 2026 18:57:16 -0500 Subject: [PATCH 30/52] fix(publish): correct test command in workflow to use npm (#108) --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e91b445..1e5a83c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -96,7 +96,7 @@ jobs: # Run test before login to not waste time if it fails - name: Run codemod Tests working-directory: ${{ steps.parse-tag.outputs.codemod-path }} - run: node --run test + run: npm run test - name: Authenticate with Codemod registry env: From d37db772d7ef9974e1e40f59d31870941041a514 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jan 2026 19:42:51 -0500 Subject: [PATCH 31/52] chore(deps): bump actions/checkout from 4.3.1 to 6.0.1 (#103) * chore(deps): bump actions/checkout from 4.3.1 to 6.0.1 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.1 to 6.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v4.3.1...v6.0.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update .github/workflows/ci.yml Signed-off-by: Sebastian Beltran * Update .github/workflows/ci.yml Signed-off-by: Sebastian Beltran * Update .github/workflows/generate-readme.yml Signed-off-by: Sebastian Beltran --------- Signed-off-by: dependabot[bot] Signed-off-by: Sebastian Beltran Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sebastian Beltran --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql.yml | 2 +- .github/workflows/generate-readme.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 276d55a..4fa0437 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Setup Node.js {{ matrix.node-version }} uses: actions/setup-node@v6.1.0 with: @@ -49,7 +49,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9afb58e..a1889a0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/generate-readme.yml b/.github/workflows/generate-readme.yml index bb7c3fd..60de381 100644 --- a/.github/workflows/generate-readme.yml +++ b/.github/workflows/generate-readme.yml @@ -19,7 +19,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - name: Setup Node.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1e5a83c..4ea7eb5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ad7b831..a7c5ed9 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -30,7 +30,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.1.2 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.2 with: persist-credentials: false From 89eea7989bdff6d74f356db82510d354e821100c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jan 2026 19:46:15 -0500 Subject: [PATCH 32/52] chore(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0 (#105) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5.0.0 to 6.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/330a01c490aca151604b8cf639adc76d48f6c5d4...b7c566a772e6b6bfb58ed0dc250532a479d7789f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a7c5ed9..e05e9bf 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -57,7 +57,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: SARIF file path: results.sarif From 325f04d80f37fd0c72cbd63fb2ac9f13abc0bbd8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jan 2026 19:56:10 -0500 Subject: [PATCH 33/52] chore(deps): bump github/codeql-action from 4.31.5 to 4.31.9 (#104) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.5 to 4.31.9. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/fdbfb4d2750291e159f0156def62b853c2798ca2...5d4e8d1aca955e8d8589aabd499c5cae939e33c7) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.31.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a1889a0..cc6eba0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 + uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 + uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e05e9bf..6dd4968 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,6 +65,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 + uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 with: sarif_file: results.sarif \ No newline at end of file From 8e2093723ae95a5cc9b26858436c322278bb97bc Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Fri, 9 Jan 2026 17:30:40 -0500 Subject: [PATCH 34/52] feat(sendfile): add migration for res.sendfile to res.sendFile (#98) * feat(sendfile): add migration for res.sendfile to res.sendFile * fix(package): update repository directory and homepage in package.json * fix: update package-lock * rename codemod * Update codemods/camelcase-sendfile/codemod.yaml Signed-off-by: Sebastian Beltran * fix(workflow): simplify empty checks for nodes and edits --------- Signed-off-by: Sebastian Beltran --- codemods/camelcase-sendfile/README.md | 21 ++++++ codemods/camelcase-sendfile/codemod.yaml | 25 +++++++ codemods/camelcase-sendfile/package.json | 22 ++++++ codemods/camelcase-sendfile/src/workflow.ts | 35 ++++++++++ .../tests/expected/send-file.ts | 67 +++++++++++++++++++ .../tests/input/send-file.ts | 67 +++++++++++++++++++ codemods/camelcase-sendfile/workflow.yaml | 28 ++++++++ package-lock.json | 12 ++++ 8 files changed, 277 insertions(+) create mode 100644 codemods/camelcase-sendfile/README.md create mode 100644 codemods/camelcase-sendfile/codemod.yaml create mode 100644 codemods/camelcase-sendfile/package.json create mode 100644 codemods/camelcase-sendfile/src/workflow.ts create mode 100644 codemods/camelcase-sendfile/tests/expected/send-file.ts create mode 100644 codemods/camelcase-sendfile/tests/input/send-file.ts create mode 100644 codemods/camelcase-sendfile/workflow.yaml diff --git a/codemods/camelcase-sendfile/README.md b/codemods/camelcase-sendfile/README.md new file mode 100644 index 0000000..a707f0e --- /dev/null +++ b/codemods/camelcase-sendfile/README.md @@ -0,0 +1,21 @@ +# Migrate legacy `res.sendfile(file)` to `res.sendFile(file)` + +Migrates usage of the legacy APIs `res.sendfile(file)` to `res.sendFile(file)`. + +## Example + +### Migrating `res.sendfile(file)` + +The migration involves replacing instances of `res.sendfile(file)` with `res.sendFile(file)`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.sendfile('/path/to/file'); ++ res.sendFile('/path/to/file'); +}); +``` + +## References + +- [Migration of res.sendfile(file)](https://expressjs.com/en/guide/migrating-5.html#res.sendFile) \ No newline at end of file diff --git a/codemods/camelcase-sendfile/codemod.yaml b/codemods/camelcase-sendfile/codemod.yaml new file mode 100644 index 0000000..1f2a6ac --- /dev/null +++ b/codemods/camelcase-sendfile/codemod.yaml @@ -0,0 +1,25 @@ +schema_version: "1.0" +name: "@expressjs/camelcase-sendfile" +version: "1.0.0" +description: Migrates usage of the legacy API `res.sendfile(file)` to `res.sendFile(file)` +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/camelcase-sendfile" +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - sendFile + - files + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/camelcase-sendfile/package.json b/codemods/camelcase-sendfile/package.json new file mode 100644 index 0000000..dc5275f --- /dev/null +++ b/codemods/camelcase-sendfile/package.json @@ -0,0 +1,22 @@ +{ + "name": "@expressjs/camelcase-sendfile", + "private": true, + "version": "1.0.0", + "description": "Migrates usage of the legacy API `res.sendfile(file)` to `res.sendFile(file)`.", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/camelcase-sendfile", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/camelcase-sendfile/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/camelcase-sendfile/src/workflow.ts b/codemods/camelcase-sendfile/src/workflow.ts new file mode 100644 index 0000000..1238746 --- /dev/null +++ b/codemods/camelcase-sendfile/src/workflow.ts @@ -0,0 +1,35 @@ +import type Js from '@codemod.com/jssg-types/src/langs/javascript' +import type { Edit, SgRoot } from '@codemod.com/jssg-types/src/main' + +async function transform(root: SgRoot): Promise { + const rootNode = root.root() + + const nodes = rootNode.findAll({ + rule: { + pattern: '$OBJ.$METHOD($$$METHOD)', + }, + constraints: { + METHOD: { regex: '^(sendfile)$' }, + }, + }) + + if (!nodes.length) return null + + const edits: Edit[] = [] + + for (const call of nodes) { + const method = call.getMatch('METHOD') + const obj = call.getMatch('OBJ') + if (!method || !obj) continue + + const objDef = obj.definition({ resolveExternal: false }) + if (!objDef) continue + + edits.push(method.replace('sendFile')) + } + + if (!edits.length) return null + return rootNode.commitEdits(edits) +} + +export default transform diff --git a/codemods/camelcase-sendfile/tests/expected/send-file.ts b/codemods/camelcase-sendfile/tests/expected/send-file.ts new file mode 100644 index 0000000..f222bc4 --- /dev/null +++ b/codemods/camelcase-sendfile/tests/expected/send-file.ts @@ -0,0 +1,67 @@ +import express from "express"; +import path from "path"; +import sendfile from "other-place" + +const app = express(); +const options = { + root: path.join(__dirname, 'public'), + dotfiles: 'deny', + headers: { + 'x-timestamp': Date.now(), + 'x-sent': true + } +} + +const sharedSendFile = (res, next, fileName) => { + res.sendFile(fileName, options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', fileName) + } + }) +} + +app.get('/file/:name', (req, res, next) => { + res.sendFile() +}) + +app.get('/file/:name', (req, res, next) => { + res.sendFile("file.txt") +}) + +app.get('/file/:name', (req, res, next) => { + const fileName = req.params.name + + res.sendFile(fileName, options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', fileName) + } + }) + sharedSendFile(res, next, fileName); +}) + +app.get('/filename/:name', function (req, res, next) { + const fileName = req.params.name + + res.sendFile(fileName, options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', fileName) + } + }) + sharedSendFile(res, next, fileName); +}) + +app.get('/file-handler', (req, res, next) => { + sendfile('test', options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', 'test') + } + }) +}) \ No newline at end of file diff --git a/codemods/camelcase-sendfile/tests/input/send-file.ts b/codemods/camelcase-sendfile/tests/input/send-file.ts new file mode 100644 index 0000000..37926ea --- /dev/null +++ b/codemods/camelcase-sendfile/tests/input/send-file.ts @@ -0,0 +1,67 @@ +import express from "express"; +import path from "path"; +import sendfile from "other-place" + +const app = express(); +const options = { + root: path.join(__dirname, 'public'), + dotfiles: 'deny', + headers: { + 'x-timestamp': Date.now(), + 'x-sent': true + } +} + +const sharedSendFile = (res, next, fileName) => { + res.sendfile(fileName, options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', fileName) + } + }) +} + +app.get('/file/:name', (req, res, next) => { + res.sendfile() +}) + +app.get('/file/:name', (req, res, next) => { + res.sendfile("file.txt") +}) + +app.get('/file/:name', (req, res, next) => { + const fileName = req.params.name + + res.sendfile(fileName, options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', fileName) + } + }) + sharedSendFile(res, next, fileName); +}) + +app.get('/filename/:name', function (req, res, next) { + const fileName = req.params.name + + res.sendfile(fileName, options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', fileName) + } + }) + sharedSendFile(res, next, fileName); +}) + +app.get('/file-handler', (req, res, next) => { + sendfile('test', options, (err) => { + if (err) { + next(err) + } else { + console.log('Sent:', 'test') + } + }) +}) \ No newline at end of file diff --git a/codemods/camelcase-sendfile/workflow.yaml b/codemods/camelcase-sendfile/workflow.yaml new file mode 100644 index 0000000..0749364 --- /dev/null +++ b/codemods/camelcase-sendfile/workflow.yaml @@ -0,0 +1,28 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of the legacy APIs `res.sendfile(file)` to `res.sendFile(file)` + js-ast-grep: + js_file: src/workflow.ts + base_path: . + semantic_analysis: file + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index aeac2ae..f65e18b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,6 +56,14 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/sendfile-to-sendFile": { + "name": "@expressjs/sendfile-to-sendfile", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -1017,6 +1025,10 @@ "resolved": "codemods/back-redirect-deprecated", "link": true }, + "node_modules/@expressjs/sendfile-to-sendfile": { + "resolved": "codemods/sendfile-to-sendFile", + "link": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", From 5856cfdfc4f73606a542d048b877d9c15ca47448 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Fri, 9 Jan 2026 17:37:12 -0500 Subject: [PATCH 35/52] feat(status-send-order): migrate logic of v4-deprecate-signatures to ast-grep (#97) * feat(status-send-order): migrate logic of v4-deprecate-signatures to ast-grep * fix(package): update repository directory and homepage for status-send-order * Update codemods/status-send-order/codemod.yaml Signed-off-by: Sebastian Beltran * refactor(workflow): simplify early return conditions for nodes and edits --------- Signed-off-by: Sebastian Beltran --- codemods/status-send-order/README.md | 62 +++++++++++++++ codemods/status-send-order/codemod.yaml | 27 +++++++ codemods/status-send-order/package.json | 22 ++++++ codemods/status-send-order/src/workflow.ts | 78 +++++++++++++++++++ .../status-send-order/tests/expected/json.ts | 71 +++++++++++++++++ .../status-send-order/tests/expected/jsonp.ts | 61 +++++++++++++++ .../status-send-order/tests/expected/send.ts | 75 ++++++++++++++++++ .../status-send-order/tests/input/json.ts | 71 +++++++++++++++++ .../status-send-order/tests/input/jsonp.ts | 61 +++++++++++++++ .../status-send-order/tests/input/send.ts | 75 ++++++++++++++++++ codemods/status-send-order/workflow.yaml | 28 +++++++ package-lock.json | 20 ++++- 12 files changed, 647 insertions(+), 4 deletions(-) create mode 100644 codemods/status-send-order/README.md create mode 100644 codemods/status-send-order/codemod.yaml create mode 100644 codemods/status-send-order/package.json create mode 100644 codemods/status-send-order/src/workflow.ts create mode 100644 codemods/status-send-order/tests/expected/json.ts create mode 100644 codemods/status-send-order/tests/expected/jsonp.ts create mode 100644 codemods/status-send-order/tests/expected/send.ts create mode 100644 codemods/status-send-order/tests/input/json.ts create mode 100644 codemods/status-send-order/tests/input/jsonp.ts create mode 100644 codemods/status-send-order/tests/input/send.ts create mode 100644 codemods/status-send-order/workflow.yaml diff --git a/codemods/status-send-order/README.md b/codemods/status-send-order/README.md new file mode 100644 index 0000000..a0fbea2 --- /dev/null +++ b/codemods/status-send-order/README.md @@ -0,0 +1,62 @@ +# Migrate legacy `res.send(obj, status)`, `res.send(status)`, `res.json(obj, status)` and `res.jsonp(obj, status)` + +Migrates usage of the legacy APIs `res.send(obj, status)`, `res.json(obj, status)`, and `res.jsonp(obj, status)` to use the recommended approach of specifying the status code +using the `res.status(status).send(obj)`, `res.status(status).json(obj)`, and +`res.status(status).jsonp(obj)` methods respectively. The older APIs that allowed +specifying the status code as a second argument have been deprecated. + +## Example + +### Migrating `res.send(obj, status)` + +The migration involves replacing instances of `res.send(obj, status)` with `res.status(status).send(obj)`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.send(obj, status); ++ res.status(status).send(obj); +}); +``` + +### Migrating `res.json(obj, status)` + +The migration involves replacing instances of `res.json(obj, status)` with `res.status(status).json(obj)`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.json(obj, status); ++ res.status(status).json(obj); +}); +``` +### Migrating `res.jsonp(obj, status)` + +The migration involves replacing instances of `res.jsonp(obj, status)` with `res.status(status).jsonp(obj)`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.jsonp(obj, status); ++ res.status(status).jsonp(obj); +}); +``` + +### Migrating `res.send(status)` + +The migration involves replacing instances of `res.send(status)` with `res.sendStatus(status)`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.send(status); ++ res.sendStatus(status); +}); +``` + +## References + +- [Migration of res.send(status)](https://expressjs.com/en/guide/migrating-5.html#res.send.status) +- [Migration of res.send(obj, status)](https://expressjs.com/en/guide/migrating-5.html#res.send.body) +- [Migration of res.json(obj, status)](https://expressjs.com/en/guide/migrating-5.html#res.json) +- [Migration of res.jsonp(obj, status)](https://expressjs.com/en/guide/migrating-5.html#res.jsonp) diff --git a/codemods/status-send-order/codemod.yaml b/codemods/status-send-order/codemod.yaml new file mode 100644 index 0000000..3d15b5d --- /dev/null +++ b/codemods/status-send-order/codemod.yaml @@ -0,0 +1,27 @@ +schema_version: "1.0" +name: "@expressjs/status-send-order" +version: "1.0.0" +description: Migrates usage of the legacy APIs `res.send(status)`, `res.send(obj, status)`, `res.json(obj, status)` and `res.jsonp(obj, status)` to the current recommended approaches +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/status-send-order" +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - send + - json + - jsonp + - status + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/status-send-order/package.json b/codemods/status-send-order/package.json new file mode 100644 index 0000000..b249239 --- /dev/null +++ b/codemods/status-send-order/package.json @@ -0,0 +1,22 @@ +{ + "name": "@expressjs/status-send-order", + "private": true, + "version": "1.0.0", + "description": "Migrates usage of the legacy APIs `res.send(status)`, `res.send(obj, status)`, `res.json(obj, status)` and `res.jsonp(obj, status)` to the current recommended approaches", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/status-send-order", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/status-send-order/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/status-send-order/src/workflow.ts b/codemods/status-send-order/src/workflow.ts new file mode 100644 index 0000000..50ce5cb --- /dev/null +++ b/codemods/status-send-order/src/workflow.ts @@ -0,0 +1,78 @@ +import type Js from '@codemod.com/jssg-types/src/langs/javascript' +import type { Edit, SgRoot } from '@codemod.com/jssg-types/src/main' + +async function transform(root: SgRoot): Promise { + const rootNode = root.root() + + const nodes = rootNode.findAll({ + rule: { + pattern: '$OBJ.$METHOD($$$ARG)', + }, + constraints: { + METHOD: { regex: '^(send|json|jsonp)$' }, + }, + }) + + if (!nodes.length) return null + + const edits: Edit[] = [] + + for (const call of nodes) { + const obj = call.getMatch('OBJ') + const args = call.getMultipleMatches('ARG') + + if (args.length === 0 || !obj) continue + + const objDef = obj.definition({ resolveExternal: false }) + if (!objDef) continue + + const method = call.getMatch('METHOD')?.text() + if (!method) continue + + // Single-argument forms: res.send(status) -> res.sendStatus(status) + if (args.length === 1) { + const a0 = args[0] + if (method === 'send' && a0.is('number')) { + edits.push(call.replace(`${obj.text()}.sendStatus(${a0.text()})`)) + } + continue + } + + // Two-argument forms: res.send(obj, status) -> res.status(status).send(obj) + if (args.length >= 2) { + const first = args[0] + const second = args[2] + + if (!second) continue + + // support both orders: (obj, status) and (status, obj) + if (first.is('number') && !second.is('number')) { + const status = first + const body = second + if (method === 'send') { + edits.push(call.replace(`${obj.text()}.status(${status.text()}).send(${body.text()})`)) + } else if (method === 'json') { + edits.push(call.replace(`${obj.text()}.status(${status.text()}).json(${body.text()})`)) + } else if (method === 'jsonp') { + edits.push(call.replace(`${obj.text()}.status(${status.text()}).jsonp(${body.text()})`)) + } + } else if (second.is('number') && !first.is('number')) { + const status = second + const body = first + if (method === 'send') { + edits.push(call.replace(`${obj.text()}.status(${status.text()}).send(${body.text()})`)) + } else if (method === 'json') { + edits.push(call.replace(`${obj.text()}.status(${status.text()}).json(${body.text()})`)) + } else if (method === 'jsonp') { + edits.push(call.replace(`${obj.text()}.status(${status.text()}).jsonp(${body.text()})`)) + } + } + } + } + + if (!edits.length) return null + + return rootNode.commitEdits(edits) +} + +export default transform diff --git a/codemods/status-send-order/tests/expected/json.ts b/codemods/status-send-order/tests/expected/json.ts new file mode 100644 index 0000000..c25583c --- /dev/null +++ b/codemods/status-send-order/tests/expected/json.ts @@ -0,0 +1,71 @@ +import express from "express"; + +const app = express(); + +app.get("/json", function (...arg) { + const [, res] = arg + res.json(); +}); + +app.get("/json", function (...arg) { + const [, res] = arg + res.status(200).json({ user: "Username", isValid: true }); +}); + +app.get("/json", function (req, res) { + res.json(); +}); + +app.get("/json", function (req, res) { + res.status(200).json({ user: "Username", isValid: true }); +}); + +app.get("/json", function (req, response) { + response.status(200).json({ user: "Username", isValid: true }); +}); + +app.get("/json", (req, res) => { + res.status(200).json({ user: "Username", isValid: true }); +}); + +app.get("/json", (req, response) => { + response.status(200).json({ user: "Username", isValid: true }); +}); + +app.get("/json", function (req, res) { + res.status(200).json({}); +}); + +app.get("/json", function (req, response) { + response.status(200).json({}); +}); + +app.get("/json", (req, res) => { + res.status(200).json({}); +}); + +app.get("/json", (req, response) => { + response.status(200).json({}); +}); + +// Still valid syntax -- START +app.get("/json", function (req, res) { + res.json(null) + res.json({ user: 'tobi' }) +}) + +app.get("/json", function (req, response) { + response.json(null) + response.json({ user: 'tobi' }) +}) + +app.get("/json", function (req, res) { + res.json(null) + res.json({ user: 'tobi' }) +}) + +app.get("/json", function (req, response) { + response.json(null) + response.json({ user: 'tobi' }) +}) +// Still valid syntax -- END \ No newline at end of file diff --git a/codemods/status-send-order/tests/expected/jsonp.ts b/codemods/status-send-order/tests/expected/jsonp.ts new file mode 100644 index 0000000..4aafe06 --- /dev/null +++ b/codemods/status-send-order/tests/expected/jsonp.ts @@ -0,0 +1,61 @@ +import express from "express"; + +const app = express(); + +app.get("/json", function (req, res) { + res.json(); +}); + +app.get("/jsonp", function (req, res) { + res.status(200).jsonp({ user: "Username", isValid: true }); +}); + +app.get("/jsonp", function (req, response) { + response.status(200).jsonp({ user: "Username", isValid: true }); +}); + +app.get("/jsonp", (req, res) => { + res.status(200).jsonp({ user: "Username", isValid: true }); +}); + +app.get("/jsonp", (req, response) => { + response.status(200).jsonp({ user: "Username", isValid: true }); +}); + +app.get("/jsonp", function (req, res) { + res.status(200).jsonp({}); +}); + +app.get("/jsonp", function (req, response) { + response.status(200).jsonp({}); +}); + +app.get("/jsonp", (req, res) => { + res.status(200).jsonp({}) +}); + +app.get("/jsonp", (req, response) => { + response.status(200).jsonp({}) +}); + +// Still valid syntax -- START +app.get("/jsonp", function (req, res) { + res.jsonp(null) + res.jsonp({ user: 'tobi' }) +}) + +app.get("/jsonp", function (req, response) { + response.jsonp(null) + response.jsonp({ user: 'tobi' }) +}) + +app.get("/jsonp", function (req, res) { + res.jsonp(null) + res.jsonp({ user: 'tobi' }) +}) + +app.get("/jsonp", function (req, response) { + response.jsonp(null) + response.jsonp({ user: 'tobi' }) +}) +// Still valid syntax -- END \ No newline at end of file diff --git a/codemods/status-send-order/tests/expected/send.ts b/codemods/status-send-order/tests/expected/send.ts new file mode 100644 index 0000000..0824a61 --- /dev/null +++ b/codemods/status-send-order/tests/expected/send.ts @@ -0,0 +1,75 @@ +import express from "express"; + +const app = express(); + +app.get("/send", function (...arg) { + const [, res] = arg + res.send(); +}); + +app.get("/send", function (...arg) { + const [, res] = arg + res.status(200).send(true); +}); + +app.get("/send", function (req, res) { + res.send(); +}); + +app.get("/send", function (req, res) { + res.status(200).send({ hello: "world" }); +}); + +app.get("/send", function (req, response) { + response.status(200).send("Hello World"); +}); + +app.get("/send", function (req, res) { + res.sendStatus(200); +}); + +app.get("/send", function (req, res) { + res.status(200).send(true); +}); + +app.get("/send", (req, res) => { + res.status(200).send({ hello: "world" }); +}); + +app.get("/send", (req, res) => { + res.sendStatus(200); +}); + +app.get("/send", (req, response) => { + response.sendStatus(200); +}); + +app.get("/send", (req, response) => { + response.status(200).send(true); +}); + +// Still valid syntax -- START +app.get("/send", function (req, res) { + res.send(Buffer.from('whoop')); + res.send({ some: 'json' }); + res.send('

some html

'); +}); + +app.get("/send", function (req, response) { + response.send(Buffer.from('whoop')); + response.send({ some: 'json' }); + response.send('

some html

'); +}); + +app.get("/send", (req, response) => { + response.send(Buffer.from('whoop')); + response.send({ some: 'json' }); + response.send('

some html

'); +}); + +app.get("/send", (req, res) => { + res.send(Buffer.from('whoop')); + res.send({ some: 'json' }); + res.send('

some html

'); +}); +// Still valid syntax -- END \ No newline at end of file diff --git a/codemods/status-send-order/tests/input/json.ts b/codemods/status-send-order/tests/input/json.ts new file mode 100644 index 0000000..2f23e2a --- /dev/null +++ b/codemods/status-send-order/tests/input/json.ts @@ -0,0 +1,71 @@ +import express from "express"; + +const app = express(); + +app.get("/json", function (...arg) { + const [, res] = arg + res.json(); +}); + +app.get("/json", function (...arg) { + const [, res] = arg + res.json({ user: "Username", isValid: true }, 200); +}); + +app.get("/json", function (req, res) { + res.json(); +}); + +app.get("/json", function (req, res) { + res.json({ user: "Username", isValid: true }, 200); +}); + +app.get("/json", function (req, response) { + response.json({ user: "Username", isValid: true }, 200); +}); + +app.get("/json", (req, res) => { + res.json({ user: "Username", isValid: true }, 200); +}); + +app.get("/json", (req, response) => { + response.json({ user: "Username", isValid: true }, 200); +}); + +app.get("/json", function (req, res) { + res.json({}, 200); +}); + +app.get("/json", function (req, response) { + response.json({}, 200); +}); + +app.get("/json", (req, res) => { + res.json({}, 200); +}); + +app.get("/json", (req, response) => { + response.json({}, 200); +}); + +// Still valid syntax -- START +app.get("/json", function (req, res) { + res.json(null) + res.json({ user: 'tobi' }) +}) + +app.get("/json", function (req, response) { + response.json(null) + response.json({ user: 'tobi' }) +}) + +app.get("/json", function (req, res) { + res.json(null) + res.json({ user: 'tobi' }) +}) + +app.get("/json", function (req, response) { + response.json(null) + response.json({ user: 'tobi' }) +}) +// Still valid syntax -- END \ No newline at end of file diff --git a/codemods/status-send-order/tests/input/jsonp.ts b/codemods/status-send-order/tests/input/jsonp.ts new file mode 100644 index 0000000..88a7e27 --- /dev/null +++ b/codemods/status-send-order/tests/input/jsonp.ts @@ -0,0 +1,61 @@ +import express from "express"; + +const app = express(); + +app.get("/json", function (req, res) { + res.json(); +}); + +app.get("/jsonp", function (req, res) { + res.jsonp({ user: "Username", isValid: true }, 200); +}); + +app.get("/jsonp", function (req, response) { + response.jsonp({ user: "Username", isValid: true }, 200); +}); + +app.get("/jsonp", (req, res) => { + res.jsonp({ user: "Username", isValid: true }, 200); +}); + +app.get("/jsonp", (req, response) => { + response.jsonp({ user: "Username", isValid: true }, 200); +}); + +app.get("/jsonp", function (req, res) { + res.jsonp({}, 200); +}); + +app.get("/jsonp", function (req, response) { + response.jsonp({}, 200); +}); + +app.get("/jsonp", (req, res) => { + res.jsonp({}, 200) +}); + +app.get("/jsonp", (req, response) => { + response.jsonp({}, 200) +}); + +// Still valid syntax -- START +app.get("/jsonp", function (req, res) { + res.jsonp(null) + res.jsonp({ user: 'tobi' }) +}) + +app.get("/jsonp", function (req, response) { + response.jsonp(null) + response.jsonp({ user: 'tobi' }) +}) + +app.get("/jsonp", function (req, res) { + res.jsonp(null) + res.jsonp({ user: 'tobi' }) +}) + +app.get("/jsonp", function (req, response) { + response.jsonp(null) + response.jsonp({ user: 'tobi' }) +}) +// Still valid syntax -- END \ No newline at end of file diff --git a/codemods/status-send-order/tests/input/send.ts b/codemods/status-send-order/tests/input/send.ts new file mode 100644 index 0000000..f436e85 --- /dev/null +++ b/codemods/status-send-order/tests/input/send.ts @@ -0,0 +1,75 @@ +import express from "express"; + +const app = express(); + +app.get("/send", function (...arg) { + const [, res] = arg + res.send(); +}); + +app.get("/send", function (...arg) { + const [, res] = arg + res.send(200, true); +}); + +app.get("/send", function (req, res) { + res.send(); +}); + +app.get("/send", function (req, res) { + res.send(200, { hello: "world" }); +}); + +app.get("/send", function (req, response) { + response.send(200, "Hello World"); +}); + +app.get("/send", function (req, res) { + res.send(200); +}); + +app.get("/send", function (req, res) { + res.send(200, true); +}); + +app.get("/send", (req, res) => { + res.send(200, { hello: "world" }); +}); + +app.get("/send", (req, res) => { + res.send(200); +}); + +app.get("/send", (req, response) => { + response.send(200); +}); + +app.get("/send", (req, response) => { + response.send(200, true); +}); + +// Still valid syntax -- START +app.get("/send", function (req, res) { + res.send(Buffer.from('whoop')); + res.send({ some: 'json' }); + res.send('

some html

'); +}); + +app.get("/send", function (req, response) { + response.send(Buffer.from('whoop')); + response.send({ some: 'json' }); + response.send('

some html

'); +}); + +app.get("/send", (req, response) => { + response.send(Buffer.from('whoop')); + response.send({ some: 'json' }); + response.send('

some html

'); +}); + +app.get("/send", (req, res) => { + res.send(Buffer.from('whoop')); + res.send({ some: 'json' }); + res.send('

some html

'); +}); +// Still valid syntax -- END \ No newline at end of file diff --git a/codemods/status-send-order/workflow.yaml b/codemods/status-send-order/workflow.yaml new file mode 100644 index 0000000..5e2eda3 --- /dev/null +++ b/codemods/status-send-order/workflow.yaml @@ -0,0 +1,28 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of the legacy APIs `res.send(status)`, `res.send(obj, status)`, `res.json(obj, status)` and `res.jsonp(obj, status)` to the current recommended approaches + js-ast-grep: + js_file: src/workflow.ts + base_path: . + semantic_analysis: file + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f65e18b..93ec2b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,14 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/camelcase-sendfile": { + "name": "@expressjs/camelcase-sendfile", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "codemods/magic-redirect": { "name": "@expressjs/back-redirect-deprecated", "version": "1.0.0", @@ -56,8 +64,8 @@ "@codemod.com/jssg-types": "^1.3.1" } }, - "codemods/sendfile-to-sendFile": { - "name": "@expressjs/sendfile-to-sendfile", + "codemods/status-send-order": { + "name": "@expressjs/status-send-order", "version": "1.0.0", "license": "MIT", "devDependencies": { @@ -1025,8 +1033,12 @@ "resolved": "codemods/back-redirect-deprecated", "link": true }, - "node_modules/@expressjs/sendfile-to-sendfile": { - "resolved": "codemods/sendfile-to-sendFile", + "node_modules/@expressjs/camelcase-sendfile": { + "resolved": "codemods/camelcase-sendfile", + "link": true + }, + "node_modules/@expressjs/status-send-order": { + "resolved": "codemods/status-send-order", "link": true }, "node_modules/@istanbuljs/load-nyc-config": { From d9782a655727956b244cfbd0aa9ebec46765ec82 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Fri, 9 Jan 2026 17:46:12 -0500 Subject: [PATCH 36/52] feat(pluralize-deprecated-methods): migrate pluralize-methods to codemod.com (#95) * feat(pluralize-deprecated-methods): migrate pluralize-methods to codemod.com * rename codemod * apply suggestions * chore: update repository URL in codemod.yaml --- codemods/pluralize-method-names/README.md | 44 +++++++++++++++++++ codemods/pluralize-method-names/codemod.yaml | 27 ++++++++++++ codemods/pluralize-method-names/package.json | 22 ++++++++++ .../pluralize-method-names/src/workflow.ts | 41 +++++++++++++++++ .../tests/expected/charset.ts | 19 ++++++++ .../tests/expected/encoding.ts | 18 ++++++++ .../tests/expected/language.ts | 18 ++++++++ .../tests/input/charset.ts | 19 ++++++++ .../tests/input/encoding.ts | 18 ++++++++ .../tests/input/language.ts | 18 ++++++++ codemods/pluralize-method-names/workflow.yaml | 28 ++++++++++++ package-lock.json | 12 +++++ 12 files changed, 284 insertions(+) create mode 100644 codemods/pluralize-method-names/README.md create mode 100644 codemods/pluralize-method-names/codemod.yaml create mode 100644 codemods/pluralize-method-names/package.json create mode 100644 codemods/pluralize-method-names/src/workflow.ts create mode 100644 codemods/pluralize-method-names/tests/expected/charset.ts create mode 100644 codemods/pluralize-method-names/tests/expected/encoding.ts create mode 100644 codemods/pluralize-method-names/tests/expected/language.ts create mode 100644 codemods/pluralize-method-names/tests/input/charset.ts create mode 100644 codemods/pluralize-method-names/tests/input/encoding.ts create mode 100644 codemods/pluralize-method-names/tests/input/language.ts create mode 100644 codemods/pluralize-method-names/workflow.yaml diff --git a/codemods/pluralize-method-names/README.md b/codemods/pluralize-method-names/README.md new file mode 100644 index 0000000..f345f23 --- /dev/null +++ b/codemods/pluralize-method-names/README.md @@ -0,0 +1,44 @@ +# Migrate pluralized request methods + +Migrates deprecated request methods to their pluralized versions that were deprecated in Express 4 and removed in Express 5. + +## Example + +### Migrating `req.acceptsCharset(charset)` + +The migration involves replacing instances of `req.acceptsCharset(charset)` with `req.acceptsCharsets(charset)`. + +```diff +app.get('/', (req, res) => { +- const charset = req.acceptsCharset('utf-8'); ++ const charset = req.acceptsCharsets('utf-8'); + res.json({ charset }); +}); +``` +### Migrating `req.acceptsEncoding(encoding) + +The migration involves replacing instances of `req.acceptsEncoding(encoding)` with `req.acceptsEncodings(encoding)`. + +```diff +app.get('/', (req, res) => { +- const encoding = req.acceptsEncoding('gzip'); ++ const encoding = req.acceptsEncodings('gzip'); + res.json({ encoding }); +}); +``` + +### Migrating `req.acceptsLanguage(language)` + +The migration involves replacing instances of `req.acceptsLanguage(language)` with `req.acceptsLanguages(language)`. + +```diff +app.get('/', (req, res) => { +- const language = req.acceptsLanguage('en'); ++ const language = req.acceptsLanguages('en'); + res.json({ language }); +}); +``` + +## References + +- [Migration of pluralized request methods](https://expressjs.com/en/guide/migrating-5.html#plural) diff --git a/codemods/pluralize-method-names/codemod.yaml b/codemods/pluralize-method-names/codemod.yaml new file mode 100644 index 0000000..56ba749 --- /dev/null +++ b/codemods/pluralize-method-names/codemod.yaml @@ -0,0 +1,27 @@ +schema_version: "1.0" +name: "@expressjs/pluralize-method-names" +version: "1.0.0" +description: Migrates usage of deprecated singular request methods to their pluralized versions in Express.js applications. +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/pluralize-method-names" +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - accepts + - accepetsCharsets + - acceptsEncodings + - acceptsLanguages + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/pluralize-method-names/package.json b/codemods/pluralize-method-names/package.json new file mode 100644 index 0000000..1c3cd1c --- /dev/null +++ b/codemods/pluralize-method-names/package.json @@ -0,0 +1,22 @@ +{ + "name": "@expressjs/pluralize-method-names", + "private": true, + "version": "1.0.0", + "description": "Migrates usage of deprecated singular request methods to their pluralized versions in Express.js applications.", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/pluralize-method-names", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/pluralize-method-names/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/pluralize-method-names/src/workflow.ts b/codemods/pluralize-method-names/src/workflow.ts new file mode 100644 index 0000000..1baf93a --- /dev/null +++ b/codemods/pluralize-method-names/src/workflow.ts @@ -0,0 +1,41 @@ +import type Js from '@codemod.com/jssg-types/src/langs/javascript' +import type { Edit, SgRoot } from '@codemod.com/jssg-types/src/main' + +async function transform(root: SgRoot): Promise { + const rootNode = root.root() + + const nodes = rootNode.findAll({ + rule: { + any: [ + { pattern: '$OBJ.$METHOD($ARG)' }, + { + pattern: '$OBJ.$METHOD()', + }, + ], + }, + constraints: { + METHOD: { regex: '^(acceptsCharset|acceptsEncoding|acceptsLanguage)$' }, + }, + }) + + if (!nodes.length) return null + + const edits: Edit[] = [] + + for (const call of nodes) { + const method = call.getMatch('METHOD') + const obj = call.getMatch('OBJ') + if (!obj || !method) continue + + const objDef = obj.definition({ resolveExternal: false }) + if (!objDef) continue + + edits.push(method.replace(`${method.text()}s`)) + } + + if (!edits.length) return null + + return rootNode.commitEdits(edits) +} + +export default transform diff --git a/codemods/pluralize-method-names/tests/expected/charset.ts b/codemods/pluralize-method-names/tests/expected/charset.ts new file mode 100644 index 0000000..73713dd --- /dev/null +++ b/codemods/pluralize-method-names/tests/expected/charset.ts @@ -0,0 +1,19 @@ +import express from 'express' + +const app = express() + +app.get('/', (req, res) => { + const charset = req.acceptsCharsets(); + res.json({ charset }); +}); + + +app.get('/', (req, res) => { + const charset = req.acceptsCharsets('utf-8'); + res.json({ charset }); +}); + +app.get('/', function (request, response) { + const charset = request.acceptsCharsets('utf-8'); + response.json({ charset }); +}); \ No newline at end of file diff --git a/codemods/pluralize-method-names/tests/expected/encoding.ts b/codemods/pluralize-method-names/tests/expected/encoding.ts new file mode 100644 index 0000000..bf2c3f4 --- /dev/null +++ b/codemods/pluralize-method-names/tests/expected/encoding.ts @@ -0,0 +1,18 @@ +import express from 'express' + +const app = express() + +app.get('/', (req, res) => { + const encoding = req.acceptsEncodings(); + res.json({ encoding }); +}); + +app.get('/', (req, res) => { + const encoding = req.acceptsEncodings('gzip'); + res.json({ encoding }); +}); + +app.get('/', function (request, response) { + const encoding = request.acceptsEncodings('gzip'); + response.json({ encoding }); +}); \ No newline at end of file diff --git a/codemods/pluralize-method-names/tests/expected/language.ts b/codemods/pluralize-method-names/tests/expected/language.ts new file mode 100644 index 0000000..5c4f2b9 --- /dev/null +++ b/codemods/pluralize-method-names/tests/expected/language.ts @@ -0,0 +1,18 @@ +import express from 'express' + +const app = express() + +app.get('/', (req, res) => { + const encoding = req.acceptsLanguages(); + res.json({ encoding }); +}); + +app.get('/', (req, res) => { + const encoding = req.acceptsLanguages('gzip'); + res.json({ encoding }); +}); + +app.get('/', function (request, response) { + const encoding = request.acceptsLanguages('gzip'); + response.json({ encoding }); +}); \ No newline at end of file diff --git a/codemods/pluralize-method-names/tests/input/charset.ts b/codemods/pluralize-method-names/tests/input/charset.ts new file mode 100644 index 0000000..5e7c962 --- /dev/null +++ b/codemods/pluralize-method-names/tests/input/charset.ts @@ -0,0 +1,19 @@ +import express from 'express' + +const app = express() + +app.get('/', (req, res) => { + const charset = req.acceptsCharset(); + res.json({ charset }); +}); + + +app.get('/', (req, res) => { + const charset = req.acceptsCharset('utf-8'); + res.json({ charset }); +}); + +app.get('/', function (request, response) { + const charset = request.acceptsCharset('utf-8'); + response.json({ charset }); +}); \ No newline at end of file diff --git a/codemods/pluralize-method-names/tests/input/encoding.ts b/codemods/pluralize-method-names/tests/input/encoding.ts new file mode 100644 index 0000000..fa130ca --- /dev/null +++ b/codemods/pluralize-method-names/tests/input/encoding.ts @@ -0,0 +1,18 @@ +import express from 'express' + +const app = express() + +app.get('/', (req, res) => { + const encoding = req.acceptsEncoding(); + res.json({ encoding }); +}); + +app.get('/', (req, res) => { + const encoding = req.acceptsEncoding('gzip'); + res.json({ encoding }); +}); + +app.get('/', function (request, response) { + const encoding = request.acceptsEncoding('gzip'); + response.json({ encoding }); +}); \ No newline at end of file diff --git a/codemods/pluralize-method-names/tests/input/language.ts b/codemods/pluralize-method-names/tests/input/language.ts new file mode 100644 index 0000000..a719ed3 --- /dev/null +++ b/codemods/pluralize-method-names/tests/input/language.ts @@ -0,0 +1,18 @@ +import express from 'express' + +const app = express() + +app.get('/', (req, res) => { + const encoding = req.acceptsLanguage(); + res.json({ encoding }); +}); + +app.get('/', (req, res) => { + const encoding = req.acceptsLanguage('gzip'); + res.json({ encoding }); +}); + +app.get('/', function (request, response) { + const encoding = request.acceptsLanguage('gzip'); + response.json({ encoding }); +}); \ No newline at end of file diff --git a/codemods/pluralize-method-names/workflow.yaml b/codemods/pluralize-method-names/workflow.yaml new file mode 100644 index 0000000..4dcf1d6 --- /dev/null +++ b/codemods/pluralize-method-names/workflow.yaml @@ -0,0 +1,28 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of deprecated singular request methods to their pluralized versions in Express.js applications. + js-ast-grep: + js_file: src/workflow.ts + base_path: . + semantic_analysis: file + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 93ec2b5..cb10744 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,6 +64,14 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/pluralize-method-names": { + "name": "@expressjs/pluralize-method-names", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "codemods/status-send-order": { "name": "@expressjs/status-send-order", "version": "1.0.0", @@ -1037,6 +1045,10 @@ "resolved": "codemods/camelcase-sendfile", "link": true }, + "node_modules/@expressjs/pluralize-method-names": { + "resolved": "codemods/pluralize-method-names", + "link": true + }, "node_modules/@expressjs/status-send-order": { "resolved": "codemods/status-send-order", "link": true From ce5c9adfe7098463254c74bb1e607d16c27155b0 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 13 Jan 2026 09:59:35 -0500 Subject: [PATCH 37/52] feat(route-del-to-delete): add migration codemod for app.del() to app.delete() (#102) * feat(route-del-to-delete): add migration codemod for app.del() to app.delete() * fix(workflow): simplify early return checks for nodes and edits * fix(codemod): update repository URL in codemod.yaml * fix(docs): clarify deprecation of app.del() in migration guide --- codemods/route-del-to-delete/README.md | 21 +++++++++ codemods/route-del-to-delete/codemod.yaml | 25 +++++++++++ codemods/route-del-to-delete/package.json | 22 ++++++++++ codemods/route-del-to-delete/src/workflow.ts | 43 +++++++++++++++++++ .../tests/expected/delete.ts | 39 +++++++++++++++++ .../route-del-to-delete/tests/input/delete.ts | 39 +++++++++++++++++ codemods/route-del-to-delete/workflow.yaml | 28 ++++++++++++ package-lock.json | 12 ++++++ 8 files changed, 229 insertions(+) create mode 100644 codemods/route-del-to-delete/README.md create mode 100644 codemods/route-del-to-delete/codemod.yaml create mode 100644 codemods/route-del-to-delete/package.json create mode 100644 codemods/route-del-to-delete/src/workflow.ts create mode 100644 codemods/route-del-to-delete/tests/expected/delete.ts create mode 100644 codemods/route-del-to-delete/tests/input/delete.ts create mode 100644 codemods/route-del-to-delete/workflow.yaml diff --git a/codemods/route-del-to-delete/README.md b/codemods/route-del-to-delete/README.md new file mode 100644 index 0000000..250e5c6 --- /dev/null +++ b/codemods/route-del-to-delete/README.md @@ -0,0 +1,21 @@ +# Migrate legacy `app.del()` to `app.delete()` + +Migrates usage of the legacy APIs `app.del()` to `app.delete()`. +Initially, `del` was used instead of `delete`, because `delete` is a reserved keyword in JavaScript. However, as of ECMAScript 6, `delete` and other reserved keywords can legally be used as property names. The `app.del()` method was deprecated in Express 4 and removed in Express 5. + +## Example + +### Migrating `app.del()` + +The migration involves replacing instances of `app.del()` with `app.delete()`. + +```diff +- app.del('/some-route', (req, res) => { ++ app.delete('/some-route', (req, res) => { + // Some logic here + }); +``` + +## References + +- [Migration of app.del()](https://expressjs.com/en/guide/migrating-5.html#app.del) diff --git a/codemods/route-del-to-delete/codemod.yaml b/codemods/route-del-to-delete/codemod.yaml new file mode 100644 index 0000000..cece85c --- /dev/null +++ b/codemods/route-del-to-delete/codemod.yaml @@ -0,0 +1,25 @@ +schema_version: "1.0" +name: "@expressjs/route-del-to-delete" +version: "1.0.0" +description: Migrates usage of the legacy APIs `app.del()` to `app.delete()` +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/route-del-to-delete" +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - redirect + - location + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/route-del-to-delete/package.json b/codemods/route-del-to-delete/package.json new file mode 100644 index 0000000..5482aed --- /dev/null +++ b/codemods/route-del-to-delete/package.json @@ -0,0 +1,22 @@ +{ + "name": "@expressjs/route-del-to-delete", + "private": true, + "version": "1.0.0", + "description": "Migrates usage of the legacy APIs `app.del` to `app.delete`.", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/route-del-to-delete", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/route-del-to-delete/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/route-del-to-delete/src/workflow.ts b/codemods/route-del-to-delete/src/workflow.ts new file mode 100644 index 0000000..6d74a97 --- /dev/null +++ b/codemods/route-del-to-delete/src/workflow.ts @@ -0,0 +1,43 @@ +import type Js from '@codemod.com/jssg-types/src/langs/javascript' +import type { Edit, SgRoot } from '@codemod.com/jssg-types/src/main' + +async function transform(root: SgRoot): Promise { + const rootNode = root.root() + + const nodes = rootNode.findAll({ + rule: { + pattern: '$OBJ.$METHOD($$$ARG)', + }, + constraints: { + METHOD: { regex: '^(del)$' }, + }, + }) + + if (!nodes.length) return null + + const edits: Edit[] = [] + + for (const call of nodes) { + const method = call.getMatch('METHOD') + const args = call.getMultipleMatches('ARG') + if (!method) continue + + // $$$ARG yields argument nodes interleaved with separators, so arg nodes are at 0,2,4... + const first = args[0] + if (!first) continue + + const isString = first.is('string') + const isRegexp = first.is('regexp') || first.is('regex') || first.is('regular_expression') + const isArray = first.is('array') || first.is('array_expression') + + if (!isString && !isRegexp && !isArray) continue + + edits.push(method.replace('delete')) + } + + if (!edits.length) return null + + return rootNode.commitEdits(edits) +} + +export default transform diff --git a/codemods/route-del-to-delete/tests/expected/delete.ts b/codemods/route-del-to-delete/tests/expected/delete.ts new file mode 100644 index 0000000..b1dbf42 --- /dev/null +++ b/codemods/route-del-to-delete/tests/expected/delete.ts @@ -0,0 +1,39 @@ +import express from "express"; + +const app = express(); + +app.get("/", (req, res) => {}); + +app.delete([""],() => { + myImportantLogic(); +}); + +app.delete([],() => { + myImportantLogic(); +}); + +app.delete(/d/,() => { + myImportantLogic(); +}); + +app.del(() => { + myImportantLogic(); +}); + +app.del(function () { + myImportantLogic(); +}); + +app.delete("/old", () => { + myImportantLogic(); +}); + +function noModify() { + let a + + app.del(a) +} + +const myImportantLogic = () => { + console.log("making sure it's there"); +}; diff --git a/codemods/route-del-to-delete/tests/input/delete.ts b/codemods/route-del-to-delete/tests/input/delete.ts new file mode 100644 index 0000000..aeab3e3 --- /dev/null +++ b/codemods/route-del-to-delete/tests/input/delete.ts @@ -0,0 +1,39 @@ +import express from "express"; + +const app = express(); + +app.get("/", (req, res) => {}); + +app.del([""],() => { + myImportantLogic(); +}); + +app.del([],() => { + myImportantLogic(); +}); + +app.del(/d/,() => { + myImportantLogic(); +}); + +app.del(() => { + myImportantLogic(); +}); + +app.del(function () { + myImportantLogic(); +}); + +app.del("/old", () => { + myImportantLogic(); +}); + +function noModify() { + let a + + app.del(a) +} + +const myImportantLogic = () => { + console.log("making sure it's there"); +}; diff --git a/codemods/route-del-to-delete/workflow.yaml b/codemods/route-del-to-delete/workflow.yaml new file mode 100644 index 0000000..0253be9 --- /dev/null +++ b/codemods/route-del-to-delete/workflow.yaml @@ -0,0 +1,28 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of the legacy APIs `app.del()` to `app.delete()` + js-ast-grep: + js_file: src/workflow.ts + base_path: . + semantic_analysis: file + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cb10744..1bf6ff7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,14 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/route-del-to-delete": { + "name": "@expressjs/route-del-to-delete", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "codemods/status-send-order": { "name": "@expressjs/status-send-order", "version": "1.0.0", @@ -1049,6 +1057,10 @@ "resolved": "codemods/pluralize-method-names", "link": true }, + "node_modules/@expressjs/route-del-to-delete": { + "resolved": "codemods/route-del-to-delete", + "link": true + }, "node_modules/@expressjs/status-send-order": { "resolved": "codemods/status-send-order", "link": true From a0a45a0cdb38090b890ec5066a8d66976dcb22a6 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 13 Jan 2026 10:09:08 -0500 Subject: [PATCH 38/52] feat(redirect-arg-order): add migration codemod for res.redirect argument order (#99) * feat(redirect-arg-order): add migration codemod for res.redirect argument order * refactor(workflow): simplify early return checks for nodes and edits * fix(codemod.yaml): update repository URL for redirect-arg-order migration * fix(docs): clarify deprecation notice for res.redirect argument order migration --- codemods/redirect-arg-order/README.md | 22 ++++++++++ codemods/redirect-arg-order/codemod.yaml | 25 +++++++++++ codemods/redirect-arg-order/package.json | 22 ++++++++++ codemods/redirect-arg-order/src/workflow.ts | 44 +++++++++++++++++++ .../tests/expected/redirect.ts | 38 ++++++++++++++++ .../tests/input/redirect.ts | 38 ++++++++++++++++ codemods/redirect-arg-order/workflow.yaml | 28 ++++++++++++ package-lock.json | 12 +++++ 8 files changed, 229 insertions(+) create mode 100644 codemods/redirect-arg-order/README.md create mode 100644 codemods/redirect-arg-order/codemod.yaml create mode 100644 codemods/redirect-arg-order/package.json create mode 100644 codemods/redirect-arg-order/src/workflow.ts create mode 100644 codemods/redirect-arg-order/tests/expected/redirect.ts create mode 100644 codemods/redirect-arg-order/tests/input/redirect.ts create mode 100644 codemods/redirect-arg-order/workflow.yaml diff --git a/codemods/redirect-arg-order/README.md b/codemods/redirect-arg-order/README.md new file mode 100644 index 0000000..05e90b3 --- /dev/null +++ b/codemods/redirect-arg-order/README.md @@ -0,0 +1,22 @@ +# Migrate legacy `res.redirect(url, status)` + +Migrates usage of the legacy APIs `res.redirect(url, status)` to the new signature +`res.redirect(status, url)`. This usage was deprecated in Express 4, in Express 5 you must use the new signature `res.redirect(status, url)`. + +## Example + +### Migrating `res.redirect(url, status)` + +The migration involves replacing instances of `res.redirect(url, status)` with `res.redirect(status, url)`. + +```diff +app.get('/some-route', (req, res) => { + // Some logic here +- res.redirect(url, status); ++ res.redirect(status, url); +}); +``` + +## References + +- [Migration of res.redirect(url, status)](https://expressjs.com/en/guide/migrating-5.html#res.redirect) diff --git a/codemods/redirect-arg-order/codemod.yaml b/codemods/redirect-arg-order/codemod.yaml new file mode 100644 index 0000000..2af0c34 --- /dev/null +++ b/codemods/redirect-arg-order/codemod.yaml @@ -0,0 +1,25 @@ +schema_version: "1.0" +name: "@expressjs/redirect-arg-order" +version: "1.0.0" +description: Migrates usage of the legacy APIs `res.redirect(url, status)` to use the recommended argument order `res.redirect(status, url)`. +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/redirect-arg-order" +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - redirect + - location + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/redirect-arg-order/package.json b/codemods/redirect-arg-order/package.json new file mode 100644 index 0000000..b76d0b5 --- /dev/null +++ b/codemods/redirect-arg-order/package.json @@ -0,0 +1,22 @@ +{ + "name": "@expressjs/redirect-arg-order", + "private": true, + "version": "1.0.0", + "description": "Migrates usage of the legacy APIs `res.redirect(url, status)` to use the recommended argument order `res.redirect(status, url)`.", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/redirect-arg-order", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/redirect-arg-order/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/redirect-arg-order/src/workflow.ts b/codemods/redirect-arg-order/src/workflow.ts new file mode 100644 index 0000000..58135f8 --- /dev/null +++ b/codemods/redirect-arg-order/src/workflow.ts @@ -0,0 +1,44 @@ +import type Js from '@codemod.com/jssg-types/src/langs/javascript' +import type { Edit, SgRoot } from '@codemod.com/jssg-types/src/main' + +async function transform(root: SgRoot): Promise { + const rootNode = root.root() + + const nodes = rootNode.findAll({ + rule: { + pattern: '$OBJ.$METHOD($$$ARG)', + }, + constraints: { + METHOD: { regex: '^(redirect)$' }, + }, + }) + + if (!nodes.length) return null + + const edits: Edit[] = [] + + for (const call of nodes) { + const obj = call.getMatch('OBJ') + const args = call.getMultipleMatches('ARG') + if (!obj || args.length < 3) continue + + const objDef = obj.definition({ resolveExternal: false }) + if (!objDef) continue + + // $$$ARG yields argument nodes interleaved with separators, so arg nodes are at 0,2,4... + const first = args[0] + const second = args[2] + if (!first || !second) continue + + // Only transform legacy form redirect(url, status) where second is number + if (second.is('number') && !first.is('number')) { + edits.push(call.replace(`${obj.text()}.redirect(${second.text()}, ${first.text()})`)) + } + } + + if (!edits.length) return null + + return rootNode.commitEdits(edits) +} + +export default transform diff --git a/codemods/redirect-arg-order/tests/expected/redirect.ts b/codemods/redirect-arg-order/tests/expected/redirect.ts new file mode 100644 index 0000000..3db2d52 --- /dev/null +++ b/codemods/redirect-arg-order/tests/expected/redirect.ts @@ -0,0 +1,38 @@ +import express from "express"; +import { redirect } from "somelibrary"; + +const app = express(); + +app.get("/", function (...arg) { + const [, res] = arg + res.redirect(); +}); + +app.get("/", function (...arg) { + const [, res] = arg + res.redirect(301, "/other-page"); +}); + +app.get("/", function (req, res) { + res.redirect(); +}); + +app.get("/", function (req, res) { + res.redirect(301, "/other-page"); +}); + +app.get("/", function (req, response) { + response.redirect(301, "/other-page"); +}); + +app.get("/", function (req, res) { + res.redirect(301, "/other-page"); +}); + +app.get("/", function (req, res) { + res.redirect("/other-page"); +}); + +app.get("/", function (req, res) { + redirect(301, "/other-page"); +}); \ No newline at end of file diff --git a/codemods/redirect-arg-order/tests/input/redirect.ts b/codemods/redirect-arg-order/tests/input/redirect.ts new file mode 100644 index 0000000..805d5a5 --- /dev/null +++ b/codemods/redirect-arg-order/tests/input/redirect.ts @@ -0,0 +1,38 @@ +import express from "express"; +import { redirect } from "somelibrary"; + +const app = express(); + +app.get("/", function (...arg) { + const [, res] = arg + res.redirect(); +}); + +app.get("/", function (...arg) { + const [, res] = arg + res.redirect("/other-page", 301); +}); + +app.get("/", function (req, res) { + res.redirect(); +}); + +app.get("/", function (req, res) { + res.redirect("/other-page", 301); +}); + +app.get("/", function (req, response) { + response.redirect("/other-page", 301); +}); + +app.get("/", function (req, res) { + res.redirect(301, "/other-page"); +}); + +app.get("/", function (req, res) { + res.redirect("/other-page"); +}); + +app.get("/", function (req, res) { + redirect(301, "/other-page"); +}); \ No newline at end of file diff --git a/codemods/redirect-arg-order/workflow.yaml b/codemods/redirect-arg-order/workflow.yaml new file mode 100644 index 0000000..08a3b89 --- /dev/null +++ b/codemods/redirect-arg-order/workflow.yaml @@ -0,0 +1,28 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of the legacy APIs `res.redirect(url, status)` to use the recommended argument order `res.redirect(status, url)`. + js-ast-grep: + js_file: src/workflow.ts + base_path: . + semantic_analysis: file + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1bf6ff7..ddda229 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,14 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/redirect-arg-order": { + "name": "@expressjs/redirect-arg-order", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "codemods/route-del-to-delete": { "name": "@expressjs/route-del-to-delete", "version": "1.0.0", @@ -1057,6 +1065,10 @@ "resolved": "codemods/pluralize-method-names", "link": true }, + "node_modules/@expressjs/redirect-arg-order": { + "resolved": "codemods/redirect-arg-order", + "link": true + }, "node_modules/@expressjs/route-del-to-delete": { "resolved": "codemods/route-del-to-delete", "link": true From 5464214fb1dd9eb034dbb8b7f65b4a8b6c555255 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 13 Jan 2026 10:33:58 -0500 Subject: [PATCH 39/52] feat(req-param): migrate req-param to codemod.com (#94) * feat(req-param): migrate req-param to codemod.com * feat(req-param): update migration documentation * fix(transform): handle empty nodes and edits cases in transformation logic * rename codemod to explicit-request-params --- codemods/explicit-request-params/README.md | 38 ++++++++++ codemods/explicit-request-params/codemod.yaml | 24 ++++++ codemods/explicit-request-params/package.json | 22 ++++++ .../explicit-request-params/src/workflow.ts | 73 +++++++++++++++++++ .../tests/expected/params.ts | 39 ++++++++++ .../tests/input/params.ts | 39 ++++++++++ .../explicit-request-params/workflow.yaml | 28 +++++++ package-lock.json | 21 ++++++ 8 files changed, 284 insertions(+) create mode 100644 codemods/explicit-request-params/README.md create mode 100644 codemods/explicit-request-params/codemod.yaml create mode 100644 codemods/explicit-request-params/package.json create mode 100644 codemods/explicit-request-params/src/workflow.ts create mode 100644 codemods/explicit-request-params/tests/expected/params.ts create mode 100644 codemods/explicit-request-params/tests/input/params.ts create mode 100644 codemods/explicit-request-params/workflow.yaml diff --git a/codemods/explicit-request-params/README.md b/codemods/explicit-request-params/README.md new file mode 100644 index 0000000..34cb527 --- /dev/null +++ b/codemods/explicit-request-params/README.md @@ -0,0 +1,38 @@ +# Migrate legacy `req.param(name)` + +The `req.param(name)` helper that used to magically look up values from multiple places has been removed. This potentially confusing and dangerous method of retrieving form data has been removed. You will now need to specifically look for the submitted parameter name in the `req.params`, `req.body`, or `req.query` object. + +## Examples + +### Replacing `req.param('body')` and `req.param('query')` + +Replace `req.param('body')` with `req.body` and +`req.param('query')` with `req.query`. + +```diff +app.get('/', (req, res) => { + // Before +- const reqBody = req.param('body'); +- const reqQuery = req.param('query'); + // After ++ const reqBody = req.body; ++ const reqQuery = req.query; +}); +``` + +### Replacing `req.param('paramName')` + +Replace `req.param('paramName')` with `req.params.paramName`. + +```diff +app.get('/user/:id', (req, res) => { + // Before +- const userId = req.param('id'); + // After ++ const userId = req.params.id; +}); +``` + +## References + +- [Migration of `req.param()`](https://expressjs.com/en/guide/migrating-5.html#req.param) diff --git a/codemods/explicit-request-params/codemod.yaml b/codemods/explicit-request-params/codemod.yaml new file mode 100644 index 0000000..a11cf3e --- /dev/null +++ b/codemods/explicit-request-params/codemod.yaml @@ -0,0 +1,24 @@ +schema_version: "1.0" +name: "@expressjs/explicit-request-params" +version: "1.0.0" +description: Migrates usage of the legacy APIs `req.param(name)` to the current recommended approaches +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/explicit-request-params" +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - params + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/explicit-request-params/package.json b/codemods/explicit-request-params/package.json new file mode 100644 index 0000000..817ffaf --- /dev/null +++ b/codemods/explicit-request-params/package.json @@ -0,0 +1,22 @@ +{ + "name": "@expressjs/explicit-request-params", + "private": true, + "version": "1.0.0", + "description": "Migrates usage of the legacy APIs `req.param(name)` to the current recommended approaches.", + "type": "module", + "scripts": { + "test": "npx codemod jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/explicit-request-params", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/explicit-request-params/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/explicit-request-params/src/workflow.ts b/codemods/explicit-request-params/src/workflow.ts new file mode 100644 index 0000000..3af7a37 --- /dev/null +++ b/codemods/explicit-request-params/src/workflow.ts @@ -0,0 +1,73 @@ +import type Js from '@codemod.com/jssg-types/src/langs/javascript' +import type { Edit, SgNode, SgRoot } from '@codemod.com/jssg-types/src/main' + +function getStringLiteralValue(node: SgNode): string | null { + if (!node.is('string')) return null + + const fragments = node.findAll({ rule: { kind: 'string_fragment' } }) + if (fragments.length !== 1) return null + return fragments[0]?.text() ?? null +} + +function findParentFunctionParameters(node: SgNode): SgNode | null { + let parent = node.parent() + while (parent) { + if (parent.is('formal_parameters')) return parent + parent = parent.parent() + } + return null +} + +async function transform(root: SgRoot): Promise { + const rootNode = root.root() + + const nodes = rootNode.findAll({ + rule: { + pattern: '$OBJ.$METHOD($ARG)', + }, + constraints: { + METHOD: { regex: '^(param)$' }, + }, + }) + + if (!nodes.length) return null + + const edits: Edit[] = [] + + for (const call of nodes) { + const arg = call.getMatch('ARG') + const obj = call.getMatch('OBJ') + + if (!arg || !obj) continue + const objDef = obj.definition({ resolveExternal: false }) + if (!objDef) continue + + const isParameter = objDef.node.matches({ + rule: { inside: { kind: 'formal_parameters', stopBy: 'end' } }, + }) + if (!isParameter) continue + + const parameters = findParentFunctionParameters(objDef.node) + if (!parameters) continue + const firstParameter = parameters.find({ rule: { kind: 'identifier' } }) + + if (!firstParameter) continue + const requestName = firstParameter.text() + + const argValue = getStringLiteralValue(arg) + + if (argValue === 'body') { + edits.push(call.replace(`${requestName}.body`)) + } else if (argValue === 'query') { + edits.push(call.replace(`${requestName}.query`)) + } else if (argValue) { + edits.push(call.replace(`${requestName}.params.${argValue}`)) + } + } + + if (!edits.length) return null + + return rootNode.commitEdits(edits) +} + +export default transform diff --git a/codemods/explicit-request-params/tests/expected/params.ts b/codemods/explicit-request-params/tests/expected/params.ts new file mode 100644 index 0000000..2457634 --- /dev/null +++ b/codemods/explicit-request-params/tests/expected/params.ts @@ -0,0 +1,39 @@ +import express from "express"; + +const app = express(); + +app.get("/", function (req, res) { + const reqBody = req.body; + const reqQuery = req.query; + const reqQueryTest = req.query.test; + const reqOther = req.params.other; + const reqOtherNested = req.params.other.nested; +}); + +app.get("/", function (request, response) { + const reqBody = request.body; + const reqQuery = request.query; + const reqQueryTest = request.query.test; + const reqOther = request.params.other; + const reqOtherNested = request.params.other.nested; +}); + +app.get("/", (req, res) => { + const reqBody = req.body; + const reqQuery = req.query; + const reqQueryTest = req.query.test; + const reqOther = req.params.other; + const reqOtherNested = req.params.other.nested; +}); + +app.get("/", (request, response) => { + const reqBody = request.body; + const reqQuery = request.query; + const reqQueryTest = request.query.test; + const reqOther = request.params.other; + const reqOtherNested = request.params.other.nested; +}); + +app.param(function () { + // my important logic +}) \ No newline at end of file diff --git a/codemods/explicit-request-params/tests/input/params.ts b/codemods/explicit-request-params/tests/input/params.ts new file mode 100644 index 0000000..45f1d0f --- /dev/null +++ b/codemods/explicit-request-params/tests/input/params.ts @@ -0,0 +1,39 @@ +import express from "express"; + +const app = express(); + +app.get("/", function (req, res) { + const reqBody = req.param('body'); + const reqQuery = req.param('query'); + const reqQueryTest = req.param('query').test; + const reqOther = req.param('other'); + const reqOtherNested = req.param('other').nested; +}); + +app.get("/", function (request, response) { + const reqBody = request.param('body'); + const reqQuery = request.param('query'); + const reqQueryTest = request.param('query').test; + const reqOther = request.param('other'); + const reqOtherNested = request.param('other').nested; +}); + +app.get("/", (req, res) => { + const reqBody = req.param('body'); + const reqQuery = req.param('query'); + const reqQueryTest = req.param('query').test; + const reqOther = req.param('other'); + const reqOtherNested = req.param('other').nested; +}); + +app.get("/", (request, response) => { + const reqBody = request.param('body'); + const reqQuery = request.param('query'); + const reqQueryTest = request.param('query').test; + const reqOther = request.param('other'); + const reqOtherNested = request.param('other').nested; +}); + +app.param(function () { + // my important logic +}) \ No newline at end of file diff --git a/codemods/explicit-request-params/workflow.yaml b/codemods/explicit-request-params/workflow.yaml new file mode 100644 index 0000000..b9ac0a6 --- /dev/null +++ b/codemods/explicit-request-params/workflow.yaml @@ -0,0 +1,28 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of the legacy APIs `req.param(name)` to the current recommended approaches + js-ast-grep: + js_file: src/workflow.ts + base_path: . + semantic_analysis: file + include: + - "**/*.cjs" + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ddda229..f9dd8a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,6 +55,14 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/explicit-request-params": { + "name": "@expressjs/explicit-request-params", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "codemods/magic-redirect": { "name": "@expressjs/back-redirect-deprecated", "version": "1.0.0", @@ -80,6 +88,15 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/req-param": { + "name": "@expressjs/req-param", + "version": "1.0.0", + "extraneous": true, + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "codemods/route-del-to-delete": { "name": "@expressjs/route-del-to-delete", "version": "1.0.0", @@ -1061,6 +1078,10 @@ "resolved": "codemods/camelcase-sendfile", "link": true }, + "node_modules/@expressjs/explicit-request-params": { + "resolved": "codemods/explicit-request-params", + "link": true + }, "node_modules/@expressjs/pluralize-method-names": { "resolved": "codemods/pluralize-method-names", "link": true From add40f73be5b4bb51893c2951687e23816010a2d Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 13 Jan 2026 10:58:33 -0500 Subject: [PATCH 40/52] feat(v5-migration-recipe): create migration recipe for Express.js v5 (#101) * feat(v5-migration-recipe): create migration recipe for Express.js v5 addressing deprecated APIs * feat(v5-migration-recipe): add transformation for migrating app.del() to app.delete() * Update codemods/v5-migration-recipe/workflow.yaml Co-authored-by: Mohamad Mohebifar Signed-off-by: Sebastian Beltran * feat(v5-migration-recipe): update repository link and add metadata to package-lock * fix(v5-migration-recipe): update registry source for req.param migration to explicit-request-params --------- Signed-off-by: Sebastian Beltran Co-authored-by: Mohamad Mohebifar --- codemods/v5-migration-recipe/README.md | 17 ++++++++++++ codemods/v5-migration-recipe/codemod.yaml | 26 ++++++++++++++++++ codemods/v5-migration-recipe/package.json | 19 +++++++++++++ codemods/v5-migration-recipe/workflow.yaml | 32 ++++++++++++++++++++++ package-lock.json | 12 ++++++++ 5 files changed, 106 insertions(+) create mode 100644 codemods/v5-migration-recipe/README.md create mode 100644 codemods/v5-migration-recipe/codemod.yaml create mode 100644 codemods/v5-migration-recipe/package.json create mode 100644 codemods/v5-migration-recipe/workflow.yaml diff --git a/codemods/v5-migration-recipe/README.md b/codemods/v5-migration-recipe/README.md new file mode 100644 index 0000000..3b1abc1 --- /dev/null +++ b/codemods/v5-migration-recipe/README.md @@ -0,0 +1,17 @@ +# Migrate recipes for Express.js v5 + +This codemod migration recipe helps you update your Express.js v4 applications to be compatible with Express.js v5 by addressing deprecated APIs. + +Included transformations: + +- **Back Redirect Deprecated**: This transformation updates instances of `res.redirect('back')` and `res.location('back')` to use the recommended alternatives. Registry entry: [https://app.codemod.com/registry/@expressjs/back-redirect-deprecated](https://app.codemod.com/registry/@expressjs/back-redirect-deprecated). +- **Explicit Request Params**: Migrates usage of the legacy API `req.param(name)` to the current recommended alternatives. Registry entry: [https://app.codemod.com/registry/@expressjs/explicit-request-params](https://app.codemod.com/registry/@expressjs/explicit-request-params). +- **Pluralize Method Names**: Migrates deprecated singular request methods to their pluralized counterparts where applicable. Registry entry: [https://app.codemod.com/registry/@expressjs/pluralize-method-names](https://app.codemod.com/registry/@expressjs/pluralize-method-names). +- **Status Send Order**: Migrates usages of `res.send(status)`, `res.send(obj, status)`, `res.json(obj, status)`, and `res.jsonp(obj, status)` to the recommended argument ordering. Registry entry: [https://app.codemod.com/registry/@expressjs/status-send-order](https://app.codemod.com/registry/@expressjs/status-send-order). +- **Redirect Arg Order**: Converts `res.redirect(url, status)` calls to the recommended `res.redirect(status, url)` ordering. Registry entry: [https://app.codemod.com/registry/@expressjs/redirect-arg-order](https://app.codemod.com/registry/@expressjs/redirect-arg-order). +- **Camelcase Sendfile**: Replaces legacy `res.sendfile(file)` usages with the camel-cased `res.sendFile(file)` API. Registry entry: [https://app.codemod.com/registry/@expressjs/camelcase-sendfile](https://app.codemod.com/registry/@expressjs/camelcase-sendfile). +- **Route Del to Delete**: Migrates usage of the legacy APIs `app.del()` to `app.delete()`. Registry entry: [https://app.codemod.com/registry/@expressjs/route-del-to-delete](https://app.codemod.com/registry/@expressjs/route-del-to-delete). + +## References + +- [Express.js v5 Migration Guide](https://expressjs.com/en/guide/migrating-5) diff --git a/codemods/v5-migration-recipe/codemod.yaml b/codemods/v5-migration-recipe/codemod.yaml new file mode 100644 index 0000000..418dc9e --- /dev/null +++ b/codemods/v5-migration-recipe/codemod.yaml @@ -0,0 +1,26 @@ +schema_version: "1.0" +name: "@expressjs/v5/migration-recipe" +version: "1.0.0" +description: This codemod migration recipe helps you update your Express.js v4 applications to be compatible with Express.js v5 by addressing deprecated APIs. +author: bjohansebas (Sebastian Beltran) +license: MIT +workflow: workflow.yaml +repository: "https://github.com/expressjs/codemod/tree/HEAD/codemods/v5-migration-recipe" +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + - express + - v5 + - v4 + - legacy + +registry: + access: public + visibility: public \ No newline at end of file diff --git a/codemods/v5-migration-recipe/package.json b/codemods/v5-migration-recipe/package.json new file mode 100644 index 0000000..7663ab4 --- /dev/null +++ b/codemods/v5-migration-recipe/package.json @@ -0,0 +1,19 @@ +{ + "name": "@expressjs/v5-migration-recipe", + "private": true, + "version": "1.0.0", + "description": "This codemod migration recipe helps you update your Express.js v4 applications to be compatible with Express.js v5 by addressing deprecated APIs.", + "type": "module", + "repository": { + "type": "git", + "url": "git+https://github.com/expressjs/codemod.git", + "directory": "codemods/v5-migration-recipe", + "bugs": "https://github.com/expressjs/codemod/issues" + }, + "author": "bjohansebas (Sebastian Beltran)", + "license": "MIT", + "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/v5-migration-recipe/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } +} diff --git a/codemods/v5-migration-recipe/workflow.yaml b/codemods/v5-migration-recipe/workflow.yaml new file mode 100644 index 0000000..77ae2fd --- /dev/null +++ b/codemods/v5-migration-recipe/workflow.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/codemod-com/codemod/refs/heads/main/schemas/workflow.json + +version: "1" + +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Migrates usage of the legacy APIs `res.redirect('back')` and `res.location('back')` to the current recommended approaches + codemod: + source: "@expressjs/back-redirect-deprecated" + - name: Migrates usage of the legacy APIs `req.param(name)` to the current recommended approaches. + codemod: + source: "@expressjs/explicit-request-params" + - name: Migrates usage of deprecated singular request methods to their pluralized versions in Express.js applications. + codemod: + source: "@expressjs/pluralize-method-names" + - name: Migrates usage of the legacy APIs `res.send(status)`, `res.send(obj, status)`, `res.json(obj, status)` and `res.jsonp(obj, status)` to the current recommended approaches + codemod: + source: "@expressjs/status-send-order" + - name: Migrates usage of the legacy APIs `res.redirect(url, status)` to use the recommended argument order `res.redirect(status, url)`. + codemod: + source: "@expressjs/redirect-arg-order" + - name: Migrates usage of the legacy API `res.sendfile(file)` to `res.sendFile(file)` + codemod: + source: "@expressjs/camelcase-sendfile" + - name: Migrates usage of the legacy APIs `app.del()` to `app.delete()` + codemod: + source: "@expressjs/route-del-to-delete" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f9dd8a2..fc318a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -113,6 +113,14 @@ "@codemod.com/jssg-types": "^1.3.1" } }, + "codemods/v5-migration-recipe": { + "name": "@expressjs/v5-migration-recipe", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@codemod.com/jssg-types": "^1.3.1" + } + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -1098,6 +1106,10 @@ "resolved": "codemods/status-send-order", "link": true }, + "node_modules/@expressjs/v5-migration-recipe": { + "resolved": "codemods/v5-migration-recipe", + "link": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", From 8e96b6f212509e3655248fdc03924908ec75003e Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 13 Jan 2026 11:06:24 -0500 Subject: [PATCH 41/52] fix(publish-workflow): update test command to use --if-present flag (#109) --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4ea7eb5..92fe828 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -96,7 +96,7 @@ jobs: # Run test before login to not waste time if it fails - name: Run codemod Tests working-directory: ${{ steps.parse-tag.outputs.codemod-path }} - run: npm run test + run: npm run --if-present test - name: Authenticate with Codemod registry env: From 943bf417cfc51d3900f66655b199f7f27647652b Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 13 Jan 2026 11:12:14 -0500 Subject: [PATCH 42/52] fix(codemod.yaml): correct package name format for v5 migration recipe (#110) --- codemods/v5-migration-recipe/codemod.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codemods/v5-migration-recipe/codemod.yaml b/codemods/v5-migration-recipe/codemod.yaml index 418dc9e..5fe3fe7 100644 --- a/codemods/v5-migration-recipe/codemod.yaml +++ b/codemods/v5-migration-recipe/codemod.yaml @@ -1,5 +1,5 @@ schema_version: "1.0" -name: "@expressjs/v5/migration-recipe" +name: "@expressjs/v5-migration-recipe" version: "1.0.0" description: This codemod migration recipe helps you update your Express.js v4 applications to be compatible with Express.js v5 by addressing deprecated APIs. author: bjohansebas (Sebastian Beltran) From 46ce85feff82f9da38f1fcfda0ec1d37ebc01a93 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 13 Jan 2026 11:24:23 -0500 Subject: [PATCH 43/52] chore: remove old package (#96) * chore: remove old package * docs: update docs * docs: update contributing guide with new codemod initialization steps * Update README.md Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Signed-off-by: Sebastian Beltran * chore(package.json): remove obsolete bin and engines fields * Apply suggestion from @bjohansebas Signed-off-by: Sebastian Beltran --------- Signed-off-by: Sebastian Beltran Co-authored-by: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> --- .github/actions/generate-help-docs.mjs | 30 - .github/workflows/ci.yml | 7 +- .github/workflows/generate-readme.yml | 49 - CONTRIBUTING.md | 83 +- README.md | 68 +- codemods/.gitkeep | 0 commands/__test__/transform.spec.ts | 118 - commands/__test__/upgrade.spec.ts | 69 - commands/transform.ts | 58 - commands/upgrade.ts | 63 - config.ts | 22 - index.ts | 33 - jest.config.js | 7 - package-lock.json | 4973 +---------------- package.json | 29 +- transforms/__test__/magic-redirect.spec.ts | 3 - .../__test__/pluralized-methods.spec.ts | 15 - transforms/__test__/req-param.spec.ts | 3 - transforms/__test__/util.ts | 16 - .../__test__/v4-deprecated-signatures.spec.ts | 3 - .../magic-redirect/location.input.ts | 20 - .../magic-redirect/location.output.ts | 20 - .../magic-redirect/redirect.input.ts | 20 - .../magic-redirect/redirect.output.ts | 20 - .../pluralized-methods/charset.input.ts | 13 - .../pluralized-methods/charset.output.ts | 13 - .../pluralized-methods/encoding.input.ts | 13 - .../pluralized-methods/encoding.output.ts | 13 - .../pluralized-methods/language.input.ts | 14 - .../pluralized-methods/language.output.ts | 13 - .../req-param/req-param.input.ts | 39 - .../req-param/req-param.output.ts | 39 - .../v4-deprecated-signatures/delete.input.ts | 39 - .../v4-deprecated-signatures/delete.output.ts | 39 - .../v4-deprecated-signatures/json.input.ts | 71 - .../v4-deprecated-signatures/json.output.ts | 71 - .../v4-deprecated-signatures/jsonp.input.ts | 61 - .../v4-deprecated-signatures/jsonp.output.ts | 61 - .../redirect.input.ts | 38 - .../redirect.output.ts | 38 - .../send-file.input.ts | 67 - .../send-file.output.ts | 67 - .../v4-deprecated-signatures/send.input.ts | 75 - .../v4-deprecated-signatures/send.output.ts | 75 - transforms/magic-redirect.ts | 56 - transforms/pluralized-methods.ts | 22 - transforms/req-param.ts | 45 - transforms/v4-deprecated-signatures.ts | 158 - tsconfig.json | 7 +- utils/__test__/recastOptions.spec.ts | 68 - utils/parse.ts | 5 - utils/prompts.ts | 20 - utils/recastOptions.ts | 17 - utils/recursiveParent.ts | 23 - 54 files changed, 221 insertions(+), 6788 deletions(-) delete mode 100644 .github/actions/generate-help-docs.mjs delete mode 100644 .github/workflows/generate-readme.yml delete mode 100644 codemods/.gitkeep delete mode 100644 commands/__test__/transform.spec.ts delete mode 100644 commands/__test__/upgrade.spec.ts delete mode 100644 commands/transform.ts delete mode 100644 commands/upgrade.ts delete mode 100644 config.ts delete mode 100644 index.ts delete mode 100644 jest.config.js delete mode 100644 transforms/__test__/magic-redirect.spec.ts delete mode 100644 transforms/__test__/pluralized-methods.spec.ts delete mode 100644 transforms/__test__/req-param.spec.ts delete mode 100644 transforms/__test__/util.ts delete mode 100644 transforms/__test__/v4-deprecated-signatures.spec.ts delete mode 100644 transforms/__testfixtures__/magic-redirect/location.input.ts delete mode 100644 transforms/__testfixtures__/magic-redirect/location.output.ts delete mode 100644 transforms/__testfixtures__/magic-redirect/redirect.input.ts delete mode 100644 transforms/__testfixtures__/magic-redirect/redirect.output.ts delete mode 100644 transforms/__testfixtures__/pluralized-methods/charset.input.ts delete mode 100644 transforms/__testfixtures__/pluralized-methods/charset.output.ts delete mode 100644 transforms/__testfixtures__/pluralized-methods/encoding.input.ts delete mode 100644 transforms/__testfixtures__/pluralized-methods/encoding.output.ts delete mode 100644 transforms/__testfixtures__/pluralized-methods/language.input.ts delete mode 100644 transforms/__testfixtures__/pluralized-methods/language.output.ts delete mode 100644 transforms/__testfixtures__/req-param/req-param.input.ts delete mode 100644 transforms/__testfixtures__/req-param/req-param.output.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/delete.input.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/delete.output.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/json.input.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/json.output.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/jsonp.input.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/jsonp.output.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/redirect.input.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/redirect.output.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/send-file.input.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/send-file.output.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/send.input.ts delete mode 100644 transforms/__testfixtures__/v4-deprecated-signatures/send.output.ts delete mode 100644 transforms/magic-redirect.ts delete mode 100644 transforms/pluralized-methods.ts delete mode 100644 transforms/req-param.ts delete mode 100644 transforms/v4-deprecated-signatures.ts delete mode 100644 utils/__test__/recastOptions.spec.ts delete mode 100644 utils/parse.ts delete mode 100644 utils/prompts.ts delete mode 100644 utils/recastOptions.ts delete mode 100644 utils/recursiveParent.ts diff --git a/.github/actions/generate-help-docs.mjs b/.github/actions/generate-help-docs.mjs deleted file mode 100644 index 6e9417a..0000000 --- a/.github/actions/generate-help-docs.mjs +++ /dev/null @@ -1,30 +0,0 @@ -import { execSync } from 'node:child_process' -import { readFile, writeFile } from 'node:fs/promises' -import { join } from 'node:path' -import { TRANSFORM_OPTIONS } from '../../build/config.js' - -let output = execSync('node ../../build/index.js --help', { - encoding: 'utf-8', -}) - -output = output.replace( - /(?<=Usage: @expressjs\/codemod \[codemod\] \[source\] \[options\]\n\n)[\s\S]*?(?=Options:)/, - '', -) - -const codemods = TRANSFORM_OPTIONS.map(({ value, description, version }) => { - return `### ${value.replaceAll('-', ' ')} (v${version}) - -${description} - -` -}).join('') - -const readmePath = join('..', '..', 'README.md') -const readme = await readFile(readmePath, 'utf-8') - -const updatedReadme = readme - .replace(/(?<=\n\n```\n)[\s\S]*?(?=```\n\n)/, output) - .replace(/(?<=\n\n)[\s\S]*?(?=)/, codemods) - -await writeFile(readmePath, updatedReadme, 'utf-8') diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fa0437..7707787 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [18, 19, 20, 21, 22, 23] + node-version: [18, 19, 20, 21, 22, 23, 24, 25] # Node.js release schedule: https://nodejs.org/en/about/releases/ name: Node.js ${{ matrix.node-version }} - ${{matrix.os}} @@ -71,11 +71,6 @@ jobs: echo "Node.js version: $(node -v)" echo "NPM version: $(npm -v)" - - name: Run tests-legacy cli - shell: bash - run: | - npm run test-legacy:ci - - name: Run test shell: bash run: | diff --git a/.github/workflows/generate-readme.yml b/.github/workflows/generate-readme.yml deleted file mode 100644 index 60de381..0000000 --- a/.github/workflows/generate-readme.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Generate dynamic README - -on: - workflow_dispatch: - push: - branches: - - main - paths: - - index.ts - - config.ts - -permissions: - contents: read - -jobs: - generate-readme: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - name: Setup Node.js - uses: actions/setup-node@v6.1.0 - with: - node-version: '22' - - - name: Install dependencies - run: npm install - - - name: Build package - run: npm run build - - - name: Run script - working-directory: .github/actions - run: node ./generate-help-docs.mjs - - - name: Create Pull Request - uses: gr2m/create-or-update-pull-request-action@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - title: 'Update options in README' - commit-message: 'chore: update README' - branch: readme-${{ github.sha }} - body: > - 'Update the available options of the package in the CLI' \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d9821e..732bcc0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,86 +8,71 @@ The steps below will give you a general idea of how to prepare your local enviro 1. [Create an issue](https://github.com/expressjs/codemod/issues/new) for the bug you want to fix or the feature that you want to add. -2. Create your own [fork](https://github.com/expressjs/codemod) on GitHub -3. Clone your fork using SSH, GitHub CLI, or HTTPS. + +1. Create your own [fork](https://github.com/expressjs/codemod) on GitHub + +1. Clone your fork using SSH, GitHub CLI, or HTTPS. + ```sh git clone git@github.com:/codemod.git # SSH git clone https://github.com//codemod.git # HTTPS gh repo clone /codemod # GitHub CLI ``` -4. Change into the nodejs.org directory. + +1. Change into the codemod directory. ```sh cd codemod ``` -5. Create a remote to keep your fork and local clone up-to-date. + +1. Create a remote to keep your fork and local clone up-to-date. + ```sh git remote add upstream git@github.com:expressjs/codemod.git # SSH git remote add upstream https://github.com/expressjs/codemod.git # HTTPS gh repo sync expressjs/codemod # GitHub CLI ``` -6. Create a new branch for your work. + +1. Create a new branch for your work. + ```sh git checkout -b name-of-your-branch ``` -7. Run the following to install the dependencies and start a local build of your work. + +1. Run the following to install the dependencies. + ```sh npm ci # installs this project's dependencies -npm run dev # starts a development environment + ``` -8. Perform your changes -9. Ensure your code is linted by running `npm run lint` -- fix any issue you +1. create the [new codemod](#how-to-add-codemods) or make your changes. + +1. Ensure your code is linted by running `npm run lint` -- fix any issue you see listed. -10. If the tests pass, you can commit your changes to your fork and then create + +1. If the tests pass, you can commit your changes to your fork and then create a pull request from there. Make sure to reference your issue from the pull request comments by including the issue number e.g. `#123`. ## How to add codemods -We use `jscodeshift` to create and run the codemods. To add a new codemod for Express, we follow the following process. - -1. Create a new file in the `transforms` directory. For example, `transforms/pluralized-methods.ts`. - -2. Write your codemod. Here's an example that pluralizes Express methods: - -```typescript -// filepath: codemod/transforms/pluralized-methods.ts -import type { API, FileInfo } from 'jscodeshift' -import { Identifier, identifier } from 'jscodeshift' -import { getParsedFile } from '../utils/parse' - -export default function transformer(file: FileInfo, _api: API): string { - const parsedFile = getParsedFile(file) +Each codemod recides in its own directory inside the `codemods` folder. For initializing a new codemod, you can use the following command in the root of the repository and change the parameters as needed: - const identifierNamesToReplace = ['acceptsLanguage', 'acceptsCharset', 'acceptsEncoding'] - - for (const singular of identifierNamesToReplace) { - const plural = `${singular}s` - - parsedFile - .find(Identifier, { - name: singular, - }) - .replaceWith(() => identifier(plural)) - } - - return parsedFile.toSource() -} +```sh +npx codemod init codemods/name-of-codemod --name @expressjs/name-of-codemod --description "Brief description of the codemod" --git-repository-url "git+https://github.com/expressjs/codemod.git" --author "your-github-username (Your Name)" --language typescript --project-type ast-grep-js --package-manager npm --license MIT --no-interactive ``` -3. Add tests to verify the functionality of the codemod - - A new file is created in the `/transforms/__test__` directory with the same name as the codemod with the following content - ```ts - // filepath: codemod/transforms/__test__/pluralized-methods.ts +Then, rename the `scripts` folder to `src` to keep it consistent with the rest of the repository. After that, you can start implementing your codemod by editing the `codemod.yaml` file and adding any additional files your codemod requires. - import { testSpecBuilder } from './util' +## Useful Resources - testSpecBuilder('magic-redirect') - ``` - - Two new files are created, `name-codemod.input.ts` and `name_codemod.output.ts`, inside the `/transforms/__testfixtures__` directory - - The files ending in `.input.ts ` contain the content that should be changed by the codemod - - The `.output.ts` files contain the content that should be present after the codemod has been correctly applied. +- [Codemod CLI Reference](https://docs.codemod.com/cli/cli-reference) +- [Codemod Workflow Documentation](https://docs.codemod.com/cli/workflows) +- [Codemod Studio Documentation](https://docs.codemod.com/codemod-studio) +- [JS ast-grep (jssg) API reference](https://docs.codemod.com/jssg/reference) +- [JS ast-grep Testing Utilities](https://docs.codemod.com/jssg/testing) +- [JS ast-grep Semantic Analysis](https://docs.codemod.com/jssg/semantic-analysis) +- [ast-grep Documentation](https://ast-grep.github.io/) -4. To make the codemod visible within the CLI, the `config.ts` file is modified, where a brief description of the codemod, its name, and the version of Express to which the migration should be applied are added. ## Developer's Certificate of Origin 1.1 diff --git a/README.md b/README.md index 77f28e6..fc911d0 100644 --- a/README.md +++ b/README.md @@ -1,74 +1,34 @@ # @expressjs/codemod -[![NPM Version][npm-version-image]][npm-url] -[![NPM Downloads][npm-downloads-image]][npm-downloads-url] [![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer] Express.js provides Codemod transforms to help you upgrade your express server when a feature is deprecated or removed. Codemods are transformations that run on your codebase programmatically. This allows for a large amount of changes to be applied without having to manually go through every file. -## Installation +## Usage -You don't need to install this package, run the following command: +### From Registry -```sh -npx @expressjs/codemod # or pnpx, bunx, etc. -``` - -or install globally: +With the codemod CLI you can run a workflow from the Codemod Registry. Replace `` with the name of the codemod you want to run: ```sh -npm i -g @expressjs/codemod # or pnpm, bun, etc. +npx codemod @expressjs/ ``` -## Usage +For see the list of available codemods, visit the [Express.js Codemod Registry](https://codemod.link/express). -Use `@expressjs/codemod -h` to explore available command-line options. +### From source - +You can also clone the repository and run the codemods locally. First, clone the repository: +```sh +git clone https://github.com/expressjs/codemod.git +cd /path/to/your-project +npx codemod workflow run -w /path/to/codemod/codemods//workflow.yaml ``` -Usage: @expressjs/codemod [codemod] [source] [options] - -Options: - -v, --version Output the current version of @expressjs/codemod. - -d, --dry Dry run (no changes are made to files) - -p, --print Print transformed files to stdout - --verbose Show more information about the transform process - --silent Don't print anything to stdout - -h, --help Display this help message. - -Commands: - upgrade [options] [source] Upgrade your express server to the latest - version. -``` - - - -## Available Codemods - -All the available codemods to update your express server: - - - -### magic redirect (v5.0.0) - -Transform the deprecated magic string "back" - -### pluralized methods (v5.0.0) - -Transform the methods to their pluralized versions - -### v4 deprecated signatures (v5.0.0) - -Transform the deprecated signatures in Express v4 - -### req param (v5.0.0) - -Change request.param() to dedicated methods - +See the [codemod CLI doc](https://docs.codemod.com/cli) for a full list of available commands. ## Contributing @@ -83,9 +43,5 @@ See the [Contributing Guide](https://github.com/expressjs/codemod/blob/main/CONT [MIT](LICENSE) -[npm-downloads-image]: https://badgen.net/npm/dm/@expressjs/codemod -[npm-downloads-url]: https://npmcharts.com/compare/@expressjs/codemod?minimal=true -[npm-url]: https://npmjs.org/package/@expressjs/codemod -[npm-version-image]: https://badgen.net/npm/v/@expressjs/codemod [ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/codemod/badge [ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/codemod \ No newline at end of file diff --git a/codemods/.gitkeep b/codemods/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/commands/__test__/transform.spec.ts b/commands/__test__/transform.spec.ts deleted file mode 100644 index 71e2c72..0000000 --- a/commands/__test__/transform.spec.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { sep } from 'node:path' -import { run } from 'jscodeshift/src/Runner' -import prompts from 'prompts' -import { transform } from '../transform' - -const defaultOptions = { - dry: true, - silent: true, -} - -const getSystemPath = (inputPath: string) => inputPath.replaceAll('/', sep) - -jest.mock('jscodeshift/src/Runner', () => ({ - run: jest.fn(), -})) - -describe('interactive mode', () => { - beforeEach(() => { - jest.clearAllMocks() - }) - - it('runs without codemodName and source params provided', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - prompts.inject(['magic-redirect']) - prompts.inject(['./transforms/__testfixtures__']) - - await transform(undefined, undefined, defaultOptions) - - expect(spyOnConsole).not.toHaveBeenCalled() - expect(run).toHaveBeenCalledTimes(1) - expect(run).toHaveBeenCalledWith( - expect.stringContaining(getSystemPath('/transforms/magic-redirect.js')), - expect.arrayContaining([expect.stringContaining(getSystemPath('/transforms/__testfixtures__'))]), - { - babel: false, - dry: true, - extensions: 'cts,mts,ts,js,mjs,cjs', - ignorePattern: '**/node_modules/**', - silent: true, - verbose: 0, - }, - ) - }) - - it('runs properly on incorrect user input', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - prompts.inject(['magic-redirect']) - - await transform('bad-codemod', './transforms/__testfixtures__', defaultOptions) - - expect(spyOnConsole).not.toHaveBeenCalled() - expect(run).toHaveBeenCalledTimes(1) - expect(run).toHaveBeenCalledWith( - expect.stringContaining(getSystemPath('/transforms/magic-redirect.js')), - expect.arrayContaining([expect.stringContaining(getSystemPath('/transforms/__testfixtures__'))]), - { - babel: false, - dry: true, - extensions: 'cts,mts,ts,js,mjs,cjs', - ignorePattern: '**/node_modules/**', - silent: true, - verbose: 0, - }, - ) - }) - - it('runs with codemodName and without source param provided', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - prompts.inject(['__testfixtures__']) - - await transform('magic-redirect', undefined, defaultOptions) - - expect(spyOnConsole).not.toHaveBeenCalled() - expect(run).toHaveBeenCalledTimes(1) - expect(run).toHaveBeenCalledWith( - expect.stringContaining(getSystemPath('/transforms/magic-redirect.js')), - expect.arrayContaining([expect.stringContaining('__testfixtures__')]), - { - babel: false, - dry: true, - extensions: 'cts,mts,ts,js,mjs,cjs', - ignorePattern: '**/node_modules/**', - silent: true, - verbose: 0, - }, - ) - }) -}) - -describe('Non-Interactive Mode', () => { - beforeEach(() => { - jest.clearAllMocks() - }) - - it('Transforms code with codemodName and source params provided', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - await transform('magic-redirect', '__testfixtures__', defaultOptions) - - expect(spyOnConsole).not.toHaveBeenCalled() - expect(run).toHaveBeenCalledTimes(1) - expect(run).toHaveBeenCalledWith( - expect.stringContaining(getSystemPath('/transforms/magic-redirect.js')), - expect.arrayContaining([expect.stringContaining('__testfixtures__')]), - { - babel: false, - dry: true, - extensions: 'cts,mts,ts,js,mjs,cjs', - ignorePattern: '**/node_modules/**', - silent: true, - verbose: 0, - }, - ) - }) -}) diff --git a/commands/__test__/upgrade.spec.ts b/commands/__test__/upgrade.spec.ts deleted file mode 100644 index c19b058..0000000 --- a/commands/__test__/upgrade.spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { run } from 'jscodeshift/src/Runner' -import prompts from 'prompts' -import { upgrade } from '../upgrade' - -jest.mock('jscodeshift/src/Runner', () => ({ - run: jest.fn(), -})) - -describe('interactive mode', () => { - beforeEach(() => { - jest.clearAllMocks() - }) - - it('runs without source params provided and select is true', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - prompts.inject([['magic-redirect', 'req-param']]) - - await upgrade('__testfixtures__', { select: true }) - - expect(spyOnConsole).toHaveBeenCalled() - expect(spyOnConsole).toHaveBeenCalledTimes(3) - expect(run).toHaveBeenCalledTimes(2) - }) - - it('runs with source params provided and select is true', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - prompts.inject([['magic-redirect', 'req-param']]) - - await upgrade('__testfixtures__', { select: true }) - - expect(spyOnConsole).toHaveBeenCalled() - expect(spyOnConsole).toHaveBeenCalledTimes(3) - expect(run).toHaveBeenCalledTimes(2) - }) - - it('runs without source params provided and select is undefined', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - prompts.inject(['__testfixtures__']) - - await upgrade(undefined) - - expect(spyOnConsole).toHaveBeenCalled() - expect(spyOnConsole).toHaveBeenCalledTimes(5) - expect(run).toHaveBeenCalledTimes(4) - }) -}) - -describe('Non-Interactive Mode', () => { - beforeEach(() => { - jest.clearAllMocks() - }) - - it('Transforms code with source params provided', async () => { - const spyOnConsole = jest.spyOn(console, 'log').mockImplementation() - - await upgrade('__testfixtures__') - - expect(spyOnConsole).toHaveBeenCalledTimes(5) - expect(spyOnConsole).toHaveBeenCalledWith('> Applying codemod: magic-redirect') - expect(spyOnConsole).toHaveBeenCalledWith('> Applying codemod: pluralized-methods') - expect(spyOnConsole).toHaveBeenCalledWith('> Applying codemod: req-param') - expect(spyOnConsole).toHaveBeenCalledWith('> Applying codemod: v4-deprecated-signatures') - expect(spyOnConsole).toHaveBeenLastCalledWith('\n> All codemods have been applied successfully. \n') - expect(run).toHaveBeenCalledTimes(4) - }) -}) diff --git a/commands/transform.ts b/commands/transform.ts deleted file mode 100644 index 601754c..0000000 --- a/commands/transform.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { join, resolve } from 'node:path' -import type { Options } from 'jscodeshift' -import { run as jscodeshift } from 'jscodeshift/src/Runner' -import { bold } from 'picocolors' -import prompts from 'prompts' -import { TRANSFORM_OPTIONS } from '../config' -import { onCancel, promptSource } from '../utils/prompts' - -const transformerDirectory = join(__dirname, '../', 'transforms') - -const selectCodemod = async (): Promise => { - const res = await prompts( - { - type: 'select', - name: 'transformer', - message: 'Which codemod would you like to apply?', - choices: TRANSFORM_OPTIONS.map(({ description, value, version }) => { - return { - title: `(${bold(`v${version}`)}) ${value}`, - description, - value, - } - }), - }, - { onCancel }, - ) - - return res.transformer -} - -export async function transform(codemodName?: string, source?: string, options?: Record) { - const existCodemod = TRANSFORM_OPTIONS.find(({ value }) => value === codemodName) - const codemodSelected = !codemodName || (codemodName && !existCodemod) ? await selectCodemod() : codemodName - - if (!codemodSelected) { - console.info('> Codemod is not selected. Exits the program. \n') - process.exit(1) - } - - const sourceSelected = source || (await promptSource('Which files or directories should the codemods be applied to?')) - - if (!sourceSelected) { - console.info('> Source path for project is not selected. Exits the program. \n') - process.exit(1) - } - - const transformerPath = join(transformerDirectory, `${codemodSelected}.js`) - - const args: Options = { - ...options, - verbose: options?.verbose ? 2 : 0, - babel: false, - ignorePattern: '**/node_modules/**', - extensions: 'cts,mts,ts,js,mjs,cjs', - } - - await jscodeshift(transformerPath, [resolve(sourceSelected)], args) -} diff --git a/commands/upgrade.ts b/commands/upgrade.ts deleted file mode 100644 index bcc134d..0000000 --- a/commands/upgrade.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { join, resolve } from 'node:path' -import type { Options } from 'jscodeshift' -import { run as jscodeshift } from 'jscodeshift/src/Runner' -import prompts from 'prompts' -import { TRANSFORM_OPTIONS } from '../config' -import { onCancel, promptSource } from '../utils/prompts' - -const transformerDirectory = join(__dirname, '../', 'transforms') - -export async function upgrade(source?: string, options?: Record) { - const sourceSelected = source || (await promptSource('Which directory should the codemods be applied to?')) - - if (!sourceSelected) { - console.info('> Source path for project is not selected. Exits the program. \n') - process.exit(1) - } - let codemods: string[] = [] - - if (options?.select) { - const { codemodsSelected } = await prompts( - { - type: 'multiselect', - name: 'codemodsSelected', - message: `The following 'codemods' are recommended for your upgrade. Select the ones to apply.`, - choices: TRANSFORM_OPTIONS.map(({ description, value, version }) => { - return { - title: `(v${version}) ${value}`, - description, - value, - selected: true, - } - }), - }, - { onCancel }, - ) - codemods = codemodsSelected - } else { - codemods = TRANSFORM_OPTIONS.map(({ value }) => value) - } - - const args: Options = { - dry: false, - babel: false, - silent: true, - ignorePattern: '**/node_modules/**', - extensions: 'cts,mts,ts,js,mjs,cjs', - } - - for (const codemod of codemods) { - const transformerPath = join(transformerDirectory, `${codemod}.js`) - - console.log(`> Applying codemod: ${codemod}`) - - try { - await jscodeshift(transformerPath, [resolve(sourceSelected)], args) - } catch (error) { - console.error(`> Error applying codemod: ${codemod}`) - console.error(error) - } - } - - console.log('\n> All codemods have been applied successfully. \n') -} diff --git a/config.ts b/config.ts deleted file mode 100644 index 2d0416e..0000000 --- a/config.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const TRANSFORM_OPTIONS = [ - { - description: 'Transform the deprecated magic string "back"', - value: 'magic-redirect', - version: '5.0.0', - }, - { - description: 'Transform the methods to their pluralized versions', - value: 'pluralized-methods', - version: '5.0.0', - }, - { - description: 'Transform the deprecated signatures in Express v4', - value: 'v4-deprecated-signatures', - version: '5.0.0', - }, - { - description: 'Change request.param() to dedicated methods', - value: 'req-param', - version: '5.0.0', - }, -] diff --git a/index.ts b/index.ts deleted file mode 100644 index a6ab0a3..0000000 --- a/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env node - -// Based on https://github.com/vercel/next.js/blob/26a2bab6fa0f0bdf9ff88f85d64342bb5a975658/packages/next-codemod/bin/next-codemod.ts -// @expressjs/codemod optional-name-of-transform optional/path/ [...options] - -import { Command } from 'commander' -import { transform } from './commands/transform' -import { upgrade } from './commands/upgrade' -import packageJson from './package.json' - -const program = new Command(packageJson.name) - .version(packageJson.version, '-v, --version', `Output the current version of ${packageJson.name}.`) - .description(packageJson.description) - .argument('[codemod]', 'Codemod slug to run') - .argument('[source]', 'Path to source files or directory to transform.') - .helpOption('-h, --help', 'Display this help message.') - .option('-d, --dry', 'Dry run (no changes are made to files)') - .option('-p, --print', 'Print transformed files to stdout') - .option('--verbose', 'Show more information about the transform process') - .option('--silent', "Don't print anything to stdout") - .usage('[codemod] [source] [options]') - .action(transform) - // Why this option is necessary is explained here: https://github.com/tj/commander.js/pull/1427 - .enablePositionalOptions() - -program - .command('upgrade') - .description('Upgrade your express server to the latest version.') - .argument('[source]', 'Path to source files or directory to transform.') - .option('--select', 'Select which codemods to apply (Show a list of available codemods)') - .action(upgrade) - -program.parse(process.argv) diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index d1f1374..0000000 --- a/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - automock: false, - transform: { - '\\.ts$': ['ts-jest', { isolatedModules: true }], - }, - modulePathIgnorePatterns: ['/build/'], -} diff --git a/package-lock.json b/package-lock.json index fc318a3..9ac4f64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,24 +11,12 @@ "workspaces": [ "./codemods/*" ], - "dependencies": { - "commander": "^12.1.0", - "fast-glob": "^3.3.2", - "jscodeshift": "^17.1.1", - "picocolors": "^1.1.1", - "prompts": "^2.4.2" - }, "bin": { "express-codemod": "build/index.js" }, "devDependencies": { "@biomejs/biome": "1.9.4", - "@types/jest": "29.5.14", - "@types/jscodeshift": "^0.12.0", "@types/node": "^22.19.3", - "@types/prompts": "2.4.9", - "jest": "29.7.0", - "ts-jest": "29.3.4", "typescript": "5.9.3" }, "engines": { @@ -63,15 +51,6 @@ "@codemod.com/jssg-types": "^1.3.1" } }, - "codemods/magic-redirect": { - "name": "@expressjs/back-redirect-deprecated", - "version": "1.0.0", - "extraneous": true, - "license": "MIT", - "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" - } - }, "codemods/pluralize-method-names": { "name": "@expressjs/pluralize-method-names", "version": "1.0.0", @@ -88,15 +67,6 @@ "@codemod.com/jssg-types": "^1.3.1" } }, - "codemods/req-param": { - "name": "@expressjs/req-param", - "version": "1.0.0", - "extraneous": true, - "license": "MIT", - "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" - } - }, "codemods/route-del-to-delete": { "name": "@expressjs/route-del-to-delete", "version": "1.0.0", @@ -121,4830 +91,225 @@ "@codemod.com/jssg-types": "^1.3.1" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", - "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", - "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.26.3", - "@babel/types": "^7.26.3", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" + "url": "https://opencollective.com/biome" }, - "engines": { - "node": ">=6.9.0" + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", - "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.9" - }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", + "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", + "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", - "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/traverse": "^7.25.9", - "semver": "^6.3.1" - }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", + "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", - "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", + "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.9.4", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.9.4", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", - "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.9" - }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", + "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", - "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", - "license": "MIT", + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", + "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", - "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } + "node_modules/@codemod.com/jssg-types": { + "version": "1.3.1", + "dev": true, + "license": "Apache-2.0" }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", - "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@expressjs/back-redirect-deprecated": { + "resolved": "codemods/back-redirect-deprecated", + "link": true }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "node_modules/@expressjs/camelcase-sendfile": { + "resolved": "codemods/camelcase-sendfile", + "link": true }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "node_modules/@expressjs/explicit-request-params": { + "resolved": "codemods/explicit-request-params", + "link": true }, - "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "node_modules/@expressjs/pluralize-method-names": { + "resolved": "codemods/pluralize-method-names", + "link": true }, - "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "node_modules/@expressjs/redirect-arg-order": { + "resolved": "codemods/redirect-arg-order", + "link": true + }, + "node_modules/@expressjs/route-del-to-delete": { + "resolved": "codemods/route-del-to-delete", + "link": true + }, + "node_modules/@expressjs/status-send-order": { + "resolved": "codemods/status-send-order", + "link": true + }, + "node_modules/@expressjs/v5-migration-recipe": { + "resolved": "codemods/v5-migration-recipe", + "link": true + }, + "node_modules/@types/node": { + "version": "22.19.3", + "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" - }, - "engines": { - "node": ">=6.9.0" + "undici-types": "~6.21.0" } }, - "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.26.3" - }, + "node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", "bin": { - "parser": "bin/babel-parser.js" + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz", - "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", - "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", - "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", - "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.9.tgz", - "integrity": "sha512-/VVukELzPDdci7UUsWQaSkhgnjIWXnIyRpM02ldxaVoFK96c41So8JcKT3m0gYjyv7j5FNPGS5vfELrWalkbDA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/plugin-syntax-flow": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", - "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", - "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", - "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", - "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz", - "integrity": "sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/plugin-syntax-typescript": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-flow": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.25.9.tgz", - "integrity": "sha512-EASHsAhE+SSlEzJ4bzfusnXSHiU+JfAYzj+jbw2vgQKgq5HrUr8qs+vgtiEL5dOH6sEweI+PNt2D7AqrDSHyqQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-transform-flow-strip-types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", - "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-syntax-jsx": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.25.9", - "@babel/plugin-transform-typescript": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/register": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.25.9.tgz", - "integrity": "sha512-8D43jXtGsYmEeDvm4MWHYUpWf8iiXgWYx3fW7E7Wb7Oe6FWqJPl5K6TuFW0dOwNZzEE5rjlaSJYH9JjrUKJszA==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "find-cache-dir": "^2.0.0", - "make-dir": "^2.1.0", - "pirates": "^4.0.6", - "source-map-support": "^0.5.16" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/register/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "license": "MIT", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/register/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@babel/register/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.26.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", - "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.3", - "@babel/parser": "^7.26.3", - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.3", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", - "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@biomejs/biome": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", - "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", - "dev": true, - "hasInstallScript": true, - "license": "MIT OR Apache-2.0", - "bin": { - "biome": "bin/biome" - }, - "engines": { - "node": ">=14.21.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/biome" - }, - "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.4", - "@biomejs/cli-darwin-x64": "1.9.4", - "@biomejs/cli-linux-arm64": "1.9.4", - "@biomejs/cli-linux-arm64-musl": "1.9.4", - "@biomejs/cli-linux-x64": "1.9.4", - "@biomejs/cli-linux-x64-musl": "1.9.4", - "@biomejs/cli-win32-arm64": "1.9.4", - "@biomejs/cli-win32-x64": "1.9.4" - } - }, - "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", - "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", - "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", - "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.21.3" - } - }, - "node_modules/@codemod.com/jssg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@codemod.com/jssg-types/-/jssg-types-1.3.1.tgz", - "integrity": "sha512-poYNa8mfr8+4+kBPc3bAKBTaUtOQdg5z3voeGGAAr0tiTBvC4cmmoY/dyHXEWT8F+p8A1tWUnhmJZ4WQXV3HVA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@expressjs/back-redirect-deprecated": { - "resolved": "codemods/back-redirect-deprecated", - "link": true - }, - "node_modules/@expressjs/camelcase-sendfile": { - "resolved": "codemods/camelcase-sendfile", - "link": true - }, - "node_modules/@expressjs/explicit-request-params": { - "resolved": "codemods/explicit-request-params", - "link": true - }, - "node_modules/@expressjs/pluralize-method-names": { - "resolved": "codemods/pluralize-method-names", - "link": true - }, - "node_modules/@expressjs/redirect-arg-order": { - "resolved": "codemods/redirect-arg-order", - "link": true - }, - "node_modules/@expressjs/route-del-to-delete": { - "resolved": "codemods/route-del-to-delete", - "link": true - }, - "node_modules/@expressjs/status-send-order": { - "resolved": "codemods/status-send-order", - "link": true - }, - "node_modules/@expressjs/v5-migration-recipe": { - "resolved": "codemods/v5-migration-recipe", - "link": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", - "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/jscodeshift": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.12.0.tgz", - "integrity": "sha512-Jr2fQbEoDmjwEa92TreR/mX2t9iAaY/l5P/GKezvK4BodXahex60PDLXaQR0vAgP0KfCzc1CivHusQB9NhzX8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "^0.14.1", - "recast": "^0.20.3" - } - }, - "node_modules/@types/node": { - "version": "22.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", - "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/prompts": { - "version": "2.4.9", - "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.9.tgz", - "integrity": "sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "kleur": "^3.0.3" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/ast-types": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", - "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", - "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001687", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", - "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", - "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "license": "MIT" - }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", - "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==", - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "license": "MIT", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/find-cache-dir/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "license": "MIT", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flow-parser": { - "version": "0.256.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.256.0.tgz", - "integrity": "sha512-HFb/GgB7hq+TYosLJuMLdLp8aGlyAVfrJaTvcM0w2rz2T33PjkVbRU419ncK/69cjowUksewuspkBheq9ZX9Hw==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "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" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jscodeshift": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-17.1.1.tgz", - "integrity": "sha512-4vq5B1sD37aa9qed3zWq2XQPun5XjxebIv+Folr57lt8B4HLGDHEz1UG7pfcxzSaelzPbcY7yZSs033/S0i6wQ==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/plugin-transform-class-properties": "^7.24.7", - "@babel/plugin-transform-modules-commonjs": "^7.24.7", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", - "@babel/plugin-transform-optional-chaining": "^7.24.7", - "@babel/plugin-transform-private-methods": "^7.24.7", - "@babel/preset-flow": "^7.24.7", - "@babel/preset-typescript": "^7.24.7", - "@babel/register": "^7.24.6", - "flow-parser": "0.*", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.7", - "neo-async": "^2.5.0", - "picocolors": "^1.0.1", - "recast": "^0.23.9", - "tmp": "^0.2.3", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "jscodeshift": "bin/jscodeshift.js" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@babel/preset-env": "^7.1.6" - }, - "peerDependenciesMeta": { - "@babel/preset-env": { - "optional": true - } - } - }, - "node_modules/jscodeshift/node_modules/ast-types": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", - "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/jscodeshift/node_modules/recast": { - "version": "0.23.9", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", - "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", - "license": "MIT", - "dependencies": { - "ast-types": "^0.16.1", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tiny-invariant": "^1.3.3", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/jscodeshift/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jscodeshift/node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "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, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/recast": { - "version": "0.20.5", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", - "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "0.14.2", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", - "license": "MIT" - }, - "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-jest": { - "version": "29.3.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.4.tgz", - "integrity": "sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "^0.2.6", - "ejs": "^3.1.10", - "fast-json-stable-stringify": "^2.1.0", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "^4.1.2", - "make-error": "^1.3.6", - "semver": "^7.7.2", - "type-fest": "^4.41.0", - "yargs-parser": "^21.1.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-jest/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" + "node": ">=14.17" } }, "node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" - }, - "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "recipes/magic-redirect": { - "name": "@expressjs/magic-redirect", - "version": "1.0.0", - "extraneous": true, - "license": "MIT", - "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" - } } } } diff --git a/package.json b/package.json index c4101d9..e92a72f 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,9 @@ { "name": "@expressjs/codemod", - "version": "0.0.5", + "private": "true", "description": "Codemods for updating express servers.", "contributors": ["Sebastian Beltran ", "Filip Kudla "], "license": "MIT", - "bin": { - "express-codemod": "build/index.js" - }, "repository": { "type": "git", "url": "git+https://github.com/expressjs/codemod.git" @@ -16,37 +13,15 @@ "url": "https://opencollective.com/express" }, "keywords": ["codemods", "express"], - "files": ["build"], "scripts": { - "clean": "rm -rf build", - "dev": "tsc -d -w -p tsconfig.json", - "build": "tsc -d -p tsconfig.json", "lint": "biome check", "lint:fix": "biome check --fix", - "test": "npm run test --workspaces --if-present", - "test-legacy": "jest", - "test-legacy:ci": "jest --ci", - "prepublishOnly": "npm run clean && npm run build" - }, - "dependencies": { - "commander": "^12.1.0", - "fast-glob": "^3.3.2", - "jscodeshift": "^17.1.1", - "picocolors": "^1.1.1", - "prompts": "^2.4.2" + "test": "npm run test --workspaces --if-present" }, "devDependencies": { "@biomejs/biome": "1.9.4", - "@types/jest": "29.5.14", - "@types/jscodeshift": "^0.12.0", "@types/node": "^22.19.3", - "@types/prompts": "2.4.9", - "jest": "29.7.0", - "ts-jest": "29.3.4", "typescript": "5.9.3" }, - "engines": { - "node": ">=18" - }, "workspaces": ["./codemods/*"] } diff --git a/transforms/__test__/magic-redirect.spec.ts b/transforms/__test__/magic-redirect.spec.ts deleted file mode 100644 index da29e94..0000000 --- a/transforms/__test__/magic-redirect.spec.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { testSpecBuilder } from './util' - -testSpecBuilder('magic-redirect') diff --git a/transforms/__test__/pluralized-methods.spec.ts b/transforms/__test__/pluralized-methods.spec.ts deleted file mode 100644 index e90b566..0000000 --- a/transforms/__test__/pluralized-methods.spec.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { defineTest } from 'jscodeshift/src/testUtils' - -import { readdirSync } from 'node:fs' -import { join } from 'node:path' - -const fixtureDir = 'pluralized-methods' -const fixtureDirPath = join(__dirname, '..', '__testfixtures__', fixtureDir) -const fixtures = readdirSync(fixtureDirPath) - .filter((file) => file.endsWith('.input.ts')) - .map((file) => file.replace('.input.ts', '')) - -for (const fixture of fixtures) { - const prefix = `${fixtureDir}/${fixture}` - defineTest(__dirname, fixtureDir, null, prefix, { parser: 'ts' }) -} diff --git a/transforms/__test__/req-param.spec.ts b/transforms/__test__/req-param.spec.ts deleted file mode 100644 index f653426..0000000 --- a/transforms/__test__/req-param.spec.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { testSpecBuilder } from './util' - -testSpecBuilder('req-param') diff --git a/transforms/__test__/util.ts b/transforms/__test__/util.ts deleted file mode 100644 index 8090ae8..0000000 --- a/transforms/__test__/util.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { defineTest } from 'jscodeshift/src/testUtils' - -import { readdirSync } from 'node:fs' -import { join } from 'node:path' - -export function testSpecBuilder(fixtureDir: string): void { - const fixtureDirPath = join(__dirname, '..', '__testfixtures__', fixtureDir) - const fixtures = readdirSync(fixtureDirPath) - .filter((file) => file.endsWith('.input.ts')) - .map((file) => file.replace('.input.ts', '')) - - for (const fixture of fixtures) { - const prefix = `${fixtureDir}/${fixture}` - defineTest(__dirname, fixtureDir, null, prefix, { parser: 'ts' }) - } -} diff --git a/transforms/__test__/v4-deprecated-signatures.spec.ts b/transforms/__test__/v4-deprecated-signatures.spec.ts deleted file mode 100644 index 4df36b4..0000000 --- a/transforms/__test__/v4-deprecated-signatures.spec.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { testSpecBuilder } from './util' - -testSpecBuilder('v4-deprecated-signatures') diff --git a/transforms/__testfixtures__/magic-redirect/location.input.ts b/transforms/__testfixtures__/magic-redirect/location.input.ts deleted file mode 100644 index bb001ba..0000000 --- a/transforms/__testfixtures__/magic-redirect/location.input.ts +++ /dev/null @@ -1,20 +0,0 @@ -import express from "express"; -import { location } from "somelibrary"; - -const app = express(); - -app.get("/", function (req, res) { - res.location("back"); -}); -app.get("/", (req, res) => { - res.location("back"); -}); -app.get("/articles", function (request, response) { - response.location("back"); -}); -app.get("/articles", (request, response) => { - response.location("back"); -}); -app.get("/articles", function (_req, _res) { - location("back"); -}); diff --git a/transforms/__testfixtures__/magic-redirect/location.output.ts b/transforms/__testfixtures__/magic-redirect/location.output.ts deleted file mode 100644 index 869f27f..0000000 --- a/transforms/__testfixtures__/magic-redirect/location.output.ts +++ /dev/null @@ -1,20 +0,0 @@ -import express from "express"; -import { location } from "somelibrary"; - -const app = express(); - -app.get("/", function (req, res) { - res.location(req.get("Referrer") || "/"); -}); -app.get("/", (req, res) => { - res.location(req.get("Referrer") || "/"); -}); -app.get("/articles", function (request, response) { - response.location(request.get("Referrer") || "/"); -}); -app.get("/articles", (request, response) => { - response.location(request.get("Referrer") || "/"); -}); -app.get("/articles", function (_req, _res) { - location("back"); -}); \ No newline at end of file diff --git a/transforms/__testfixtures__/magic-redirect/redirect.input.ts b/transforms/__testfixtures__/magic-redirect/redirect.input.ts deleted file mode 100644 index 7be5724..0000000 --- a/transforms/__testfixtures__/magic-redirect/redirect.input.ts +++ /dev/null @@ -1,20 +0,0 @@ -import express from "express"; -import { redirect } from "somelibrary"; - -const app = express(); - -app.get("/", function (req, res) { - res.redirect("back"); -}); -app.get("/", (req, res) => { - res.redirect("back"); -}); -app.get("/articles", function (request, response) { - response.redirect("back"); -}); -app.get("/articles", (request, response) => { - response.redirect("back"); -}); -app.get("/articles", function (_req, _res) { - redirect("back"); -}); diff --git a/transforms/__testfixtures__/magic-redirect/redirect.output.ts b/transforms/__testfixtures__/magic-redirect/redirect.output.ts deleted file mode 100644 index b45f88e..0000000 --- a/transforms/__testfixtures__/magic-redirect/redirect.output.ts +++ /dev/null @@ -1,20 +0,0 @@ -import express from "express"; -import { redirect } from "somelibrary"; - -const app = express(); - -app.get("/", function (req, res) { - res.redirect(req.get("Referrer") || "/"); -}); -app.get("/", (req, res) => { - res.redirect(req.get("Referrer") || "/"); -}); -app.get("/articles", function (request, response) { - response.redirect(request.get("Referrer") || "/"); -}); -app.get("/articles", (request, response) => { - response.redirect(request.get("Referrer") || "/"); -}); -app.get("/articles", function (_req, _res) { - redirect("back"); -}); diff --git a/transforms/__testfixtures__/pluralized-methods/charset.input.ts b/transforms/__testfixtures__/pluralized-methods/charset.input.ts deleted file mode 100644 index 32f352b..0000000 --- a/transforms/__testfixtures__/pluralized-methods/charset.input.ts +++ /dev/null @@ -1,13 +0,0 @@ -import express from 'express' - -const app = express() - -app.get('/', (req, res) => { - const charset = req.acceptsCharset('utf-8'); - res.json({ charset }); -}); - -app.get('/', function (request, response) { - const charset = request.acceptsCharset('utf-8'); - response.json({ charset }); -}); \ No newline at end of file diff --git a/transforms/__testfixtures__/pluralized-methods/charset.output.ts b/transforms/__testfixtures__/pluralized-methods/charset.output.ts deleted file mode 100644 index ef72f8c..0000000 --- a/transforms/__testfixtures__/pluralized-methods/charset.output.ts +++ /dev/null @@ -1,13 +0,0 @@ -import express from 'express' - -const app = express() - -app.get('/', (req, res) => { - const charset = req.acceptsCharsets('utf-8'); - res.json({ charset }); -}); - -app.get('/', function (request, response) { - const charset = request.acceptsCharsets('utf-8'); - response.json({ charset }); -}); \ No newline at end of file diff --git a/transforms/__testfixtures__/pluralized-methods/encoding.input.ts b/transforms/__testfixtures__/pluralized-methods/encoding.input.ts deleted file mode 100644 index 3d256a1..0000000 --- a/transforms/__testfixtures__/pluralized-methods/encoding.input.ts +++ /dev/null @@ -1,13 +0,0 @@ -import express from 'express' - -const app = express() - -app.get('/', (req, res) => { - const encoding = req.acceptsEncoding('gzip'); - res.json({ encoding }); -}); - -app.get('/', function (request, response) { - const encoding = request.acceptsEncoding('gzip'); - response.json({ encoding }); -}); diff --git a/transforms/__testfixtures__/pluralized-methods/encoding.output.ts b/transforms/__testfixtures__/pluralized-methods/encoding.output.ts deleted file mode 100644 index 9e5d1a9..0000000 --- a/transforms/__testfixtures__/pluralized-methods/encoding.output.ts +++ /dev/null @@ -1,13 +0,0 @@ -import express from 'express' - -const app = express() - -app.get('/', (req, res) => { - const encoding = req.acceptsEncodings('gzip'); - res.json({ encoding }); -}); - -app.get('/', function (request, response) { - const encoding = request.acceptsEncodings('gzip'); - response.json({ encoding }); -}); \ No newline at end of file diff --git a/transforms/__testfixtures__/pluralized-methods/language.input.ts b/transforms/__testfixtures__/pluralized-methods/language.input.ts deleted file mode 100644 index 6618cc0..0000000 --- a/transforms/__testfixtures__/pluralized-methods/language.input.ts +++ /dev/null @@ -1,14 +0,0 @@ -import express from 'express' - -const app = express() - -app.get('/', (req, res) => { - const encoding = req.acceptsLanguage('gzip'); - res.json({ encoding }); -}); - -app.get('/', function (request, response) { - const encoding = request.acceptsLanguage('gzip'); - response.json({ encoding }); -}); - diff --git a/transforms/__testfixtures__/pluralized-methods/language.output.ts b/transforms/__testfixtures__/pluralized-methods/language.output.ts deleted file mode 100644 index 7dbc805..0000000 --- a/transforms/__testfixtures__/pluralized-methods/language.output.ts +++ /dev/null @@ -1,13 +0,0 @@ -import express from 'express' - -const app = express() - -app.get('/', (req, res) => { - const encoding = req.acceptsLanguages('gzip'); - res.json({ encoding }); -}); - -app.get('/', function (request, response) { - const encoding = request.acceptsLanguages('gzip'); - response.json({ encoding }); -}); \ No newline at end of file diff --git a/transforms/__testfixtures__/req-param/req-param.input.ts b/transforms/__testfixtures__/req-param/req-param.input.ts deleted file mode 100644 index 45f1d0f..0000000 --- a/transforms/__testfixtures__/req-param/req-param.input.ts +++ /dev/null @@ -1,39 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/", function (req, res) { - const reqBody = req.param('body'); - const reqQuery = req.param('query'); - const reqQueryTest = req.param('query').test; - const reqOther = req.param('other'); - const reqOtherNested = req.param('other').nested; -}); - -app.get("/", function (request, response) { - const reqBody = request.param('body'); - const reqQuery = request.param('query'); - const reqQueryTest = request.param('query').test; - const reqOther = request.param('other'); - const reqOtherNested = request.param('other').nested; -}); - -app.get("/", (req, res) => { - const reqBody = req.param('body'); - const reqQuery = req.param('query'); - const reqQueryTest = req.param('query').test; - const reqOther = req.param('other'); - const reqOtherNested = req.param('other').nested; -}); - -app.get("/", (request, response) => { - const reqBody = request.param('body'); - const reqQuery = request.param('query'); - const reqQueryTest = request.param('query').test; - const reqOther = request.param('other'); - const reqOtherNested = request.param('other').nested; -}); - -app.param(function () { - // my important logic -}) \ No newline at end of file diff --git a/transforms/__testfixtures__/req-param/req-param.output.ts b/transforms/__testfixtures__/req-param/req-param.output.ts deleted file mode 100644 index 2457634..0000000 --- a/transforms/__testfixtures__/req-param/req-param.output.ts +++ /dev/null @@ -1,39 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/", function (req, res) { - const reqBody = req.body; - const reqQuery = req.query; - const reqQueryTest = req.query.test; - const reqOther = req.params.other; - const reqOtherNested = req.params.other.nested; -}); - -app.get("/", function (request, response) { - const reqBody = request.body; - const reqQuery = request.query; - const reqQueryTest = request.query.test; - const reqOther = request.params.other; - const reqOtherNested = request.params.other.nested; -}); - -app.get("/", (req, res) => { - const reqBody = req.body; - const reqQuery = req.query; - const reqQueryTest = req.query.test; - const reqOther = req.params.other; - const reqOtherNested = req.params.other.nested; -}); - -app.get("/", (request, response) => { - const reqBody = request.body; - const reqQuery = request.query; - const reqQueryTest = request.query.test; - const reqOther = request.params.other; - const reqOtherNested = request.params.other.nested; -}); - -app.param(function () { - // my important logic -}) \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/delete.input.ts b/transforms/__testfixtures__/v4-deprecated-signatures/delete.input.ts deleted file mode 100644 index aeab3e3..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/delete.input.ts +++ /dev/null @@ -1,39 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/", (req, res) => {}); - -app.del([""],() => { - myImportantLogic(); -}); - -app.del([],() => { - myImportantLogic(); -}); - -app.del(/d/,() => { - myImportantLogic(); -}); - -app.del(() => { - myImportantLogic(); -}); - -app.del(function () { - myImportantLogic(); -}); - -app.del("/old", () => { - myImportantLogic(); -}); - -function noModify() { - let a - - app.del(a) -} - -const myImportantLogic = () => { - console.log("making sure it's there"); -}; diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/delete.output.ts b/transforms/__testfixtures__/v4-deprecated-signatures/delete.output.ts deleted file mode 100644 index b1dbf42..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/delete.output.ts +++ /dev/null @@ -1,39 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/", (req, res) => {}); - -app.delete([""],() => { - myImportantLogic(); -}); - -app.delete([],() => { - myImportantLogic(); -}); - -app.delete(/d/,() => { - myImportantLogic(); -}); - -app.del(() => { - myImportantLogic(); -}); - -app.del(function () { - myImportantLogic(); -}); - -app.delete("/old", () => { - myImportantLogic(); -}); - -function noModify() { - let a - - app.del(a) -} - -const myImportantLogic = () => { - console.log("making sure it's there"); -}; diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/json.input.ts b/transforms/__testfixtures__/v4-deprecated-signatures/json.input.ts deleted file mode 100644 index 2f23e2a..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/json.input.ts +++ /dev/null @@ -1,71 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/json", function (...arg) { - const [, res] = arg - res.json(); -}); - -app.get("/json", function (...arg) { - const [, res] = arg - res.json({ user: "Username", isValid: true }, 200); -}); - -app.get("/json", function (req, res) { - res.json(); -}); - -app.get("/json", function (req, res) { - res.json({ user: "Username", isValid: true }, 200); -}); - -app.get("/json", function (req, response) { - response.json({ user: "Username", isValid: true }, 200); -}); - -app.get("/json", (req, res) => { - res.json({ user: "Username", isValid: true }, 200); -}); - -app.get("/json", (req, response) => { - response.json({ user: "Username", isValid: true }, 200); -}); - -app.get("/json", function (req, res) { - res.json({}, 200); -}); - -app.get("/json", function (req, response) { - response.json({}, 200); -}); - -app.get("/json", (req, res) => { - res.json({}, 200); -}); - -app.get("/json", (req, response) => { - response.json({}, 200); -}); - -// Still valid syntax -- START -app.get("/json", function (req, res) { - res.json(null) - res.json({ user: 'tobi' }) -}) - -app.get("/json", function (req, response) { - response.json(null) - response.json({ user: 'tobi' }) -}) - -app.get("/json", function (req, res) { - res.json(null) - res.json({ user: 'tobi' }) -}) - -app.get("/json", function (req, response) { - response.json(null) - response.json({ user: 'tobi' }) -}) -// Still valid syntax -- END \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/json.output.ts b/transforms/__testfixtures__/v4-deprecated-signatures/json.output.ts deleted file mode 100644 index c25583c..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/json.output.ts +++ /dev/null @@ -1,71 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/json", function (...arg) { - const [, res] = arg - res.json(); -}); - -app.get("/json", function (...arg) { - const [, res] = arg - res.status(200).json({ user: "Username", isValid: true }); -}); - -app.get("/json", function (req, res) { - res.json(); -}); - -app.get("/json", function (req, res) { - res.status(200).json({ user: "Username", isValid: true }); -}); - -app.get("/json", function (req, response) { - response.status(200).json({ user: "Username", isValid: true }); -}); - -app.get("/json", (req, res) => { - res.status(200).json({ user: "Username", isValid: true }); -}); - -app.get("/json", (req, response) => { - response.status(200).json({ user: "Username", isValid: true }); -}); - -app.get("/json", function (req, res) { - res.status(200).json({}); -}); - -app.get("/json", function (req, response) { - response.status(200).json({}); -}); - -app.get("/json", (req, res) => { - res.status(200).json({}); -}); - -app.get("/json", (req, response) => { - response.status(200).json({}); -}); - -// Still valid syntax -- START -app.get("/json", function (req, res) { - res.json(null) - res.json({ user: 'tobi' }) -}) - -app.get("/json", function (req, response) { - response.json(null) - response.json({ user: 'tobi' }) -}) - -app.get("/json", function (req, res) { - res.json(null) - res.json({ user: 'tobi' }) -}) - -app.get("/json", function (req, response) { - response.json(null) - response.json({ user: 'tobi' }) -}) -// Still valid syntax -- END \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/jsonp.input.ts b/transforms/__testfixtures__/v4-deprecated-signatures/jsonp.input.ts deleted file mode 100644 index 88a7e27..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/jsonp.input.ts +++ /dev/null @@ -1,61 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/json", function (req, res) { - res.json(); -}); - -app.get("/jsonp", function (req, res) { - res.jsonp({ user: "Username", isValid: true }, 200); -}); - -app.get("/jsonp", function (req, response) { - response.jsonp({ user: "Username", isValid: true }, 200); -}); - -app.get("/jsonp", (req, res) => { - res.jsonp({ user: "Username", isValid: true }, 200); -}); - -app.get("/jsonp", (req, response) => { - response.jsonp({ user: "Username", isValid: true }, 200); -}); - -app.get("/jsonp", function (req, res) { - res.jsonp({}, 200); -}); - -app.get("/jsonp", function (req, response) { - response.jsonp({}, 200); -}); - -app.get("/jsonp", (req, res) => { - res.jsonp({}, 200) -}); - -app.get("/jsonp", (req, response) => { - response.jsonp({}, 200) -}); - -// Still valid syntax -- START -app.get("/jsonp", function (req, res) { - res.jsonp(null) - res.jsonp({ user: 'tobi' }) -}) - -app.get("/jsonp", function (req, response) { - response.jsonp(null) - response.jsonp({ user: 'tobi' }) -}) - -app.get("/jsonp", function (req, res) { - res.jsonp(null) - res.jsonp({ user: 'tobi' }) -}) - -app.get("/jsonp", function (req, response) { - response.jsonp(null) - response.jsonp({ user: 'tobi' }) -}) -// Still valid syntax -- END \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/jsonp.output.ts b/transforms/__testfixtures__/v4-deprecated-signatures/jsonp.output.ts deleted file mode 100644 index 4aafe06..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/jsonp.output.ts +++ /dev/null @@ -1,61 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/json", function (req, res) { - res.json(); -}); - -app.get("/jsonp", function (req, res) { - res.status(200).jsonp({ user: "Username", isValid: true }); -}); - -app.get("/jsonp", function (req, response) { - response.status(200).jsonp({ user: "Username", isValid: true }); -}); - -app.get("/jsonp", (req, res) => { - res.status(200).jsonp({ user: "Username", isValid: true }); -}); - -app.get("/jsonp", (req, response) => { - response.status(200).jsonp({ user: "Username", isValid: true }); -}); - -app.get("/jsonp", function (req, res) { - res.status(200).jsonp({}); -}); - -app.get("/jsonp", function (req, response) { - response.status(200).jsonp({}); -}); - -app.get("/jsonp", (req, res) => { - res.status(200).jsonp({}) -}); - -app.get("/jsonp", (req, response) => { - response.status(200).jsonp({}) -}); - -// Still valid syntax -- START -app.get("/jsonp", function (req, res) { - res.jsonp(null) - res.jsonp({ user: 'tobi' }) -}) - -app.get("/jsonp", function (req, response) { - response.jsonp(null) - response.jsonp({ user: 'tobi' }) -}) - -app.get("/jsonp", function (req, res) { - res.jsonp(null) - res.jsonp({ user: 'tobi' }) -}) - -app.get("/jsonp", function (req, response) { - response.jsonp(null) - response.jsonp({ user: 'tobi' }) -}) -// Still valid syntax -- END \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/redirect.input.ts b/transforms/__testfixtures__/v4-deprecated-signatures/redirect.input.ts deleted file mode 100644 index 805d5a5..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/redirect.input.ts +++ /dev/null @@ -1,38 +0,0 @@ -import express from "express"; -import { redirect } from "somelibrary"; - -const app = express(); - -app.get("/", function (...arg) { - const [, res] = arg - res.redirect(); -}); - -app.get("/", function (...arg) { - const [, res] = arg - res.redirect("/other-page", 301); -}); - -app.get("/", function (req, res) { - res.redirect(); -}); - -app.get("/", function (req, res) { - res.redirect("/other-page", 301); -}); - -app.get("/", function (req, response) { - response.redirect("/other-page", 301); -}); - -app.get("/", function (req, res) { - res.redirect(301, "/other-page"); -}); - -app.get("/", function (req, res) { - res.redirect("/other-page"); -}); - -app.get("/", function (req, res) { - redirect(301, "/other-page"); -}); \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/redirect.output.ts b/transforms/__testfixtures__/v4-deprecated-signatures/redirect.output.ts deleted file mode 100644 index 3db2d52..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/redirect.output.ts +++ /dev/null @@ -1,38 +0,0 @@ -import express from "express"; -import { redirect } from "somelibrary"; - -const app = express(); - -app.get("/", function (...arg) { - const [, res] = arg - res.redirect(); -}); - -app.get("/", function (...arg) { - const [, res] = arg - res.redirect(301, "/other-page"); -}); - -app.get("/", function (req, res) { - res.redirect(); -}); - -app.get("/", function (req, res) { - res.redirect(301, "/other-page"); -}); - -app.get("/", function (req, response) { - response.redirect(301, "/other-page"); -}); - -app.get("/", function (req, res) { - res.redirect(301, "/other-page"); -}); - -app.get("/", function (req, res) { - res.redirect("/other-page"); -}); - -app.get("/", function (req, res) { - redirect(301, "/other-page"); -}); \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/send-file.input.ts b/transforms/__testfixtures__/v4-deprecated-signatures/send-file.input.ts deleted file mode 100644 index 37926ea..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/send-file.input.ts +++ /dev/null @@ -1,67 +0,0 @@ -import express from "express"; -import path from "path"; -import sendfile from "other-place" - -const app = express(); -const options = { - root: path.join(__dirname, 'public'), - dotfiles: 'deny', - headers: { - 'x-timestamp': Date.now(), - 'x-sent': true - } -} - -const sharedSendFile = (res, next, fileName) => { - res.sendfile(fileName, options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', fileName) - } - }) -} - -app.get('/file/:name', (req, res, next) => { - res.sendfile() -}) - -app.get('/file/:name', (req, res, next) => { - res.sendfile("file.txt") -}) - -app.get('/file/:name', (req, res, next) => { - const fileName = req.params.name - - res.sendfile(fileName, options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', fileName) - } - }) - sharedSendFile(res, next, fileName); -}) - -app.get('/filename/:name', function (req, res, next) { - const fileName = req.params.name - - res.sendfile(fileName, options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', fileName) - } - }) - sharedSendFile(res, next, fileName); -}) - -app.get('/file-handler', (req, res, next) => { - sendfile('test', options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', 'test') - } - }) -}) \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/send-file.output.ts b/transforms/__testfixtures__/v4-deprecated-signatures/send-file.output.ts deleted file mode 100644 index f222bc4..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/send-file.output.ts +++ /dev/null @@ -1,67 +0,0 @@ -import express from "express"; -import path from "path"; -import sendfile from "other-place" - -const app = express(); -const options = { - root: path.join(__dirname, 'public'), - dotfiles: 'deny', - headers: { - 'x-timestamp': Date.now(), - 'x-sent': true - } -} - -const sharedSendFile = (res, next, fileName) => { - res.sendFile(fileName, options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', fileName) - } - }) -} - -app.get('/file/:name', (req, res, next) => { - res.sendFile() -}) - -app.get('/file/:name', (req, res, next) => { - res.sendFile("file.txt") -}) - -app.get('/file/:name', (req, res, next) => { - const fileName = req.params.name - - res.sendFile(fileName, options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', fileName) - } - }) - sharedSendFile(res, next, fileName); -}) - -app.get('/filename/:name', function (req, res, next) { - const fileName = req.params.name - - res.sendFile(fileName, options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', fileName) - } - }) - sharedSendFile(res, next, fileName); -}) - -app.get('/file-handler', (req, res, next) => { - sendfile('test', options, (err) => { - if (err) { - next(err) - } else { - console.log('Sent:', 'test') - } - }) -}) \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/send.input.ts b/transforms/__testfixtures__/v4-deprecated-signatures/send.input.ts deleted file mode 100644 index f436e85..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/send.input.ts +++ /dev/null @@ -1,75 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/send", function (...arg) { - const [, res] = arg - res.send(); -}); - -app.get("/send", function (...arg) { - const [, res] = arg - res.send(200, true); -}); - -app.get("/send", function (req, res) { - res.send(); -}); - -app.get("/send", function (req, res) { - res.send(200, { hello: "world" }); -}); - -app.get("/send", function (req, response) { - response.send(200, "Hello World"); -}); - -app.get("/send", function (req, res) { - res.send(200); -}); - -app.get("/send", function (req, res) { - res.send(200, true); -}); - -app.get("/send", (req, res) => { - res.send(200, { hello: "world" }); -}); - -app.get("/send", (req, res) => { - res.send(200); -}); - -app.get("/send", (req, response) => { - response.send(200); -}); - -app.get("/send", (req, response) => { - response.send(200, true); -}); - -// Still valid syntax -- START -app.get("/send", function (req, res) { - res.send(Buffer.from('whoop')); - res.send({ some: 'json' }); - res.send('

some html

'); -}); - -app.get("/send", function (req, response) { - response.send(Buffer.from('whoop')); - response.send({ some: 'json' }); - response.send('

some html

'); -}); - -app.get("/send", (req, response) => { - response.send(Buffer.from('whoop')); - response.send({ some: 'json' }); - response.send('

some html

'); -}); - -app.get("/send", (req, res) => { - res.send(Buffer.from('whoop')); - res.send({ some: 'json' }); - res.send('

some html

'); -}); -// Still valid syntax -- END \ No newline at end of file diff --git a/transforms/__testfixtures__/v4-deprecated-signatures/send.output.ts b/transforms/__testfixtures__/v4-deprecated-signatures/send.output.ts deleted file mode 100644 index 0824a61..0000000 --- a/transforms/__testfixtures__/v4-deprecated-signatures/send.output.ts +++ /dev/null @@ -1,75 +0,0 @@ -import express from "express"; - -const app = express(); - -app.get("/send", function (...arg) { - const [, res] = arg - res.send(); -}); - -app.get("/send", function (...arg) { - const [, res] = arg - res.status(200).send(true); -}); - -app.get("/send", function (req, res) { - res.send(); -}); - -app.get("/send", function (req, res) { - res.status(200).send({ hello: "world" }); -}); - -app.get("/send", function (req, response) { - response.status(200).send("Hello World"); -}); - -app.get("/send", function (req, res) { - res.sendStatus(200); -}); - -app.get("/send", function (req, res) { - res.status(200).send(true); -}); - -app.get("/send", (req, res) => { - res.status(200).send({ hello: "world" }); -}); - -app.get("/send", (req, res) => { - res.sendStatus(200); -}); - -app.get("/send", (req, response) => { - response.sendStatus(200); -}); - -app.get("/send", (req, response) => { - response.status(200).send(true); -}); - -// Still valid syntax -- START -app.get("/send", function (req, res) { - res.send(Buffer.from('whoop')); - res.send({ some: 'json' }); - res.send('

some html

'); -}); - -app.get("/send", function (req, response) { - response.send(Buffer.from('whoop')); - response.send({ some: 'json' }); - response.send('

some html

'); -}); - -app.get("/send", (req, response) => { - response.send(Buffer.from('whoop')); - response.send({ some: 'json' }); - response.send('

some html

'); -}); - -app.get("/send", (req, res) => { - res.send(Buffer.from('whoop')); - res.send({ some: 'json' }); - res.send('

some html

'); -}); -// Still valid syntax -- END \ No newline at end of file diff --git a/transforms/magic-redirect.ts b/transforms/magic-redirect.ts deleted file mode 100644 index 7333352..0000000 --- a/transforms/magic-redirect.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { - type API, - type ASTPath, - CallExpression, - type FileInfo, - callExpression, - identifier, - literal, - logicalExpression, - memberExpression, -} from 'jscodeshift' -import { getParsedFile } from '../utils/parse' -import { getOptions } from '../utils/recastOptions' -import { recursiveParent } from '../utils/recursiveParent' - -const unifiedMagicString = (path: ASTPath, projectRequestName: string) => { - const pathArguments = path.value.arguments - - if (pathArguments.length === 1 && pathArguments[0]?.type === 'StringLiteral' && pathArguments[0].value === 'back') { - path.value.arguments = [ - logicalExpression( - '||', - callExpression(memberExpression(identifier(projectRequestName), identifier('get')), [identifier('"Referrer"')]), - literal('/'), - ), - ] - - return path - } -} - -export default function transformer(file: FileInfo, _api: API) { - const parsedFile = getParsedFile(file) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'redirect', - }, - }, - }) - .map((path) => unifiedMagicString(path, recursiveParent(path.parentPath) || 'req')) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'location', - }, - }, - }) - .map((path) => unifiedMagicString(path, recursiveParent(path.parentPath) || 'req')) - - return parsedFile.toSource(getOptions(file.source)) -} diff --git a/transforms/pluralized-methods.ts b/transforms/pluralized-methods.ts deleted file mode 100644 index 14a295b..0000000 --- a/transforms/pluralized-methods.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { API, FileInfo } from 'jscodeshift' -import { Identifier, identifier } from 'jscodeshift' -import { getParsedFile } from '../utils/parse' -import { getOptions } from '../utils/recastOptions' - -export default function transformer(file: FileInfo, _api: API): string { - const parsedFile = getParsedFile(file) - - const identifierNamesToReplace = ['acceptsLanguage', 'acceptsCharset', 'acceptsEncoding'] - - for (const singular of identifierNamesToReplace) { - const plural = `${singular}s` - - parsedFile - .find(Identifier, { - name: singular, - }) - .replaceWith(() => identifier(plural)) - } - - return parsedFile.toSource(getOptions(file.source)) -} diff --git a/transforms/req-param.ts b/transforms/req-param.ts deleted file mode 100644 index 96d52ae..0000000 --- a/transforms/req-param.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { API, FileInfo } from 'jscodeshift' -import { CallExpression, identifier, memberExpression, withParser } from 'jscodeshift' -import { getOptions } from '../utils/recastOptions' -import { recursiveParent } from '../utils/recursiveParent' - -export default function transformer(file: FileInfo, _api: API): string { - const parser = withParser('ts') - - return parser(file.source) - .find(CallExpression, { - callee: { - property: { - name: 'param', - }, - }, - }) - .filter((path) => Boolean(recursiveParent(path.parentPath))) - .replaceWith((path) => { - const pathArguments = path.node.arguments - - if (pathArguments.length > 1) { - return path - } - - if (pathArguments[0].type === 'StringLiteral') { - if (pathArguments[0].value === 'query') { - // convert to req.query - return memberExpression(identifier(recursiveParent(path.parentPath) || 'req'), identifier('query')) - } - if (pathArguments[0].value === 'body') { - // convert to req.body - return memberExpression(identifier(recursiveParent(path.parentPath) || 'req'), identifier('body')) - } - - // convert to req.params.[value] - return memberExpression( - memberExpression(identifier(recursiveParent(path.parentPath) || 'req'), identifier('params')), - identifier(pathArguments[0].value), - ) - } - - return path - }) - .toSource(getOptions(file.source)) -} diff --git a/transforms/v4-deprecated-signatures.ts b/transforms/v4-deprecated-signatures.ts deleted file mode 100644 index 842b22c..0000000 --- a/transforms/v4-deprecated-signatures.ts +++ /dev/null @@ -1,158 +0,0 @@ -import type { API, ASTPath, FileInfo } from 'jscodeshift' -import { CallExpression, callExpression, identifier, memberExpression, withParser } from 'jscodeshift' -import { getOptions } from '../utils/recastOptions' -import { recursiveParent } from '../utils/recursiveParent' - -const separateStatusAndBody = (path: ASTPath, calleePropertyName: string) => { - const pathArguments = path.node.arguments - const statusParamIndex = pathArguments.findIndex((arg) => arg.type === 'NumericLiteral') - const bodyParamIndex = pathArguments.findIndex((arg) => arg.type !== 'NumericLiteral') - - path.replace( - callExpression( - memberExpression( - callExpression( - memberExpression(identifier(recursiveParent(path.parentPath, 1) || 'res'), identifier('status')), - [pathArguments[statusParamIndex]], - ), - identifier(calleePropertyName), - ), - [pathArguments[bodyParamIndex]], - ), - ) -} - -export default function transformer(file: FileInfo, _api: API): string { - const parser = withParser('ts') - const parsedFile = parser(file.source) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'send', - }, - }, - }) - .map((path) => { - // from v3: https://expressjs.com/en/3x/api.html#res.send - const pathArguments = path.node.arguments - - if (pathArguments.length === 2) { - separateStatusAndBody(path, 'send') - } else if (pathArguments.length === 1) { - const statusValue = pathArguments[0].type === 'NumericLiteral' ? pathArguments[0].value : false - - if (statusValue) { - path.replace( - callExpression( - memberExpression(identifier(recursiveParent(path.parentPath, 1) || 'res'), identifier('sendStatus')), - [pathArguments[0]], - ), - ) - } - } - - return path - }) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'json', - }, - }, - }) - .map((path) => { - // from v3: https://expressjs.com/en/3x/api.html#res.json - const pathArguments = path.node.arguments - - if (pathArguments.length === 2) { - separateStatusAndBody(path, 'json') - } - - return path - }) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'jsonp', - }, - }, - }) - .map((path) => { - // from v3: https://expressjs.com/en/3x/api.html#res.jsonp - const pathArguments = path.node.arguments - - if (pathArguments.length === 2) { - separateStatusAndBody(path, 'jsonp') - } - - return path - }) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'del', - }, - }, - }) - .map((path) => { - const pathArguments = path.node.arguments - - if ( - pathArguments[0].type !== 'RegExpLiteral' && - pathArguments[0].type !== 'StringLiteral' && - pathArguments[0].type !== 'ArrayExpression' - ) - return path - - if (path.node.callee.type === 'MemberExpression' && path.node.callee.property.type === 'Identifier') { - path.node.callee.property.name = 'delete' - } - - return path - }) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'sendfile', - }, - }, - }) - .map((path) => { - if (path.node.callee.type === 'MemberExpression' && path.node.callee.property.type === 'Identifier') { - path.node.callee.property.name = 'sendFile' - } - - return path - }) - - parsedFile - .find(CallExpression, { - callee: { - property: { - name: 'redirect', - }, - }, - }) - .map((path) => { - const args = path.value.arguments - - // if its already in the correct order, dont reverse - if (args.length === 2 && args[0]?.type !== 'NumericLiteral') { - args.reverse() - } - - return path - }) - - return parsedFile.toSource(getOptions(file.source)) -} diff --git a/tsconfig.json b/tsconfig.json index fbdb66a..52fcce0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,9 +7,8 @@ "downlevelIteration": true, "preserveWatchOutput": true, "resolveJsonModule": true, - "strictNullChecks": true, - "outDir": "build" + "strictNullChecks": true }, - "include": ["**/*.ts", "./codemods/"], - "exclude": ["node_modules", "build", "**/__testfixtures__", "**/__test__", "**/*.spec.ts"] + "include": ["./codemods/"], + "exclude": ["node_modules", "**/__testfixtures__", "**/__test__", "**/*.spec.ts"] } diff --git a/utils/__test__/recastOptions.spec.ts b/utils/__test__/recastOptions.spec.ts deleted file mode 100644 index 7047b87..0000000 --- a/utils/__test__/recastOptions.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { getOptions } from '../recastOptions' - -describe('recastOptions', () => { - describe('getOptions', () => { - it('should return Unix line terminator for code with only LF', () => { - const code = 'const a = 1\nconst b = 2\n' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\n' }) - }) - - it('should return Windows line terminator for code with only CRLF', () => { - const code = 'const a = 1\r\nconst b = 2\r\n' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\r\n' }) - }) - - it('should return Unix line terminator for code with mixed line terminators', () => { - const code = 'const a = 1\r\nconst b = 2\nconst c = 3\r\n' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\n' }) - }) - - it('should return Unix line terminator for code with no line terminators', () => { - const code = 'const a = 1' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\n' }) - }) - - it('should return Unix line terminator for empty string', () => { - const code = '' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\n' }) - }) - - it('should handle code with LF at beginning after CR', () => { - const code = '\r\nconst a = 1\nconst b = 2' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\n' }) - }) - - it('should handle single CRLF without other line breaks', () => { - const code = 'const a = 1\r\nconst b = 2' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\r\n' }) - }) - - it('should handle multiple CRLF without LF', () => { - const code = 'line1\r\nline2\r\nline3\r\n' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\r\n' }) - }) - - it('should detect LF even when preceded by CR in different context', () => { - const code = 'const str = "\\r"\nconst a = 1\r\n' - const result = getOptions(code) - - expect(result).toEqual({ lineTerminator: '\n' }) - }) - }) -}) diff --git a/utils/parse.ts b/utils/parse.ts deleted file mode 100644 index d6e3bfc..0000000 --- a/utils/parse.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { type FileInfo, withParser } from 'jscodeshift' - -export const getParsedFile = (file: FileInfo) => { - return withParser('ts')(file.source) -} diff --git a/utils/prompts.ts b/utils/prompts.ts deleted file mode 100644 index d583466..0000000 --- a/utils/prompts.ts +++ /dev/null @@ -1,20 +0,0 @@ -import prompts from 'prompts' - -export function onCancel() { - console.info('> Cancelled process. Program will stop now without any actions. \n') - process.exit(1) -} - -export const promptSource = async (message: string): Promise => { - const res = await prompts( - { - type: 'text', - name: 'path', - message, - initial: '.', - }, - { onCancel }, - ) - - return res.path -} diff --git a/utils/recastOptions.ts b/utils/recastOptions.ts deleted file mode 100644 index f0c9130..0000000 --- a/utils/recastOptions.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * By default, jscodeshift(recast) uses the line terminator of the OS the code runs on. - * This is often not desired, so we instead try to detect it from the input. - * If there is at least one Windows-style linebreak (CRLF) in the input and - * no Unix-style linebreak (LF), use that. In all other cases, use Unix-style (LF). - * @return '\n' or '\r\n' - */ -export function getOptions(code: string) { - return { lineTerminator: detectLineTerminator(code) } -} - -function detectLineTerminator(code: string) { - const hasCRLF = /\r\n/.test(code) - const hasLF = /[^\r]\n/.test(code) - - return hasCRLF && !hasLF ? '\r\n' : '\n' -} diff --git a/utils/recursiveParent.ts b/utils/recursiveParent.ts deleted file mode 100644 index bae9f09..0000000 --- a/utils/recursiveParent.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ASTNode, ASTPath, ArrowFunctionExpression, FunctionExpression } from 'jscodeshift' - -const defaultParentExpressionType = ['ArrowFunctionExpression', 'FunctionExpression'] as const - -export const recursiveParent = ( - parent: ASTPath, - paramIndex = 0, - parentExpressionType = defaultParentExpressionType, -): string | null => { - if (parentExpressionType.some((type) => parent.value?.type === type)) { - const foundNode = parent.value as unknown as ArrowFunctionExpression | FunctionExpression - if (foundNode.params[paramIndex]?.type === 'Identifier') { - return foundNode.params[paramIndex].name - } - return null - } - - if (parent?.parentPath) { - return recursiveParent(parent.parentPath, paramIndex, parentExpressionType) - } - - return null -} From 90a71f508e1b7b2f3ee022db825d9cb5fe5f842a Mon Sep 17 00:00:00 2001 From: Ayush Saha Date: Sun, 1 Feb 2026 09:40:55 +0530 Subject: [PATCH 44/52] chore: upgrade Biome to v2.3.11 Closes #111 (#118) * biome-version2 update * chore: upgrade biome to v2 * work in progress * Delete codemods/back-redirect-deprecated/tests/input/location.ts closes #117 Signed-off-by: Ayush Saha * Revert "work in progress" This reverts commit 761e5eec0ab78a53575c7dcadf206196ad73276f. * refactor: simplify linter configuration in biome.json --------- Signed-off-by: Ayush Saha Co-authored-by: Sebastian Beltran --- biome.json | 12 ++------ package-lock.json | 78 +++++++++++++++++++++++------------------------ package.json | 16 +++++++--- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/biome.json b/biome.json index 9aee26d..5ec1757 100644 --- a/biome.json +++ b/biome.json @@ -6,24 +6,18 @@ "useIgnoreFile": true }, "files": { - "ignore": ["__testfixtures__", "tests"] + "includes": ["**", "!**/__testfixtures__", "!**/tests"] }, "linter": { "enabled": true, "rules": { "recommended": true, "correctness": { - "noUnusedImports": "error", - "useExhaustiveDependencies": "off" - }, - "suspicious": { - "noExplicitAny": "off" + "noUnusedImports": "error" } } }, - "organizeImports": { - "enabled": true - }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, "json": { "parser": { "allowComments": true diff --git a/package-lock.json b/package-lock.json index 9ac4f64..61477a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,22 +6,15 @@ "packages": { "": { "name": "@expressjs/codemod", - "version": "0.0.5", "license": "MIT", "workspaces": [ "./codemods/*" ], - "bin": { - "express-codemod": "build/index.js" - }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "^2.3.11", "@types/node": "^22.19.3", "typescript": "5.9.3" }, - "engines": { - "node": ">=18" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" @@ -92,9 +85,10 @@ } }, "node_modules/@biomejs/biome": { - "version": "1.9.4", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.11.tgz", + "integrity": "sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==", "dev": true, - "hasInstallScript": true, "license": "MIT OR Apache-2.0", "bin": { "biome": "bin/biome" @@ -107,20 +101,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "1.9.4", - "@biomejs/cli-darwin-x64": "1.9.4", - "@biomejs/cli-linux-arm64": "1.9.4", - "@biomejs/cli-linux-arm64-musl": "1.9.4", - "@biomejs/cli-linux-x64": "1.9.4", - "@biomejs/cli-linux-x64-musl": "1.9.4", - "@biomejs/cli-win32-arm64": "1.9.4", - "@biomejs/cli-win32-x64": "1.9.4" + "@biomejs/cli-darwin-arm64": "2.3.11", + "@biomejs/cli-darwin-x64": "2.3.11", + "@biomejs/cli-linux-arm64": "2.3.11", + "@biomejs/cli-linux-arm64-musl": "2.3.11", + "@biomejs/cli-linux-x64": "2.3.11", + "@biomejs/cli-linux-x64-musl": "2.3.11", + "@biomejs/cli-win32-arm64": "2.3.11", + "@biomejs/cli-win32-x64": "2.3.11" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", - "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.11.tgz", + "integrity": "sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA==", "cpu": [ "arm64" ], @@ -135,9 +129,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", - "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.11.tgz", + "integrity": "sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg==", "cpu": [ "x64" ], @@ -152,9 +146,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", - "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.11.tgz", + "integrity": "sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g==", "cpu": [ "arm64" ], @@ -169,9 +163,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", - "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.11.tgz", + "integrity": "sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg==", "cpu": [ "arm64" ], @@ -186,7 +180,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "1.9.4", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.11.tgz", + "integrity": "sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg==", "cpu": [ "x64" ], @@ -201,7 +197,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "1.9.4", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.11.tgz", + "integrity": "sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw==", "cpu": [ "x64" ], @@ -216,9 +214,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", - "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.11.tgz", + "integrity": "sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw==", "cpu": [ "arm64" ], @@ -233,9 +231,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", - "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.11.tgz", + "integrity": "sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg==", "cpu": [ "x64" ], @@ -287,7 +285,9 @@ "link": true }, "node_modules/@types/node": { - "version": "22.19.3", + "version": "22.19.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.7.tgz", + "integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index e92a72f..a9eb28f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "@expressjs/codemod", "private": "true", "description": "Codemods for updating express servers.", - "contributors": ["Sebastian Beltran ", "Filip Kudla "], + "contributors": [ + "Sebastian Beltran ", + "Filip Kudla " + ], "license": "MIT", "repository": { "type": "git", @@ -12,16 +15,21 @@ "type": "opencollective", "url": "https://opencollective.com/express" }, - "keywords": ["codemods", "express"], + "keywords": [ + "codemods", + "express" + ], "scripts": { "lint": "biome check", "lint:fix": "biome check --fix", "test": "npm run test --workspaces --if-present" }, "devDependencies": { - "@biomejs/biome": "1.9.4", + "@biomejs/biome": "^2.3.11", "@types/node": "^22.19.3", "typescript": "5.9.3" }, - "workspaces": ["./codemods/*"] + "workspaces": [ + "./codemods/*" + ] } From 29923804b6f855934569a5d94d24078f4647d564 Mon Sep 17 00:00:00 2001 From: Ayush Saha Date: Mon, 23 Feb 2026 01:46:58 +0530 Subject: [PATCH 45/52] feat: add codemod and publishing workflow updates via GitHub Actions OIDC closes #112 (#124) * feat: add codemod and publishing workflow updates * Update publish.yml Signed-off-by: Ayush Saha * Apply suggestion from @bjohansebas Signed-off-by: Sebastian Beltran * Apply suggestion from @bjohansebas Signed-off-by: Sebastian Beltran --------- Signed-off-by: Ayush Saha Signed-off-by: Sebastian Beltran Co-authored-by: Sebastian Beltran --- .github/workflows/publish.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 92fe828..37d859f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,19 +14,25 @@ on: description: "Tag to publish (format: v1.0.0@codemod-name)" required: true type: string + +permissions: read-all + jobs: validate-and-publish: name: Validate and Publish Codemod environment: publish runs-on: ubuntu-latest - + + permissions: + id-token: write + contents: read outputs: version: ${{ steps.parse-tag.outputs.version }} codemod-name: ${{ steps.parse-tag.outputs.codemod-name }} codemod-path: ${{ steps.parse-tag.outputs.codemod-path }} - steps: + - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: @@ -98,15 +104,13 @@ jobs: working-directory: ${{ steps.parse-tag.outputs.codemod-path }} run: npm run --if-present test - - name: Authenticate with Codemod registry - env: - CODEMOD_TOKEN: ${{ secrets.CODEMOD_TOKEN }} - run: npx codemod login --api-key "$CODEMOD_TOKEN" + - name: Publish codemod - working-directory: ${{ steps.parse-tag.outputs.codemod-path }} - run: npx codemod publish - + uses: codemod/publish-action@dd6c8dbc5ceb1a6146feba41481d88b43da50024 # v1 + with: + path: ${{ steps.parse-tag.outputs.codemod-path }} + - name: Create release summary env: CODEMOD_NAME: ${{ steps.parse-tag.outputs.codemod-name }} @@ -124,4 +128,4 @@ jobs: **Trigger:** $TRIGGER by $ACTOR ✅ Codemod has been successfully published to the registry! - EOF \ No newline at end of file + EOF From 5f9caf0bacfddcd3b01d6ee63a191507bd6eafa0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 11:45:25 +0100 Subject: [PATCH 46/52] chore(deps): bump github/codeql-action from 4.31.9 to 4.32.4 (#126) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.9 to 4.32.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5d4e8d1aca955e8d8589aabd499c5cae939e33c7...89a39a4e59826350b863aa6b6252a07ad50cf83e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.32.4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cc6eba0..8382d4a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 with: languages: javascript # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 with: category: "/language:javascript" \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 6dd4968..9da7506 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,6 +65,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 with: sarif_file: results.sarif \ No newline at end of file From d9ba7798bcc91ecc3213f6e9f7b4cfb59ce5c9f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 11:48:41 +0100 Subject: [PATCH 47/52] chore(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 (#127) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/b7c566a772e6b6bfb58ed0dc250532a479d7789f...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 9da7506..15a3e7b 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -57,7 +57,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: SARIF file path: results.sarif From 0225cbc6f77fcf023f852ee27c156a548752df12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:46:45 +0100 Subject: [PATCH 48/52] chore(deps-dev): bump @codemod.com/jssg-types from 1.3.1 to 1.5.0 (#130) Bumps [@codemod.com/jssg-types](https://github.com/codemod/codemod) from 1.3.1 to 1.5.0. - [Release notes](https://github.com/codemod/codemod/releases) - [Changelog](https://github.com/codemod/codemod/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemod/codemod/compare/codemod-cli@1.3.1...@codemod.com/jssg-types@1.5.0) --- updated-dependencies: - dependency-name: "@codemod.com/jssg-types" dependency-version: 1.5.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../back-redirect-deprecated/package.json | 2 +- codemods/camelcase-sendfile/package.json | 2 +- codemods/explicit-request-params/package.json | 2 +- codemods/pluralize-method-names/package.json | 2 +- codemods/redirect-arg-order/package.json | 2 +- codemods/route-del-to-delete/package.json | 2 +- codemods/status-send-order/package.json | 2 +- codemods/v5-migration-recipe/package.json | 2 +- package-lock.json | 20 ++++++++++--------- 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/codemods/back-redirect-deprecated/package.json b/codemods/back-redirect-deprecated/package.json index 83d8feb..e35afc3 100644 --- a/codemods/back-redirect-deprecated/package.json +++ b/codemods/back-redirect-deprecated/package.json @@ -17,6 +17,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/back-redirect-deprecated/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/codemods/camelcase-sendfile/package.json b/codemods/camelcase-sendfile/package.json index dc5275f..14f9d3b 100644 --- a/codemods/camelcase-sendfile/package.json +++ b/codemods/camelcase-sendfile/package.json @@ -17,6 +17,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/camelcase-sendfile/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/codemods/explicit-request-params/package.json b/codemods/explicit-request-params/package.json index 817ffaf..4d07dd5 100644 --- a/codemods/explicit-request-params/package.json +++ b/codemods/explicit-request-params/package.json @@ -17,6 +17,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/explicit-request-params/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/codemods/pluralize-method-names/package.json b/codemods/pluralize-method-names/package.json index 1c3cd1c..b95c8b9 100644 --- a/codemods/pluralize-method-names/package.json +++ b/codemods/pluralize-method-names/package.json @@ -17,6 +17,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/pluralize-method-names/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/codemods/redirect-arg-order/package.json b/codemods/redirect-arg-order/package.json index b76d0b5..2585e4a 100644 --- a/codemods/redirect-arg-order/package.json +++ b/codemods/redirect-arg-order/package.json @@ -17,6 +17,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/redirect-arg-order/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/codemods/route-del-to-delete/package.json b/codemods/route-del-to-delete/package.json index 5482aed..d8a7974 100644 --- a/codemods/route-del-to-delete/package.json +++ b/codemods/route-del-to-delete/package.json @@ -17,6 +17,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/route-del-to-delete/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/codemods/status-send-order/package.json b/codemods/status-send-order/package.json index b249239..b4321d8 100644 --- a/codemods/status-send-order/package.json +++ b/codemods/status-send-order/package.json @@ -17,6 +17,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/status-send-order/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/codemods/v5-migration-recipe/package.json b/codemods/v5-migration-recipe/package.json index 7663ab4..c57d61a 100644 --- a/codemods/v5-migration-recipe/package.json +++ b/codemods/v5-migration-recipe/package.json @@ -14,6 +14,6 @@ "license": "MIT", "homepage": "https://github.com/expressjs/codemod/blob/main/codemods/v5-migration-recipe/README.md", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } } diff --git a/package-lock.json b/package-lock.json index 61477a7..479c31d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "codemods/camelcase-sendfile": { @@ -33,7 +33,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "codemods/explicit-request-params": { @@ -41,7 +41,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "codemods/pluralize-method-names": { @@ -49,7 +49,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "codemods/redirect-arg-order": { @@ -57,7 +57,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "codemods/route-del-to-delete": { @@ -65,7 +65,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "codemods/status-send-order": { @@ -73,7 +73,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "codemods/v5-migration-recipe": { @@ -81,7 +81,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@codemod.com/jssg-types": "^1.3.1" + "@codemod.com/jssg-types": "^1.5.0" } }, "node_modules/@biomejs/biome": { @@ -248,7 +248,9 @@ } }, "node_modules/@codemod.com/jssg-types": { - "version": "1.3.1", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@codemod.com/jssg-types/-/jssg-types-1.5.0.tgz", + "integrity": "sha512-zChRbxI3hBSGrAHnWlEzOw1FztLWMMiarwcr0Wbk0On4hmv7dVgoUqpIHfxb64mEMKJ5syTIKY3ZNd8DcFQa5w==", "dev": true, "license": "Apache-2.0" }, From e014b27bc8609122f496d09b34e075b0ad2b6288 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:50:17 +0100 Subject: [PATCH 49/52] chore(deps-dev): bump @types/node from 22.19.7 to 22.19.13 (#129) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.19.7 to 22.19.13. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 22.19.13 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 479c31d..9a78767 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ ], "devDependencies": { "@biomejs/biome": "^2.3.11", - "@types/node": "^22.19.3", + "@types/node": "^22.19.13", "typescript": "5.9.3" }, "funding": { @@ -287,9 +287,9 @@ "link": true }, "node_modules/@types/node": { - "version": "22.19.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.7.tgz", - "integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==", + "version": "22.19.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.13.tgz", + "integrity": "sha512-akNQMv0wW5uyRpD2v2IEyRSZiR+BeGuoB6L310EgGObO44HSMNT8z1xzio28V8qOrgYaopIDNA18YgdXd+qTiw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index a9eb28f..102b041 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "devDependencies": { "@biomejs/biome": "^2.3.11", - "@types/node": "^22.19.3", + "@types/node": "^22.19.13", "typescript": "5.9.3" }, "workspaces": [ From 9fa6c08bb859bf7cf392cd5a4555d2daac86a1b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:53:22 +0100 Subject: [PATCH 50/52] chore(deps-dev): bump @biomejs/biome from 2.3.11 to 2.4.4 (#128) Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.3.11 to 2.4.4. - [Release notes](https://github.com/biomejs/biome/releases) - [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md) - [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.4/packages/@biomejs/biome) --- updated-dependencies: - dependency-name: "@biomejs/biome" dependency-version: 2.4.4 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 72 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a78767..2d9f155 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "./codemods/*" ], "devDependencies": { - "@biomejs/biome": "^2.3.11", + "@biomejs/biome": "^2.4.4", "@types/node": "^22.19.13", "typescript": "5.9.3" }, @@ -85,9 +85,9 @@ } }, "node_modules/@biomejs/biome": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.11.tgz", - "integrity": "sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.4.tgz", + "integrity": "sha512-tigwWS5KfJf0cABVd52NVaXyAVv4qpUXOWJ1rxFL8xF1RVoeS2q/LK+FHgYoKMclJCuRoCWAPy1IXaN9/mS61Q==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -101,20 +101,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.3.11", - "@biomejs/cli-darwin-x64": "2.3.11", - "@biomejs/cli-linux-arm64": "2.3.11", - "@biomejs/cli-linux-arm64-musl": "2.3.11", - "@biomejs/cli-linux-x64": "2.3.11", - "@biomejs/cli-linux-x64-musl": "2.3.11", - "@biomejs/cli-win32-arm64": "2.3.11", - "@biomejs/cli-win32-x64": "2.3.11" + "@biomejs/cli-darwin-arm64": "2.4.4", + "@biomejs/cli-darwin-x64": "2.4.4", + "@biomejs/cli-linux-arm64": "2.4.4", + "@biomejs/cli-linux-arm64-musl": "2.4.4", + "@biomejs/cli-linux-x64": "2.4.4", + "@biomejs/cli-linux-x64-musl": "2.4.4", + "@biomejs/cli-win32-arm64": "2.4.4", + "@biomejs/cli-win32-x64": "2.4.4" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.11.tgz", - "integrity": "sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.4.tgz", + "integrity": "sha512-jZ+Xc6qvD6tTH5jM6eKX44dcbyNqJHssfl2nnwT6vma6B1sj7ZLTGIk6N5QwVBs5xGN52r3trk5fgd3sQ9We9A==", "cpu": [ "arm64" ], @@ -129,9 +129,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.11.tgz", - "integrity": "sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.4.tgz", + "integrity": "sha512-Dh1a/+W+SUCXhEdL7TiX3ArPTFCQKJTI1mGncZNWfO+6suk+gYA4lNyJcBB+pwvF49uw0pEbUS49BgYOY4hzUg==", "cpu": [ "x64" ], @@ -146,9 +146,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.11.tgz", - "integrity": "sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.4.tgz", + "integrity": "sha512-V/NFfbWhsUU6w+m5WYbBenlEAz8eYnSqRMDMAW3K+3v0tYVkNyZn8VU0XPxk/lOqNXLSCCrV7FmV/u3SjCBShg==", "cpu": [ "arm64" ], @@ -163,9 +163,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.11.tgz", - "integrity": "sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.4.tgz", + "integrity": "sha512-+sPAXq3bxmFwhVFJnSwkSF5Rw2ZAJMH3MF6C9IveAEOdSpgajPhoQhbbAK12SehN9j2QrHpk4J/cHsa/HqWaYQ==", "cpu": [ "arm64" ], @@ -180,9 +180,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.11.tgz", - "integrity": "sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.4.tgz", + "integrity": "sha512-R4+ZCDtG9kHArasyBO+UBD6jr/FcFCTH8QkNTOCu0pRJzCWyWC4EtZa2AmUZB5h3e0jD7bRV2KvrENcf8rndBg==", "cpu": [ "x64" ], @@ -197,9 +197,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.11.tgz", - "integrity": "sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.4.tgz", + "integrity": "sha512-gGvFTGpOIQDb5CQ2VC0n9Z2UEqlP46c4aNgHmAMytYieTGEcfqhfCFnhs6xjt0S3igE6q5GLuIXtdQt3Izok+g==", "cpu": [ "x64" ], @@ -214,9 +214,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.11.tgz", - "integrity": "sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.4.tgz", + "integrity": "sha512-trzCqM7x+Gn832zZHgr28JoYagQNX4CZkUZhMUac2YxvvyDRLJDrb5m9IA7CaZLlX6lTQmADVfLEKP1et1Ma4Q==", "cpu": [ "arm64" ], @@ -231,9 +231,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.11.tgz", - "integrity": "sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.4.tgz", + "integrity": "sha512-gnOHKVPFAAPrpoPt2t+Q6FZ7RPry/FDV3GcpU53P3PtLNnQjBmKyN2Vh/JtqXet+H4pme8CC76rScwdjDcT1/A==", "cpu": [ "x64" ], diff --git a/package.json b/package.json index 102b041..eaba371 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "test": "npm run test --workspaces --if-present" }, "devDependencies": { - "@biomejs/biome": "^2.3.11", + "@biomejs/biome": "^2.4.4", "@types/node": "^22.19.13", "typescript": "5.9.3" }, From b195640fdb9980dafc750f0b2d2645ab7cab3267 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:56:44 +0100 Subject: [PATCH 51/52] chore(deps): bump actions/setup-node from 6.1.0 to 6.2.0 (#120) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v6.1.0...v6.2.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/publish.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7707787..820c711 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Setup Node.js {{ matrix.node-version }} - uses: actions/setup-node@v6.1.0 + uses: actions/setup-node@v6.2.0 with: node-version: 'lts/*' @@ -54,7 +54,7 @@ jobs: persist-credentials: false - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v6.1.0 + uses: actions/setup-node@v6.2.0 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 37d859f..e555d95 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -88,7 +88,7 @@ jobs: ls -lah "$CODEMOD_PATH" - name: Setup Node.js environment - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + uses: actions/setup-node@54045abd5dcd3b0fee9ca02fa24c57545834c9cc # v6.1.0 with: cache: npm cache-dependency-path: package-lock.json From b41f6e63fddcb520c9d0472644f8658bdb2036f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:59:24 +0100 Subject: [PATCH 52/52] chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#119) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8e8c483db84b4bee98b60c0593521ed34d9990e8...de0fac2e4500dabe0009e67214ff5f5447ce83dd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 820c711..b733289 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js {{ matrix.node-version }} uses: actions/setup-node@v6.2.0 with: @@ -49,7 +49,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8382d4a..88b064d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e555d95..b226fb9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 15a3e7b..6830f57 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -30,7 +30,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4.1.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.1.2 with: persist-credentials: false