From 4349931651d2bd6d719e1d3a3c5ab4a71b6cea76 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sat, 26 Jul 2025 15:55:07 +0200 Subject: [PATCH 01/23] scaffold codemod --- package-lock.json | 15 +++++++++ recipes/fs-truncate-fs-depreciation/README.md | 33 +++++++++++++++++++ .../fs-truncate-fs-depreciation/codemod.yml | 21 ++++++++++++ .../fs-truncate-fs-depreciation/package.json | 24 ++++++++++++++ .../src/workflow.ts | 15 +++++++++ .../tests/expected/file-1.js | 9 +++++ .../tests/expected/file-2.js | 8 +++++ .../tests/expected/file-3.js | 11 +++++++ .../tests/expected/file-4.mjs | 9 +++++ .../tests/expected/file-5.mjs | 9 +++++ .../tests/input/file-1.js | 9 +++++ .../tests/input/file-2.js | 8 +++++ .../tests/input/file-3.js | 11 +++++++ .../tests/input/file-4.mjs | 9 +++++ .../tests/input/file-5.mjs | 9 +++++ .../fs-truncate-fs-depreciation/workflow.yaml | 24 ++++++++++++++ 16 files changed, 224 insertions(+) create mode 100644 recipes/fs-truncate-fs-depreciation/README.md create mode 100644 recipes/fs-truncate-fs-depreciation/codemod.yml create mode 100644 recipes/fs-truncate-fs-depreciation/package.json create mode 100644 recipes/fs-truncate-fs-depreciation/src/workflow.ts create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-1.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-2.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-3.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/workflow.yaml diff --git a/package-lock.json b/package-lock.json index 1b8e0251..c4d02202 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1420,6 +1420,10 @@ "resolved": "recipes/create-require-from-path", "link": true }, + "node_modules/@nodejs/fs-truncate-fs-depreciation": { + "resolved": "recipes/fs-truncate-fs-depreciation", + "link": true + }, "node_modules/@nodejs/import-assertions-to-attributes": { "resolved": "recipes/import-assertions-to-attributes", "link": true @@ -4069,6 +4073,17 @@ "@types/node": "^24.0.3" } }, + "recipes/fs-truncate-fs-depreciation": { + "name": "@nodejs/fs-truncate-fs-depreciation", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@nodejs/codemod-utils": "0.0.0" + }, + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.3" + } + }, "recipes/import-assertions-to-attributes": { "name": "@nodejs/import-assertions-to-attributes", "version": "1.0.0", diff --git a/recipes/fs-truncate-fs-depreciation/README.md b/recipes/fs-truncate-fs-depreciation/README.md new file mode 100644 index 00000000..1d25932c --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/README.md @@ -0,0 +1,33 @@ +# DEP0081: `fs.truncate()` using a file descriptor + +This recipe transforms the usage of `fs.truncate()` to `fs.ftruncateSync()` when a file descriptor is used. + +See [DEP0081](https://nodejs.org/api/deprecations.html#DEP0081). + +## Example + +**Before:** +```js +const { truncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + truncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => {}); + }); +}); +``` + +**After:** +```js +const { ftruncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + ftruncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => {}); + }); +}); +``` diff --git a/recipes/fs-truncate-fs-depreciation/codemod.yml b/recipes/fs-truncate-fs-depreciation/codemod.yml new file mode 100644 index 00000000..e8f7f9ae --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/codemod.yml @@ -0,0 +1,21 @@ +schema_version: "1.0" +name: nodejs/create-require-from-path +version: 0.0.1 +description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. +author: Augustin Mauroy +license: MIT +workflow: workflow.yaml +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + +registry: + access: public + visibility: public diff --git a/recipes/fs-truncate-fs-depreciation/package.json b/recipes/fs-truncate-fs-depreciation/package.json new file mode 100644 index 00000000..f9a42bae --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/package.json @@ -0,0 +1,24 @@ +{ + "name": "@nodejs/fs-truncate-fs-depreciation", + "version": "0.0.1", + "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", + "type": "module", + "scripts": { + "test": "npx codemod@next jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/nodejs/userland-migrations.git", + "directory": "recipes/fs-truncate-fs-depreciation", + "bugs": "https://github.com/nodejs/userland-migrations/issues" + }, + "author": "Augustin Mauroy", + "license": "MIT", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fs-depreciation/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.3" + }, + "dependencies": { + "@nodejs/codemod-utils": "0.0.0" + } +} diff --git a/recipes/fs-truncate-fs-depreciation/src/workflow.ts b/recipes/fs-truncate-fs-depreciation/src/workflow.ts new file mode 100644 index 00000000..a59e8ea5 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/src/workflow.ts @@ -0,0 +1,15 @@ +import type { SgRoot, Edit } from "@codemod.com/jssg-types/main"; + +/** + * + */ +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + let hasChanges = false; + + + if (!hasChanges) return null; + + return rootNode.commitEdits(edits); +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js b/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js new file mode 100644 index 00000000..75fa3ae3 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js @@ -0,0 +1,9 @@ +const { ftruncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + ftruncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js b/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js new file mode 100644 index 00000000..c363686d --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js @@ -0,0 +1,8 @@ +const fs = require('node:fs'); + +const fd = fs.openSync('file.txt', 'w'); +try { + fs.ftruncateSync(fd, 10); +} finally { + fs.closeSync(fd); +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js b/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js new file mode 100644 index 00000000..96a5f724 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js @@ -0,0 +1,11 @@ +const { truncate, ftruncateSync, open, openSync, close, closeSync } = require('node:fs'); + +// This should be replaced (file descriptor) +const fd = openSync('file.txt', 'w'); +ftruncateSync(fd, 10); +closeSync(fd); + +// This should NOT be replaced (file path) +truncate('other.txt', 5, (err) => { + if (err) throw err; +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs b/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs new file mode 100644 index 00000000..fbcdf61c --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs @@ -0,0 +1,9 @@ +import { ftruncate, open, close } from 'node:fs'; + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + ftruncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs b/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs new file mode 100644 index 00000000..04245b06 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs @@ -0,0 +1,9 @@ +import fs from 'node:fs'; + +fs.open('file.txt', 'w', (err, fd) => { + if (err) throw err; + fs.ftruncate(fd, 10, (err) => { + if (err) throw err; + fs.close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js b/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js new file mode 100644 index 00000000..db75880b --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js @@ -0,0 +1,9 @@ +const { truncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + truncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js b/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js new file mode 100644 index 00000000..aefa3344 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js @@ -0,0 +1,8 @@ +const fs = require('node:fs'); + +const fd = fs.openSync('file.txt', 'w'); +try { + fs.truncateSync(fd, 10); +} finally { + fs.closeSync(fd); +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js b/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js new file mode 100644 index 00000000..96a5f724 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js @@ -0,0 +1,11 @@ +const { truncate, ftruncateSync, open, openSync, close, closeSync } = require('node:fs'); + +// This should be replaced (file descriptor) +const fd = openSync('file.txt', 'w'); +ftruncateSync(fd, 10); +closeSync(fd); + +// This should NOT be replaced (file path) +truncate('other.txt', 5, (err) => { + if (err) throw err; +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs b/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs new file mode 100644 index 00000000..cc4dd98c --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs @@ -0,0 +1,9 @@ +import { truncate, open, close } from 'node:fs'; + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + truncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs b/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs new file mode 100644 index 00000000..78fed4b1 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs @@ -0,0 +1,9 @@ +import fs from 'node:fs'; + +fs.open('file.txt', 'w', (err, fd) => { + if (err) throw err; + fs.truncate(fd, 10, (err) => { + if (err) throw err; + fs.close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/workflow.yaml b/recipes/fs-truncate-fs-depreciation/workflow.yaml new file mode 100644 index 00000000..1bc57731 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/workflow.yaml @@ -0,0 +1,24 @@ +version: "1" +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Apply JS AST Grep transformations + js-ast-grep: + js_file: src/workflow.ts + base_path: . + include: + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript From c4dd3baea19ef2a16c3729f0d86ecada66b1c0ce Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:05:51 +0200 Subject: [PATCH 02/23] add first draft --- package-lock.json | 8 +- .../README.md | 0 .../codemod.yml | 2 +- .../package.json | 6 +- .../src/workflow.ts | 203 ++++++++++++++++++ .../tests/expected/file-1.js | 0 .../tests/expected/file-2.js | 0 .../tests/expected/file-3.js | 0 .../tests/expected/file-4.mjs | 0 .../tests/expected/file-5.mjs | 0 .../tests/input/file-1.js | 0 .../tests/input/file-2.js | 0 .../tests/input/file-3.js | 0 .../tests/input/file-4.mjs | 0 .../tests/input/file-5.mjs | 0 .../workflow.yaml | 0 .../src/workflow.ts | 15 -- 17 files changed, 211 insertions(+), 23 deletions(-) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/README.md (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/codemod.yml (90%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/package.json (80%) create mode 100644 recipes/fs-truncate-fd-depreciation/src/workflow.ts rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-1.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-2.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-3.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-4.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-5.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-1.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-2.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-3.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-4.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-5.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/workflow.yaml (100%) delete mode 100644 recipes/fs-truncate-fs-depreciation/src/workflow.ts diff --git a/package-lock.json b/package-lock.json index c4d02202..ee7d8a93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1420,8 +1420,8 @@ "resolved": "recipes/create-require-from-path", "link": true }, - "node_modules/@nodejs/fs-truncate-fs-depreciation": { - "resolved": "recipes/fs-truncate-fs-depreciation", + "node_modules/@nodejs/fs-truncate-fd-depreciation": { + "resolved": "recipes/fs-truncate-fd-depreciation", "link": true }, "node_modules/@nodejs/import-assertions-to-attributes": { @@ -4073,8 +4073,8 @@ "@types/node": "^24.0.3" } }, - "recipes/fs-truncate-fs-depreciation": { - "name": "@nodejs/fs-truncate-fs-depreciation", + "recipes/fs-truncate-fd-depreciation": { + "name": "@nodejs/fs-truncate-fd-depreciation", "version": "0.0.1", "license": "MIT", "dependencies": { diff --git a/recipes/fs-truncate-fs-depreciation/README.md b/recipes/fs-truncate-fd-depreciation/README.md similarity index 100% rename from recipes/fs-truncate-fs-depreciation/README.md rename to recipes/fs-truncate-fd-depreciation/README.md diff --git a/recipes/fs-truncate-fs-depreciation/codemod.yml b/recipes/fs-truncate-fd-depreciation/codemod.yml similarity index 90% rename from recipes/fs-truncate-fs-depreciation/codemod.yml rename to recipes/fs-truncate-fd-depreciation/codemod.yml index e8f7f9ae..e8e87a5b 100644 --- a/recipes/fs-truncate-fs-depreciation/codemod.yml +++ b/recipes/fs-truncate-fd-depreciation/codemod.yml @@ -1,5 +1,5 @@ schema_version: "1.0" -name: nodejs/create-require-from-path +name: nodejs/fs-truncate-fd-depreciation version: 0.0.1 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy diff --git a/recipes/fs-truncate-fs-depreciation/package.json b/recipes/fs-truncate-fd-depreciation/package.json similarity index 80% rename from recipes/fs-truncate-fs-depreciation/package.json rename to recipes/fs-truncate-fd-depreciation/package.json index f9a42bae..bf988930 100644 --- a/recipes/fs-truncate-fs-depreciation/package.json +++ b/recipes/fs-truncate-fd-depreciation/package.json @@ -1,5 +1,5 @@ { - "name": "@nodejs/fs-truncate-fs-depreciation", + "name": "@nodejs/fs-truncate-fd-depreciation", "version": "0.0.1", "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", "type": "module", @@ -9,12 +9,12 @@ "repository": { "type": "git", "url": "git+https://github.com/nodejs/userland-migrations.git", - "directory": "recipes/fs-truncate-fs-depreciation", + "directory": "recipes/fs-truncate-fd-depreciation", "bugs": "https://github.com/nodejs/userland-migrations/issues" }, "author": "Augustin Mauroy", "license": "MIT", - "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fs-depreciation/README.md", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fd-depreciation/README.md", "devDependencies": { "@codemod.com/jssg-types": "^1.0.3" }, diff --git a/recipes/fs-truncate-fd-depreciation/src/workflow.ts b/recipes/fs-truncate-fd-depreciation/src/workflow.ts new file mode 100644 index 00000000..2780851d --- /dev/null +++ b/recipes/fs-truncate-fd-depreciation/src/workflow.ts @@ -0,0 +1,203 @@ +import { getNodeImportStatements } from "@nodejs/codemod-utils/ast-grep/import-statement"; +import { getNodeRequireCalls } from "@nodejs/codemod-utils/ast-grep/require-call"; +import type { SgRoot, Edit, SgNode } from "@codemod.com/jssg-types/main"; +import type Js from "@codemod.com/jssg-types/langs/javascript"; + +/** + * Transform function that converts deprecated fs.truncate calls to fs.ftruncate. + * + * See DEP0081: https://nodejs.org/api/deprecations.html#DEP0081 + * + * Handles: + * 1. fs.truncate(fd, len, callback) -> fs.ftruncate(fd, len, callback) + * 2. fs.truncateSync(fd, len) -> fs.ftruncateSync(fd, len) + * 3. truncate(fd, len, callback) -> ftruncate(fd, len, callback) (destructured imports) + * 4. truncateSync(fd, len) -> ftruncateSync(fd, len) (destructured imports) + * 5. Import/require statement updates to replace truncate/truncateSync with ftruncate/ftruncateSync + */ +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + let hasChanges = false; + + // Track what imports need to be updated + let usedTruncate = false; + let usedTruncateSync = false; + + // Find all truncate and truncateSync calls + const truncateCalls = rootNode.findAll({ + rule: { + any: [ + { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "fs.truncate($FD, $LEN)" }, + { pattern: "truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "truncate($FD, $LEN)" } + ] + } + }); + + const truncateSyncCalls = rootNode.findAll({ + rule: { + any: [ + { pattern: "fs.truncateSync($FD, $LEN)" }, + { pattern: "truncateSync($FD, $LEN)" } + ] + } + }); + + // Transform truncate calls + for (const call of truncateCalls) { + const fdMatch = call.getMatch("FD"); + const lenMatch = call.getMatch("LEN"); + const callbackMatch = call.getMatch("CALLBACK"); + + if (!fdMatch || !lenMatch) continue; + + const fd = fdMatch.text(); + const len = lenMatch.text(); + const callback = callbackMatch?.text(); + const callText = call.text(); + + // Check if this looks like a file descriptor (numeric or variable from open) + if (isLikelyFileDescriptor(fd, rootNode)) { + if (callText.includes("fs.truncate(")) { + const newCallText = callback + ? `fs.ftruncate(${fd}, ${len}, ${callback})` + : `fs.ftruncate(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + } else { + // destructured call like truncate(...) + const newCallText = callback + ? `ftruncate(${fd}, ${len}, ${callback})` + : `ftruncate(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + usedTruncate = true; + } + hasChanges = true; + } + } + + // Transform truncateSync calls + for (const call of truncateSyncCalls) { + const fdMatch = call.getMatch("FD"); + const lenMatch = call.getMatch("LEN"); + + if (!fdMatch || !lenMatch) continue; + + const fd = fdMatch.text(); + const len = lenMatch.text(); + const callText = call.text(); + + // Check if this looks like a file descriptor + if (isLikelyFileDescriptor(fd, rootNode)) { + if (callText.includes("fs.truncateSync(")) { + const newCallText = `fs.ftruncateSync(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + } else { + // destructured call like truncateSync(...) + const newCallText = `ftruncateSync(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + usedTruncateSync = true; + } + hasChanges = true; + } + } + + // Update imports/requires if we have destructured calls that were transformed + if (usedTruncate || usedTruncateSync) { + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const importStatements = getNodeImportStatements(root, 'fs'); + + // Update import statements + for (const importNode of importStatements) { + const namedImports = importNode.find({ rule: { kind: 'named_imports' } }); + if (!namedImports) continue; + + let importText = importNode.text(); + let updated = false; + + if (usedTruncate && importText.includes("truncate") && !importText.includes("ftruncate")) { + // Replace truncate with ftruncate in imports + importText = importText.replace(/\btruncate\b/g, "ftruncate"); + updated = true; + } + + if (usedTruncateSync && importText.includes("truncateSync") && !importText.includes("ftruncateSync")) { + // Replace truncateSync with ftruncateSync in imports + importText = importText.replace(/\btruncateSync\b/g, "ftruncateSync"); + updated = true; + } + + if (updated) { + edits.push(importNode.replace(importText)); + hasChanges = true; + } + } + + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const requireStatements = getNodeRequireCalls(root, 'fs'); + + // Update require statements + for (const requireNode of requireStatements) { + let requireText = requireNode.text(); + let updated = false; + + if (usedTruncate && requireText.includes("truncate") && !requireText.includes("ftruncate")) { + // Replace truncate with ftruncate in requires + requireText = requireText.replace(/\btruncate\b/g, "ftruncate"); + updated = true; + } + + if (usedTruncateSync && requireText.includes("truncateSync") && !requireText.includes("ftruncateSync")) { + // Replace truncateSync with ftruncateSync in requires + requireText = requireText.replace(/\btruncateSync\b/g, "ftruncateSync"); + updated = true; + } + + if (updated) { + edits.push(requireNode.replace(requireText)); + hasChanges = true; + } + } + } + + if (!hasChanges) return null; + + return rootNode.commitEdits(edits); +} + +/** + * Helper function to determine if a parameter is likely a file descriptor + * rather than a file path string. + * @todo(@AugustinMauroy): use more AST than regex for this function. + * @param param The parameter to check (e.g., 'fd'). + * @param rootNode The root node of the AST to search within. + */ +function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { + // Check if it's a numeric literal + if (/^\d+$/.test(param.trim())) return true; + + // Simple check: if the parameter appears in an `openSync` assignment, it's likely a file descriptor + const sourceText = rootNode.text(); + + // Look for patterns like "const fd = openSync(...)" or "const fd = fs.openSync(...)" + const openSyncPattern = new RegExp(`(?:const|let|var)\\s+${param}\\s*=\\s*(?:fs\\.)?openSync\\s*\\(`, 'g'); + + if (openSyncPattern.test(sourceText)) return true; + + // Look for patterns where the parameter is used in an open callback + // This handles cases like: open('file', (err, fd) => { truncate(fd, ...) }) + const callbackPattern = new RegExp(`\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)\\s*=>`, 'g'); + + if (callbackPattern.test(sourceText)) return true; + + + // Look for function callback patterns + const functionCallbackPattern = new RegExp(`function\\s*\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)`, 'g'); + + if (functionCallbackPattern.test(sourceText)) return true; + + // Conservative approach: if we can't determine it's a file descriptor, + // assume it's a file path to avoid breaking valid path-based truncate calls + return false; +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js b/recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js b/recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js b/recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs b/recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs b/recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js b/recipes/fs-truncate-fd-depreciation/tests/input/file-1.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-1.js rename to recipes/fs-truncate-fd-depreciation/tests/input/file-1.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js b/recipes/fs-truncate-fd-depreciation/tests/input/file-2.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-2.js rename to recipes/fs-truncate-fd-depreciation/tests/input/file-2.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js b/recipes/fs-truncate-fd-depreciation/tests/input/file-3.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-3.js rename to recipes/fs-truncate-fd-depreciation/tests/input/file-3.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs b/recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs rename to recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs b/recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs rename to recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs diff --git a/recipes/fs-truncate-fs-depreciation/workflow.yaml b/recipes/fs-truncate-fd-depreciation/workflow.yaml similarity index 100% rename from recipes/fs-truncate-fs-depreciation/workflow.yaml rename to recipes/fs-truncate-fd-depreciation/workflow.yaml diff --git a/recipes/fs-truncate-fs-depreciation/src/workflow.ts b/recipes/fs-truncate-fs-depreciation/src/workflow.ts deleted file mode 100644 index a59e8ea5..00000000 --- a/recipes/fs-truncate-fs-depreciation/src/workflow.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { SgRoot, Edit } from "@codemod.com/jssg-types/main"; - -/** - * - */ -export default function transform(root: SgRoot): string | null { - const rootNode = root.root(); - const edits: Edit[] = []; - let hasChanges = false; - - - if (!hasChanges) return null; - - return rootNode.commitEdits(edits); -} From b46d7afdc989003c3e40509a56b554a8fe8e3138 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 17:00:11 +0200 Subject: [PATCH 03/23] fix: typo Co-Authored-By: Aviv Keller --- package-lock.json | 8 ++++---- .../README.md | 0 .../codemod.yml | 2 +- .../package.json | 6 +++--- .../src/workflow.ts | 0 .../tests/expected/file-1.js | 0 .../tests/expected/file-2.js | 0 .../tests/expected/file-3.js | 0 .../tests/expected/file-4.mjs | 0 .../tests/expected/file-5.mjs | 0 .../tests/input/file-1.js | 0 .../tests/input/file-2.js | 0 .../tests/input/file-3.js | 0 .../tests/input/file-4.mjs | 0 .../tests/input/file-5.mjs | 0 .../workflow.yaml | 0 16 files changed, 8 insertions(+), 8 deletions(-) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/README.md (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/codemod.yml (90%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/package.json (80%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/src/workflow.ts (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-1.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-2.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-3.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-4.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-5.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-1.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-2.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-3.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-4.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-5.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/workflow.yaml (100%) diff --git a/package-lock.json b/package-lock.json index ee7d8a93..ebb1c4dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1420,8 +1420,8 @@ "resolved": "recipes/create-require-from-path", "link": true }, - "node_modules/@nodejs/fs-truncate-fd-depreciation": { - "resolved": "recipes/fs-truncate-fd-depreciation", + "node_modules/@nodejs/fs-truncate-fd-deprecation": { + "resolved": "recipes/fs-truncate-fd-deprecation", "link": true }, "node_modules/@nodejs/import-assertions-to-attributes": { @@ -4073,8 +4073,8 @@ "@types/node": "^24.0.3" } }, - "recipes/fs-truncate-fd-depreciation": { - "name": "@nodejs/fs-truncate-fd-depreciation", + "recipes/fs-truncate-fd-deprecation": { + "name": "@nodejs/fs-truncate-fd-deprecation", "version": "0.0.1", "license": "MIT", "dependencies": { diff --git a/recipes/fs-truncate-fd-depreciation/README.md b/recipes/fs-truncate-fd-deprecation/README.md similarity index 100% rename from recipes/fs-truncate-fd-depreciation/README.md rename to recipes/fs-truncate-fd-deprecation/README.md diff --git a/recipes/fs-truncate-fd-depreciation/codemod.yml b/recipes/fs-truncate-fd-deprecation/codemod.yml similarity index 90% rename from recipes/fs-truncate-fd-depreciation/codemod.yml rename to recipes/fs-truncate-fd-deprecation/codemod.yml index e8e87a5b..391bde96 100644 --- a/recipes/fs-truncate-fd-depreciation/codemod.yml +++ b/recipes/fs-truncate-fd-deprecation/codemod.yml @@ -1,5 +1,5 @@ schema_version: "1.0" -name: nodejs/fs-truncate-fd-depreciation +name: nodejs/fs-truncate-fd-deprecation version: 0.0.1 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy diff --git a/recipes/fs-truncate-fd-depreciation/package.json b/recipes/fs-truncate-fd-deprecation/package.json similarity index 80% rename from recipes/fs-truncate-fd-depreciation/package.json rename to recipes/fs-truncate-fd-deprecation/package.json index bf988930..8a92d26c 100644 --- a/recipes/fs-truncate-fd-depreciation/package.json +++ b/recipes/fs-truncate-fd-deprecation/package.json @@ -1,5 +1,5 @@ { - "name": "@nodejs/fs-truncate-fd-depreciation", + "name": "@nodejs/fs-truncate-fd-deprecation", "version": "0.0.1", "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", "type": "module", @@ -9,12 +9,12 @@ "repository": { "type": "git", "url": "git+https://github.com/nodejs/userland-migrations.git", - "directory": "recipes/fs-truncate-fd-depreciation", + "directory": "recipes/fs-truncate-fd-deprecation", "bugs": "https://github.com/nodejs/userland-migrations/issues" }, "author": "Augustin Mauroy", "license": "MIT", - "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fd-depreciation/README.md", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fd-deprecation/README.md", "devDependencies": { "@codemod.com/jssg-types": "^1.0.3" }, diff --git a/recipes/fs-truncate-fd-depreciation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts similarity index 100% rename from recipes/fs-truncate-fd-depreciation/src/workflow.ts rename to recipes/fs-truncate-fd-deprecation/src/workflow.ts diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js b/recipes/fs-truncate-fd-deprecation/tests/expected/file-1.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-1.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js b/recipes/fs-truncate-fd-deprecation/tests/expected/file-2.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-2.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js b/recipes/fs-truncate-fd-deprecation/tests/expected/file-3.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-3.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-4.mjs diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-5.mjs diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-1.js b/recipes/fs-truncate-fd-deprecation/tests/input/file-1.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-1.js rename to recipes/fs-truncate-fd-deprecation/tests/input/file-1.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-2.js b/recipes/fs-truncate-fd-deprecation/tests/input/file-2.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-2.js rename to recipes/fs-truncate-fd-deprecation/tests/input/file-2.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-3.js b/recipes/fs-truncate-fd-deprecation/tests/input/file-3.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-3.js rename to recipes/fs-truncate-fd-deprecation/tests/input/file-3.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs b/recipes/fs-truncate-fd-deprecation/tests/input/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs rename to recipes/fs-truncate-fd-deprecation/tests/input/file-4.mjs diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs b/recipes/fs-truncate-fd-deprecation/tests/input/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs rename to recipes/fs-truncate-fd-deprecation/tests/input/file-5.mjs diff --git a/recipes/fs-truncate-fd-depreciation/workflow.yaml b/recipes/fs-truncate-fd-deprecation/workflow.yaml similarity index 100% rename from recipes/fs-truncate-fd-depreciation/workflow.yaml rename to recipes/fs-truncate-fd-deprecation/workflow.yaml From 9e0365abfd2b80964888c167e094e25338901472 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 18:42:51 +0200 Subject: [PATCH 04/23] refracto to use AST --- .../src/workflow.ts | 153 ++++++++++++++++-- 1 file changed, 136 insertions(+), 17 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 2780851d..4e04ab4d 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -169,7 +169,6 @@ export default function transform(root: SgRoot): string | null { /** * Helper function to determine if a parameter is likely a file descriptor * rather than a file path string. - * @todo(@AugustinMauroy): use more AST than regex for this function. * @param param The parameter to check (e.g., 'fd'). * @param rootNode The root node of the AST to search within. */ @@ -177,27 +176,147 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { // Check if it's a numeric literal if (/^\d+$/.test(param.trim())) return true; - // Simple check: if the parameter appears in an `openSync` assignment, it's likely a file descriptor - const sourceText = rootNode.text(); - - // Look for patterns like "const fd = openSync(...)" or "const fd = fs.openSync(...)" - const openSyncPattern = new RegExp(`(?:const|let|var)\\s+${param}\\s*=\\s*(?:fs\\.)?openSync\\s*\\(`, 'g'); - - if (openSyncPattern.test(sourceText)) return true; + // Search for variable declarations that might assign a file descriptor + // such as `const fd = fs.openSync(...)` or `open(..., (err, fd) => ...)` + const variableDeclarators = rootNode.findAll({ + rule: { + kind: "variable_declarator", + all: [ + { + has: { + field: "name", + kind: "identifier", + regex: `^${param}$` + } + }, + { + has: { + field: "value", + kind: "call_expression", + has: { + field: "function", + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^(open|openSync)$" + } + } + ] + } + } + } + ] + } + }); - // Look for patterns where the parameter is used in an open callback - // This handles cases like: open('file', (err, fd) => { truncate(fd, ...) }) - const callbackPattern = new RegExp(`\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)\\s*=>`, 'g'); + if (variableDeclarators.length > 0) return true; - if (callbackPattern.test(sourceText)) return true; + // Check if the parameter appears as a callback parameter in fs.open calls + // Pattern: open(..., (err, fd) => ...) + const callbackParameters = rootNode.findAll({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "identifier", + regex: "^open$" + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - idk what happend here maybe a bug in infering `Js` type + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + } + } + ] + } + }); + if (callbackParameters.length > 0) return true; - // Look for function callback patterns - const functionCallbackPattern = new RegExp(`function\\s*\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)`, 'g'); + // Check for fs.open callback patterns as well + const fsOpenCallbacks = rootNode.findAll({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^open$" + } + } + ] + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - idk what happend here maybe a bug in infering `Js` type + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + } + } + ] + } + }); - if (functionCallbackPattern.test(sourceText)) return true; + if (fsOpenCallbacks.length > 0) return true; - // Conservative approach: if we can't determine it's a file descriptor, - // assume it's a file path to avoid breaking valid path-based truncate calls + // If we didn't find any indicators, assume it's not a file descriptor return false; } From a4d49386df7c989f72e44878162d5838ffe59c55 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 20:09:45 +0200 Subject: [PATCH 05/23] refracto --- .../src/workflow.ts | 323 +++++++++++++----- 1 file changed, 244 insertions(+), 79 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 4e04ab4d..c6284f7b 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -176,9 +176,178 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { // Check if it's a numeric literal if (/^\d+$/.test(param.trim())) return true; - // Search for variable declarations that might assign a file descriptor - // such as `const fd = fs.openSync(...)` or `open(..., (err, fd) => ...)` - const variableDeclarators = rootNode.findAll({ + // Check if parameter is in a callback context + if (isInCallbackContext(param, rootNode)) return true; + + // Check if there's a variable in scope that assigns a file descriptor + if (hasFileDescriptorVariable(param, rootNode)) return true; + + // If we didn't find any indicators, assume it's not a file descriptor + return false; +} + +/** + * Check if the parameter is used inside a callback context from fs.open + * @param param The parameter name to check + * @param rootNode The root node of the AST + */ +function isInCallbackContext(param: string, rootNode: SgNode): boolean { + // Find all uses of the parameter + const parameterUsages = rootNode.findAll({ + rule: { + kind: "identifier", + regex: `^${param}$` + } + }); + + for (const usage of parameterUsages) { + // Check if this usage is inside a callback parameter list for fs.open + const isInFsOpenCallback = usage.inside({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^open$" + } + } + ] + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + any: [ + { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + }, + { + kind: "function_expression", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + ] + } + } + } + ] + } + }); + + // Check if this usage is inside a callback parameter list for destructured open + const isInDestructuredOpenCallback = usage.inside({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "identifier", + regex: "^open$" + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + any: [ + { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + }, + { + kind: "function_expression", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + ] + } + } + } + ] + } + }); + + if (isInFsOpenCallback || isInDestructuredOpenCallback) { + return true; + } + } + + return false; +} + +/** + * Check if there's a variable in scope that assigns a file descriptor value + * @param param The parameter name to check + * @param rootNode The root node of the AST + */ +function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean { + // Search for variable declarations that assign from fs.openSync + const syncVariableDeclarators = rootNode.findAll({ rule: { kind: "variable_declarator", all: [ @@ -195,21 +364,29 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { kind: "call_expression", has: { field: "function", - kind: "member_expression", - all: [ + any: [ { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^openSync$" + } + } + ] }, { - has: { - field: "property", - kind: "property_identifier", - regex: "^(open|openSync)$" - } + kind: "identifier", + regex: "^openSync$" } ] } @@ -219,40 +396,51 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { } }); - if (variableDeclarators.length > 0) return true; + if (syncVariableDeclarators.length > 0) return true; - // Check if the parameter appears as a callback parameter in fs.open calls - // Pattern: open(..., (err, fd) => ...) - const callbackParameters = rootNode.findAll({ + // Search for assignment expressions that assign from fs.openSync + const syncAssignments = rootNode.findAll({ rule: { - kind: "call_expression", + kind: "assignment_expression", all: [ { has: { - field: "function", + field: "left", kind: "identifier", - regex: "^open$" + regex: `^${param}$` } }, { has: { - field: "arguments", - kind: "arguments", + field: "right", + kind: "call_expression", has: { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - idk what happend here maybe a bug in infering `Js` type - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } + field: "function", + any: [ + { + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^openSync$" + } + } + ] + }, + { + kind: "identifier", + regex: "^openSync$" } - } + ] } } } @@ -260,63 +448,40 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { } }); - if (callbackParameters.length > 0) return true; + if (syncAssignments.length > 0) return true; - // Check for fs.open callback patterns as well - const fsOpenCallbacks = rootNode.findAll({ + // Check if the variable is assigned from another variable that's a file descriptor + const variableAssignments = rootNode.findAll({ rule: { - kind: "call_expression", + kind: "variable_declarator", all: [ { has: { - field: "function", - kind: "member_expression", - all: [ - { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } - }, - { - has: { - field: "property", - kind: "property_identifier", - regex: "^open$" - } - } - ] + field: "name", + kind: "identifier", + regex: `^${param}$` } }, { has: { - field: "arguments", - kind: "arguments", - has: { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - idk what happend here maybe a bug in infering `Js` type - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - } + field: "value", + kind: "identifier" } } ] } }); - if (fsOpenCallbacks.length > 0) return true; + for (const assignment of variableAssignments) { + const valueNode = assignment.field("value"); + if (valueNode) { + const sourceVar = valueNode.text(); + // Recursively check if the source variable is a file descriptor + if (hasFileDescriptorVariable(sourceVar, rootNode)) { + return true; + } + } + } - // If we didn't find any indicators, assume it's not a file descriptor return false; } From aa4a23d32fc5ed31e4aae9069a3b6e340ae4e713 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 20:29:36 +0200 Subject: [PATCH 06/23] WARNING: edge-case --- recipes/fs-truncate-fd-deprecation/README.md | 5 ++++ .../tests/expected/edge-case.mjs | 25 +++++++++++++++++++ .../tests/input/edge-case.mjs | 25 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs create mode 100644 recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs diff --git a/recipes/fs-truncate-fd-deprecation/README.md b/recipes/fs-truncate-fd-deprecation/README.md index 1d25932c..666622c7 100644 --- a/recipes/fs-truncate-fd-deprecation/README.md +++ b/recipes/fs-truncate-fd-deprecation/README.md @@ -31,3 +31,8 @@ open('file.txt', 'w', (err, fd) => { }); }); ``` + +## Caveats + +When using `const fd = fs.openSync('file.txt', 'w');`, the codemod don't care about scope and will always transform `fs.truncate(fd, 10)` to `fs.ftruncateSync(fd, 10)`. So if you have mutiple variables with the same name, you should be careful with the transformation. + diff --git a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs new file mode 100644 index 00000000..a05e4f02 --- /dev/null +++ b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs @@ -0,0 +1,25 @@ +import fs from 'node:fs'; + +export default function truncateFile() { + fs.open('file.txt', 'w', (err, strangeName) => { + if (err) throw err; + fs.ftruncate(strangeName, 10, (err) => { + if (err) throw err; + fs.close(strangeName, () => { }); + }); + }); +} + +const accesible = fs.openSync('file.txt', 'w'); + +fs.ftruncateSync(accesible, 10); + +fs.closeSync(accesible); + +function foo() { + truncateFile(unaccessible, 10); +} + +function bar() { + const unaccessible = fs.openSync('file.txt', 'w'); +} diff --git a/recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs new file mode 100644 index 00000000..f9214366 --- /dev/null +++ b/recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs @@ -0,0 +1,25 @@ +import fs from 'node:fs'; + +export default function truncateFile() { + fs.open('file.txt', 'w', (err, strangeName) => { + if (err) throw err; + fs.truncate(strangeName, 10, (err) => { + if (err) throw err; + fs.close(strangeName, () => { }); + }); + }); +} + +const accesible = fs.openSync('file.txt', 'w'); + +fs.truncateSync(accesible, 10); + +fs.closeSync(accesible); + +function foo() { + truncateFile(unaccessible, 10); +} + +function bar() { + const unaccessible = fs.openSync('file.txt', 'w'); +} From 13c2ddc2f0a0ebe2b12d75c8d8ab15f37c78e002 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 22:15:30 +0200 Subject: [PATCH 07/23] WIP --- package-lock.json | 96 +++++++-------- .../src/workflow.ts | 115 ++++++++++++++++-- .../tests/expected/edge-case.mjs | 2 +- 3 files changed, 156 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index ebb1c4dc..7c70edae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -169,30 +169,30 @@ } }, "node_modules/@ast-grep/napi": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.39.1.tgz", - "integrity": "sha512-omVL1aWHuc/gCMqtJRHLKJMM1VFRnaHU18IxL0tKeQHQJGVRU15I6MKi6z8RAeey4CFVw26l+HlXdfHMWMIyWQ==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.39.2.tgz", + "integrity": "sha512-q6ryspY37PKLrfx+jNQrnR1qYTahRQO2yAvlDK6X4b4AHRtg7mXlaccHGpAFtkTZLhdkI9nl1WHsuqmKx1HWhw==", "dev": true, "license": "MIT", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@ast-grep/napi-darwin-arm64": "0.39.1", - "@ast-grep/napi-darwin-x64": "0.39.1", - "@ast-grep/napi-linux-arm64-gnu": "0.39.1", - "@ast-grep/napi-linux-arm64-musl": "0.39.1", - "@ast-grep/napi-linux-x64-gnu": "0.39.1", - "@ast-grep/napi-linux-x64-musl": "0.39.1", - "@ast-grep/napi-win32-arm64-msvc": "0.39.1", - "@ast-grep/napi-win32-ia32-msvc": "0.39.1", - "@ast-grep/napi-win32-x64-msvc": "0.39.1" + "@ast-grep/napi-darwin-arm64": "0.39.2", + "@ast-grep/napi-darwin-x64": "0.39.2", + "@ast-grep/napi-linux-arm64-gnu": "0.39.2", + "@ast-grep/napi-linux-arm64-musl": "0.39.2", + "@ast-grep/napi-linux-x64-gnu": "0.39.2", + "@ast-grep/napi-linux-x64-musl": "0.39.2", + "@ast-grep/napi-win32-arm64-msvc": "0.39.2", + "@ast-grep/napi-win32-ia32-msvc": "0.39.2", + "@ast-grep/napi-win32-x64-msvc": "0.39.2" } }, "node_modules/@ast-grep/napi-darwin-arm64": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.39.1.tgz", - "integrity": "sha512-g+Bf940b/k6/yrLwWTCXDaZ4Nt5NjUM30MJcwnBbTXsmlRIYnoFIktR8X7kS33DSCu7knT22QdF3B393mHoyVg==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.39.2.tgz", + "integrity": "sha512-/tCV3ORHL1gAiepOF7i/KsZOfe14vnfz+pr6npDzffpTgPZ8tp/bTkHtytUu+xw7ow7ZoAwNd75lvNkCDy6qYw==", "cpu": [ "arm64" ], @@ -207,9 +207,9 @@ } }, "node_modules/@ast-grep/napi-darwin-x64": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.39.1.tgz", - "integrity": "sha512-jPtuBBnQT7BC+oA0UudC2nGUcIUQF//f1CKnz4DnEj3AebgsW8RAkIUTSw20Y6uhPTjbSQ9fx9AjDvbQZe/I5A==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.39.2.tgz", + "integrity": "sha512-MJqaI7JTqbNMUcAvxKIdCgdRVSew/RLnxXkBO6G89SznVgdX3lRXyzPw/trhGcCWR1dByFN/Ne2LyusgjrbGdg==", "cpu": [ "x64" ], @@ -224,9 +224,9 @@ } }, "node_modules/@ast-grep/napi-linux-arm64-gnu": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.39.1.tgz", - "integrity": "sha512-N7wH7ExECtYLeXe6Q1/s7NZFCDGJQrkmQaYa2vooSFYZB1i4BAtFu92K3IzpTlMXxbwqrGIEZGPcRmZOYW68cA==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.39.2.tgz", + "integrity": "sha512-TbC+OQD+qp1qIqDVvFPQqBPCouS17HtIs0DUn5rDvnXlzNGNd7SZNGT+Gr+hfmOBw3qgzWTSo+tI8H/FrUMG4w==", "cpu": [ "arm64" ], @@ -241,9 +241,9 @@ } }, "node_modules/@ast-grep/napi-linux-arm64-musl": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.39.1.tgz", - "integrity": "sha512-mc2yJV3mFVth1hwRwz3UTnAEVykRQhGMz8pfjC0GEistHqe6a18KYTIUwYFmQD300O/rLTCLvgV64ICzqD8k4A==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.39.2.tgz", + "integrity": "sha512-AFosOAD+9f7lZJPvEh0w32Yy7DJOmOs+PlQzFiBimpsb6gjnjx9NZLwrwMEmW9aKPI6469QKP7DIVASNPozYGw==", "cpu": [ "arm64" ], @@ -258,9 +258,9 @@ } }, "node_modules/@ast-grep/napi-linux-x64-gnu": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.39.1.tgz", - "integrity": "sha512-xvIINrydi0WTU8yS48UhfHNv/xawF0Cjob2Km+UyVKgNZc5HDlAnn/BxXnTgvV6gla1ynC1FVmxHKmixoUnA3A==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.39.2.tgz", + "integrity": "sha512-qS9V2ZBiRnvhDHEAEOeO5K7Fn84+u/pqGKxDDcGZKzmp0Z27nvZR7pIybPiWgMh802G4o+iIHeRqPJgfEq7iqg==", "cpu": [ "x64" ], @@ -275,9 +275,9 @@ } }, "node_modules/@ast-grep/napi-linux-x64-musl": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.39.1.tgz", - "integrity": "sha512-ehAce6LVhZPS612lVH0unXgmSP2kyNI1hs7vXpboJTbZkuNTNn+vWBICSP6XaInsV1BqZ6VejAIgA42iH6BrqQ==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.39.2.tgz", + "integrity": "sha512-GbErl6NOwvWFqrZKUG+pdHiVKIgcpOIHOn8lBjcR06PA2Mgx44EyqkhzRXa55mjoxgOM80n//ZnhGwxVXhnSqQ==", "cpu": [ "x64" ], @@ -292,9 +292,9 @@ } }, "node_modules/@ast-grep/napi-win32-arm64-msvc": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.39.1.tgz", - "integrity": "sha512-HWl/jX3RT69XR/2JNdv2L1Rh7YeXHvuwq8GVBJcWhNtj3wFT9h5h8MSzfWgPLLmB6VAhjulPrG1iU7LAjvWaYQ==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.39.2.tgz", + "integrity": "sha512-OHMDi9C3FbmfFHbHsIeTJw/EdxpYq7bpcLVhsnP10FOPhpr/8L+w8trO9pQ9NlwCRDP8JL53UzDfBmrZPRgWgg==", "cpu": [ "arm64" ], @@ -309,9 +309,9 @@ } }, "node_modules/@ast-grep/napi-win32-ia32-msvc": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.39.1.tgz", - "integrity": "sha512-fivsR5Et5/UHQ/BArzQgeTV05J49JcB+vjZSi0H/6uiNoq2+GOcwPkdlEGGM3HdDH64olaeXgRku0L9993r1Qw==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.39.2.tgz", + "integrity": "sha512-htbGo7d0GPCLDTtXoKP38Rgn5MgLSCO2YXZaxQ7vq8QKfeussBcIr0yfbwUu4gDFhpSM7DPzDfHUTX/YDcD2fw==", "cpu": [ "ia32" ], @@ -326,9 +326,9 @@ } }, "node_modules/@ast-grep/napi-win32-x64-msvc": { - "version": "0.39.1", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.39.1.tgz", - "integrity": "sha512-e7+eTU2aTDgE6c+vrkCkiJLxvzHm2Keirp/cHOx69KgZSYVWbfGrPj8VpLBIUHHapI58BKzLd4j+yFdD51fryg==", + "version": "0.39.2", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.39.2.tgz", + "integrity": "sha512-geqOguM9gpHB9P9p9HcV+Lnq8dU6srYe3tVYQ9Wssxk/u1ZB9/DDUYgoW51tMXdWqfXEVt4KetAfiTHOOhOi4Q==", "cpu": [ "x64" ], @@ -1896,9 +1896,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "version": "1.0.30001731", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", + "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", "funding": [ { "type": "opencollective", @@ -2214,9 +2214,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.191", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz", - "integrity": "sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==", + "version": "1.5.192", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.192.tgz", + "integrity": "sha512-rP8Ez0w7UNw/9j5eSXCe10o1g/8B1P5SM90PCCMVkIRQn2R0LEHWz4Eh9RnxkniuDe1W0cTSOB3MLlkTGDcuCg==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -3227,9 +3227,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.120", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.120.tgz", - "integrity": "sha512-WtCGHFXnVI8WHLxDAt5TbnCM4eSE+nI0QN2NJtwzcgMhht2eNz6V9evJrk+lwC8bCY8OWV5Ym8Jz7ZEyGnKnMA==", + "version": "18.19.121", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.121.tgz", + "integrity": "sha512-bHOrbyztmyYIi4f1R0s17QsPs1uyyYnGcXeZoGEd227oZjry0q6XQBQxd82X1I57zEfwO8h9Xo+Kl5gX1d9MwQ==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index c6284f7b..223d12da 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -346,8 +346,77 @@ function isInCallbackContext(param: string, rootNode: SgNode): boolean { * @param rootNode The root node of the AST */ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean { - // Search for variable declarations that assign from fs.openSync - const syncVariableDeclarators = rootNode.findAll({ + // Find all usages of the parameter to understand the context + const parameterUsages = rootNode.findAll({ + rule: { + kind: "identifier", + regex: `^${param}$` + } + }); + + // For each usage, check if there's a variable declaration in scope + for (const usage of parameterUsages) { + // Check if this usage is in a truncate call context + const isInTruncateCall = usage.inside({ + rule: { + any: [ + { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "fs.truncate($FD, $LEN)" }, + { pattern: "truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "truncate($FD, $LEN)" }, + { pattern: "fs.truncateSync($FD, $LEN)" }, + { pattern: "truncateSync($FD, $LEN)" } + ] + } + }); + + if (!isInTruncateCall) continue; + + // Find the scope containing this usage + const scope = findContainingScope(usage); + if (!scope) continue; + + // Search for variable declarations within this scope + if (hasFileDescriptorVariableInScope(param, scope)) { + return true; + } + } + + return false; +} + +/** + * Find the containing scope (function, block, or program) for a given node + * @param node The node to find the scope for + */ +function findContainingScope(node: SgNode): SgNode | null { + let current = node.parent(); + + while (current) { + const kind = current.kind(); + // These are scope-creating nodes in JavaScript + if (kind === "program" || + kind === "function_declaration" || + kind === "function_expression" || + kind === "arrow_function" || + kind === "method_definition" || + kind === "statement_block") { + return current; + } + current = current.parent(); + } + + return null; +} + +/** + * Check if there's a file descriptor variable declaration within a specific scope + * @param param The parameter name to check + * @param scope The scope node to search within + */ +function hasFileDescriptorVariableInScope(param: string, scope: SgNode): boolean { + // Search for variable declarations that assign from fs.openSync within this scope + const syncVariableDeclarators = scope.findAll({ rule: { kind: "variable_declarator", all: [ @@ -398,8 +467,8 @@ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean if (syncVariableDeclarators.length > 0) return true; - // Search for assignment expressions that assign from fs.openSync - const syncAssignments = rootNode.findAll({ + // Search for assignment expressions that assign from fs.openSync within this scope + const syncAssignments = scope.findAll({ rule: { kind: "assignment_expression", all: [ @@ -450,8 +519,8 @@ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean if (syncAssignments.length > 0) return true; - // Check if the variable is assigned from another variable that's a file descriptor - const variableAssignments = rootNode.findAll({ + // Check if the variable is assigned from another variable that's a file descriptor within this scope + const variableAssignments = scope.findAll({ rule: { kind: "variable_declarator", all: [ @@ -476,12 +545,42 @@ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean const valueNode = assignment.field("value"); if (valueNode) { const sourceVar = valueNode.text(); - // Recursively check if the source variable is a file descriptor - if (hasFileDescriptorVariable(sourceVar, rootNode)) { + // Recursively check if the source variable is a file descriptor within the same scope + if (hasFileDescriptorVariableInScope(sourceVar, scope)) { return true; } } } + // If not found in current scope, check parent scopes (for closure/lexical scoping) + const parentScope = findParentScope(scope); + if (parentScope) { + return hasFileDescriptorVariableInScope(param, parentScope); + } + return false; } + +/** + * Find the parent scope of a given scope node + * @param scope The current scope node + */ +function findParentScope(scope: SgNode): SgNode | null { + let current = scope.parent(); + + while (current) { + const kind = current.kind(); + // These are scope-creating nodes in JavaScript + if (kind === "program" || + kind === "function_declaration" || + kind === "function_expression" || + kind === "arrow_function" || + kind === "method_definition" || + kind === "statement_block") { + return current; + } + current = current.parent(); + } + + return null; +} diff --git a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs index a05e4f02..12399270 100644 --- a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs +++ b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs @@ -17,7 +17,7 @@ fs.ftruncateSync(accesible, 10); fs.closeSync(accesible); function foo() { - truncateFile(unaccessible, 10); + ftruncateFile(unaccessible, 10); } function bar() { From f989d4f3d4e5d11be22b12b6176715b8e58ff000 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Tue, 29 Jul 2025 23:23:29 +0200 Subject: [PATCH 08/23] clean chore files --- package-lock.json | 4 ++-- recipes/fs-truncate-fd-deprecation/codemod.yml | 2 +- recipes/fs-truncate-fd-deprecation/package.json | 4 ++-- recipes/fs-truncate-fd-deprecation/workflow.yaml | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7c70edae..7b9208d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4075,10 +4075,10 @@ }, "recipes/fs-truncate-fd-deprecation": { "name": "@nodejs/fs-truncate-fd-deprecation", - "version": "0.0.1", + "version": "1.0.0", "license": "MIT", "dependencies": { - "@nodejs/codemod-utils": "0.0.0" + "@nodejs/codemod-utils": "*" }, "devDependencies": { "@codemod.com/jssg-types": "^1.0.3" diff --git a/recipes/fs-truncate-fd-deprecation/codemod.yml b/recipes/fs-truncate-fd-deprecation/codemod.yml index 391bde96..0601a55a 100644 --- a/recipes/fs-truncate-fd-deprecation/codemod.yml +++ b/recipes/fs-truncate-fd-deprecation/codemod.yml @@ -1,6 +1,6 @@ schema_version: "1.0" name: nodejs/fs-truncate-fd-deprecation -version: 0.0.1 +version: 1.0.0 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy license: MIT diff --git a/recipes/fs-truncate-fd-deprecation/package.json b/recipes/fs-truncate-fd-deprecation/package.json index 8a92d26c..44f70f2d 100644 --- a/recipes/fs-truncate-fd-deprecation/package.json +++ b/recipes/fs-truncate-fd-deprecation/package.json @@ -1,6 +1,6 @@ { "name": "@nodejs/fs-truncate-fd-deprecation", - "version": "0.0.1", + "version": "1.0.0", "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", "type": "module", "scripts": { @@ -19,6 +19,6 @@ "@codemod.com/jssg-types": "^1.0.3" }, "dependencies": { - "@nodejs/codemod-utils": "0.0.0" + "@nodejs/codemod-utils": "*" } } diff --git a/recipes/fs-truncate-fd-deprecation/workflow.yaml b/recipes/fs-truncate-fd-deprecation/workflow.yaml index 1bc57731..e4777e8f 100644 --- a/recipes/fs-truncate-fd-deprecation/workflow.yaml +++ b/recipes/fs-truncate-fd-deprecation/workflow.yaml @@ -1,4 +1,5 @@ version: "1" + nodes: - id: apply-transforms name: Apply AST Transformations From 095b88ae90db1b716be51c701423d069cdee2020 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Tue, 29 Jul 2025 23:45:48 +0200 Subject: [PATCH 09/23] improve security --- recipes/fs-truncate-fd-deprecation/README.md | 5 - .../src/workflow.ts | 613 +++++------------- .../tests/expected/edge-case.mjs | 2 +- 3 files changed, 171 insertions(+), 449 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/README.md b/recipes/fs-truncate-fd-deprecation/README.md index 666622c7..1d25932c 100644 --- a/recipes/fs-truncate-fd-deprecation/README.md +++ b/recipes/fs-truncate-fd-deprecation/README.md @@ -31,8 +31,3 @@ open('file.txt', 'w', (err, fd) => { }); }); ``` - -## Caveats - -When using `const fd = fs.openSync('file.txt', 'w');`, the codemod don't care about scope and will always transform `fs.truncate(fd, 10)` to `fs.ftruncateSync(fd, 10)`. So if you have mutiple variables with the same name, you should be careful with the transformation. - diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 223d12da..2885bec1 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -24,29 +24,19 @@ export default function transform(root: SgRoot): string | null { let usedTruncate = false; let usedTruncateSync = false; - // Find all truncate and truncateSync calls - const truncateCalls = rootNode.findAll({ + // Find fs.truncate and fs.truncateSync calls (these are always safe to transform) + const fsTruncateCalls = rootNode.findAll({ rule: { any: [ { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, { pattern: "fs.truncate($FD, $LEN)" }, - { pattern: "truncate($FD, $LEN, $CALLBACK)" }, - { pattern: "truncate($FD, $LEN)" } - ] - } - }); - - const truncateSyncCalls = rootNode.findAll({ - rule: { - any: [ - { pattern: "fs.truncateSync($FD, $LEN)" }, - { pattern: "truncateSync($FD, $LEN)" } + { pattern: "fs.truncateSync($FD, $LEN)" } ] } }); - // Transform truncate calls - for (const call of truncateCalls) { + // Transform fs.truncate calls + for (const call of fsTruncateCalls) { const fdMatch = call.getMatch("FD"); const lenMatch = call.getMatch("LEN"); const callbackMatch = call.getMatch("CALLBACK"); @@ -58,112 +48,128 @@ export default function transform(root: SgRoot): string | null { const callback = callbackMatch?.text(); const callText = call.text(); - // Check if this looks like a file descriptor (numeric or variable from open) - if (isLikelyFileDescriptor(fd, rootNode)) { - if (callText.includes("fs.truncate(")) { - const newCallText = callback - ? `fs.ftruncate(${fd}, ${len}, ${callback})` - : `fs.ftruncate(${fd}, ${len})`; - edits.push(call.replace(newCallText)); - } else { - // destructured call like truncate(...) - const newCallText = callback - ? `ftruncate(${fd}, ${len}, ${callback})` - : `ftruncate(${fd}, ${len})`; - edits.push(call.replace(newCallText)); - usedTruncate = true; - } - hasChanges = true; + let newCallText: string; + if (callText.includes("fs.truncateSync(")) { + newCallText = `fs.ftruncateSync(${fd}, ${len})`; + } else { + newCallText = callback + ? `fs.ftruncate(${fd}, ${len}, ${callback})` + : `fs.ftruncate(${fd}, ${len})`; } - } - // Transform truncateSync calls - for (const call of truncateSyncCalls) { - const fdMatch = call.getMatch("FD"); - const lenMatch = call.getMatch("LEN"); + edits.push(call.replace(newCallText)); + hasChanges = true; + } - if (!fdMatch || !lenMatch) continue; + // Find destructured truncate/truncateSync calls (need scope analysis) + const destructuredCalls = rootNode.findAll({ + rule: { + any: [ + { pattern: "truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "truncate($FD, $LEN)" }, + { pattern: "truncateSync($FD, $LEN)" } + ] + } + }); - const fd = fdMatch.text(); - const len = lenMatch.text(); - const callText = call.text(); + // Transform destructured calls only if they're from fs imports/requires + for (const call of destructuredCalls) { + if (isFromFsModule(call, root)) { + const fdMatch = call.getMatch("FD"); + const lenMatch = call.getMatch("LEN"); + const callbackMatch = call.getMatch("CALLBACK"); + + if (!fdMatch || !lenMatch) continue; + + const fd = fdMatch.text(); + const len = lenMatch.text(); + const callback = callbackMatch?.text(); + const callText = call.text(); + + // Check if this looks like a file descriptor + if (isLikelyFileDescriptor(fd, rootNode)) { + let newCallText: string; + + if (callText.includes("truncateSync(")) { + newCallText = `ftruncateSync(${fd}, ${len})`; + usedTruncateSync = true; + } else { + newCallText = callback + ? `ftruncate(${fd}, ${len}, ${callback})` + : `ftruncate(${fd}, ${len})`; + usedTruncate = true; + } - // Check if this looks like a file descriptor - if (isLikelyFileDescriptor(fd, rootNode)) { - if (callText.includes("fs.truncateSync(")) { - const newCallText = `fs.ftruncateSync(${fd}, ${len})`; - edits.push(call.replace(newCallText)); - } else { - // destructured call like truncateSync(...) - const newCallText = `ftruncateSync(${fd}, ${len})`; edits.push(call.replace(newCallText)); - usedTruncateSync = true; + hasChanges = true; } - hasChanges = true; } } // Update imports/requires if we have destructured calls that were transformed if (usedTruncate || usedTruncateSync) { - // @ts-ignore - ast-grep types are not fully compatible with JSSG types - const importStatements = getNodeImportStatements(root, 'fs'); - - // Update import statements - for (const importNode of importStatements) { - const namedImports = importNode.find({ rule: { kind: 'named_imports' } }); - if (!namedImports) continue; - - let importText = importNode.text(); - let updated = false; + updateImportsAndRequires(root, usedTruncate, usedTruncateSync, edits); + hasChanges = true; + } - if (usedTruncate && importText.includes("truncate") && !importText.includes("ftruncate")) { - // Replace truncate with ftruncate in imports - importText = importText.replace(/\btruncate\b/g, "ftruncate"); - updated = true; - } + if (!hasChanges) return null; - if (usedTruncateSync && importText.includes("truncateSync") && !importText.includes("ftruncateSync")) { - // Replace truncateSync with ftruncateSync in imports - importText = importText.replace(/\btruncateSync\b/g, "ftruncateSync"); - updated = true; - } + return rootNode.commitEdits(edits); +} - if (updated) { - edits.push(importNode.replace(importText)); - hasChanges = true; - } +/** + * Update import and require statements to replace truncate functions with ftruncate + */ +function updateImportsAndRequires(root: SgRoot, usedTruncate: boolean, usedTruncateSync: boolean, edits: Edit[]): void { + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const importStatements = getNodeImportStatements(root, 'fs'); + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const requireStatements = getNodeRequireCalls(root, 'fs'); + + // Update import and require statements + for (const statement of [...importStatements, ...requireStatements]) { + let text = statement.text(); + let updated = false; + + if (usedTruncate && text.includes("truncate") && !text.includes("ftruncate")) { + text = text.replace(/\btruncate\b/g, "ftruncate"); + updated = true; } - // @ts-ignore - ast-grep types are not fully compatible with JSSG types - const requireStatements = getNodeRequireCalls(root, 'fs'); - - // Update require statements - for (const requireNode of requireStatements) { - let requireText = requireNode.text(); - let updated = false; - - if (usedTruncate && requireText.includes("truncate") && !requireText.includes("ftruncate")) { - // Replace truncate with ftruncate in requires - requireText = requireText.replace(/\btruncate\b/g, "ftruncate"); - updated = true; - } - - if (usedTruncateSync && requireText.includes("truncateSync") && !requireText.includes("ftruncateSync")) { - // Replace truncateSync with ftruncateSync in requires - requireText = requireText.replace(/\btruncateSync\b/g, "ftruncateSync"); - updated = true; - } + if (usedTruncateSync && text.includes("truncateSync") && !text.includes("ftruncateSync")) { + text = text.replace(/\btruncateSync\b/g, "ftruncateSync"); + updated = true; + } - if (updated) { - edits.push(requireNode.replace(requireText)); - hasChanges = true; - } + if (updated) { + edits.push(statement.replace(text)); } } +} - if (!hasChanges) return null; +/** + * Check if a call expression is from a destructured fs import/require + */ +function isFromFsModule(call: SgNode, root: SgRoot): boolean { + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const importStatements = getNodeImportStatements(root, 'fs'); + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const requireStatements = getNodeRequireCalls(root, 'fs'); + + // Get the function name being called (truncate or truncateSync) + const callExpression = call.child(0); + const functionName = callExpression?.text(); + if (!functionName) return false; + + // Check if this function name appears in any fs import/require destructuring + for (const statement of [...importStatements, ...requireStatements]) { + const text = statement.text(); + if (text.includes("{") && text.includes(functionName)) { + return true; + } + } - return rootNode.commitEdits(edits); + return false; } /** @@ -176,13 +182,16 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { // Check if it's a numeric literal if (/^\d+$/.test(param.trim())) return true; - // Check if parameter is in a callback context - if (isInCallbackContext(param, rootNode)) return true; + // Check if it's obviously a string literal (path) + if (/^['"`]/.test(param.trim())) return false; + + // Check if it's assigned from fs.openSync or openSync + if (isAssignedFromOpenSync(param, rootNode)) return true; - // Check if there's a variable in scope that assigns a file descriptor - if (hasFileDescriptorVariable(param, rootNode)) return true; + // Check if it's used inside a callback context from fs.open + if (isInCallbackContext(param, rootNode)) return true; - // If we didn't find any indicators, assume it's not a file descriptor + // For other cases, be conservative - don't transform unless we're sure return false; } @@ -201,386 +210,104 @@ function isInCallbackContext(param: string, rootNode: SgNode): boolean { }); for (const usage of parameterUsages) { - // Check if this usage is inside a callback parameter list for fs.open - const isInFsOpenCallback = usage.inside({ + // Check if this usage is inside a callback parameter for fs.open or open + const isInOpenCallback = usage.inside({ rule: { kind: "call_expression", - all: [ - { - has: { - field: "function", + has: { + field: "function", + any: [ + { kind: "member_expression", all: [ - { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } - }, - { - has: { - field: "property", - kind: "property_identifier", - regex: "^open$" - } - } + { has: { field: "object", kind: "identifier", regex: "^fs$" } }, + { has: { field: "property", kind: "property_identifier", regex: "^open$" } } ] - } - }, - { - has: { - field: "arguments", - kind: "arguments", - has: { - any: [ - { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - }, - { - kind: "function_expression", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - } - ] - } - } - } - ] - } - }); - - // Check if this usage is inside a callback parameter list for destructured open - const isInDestructuredOpenCallback = usage.inside({ - rule: { - kind: "call_expression", - all: [ - { - has: { - field: "function", + }, + { kind: "identifier", regex: "^open$" } - }, - { - has: { - field: "arguments", - kind: "arguments", - has: { - any: [ - { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - }, - { - kind: "function_expression", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - } - ] - } - } - } - ] + ] + } } }); - if (isInFsOpenCallback || isInDestructuredOpenCallback) { - return true; - } + if (isInOpenCallback) return true; } return false; } /** - * Check if there's a variable in scope that assigns a file descriptor value + * Check if there's a variable that's assigned from fs.openSync * @param param The parameter name to check * @param rootNode The root node of the AST */ -function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean { - // Find all usages of the parameter to understand the context - const parameterUsages = rootNode.findAll({ - rule: { - kind: "identifier", - regex: `^${param}$` - } - }); - - // For each usage, check if there's a variable declaration in scope - for (const usage of parameterUsages) { - // Check if this usage is in a truncate call context - const isInTruncateCall = usage.inside({ - rule: { - any: [ - { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, - { pattern: "fs.truncate($FD, $LEN)" }, - { pattern: "truncate($FD, $LEN, $CALLBACK)" }, - { pattern: "truncate($FD, $LEN)" }, - { pattern: "fs.truncateSync($FD, $LEN)" }, - { pattern: "truncateSync($FD, $LEN)" } - ] - } - }); - - if (!isInTruncateCall) continue; - - // Find the scope containing this usage - const scope = findContainingScope(usage); - if (!scope) continue; - - // Search for variable declarations within this scope - if (hasFileDescriptorVariableInScope(param, scope)) { - return true; - } - } - - return false; -} - -/** - * Find the containing scope (function, block, or program) for a given node - * @param node The node to find the scope for - */ -function findContainingScope(node: SgNode): SgNode | null { - let current = node.parent(); - - while (current) { - const kind = current.kind(); - // These are scope-creating nodes in JavaScript - if (kind === "program" || - kind === "function_declaration" || - kind === "function_expression" || - kind === "arrow_function" || - kind === "method_definition" || - kind === "statement_block") { - return current; - } - current = current.parent(); - } - - return null; -} - -/** - * Check if there's a file descriptor variable declaration within a specific scope - * @param param The parameter name to check - * @param scope The scope node to search within - */ -function hasFileDescriptorVariableInScope(param: string, scope: SgNode): boolean { - // Search for variable declarations that assign from fs.openSync within this scope - const syncVariableDeclarators = scope.findAll({ +function isAssignedFromOpenSync(param: string, rootNode: SgNode): boolean { + // Search for variable declarations or assignments from fs.openSync or openSync + const openSyncAssignments = rootNode.findAll({ rule: { - kind: "variable_declarator", - all: [ - { - has: { - field: "name", - kind: "identifier", - regex: `^${param}$` - } - }, + any: [ { - has: { - field: "value", - kind: "call_expression", - has: { - field: "function", - any: [ - { - kind: "member_expression", - all: [ + kind: "variable_declarator", + all: [ + { has: { field: "name", kind: "identifier", regex: `^${param}$` } }, + { + has: { + field: "value", + kind: "call_expression", + has: { + field: "function", + any: [ { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } + kind: "member_expression", + all: [ + { has: { field: "object", kind: "identifier", regex: "^fs$" } }, + { has: { field: "property", kind: "property_identifier", regex: "^openSync$" } } + ] }, { - has: { - field: "property", - kind: "property_identifier", - regex: "^openSync$" - } + kind: "identifier", + regex: "^openSync$" } ] - }, - { - kind: "identifier", - regex: "^openSync$" } - ] + } } - } - } - ] - } - }); - - if (syncVariableDeclarators.length > 0) return true; - - // Search for assignment expressions that assign from fs.openSync within this scope - const syncAssignments = scope.findAll({ - rule: { - kind: "assignment_expression", - all: [ - { - has: { - field: "left", - kind: "identifier", - regex: `^${param}$` - } + ] }, { - has: { - field: "right", - kind: "call_expression", - has: { - field: "function", - any: [ - { - kind: "member_expression", - all: [ + kind: "assignment_expression", + all: [ + { has: { field: "left", kind: "identifier", regex: `^${param}$` } }, + { + has: { + field: "right", + kind: "call_expression", + has: { + field: "function", + any: [ { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } + kind: "member_expression", + all: [ + { has: { field: "object", kind: "identifier", regex: "^fs$" } }, + { has: { field: "property", kind: "property_identifier", regex: "^openSync$" } } + ] }, { - has: { - field: "property", - kind: "property_identifier", - regex: "^openSync$" - } + kind: "identifier", + regex: "^openSync$" } ] - }, - { - kind: "identifier", - regex: "^openSync$" } - ] + } } - } - } - ] - } - }); - - if (syncAssignments.length > 0) return true; - - // Check if the variable is assigned from another variable that's a file descriptor within this scope - const variableAssignments = scope.findAll({ - rule: { - kind: "variable_declarator", - all: [ - { - has: { - field: "name", - kind: "identifier", - regex: `^${param}$` - } - }, - { - has: { - field: "value", - kind: "identifier" - } + ] } ] } }); - for (const assignment of variableAssignments) { - const valueNode = assignment.field("value"); - if (valueNode) { - const sourceVar = valueNode.text(); - // Recursively check if the source variable is a file descriptor within the same scope - if (hasFileDescriptorVariableInScope(sourceVar, scope)) { - return true; - } - } - } - - // If not found in current scope, check parent scopes (for closure/lexical scoping) - const parentScope = findParentScope(scope); - if (parentScope) { - return hasFileDescriptorVariableInScope(param, parentScope); - } - - return false; -} - -/** - * Find the parent scope of a given scope node - * @param scope The current scope node - */ -function findParentScope(scope: SgNode): SgNode | null { - let current = scope.parent(); - - while (current) { - const kind = current.kind(); - // These are scope-creating nodes in JavaScript - if (kind === "program" || - kind === "function_declaration" || - kind === "function_expression" || - kind === "arrow_function" || - kind === "method_definition" || - kind === "statement_block") { - return current; - } - current = current.parent(); - } - - return null; + return openSyncAssignments.length > 0; } diff --git a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs index 12399270..a05e4f02 100644 --- a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs +++ b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs @@ -17,7 +17,7 @@ fs.ftruncateSync(accesible, 10); fs.closeSync(accesible); function foo() { - ftruncateFile(unaccessible, 10); + truncateFile(unaccessible, 10); } function bar() { From ef62f5c672e02bbc662fa7803d29b77feaeba97d Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Tue, 29 Jul 2025 23:47:58 +0200 Subject: [PATCH 10/23] chore(`codemod.yaml`): use righ file ext + correct scope --- .../fs-truncate-fd-deprecation/{codemod.yml => codemod.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename recipes/fs-truncate-fd-deprecation/{codemod.yml => codemod.yaml} (89%) diff --git a/recipes/fs-truncate-fd-deprecation/codemod.yml b/recipes/fs-truncate-fd-deprecation/codemod.yaml similarity index 89% rename from recipes/fs-truncate-fd-deprecation/codemod.yml rename to recipes/fs-truncate-fd-deprecation/codemod.yaml index 0601a55a..faa33f85 100644 --- a/recipes/fs-truncate-fd-deprecation/codemod.yml +++ b/recipes/fs-truncate-fd-deprecation/codemod.yaml @@ -1,5 +1,5 @@ schema_version: "1.0" -name: nodejs/fs-truncate-fd-deprecation +name: "@nodejs/fs-truncate-fd-deprecation" version: 1.0.0 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy From b406468d75c296d7f07c46e7063aae4fec06aa43 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Wed, 13 Aug 2025 11:27:51 +0200 Subject: [PATCH 11/23] Update workflow.ts --- .../src/workflow.ts | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 2885bec1..f48e7aa8 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -179,20 +179,21 @@ function isFromFsModule(call: SgNode, root: SgRoot): boolean { * @param rootNode The root node of the AST to search within. */ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { - // Check if it's a numeric literal - if (/^\d+$/.test(param.trim())) return true; - - // Check if it's obviously a string literal (path) - if (/^['"`]/.test(param.trim())) return false; - - // Check if it's assigned from fs.openSync or openSync - if (isAssignedFromOpenSync(param, rootNode)) return true; - - // Check if it's used inside a callback context from fs.open - if (isInCallbackContext(param, rootNode)) return true; - - // For other cases, be conservative - don't transform unless we're sure - return false; + // Check if it's obviously a string literal (path) + if (/^['"`]/.test(param.trim())) return false; + + // Check if the parameter is likely a file descriptor: + // 1. It's a numeric literal (e.g., "123"). + // 2. It's assigned from fs.openSync or openSync. + // 3. It's used inside a callback context from fs.open. + if ( + /^\d+$/.test(param.trim()) || + isAssignedFromOpenSync(param, rootNode) || + isInCallbackContext(param, rootNode) + ) return true; + + // For other cases, be conservative - don't transform unless we're sure + return false; } /** From 062b3299c43a99bf389bb00a61aa9a6af556d1b7 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sat, 26 Jul 2025 15:55:07 +0200 Subject: [PATCH 12/23] scaffold codemod --- package-lock.json | 15 +++++++++ recipes/fs-truncate-fs-depreciation/README.md | 33 +++++++++++++++++++ .../fs-truncate-fs-depreciation/codemod.yml | 21 ++++++++++++ .../fs-truncate-fs-depreciation/package.json | 24 ++++++++++++++ .../src/workflow.ts | 15 +++++++++ .../tests/expected/file-1.js | 9 +++++ .../tests/expected/file-2.js | 8 +++++ .../tests/expected/file-3.js | 11 +++++++ .../tests/expected/file-4.mjs | 9 +++++ .../tests/expected/file-5.mjs | 9 +++++ .../tests/input/file-1.js | 9 +++++ .../tests/input/file-2.js | 8 +++++ .../tests/input/file-3.js | 11 +++++++ .../tests/input/file-4.mjs | 9 +++++ .../tests/input/file-5.mjs | 9 +++++ .../fs-truncate-fs-depreciation/workflow.yaml | 24 ++++++++++++++ 16 files changed, 224 insertions(+) create mode 100644 recipes/fs-truncate-fs-depreciation/README.md create mode 100644 recipes/fs-truncate-fs-depreciation/codemod.yml create mode 100644 recipes/fs-truncate-fs-depreciation/package.json create mode 100644 recipes/fs-truncate-fs-depreciation/src/workflow.ts create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-1.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-2.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-3.js create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs create mode 100644 recipes/fs-truncate-fs-depreciation/workflow.yaml diff --git a/package-lock.json b/package-lock.json index 221e6678..978ed385 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1420,6 +1420,10 @@ "resolved": "recipes/create-require-from-path", "link": true }, + "node_modules/@nodejs/fs-truncate-fs-depreciation": { + "resolved": "recipes/fs-truncate-fs-depreciation", + "link": true + }, "node_modules/@nodejs/import-assertions-to-attributes": { "resolved": "recipes/import-assertions-to-attributes", "link": true @@ -4072,6 +4076,17 @@ "@codemod.com/jssg-types": "^1.0.3" } }, + "recipes/fs-truncate-fs-depreciation": { + "name": "@nodejs/fs-truncate-fs-depreciation", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@nodejs/codemod-utils": "0.0.0" + }, + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.3" + } + }, "recipes/import-assertions-to-attributes": { "name": "@nodejs/import-assertions-to-attributes", "version": "1.0.0", diff --git a/recipes/fs-truncate-fs-depreciation/README.md b/recipes/fs-truncate-fs-depreciation/README.md new file mode 100644 index 00000000..1d25932c --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/README.md @@ -0,0 +1,33 @@ +# DEP0081: `fs.truncate()` using a file descriptor + +This recipe transforms the usage of `fs.truncate()` to `fs.ftruncateSync()` when a file descriptor is used. + +See [DEP0081](https://nodejs.org/api/deprecations.html#DEP0081). + +## Example + +**Before:** +```js +const { truncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + truncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => {}); + }); +}); +``` + +**After:** +```js +const { ftruncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + ftruncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => {}); + }); +}); +``` diff --git a/recipes/fs-truncate-fs-depreciation/codemod.yml b/recipes/fs-truncate-fs-depreciation/codemod.yml new file mode 100644 index 00000000..e8f7f9ae --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/codemod.yml @@ -0,0 +1,21 @@ +schema_version: "1.0" +name: nodejs/create-require-from-path +version: 0.0.1 +description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. +author: Augustin Mauroy +license: MIT +workflow: workflow.yaml +category: migration + +targets: + languages: + - javascript + - typescript + +keywords: + - transformation + - migration + +registry: + access: public + visibility: public diff --git a/recipes/fs-truncate-fs-depreciation/package.json b/recipes/fs-truncate-fs-depreciation/package.json new file mode 100644 index 00000000..f9a42bae --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/package.json @@ -0,0 +1,24 @@ +{ + "name": "@nodejs/fs-truncate-fs-depreciation", + "version": "0.0.1", + "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", + "type": "module", + "scripts": { + "test": "npx codemod@next jssg test -l typescript ./src/workflow.ts ./" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/nodejs/userland-migrations.git", + "directory": "recipes/fs-truncate-fs-depreciation", + "bugs": "https://github.com/nodejs/userland-migrations/issues" + }, + "author": "Augustin Mauroy", + "license": "MIT", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fs-depreciation/README.md", + "devDependencies": { + "@codemod.com/jssg-types": "^1.0.3" + }, + "dependencies": { + "@nodejs/codemod-utils": "0.0.0" + } +} diff --git a/recipes/fs-truncate-fs-depreciation/src/workflow.ts b/recipes/fs-truncate-fs-depreciation/src/workflow.ts new file mode 100644 index 00000000..a59e8ea5 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/src/workflow.ts @@ -0,0 +1,15 @@ +import type { SgRoot, Edit } from "@codemod.com/jssg-types/main"; + +/** + * + */ +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + let hasChanges = false; + + + if (!hasChanges) return null; + + return rootNode.commitEdits(edits); +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js b/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js new file mode 100644 index 00000000..75fa3ae3 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js @@ -0,0 +1,9 @@ +const { ftruncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + ftruncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js b/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js new file mode 100644 index 00000000..c363686d --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js @@ -0,0 +1,8 @@ +const fs = require('node:fs'); + +const fd = fs.openSync('file.txt', 'w'); +try { + fs.ftruncateSync(fd, 10); +} finally { + fs.closeSync(fd); +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js b/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js new file mode 100644 index 00000000..96a5f724 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js @@ -0,0 +1,11 @@ +const { truncate, ftruncateSync, open, openSync, close, closeSync } = require('node:fs'); + +// This should be replaced (file descriptor) +const fd = openSync('file.txt', 'w'); +ftruncateSync(fd, 10); +closeSync(fd); + +// This should NOT be replaced (file path) +truncate('other.txt', 5, (err) => { + if (err) throw err; +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs b/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs new file mode 100644 index 00000000..fbcdf61c --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs @@ -0,0 +1,9 @@ +import { ftruncate, open, close } from 'node:fs'; + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + ftruncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs b/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs new file mode 100644 index 00000000..04245b06 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs @@ -0,0 +1,9 @@ +import fs from 'node:fs'; + +fs.open('file.txt', 'w', (err, fd) => { + if (err) throw err; + fs.ftruncate(fd, 10, (err) => { + if (err) throw err; + fs.close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js b/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js new file mode 100644 index 00000000..db75880b --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js @@ -0,0 +1,9 @@ +const { truncate, open, close } = require('node:fs'); + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + truncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js b/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js new file mode 100644 index 00000000..aefa3344 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js @@ -0,0 +1,8 @@ +const fs = require('node:fs'); + +const fd = fs.openSync('file.txt', 'w'); +try { + fs.truncateSync(fd, 10); +} finally { + fs.closeSync(fd); +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js b/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js new file mode 100644 index 00000000..96a5f724 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js @@ -0,0 +1,11 @@ +const { truncate, ftruncateSync, open, openSync, close, closeSync } = require('node:fs'); + +// This should be replaced (file descriptor) +const fd = openSync('file.txt', 'w'); +ftruncateSync(fd, 10); +closeSync(fd); + +// This should NOT be replaced (file path) +truncate('other.txt', 5, (err) => { + if (err) throw err; +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs b/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs new file mode 100644 index 00000000..cc4dd98c --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs @@ -0,0 +1,9 @@ +import { truncate, open, close } from 'node:fs'; + +open('file.txt', 'w', (err, fd) => { + if (err) throw err; + truncate(fd, 10, (err) => { + if (err) throw err; + close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs b/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs new file mode 100644 index 00000000..78fed4b1 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs @@ -0,0 +1,9 @@ +import fs from 'node:fs'; + +fs.open('file.txt', 'w', (err, fd) => { + if (err) throw err; + fs.truncate(fd, 10, (err) => { + if (err) throw err; + fs.close(fd, () => { }); + }); +}); diff --git a/recipes/fs-truncate-fs-depreciation/workflow.yaml b/recipes/fs-truncate-fs-depreciation/workflow.yaml new file mode 100644 index 00000000..1bc57731 --- /dev/null +++ b/recipes/fs-truncate-fs-depreciation/workflow.yaml @@ -0,0 +1,24 @@ +version: "1" +nodes: + - id: apply-transforms + name: Apply AST Transformations + type: automatic + runtime: + type: direct + steps: + - name: Apply JS AST Grep transformations + js-ast-grep: + js_file: src/workflow.ts + base_path: . + include: + - "**/*.js" + - "**/*.jsx" + - "**/*.mjs" + - "**/*.cjs" + - "**/*.cts" + - "**/*.mts" + - "**/*.ts" + - "**/*.tsx" + exclude: + - "**/node_modules/**" + language: typescript From ac59325a77d356da79dc353139ab2eed77e1963c Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:05:51 +0200 Subject: [PATCH 13/23] add first draft --- package-lock.json | 8 +- .../README.md | 0 .../codemod.yml | 2 +- .../package.json | 6 +- .../src/workflow.ts | 203 ++++++++++++++++++ .../tests/expected/file-1.js | 0 .../tests/expected/file-2.js | 0 .../tests/expected/file-3.js | 0 .../tests/expected/file-4.mjs | 0 .../tests/expected/file-5.mjs | 0 .../tests/input/file-1.js | 0 .../tests/input/file-2.js | 0 .../tests/input/file-3.js | 0 .../tests/input/file-4.mjs | 0 .../tests/input/file-5.mjs | 0 .../workflow.yaml | 0 .../src/workflow.ts | 15 -- 17 files changed, 211 insertions(+), 23 deletions(-) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/README.md (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/codemod.yml (90%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/package.json (80%) create mode 100644 recipes/fs-truncate-fd-depreciation/src/workflow.ts rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-1.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-2.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-3.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-4.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/expected/file-5.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-1.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-2.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-3.js (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-4.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/tests/input/file-5.mjs (100%) rename recipes/{fs-truncate-fs-depreciation => fs-truncate-fd-depreciation}/workflow.yaml (100%) delete mode 100644 recipes/fs-truncate-fs-depreciation/src/workflow.ts diff --git a/package-lock.json b/package-lock.json index 978ed385..5da18da6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1420,8 +1420,8 @@ "resolved": "recipes/create-require-from-path", "link": true }, - "node_modules/@nodejs/fs-truncate-fs-depreciation": { - "resolved": "recipes/fs-truncate-fs-depreciation", + "node_modules/@nodejs/fs-truncate-fd-depreciation": { + "resolved": "recipes/fs-truncate-fd-depreciation", "link": true }, "node_modules/@nodejs/import-assertions-to-attributes": { @@ -4076,8 +4076,8 @@ "@codemod.com/jssg-types": "^1.0.3" } }, - "recipes/fs-truncate-fs-depreciation": { - "name": "@nodejs/fs-truncate-fs-depreciation", + "recipes/fs-truncate-fd-depreciation": { + "name": "@nodejs/fs-truncate-fd-depreciation", "version": "0.0.1", "license": "MIT", "dependencies": { diff --git a/recipes/fs-truncate-fs-depreciation/README.md b/recipes/fs-truncate-fd-depreciation/README.md similarity index 100% rename from recipes/fs-truncate-fs-depreciation/README.md rename to recipes/fs-truncate-fd-depreciation/README.md diff --git a/recipes/fs-truncate-fs-depreciation/codemod.yml b/recipes/fs-truncate-fd-depreciation/codemod.yml similarity index 90% rename from recipes/fs-truncate-fs-depreciation/codemod.yml rename to recipes/fs-truncate-fd-depreciation/codemod.yml index e8f7f9ae..e8e87a5b 100644 --- a/recipes/fs-truncate-fs-depreciation/codemod.yml +++ b/recipes/fs-truncate-fd-depreciation/codemod.yml @@ -1,5 +1,5 @@ schema_version: "1.0" -name: nodejs/create-require-from-path +name: nodejs/fs-truncate-fd-depreciation version: 0.0.1 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy diff --git a/recipes/fs-truncate-fs-depreciation/package.json b/recipes/fs-truncate-fd-depreciation/package.json similarity index 80% rename from recipes/fs-truncate-fs-depreciation/package.json rename to recipes/fs-truncate-fd-depreciation/package.json index f9a42bae..bf988930 100644 --- a/recipes/fs-truncate-fs-depreciation/package.json +++ b/recipes/fs-truncate-fd-depreciation/package.json @@ -1,5 +1,5 @@ { - "name": "@nodejs/fs-truncate-fs-depreciation", + "name": "@nodejs/fs-truncate-fd-depreciation", "version": "0.0.1", "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", "type": "module", @@ -9,12 +9,12 @@ "repository": { "type": "git", "url": "git+https://github.com/nodejs/userland-migrations.git", - "directory": "recipes/fs-truncate-fs-depreciation", + "directory": "recipes/fs-truncate-fd-depreciation", "bugs": "https://github.com/nodejs/userland-migrations/issues" }, "author": "Augustin Mauroy", "license": "MIT", - "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fs-depreciation/README.md", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fd-depreciation/README.md", "devDependencies": { "@codemod.com/jssg-types": "^1.0.3" }, diff --git a/recipes/fs-truncate-fd-depreciation/src/workflow.ts b/recipes/fs-truncate-fd-depreciation/src/workflow.ts new file mode 100644 index 00000000..2780851d --- /dev/null +++ b/recipes/fs-truncate-fd-depreciation/src/workflow.ts @@ -0,0 +1,203 @@ +import { getNodeImportStatements } from "@nodejs/codemod-utils/ast-grep/import-statement"; +import { getNodeRequireCalls } from "@nodejs/codemod-utils/ast-grep/require-call"; +import type { SgRoot, Edit, SgNode } from "@codemod.com/jssg-types/main"; +import type Js from "@codemod.com/jssg-types/langs/javascript"; + +/** + * Transform function that converts deprecated fs.truncate calls to fs.ftruncate. + * + * See DEP0081: https://nodejs.org/api/deprecations.html#DEP0081 + * + * Handles: + * 1. fs.truncate(fd, len, callback) -> fs.ftruncate(fd, len, callback) + * 2. fs.truncateSync(fd, len) -> fs.ftruncateSync(fd, len) + * 3. truncate(fd, len, callback) -> ftruncate(fd, len, callback) (destructured imports) + * 4. truncateSync(fd, len) -> ftruncateSync(fd, len) (destructured imports) + * 5. Import/require statement updates to replace truncate/truncateSync with ftruncate/ftruncateSync + */ +export default function transform(root: SgRoot): string | null { + const rootNode = root.root(); + const edits: Edit[] = []; + let hasChanges = false; + + // Track what imports need to be updated + let usedTruncate = false; + let usedTruncateSync = false; + + // Find all truncate and truncateSync calls + const truncateCalls = rootNode.findAll({ + rule: { + any: [ + { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "fs.truncate($FD, $LEN)" }, + { pattern: "truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "truncate($FD, $LEN)" } + ] + } + }); + + const truncateSyncCalls = rootNode.findAll({ + rule: { + any: [ + { pattern: "fs.truncateSync($FD, $LEN)" }, + { pattern: "truncateSync($FD, $LEN)" } + ] + } + }); + + // Transform truncate calls + for (const call of truncateCalls) { + const fdMatch = call.getMatch("FD"); + const lenMatch = call.getMatch("LEN"); + const callbackMatch = call.getMatch("CALLBACK"); + + if (!fdMatch || !lenMatch) continue; + + const fd = fdMatch.text(); + const len = lenMatch.text(); + const callback = callbackMatch?.text(); + const callText = call.text(); + + // Check if this looks like a file descriptor (numeric or variable from open) + if (isLikelyFileDescriptor(fd, rootNode)) { + if (callText.includes("fs.truncate(")) { + const newCallText = callback + ? `fs.ftruncate(${fd}, ${len}, ${callback})` + : `fs.ftruncate(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + } else { + // destructured call like truncate(...) + const newCallText = callback + ? `ftruncate(${fd}, ${len}, ${callback})` + : `ftruncate(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + usedTruncate = true; + } + hasChanges = true; + } + } + + // Transform truncateSync calls + for (const call of truncateSyncCalls) { + const fdMatch = call.getMatch("FD"); + const lenMatch = call.getMatch("LEN"); + + if (!fdMatch || !lenMatch) continue; + + const fd = fdMatch.text(); + const len = lenMatch.text(); + const callText = call.text(); + + // Check if this looks like a file descriptor + if (isLikelyFileDescriptor(fd, rootNode)) { + if (callText.includes("fs.truncateSync(")) { + const newCallText = `fs.ftruncateSync(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + } else { + // destructured call like truncateSync(...) + const newCallText = `ftruncateSync(${fd}, ${len})`; + edits.push(call.replace(newCallText)); + usedTruncateSync = true; + } + hasChanges = true; + } + } + + // Update imports/requires if we have destructured calls that were transformed + if (usedTruncate || usedTruncateSync) { + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const importStatements = getNodeImportStatements(root, 'fs'); + + // Update import statements + for (const importNode of importStatements) { + const namedImports = importNode.find({ rule: { kind: 'named_imports' } }); + if (!namedImports) continue; + + let importText = importNode.text(); + let updated = false; + + if (usedTruncate && importText.includes("truncate") && !importText.includes("ftruncate")) { + // Replace truncate with ftruncate in imports + importText = importText.replace(/\btruncate\b/g, "ftruncate"); + updated = true; + } + + if (usedTruncateSync && importText.includes("truncateSync") && !importText.includes("ftruncateSync")) { + // Replace truncateSync with ftruncateSync in imports + importText = importText.replace(/\btruncateSync\b/g, "ftruncateSync"); + updated = true; + } + + if (updated) { + edits.push(importNode.replace(importText)); + hasChanges = true; + } + } + + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const requireStatements = getNodeRequireCalls(root, 'fs'); + + // Update require statements + for (const requireNode of requireStatements) { + let requireText = requireNode.text(); + let updated = false; + + if (usedTruncate && requireText.includes("truncate") && !requireText.includes("ftruncate")) { + // Replace truncate with ftruncate in requires + requireText = requireText.replace(/\btruncate\b/g, "ftruncate"); + updated = true; + } + + if (usedTruncateSync && requireText.includes("truncateSync") && !requireText.includes("ftruncateSync")) { + // Replace truncateSync with ftruncateSync in requires + requireText = requireText.replace(/\btruncateSync\b/g, "ftruncateSync"); + updated = true; + } + + if (updated) { + edits.push(requireNode.replace(requireText)); + hasChanges = true; + } + } + } + + if (!hasChanges) return null; + + return rootNode.commitEdits(edits); +} + +/** + * Helper function to determine if a parameter is likely a file descriptor + * rather than a file path string. + * @todo(@AugustinMauroy): use more AST than regex for this function. + * @param param The parameter to check (e.g., 'fd'). + * @param rootNode The root node of the AST to search within. + */ +function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { + // Check if it's a numeric literal + if (/^\d+$/.test(param.trim())) return true; + + // Simple check: if the parameter appears in an `openSync` assignment, it's likely a file descriptor + const sourceText = rootNode.text(); + + // Look for patterns like "const fd = openSync(...)" or "const fd = fs.openSync(...)" + const openSyncPattern = new RegExp(`(?:const|let|var)\\s+${param}\\s*=\\s*(?:fs\\.)?openSync\\s*\\(`, 'g'); + + if (openSyncPattern.test(sourceText)) return true; + + // Look for patterns where the parameter is used in an open callback + // This handles cases like: open('file', (err, fd) => { truncate(fd, ...) }) + const callbackPattern = new RegExp(`\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)\\s*=>`, 'g'); + + if (callbackPattern.test(sourceText)) return true; + + + // Look for function callback patterns + const functionCallbackPattern = new RegExp(`function\\s*\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)`, 'g'); + + if (functionCallbackPattern.test(sourceText)) return true; + + // Conservative approach: if we can't determine it's a file descriptor, + // assume it's a file path to avoid breaking valid path-based truncate calls + return false; +} diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js b/recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-1.js rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js b/recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-2.js rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js b/recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-3.js rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs b/recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-4.mjs rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs diff --git a/recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs b/recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/expected/file-5.mjs rename to recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-1.js b/recipes/fs-truncate-fd-depreciation/tests/input/file-1.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-1.js rename to recipes/fs-truncate-fd-depreciation/tests/input/file-1.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-2.js b/recipes/fs-truncate-fd-depreciation/tests/input/file-2.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-2.js rename to recipes/fs-truncate-fd-depreciation/tests/input/file-2.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-3.js b/recipes/fs-truncate-fd-depreciation/tests/input/file-3.js similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-3.js rename to recipes/fs-truncate-fd-depreciation/tests/input/file-3.js diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs b/recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-4.mjs rename to recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs diff --git a/recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs b/recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fs-depreciation/tests/input/file-5.mjs rename to recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs diff --git a/recipes/fs-truncate-fs-depreciation/workflow.yaml b/recipes/fs-truncate-fd-depreciation/workflow.yaml similarity index 100% rename from recipes/fs-truncate-fs-depreciation/workflow.yaml rename to recipes/fs-truncate-fd-depreciation/workflow.yaml diff --git a/recipes/fs-truncate-fs-depreciation/src/workflow.ts b/recipes/fs-truncate-fs-depreciation/src/workflow.ts deleted file mode 100644 index a59e8ea5..00000000 --- a/recipes/fs-truncate-fs-depreciation/src/workflow.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { SgRoot, Edit } from "@codemod.com/jssg-types/main"; - -/** - * - */ -export default function transform(root: SgRoot): string | null { - const rootNode = root.root(); - const edits: Edit[] = []; - let hasChanges = false; - - - if (!hasChanges) return null; - - return rootNode.commitEdits(edits); -} From 83c0cf8581cab6096db7392d4fca9370938ab556 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 17:00:11 +0200 Subject: [PATCH 14/23] fix: typo Co-Authored-By: Aviv Keller --- package-lock.json | 8 ++++---- .../README.md | 0 .../codemod.yml | 2 +- .../package.json | 6 +++--- .../src/workflow.ts | 0 .../tests/expected/file-1.js | 0 .../tests/expected/file-2.js | 0 .../tests/expected/file-3.js | 0 .../tests/expected/file-4.mjs | 0 .../tests/expected/file-5.mjs | 0 .../tests/input/file-1.js | 0 .../tests/input/file-2.js | 0 .../tests/input/file-3.js | 0 .../tests/input/file-4.mjs | 0 .../tests/input/file-5.mjs | 0 .../workflow.yaml | 0 16 files changed, 8 insertions(+), 8 deletions(-) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/README.md (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/codemod.yml (90%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/package.json (80%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/src/workflow.ts (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-1.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-2.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-3.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-4.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/expected/file-5.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-1.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-2.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-3.js (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-4.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/tests/input/file-5.mjs (100%) rename recipes/{fs-truncate-fd-depreciation => fs-truncate-fd-deprecation}/workflow.yaml (100%) diff --git a/package-lock.json b/package-lock.json index 5da18da6..aacfc507 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1420,8 +1420,8 @@ "resolved": "recipes/create-require-from-path", "link": true }, - "node_modules/@nodejs/fs-truncate-fd-depreciation": { - "resolved": "recipes/fs-truncate-fd-depreciation", + "node_modules/@nodejs/fs-truncate-fd-deprecation": { + "resolved": "recipes/fs-truncate-fd-deprecation", "link": true }, "node_modules/@nodejs/import-assertions-to-attributes": { @@ -4076,8 +4076,8 @@ "@codemod.com/jssg-types": "^1.0.3" } }, - "recipes/fs-truncate-fd-depreciation": { - "name": "@nodejs/fs-truncate-fd-depreciation", + "recipes/fs-truncate-fd-deprecation": { + "name": "@nodejs/fs-truncate-fd-deprecation", "version": "0.0.1", "license": "MIT", "dependencies": { diff --git a/recipes/fs-truncate-fd-depreciation/README.md b/recipes/fs-truncate-fd-deprecation/README.md similarity index 100% rename from recipes/fs-truncate-fd-depreciation/README.md rename to recipes/fs-truncate-fd-deprecation/README.md diff --git a/recipes/fs-truncate-fd-depreciation/codemod.yml b/recipes/fs-truncate-fd-deprecation/codemod.yml similarity index 90% rename from recipes/fs-truncate-fd-depreciation/codemod.yml rename to recipes/fs-truncate-fd-deprecation/codemod.yml index e8e87a5b..391bde96 100644 --- a/recipes/fs-truncate-fd-depreciation/codemod.yml +++ b/recipes/fs-truncate-fd-deprecation/codemod.yml @@ -1,5 +1,5 @@ schema_version: "1.0" -name: nodejs/fs-truncate-fd-depreciation +name: nodejs/fs-truncate-fd-deprecation version: 0.0.1 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy diff --git a/recipes/fs-truncate-fd-depreciation/package.json b/recipes/fs-truncate-fd-deprecation/package.json similarity index 80% rename from recipes/fs-truncate-fd-depreciation/package.json rename to recipes/fs-truncate-fd-deprecation/package.json index bf988930..8a92d26c 100644 --- a/recipes/fs-truncate-fd-depreciation/package.json +++ b/recipes/fs-truncate-fd-deprecation/package.json @@ -1,5 +1,5 @@ { - "name": "@nodejs/fs-truncate-fd-depreciation", + "name": "@nodejs/fs-truncate-fd-deprecation", "version": "0.0.1", "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", "type": "module", @@ -9,12 +9,12 @@ "repository": { "type": "git", "url": "git+https://github.com/nodejs/userland-migrations.git", - "directory": "recipes/fs-truncate-fd-depreciation", + "directory": "recipes/fs-truncate-fd-deprecation", "bugs": "https://github.com/nodejs/userland-migrations/issues" }, "author": "Augustin Mauroy", "license": "MIT", - "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fd-depreciation/README.md", + "homepage": "https://github.com/nodejs/userland-migrations/blob/main/recipes/fs-truncate-fd-deprecation/README.md", "devDependencies": { "@codemod.com/jssg-types": "^1.0.3" }, diff --git a/recipes/fs-truncate-fd-depreciation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts similarity index 100% rename from recipes/fs-truncate-fd-depreciation/src/workflow.ts rename to recipes/fs-truncate-fd-deprecation/src/workflow.ts diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js b/recipes/fs-truncate-fd-deprecation/tests/expected/file-1.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-1.js rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-1.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js b/recipes/fs-truncate-fd-deprecation/tests/expected/file-2.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-2.js rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-2.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js b/recipes/fs-truncate-fd-deprecation/tests/expected/file-3.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-3.js rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-3.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-4.mjs rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-4.mjs diff --git a/recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/expected/file-5.mjs rename to recipes/fs-truncate-fd-deprecation/tests/expected/file-5.mjs diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-1.js b/recipes/fs-truncate-fd-deprecation/tests/input/file-1.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-1.js rename to recipes/fs-truncate-fd-deprecation/tests/input/file-1.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-2.js b/recipes/fs-truncate-fd-deprecation/tests/input/file-2.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-2.js rename to recipes/fs-truncate-fd-deprecation/tests/input/file-2.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-3.js b/recipes/fs-truncate-fd-deprecation/tests/input/file-3.js similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-3.js rename to recipes/fs-truncate-fd-deprecation/tests/input/file-3.js diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs b/recipes/fs-truncate-fd-deprecation/tests/input/file-4.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-4.mjs rename to recipes/fs-truncate-fd-deprecation/tests/input/file-4.mjs diff --git a/recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs b/recipes/fs-truncate-fd-deprecation/tests/input/file-5.mjs similarity index 100% rename from recipes/fs-truncate-fd-depreciation/tests/input/file-5.mjs rename to recipes/fs-truncate-fd-deprecation/tests/input/file-5.mjs diff --git a/recipes/fs-truncate-fd-depreciation/workflow.yaml b/recipes/fs-truncate-fd-deprecation/workflow.yaml similarity index 100% rename from recipes/fs-truncate-fd-depreciation/workflow.yaml rename to recipes/fs-truncate-fd-deprecation/workflow.yaml From 7d4665c9bdb2e62ffb43ad28f9521ccedcbb781d Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 18:42:51 +0200 Subject: [PATCH 15/23] refracto to use AST --- .../src/workflow.ts | 153 ++++++++++++++++-- 1 file changed, 136 insertions(+), 17 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 2780851d..4e04ab4d 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -169,7 +169,6 @@ export default function transform(root: SgRoot): string | null { /** * Helper function to determine if a parameter is likely a file descriptor * rather than a file path string. - * @todo(@AugustinMauroy): use more AST than regex for this function. * @param param The parameter to check (e.g., 'fd'). * @param rootNode The root node of the AST to search within. */ @@ -177,27 +176,147 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { // Check if it's a numeric literal if (/^\d+$/.test(param.trim())) return true; - // Simple check: if the parameter appears in an `openSync` assignment, it's likely a file descriptor - const sourceText = rootNode.text(); - - // Look for patterns like "const fd = openSync(...)" or "const fd = fs.openSync(...)" - const openSyncPattern = new RegExp(`(?:const|let|var)\\s+${param}\\s*=\\s*(?:fs\\.)?openSync\\s*\\(`, 'g'); - - if (openSyncPattern.test(sourceText)) return true; + // Search for variable declarations that might assign a file descriptor + // such as `const fd = fs.openSync(...)` or `open(..., (err, fd) => ...)` + const variableDeclarators = rootNode.findAll({ + rule: { + kind: "variable_declarator", + all: [ + { + has: { + field: "name", + kind: "identifier", + regex: `^${param}$` + } + }, + { + has: { + field: "value", + kind: "call_expression", + has: { + field: "function", + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^(open|openSync)$" + } + } + ] + } + } + } + ] + } + }); - // Look for patterns where the parameter is used in an open callback - // This handles cases like: open('file', (err, fd) => { truncate(fd, ...) }) - const callbackPattern = new RegExp(`\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)\\s*=>`, 'g'); + if (variableDeclarators.length > 0) return true; - if (callbackPattern.test(sourceText)) return true; + // Check if the parameter appears as a callback parameter in fs.open calls + // Pattern: open(..., (err, fd) => ...) + const callbackParameters = rootNode.findAll({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "identifier", + regex: "^open$" + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - idk what happend here maybe a bug in infering `Js` type + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + } + } + ] + } + }); + if (callbackParameters.length > 0) return true; - // Look for function callback patterns - const functionCallbackPattern = new RegExp(`function\\s*\\(\\s*(?:err|error)\\s*,\\s*${param}\\s*\\)`, 'g'); + // Check for fs.open callback patterns as well + const fsOpenCallbacks = rootNode.findAll({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^open$" + } + } + ] + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - idk what happend here maybe a bug in infering `Js` type + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + } + } + ] + } + }); - if (functionCallbackPattern.test(sourceText)) return true; + if (fsOpenCallbacks.length > 0) return true; - // Conservative approach: if we can't determine it's a file descriptor, - // assume it's a file path to avoid breaking valid path-based truncate calls + // If we didn't find any indicators, assume it's not a file descriptor return false; } From f4250a11d2098ff6f7bc391bf64509a71694c571 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 20:09:45 +0200 Subject: [PATCH 16/23] refracto --- .../src/workflow.ts | 323 +++++++++++++----- 1 file changed, 244 insertions(+), 79 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 4e04ab4d..c6284f7b 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -176,9 +176,178 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { // Check if it's a numeric literal if (/^\d+$/.test(param.trim())) return true; - // Search for variable declarations that might assign a file descriptor - // such as `const fd = fs.openSync(...)` or `open(..., (err, fd) => ...)` - const variableDeclarators = rootNode.findAll({ + // Check if parameter is in a callback context + if (isInCallbackContext(param, rootNode)) return true; + + // Check if there's a variable in scope that assigns a file descriptor + if (hasFileDescriptorVariable(param, rootNode)) return true; + + // If we didn't find any indicators, assume it's not a file descriptor + return false; +} + +/** + * Check if the parameter is used inside a callback context from fs.open + * @param param The parameter name to check + * @param rootNode The root node of the AST + */ +function isInCallbackContext(param: string, rootNode: SgNode): boolean { + // Find all uses of the parameter + const parameterUsages = rootNode.findAll({ + rule: { + kind: "identifier", + regex: `^${param}$` + } + }); + + for (const usage of parameterUsages) { + // Check if this usage is inside a callback parameter list for fs.open + const isInFsOpenCallback = usage.inside({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^open$" + } + } + ] + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + any: [ + { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + }, + { + kind: "function_expression", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + ] + } + } + } + ] + } + }); + + // Check if this usage is inside a callback parameter list for destructured open + const isInDestructuredOpenCallback = usage.inside({ + rule: { + kind: "call_expression", + all: [ + { + has: { + field: "function", + kind: "identifier", + regex: "^open$" + } + }, + { + has: { + field: "arguments", + kind: "arguments", + has: { + any: [ + { + kind: "arrow_function", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + }, + { + kind: "function_expression", + has: { + field: "parameters", + kind: "formal_parameters", + has: { + // @ts-ignore - jssg-types arren't happy but jssg work with type_error + kind: "required_parameter", + has: { + field: "pattern", + kind: "identifier", + regex: `^${param}$` + } + } + } + } + ] + } + } + } + ] + } + }); + + if (isInFsOpenCallback || isInDestructuredOpenCallback) { + return true; + } + } + + return false; +} + +/** + * Check if there's a variable in scope that assigns a file descriptor value + * @param param The parameter name to check + * @param rootNode The root node of the AST + */ +function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean { + // Search for variable declarations that assign from fs.openSync + const syncVariableDeclarators = rootNode.findAll({ rule: { kind: "variable_declarator", all: [ @@ -195,21 +364,29 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { kind: "call_expression", has: { field: "function", - kind: "member_expression", - all: [ + any: [ { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^openSync$" + } + } + ] }, { - has: { - field: "property", - kind: "property_identifier", - regex: "^(open|openSync)$" - } + kind: "identifier", + regex: "^openSync$" } ] } @@ -219,40 +396,51 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { } }); - if (variableDeclarators.length > 0) return true; + if (syncVariableDeclarators.length > 0) return true; - // Check if the parameter appears as a callback parameter in fs.open calls - // Pattern: open(..., (err, fd) => ...) - const callbackParameters = rootNode.findAll({ + // Search for assignment expressions that assign from fs.openSync + const syncAssignments = rootNode.findAll({ rule: { - kind: "call_expression", + kind: "assignment_expression", all: [ { has: { - field: "function", + field: "left", kind: "identifier", - regex: "^open$" + regex: `^${param}$` } }, { has: { - field: "arguments", - kind: "arguments", + field: "right", + kind: "call_expression", has: { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - idk what happend here maybe a bug in infering `Js` type - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } + field: "function", + any: [ + { + kind: "member_expression", + all: [ + { + has: { + field: "object", + kind: "identifier", + regex: "^fs$" + } + }, + { + has: { + field: "property", + kind: "property_identifier", + regex: "^openSync$" + } + } + ] + }, + { + kind: "identifier", + regex: "^openSync$" } - } + ] } } } @@ -260,63 +448,40 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { } }); - if (callbackParameters.length > 0) return true; + if (syncAssignments.length > 0) return true; - // Check for fs.open callback patterns as well - const fsOpenCallbacks = rootNode.findAll({ + // Check if the variable is assigned from another variable that's a file descriptor + const variableAssignments = rootNode.findAll({ rule: { - kind: "call_expression", + kind: "variable_declarator", all: [ { has: { - field: "function", - kind: "member_expression", - all: [ - { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } - }, - { - has: { - field: "property", - kind: "property_identifier", - regex: "^open$" - } - } - ] + field: "name", + kind: "identifier", + regex: `^${param}$` } }, { has: { - field: "arguments", - kind: "arguments", - has: { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - idk what happend here maybe a bug in infering `Js` type - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - } + field: "value", + kind: "identifier" } } ] } }); - if (fsOpenCallbacks.length > 0) return true; + for (const assignment of variableAssignments) { + const valueNode = assignment.field("value"); + if (valueNode) { + const sourceVar = valueNode.text(); + // Recursively check if the source variable is a file descriptor + if (hasFileDescriptorVariable(sourceVar, rootNode)) { + return true; + } + } + } - // If we didn't find any indicators, assume it's not a file descriptor return false; } From 8a7741e42acb0d075312acecb332dc692cd57c79 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 20:29:36 +0200 Subject: [PATCH 17/23] WARNING: edge-case --- recipes/fs-truncate-fd-deprecation/README.md | 5 ++++ .../tests/expected/edge-case.mjs | 25 +++++++++++++++++++ .../tests/input/edge-case.mjs | 25 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs create mode 100644 recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs diff --git a/recipes/fs-truncate-fd-deprecation/README.md b/recipes/fs-truncate-fd-deprecation/README.md index 1d25932c..666622c7 100644 --- a/recipes/fs-truncate-fd-deprecation/README.md +++ b/recipes/fs-truncate-fd-deprecation/README.md @@ -31,3 +31,8 @@ open('file.txt', 'w', (err, fd) => { }); }); ``` + +## Caveats + +When using `const fd = fs.openSync('file.txt', 'w');`, the codemod don't care about scope and will always transform `fs.truncate(fd, 10)` to `fs.ftruncateSync(fd, 10)`. So if you have mutiple variables with the same name, you should be careful with the transformation. + diff --git a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs new file mode 100644 index 00000000..a05e4f02 --- /dev/null +++ b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs @@ -0,0 +1,25 @@ +import fs from 'node:fs'; + +export default function truncateFile() { + fs.open('file.txt', 'w', (err, strangeName) => { + if (err) throw err; + fs.ftruncate(strangeName, 10, (err) => { + if (err) throw err; + fs.close(strangeName, () => { }); + }); + }); +} + +const accesible = fs.openSync('file.txt', 'w'); + +fs.ftruncateSync(accesible, 10); + +fs.closeSync(accesible); + +function foo() { + truncateFile(unaccessible, 10); +} + +function bar() { + const unaccessible = fs.openSync('file.txt', 'w'); +} diff --git a/recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs new file mode 100644 index 00000000..f9214366 --- /dev/null +++ b/recipes/fs-truncate-fd-deprecation/tests/input/edge-case.mjs @@ -0,0 +1,25 @@ +import fs from 'node:fs'; + +export default function truncateFile() { + fs.open('file.txt', 'w', (err, strangeName) => { + if (err) throw err; + fs.truncate(strangeName, 10, (err) => { + if (err) throw err; + fs.close(strangeName, () => { }); + }); + }); +} + +const accesible = fs.openSync('file.txt', 'w'); + +fs.truncateSync(accesible, 10); + +fs.closeSync(accesible); + +function foo() { + truncateFile(unaccessible, 10); +} + +function bar() { + const unaccessible = fs.openSync('file.txt', 'w'); +} From 2441b8e7d7f25998d752238df3c38f6ba0d300d2 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Sun, 27 Jul 2025 22:15:30 +0200 Subject: [PATCH 18/23] WIP --- package-lock.json | 1070 +---------------- .../src/workflow.ts | 115 +- .../tests/expected/edge-case.mjs | 2 +- 3 files changed, 111 insertions(+), 1076 deletions(-) diff --git a/package-lock.json b/package-lock.json index aacfc507..041ad18d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,6 @@ }, "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", @@ -33,8 +31,6 @@ }, "node_modules/@ast-grep/cli": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli/-/cli-0.25.7.tgz", - "integrity": "sha512-vklcPRFHPHkwHq05nb2Fuaj4BYNWxhr8GIdB6la090jWob9FdbM/Jz86vlQp2tRELb2rKzuHeksG8qDrbX4REg==", "hasInstallScript": true, "dependencies": { "detect-libc": "2.0.3" @@ -58,8 +54,6 @@ }, "node_modules/@ast-grep/cli-darwin-arm64": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli-darwin-arm64/-/cli-darwin-arm64-0.25.7.tgz", - "integrity": "sha512-dkj8hy32mWuQwCJUEpnKwTS8tLE+e7dhvu6is+v5Q6AumOVlcL6PJWQsyaA4vedDm6XOGK9+WnyFpCnV3b5ouA==", "cpu": [ "arm64" ], @@ -72,106 +66,8 @@ "node": ">= 10" } }, - "node_modules/@ast-grep/cli-darwin-x64": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli-darwin-x64/-/cli-darwin-x64-0.25.7.tgz", - "integrity": "sha512-FBdv7GH3llH5LI0S2yeqgQM5QEUHeoYMhw1pv+C439UeL5BBFFjI+LYVALciwsYzuq/DQDTnT2cM0JhYGajDLQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/cli-linux-arm64-gnu": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-0.25.7.tgz", - "integrity": "sha512-lsE+cSe4rFO8rvLhMM7PM3T83LlmV60H9dOH+1hq8thkWhLCL6vAJijEVWgAQDDvvZf3xnNVgG2GG4jOMfTuTQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/cli-linux-x64-gnu": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli-linux-x64-gnu/-/cli-linux-x64-gnu-0.25.7.tgz", - "integrity": "sha512-uuF5GXgeUZtBrftJJYuQU7PvDT7Q9fJkKKwpIscEfQqLndri1tdYzzT9jKj2taWFlhiCVqLaDEHsdfTeWaVjZQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/cli-win32-arm64-msvc": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-0.25.7.tgz", - "integrity": "sha512-GSWRjOnWybzNP5rnvPb6lQ7lSPoEIl64gk4uHE1h+a2nnFhT9REWTKFcmNB2aG8VmKEz1gu0pxpg9HmBe2OUBA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/cli-win32-ia32-msvc": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-0.25.7.tgz", - "integrity": "sha512-5p9PWbTeXaivQYixB+JkkpFKgY7G1Tm6R46Dhq6cHvKksiQ6lWlTOOmhl0QARtY7y3XP0MWuvjDEWCYrvYtO4A==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/cli-win32-x64-msvc": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/cli-win32-x64-msvc/-/cli-win32-x64-msvc-0.25.7.tgz", - "integrity": "sha512-WjsRuyKTCeGWpMhvobzU/6HaWbseENPl5mNMZIKs8gsCpkUyTUfvV8/A2W29oHCgbDWRtixYppWtd87Qjpm6cg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@ast-grep/napi": { "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.39.3.tgz", - "integrity": "sha512-Y+16O9AbeR+yr5qnVpXHXHv/3EG2IPGCIbvxYo4MZpFSAmUBYibiLP0GljK5TWkQz6y4u5eHso3F13evyww4rw==", "dev": true, "license": "MIT", "engines": { @@ -191,8 +87,6 @@ }, "node_modules/@ast-grep/napi-darwin-arm64": { "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.39.3.tgz", - "integrity": "sha512-XfTqyDOOyYzAJo0ZOLowrWKnwIB2q6PpFJG1EZFWLkMB54nHub+XDseLxA33uy3O4TpereMaJwUYBDFmOlDqtg==", "cpu": [ "arm64" ], @@ -206,146 +100,8 @@ "node": ">= 10" } }, - "node_modules/@ast-grep/napi-darwin-x64": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.39.3.tgz", - "integrity": "sha512-uncDaz0wJWPHRSB76cllFzVVqJJoN2KisbJKvoBoX7yTCtQtOloWpLf+V+RM7KLzk9sruhDZeWqV2929MgUGTw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/napi-linux-arm64-gnu": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.39.3.tgz", - "integrity": "sha512-ciNe9s54JUtttFtsdkBmexdZroX0WwgYgj8CE0qscGs5u1fjaEaQghgwR8l9DnckAm556S6KpszFhscTj69vNA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/napi-linux-arm64-musl": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.39.3.tgz", - "integrity": "sha512-K5rXJmaQ06H5PGCeSRTTiqszkFcEgRSryJYVs/5r/xj5scZwM7Xme+D6gc7FD/x2CuQ5cPQAJeH698zGbPV2Zg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/napi-linux-x64-gnu": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.39.3.tgz", - "integrity": "sha512-5xHCVTYj2sOsv0FriSpymrNx9FX5qOxjFKYkDwmJsTiAiENmmFyELNyfAN3ONeEpsV3kBJAZ0BBmd1KcBVOwRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/napi-linux-x64-musl": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.39.3.tgz", - "integrity": "sha512-6sD1YRKhios38r0muRX2AMIZDinaiRfF31rE4L2gMP0IeJm5s4uJKqVa6eoBAMyGgZlhne1ySNwJ06HBxgIqRw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/napi-win32-arm64-msvc": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.39.3.tgz", - "integrity": "sha512-3f5jrd6ar7RfD+djCxgf4QCRjVVOsyuU4lnwzFpdEcuZPVdI6jTzCoXg7D5bDkHeml8ZO6ojezkty74PbJZm4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/napi-win32-ia32-msvc": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.39.3.tgz", - "integrity": "sha512-h5qtHRnV8KaAFRQWff1PkRctFueRTEDSrBnr18xQTShbRdUEzQApoEPsGRWnpuOJzBDgTYkkX3XDEQy8tVFJyg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@ast-grep/napi-win32-x64-msvc": { - "version": "0.39.3", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.39.3.tgz", - "integrity": "sha512-syA3xRMS25RiSCJ1JWP5D00UwFvJSoQgHP4O5BGreouRqRpQlJr4CD4Sdf+UuHHwGbDYb652SoEKsi1rHo0M/Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@babel/code-frame": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -358,8 +114,6 @@ }, "node_modules/@babel/compat-data": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -367,8 +121,6 @@ }, "node_modules/@babel/core": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -397,8 +149,6 @@ }, "node_modules/@babel/generator": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", "license": "MIT", "dependencies": { "@babel/parser": "^7.28.0", @@ -413,8 +163,6 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "license": "MIT", "dependencies": { "@babel/types": "^7.27.3" @@ -425,8 +173,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.27.2", @@ -441,8 +187,6 @@ }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", - "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -462,8 +206,6 @@ }, "node_modules/@babel/helper-globals": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -471,8 +213,6 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", - "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -484,8 +224,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -497,8 +235,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -514,8 +250,6 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "license": "MIT", "dependencies": { "@babel/types": "^7.27.1" @@ -526,8 +260,6 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -535,8 +267,6 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", @@ -552,8 +282,6 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -565,8 +293,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -574,8 +300,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -583,8 +307,6 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -592,8 +314,6 @@ }, "node_modules/@babel/helpers": { "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", - "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", @@ -605,8 +325,6 @@ }, "node_modules/@babel/parser": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", "license": "MIT", "dependencies": { "@babel/types": "^7.28.0" @@ -620,8 +338,6 @@ }, "node_modules/@babel/plugin-syntax-flow": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz", - "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -635,8 +351,6 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -650,8 +364,6 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -665,8 +377,6 @@ }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -681,8 +391,6 @@ }, "node_modules/@babel/plugin-transform-flow-strip-types": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", - "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -697,8 +405,6 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", @@ -713,8 +419,6 @@ }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -728,8 +432,6 @@ }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", - "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -744,8 +446,6 @@ }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -760,8 +460,6 @@ }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", - "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -779,8 +477,6 @@ }, "node_modules/@babel/preset-flow": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.27.1.tgz", - "integrity": "sha512-ez3a2it5Fn6P54W8QkbfIyyIbxlXvcxyWHHvno1Wg0Ej5eiJY5hBb8ExttoIOJJk7V2dZE6prP7iby5q2aQ0Lg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -796,8 +492,6 @@ }, "node_modules/@babel/preset-typescript": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", - "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -815,8 +509,6 @@ }, "node_modules/@babel/register": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.27.1.tgz", - "integrity": "sha512-K13lQpoV54LATKkzBpBAEu1GGSIRzxR9f4IN4V8DCDgiUMo2UDGagEZr3lPeVNJPLkWUi5JE4hCHKneVTwQlYQ==", "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", @@ -834,8 +526,6 @@ }, "node_modules/@babel/template": { "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -848,8 +538,6 @@ }, "node_modules/@babel/traverse": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -866,8 +554,6 @@ }, "node_modules/@babel/types": { "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -879,8 +565,6 @@ }, "node_modules/@biomejs/biome": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.1.4.tgz", - "integrity": "sha512-QWlrqyxsU0FCebuMnkvBIkxvPqH89afiJzjMl+z67ybutse590jgeaFdDurE9XYtzpjRGTI1tlUZPGWmbKsElA==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -906,8 +590,6 @@ }, "node_modules/@biomejs/cli-darwin-arm64": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.1.4.tgz", - "integrity": "sha512-sCrNENE74I9MV090Wq/9Dg7EhPudx3+5OiSoQOkIe3DLPzFARuL1dOwCWhKCpA3I5RHmbrsbNSRfZwCabwd8Qg==", "cpu": [ "arm64" ], @@ -921,136 +603,13 @@ "node": ">=14.21.3" } }, - "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.1.4.tgz", - "integrity": "sha512-gOEICJbTCy6iruBywBDcG4X5rHMbqCPs3clh3UQ+hRKlgvJTk4NHWQAyHOXvaLe+AxD1/TNX1jbZeffBJzcrOw==", - "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": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.1.4.tgz", - "integrity": "sha512-juhEkdkKR4nbUi5k/KRp1ocGPNWLgFRD4NrHZSveYrD6i98pyvuzmS9yFYgOZa5JhaVqo0HPnci0+YuzSwT2fw==", - "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": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.1.4.tgz", - "integrity": "sha512-nYr7H0CyAJPaLupFE2cH16KZmRC5Z9PEftiA2vWxk+CsFkPZQ6dBRdcC6RuS+zJlPc/JOd8xw3uCCt9Pv41WvQ==", - "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": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.1.4.tgz", - "integrity": "sha512-Eoy9ycbhpJVYuR+LskV9s3uyaIkp89+qqgqhGQsWnp/I02Uqg2fXFblHJOpGZR8AxdB9ADy87oFVxn9MpFKUrw==", - "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": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.1.4.tgz", - "integrity": "sha512-lvwvb2SQQHctHUKvBKptR6PLFCM7JfRjpCCrDaTmvB7EeZ5/dQJPhTYBf36BE/B4CRWR2ZiBLRYhK7hhXBCZAg==", - "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": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.1.4.tgz", - "integrity": "sha512-3WRYte7orvyi6TRfIZkDN9Jzoogbv+gSvR+b9VOXUg1We1XrjBg6WljADeVEaKTvOcpVdH0a90TwyOQ6ue4fGw==", - "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": "2.1.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.1.4.tgz", - "integrity": "sha512-tBc+W7anBPSFXGAoQW+f/+svkpt8/uXfRwDzN1DvnatkRMt16KIYpEi/iw8u9GahJlFv98kgHcIrSsZHZTR0sw==", - "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.0.3", - "resolved": "https://registry.npmjs.org/@codemod.com/jssg-types/-/jssg-types-1.0.3.tgz", - "integrity": "sha512-spr0WkE2cRliMiz1pDO5xWaCWH6dZuq1QRqbnVSPj6gqKN/26LY7Sk5k/Xm5hJEZaOgy8GqEpX4BPUeOOqVlEw==", "dev": true, "license": "Apache-2.0" }, "node_modules/@codemod.com/workflow": { "version": "0.0.31", - "resolved": "https://registry.npmjs.org/@codemod.com/workflow/-/workflow-0.0.31.tgz", - "integrity": "sha512-8xmbxwjxr6d0ZUm3RS/eQqud2mUGXwQgf2v+YEjwQQVwOse6yShgoFljrg7ujvJlhzymivYloL0T0VSS9YubNw==", "license": "Apache-2.0", "dependencies": { "@ast-grep/cli": "^0.25.4", @@ -1079,8 +638,6 @@ }, "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.25.7.tgz", - "integrity": "sha512-kDw/JNyOLttVbm2hl+55C9lXuUcuIFt31LQIpSptUkyTgI+2Cdqdeah2bNPe4/GQM2ysDjBDS4y1+9iQxMdJiw==", "license": "MIT", "engines": { "node": ">= 10" @@ -1099,8 +656,6 @@ }, "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-darwin-arm64": { "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.25.7.tgz", - "integrity": "sha512-qqI1JvB6ULgOUOVE3YviQNQ6KAYOnkiE8W5fNwVJGUgMkUuM8tUm1Nal3vfKCI7dnYgpcNlKxdTWGlbt7aHKNg==", "cpu": [ "arm64" ], @@ -1113,138 +668,8 @@ "node": ">= 10" } }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-darwin-x64": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.25.7.tgz", - "integrity": "sha512-gq1Cf7US322ZJYPrVnAnn6eBLS6xi5catb5t99Wu6Rbm67XadEc81gtPTbPeNIu8FGgPjvKUc010rts2ZZbJeA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-arm64-gnu": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.25.7.tgz", - "integrity": "sha512-q+BzEC7wB7pkK+pQKbn4TVJThrEtvxjObz0okscPtxTNYvSJGv9jr3Nde5SYjdkfk8Ab4NgDMshVjKWVz2TSbQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-arm64-musl": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.25.7.tgz", - "integrity": "sha512-SEqZ6y0UhzmvZS938jIgR04kgHAW70hJ8yF4x9AkcqEhbeyqgElxIE7ve50ukDzs70fAKccdV8zYmebYN/7iPg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-x64-gnu": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.25.7.tgz", - "integrity": "sha512-8YuE/zTywTBb/iTm601JXTdWV2Redy9L9ab27aRD0hwX8FLmKUy8gK0fSo3xx+FyvSET49xkoR9tYdNaG2Wrkw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-x64-musl": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.25.7.tgz", - "integrity": "sha512-sT3eslR50IU6lHfqvq/c7vpxksJiB3h1NjEy1LpG+CYPuoLsQaB8j9OQlX8TqgVlDty/d/13cSls1Y3n/pm9xw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-win32-arm64-msvc": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.25.7.tgz", - "integrity": "sha512-pDi9vyXzUbpiRwFTif6+R7ZIIVB1ZKcRUJLKSIPyYb39DcSX7aOuxQcSZderWnBrwPGxZKzdgztdQ16TuAz2IQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-win32-ia32-msvc": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.25.7.tgz", - "integrity": "sha512-WFSNDMI5L9N9dK5zFQ6N900nhraOSYtKns/2p/EKZIKPBDXJSzzhT/jBakCSDix1GUs8K0XgkDoq2rXmuiBqXA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-win32-x64-msvc": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.25.7.tgz", - "integrity": "sha512-HlsoVwQ9XrgNZ0JAmXgV5t8Ltx9tGyWZNS2UMY/2cvNU/SG9EpJLm1Bu9Mlk5seiJLbl28QTTbhZdfPKBzGTVQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@inquirer/figures": { "version": "1.0.13", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", - "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", "license": "MIT", "engines": { "node": ">=18" @@ -1252,8 +677,6 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -1269,8 +692,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "license": "MIT", "engines": { "node": ">=12" @@ -1281,8 +702,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "license": "MIT", "engines": { "node": ">=12" @@ -1293,14 +712,10 @@ }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -1316,8 +731,6 @@ }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -1331,8 +744,6 @@ }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -1348,8 +759,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1358,8 +767,6 @@ }, "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" @@ -1367,14 +774,10 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1383,8 +786,6 @@ }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", "license": "MIT", "dependencies": { "debug": "^4.1.1" @@ -1392,14 +793,10 @@ }, "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", "license": "MIT" }, "node_modules/@nodejs-loaders/alias": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@nodejs-loaders/alias/-/alias-2.1.2.tgz", - "integrity": "sha512-thHaBXfGUbu7WpMqWt6Fw2xA6eN4faMl8kNFO8ufb2Ae4B9+9RhAg4vai1bFvzlBtnSTvUPU6qDz7sbpImFAbA==", "license": "ISC", "dependencies": { "json5": "^2.2.3" @@ -1442,8 +839,6 @@ }, "node_modules/@octokit/auth-token": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "license": "MIT", "engines": { "node": ">= 18" @@ -1451,8 +846,6 @@ }, "node_modules/@octokit/core": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", - "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", "license": "MIT", "dependencies": { "@octokit/auth-token": "^4.0.0", @@ -1469,8 +862,6 @@ }, "node_modules/@octokit/endpoint": { "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", - "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", "license": "MIT", "dependencies": { "@octokit/types": "^13.1.0", @@ -1482,8 +873,6 @@ }, "node_modules/@octokit/graphql": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", - "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", "license": "MIT", "dependencies": { "@octokit/request": "^8.4.1", @@ -1496,14 +885,10 @@ }, "node_modules/@octokit/openapi-types": { "version": "24.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", - "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { "version": "11.4.4-cjs.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", - "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", "license": "MIT", "dependencies": { "@octokit/types": "^13.7.0" @@ -1517,8 +902,6 @@ }, "node_modules/@octokit/plugin-request-log": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", - "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", "license": "MIT", "engines": { "node": ">= 18" @@ -1529,8 +912,6 @@ }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "13.3.2-cjs.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", - "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", "license": "MIT", "dependencies": { "@octokit/types": "^13.8.0" @@ -1544,8 +925,6 @@ }, "node_modules/@octokit/request": { "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", - "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", "license": "MIT", "dependencies": { "@octokit/endpoint": "^9.0.6", @@ -1559,8 +938,6 @@ }, "node_modules/@octokit/request-error": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", - "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", "license": "MIT", "dependencies": { "@octokit/types": "^13.1.0", @@ -1573,8 +950,6 @@ }, "node_modules/@octokit/rest": { "version": "20.1.2", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", - "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", "license": "MIT", "dependencies": { "@octokit/core": "^5.0.2", @@ -1588,8 +963,6 @@ }, "node_modules/@octokit/types": { "version": "13.10.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", - "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", "license": "MIT", "dependencies": { "@octokit/openapi-types": "^24.2.0" @@ -1597,8 +970,6 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", "optional": true, "engines": { @@ -1607,8 +978,6 @@ }, "node_modules/@sindresorhus/slugify": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", - "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==", "license": "MIT", "dependencies": { "@sindresorhus/transliterate": "^1.0.0", @@ -1623,8 +992,6 @@ }, "node_modules/@sindresorhus/transliterate": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz", - "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==", "license": "MIT", "dependencies": { "escape-string-regexp": "^5.0.0" @@ -1638,8 +1005,6 @@ }, "node_modules/@types/jscodeshift": { "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.11.11.tgz", - "integrity": "sha512-d7CAfFGOupj5qCDqMODXxNz2/NwCv/Lha78ZFbnr6qpk3K98iSB8I+ig9ERE2+EeYML352VMRsjPyOpeA+04eQ==", "license": "MIT", "dependencies": { "ast-types": "^0.14.1", @@ -1648,8 +1013,6 @@ }, "node_modules/@types/node": { "version": "24.2.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.1.tgz", - "integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==", "license": "MIT", "dependencies": { "undici-types": "~7.10.0" @@ -1657,8 +1020,6 @@ }, "node_modules/@types/node-fetch": { "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -1667,8 +1028,6 @@ }, "node_modules/abort-controller": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -1679,8 +1038,6 @@ }, "node_modules/agentkeepalive": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" @@ -1691,8 +1048,6 @@ }, "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==", "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -1706,8 +1061,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -1715,8 +1068,6 @@ }, "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==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1730,8 +1081,6 @@ }, "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==", "license": "MIT", "dependencies": { "tslib": "^2.0.1" @@ -1742,14 +1091,10 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", - "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -1757,19 +1102,13 @@ }, "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==", "license": "MIT" }, "node_modules/base-64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", - "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" + "version": "0.1.0" }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -1788,14 +1127,10 @@ }, "node_modules/before-after-hook": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "license": "Apache-2.0" }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -1805,8 +1140,6 @@ }, "node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -1814,8 +1147,6 @@ }, "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" @@ -1826,8 +1157,6 @@ }, "node_modules/browserslist": { "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "funding": [ { "type": "opencollective", @@ -1858,8 +1187,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -1882,14 +1209,10 @@ }, "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/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -1901,8 +1224,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "funding": [ { "type": "opencollective", @@ -1921,8 +1242,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1937,14 +1256,10 @@ }, "node_modules/chardet": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "license": "MIT" }, "node_modules/charenc": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "license": "BSD-3-Clause", "engines": { "node": "*" @@ -1952,8 +1267,6 @@ }, "node_modules/cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" @@ -1964,8 +1277,6 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "license": "MIT", "engines": { "node": ">=6" @@ -1976,8 +1287,6 @@ }, "node_modules/cli-width": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "license": "ISC", "engines": { "node": ">= 12" @@ -1985,8 +1294,6 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "license": "MIT", "engines": { "node": ">=0.8" @@ -1994,8 +1301,6 @@ }, "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", @@ -2008,8 +1313,6 @@ }, "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==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2020,14 +1323,10 @@ }, "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==", "license": "MIT" }, "node_modules/colors-cli": { "version": "1.0.33", - "resolved": "https://registry.npmjs.org/colors-cli/-/colors-cli-1.0.33.tgz", - "integrity": "sha512-PWGsmoJFdOB0t+BeHgmtuoRZUQucOLl5ii81NBzOOGVxlgE04muFNHlR5j8i8MKbOPELBl3243AI6lGBTj5ICQ==", "license": "MIT", "bin": { "colors": "bin/colors" @@ -2038,8 +1337,6 @@ }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -2050,26 +1347,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==", "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/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -2082,8 +1371,6 @@ }, "node_modules/crypt": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "license": "BSD-3-Clause", "engines": { "node": "*" @@ -2091,8 +1378,6 @@ }, "node_modules/debug": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2108,8 +1393,6 @@ }, "node_modules/dedent": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", - "integrity": "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2123,8 +1406,6 @@ }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "license": "MIT", "dependencies": { "clone": "^1.0.2" @@ -2135,8 +1416,6 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -2144,14 +1423,10 @@ }, "node_modules/deprecation": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "license": "ISC" }, "node_modules/detect-indent": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.1.tgz", - "integrity": "sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==", "license": "MIT", "engines": { "node": ">=12.20" @@ -2159,8 +1434,6 @@ }, "node_modules/detect-libc": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -2168,8 +1441,6 @@ }, "node_modules/detect-newline": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-4.0.1.tgz", - "integrity": "sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -2180,8 +1451,6 @@ }, "node_modules/diff": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -2189,8 +1458,6 @@ }, "node_modules/digest-fetch": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", - "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", "license": "ISC", "dependencies": { "base-64": "^0.1.0", @@ -2199,8 +1466,6 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -2213,26 +1478,18 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.5.191", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz", - "integrity": "sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==", "license": "ISC" }, "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==", "license": "MIT" }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -2240,8 +1497,6 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -2249,8 +1504,6 @@ }, "node_modules/es-object-atoms": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -2261,8 +1514,6 @@ }, "node_modules/es-set-tostringtag": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2276,8 +1527,6 @@ }, "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" @@ -2285,8 +1534,6 @@ }, "node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "license": "MIT", "engines": { "node": ">=12" @@ -2297,8 +1544,6 @@ }, "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", @@ -2310,8 +1555,6 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" @@ -2319,8 +1562,6 @@ }, "node_modules/external-editor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "license": "MIT", "dependencies": { "chardet": "^0.7.0", @@ -2333,8 +1574,6 @@ }, "node_modules/filename-reserved-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", - "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -2345,8 +1584,6 @@ }, "node_modules/filenamify": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", - "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", "license": "MIT", "dependencies": { "filename-reserved-regex": "^3.0.0" @@ -2360,8 +1597,6 @@ }, "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" @@ -2372,8 +1607,6 @@ }, "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", @@ -2386,8 +1619,6 @@ }, "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" @@ -2398,8 +1629,6 @@ }, "node_modules/flow-parser": { "version": "0.277.1", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.277.1.tgz", - "integrity": "sha512-86F5PGl+OrFvCzyK04id9Yf9rxFB8485GPs5sexB4cVLOXmpHbSi1/dYiaemI53I85CpImBu/qHVmZnGQflgmw==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -2407,8 +1636,6 @@ }, "node_modules/foreground-child": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -2423,8 +1650,6 @@ }, "node_modules/form-data": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -2439,14 +1664,10 @@ }, "node_modules/form-data-encoder": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", - "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", "license": "MIT" }, "node_modules/formdata-node": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", - "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", "license": "MIT", "dependencies": { "node-domexception": "1.0.0", @@ -2458,8 +1679,6 @@ }, "node_modules/formdata-node/node_modules/web-streams-polyfill": { "version": "4.0.0-beta.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", - "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", "license": "MIT", "engines": { "node": ">= 14" @@ -2467,14 +1686,10 @@ }, "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==", "license": "ISC" }, "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==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2482,8 +1697,6 @@ }, "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" @@ -2491,8 +1704,6 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -2515,8 +1726,6 @@ }, "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -2528,8 +1737,6 @@ }, "node_modules/git-up": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", - "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", "license": "MIT", "dependencies": { "is-ssh": "^1.4.0", @@ -2538,8 +1745,6 @@ }, "node_modules/git-url-parse": { "version": "14.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-14.1.0.tgz", - "integrity": "sha512-8xg65dTxGHST3+zGpycMMFZcoTzAdZ2dOtu4vmgIfkTFnVHBxHMzBC2L1k8To7EmrSiHesT8JgPLT91VKw1B5g==", "license": "MIT", "dependencies": { "git-up": "^7.0.0" @@ -2547,8 +1752,6 @@ }, "node_modules/glob": { "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -2567,8 +1770,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -2579,14 +1780,10 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -2594,8 +1791,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -2606,8 +1801,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -2621,8 +1814,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -2633,8 +1824,6 @@ }, "node_modules/humanize-ms": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "license": "MIT", "dependencies": { "ms": "^2.0.0" @@ -2642,8 +1831,6 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -2654,8 +1841,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -2674,8 +1859,6 @@ }, "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" @@ -2683,9 +1866,6 @@ }, "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.", "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -2694,14 +1874,10 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/inquirer": { "version": "9.3.7", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.7.tgz", - "integrity": "sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==", "license": "MIT", "dependencies": { "@inquirer/figures": "^1.0.3", @@ -2723,14 +1899,10 @@ }, "node_modules/is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "license": "MIT" }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -2738,8 +1910,6 @@ }, "node_modules/is-interactive": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "license": "MIT", "engines": { "node": ">=8" @@ -2747,8 +1917,6 @@ }, "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" @@ -2756,8 +1924,6 @@ }, "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" @@ -2768,8 +1934,6 @@ }, "node_modules/is-ssh": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", - "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", "license": "MIT", "dependencies": { "protocols": "^2.0.1" @@ -2777,8 +1941,6 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "license": "MIT", "engines": { "node": ">=10" @@ -2789,14 +1951,10 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "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" @@ -2804,8 +1962,6 @@ }, "node_modules/jackspeak": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -2819,14 +1975,10 @@ }, "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/jscodeshift": { "version": "0.15.2", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz", - "integrity": "sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==", "license": "MIT", "dependencies": { "@babel/core": "^7.23.0", @@ -2864,8 +2016,6 @@ }, "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" @@ -2876,8 +2026,6 @@ }, "node_modules/jscodeshift/node_modules/recast": { "version": "0.23.11", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", - "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", "license": "MIT", "dependencies": { "ast-types": "^0.16.1", @@ -2892,8 +2040,6 @@ }, "node_modules/jsesc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -2904,8 +2050,6 @@ }, "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" @@ -2916,8 +2060,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" @@ -2925,8 +2067,6 @@ }, "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", @@ -2938,14 +2078,10 @@ }, "node_modules/lodash-es": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "license": "MIT", "dependencies": { "chalk": "^4.1.0", @@ -2960,8 +2096,6 @@ }, "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" @@ -2969,8 +2103,6 @@ }, "node_modules/magic-string": { "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" @@ -2978,8 +2110,6 @@ }, "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", @@ -2991,8 +2121,6 @@ }, "node_modules/make-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" @@ -3000,8 +2128,6 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -3009,8 +2135,6 @@ }, "node_modules/md5": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", "license": "BSD-3-Clause", "dependencies": { "charenc": "0.0.2", @@ -3020,8 +2144,6 @@ }, "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", @@ -3033,8 +2155,6 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -3042,8 +2162,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -3054,8 +2172,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==", "license": "MIT", "engines": { "node": ">=6" @@ -3063,8 +2179,6 @@ }, "node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -3078,8 +2192,6 @@ }, "node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -3087,14 +2199,10 @@ }, "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/mute-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -3102,14 +2210,10 @@ }, "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-dir": { "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", "license": "MIT", "dependencies": { "minimatch": "^3.0.2" @@ -3120,8 +2224,6 @@ }, "node_modules/node-dir/node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -3130,8 +2232,6 @@ }, "node_modules/node-dir/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -3142,9 +2242,6 @@ }, "node_modules/node-domexception": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", "funding": [ { "type": "github", @@ -3162,8 +2259,6 @@ }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -3182,14 +2277,10 @@ }, "node_modules/node-releases": { "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, "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==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -3197,8 +2288,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -3212,8 +2301,6 @@ }, "node_modules/openai": { "version": "4.23.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.23.0.tgz", - "integrity": "sha512-ey2CXh1OTcTUa0AWZWuTpgA9t5GuAG3DVU1MofCRUI7fQJij8XJ3Sr0VtgxoAE69C9wbHBMCux8Z/IQZfSwHiA==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", @@ -3232,8 +2319,6 @@ }, "node_modules/openai/node_modules/@types/node": { "version": "18.19.120", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.120.tgz", - "integrity": "sha512-WtCGHFXnVI8WHLxDAt5TbnCM4eSE+nI0QN2NJtwzcgMhht2eNz6V9evJrk+lwC8bCY8OWV5Ym8Jz7ZEyGnKnMA==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -3241,14 +2326,10 @@ }, "node_modules/openai/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, "node_modules/ora": { "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "license": "MIT", "dependencies": { "bl": "^4.1.0", @@ -3270,8 +2351,6 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3279,8 +2358,6 @@ }, "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" @@ -3294,8 +2371,6 @@ }, "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" @@ -3306,8 +2381,6 @@ }, "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" @@ -3315,14 +2388,10 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/parse-path": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", - "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", "license": "MIT", "dependencies": { "protocols": "^2.0.0" @@ -3330,8 +2399,6 @@ }, "node_modules/parse-url": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", - "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", "license": "MIT", "dependencies": { "parse-path": "^7.0.0" @@ -3339,8 +2406,6 @@ }, "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" @@ -3348,8 +2413,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3357,8 +2420,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -3366,8 +2427,6 @@ }, "node_modules/path-scurry": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -3382,20 +2441,14 @@ }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, "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" @@ -3406,8 +2459,6 @@ }, "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" @@ -3415,8 +2466,6 @@ }, "node_modules/pirates": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "license": "MIT", "engines": { "node": ">= 6" @@ -3424,8 +2473,6 @@ }, "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" @@ -3436,8 +2483,6 @@ }, "node_modules/prettier": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -3451,14 +2496,10 @@ }, "node_modules/protocols": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", - "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", "license": "MIT" }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -3471,8 +2512,6 @@ }, "node_modules/recast": { "version": "0.20.5", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", - "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", "license": "MIT", "dependencies": { "ast-types": "0.14.2", @@ -3486,8 +2525,6 @@ }, "node_modules/restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "license": "MIT", "dependencies": { "onetime": "^5.1.0", @@ -3499,15 +2536,10 @@ }, "node_modules/restore-cursor/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==", "license": "ISC" }, "node_modules/rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -3518,8 +2550,6 @@ }, "node_modules/rimraf/node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -3528,9 +2558,6 @@ }, "node_modules/rimraf/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", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -3549,8 +2576,6 @@ }, "node_modules/rimraf/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -3561,8 +2586,6 @@ }, "node_modules/run-async": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -3570,8 +2593,6 @@ }, "node_modules/rxjs": { "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -3579,8 +2600,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -3599,14 +2618,10 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "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" @@ -3614,8 +2629,6 @@ }, "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" @@ -3626,8 +2639,6 @@ }, "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==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -3638,8 +2649,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -3647,8 +2656,6 @@ }, "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" @@ -3659,8 +2666,6 @@ }, "node_modules/simple-git": { "version": "3.28.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz", - "integrity": "sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==", "license": "MIT", "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -3674,8 +2679,6 @@ }, "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" @@ -3683,8 +2686,6 @@ }, "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", @@ -3693,8 +2694,6 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -3702,8 +2701,6 @@ }, "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -3717,8 +2714,6 @@ "node_modules/string-width-cjs": { "name": "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -3731,8 +2726,6 @@ }, "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==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -3744,8 +2737,6 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -3756,8 +2747,6 @@ }, "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==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -3768,8 +2757,6 @@ }, "node_modules/temp": { "version": "0.8.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", - "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", "license": "MIT", "dependencies": { "rimraf": "~2.6.2" @@ -3780,14 +2767,10 @@ }, "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.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" @@ -3798,8 +2781,6 @@ }, "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" @@ -3810,14 +2791,10 @@ }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/tree-kill": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "license": "MIT", "bin": { "tree-kill": "cli.js" @@ -3825,8 +2802,6 @@ }, "node_modules/ts-invariant": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", - "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", "license": "MIT", "dependencies": { "tslib": "^2.1.0" @@ -3837,14 +2812,10 @@ }, "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-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==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -3855,8 +2826,6 @@ }, "node_modules/typescript": { "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3869,20 +2838,14 @@ }, "node_modules/undici-types": { "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", "license": "MIT" }, "node_modules/universal-user-agent": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", "license": "ISC" }, "node_modules/update-browserslist-db": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "funding": [ { "type": "opencollective", @@ -3911,14 +2874,10 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "license": "MIT", "dependencies": { "defaults": "^1.0.3" @@ -3926,8 +2885,6 @@ }, "node_modules/web-streams-polyfill": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", "engines": { "node": ">= 8" @@ -3935,14 +2892,10 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -3951,8 +2904,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -3966,8 +2917,6 @@ }, "node_modules/wrap-ansi": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -3981,8 +2930,6 @@ "node_modules/wrap-ansi-cjs": { "name": "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==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -3998,14 +2945,10 @@ }, "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==", "license": "ISC" }, "node_modules/write-file-atomic": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "license": "ISC", "dependencies": { "graceful-fs": "^4.1.11", @@ -4015,20 +2958,14 @@ }, "node_modules/write-file-atomic/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==", "license": "ISC" }, "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/yaml": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -4039,8 +2976,6 @@ }, "node_modules/yoctocolors-cjs": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", - "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", "license": "MIT", "engines": { "node": ">=18" @@ -4125,7 +3060,7 @@ "@nodejs/codemod-utils": "*" }, "devDependencies": { - "@types/node": "^24.2.1" + "@codemod.com/jssg-types": "^1.0.3" } }, "utils": { @@ -4134,6 +3069,7 @@ "license": "MIT", "devDependencies": { "@ast-grep/napi": "^0.39.3", + "@codemod.com/jssg-types": "^1.0.3", "dedent": "^1.6.0" } } diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index c6284f7b..223d12da 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -346,8 +346,77 @@ function isInCallbackContext(param: string, rootNode: SgNode): boolean { * @param rootNode The root node of the AST */ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean { - // Search for variable declarations that assign from fs.openSync - const syncVariableDeclarators = rootNode.findAll({ + // Find all usages of the parameter to understand the context + const parameterUsages = rootNode.findAll({ + rule: { + kind: "identifier", + regex: `^${param}$` + } + }); + + // For each usage, check if there's a variable declaration in scope + for (const usage of parameterUsages) { + // Check if this usage is in a truncate call context + const isInTruncateCall = usage.inside({ + rule: { + any: [ + { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "fs.truncate($FD, $LEN)" }, + { pattern: "truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "truncate($FD, $LEN)" }, + { pattern: "fs.truncateSync($FD, $LEN)" }, + { pattern: "truncateSync($FD, $LEN)" } + ] + } + }); + + if (!isInTruncateCall) continue; + + // Find the scope containing this usage + const scope = findContainingScope(usage); + if (!scope) continue; + + // Search for variable declarations within this scope + if (hasFileDescriptorVariableInScope(param, scope)) { + return true; + } + } + + return false; +} + +/** + * Find the containing scope (function, block, or program) for a given node + * @param node The node to find the scope for + */ +function findContainingScope(node: SgNode): SgNode | null { + let current = node.parent(); + + while (current) { + const kind = current.kind(); + // These are scope-creating nodes in JavaScript + if (kind === "program" || + kind === "function_declaration" || + kind === "function_expression" || + kind === "arrow_function" || + kind === "method_definition" || + kind === "statement_block") { + return current; + } + current = current.parent(); + } + + return null; +} + +/** + * Check if there's a file descriptor variable declaration within a specific scope + * @param param The parameter name to check + * @param scope The scope node to search within + */ +function hasFileDescriptorVariableInScope(param: string, scope: SgNode): boolean { + // Search for variable declarations that assign from fs.openSync within this scope + const syncVariableDeclarators = scope.findAll({ rule: { kind: "variable_declarator", all: [ @@ -398,8 +467,8 @@ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean if (syncVariableDeclarators.length > 0) return true; - // Search for assignment expressions that assign from fs.openSync - const syncAssignments = rootNode.findAll({ + // Search for assignment expressions that assign from fs.openSync within this scope + const syncAssignments = scope.findAll({ rule: { kind: "assignment_expression", all: [ @@ -450,8 +519,8 @@ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean if (syncAssignments.length > 0) return true; - // Check if the variable is assigned from another variable that's a file descriptor - const variableAssignments = rootNode.findAll({ + // Check if the variable is assigned from another variable that's a file descriptor within this scope + const variableAssignments = scope.findAll({ rule: { kind: "variable_declarator", all: [ @@ -476,12 +545,42 @@ function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean const valueNode = assignment.field("value"); if (valueNode) { const sourceVar = valueNode.text(); - // Recursively check if the source variable is a file descriptor - if (hasFileDescriptorVariable(sourceVar, rootNode)) { + // Recursively check if the source variable is a file descriptor within the same scope + if (hasFileDescriptorVariableInScope(sourceVar, scope)) { return true; } } } + // If not found in current scope, check parent scopes (for closure/lexical scoping) + const parentScope = findParentScope(scope); + if (parentScope) { + return hasFileDescriptorVariableInScope(param, parentScope); + } + return false; } + +/** + * Find the parent scope of a given scope node + * @param scope The current scope node + */ +function findParentScope(scope: SgNode): SgNode | null { + let current = scope.parent(); + + while (current) { + const kind = current.kind(); + // These are scope-creating nodes in JavaScript + if (kind === "program" || + kind === "function_declaration" || + kind === "function_expression" || + kind === "arrow_function" || + kind === "method_definition" || + kind === "statement_block") { + return current; + } + current = current.parent(); + } + + return null; +} diff --git a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs index a05e4f02..12399270 100644 --- a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs +++ b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs @@ -17,7 +17,7 @@ fs.ftruncateSync(accesible, 10); fs.closeSync(accesible); function foo() { - truncateFile(unaccessible, 10); + ftruncateFile(unaccessible, 10); } function bar() { From 88e8c25fdc7169d6a49c1801ed6d7e85e3b5e32e Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Tue, 29 Jul 2025 23:23:29 +0200 Subject: [PATCH 19/23] clean chore files --- package-lock.json | 4 ++-- recipes/fs-truncate-fd-deprecation/codemod.yml | 2 +- recipes/fs-truncate-fd-deprecation/package.json | 4 ++-- recipes/fs-truncate-fd-deprecation/workflow.yaml | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 041ad18d..2afd2e59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3013,10 +3013,10 @@ }, "recipes/fs-truncate-fd-deprecation": { "name": "@nodejs/fs-truncate-fd-deprecation", - "version": "0.0.1", + "version": "1.0.0", "license": "MIT", "dependencies": { - "@nodejs/codemod-utils": "0.0.0" + "@nodejs/codemod-utils": "*" }, "devDependencies": { "@codemod.com/jssg-types": "^1.0.3" diff --git a/recipes/fs-truncate-fd-deprecation/codemod.yml b/recipes/fs-truncate-fd-deprecation/codemod.yml index 391bde96..0601a55a 100644 --- a/recipes/fs-truncate-fd-deprecation/codemod.yml +++ b/recipes/fs-truncate-fd-deprecation/codemod.yml @@ -1,6 +1,6 @@ schema_version: "1.0" name: nodejs/fs-truncate-fd-deprecation -version: 0.0.1 +version: 1.0.0 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy license: MIT diff --git a/recipes/fs-truncate-fd-deprecation/package.json b/recipes/fs-truncate-fd-deprecation/package.json index 8a92d26c..44f70f2d 100644 --- a/recipes/fs-truncate-fd-deprecation/package.json +++ b/recipes/fs-truncate-fd-deprecation/package.json @@ -1,6 +1,6 @@ { "name": "@nodejs/fs-truncate-fd-deprecation", - "version": "0.0.1", + "version": "1.0.0", "description": "Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor.", "type": "module", "scripts": { @@ -19,6 +19,6 @@ "@codemod.com/jssg-types": "^1.0.3" }, "dependencies": { - "@nodejs/codemod-utils": "0.0.0" + "@nodejs/codemod-utils": "*" } } diff --git a/recipes/fs-truncate-fd-deprecation/workflow.yaml b/recipes/fs-truncate-fd-deprecation/workflow.yaml index 1bc57731..e4777e8f 100644 --- a/recipes/fs-truncate-fd-deprecation/workflow.yaml +++ b/recipes/fs-truncate-fd-deprecation/workflow.yaml @@ -1,4 +1,5 @@ version: "1" + nodes: - id: apply-transforms name: Apply AST Transformations From b84169d1e7267bdac95a3ea2b7ed8c4a1394abf4 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Tue, 29 Jul 2025 23:45:48 +0200 Subject: [PATCH 20/23] improve security --- recipes/fs-truncate-fd-deprecation/README.md | 5 - .../src/workflow.ts | 613 +++++------------- .../tests/expected/edge-case.mjs | 2 +- 3 files changed, 171 insertions(+), 449 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/README.md b/recipes/fs-truncate-fd-deprecation/README.md index 666622c7..1d25932c 100644 --- a/recipes/fs-truncate-fd-deprecation/README.md +++ b/recipes/fs-truncate-fd-deprecation/README.md @@ -31,8 +31,3 @@ open('file.txt', 'w', (err, fd) => { }); }); ``` - -## Caveats - -When using `const fd = fs.openSync('file.txt', 'w');`, the codemod don't care about scope and will always transform `fs.truncate(fd, 10)` to `fs.ftruncateSync(fd, 10)`. So if you have mutiple variables with the same name, you should be careful with the transformation. - diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 223d12da..2885bec1 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -24,29 +24,19 @@ export default function transform(root: SgRoot): string | null { let usedTruncate = false; let usedTruncateSync = false; - // Find all truncate and truncateSync calls - const truncateCalls = rootNode.findAll({ + // Find fs.truncate and fs.truncateSync calls (these are always safe to transform) + const fsTruncateCalls = rootNode.findAll({ rule: { any: [ { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, { pattern: "fs.truncate($FD, $LEN)" }, - { pattern: "truncate($FD, $LEN, $CALLBACK)" }, - { pattern: "truncate($FD, $LEN)" } - ] - } - }); - - const truncateSyncCalls = rootNode.findAll({ - rule: { - any: [ - { pattern: "fs.truncateSync($FD, $LEN)" }, - { pattern: "truncateSync($FD, $LEN)" } + { pattern: "fs.truncateSync($FD, $LEN)" } ] } }); - // Transform truncate calls - for (const call of truncateCalls) { + // Transform fs.truncate calls + for (const call of fsTruncateCalls) { const fdMatch = call.getMatch("FD"); const lenMatch = call.getMatch("LEN"); const callbackMatch = call.getMatch("CALLBACK"); @@ -58,112 +48,128 @@ export default function transform(root: SgRoot): string | null { const callback = callbackMatch?.text(); const callText = call.text(); - // Check if this looks like a file descriptor (numeric or variable from open) - if (isLikelyFileDescriptor(fd, rootNode)) { - if (callText.includes("fs.truncate(")) { - const newCallText = callback - ? `fs.ftruncate(${fd}, ${len}, ${callback})` - : `fs.ftruncate(${fd}, ${len})`; - edits.push(call.replace(newCallText)); - } else { - // destructured call like truncate(...) - const newCallText = callback - ? `ftruncate(${fd}, ${len}, ${callback})` - : `ftruncate(${fd}, ${len})`; - edits.push(call.replace(newCallText)); - usedTruncate = true; - } - hasChanges = true; + let newCallText: string; + if (callText.includes("fs.truncateSync(")) { + newCallText = `fs.ftruncateSync(${fd}, ${len})`; + } else { + newCallText = callback + ? `fs.ftruncate(${fd}, ${len}, ${callback})` + : `fs.ftruncate(${fd}, ${len})`; } - } - // Transform truncateSync calls - for (const call of truncateSyncCalls) { - const fdMatch = call.getMatch("FD"); - const lenMatch = call.getMatch("LEN"); + edits.push(call.replace(newCallText)); + hasChanges = true; + } - if (!fdMatch || !lenMatch) continue; + // Find destructured truncate/truncateSync calls (need scope analysis) + const destructuredCalls = rootNode.findAll({ + rule: { + any: [ + { pattern: "truncate($FD, $LEN, $CALLBACK)" }, + { pattern: "truncate($FD, $LEN)" }, + { pattern: "truncateSync($FD, $LEN)" } + ] + } + }); - const fd = fdMatch.text(); - const len = lenMatch.text(); - const callText = call.text(); + // Transform destructured calls only if they're from fs imports/requires + for (const call of destructuredCalls) { + if (isFromFsModule(call, root)) { + const fdMatch = call.getMatch("FD"); + const lenMatch = call.getMatch("LEN"); + const callbackMatch = call.getMatch("CALLBACK"); + + if (!fdMatch || !lenMatch) continue; + + const fd = fdMatch.text(); + const len = lenMatch.text(); + const callback = callbackMatch?.text(); + const callText = call.text(); + + // Check if this looks like a file descriptor + if (isLikelyFileDescriptor(fd, rootNode)) { + let newCallText: string; + + if (callText.includes("truncateSync(")) { + newCallText = `ftruncateSync(${fd}, ${len})`; + usedTruncateSync = true; + } else { + newCallText = callback + ? `ftruncate(${fd}, ${len}, ${callback})` + : `ftruncate(${fd}, ${len})`; + usedTruncate = true; + } - // Check if this looks like a file descriptor - if (isLikelyFileDescriptor(fd, rootNode)) { - if (callText.includes("fs.truncateSync(")) { - const newCallText = `fs.ftruncateSync(${fd}, ${len})`; - edits.push(call.replace(newCallText)); - } else { - // destructured call like truncateSync(...) - const newCallText = `ftruncateSync(${fd}, ${len})`; edits.push(call.replace(newCallText)); - usedTruncateSync = true; + hasChanges = true; } - hasChanges = true; } } // Update imports/requires if we have destructured calls that were transformed if (usedTruncate || usedTruncateSync) { - // @ts-ignore - ast-grep types are not fully compatible with JSSG types - const importStatements = getNodeImportStatements(root, 'fs'); - - // Update import statements - for (const importNode of importStatements) { - const namedImports = importNode.find({ rule: { kind: 'named_imports' } }); - if (!namedImports) continue; - - let importText = importNode.text(); - let updated = false; + updateImportsAndRequires(root, usedTruncate, usedTruncateSync, edits); + hasChanges = true; + } - if (usedTruncate && importText.includes("truncate") && !importText.includes("ftruncate")) { - // Replace truncate with ftruncate in imports - importText = importText.replace(/\btruncate\b/g, "ftruncate"); - updated = true; - } + if (!hasChanges) return null; - if (usedTruncateSync && importText.includes("truncateSync") && !importText.includes("ftruncateSync")) { - // Replace truncateSync with ftruncateSync in imports - importText = importText.replace(/\btruncateSync\b/g, "ftruncateSync"); - updated = true; - } + return rootNode.commitEdits(edits); +} - if (updated) { - edits.push(importNode.replace(importText)); - hasChanges = true; - } +/** + * Update import and require statements to replace truncate functions with ftruncate + */ +function updateImportsAndRequires(root: SgRoot, usedTruncate: boolean, usedTruncateSync: boolean, edits: Edit[]): void { + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const importStatements = getNodeImportStatements(root, 'fs'); + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const requireStatements = getNodeRequireCalls(root, 'fs'); + + // Update import and require statements + for (const statement of [...importStatements, ...requireStatements]) { + let text = statement.text(); + let updated = false; + + if (usedTruncate && text.includes("truncate") && !text.includes("ftruncate")) { + text = text.replace(/\btruncate\b/g, "ftruncate"); + updated = true; } - // @ts-ignore - ast-grep types are not fully compatible with JSSG types - const requireStatements = getNodeRequireCalls(root, 'fs'); - - // Update require statements - for (const requireNode of requireStatements) { - let requireText = requireNode.text(); - let updated = false; - - if (usedTruncate && requireText.includes("truncate") && !requireText.includes("ftruncate")) { - // Replace truncate with ftruncate in requires - requireText = requireText.replace(/\btruncate\b/g, "ftruncate"); - updated = true; - } - - if (usedTruncateSync && requireText.includes("truncateSync") && !requireText.includes("ftruncateSync")) { - // Replace truncateSync with ftruncateSync in requires - requireText = requireText.replace(/\btruncateSync\b/g, "ftruncateSync"); - updated = true; - } + if (usedTruncateSync && text.includes("truncateSync") && !text.includes("ftruncateSync")) { + text = text.replace(/\btruncateSync\b/g, "ftruncateSync"); + updated = true; + } - if (updated) { - edits.push(requireNode.replace(requireText)); - hasChanges = true; - } + if (updated) { + edits.push(statement.replace(text)); } } +} - if (!hasChanges) return null; +/** + * Check if a call expression is from a destructured fs import/require + */ +function isFromFsModule(call: SgNode, root: SgRoot): boolean { + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const importStatements = getNodeImportStatements(root, 'fs'); + // @ts-ignore - ast-grep types are not fully compatible with JSSG types + const requireStatements = getNodeRequireCalls(root, 'fs'); + + // Get the function name being called (truncate or truncateSync) + const callExpression = call.child(0); + const functionName = callExpression?.text(); + if (!functionName) return false; + + // Check if this function name appears in any fs import/require destructuring + for (const statement of [...importStatements, ...requireStatements]) { + const text = statement.text(); + if (text.includes("{") && text.includes(functionName)) { + return true; + } + } - return rootNode.commitEdits(edits); + return false; } /** @@ -176,13 +182,16 @@ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { // Check if it's a numeric literal if (/^\d+$/.test(param.trim())) return true; - // Check if parameter is in a callback context - if (isInCallbackContext(param, rootNode)) return true; + // Check if it's obviously a string literal (path) + if (/^['"`]/.test(param.trim())) return false; + + // Check if it's assigned from fs.openSync or openSync + if (isAssignedFromOpenSync(param, rootNode)) return true; - // Check if there's a variable in scope that assigns a file descriptor - if (hasFileDescriptorVariable(param, rootNode)) return true; + // Check if it's used inside a callback context from fs.open + if (isInCallbackContext(param, rootNode)) return true; - // If we didn't find any indicators, assume it's not a file descriptor + // For other cases, be conservative - don't transform unless we're sure return false; } @@ -201,386 +210,104 @@ function isInCallbackContext(param: string, rootNode: SgNode): boolean { }); for (const usage of parameterUsages) { - // Check if this usage is inside a callback parameter list for fs.open - const isInFsOpenCallback = usage.inside({ + // Check if this usage is inside a callback parameter for fs.open or open + const isInOpenCallback = usage.inside({ rule: { kind: "call_expression", - all: [ - { - has: { - field: "function", + has: { + field: "function", + any: [ + { kind: "member_expression", all: [ - { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } - }, - { - has: { - field: "property", - kind: "property_identifier", - regex: "^open$" - } - } + { has: { field: "object", kind: "identifier", regex: "^fs$" } }, + { has: { field: "property", kind: "property_identifier", regex: "^open$" } } ] - } - }, - { - has: { - field: "arguments", - kind: "arguments", - has: { - any: [ - { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - }, - { - kind: "function_expression", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - } - ] - } - } - } - ] - } - }); - - // Check if this usage is inside a callback parameter list for destructured open - const isInDestructuredOpenCallback = usage.inside({ - rule: { - kind: "call_expression", - all: [ - { - has: { - field: "function", + }, + { kind: "identifier", regex: "^open$" } - }, - { - has: { - field: "arguments", - kind: "arguments", - has: { - any: [ - { - kind: "arrow_function", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - }, - { - kind: "function_expression", - has: { - field: "parameters", - kind: "formal_parameters", - has: { - // @ts-ignore - jssg-types arren't happy but jssg work with type_error - kind: "required_parameter", - has: { - field: "pattern", - kind: "identifier", - regex: `^${param}$` - } - } - } - } - ] - } - } - } - ] + ] + } } }); - if (isInFsOpenCallback || isInDestructuredOpenCallback) { - return true; - } + if (isInOpenCallback) return true; } return false; } /** - * Check if there's a variable in scope that assigns a file descriptor value + * Check if there's a variable that's assigned from fs.openSync * @param param The parameter name to check * @param rootNode The root node of the AST */ -function hasFileDescriptorVariable(param: string, rootNode: SgNode): boolean { - // Find all usages of the parameter to understand the context - const parameterUsages = rootNode.findAll({ - rule: { - kind: "identifier", - regex: `^${param}$` - } - }); - - // For each usage, check if there's a variable declaration in scope - for (const usage of parameterUsages) { - // Check if this usage is in a truncate call context - const isInTruncateCall = usage.inside({ - rule: { - any: [ - { pattern: "fs.truncate($FD, $LEN, $CALLBACK)" }, - { pattern: "fs.truncate($FD, $LEN)" }, - { pattern: "truncate($FD, $LEN, $CALLBACK)" }, - { pattern: "truncate($FD, $LEN)" }, - { pattern: "fs.truncateSync($FD, $LEN)" }, - { pattern: "truncateSync($FD, $LEN)" } - ] - } - }); - - if (!isInTruncateCall) continue; - - // Find the scope containing this usage - const scope = findContainingScope(usage); - if (!scope) continue; - - // Search for variable declarations within this scope - if (hasFileDescriptorVariableInScope(param, scope)) { - return true; - } - } - - return false; -} - -/** - * Find the containing scope (function, block, or program) for a given node - * @param node The node to find the scope for - */ -function findContainingScope(node: SgNode): SgNode | null { - let current = node.parent(); - - while (current) { - const kind = current.kind(); - // These are scope-creating nodes in JavaScript - if (kind === "program" || - kind === "function_declaration" || - kind === "function_expression" || - kind === "arrow_function" || - kind === "method_definition" || - kind === "statement_block") { - return current; - } - current = current.parent(); - } - - return null; -} - -/** - * Check if there's a file descriptor variable declaration within a specific scope - * @param param The parameter name to check - * @param scope The scope node to search within - */ -function hasFileDescriptorVariableInScope(param: string, scope: SgNode): boolean { - // Search for variable declarations that assign from fs.openSync within this scope - const syncVariableDeclarators = scope.findAll({ +function isAssignedFromOpenSync(param: string, rootNode: SgNode): boolean { + // Search for variable declarations or assignments from fs.openSync or openSync + const openSyncAssignments = rootNode.findAll({ rule: { - kind: "variable_declarator", - all: [ - { - has: { - field: "name", - kind: "identifier", - regex: `^${param}$` - } - }, + any: [ { - has: { - field: "value", - kind: "call_expression", - has: { - field: "function", - any: [ - { - kind: "member_expression", - all: [ + kind: "variable_declarator", + all: [ + { has: { field: "name", kind: "identifier", regex: `^${param}$` } }, + { + has: { + field: "value", + kind: "call_expression", + has: { + field: "function", + any: [ { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } + kind: "member_expression", + all: [ + { has: { field: "object", kind: "identifier", regex: "^fs$" } }, + { has: { field: "property", kind: "property_identifier", regex: "^openSync$" } } + ] }, { - has: { - field: "property", - kind: "property_identifier", - regex: "^openSync$" - } + kind: "identifier", + regex: "^openSync$" } ] - }, - { - kind: "identifier", - regex: "^openSync$" } - ] + } } - } - } - ] - } - }); - - if (syncVariableDeclarators.length > 0) return true; - - // Search for assignment expressions that assign from fs.openSync within this scope - const syncAssignments = scope.findAll({ - rule: { - kind: "assignment_expression", - all: [ - { - has: { - field: "left", - kind: "identifier", - regex: `^${param}$` - } + ] }, { - has: { - field: "right", - kind: "call_expression", - has: { - field: "function", - any: [ - { - kind: "member_expression", - all: [ + kind: "assignment_expression", + all: [ + { has: { field: "left", kind: "identifier", regex: `^${param}$` } }, + { + has: { + field: "right", + kind: "call_expression", + has: { + field: "function", + any: [ { - has: { - field: "object", - kind: "identifier", - regex: "^fs$" - } + kind: "member_expression", + all: [ + { has: { field: "object", kind: "identifier", regex: "^fs$" } }, + { has: { field: "property", kind: "property_identifier", regex: "^openSync$" } } + ] }, { - has: { - field: "property", - kind: "property_identifier", - regex: "^openSync$" - } + kind: "identifier", + regex: "^openSync$" } ] - }, - { - kind: "identifier", - regex: "^openSync$" } - ] + } } - } - } - ] - } - }); - - if (syncAssignments.length > 0) return true; - - // Check if the variable is assigned from another variable that's a file descriptor within this scope - const variableAssignments = scope.findAll({ - rule: { - kind: "variable_declarator", - all: [ - { - has: { - field: "name", - kind: "identifier", - regex: `^${param}$` - } - }, - { - has: { - field: "value", - kind: "identifier" - } + ] } ] } }); - for (const assignment of variableAssignments) { - const valueNode = assignment.field("value"); - if (valueNode) { - const sourceVar = valueNode.text(); - // Recursively check if the source variable is a file descriptor within the same scope - if (hasFileDescriptorVariableInScope(sourceVar, scope)) { - return true; - } - } - } - - // If not found in current scope, check parent scopes (for closure/lexical scoping) - const parentScope = findParentScope(scope); - if (parentScope) { - return hasFileDescriptorVariableInScope(param, parentScope); - } - - return false; -} - -/** - * Find the parent scope of a given scope node - * @param scope The current scope node - */ -function findParentScope(scope: SgNode): SgNode | null { - let current = scope.parent(); - - while (current) { - const kind = current.kind(); - // These are scope-creating nodes in JavaScript - if (kind === "program" || - kind === "function_declaration" || - kind === "function_expression" || - kind === "arrow_function" || - kind === "method_definition" || - kind === "statement_block") { - return current; - } - current = current.parent(); - } - - return null; + return openSyncAssignments.length > 0; } diff --git a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs index 12399270..a05e4f02 100644 --- a/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs +++ b/recipes/fs-truncate-fd-deprecation/tests/expected/edge-case.mjs @@ -17,7 +17,7 @@ fs.ftruncateSync(accesible, 10); fs.closeSync(accesible); function foo() { - ftruncateFile(unaccessible, 10); + truncateFile(unaccessible, 10); } function bar() { From f6313551b163cdbee961536bb37e6859ee813c0e Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Tue, 29 Jul 2025 23:47:58 +0200 Subject: [PATCH 21/23] chore(`codemod.yaml`): use righ file ext + correct scope --- .../fs-truncate-fd-deprecation/{codemod.yml => codemod.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename recipes/fs-truncate-fd-deprecation/{codemod.yml => codemod.yaml} (89%) diff --git a/recipes/fs-truncate-fd-deprecation/codemod.yml b/recipes/fs-truncate-fd-deprecation/codemod.yaml similarity index 89% rename from recipes/fs-truncate-fd-deprecation/codemod.yml rename to recipes/fs-truncate-fd-deprecation/codemod.yaml index 0601a55a..faa33f85 100644 --- a/recipes/fs-truncate-fd-deprecation/codemod.yml +++ b/recipes/fs-truncate-fd-deprecation/codemod.yaml @@ -1,5 +1,5 @@ schema_version: "1.0" -name: nodejs/fs-truncate-fd-deprecation +name: "@nodejs/fs-truncate-fd-deprecation" version: 1.0.0 description: Handle DEP0081 via transforming `truncate` to `ftruncateSync` when using a file descriptor. author: Augustin Mauroy From cbf286768e36f0e3b58a2aabf1e302a19070c174 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Wed, 13 Aug 2025 11:27:51 +0200 Subject: [PATCH 22/23] Update workflow.ts --- .../src/workflow.ts | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/recipes/fs-truncate-fd-deprecation/src/workflow.ts b/recipes/fs-truncate-fd-deprecation/src/workflow.ts index 2885bec1..f48e7aa8 100644 --- a/recipes/fs-truncate-fd-deprecation/src/workflow.ts +++ b/recipes/fs-truncate-fd-deprecation/src/workflow.ts @@ -179,20 +179,21 @@ function isFromFsModule(call: SgNode, root: SgRoot): boolean { * @param rootNode The root node of the AST to search within. */ function isLikelyFileDescriptor(param: string, rootNode: SgNode): boolean { - // Check if it's a numeric literal - if (/^\d+$/.test(param.trim())) return true; - - // Check if it's obviously a string literal (path) - if (/^['"`]/.test(param.trim())) return false; - - // Check if it's assigned from fs.openSync or openSync - if (isAssignedFromOpenSync(param, rootNode)) return true; - - // Check if it's used inside a callback context from fs.open - if (isInCallbackContext(param, rootNode)) return true; - - // For other cases, be conservative - don't transform unless we're sure - return false; + // Check if it's obviously a string literal (path) + if (/^['"`]/.test(param.trim())) return false; + + // Check if the parameter is likely a file descriptor: + // 1. It's a numeric literal (e.g., "123"). + // 2. It's assigned from fs.openSync or openSync. + // 3. It's used inside a callback context from fs.open. + if ( + /^\d+$/.test(param.trim()) || + isAssignedFromOpenSync(param, rootNode) || + isInCallbackContext(param, rootNode) + ) return true; + + // For other cases, be conservative - don't transform unless we're sure + return false; } /** From d2864ff8cefd67fb38d1698b7072ded0bffe023e Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Wed, 13 Aug 2025 19:39:30 +0200 Subject: [PATCH 23/23] Update package-lock.json --- package-lock.json | 1093 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1079 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2afd2e59..7b842431 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,8 @@ }, "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", @@ -31,6 +33,8 @@ }, "node_modules/@ast-grep/cli": { "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli/-/cli-0.25.7.tgz", + "integrity": "sha512-vklcPRFHPHkwHq05nb2Fuaj4BYNWxhr8GIdB6la090jWob9FdbM/Jz86vlQp2tRELb2rKzuHeksG8qDrbX4REg==", "hasInstallScript": true, "dependencies": { "detect-libc": "2.0.3" @@ -54,6 +58,8 @@ }, "node_modules/@ast-grep/cli-darwin-arm64": { "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli-darwin-arm64/-/cli-darwin-arm64-0.25.7.tgz", + "integrity": "sha512-dkj8hy32mWuQwCJUEpnKwTS8tLE+e7dhvu6is+v5Q6AumOVlcL6PJWQsyaA4vedDm6XOGK9+WnyFpCnV3b5ouA==", "cpu": [ "arm64" ], @@ -66,8 +72,106 @@ "node": ">= 10" } }, + "node_modules/@ast-grep/cli-darwin-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli-darwin-x64/-/cli-darwin-x64-0.25.7.tgz", + "integrity": "sha512-FBdv7GH3llH5LI0S2yeqgQM5QEUHeoYMhw1pv+C439UeL5BBFFjI+LYVALciwsYzuq/DQDTnT2cM0JhYGajDLQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/cli-linux-arm64-gnu": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-0.25.7.tgz", + "integrity": "sha512-lsE+cSe4rFO8rvLhMM7PM3T83LlmV60H9dOH+1hq8thkWhLCL6vAJijEVWgAQDDvvZf3xnNVgG2GG4jOMfTuTQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/cli-linux-x64-gnu": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli-linux-x64-gnu/-/cli-linux-x64-gnu-0.25.7.tgz", + "integrity": "sha512-uuF5GXgeUZtBrftJJYuQU7PvDT7Q9fJkKKwpIscEfQqLndri1tdYzzT9jKj2taWFlhiCVqLaDEHsdfTeWaVjZQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/cli-win32-arm64-msvc": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-0.25.7.tgz", + "integrity": "sha512-GSWRjOnWybzNP5rnvPb6lQ7lSPoEIl64gk4uHE1h+a2nnFhT9REWTKFcmNB2aG8VmKEz1gu0pxpg9HmBe2OUBA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/cli-win32-ia32-msvc": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-0.25.7.tgz", + "integrity": "sha512-5p9PWbTeXaivQYixB+JkkpFKgY7G1Tm6R46Dhq6cHvKksiQ6lWlTOOmhl0QARtY7y3XP0MWuvjDEWCYrvYtO4A==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/cli-win32-x64-msvc": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/cli-win32-x64-msvc/-/cli-win32-x64-msvc-0.25.7.tgz", + "integrity": "sha512-WjsRuyKTCeGWpMhvobzU/6HaWbseENPl5mNMZIKs8gsCpkUyTUfvV8/A2W29oHCgbDWRtixYppWtd87Qjpm6cg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@ast-grep/napi": { "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.39.3.tgz", + "integrity": "sha512-Y+16O9AbeR+yr5qnVpXHXHv/3EG2IPGCIbvxYo4MZpFSAmUBYibiLP0GljK5TWkQz6y4u5eHso3F13evyww4rw==", "dev": true, "license": "MIT", "engines": { @@ -87,6 +191,8 @@ }, "node_modules/@ast-grep/napi-darwin-arm64": { "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.39.3.tgz", + "integrity": "sha512-XfTqyDOOyYzAJo0ZOLowrWKnwIB2q6PpFJG1EZFWLkMB54nHub+XDseLxA33uy3O4TpereMaJwUYBDFmOlDqtg==", "cpu": [ "arm64" ], @@ -100,8 +206,146 @@ "node": ">= 10" } }, + "node_modules/@ast-grep/napi-darwin-x64": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.39.3.tgz", + "integrity": "sha512-uncDaz0wJWPHRSB76cllFzVVqJJoN2KisbJKvoBoX7yTCtQtOloWpLf+V+RM7KLzk9sruhDZeWqV2929MgUGTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/napi-linux-arm64-gnu": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.39.3.tgz", + "integrity": "sha512-ciNe9s54JUtttFtsdkBmexdZroX0WwgYgj8CE0qscGs5u1fjaEaQghgwR8l9DnckAm556S6KpszFhscTj69vNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/napi-linux-arm64-musl": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.39.3.tgz", + "integrity": "sha512-K5rXJmaQ06H5PGCeSRTTiqszkFcEgRSryJYVs/5r/xj5scZwM7Xme+D6gc7FD/x2CuQ5cPQAJeH698zGbPV2Zg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/napi-linux-x64-gnu": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.39.3.tgz", + "integrity": "sha512-5xHCVTYj2sOsv0FriSpymrNx9FX5qOxjFKYkDwmJsTiAiENmmFyELNyfAN3ONeEpsV3kBJAZ0BBmd1KcBVOwRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/napi-linux-x64-musl": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.39.3.tgz", + "integrity": "sha512-6sD1YRKhios38r0muRX2AMIZDinaiRfF31rE4L2gMP0IeJm5s4uJKqVa6eoBAMyGgZlhne1ySNwJ06HBxgIqRw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/napi-win32-arm64-msvc": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.39.3.tgz", + "integrity": "sha512-3f5jrd6ar7RfD+djCxgf4QCRjVVOsyuU4lnwzFpdEcuZPVdI6jTzCoXg7D5bDkHeml8ZO6ojezkty74PbJZm4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/napi-win32-ia32-msvc": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.39.3.tgz", + "integrity": "sha512-h5qtHRnV8KaAFRQWff1PkRctFueRTEDSrBnr18xQTShbRdUEzQApoEPsGRWnpuOJzBDgTYkkX3XDEQy8tVFJyg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ast-grep/napi-win32-x64-msvc": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.39.3.tgz", + "integrity": "sha512-syA3xRMS25RiSCJ1JWP5D00UwFvJSoQgHP4O5BGreouRqRpQlJr4CD4Sdf+UuHHwGbDYb652SoEKsi1rHo0M/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -114,6 +358,8 @@ }, "node_modules/@babel/compat-data": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -121,6 +367,8 @@ }, "node_modules/@babel/core": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -149,6 +397,8 @@ }, "node_modules/@babel/generator": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", "license": "MIT", "dependencies": { "@babel/parser": "^7.28.0", @@ -163,6 +413,8 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "license": "MIT", "dependencies": { "@babel/types": "^7.27.3" @@ -173,6 +425,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.27.2", @@ -187,6 +441,8 @@ }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -206,6 +462,8 @@ }, "node_modules/@babel/helper-globals": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -213,6 +471,8 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -224,6 +484,8 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -235,6 +497,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -250,6 +514,8 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "license": "MIT", "dependencies": { "@babel/types": "^7.27.1" @@ -260,6 +526,8 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -267,6 +535,8 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", @@ -282,6 +552,8 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -293,6 +565,8 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -300,6 +574,8 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -307,6 +583,8 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -314,6 +592,8 @@ }, "node_modules/@babel/helpers": { "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", + "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", @@ -325,6 +605,8 @@ }, "node_modules/@babel/parser": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", "license": "MIT", "dependencies": { "@babel/types": "^7.28.0" @@ -338,6 +620,8 @@ }, "node_modules/@babel/plugin-syntax-flow": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz", + "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -351,6 +635,8 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -364,6 +650,8 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -377,6 +665,8 @@ }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -391,6 +681,8 @@ }, "node_modules/@babel/plugin-transform-flow-strip-types": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", + "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -405,6 +697,8 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", @@ -419,6 +713,8 @@ }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -432,6 +728,8 @@ }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -446,6 +744,8 @@ }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -460,6 +760,8 @@ }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", + "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -477,6 +779,8 @@ }, "node_modules/@babel/preset-flow": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.27.1.tgz", + "integrity": "sha512-ez3a2it5Fn6P54W8QkbfIyyIbxlXvcxyWHHvno1Wg0Ej5eiJY5hBb8ExttoIOJJk7V2dZE6prP7iby5q2aQ0Lg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -492,6 +796,8 @@ }, "node_modules/@babel/preset-typescript": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", + "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -509,6 +815,8 @@ }, "node_modules/@babel/register": { "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.27.1.tgz", + "integrity": "sha512-K13lQpoV54LATKkzBpBAEu1GGSIRzxR9f4IN4V8DCDgiUMo2UDGagEZr3lPeVNJPLkWUi5JE4hCHKneVTwQlYQ==", "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", @@ -526,6 +834,8 @@ }, "node_modules/@babel/template": { "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -538,6 +848,8 @@ }, "node_modules/@babel/traverse": { "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -554,6 +866,8 @@ }, "node_modules/@babel/types": { "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -565,6 +879,8 @@ }, "node_modules/@biomejs/biome": { "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.1.4.tgz", + "integrity": "sha512-QWlrqyxsU0FCebuMnkvBIkxvPqH89afiJzjMl+z67ybutse590jgeaFdDurE9XYtzpjRGTI1tlUZPGWmbKsElA==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -590,6 +906,8 @@ }, "node_modules/@biomejs/cli-darwin-arm64": { "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.1.4.tgz", + "integrity": "sha512-sCrNENE74I9MV090Wq/9Dg7EhPudx3+5OiSoQOkIe3DLPzFARuL1dOwCWhKCpA3I5RHmbrsbNSRfZwCabwd8Qg==", "cpu": [ "arm64" ], @@ -603,13 +921,136 @@ "node": ">=14.21.3" } }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.1.4.tgz", + "integrity": "sha512-gOEICJbTCy6iruBywBDcG4X5rHMbqCPs3clh3UQ+hRKlgvJTk4NHWQAyHOXvaLe+AxD1/TNX1jbZeffBJzcrOw==", + "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": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.1.4.tgz", + "integrity": "sha512-juhEkdkKR4nbUi5k/KRp1ocGPNWLgFRD4NrHZSveYrD6i98pyvuzmS9yFYgOZa5JhaVqo0HPnci0+YuzSwT2fw==", + "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": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.1.4.tgz", + "integrity": "sha512-nYr7H0CyAJPaLupFE2cH16KZmRC5Z9PEftiA2vWxk+CsFkPZQ6dBRdcC6RuS+zJlPc/JOd8xw3uCCt9Pv41WvQ==", + "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": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.1.4.tgz", + "integrity": "sha512-Eoy9ycbhpJVYuR+LskV9s3uyaIkp89+qqgqhGQsWnp/I02Uqg2fXFblHJOpGZR8AxdB9ADy87oFVxn9MpFKUrw==", + "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": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.1.4.tgz", + "integrity": "sha512-lvwvb2SQQHctHUKvBKptR6PLFCM7JfRjpCCrDaTmvB7EeZ5/dQJPhTYBf36BE/B4CRWR2ZiBLRYhK7hhXBCZAg==", + "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": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.1.4.tgz", + "integrity": "sha512-3WRYte7orvyi6TRfIZkDN9Jzoogbv+gSvR+b9VOXUg1We1XrjBg6WljADeVEaKTvOcpVdH0a90TwyOQ6ue4fGw==", + "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": "2.1.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.1.4.tgz", + "integrity": "sha512-tBc+W7anBPSFXGAoQW+f/+svkpt8/uXfRwDzN1DvnatkRMt16KIYpEi/iw8u9GahJlFv98kgHcIrSsZHZTR0sw==", + "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.0.3", + "resolved": "https://registry.npmjs.org/@codemod.com/jssg-types/-/jssg-types-1.0.3.tgz", + "integrity": "sha512-spr0WkE2cRliMiz1pDO5xWaCWH6dZuq1QRqbnVSPj6gqKN/26LY7Sk5k/Xm5hJEZaOgy8GqEpX4BPUeOOqVlEw==", "dev": true, "license": "Apache-2.0" }, "node_modules/@codemod.com/workflow": { "version": "0.0.31", + "resolved": "https://registry.npmjs.org/@codemod.com/workflow/-/workflow-0.0.31.tgz", + "integrity": "sha512-8xmbxwjxr6d0ZUm3RS/eQqud2mUGXwQgf2v+YEjwQQVwOse6yShgoFljrg7ujvJlhzymivYloL0T0VSS9YubNw==", "license": "Apache-2.0", "dependencies": { "@ast-grep/cli": "^0.25.4", @@ -638,6 +1079,8 @@ }, "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi": { "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi/-/napi-0.25.7.tgz", + "integrity": "sha512-kDw/JNyOLttVbm2hl+55C9lXuUcuIFt31LQIpSptUkyTgI+2Cdqdeah2bNPe4/GQM2ysDjBDS4y1+9iQxMdJiw==", "license": "MIT", "engines": { "node": ">= 10" @@ -656,6 +1099,8 @@ }, "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-darwin-arm64": { "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-arm64/-/napi-darwin-arm64-0.25.7.tgz", + "integrity": "sha512-qqI1JvB6ULgOUOVE3YviQNQ6KAYOnkiE8W5fNwVJGUgMkUuM8tUm1Nal3vfKCI7dnYgpcNlKxdTWGlbt7aHKNg==", "cpu": [ "arm64" ], @@ -668,8 +1113,138 @@ "node": ">= 10" } }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-darwin-x64": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-darwin-x64/-/napi-darwin-x64-0.25.7.tgz", + "integrity": "sha512-gq1Cf7US322ZJYPrVnAnn6eBLS6xi5catb5t99Wu6Rbm67XadEc81gtPTbPeNIu8FGgPjvKUc010rts2ZZbJeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-arm64-gnu": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-gnu/-/napi-linux-arm64-gnu-0.25.7.tgz", + "integrity": "sha512-q+BzEC7wB7pkK+pQKbn4TVJThrEtvxjObz0okscPtxTNYvSJGv9jr3Nde5SYjdkfk8Ab4NgDMshVjKWVz2TSbQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-arm64-musl": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-arm64-musl/-/napi-linux-arm64-musl-0.25.7.tgz", + "integrity": "sha512-SEqZ6y0UhzmvZS938jIgR04kgHAW70hJ8yF4x9AkcqEhbeyqgElxIE7ve50ukDzs70fAKccdV8zYmebYN/7iPg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-x64-gnu": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-gnu/-/napi-linux-x64-gnu-0.25.7.tgz", + "integrity": "sha512-8YuE/zTywTBb/iTm601JXTdWV2Redy9L9ab27aRD0hwX8FLmKUy8gK0fSo3xx+FyvSET49xkoR9tYdNaG2Wrkw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-linux-x64-musl": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-linux-x64-musl/-/napi-linux-x64-musl-0.25.7.tgz", + "integrity": "sha512-sT3eslR50IU6lHfqvq/c7vpxksJiB3h1NjEy1LpG+CYPuoLsQaB8j9OQlX8TqgVlDty/d/13cSls1Y3n/pm9xw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-win32-arm64-msvc": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-arm64-msvc/-/napi-win32-arm64-msvc-0.25.7.tgz", + "integrity": "sha512-pDi9vyXzUbpiRwFTif6+R7ZIIVB1ZKcRUJLKSIPyYb39DcSX7aOuxQcSZderWnBrwPGxZKzdgztdQ16TuAz2IQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-win32-ia32-msvc": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-ia32-msvc/-/napi-win32-ia32-msvc-0.25.7.tgz", + "integrity": "sha512-WFSNDMI5L9N9dK5zFQ6N900nhraOSYtKns/2p/EKZIKPBDXJSzzhT/jBakCSDix1GUs8K0XgkDoq2rXmuiBqXA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@codemod.com/workflow/node_modules/@ast-grep/napi-win32-x64-msvc": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/@ast-grep/napi-win32-x64-msvc/-/napi-win32-x64-msvc-0.25.7.tgz", + "integrity": "sha512-HlsoVwQ9XrgNZ0JAmXgV5t8Ltx9tGyWZNS2UMY/2cvNU/SG9EpJLm1Bu9Mlk5seiJLbl28QTTbhZdfPKBzGTVQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@inquirer/figures": { "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", + "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", "license": "MIT", "engines": { "node": ">=18" @@ -677,6 +1252,8 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -692,6 +1269,8 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "license": "MIT", "engines": { "node": ">=12" @@ -702,6 +1281,8 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "license": "MIT", "engines": { "node": ">=12" @@ -712,10 +1293,14 @@ }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -731,6 +1316,8 @@ }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -744,6 +1331,8 @@ }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -758,7 +1347,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -767,17 +1358,23 @@ }, "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/sourcemap-codec": { - "version": "1.5.4", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -786,6 +1383,8 @@ }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", "license": "MIT", "dependencies": { "debug": "^4.1.1" @@ -793,10 +1392,14 @@ }, "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", "license": "MIT" }, "node_modules/@nodejs-loaders/alias": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@nodejs-loaders/alias/-/alias-2.1.2.tgz", + "integrity": "sha512-thHaBXfGUbu7WpMqWt6Fw2xA6eN4faMl8kNFO8ufb2Ae4B9+9RhAg4vai1bFvzlBtnSTvUPU6qDz7sbpImFAbA==", "license": "ISC", "dependencies": { "json5": "^2.2.3" @@ -839,6 +1442,8 @@ }, "node_modules/@octokit/auth-token": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", "license": "MIT", "engines": { "node": ">= 18" @@ -846,6 +1451,8 @@ }, "node_modules/@octokit/core": { "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", + "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", "license": "MIT", "dependencies": { "@octokit/auth-token": "^4.0.0", @@ -862,6 +1469,8 @@ }, "node_modules/@octokit/endpoint": { "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", + "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", "license": "MIT", "dependencies": { "@octokit/types": "^13.1.0", @@ -873,6 +1482,8 @@ }, "node_modules/@octokit/graphql": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", + "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", "license": "MIT", "dependencies": { "@octokit/request": "^8.4.1", @@ -885,10 +1496,14 @@ }, "node_modules/@octokit/openapi-types": { "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { "version": "11.4.4-cjs.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.4-cjs.2.tgz", + "integrity": "sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==", "license": "MIT", "dependencies": { "@octokit/types": "^13.7.0" @@ -902,6 +1517,8 @@ }, "node_modules/@octokit/plugin-request-log": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", "license": "MIT", "engines": { "node": ">= 18" @@ -912,6 +1529,8 @@ }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "13.3.2-cjs.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.2-cjs.1.tgz", + "integrity": "sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==", "license": "MIT", "dependencies": { "@octokit/types": "^13.8.0" @@ -925,6 +1544,8 @@ }, "node_modules/@octokit/request": { "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", + "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", "license": "MIT", "dependencies": { "@octokit/endpoint": "^9.0.6", @@ -938,6 +1559,8 @@ }, "node_modules/@octokit/request-error": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", + "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", "license": "MIT", "dependencies": { "@octokit/types": "^13.1.0", @@ -950,6 +1573,8 @@ }, "node_modules/@octokit/rest": { "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.2.tgz", + "integrity": "sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==", "license": "MIT", "dependencies": { "@octokit/core": "^5.0.2", @@ -963,6 +1588,8 @@ }, "node_modules/@octokit/types": { "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", "license": "MIT", "dependencies": { "@octokit/openapi-types": "^24.2.0" @@ -970,6 +1597,8 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", "optional": true, "engines": { @@ -978,6 +1607,8 @@ }, "node_modules/@sindresorhus/slugify": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", + "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==", "license": "MIT", "dependencies": { "@sindresorhus/transliterate": "^1.0.0", @@ -992,6 +1623,8 @@ }, "node_modules/@sindresorhus/transliterate": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz", + "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==", "license": "MIT", "dependencies": { "escape-string-regexp": "^5.0.0" @@ -1005,6 +1638,8 @@ }, "node_modules/@types/jscodeshift": { "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.11.11.tgz", + "integrity": "sha512-d7CAfFGOupj5qCDqMODXxNz2/NwCv/Lha78ZFbnr6qpk3K98iSB8I+ig9ERE2+EeYML352VMRsjPyOpeA+04eQ==", "license": "MIT", "dependencies": { "ast-types": "^0.14.1", @@ -1013,21 +1648,27 @@ }, "node_modules/@types/node": { "version": "24.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.1.tgz", + "integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==", "license": "MIT", "dependencies": { "undici-types": "~7.10.0" } }, "node_modules/@types/node-fetch": { - "version": "2.6.12", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "license": "MIT", "dependencies": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^4.0.4" } }, "node_modules/abort-controller": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -1038,6 +1679,8 @@ }, "node_modules/agentkeepalive": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" @@ -1048,6 +1691,8 @@ }, "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==", "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -1061,6 +1706,8 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -1068,6 +1715,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==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1081,6 +1730,8 @@ }, "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==", "license": "MIT", "dependencies": { "tslib": "^2.0.1" @@ -1091,10 +1742,14 @@ }, "node_modules/asynckit": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -1102,13 +1757,19 @@ }, "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==", "license": "MIT" }, "node_modules/base-64": { - "version": "0.1.0" + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -1127,10 +1788,14 @@ }, "node_modules/before-after-hook": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "license": "Apache-2.0" }, "node_modules/bl": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -1140,6 +1805,8 @@ }, "node_modules/brace-expansion": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -1147,6 +1814,8 @@ }, "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" @@ -1156,7 +1825,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.1", + "version": "4.25.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.2.tgz", + "integrity": "sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==", "funding": [ { "type": "opencollective", @@ -1173,8 +1844,8 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", + "caniuse-lite": "^1.0.30001733", + "electron-to-chromium": "^1.5.199", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, @@ -1187,6 +1858,8 @@ }, "node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -1209,10 +1882,14 @@ }, "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/call-bind-apply-helpers": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -1223,7 +1900,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001727", + "version": "1.0.30001734", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001734.tgz", + "integrity": "sha512-uhE1Ye5vgqju6OI71HTQqcBCZrvHugk0MjLak7Q+HfoBgoq5Bi+5YnwjP4fjDgrtYr/l8MVRBvzz9dPD4KyK0A==", "funding": [ { "type": "opencollective", @@ -1242,6 +1921,8 @@ }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -1256,10 +1937,14 @@ }, "node_modules/chardet": { "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "license": "MIT" }, "node_modules/charenc": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "license": "BSD-3-Clause", "engines": { "node": "*" @@ -1267,6 +1952,8 @@ }, "node_modules/cli-cursor": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" @@ -1277,6 +1964,8 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "license": "MIT", "engines": { "node": ">=6" @@ -1287,6 +1976,8 @@ }, "node_modules/cli-width": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "license": "ISC", "engines": { "node": ">= 12" @@ -1294,6 +1985,8 @@ }, "node_modules/clone": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "license": "MIT", "engines": { "node": ">=0.8" @@ -1301,6 +1994,8 @@ }, "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", @@ -1313,6 +2008,8 @@ }, "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==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -1323,10 +2020,14 @@ }, "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==", "license": "MIT" }, "node_modules/colors-cli": { "version": "1.0.33", + "resolved": "https://registry.npmjs.org/colors-cli/-/colors-cli-1.0.33.tgz", + "integrity": "sha512-PWGsmoJFdOB0t+BeHgmtuoRZUQucOLl5ii81NBzOOGVxlgE04muFNHlR5j8i8MKbOPELBl3243AI6lGBTj5ICQ==", "license": "MIT", "bin": { "colors": "bin/colors" @@ -1337,6 +2038,8 @@ }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -1347,18 +2050,26 @@ }, "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==", "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/cross-spawn": { "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -1371,6 +2082,8 @@ }, "node_modules/crypt": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "license": "BSD-3-Clause", "engines": { "node": "*" @@ -1378,6 +2091,8 @@ }, "node_modules/debug": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1393,6 +2108,8 @@ }, "node_modules/dedent": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", + "integrity": "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1406,6 +2123,8 @@ }, "node_modules/defaults": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "license": "MIT", "dependencies": { "clone": "^1.0.2" @@ -1416,6 +2135,8 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -1423,10 +2144,14 @@ }, "node_modules/deprecation": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "license": "ISC" }, "node_modules/detect-indent": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.1.tgz", + "integrity": "sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==", "license": "MIT", "engines": { "node": ">=12.20" @@ -1434,6 +2159,8 @@ }, "node_modules/detect-libc": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -1441,6 +2168,8 @@ }, "node_modules/detect-newline": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-4.0.1.tgz", + "integrity": "sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -1451,6 +2180,8 @@ }, "node_modules/diff": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -1458,6 +2189,8 @@ }, "node_modules/digest-fetch": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", + "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", "license": "ISC", "dependencies": { "base-64": "^0.1.0", @@ -1466,6 +2199,8 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -1478,18 +2213,26 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.191", + "version": "1.5.200", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.200.tgz", + "integrity": "sha512-rFCxROw7aOe4uPTfIAx+rXv9cEcGx+buAF4npnhtTqCJk5KDFRnh3+KYj7rdVh6lsFt5/aPs+Irj9rZ33WMA7w==", "license": "ISC" }, "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==", "license": "MIT" }, "node_modules/es-define-property": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1497,6 +2240,8 @@ }, "node_modules/es-errors": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1504,6 +2249,8 @@ }, "node_modules/es-object-atoms": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -1514,6 +2261,8 @@ }, "node_modules/es-set-tostringtag": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -1527,6 +2276,8 @@ }, "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" @@ -1534,6 +2285,8 @@ }, "node_modules/escape-string-regexp": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "license": "MIT", "engines": { "node": ">=12" @@ -1544,6 +2297,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", @@ -1555,6 +2310,8 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" @@ -1562,6 +2319,8 @@ }, "node_modules/external-editor": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "license": "MIT", "dependencies": { "chardet": "^0.7.0", @@ -1574,6 +2333,8 @@ }, "node_modules/filename-reserved-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -1584,6 +2345,8 @@ }, "node_modules/filenamify": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", + "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", "license": "MIT", "dependencies": { "filename-reserved-regex": "^3.0.0" @@ -1597,6 +2360,8 @@ }, "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" @@ -1607,6 +2372,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", @@ -1619,6 +2386,8 @@ }, "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" @@ -1628,7 +2397,9 @@ } }, "node_modules/flow-parser": { - "version": "0.277.1", + "version": "0.278.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.278.0.tgz", + "integrity": "sha512-9oUcYDHf9n+E/t0FXndgBqGbaUsGEcmWqIr1ldqCzTzctsJV5E/bHusOj4ThB72Ss2mqWpLFNz0+o2c1O8J6+A==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -1636,6 +2407,8 @@ }, "node_modules/foreground-child": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -1650,6 +2423,8 @@ }, "node_modules/form-data": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -1664,10 +2439,14 @@ }, "node_modules/form-data-encoder": { "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", "license": "MIT" }, "node_modules/formdata-node": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", "license": "MIT", "dependencies": { "node-domexception": "1.0.0", @@ -1679,6 +2458,8 @@ }, "node_modules/formdata-node/node_modules/web-streams-polyfill": { "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", "license": "MIT", "engines": { "node": ">= 14" @@ -1686,10 +2467,14 @@ }, "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==", "license": "ISC" }, "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==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1697,6 +2482,8 @@ }, "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" @@ -1704,6 +2491,8 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -1726,6 +2515,8 @@ }, "node_modules/get-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -1737,6 +2528,8 @@ }, "node_modules/git-up": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", + "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", "license": "MIT", "dependencies": { "is-ssh": "^1.4.0", @@ -1745,6 +2538,8 @@ }, "node_modules/git-url-parse": { "version": "14.1.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-14.1.0.tgz", + "integrity": "sha512-8xg65dTxGHST3+zGpycMMFZcoTzAdZ2dOtu4vmgIfkTFnVHBxHMzBC2L1k8To7EmrSiHesT8JgPLT91VKw1B5g==", "license": "MIT", "dependencies": { "git-up": "^7.0.0" @@ -1752,6 +2547,8 @@ }, "node_modules/glob": { "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -1770,6 +2567,8 @@ }, "node_modules/gopd": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1780,10 +2579,14 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -1791,6 +2594,8 @@ }, "node_modules/has-symbols": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -1801,6 +2606,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -1814,6 +2621,8 @@ }, "node_modules/hasown": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -1824,6 +2633,8 @@ }, "node_modules/humanize-ms": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "license": "MIT", "dependencies": { "ms": "^2.0.0" @@ -1831,6 +2642,8 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -1841,6 +2654,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -1859,6 +2674,8 @@ }, "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" @@ -1866,6 +2683,9 @@ }, "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.", "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -1874,10 +2694,14 @@ }, "node_modules/inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/inquirer": { "version": "9.3.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.7.tgz", + "integrity": "sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==", "license": "MIT", "dependencies": { "@inquirer/figures": "^1.0.3", @@ -1899,10 +2723,14 @@ }, "node_modules/is-buffer": { "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "license": "MIT" }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -1910,6 +2738,8 @@ }, "node_modules/is-interactive": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "license": "MIT", "engines": { "node": ">=8" @@ -1917,6 +2747,8 @@ }, "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" @@ -1924,6 +2756,8 @@ }, "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" @@ -1934,6 +2768,8 @@ }, "node_modules/is-ssh": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", "license": "MIT", "dependencies": { "protocols": "^2.0.1" @@ -1941,6 +2777,8 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "license": "MIT", "engines": { "node": ">=10" @@ -1951,10 +2789,14 @@ }, "node_modules/isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "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" @@ -1962,6 +2804,8 @@ }, "node_modules/jackspeak": { "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -1975,10 +2819,14 @@ }, "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/jscodeshift": { "version": "0.15.2", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz", + "integrity": "sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==", "license": "MIT", "dependencies": { "@babel/core": "^7.23.0", @@ -2016,6 +2864,8 @@ }, "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" @@ -2026,6 +2876,8 @@ }, "node_modules/jscodeshift/node_modules/recast": { "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", "license": "MIT", "dependencies": { "ast-types": "^0.16.1", @@ -2040,6 +2892,8 @@ }, "node_modules/jsesc": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -2050,6 +2904,8 @@ }, "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" @@ -2060,6 +2916,8 @@ }, "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" @@ -2067,6 +2925,8 @@ }, "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", @@ -2078,10 +2938,14 @@ }, "node_modules/lodash-es": { "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "license": "MIT", "dependencies": { "chalk": "^4.1.0", @@ -2096,6 +2960,8 @@ }, "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" @@ -2103,6 +2969,8 @@ }, "node_modules/magic-string": { "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" @@ -2110,6 +2978,8 @@ }, "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", @@ -2121,6 +2991,8 @@ }, "node_modules/make-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" @@ -2128,6 +3000,8 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -2135,6 +3009,8 @@ }, "node_modules/md5": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", "license": "BSD-3-Clause", "dependencies": { "charenc": "0.0.2", @@ -2144,6 +3020,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", @@ -2155,6 +3033,8 @@ }, "node_modules/mime-db": { "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -2162,6 +3042,8 @@ }, "node_modules/mime-types": { "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -2172,6 +3054,8 @@ }, "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==", "license": "MIT", "engines": { "node": ">=6" @@ -2179,6 +3063,8 @@ }, "node_modules/minimatch": { "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -2192,6 +3078,8 @@ }, "node_modules/minipass": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -2199,10 +3087,14 @@ }, "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/mute-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -2210,10 +3102,14 @@ }, "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-dir": { "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", "license": "MIT", "dependencies": { "minimatch": "^3.0.2" @@ -2224,6 +3120,8 @@ }, "node_modules/node-dir/node_modules/brace-expansion": { "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2232,6 +3130,8 @@ }, "node_modules/node-dir/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -2242,6 +3142,9 @@ }, "node_modules/node-domexception": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", "funding": [ { "type": "github", @@ -2259,6 +3162,8 @@ }, "node_modules/node-fetch": { "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -2277,10 +3182,14 @@ }, "node_modules/node-releases": { "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, "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==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -2288,6 +3197,8 @@ }, "node_modules/onetime": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -2301,6 +3212,8 @@ }, "node_modules/openai": { "version": "4.23.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.23.0.tgz", + "integrity": "sha512-ey2CXh1OTcTUa0AWZWuTpgA9t5GuAG3DVU1MofCRUI7fQJij8XJ3Sr0VtgxoAE69C9wbHBMCux8Z/IQZfSwHiA==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", @@ -2318,7 +3231,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.120", + "version": "18.19.122", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.122.tgz", + "integrity": "sha512-yzegtT82dwTNEe/9y+CM8cgb42WrUfMMCg2QqSddzO1J6uPmBD7qKCZ7dOHZP2Yrpm/kb0eqdNMn2MUyEiqBmA==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -2326,10 +3241,14 @@ }, "node_modules/openai/node_modules/undici-types": { "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, "node_modules/ora": { "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "license": "MIT", "dependencies": { "bl": "^4.1.0", @@ -2351,6 +3270,8 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -2358,6 +3279,8 @@ }, "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" @@ -2371,6 +3294,8 @@ }, "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" @@ -2381,6 +3306,8 @@ }, "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" @@ -2388,10 +3315,14 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/parse-path": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", "license": "MIT", "dependencies": { "protocols": "^2.0.0" @@ -2399,6 +3330,8 @@ }, "node_modules/parse-url": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", + "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", "license": "MIT", "dependencies": { "parse-path": "^7.0.0" @@ -2406,6 +3339,8 @@ }, "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" @@ -2413,6 +3348,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==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -2420,6 +3357,8 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -2427,6 +3366,8 @@ }, "node_modules/path-scurry": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -2441,14 +3382,20 @@ }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, "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" @@ -2459,6 +3406,8 @@ }, "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" @@ -2466,6 +3415,8 @@ }, "node_modules/pirates": { "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "license": "MIT", "engines": { "node": ">= 6" @@ -2473,6 +3424,8 @@ }, "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" @@ -2483,6 +3436,8 @@ }, "node_modules/prettier": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -2496,10 +3451,14 @@ }, "node_modules/protocols": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", "license": "MIT" }, "node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -2512,6 +3471,8 @@ }, "node_modules/recast": { "version": "0.20.5", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz", + "integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==", "license": "MIT", "dependencies": { "ast-types": "0.14.2", @@ -2525,6 +3486,8 @@ }, "node_modules/restore-cursor": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "license": "MIT", "dependencies": { "onetime": "^5.1.0", @@ -2536,10 +3499,15 @@ }, "node_modules/restore-cursor/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==", "license": "ISC" }, "node_modules/rimraf": { "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -2550,6 +3518,8 @@ }, "node_modules/rimraf/node_modules/brace-expansion": { "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -2558,6 +3528,9 @@ }, "node_modules/rimraf/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", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -2576,6 +3549,8 @@ }, "node_modules/rimraf/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -2586,6 +3561,8 @@ }, "node_modules/run-async": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -2593,6 +3570,8 @@ }, "node_modules/rxjs": { "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -2600,6 +3579,8 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -2618,10 +3599,14 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "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" @@ -2629,6 +3614,8 @@ }, "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" @@ -2639,6 +3626,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==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -2649,6 +3638,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==", "license": "MIT", "engines": { "node": ">=8" @@ -2656,6 +3647,8 @@ }, "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" @@ -2666,6 +3659,8 @@ }, "node_modules/simple-git": { "version": "3.28.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz", + "integrity": "sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==", "license": "MIT", "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -2679,6 +3674,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" @@ -2686,6 +3683,8 @@ }, "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", @@ -2694,6 +3693,8 @@ }, "node_modules/string_decoder": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -2701,6 +3702,8 @@ }, "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -2714,6 +3717,8 @@ "node_modules/string-width-cjs": { "name": "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -2726,6 +3731,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==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -2737,6 +3744,8 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -2747,6 +3756,8 @@ }, "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==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -2757,6 +3768,8 @@ }, "node_modules/temp": { "version": "0.8.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", + "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", "license": "MIT", "dependencies": { "rimraf": "~2.6.2" @@ -2767,10 +3780,14 @@ }, "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.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" @@ -2781,6 +3798,8 @@ }, "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" @@ -2791,10 +3810,14 @@ }, "node_modules/tr46": { "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/tree-kill": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "license": "MIT", "bin": { "tree-kill": "cli.js" @@ -2802,6 +3825,8 @@ }, "node_modules/ts-invariant": { "version": "0.10.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", + "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", "license": "MIT", "dependencies": { "tslib": "^2.1.0" @@ -2812,10 +3837,14 @@ }, "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-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==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -2826,6 +3855,8 @@ }, "node_modules/typescript": { "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2838,14 +3869,20 @@ }, "node_modules/undici-types": { "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", "license": "MIT" }, "node_modules/universal-user-agent": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", "license": "ISC" }, "node_modules/update-browserslist-db": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "funding": [ { "type": "opencollective", @@ -2874,10 +3911,14 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/wcwidth": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "license": "MIT", "dependencies": { "defaults": "^1.0.3" @@ -2885,6 +3926,8 @@ }, "node_modules/web-streams-polyfill": { "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", "engines": { "node": ">= 8" @@ -2892,10 +3935,14 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -2904,6 +3951,8 @@ }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -2917,6 +3966,8 @@ }, "node_modules/wrap-ansi": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -2930,6 +3981,8 @@ "node_modules/wrap-ansi-cjs": { "name": "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==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -2945,10 +3998,14 @@ }, "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==", "license": "ISC" }, "node_modules/write-file-atomic": { "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "license": "ISC", "dependencies": { "graceful-fs": "^4.1.11", @@ -2958,14 +4015,20 @@ }, "node_modules/write-file-atomic/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==", "license": "ISC" }, "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/yaml": { - "version": "2.8.0", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -2976,6 +4039,8 @@ }, "node_modules/yoctocolors-cjs": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", "license": "MIT", "engines": { "node": ">=18"