diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..f841cf2 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +npx lint-staged diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 0000000..c05253c --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +npm run prettier:check +npm run lint +npm test diff --git a/README.md b/README.md index 56de234..0d2e2d6 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,10 @@ Node.js utility for transforming a JavaScript or TypeScript file from an ES modu - ES module ➡️ CommonJS - CommonJS ➡️ ES module -By default `@knighted/module` transforms the one-to-one [differences between ES modules and CommonJS](https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs), but it also accepts options that allow: +> [!IMPORTANT] +> All parsing logic is applied under the assumption the code is in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) which [modules run under by default](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_classic_scripts). -- Converting `import`/`export` to `require`/`exports` -- Extensions to be updated in relative specifiers -- Write transformed source code to a filename +By default `@knighted/module` transforms the one-to-one [differences between ES modules and CommonJS](https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs). Options let you control syntax rewriting, specifier updates, and output. ## Requirements @@ -47,9 +46,8 @@ You can transform it to the equivalent CommonJS module import { transform } from '@knighted/module' await transform('./file.js', { - type: 'commonjs' - moduleLoading: true, - out: './file.cjs' + target: 'commonjs', + out: './file.cjs', }) ``` @@ -65,7 +63,10 @@ const { realpath } = require('node:fs/promises') const detectCalledFromCli = async path => { const realPath = await realpath(path) - if (require('node:url').pathToFileURL(__filename).toString() === pathToFileURL(realPath).href) { + if ( + require('node:url').pathToFileURL(__filename).toString() === + pathToFileURL(realPath).href + ) { console.log('invoked directly by node') } } @@ -84,18 +85,29 @@ invoked directly by node ```ts type ModuleOptions = { - /* What module system to convert to. */ - type?: 'module' | 'commonjs' - /* Whether import/export and require/exports should be transformed. */ - modules?: boolean - /* Whether to change specifier extensions to the assigned value. If omitted they are left alone. */ - specifier?: '.js' | '.mjs' | '.cjs' | '.ts' | '.mts' | '.cts' - /* What filepath to write the transformed source to. */ + target: 'module' | 'commonjs' + sourceType?: 'auto' | 'module' | 'commonjs' + transformSyntax?: boolean + liveBindings?: 'strict' | 'loose' | 'off' + rewriteSpecifier?: + | '.js' + | '.mjs' + | '.cjs' + | '.ts' + | '.mts' + | '.cts' + | ((value: string) => string | null | undefined) + dirFilename?: 'inject' | 'preserve' | 'error' + importMeta?: 'preserve' | 'shim' | 'error' + requireSource?: 'builtin' | 'create-require' + cjsDefault?: 'module-exports' | 'auto' | 'none' + topLevelAwait?: 'error' | 'wrap' | 'preserve' out?: string + inPlace?: boolean } ``` ## Roadmap -- Support option `modules`. - Remove `@knighted/specifier` and avoid double parsing. +- Flesh out live-binding and top-level await handling. diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index d2efb4e..0000000 --- a/eslint.config.js +++ /dev/null @@ -1,41 +0,0 @@ -import eslint from '@eslint/js' -import tseslint from 'typescript-eslint' -import nodePlugin from 'eslint-plugin-n' - -export default tseslint.config( - eslint.configs.recommended, - nodePlugin.configs['flat/recommended'], - ...tseslint.configs.recommended, - { - rules: { - 'no-console': 'error', - }, - }, - { - files: ['test/fixtures/**/*'], - rules: { - 'no-undef': 'off', - 'n/no-missing-import': 'off', - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/no-unused-expressions': 'off', - '@typescript-eslint/no-require-imports': 'off', - 'n/no-unsupported-features/node-builtins': [ - 'error', - { - ignores: ['import.meta.dirname', 'import.meta.filename'], - }, - ], - }, - }, - { - files: ['test/*.ts'], - rules: { - 'n/no-unsupported-features/node-builtins': [ - 'error', - { - ignores: ['test.describe', 'import.meta.dirname'], - }, - ], - }, - }, -) diff --git a/oxlint.json b/oxlint.json new file mode 100644 index 0000000..db79128 --- /dev/null +++ b/oxlint.json @@ -0,0 +1,30 @@ +{ + "ignorePatterns": ["dist/**", "coverage/**", "node_modules/**"], + "plugins": ["eslint", "typescript", "unicorn", "import", "oxc", "node"], + "rules": { + "no-console": "error", + "unicorn/filename-case": ["error", { "case": "camelCase" }], + "import/no-unused-modules": [ + "warn", + { "missingExports": true, "unusedExports": true } + ] + }, + "overrides": [ + { + "files": ["test/fixtures/**", "testing.*", "test/helpers/**"], + "rules": { + "no-unused-vars": "off", + "no-unused-expressions": "off", + "no-dupe-class-members": "off", + "no-useless-rename": "off", + "unicorn/no-empty-file": "off" + } + }, + { + "files": ["test/fixtures/identifiers/**"], + "rules": { + "no-unused-vars": "off" + } + } + ] +} diff --git a/package-lock.json b/package-lock.json index 0e800d4..0f9fd38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,37 +1,31 @@ { "name": "@knighted/module", - "version": "1.0.0-alpha.10", + "version": "1.0.0-beta.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@knighted/module", - "version": "1.0.0-alpha.10", + "version": "1.0.0-beta.0", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/traverse": "^7.28.0", - "@knighted/specifier": "^2.0.7", - "@knighted/walk": "^1.0.0", - "magic-string": "^0.30.10", - "node-module-type": "^1.0.2", - "oxc-parser": "^0.78.0" + "@knighted/specifier": "^2.0.9", + "magic-string": "^0.30.21", + "node-module-type": "^1.0.4", + "oxc-parser": "^0.105.0", + "periscopic": "^4.0.2" }, "devDependencies": { - "@babel/preset-env": "^7.28.0", - "@babel/preset-typescript": "^7.27.1", - "@babel/types": "^7.28.2", - "@eslint/js": "^9.39.1", - "@types/babel__traverse": "^7.20.7", + "@knighted/dump": "^1.0.3", "@types/node": "^22.13.17", "babel-dual-package": "^1.2.3", "c8": "^10.1.3", - "eslint": "^9.39.1", - "eslint-plugin-n": "^17.23.1", - "prettier": "^3.2.5", - "tsx": "^4.20.3", - "typescript": "^5.9.3", - "typescript-eslint": "^8.48.0" + "husky": "^9.1.7", + "lint-staged": "^16.2.7", + "oxlint": "^1.35.0", + "prettier": "^3.7.4", + "tsx": "^4.21.0", + "typescript": "^5.9.3" }, "engines": { "node": ">=20.11.0" @@ -41,6 +35,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -106,6 +101,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", @@ -237,6 +233,7 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -365,6 +362,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -374,6 +372,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -422,6 +421,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.5" @@ -1707,6 +1707,7 @@ "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -1721,6 +1722,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -1739,6 +1741,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -1759,20 +1762,20 @@ } }, "node_modules/@emnapi/core": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", - "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.0.4", + "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", - "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", "license": "MIT", "optional": true, "dependencies": { @@ -1780,9 +1783,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", - "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", "license": "MIT", "optional": true, "dependencies": { @@ -1790,9 +1793,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", "cpu": [ "ppc64" ], @@ -1807,9 +1810,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", "cpu": [ "arm" ], @@ -1824,9 +1827,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", "cpu": [ "arm64" ], @@ -1841,9 +1844,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", "cpu": [ "x64" ], @@ -1858,9 +1861,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", "cpu": [ "arm64" ], @@ -1875,9 +1878,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", "cpu": [ "x64" ], @@ -1892,9 +1895,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", "cpu": [ "arm64" ], @@ -1909,9 +1912,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", "cpu": [ "x64" ], @@ -1926,9 +1929,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", "cpu": [ "arm" ], @@ -1943,9 +1946,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", "cpu": [ "arm64" ], @@ -1960,9 +1963,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", "cpu": [ "ia32" ], @@ -1977,9 +1980,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", "cpu": [ "loong64" ], @@ -1994,9 +1997,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", "cpu": [ "mips64el" ], @@ -2011,9 +2014,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", "cpu": [ "ppc64" ], @@ -2028,9 +2031,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", "cpu": [ "riscv64" ], @@ -2045,9 +2048,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", "cpu": [ "s390x" ], @@ -2062,9 +2065,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", "cpu": [ "x64" ], @@ -2079,9 +2082,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", "cpu": [ "arm64" ], @@ -2096,9 +2099,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", "cpu": [ "x64" ], @@ -2113,9 +2116,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", "cpu": [ "arm64" ], @@ -2130,9 +2133,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", "cpu": [ "x64" ], @@ -2146,10 +2149,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", "cpu": [ "x64" ], @@ -2164,9 +2184,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", "cpu": [ "arm64" ], @@ -2181,9 +2201,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", "cpu": [ "ia32" ], @@ -2198,9 +2218,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", "cpu": [ "x64" ], @@ -2214,214 +2234,6 @@ "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", @@ -2506,6 +2318,7 @@ "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==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -2527,71 +2340,56 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "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", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@knighted/specifier": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@knighted/specifier/-/specifier-2.0.7.tgz", - "integrity": "sha512-M/cBnS9lgaxG8rjQ+oSaEqzGIhBoeIk1MiJldESbnEW/+ExdeMdTty2+X759Zg02FNgeHHfGXdangUwqJWvvMA==", + "node_modules/@knighted/dump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@knighted/dump/-/dump-1.0.3.tgz", + "integrity": "sha512-Q0vG/6Blsz/EezuiSoahJBx43OOqACM4iwM5yYYiFDoxShBctAsySIckpVEthGo/7+Veo1aETcr2EBNwFi4zhQ==", + "dev": true, "license": "MIT", - "dependencies": { - "@knighted/walk": "^1.0.0", - "magic-string": "^0.30.17", - "oxc-parser": "^0.78.0" - }, "engines": { - "node": ">=20" + "node": ">=12.20.0" } }, - "node_modules/@knighted/walk": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@knighted/walk/-/walk-1.0.0.tgz", - "integrity": "sha512-cBM9+XDBicWArHfD1rTFOo+2UYCE/wlla1BGwktGvKiq/2I7eSf7FdmM1MmbQCTameIP8rJaz0nDi1uLgBMqxw==", + "node_modules/@knighted/specifier": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@knighted/specifier/-/specifier-2.0.9.tgz", + "integrity": "sha512-r+g/NVHDKSUu4gQh72x6A8l3Qh3X3L0qpF9hd+SYrawfmzyaTyXH02n8lpl1PpaGwnmcJOU2q95sI0m/Ifppxg==", "license": "MIT", "dependencies": { - "estree-walker": "^3.0.3" + "@knighted/walk": "^1.0.1", + "magic-string": "^0.30.21", + "oxc-parser": "^0.99.0" }, "engines": { "node": ">=20" - }, - "peerDependencies": { - "oxc-parser": ">=0.61.2" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.1.tgz", - "integrity": "sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g==", - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.5", - "@emnapi/runtime": "^1.4.5", - "@tybys/wasm-util": "^0.10.0" - } - }, - "node_modules/@oxc-parser/binding-android-arm64": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.78.0.tgz", - "integrity": "sha512-Oh3e1KeD2RY0K/8EmDaCi8bUGxf+5PF2o1dEygyM2m5FXlxa8n5wtN39GUXRHMRCSk0Peg7tLgA/HFV8lBtlvg==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-android-arm64": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.99.0.tgz", + "integrity": "sha512-V4jhmKXgQQdRnm73F+r3ZY4pUEsijQeSraFeaCGng7abSNJGs76X6l82wHnmjLGFAeY00LWtjcELs7ZmbJ9+lA==", "cpu": [ "arm64" ], @@ -2601,13 +2399,13 @@ "android" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-darwin-arm64": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.78.0.tgz", - "integrity": "sha512-MdoPQhdKnQ5QZzws9hW4+Ew+59ftOUlQvOTDJ6HeVNxMU4+DBBOycFniRrqqhM1OUfrMjTtJ7kmx7Eoy4SvtWA==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-darwin-arm64": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.99.0.tgz", + "integrity": "sha512-Rp41nf9zD5FyLZciS9l1GfK8PhYqrD5kEGxyTOA2esTLeAy37rZxetG2E3xteEolAkeb2WDkVrlxPtibeAncMg==", "cpu": [ "arm64" ], @@ -2617,13 +2415,13 @@ "darwin" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-darwin-x64": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.78.0.tgz", - "integrity": "sha512-R7psaP7nmFA9KwdHv/ppdWVHsI6Eo6LeFxMmc7KKQEcKC0Po+PlgUosbcvJfLybFNLeAVLBVbMtCf0GhuvCdoQ==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-darwin-x64": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.99.0.tgz", + "integrity": "sha512-WVonp40fPPxo5Gs0POTI57iEFv485TvNKOHMwZRhigwZRhZY2accEAkYIhei9eswF4HN5B44Wybkz7Gd1Qr/5Q==", "cpu": [ "x64" ], @@ -2633,13 +2431,13 @@ "darwin" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-freebsd-x64": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.78.0.tgz", - "integrity": "sha512-EFva2L+0JdItSAQR3ESf06mt6gMUu0pX0NJ1WYUf171RMUxl4N6VD81UDmLt9SRVNaghF3J6MVtnLsTtMXZArg==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-freebsd-x64": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.99.0.tgz", + "integrity": "sha512-H30bjOOttPmG54gAqu6+HzbLEzuNOYO2jZYrIq4At+NtLJwvNhXz28Hf5iEAFZIH/4hMpLkM4VN7uc+5UlNW3Q==", "cpu": [ "x64" ], @@ -2649,29 +2447,13 @@ "freebsd" ], "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.78.0.tgz", - "integrity": "sha512-d4DgfgA4hw4WcMBWkHzZKZo8Wq4Nj2ANV645pyxW8kPfGC5yP5KA74gZcUAYlRzfNUZ51huIQbaHTb8EVibIhQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.78.0.tgz", - "integrity": "sha512-JVf1+9JMLCtRi6wguZ6ZA/xRBmJxE55FFBoshEpuFLCtT0UVNabjN55Wp3Wd09TDxXOZOxkjEzYGxek24vtazA==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.99.0.tgz", + "integrity": "sha512-0Z/Th0SYqzSRDPs6tk5lQdW0i73UCupnim3dgq2oW0//UdLonV/5wIZCArfKGC7w9y4h8TxgXpgtIyD1kKzzlQ==", "cpu": [ "arm" ], @@ -2681,13 +2463,13 @@ "linux" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-arm64-gnu": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.78.0.tgz", - "integrity": "sha512-YbXJzCfZ6Tyupe/z0+OerL65JY9KU069Yh0G4mGMVNr7taW2jtsuUiV6CWdgNpXnXJTgKopjyHvc0g9yQsG2Rg==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-linux-arm64-gnu": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.99.0.tgz", + "integrity": "sha512-u26I6LKoLTPTd4Fcpr0aoAtjnGf5/ulMllo+QUiBhupgbVCAlaj4RyXH/mvcjcsl2bVBv9E/gYJZz2JjxQWXBA==", "cpu": [ "arm64" ], @@ -2697,13 +2479,13 @@ "linux" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-arm64-musl": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.78.0.tgz", - "integrity": "sha512-VBdPB2N37A+M49zPV8ziiFywlgE3VX3AnR+zT1cIdQyKDoFM3uGPtjmtRe1qw6KhFF5YtxInzb0v3E3VkSdhuQ==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-linux-arm64-musl": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.99.0.tgz", + "integrity": "sha512-qhftDo2D37SqCEl3ZTa367NqWSZNb1Ddp34CTmShLKFrnKdNiUn55RdokLnHtf1AL5ssaQlYDwBECX7XiBWOhw==", "cpu": [ "arm64" ], @@ -2713,13 +2495,13 @@ "linux" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.78.0.tgz", - "integrity": "sha512-743OajvLP/fJm2d2da4/vqLMfki6XxfXizbUfPzEAXJMH0vEjf63s4gf55SBuy6hpmXOdCW5k4L6AoS+E89qtw==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-linux-riscv64-gnu": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.99.0.tgz", + "integrity": "sha512-zxn/xkf519f12FKkpL5XwJipsylfSSnm36h6c1zBDTz4fbIDMGyIhHfWfwM7uUmHo9Aqw1pLxFpY39Etv398+Q==", "cpu": [ "riscv64" ], @@ -2729,13 +2511,13 @@ "linux" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-s390x-gnu": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.78.0.tgz", - "integrity": "sha512-z3HVOr6F1PpKAxzwwG9NKfFmCCMMI8MbmxZ3l+UKKViFD9NlJYKx+Afye3SgHHTkYKEm3POgmmR4Aq3kKMP7sQ==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-linux-s390x-gnu": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.99.0.tgz", + "integrity": "sha512-Y1eSDKDS5E4IVC7Oxw+NbYAKRmJPMJTIjW+9xOWwteDHkFqpocKe0USxog+Q1uhzalD9M0p9eXWEWdGQCMDBMQ==", "cpu": [ "s390x" ], @@ -2745,13 +2527,13 @@ "linux" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-x64-gnu": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.78.0.tgz", - "integrity": "sha512-qJULpZeRsN0mfxasPh8EzzE7lsEEMEEtcprgw8QetB5l1Urz4gzKyeKdqs1vuxBl9o0s+WHSiowH2YqFMALs/g==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-linux-x64-gnu": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.99.0.tgz", + "integrity": "sha512-YVJMfk5cFWB8i2/nIrbk6n15bFkMHqWnMIWkVx7r2KwpTxHyFMfu2IpeVKo1ITDSmt5nBrGdLHD36QRlu2nDLg==", "cpu": [ "x64" ], @@ -2761,13 +2543,13 @@ "linux" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-linux-x64-musl": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.78.0.tgz", - "integrity": "sha512-ctEL662Oe9Gaqf/48lsVZzAMcAcXIWsddZy59kGH7592rJBaXxmQhkOnnVEeJF25k4JMbCCdYwGsgI7WtC+Fdg==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-linux-x64-musl": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.99.0.tgz", + "integrity": "sha512-2+SDPrie5f90A1b9EirtVggOgsqtsYU5raZwkDYKyS1uvJzjqHCDhG/f4TwQxHmIc5YkczdQfwvN91lwmjsKYQ==", "cpu": [ "x64" ], @@ -2777,29 +2559,29 @@ "linux" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-wasm32-wasi": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.78.0.tgz", - "integrity": "sha512-Pq0uT2CuN3J7Tv3KLuO7Sh4C7zTuqdJl0IDg3zB5keKx0BSbaEWewJL2CUNYUlG8txf+sMpUV+bkAIS5MEcKAw==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-wasm32-wasi": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.99.0.tgz", + "integrity": "sha512-DKA4j0QerUWSMADziLM5sAyM7V53Fj95CV9SjP77bPfEfT7MnvFKnneaRMqPK1cpzjAGiQF52OBUIKyk0dwOQA==", "cpu": [ "wasm32" ], "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^1.0.1" + "@napi-rs/wasm-runtime": "^1.0.7" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@oxc-parser/binding-win32-arm64-msvc": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.78.0.tgz", - "integrity": "sha512-OBsfQKaF+ckV792JP+jIRGuRhiRWHuu9xYHnLzOQj4TqurpbPWUXuMZ9mdpZ4pAT1OxmzzRV1hZPrL1e1ms9uA==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-win32-arm64-msvc": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.99.0.tgz", + "integrity": "sha512-EaB3AvsxqdNUhh9FOoAxRZ2L4PCRwDlDb//QXItwyOJrX7XS+uGK9B1KEUV4FZ/7rDhHsWieLt5e07wl2Ti5AQ==", "cpu": [ "arm64" ], @@ -2809,13 +2591,13 @@ "win32" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-parser/binding-win32-x64-msvc": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.78.0.tgz", - "integrity": "sha512-0XLQIzU16tnOu6zVrsWAL/kp8Onv0YCQPIwoTXonbhwbVp0rtgCOF4WsY6GKH45FqX9LwP+H8wOTtjyKYl3Zaw==", + "node_modules/@knighted/specifier/node_modules/@oxc-parser/binding-win32-x64-msvc": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.99.0.tgz", + "integrity": "sha512-sJN1Q8h7ggFOyDn0zsHaXbP/MklAVUvhrbq0LA46Qum686P3SZQHjbATqJn9yaVEvaSKXCshgl0vQ1gWkGgpcQ==", "cpu": [ "x64" ], @@ -2825,381 +2607,517 @@ "win32" ], "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@oxc-project/types": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.78.0.tgz", - "integrity": "sha512-8FvExh0WRWN1FoSTjah1xa9RlavZcJQ8/yxRbZ7ElmSa2Ij5f5Em7MvRbSthE6FbwC6Wh8iAw0Gpna7QdoqLGg==", + "node_modules/@knighted/specifier/node_modules/@oxc-project/types": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.99.0.tgz", + "integrity": "sha512-LLDEhXB7g1m5J+woRSgfKsFPS3LhR9xRhTeIoEBm5WrkwMxn6eZ0Ld0c0K5eHB57ChZX6I3uSmmLjZ8pcjlRcw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" } }, - "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==", - "dev": true, + "node_modules/@knighted/specifier/node_modules/oxc-parser": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.99.0.tgz", + "integrity": "sha512-MpS1lbd2vR0NZn1v0drpgu7RUFu3x9Rd0kxExObZc2+F+DIrV0BOMval/RO3BYGwssIOerII6iS8EbbpCCZQpQ==", "license": "MIT", - "optional": true, + "dependencies": { + "@oxc-project/types": "^0.99.0" + }, "engines": { - "node": ">=14" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-parser/binding-android-arm64": "0.99.0", + "@oxc-parser/binding-darwin-arm64": "0.99.0", + "@oxc-parser/binding-darwin-x64": "0.99.0", + "@oxc-parser/binding-freebsd-x64": "0.99.0", + "@oxc-parser/binding-linux-arm-gnueabihf": "0.99.0", + "@oxc-parser/binding-linux-arm-musleabihf": "0.99.0", + "@oxc-parser/binding-linux-arm64-gnu": "0.99.0", + "@oxc-parser/binding-linux-arm64-musl": "0.99.0", + "@oxc-parser/binding-linux-riscv64-gnu": "0.99.0", + "@oxc-parser/binding-linux-s390x-gnu": "0.99.0", + "@oxc-parser/binding-linux-x64-gnu": "0.99.0", + "@oxc-parser/binding-linux-x64-musl": "0.99.0", + "@oxc-parser/binding-wasm32-wasi": "0.99.0", + "@oxc-parser/binding-win32-arm64-msvc": "0.99.0", + "@oxc-parser/binding-win32-x64-msvc": "0.99.0" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", - "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "node_modules/@knighted/walk": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@knighted/walk/-/walk-1.0.1.tgz", + "integrity": "sha512-A/JHCHRK3e0gjqZcjoonZrdfQbMTrRg94ul5C0paYfsglPtJ9HdGm8iqZlgR0syzVBBaRdHc5HjgMhglZXta2w==", "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "estree-walker": "^3.0.3" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "oxc-parser": ">=0.61.2" } }, - "node_modules/@types/babel__traverse": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", - "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", - "dev": true, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.0.tgz", + "integrity": "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==", "license": "MIT", + "optional": true, "dependencies": { - "@babel/types": "^7.20.7" + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" } }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.13.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.17.tgz", - "integrity": "sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g==", - "dev": true, + "node_modules/@oxc-parser/binding-android-arm64": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.105.0.tgz", + "integrity": "sha512-YfphT1yP5Z2rsIAId4DeaumIqnBVwIyzjnGtb3scSBjIPclfhc6asu5ci0gPcXkfswzrPxNseZ0eWUaPBo1Cdg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "undici-types": "~6.20.0" + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true + "node_modules/@oxc-parser/binding-darwin-arm64": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.105.0.tgz", + "integrity": "sha512-uh1bxJT4lCU0IHkx6N8fgl9JBYlhWQDBZDpayn1ugtGW5rwB9M8dYMemeQoXJZiVxUun9SdDkBlrFv12EapwyA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.0.tgz", - "integrity": "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==", - "dev": true, + "node_modules/@oxc-parser/binding-darwin-x64": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.105.0.tgz", + "integrity": "sha512-/sqErZWA4/jLd4QYHRaNgn/kRyHodcLFTeNrkAqYxIDlgnNRI7vLeT1zAj4CH7FOiWCtlBZb1NpubjXOraKEKg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/type-utils": "8.48.0", - "@typescript-eslint/utils": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.48.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, + "node_modules/@oxc-parser/binding-freebsd-x64": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.105.0.tgz", + "integrity": "sha512-1QhbXXkkz7w+l+iftIbsjvLOLo1g0CQkIHWBLZcsmz8vEbbAOa4VODWTaof4VpvarbHzELs3MMKkPD48bvFmrA==", + "cpu": [ + "x64" + ], "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">= 4" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.0.tgz", - "integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.105.0.tgz", + "integrity": "sha512-VU6tqS8pJJsiYbf3cQ6yAgRLt+3R1FZgF5LkzM5OUm64d7z62UPgLwr+pUSHqtfRU8QnL7M3t+Qerw1t/odTSQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", - "debug": "^4.3.4" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.0.tgz", - "integrity": "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { + "version": "0.99.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.99.0.tgz", + "integrity": "sha512-xo0wqNd5bpbzQVNpAIFbHk1xa+SaS/FGBABCd942SRTnrpxl6GeDj/s1BFaGcTl8MlwlKVMwOcyKrw/2Kdfquw==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.48.0", - "@typescript-eslint/types": "^8.48.0", - "debug": "^4.3.4" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.0.tgz", - "integrity": "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-arm64-gnu": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.105.0.tgz", + "integrity": "sha512-qP7oLZal69E0HSE/jjOHMBpCLIwqXHej1pwIo07pthjhRe2YZb1NBDE+Lsxzd+gTvr7WmmA0X52Ce2fvrFZ8GA==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.0.tgz", - "integrity": "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-arm64-musl": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.105.0.tgz", + "integrity": "sha512-PoAvVQofT7j/zlWdERNYb2xQgsu5zLGDMJZKkghd2eNijnAhegswHSyO497u4Bm0mwGlnqpHDa8GQLTR08OIuA==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.0.tgz", - "integrity": "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.105.0.tgz", + "integrity": "sha512-dDhNsKFIqqyUFl+WSbStVueJDEVY5WYexJYHOSf3aDOhT4mxVVj+z0iKU0ZjSSWStepHXIgBD1F2E+m4pvPQZw==", + "cpu": [ + "riscv64" + ], "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.0.tgz", - "integrity": "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-s390x-gnu": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.105.0.tgz", + "integrity": "sha512-/6i8VVnMRU011EEH9FbQDvYFocDMlV/N7VDUEbaiCJqABH+bk6Mx5hMn1dMP1gfuF7wqpxPGejMzADXKvt6tnA==", + "cpu": [ + "s390x" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.0.tgz", - "integrity": "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-x64-gnu": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.105.0.tgz", + "integrity": "sha512-tv4ym2FmK4lUntG+fWFw0d/UuiGv05RGmyTnCLsP33CjjUyTl85QZSojxkoIPoy4DcxOddUkJkUQWHAw7tcCUQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.48.0", - "@typescript-eslint/tsconfig-utils": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", - "debug": "^4.3.4", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.1.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/typescript-estree/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==", - "dev": true, + "node_modules/@oxc-parser/binding-linux-x64-musl": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.105.0.tgz", + "integrity": "sha512-f8e3lsBaxV3E/MxgmA7Ghf8kGvA5yxvGrUAH+RO+28UbomFj/z1d8YiHVpk7Za/VhLXFW7HCxhAepY9xJdEZVA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", + "node_modules/@oxc-parser/binding-openharmony-arm64": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.105.0.tgz", + "integrity": "sha512-b1Y3qfgpf594Ro4N8UImobmKUq4GrkyXuNzs94V2P0u65qCVNeTsrvWpKtTdQltK1j+SvNQpisFbabYrxRI63A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-wasm32-wasi": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.105.0.tgz", + "integrity": "sha512-n4ybGB3b2Gttm6mVUYMoMI09ueK7CFLl1u4mQ0fzk6SAHUwbOmC+HHGb9tERSYVxw14uIrAn4Prk9yxriAyaRQ==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, "dependencies": { - "brace-expansion": "^2.0.1" + "@napi-rs/wasm-runtime": "^1.1.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-parser/binding-win32-arm64-msvc": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.105.0.tgz", + "integrity": "sha512-WtMhV8nLZi260FyZr21ukVa+IUCSGvQ+r6LAAHAzcGMgmXUp+NGBiySdgFmBExq8SVabGYeQ0OXFjL++DSfttQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-parser/binding-win32-x64-msvc": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.105.0.tgz", + "integrity": "sha512-ycJv2HahQRUxcSW/FeC5OFDw1yO2W2LVMCI8uwPhcGCuWIfuS+rDZWCOTarHCSdf3/sIxWjSYtSgEDFdxE61sw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.105.0.tgz", + "integrity": "sha512-KUZKnfZWMGI+7Dl0FoW574LI+xOkl2cvX5JKdnHH0VSKKqcft1UbthN1Mwa7VOwhNaqzKWUHnqC5MJhWgVJnYw==", + "license": "MIT", "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.0.tgz", - "integrity": "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==", + "node_modules/@oxlint/darwin-arm64": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-1.35.0.tgz", + "integrity": "sha512-ieiYVHkNZPo77Hgrxav595wGS4rRNKuDNrljf+4xhwpJsddrxMpM64IQUf2IvR3MhK4FxdGzhhB6OVmGVHY5/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/darwin-x64": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-1.35.0.tgz", + "integrity": "sha512-1jNHu3j66X5jKySvgtE+jGtjx4ye+xioAucVTi2IuROZO6keK2YG74pnD+9FT+DpWZAtWRZGoW0r0x6aN9sEEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint/linux-arm64-gnu": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-1.35.0.tgz", + "integrity": "sha512-T1lc0UaYbTxZyqVpLfC7eipbauNG8pBpkaZEW4JGz8Y68rxTH7d9s+CF0zxUxNr5RCtcmT669RLVjQT7VrKVLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-arm64-musl": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-1.35.0.tgz", + "integrity": "sha512-7Wv5Pke9kwWKFycUziSHsmi3EM0389TLzraB0KE/MArrKxx30ycwfJ5PYoMj9ERoW+Ybs0txdaOF/xJy/XyYkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-gnu": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-1.35.0.tgz", + "integrity": "sha512-HDMPOzyVVy+rQl3H7UOq8oGHt7m1yaiWCanlhAu4jciK8dvXeO9OG/OQd74lD/h05IcJh93pCLEJ3wWOG8hTiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-musl": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-1.35.0.tgz", + "integrity": "sha512-kAPBBsUOM3HQQ6n3nnZauvFR9EoXqCSoj4O3OSXXarzsRTiItNrHabVUwxeswZEc+xMzQNR0FHEWg/d4QAAWLw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/win32-arm64": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-1.35.0.tgz", + "integrity": "sha512-qrpBkkOASS0WT8ra9xmBRXOEliN6D/MV9JhI/68lFHrtLhfFuRwg4AjzjxrCWrQCnQ0WkvAVpJzu73F4ICLYZw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint/win32-x64": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-1.35.0.tgz", + "integrity": "sha512-yPFcj6umrhusnG/kMS5wh96vblsqZ0kArQJS+7kEOSJDrH+DsFWaDCsSRF8U6gmSmZJ26KVMU3C3TMpqDN4M1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "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==", "dev": true, "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0" - }, + "optional": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "node": ">=14" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.0.tgz", - "integrity": "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==", - "dev": true, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "license": "MIT", + "optional": true, "dependencies": { - "@typescript-eslint/types": "8.48.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "tslib": "^2.4.0" } }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/@types/node": { + "version": "22.13.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.17.tgz", + "integrity": "sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g==", "dev": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "undici-types": "~6.20.0" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", + "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { @@ -3226,13 +3144,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/babel-dual-package": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/babel-dual-package/-/babel-dual-package-1.2.3.tgz", @@ -3375,15 +3286,17 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/browserslist": { @@ -3454,16 +3367,6 @@ } } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001727", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", @@ -3485,20 +3388,83 @@ ], "license": "CC-BY-4.0" }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/cliui": { @@ -3570,13 +3536,23 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, "license": "MIT" }, + "node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3616,6 +3592,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3629,12 +3606,6 @@ } } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -3656,24 +3627,23 @@ "dev": true, "license": "MIT" }, - "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, "engines": { - "node": ">=10.13.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3684,31 +3654,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" } }, "node_modules/escalade": { @@ -3718,240 +3689,7 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", - "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.1", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-compat-utils": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", - "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-plugin-es-x": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", - "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/ota-meshi", - "https://opencollective.com/eslint" - ], - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.11.0", - "eslint-compat-utils": "^0.5.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": ">=8" - } - }, - "node_modules/eslint-plugin-n": { - "version": "17.23.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.23.1.tgz", - "integrity": "sha512-68PealUpYoHOBh332JLLD9Sj7OQUDkFpmcfqt8R9sySfFSeuGJjMTJQvCRRB96zO3A/PELRLkPrzsHmzEFQQ5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.5.0", - "enhanced-resolve": "^5.17.1", - "eslint-plugin-es-x": "^7.8.0", - "get-tsconfig": "^4.8.1", - "globals": "^15.11.0", - "globrex": "^0.1.2", - "ignore": "^5.3.2", - "semver": "^7.6.3", - "ts-declaration-location": "^1.0.6" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": ">=8.23.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" + "node": ">=6" } }, "node_modules/estree-walker": { @@ -3972,54 +3710,24 @@ "node": ">=0.10.0" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true, "license": "MIT" }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "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==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, "dependencies": { - "flat-cache": "^4.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=8" } }, "node_modules/find-up": { @@ -4050,25 +3758,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -4127,6 +3816,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-tsconfig": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", @@ -4161,18 +3863,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -4199,40 +3889,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true, - "license": "MIT" - }, - "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==", - "dev": true, - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4281,40 +3937,20 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", "dev": true, "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "bin": { + "husky": "bin.js" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" + "url": "https://github.com/sponsors/typicode" } }, "node_modules/index-to-position": { @@ -4345,15 +3981,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -4363,16 +3990,23 @@ "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "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==", "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=0.12.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" } }, "node_modules/isexe": { @@ -4437,25 +4071,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } + "license": "MIT" }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -4464,25 +4087,6 @@ "node": ">=6" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -4495,56 +4099,261 @@ "node": ">=6" } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "node_modules/lint-staged": { + "version": "16.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.7.tgz", + "integrity": "sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^14.0.2", + "listr2": "^9.0.5", + "micromatch": "^4.0.8", + "nano-spawn": "^2.0.0", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.8.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { - "json-buffer": "3.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, + "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^5.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4555,12 +4364,12 @@ } }, "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==", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/make-dir": { @@ -4578,17 +4387,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minipass": { @@ -4605,25 +4441,34 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "node_modules/nano-spawn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz", + "integrity": "sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" + } }, "node_modules/node-module-type": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/node-module-type/-/node-module-type-1.0.2.tgz", - "integrity": "sha512-5UZUtgz2txICZxHjwODRUzU316wFl8F9P1nU8ri7KwFW3FNCHVtXEeRed2CBdKyiijrNNl2hpoUSKtjXASn29w==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-module-type/-/node-module-type-1.0.4.tgz", + "integrity": "sha512-jJEWdpQFDFhjA87debF8AgaBXPkHyFCw/6atsRwOGu/bpVwje1ZAl8/0WuwxrYNRUdWQ5YNUOT0ARSZeqjFlGA==", "license": "MIT", "workspaces": [ + "test/ambiguous", "test/cjslib", "test/esmlib" ], "engines": { - "node": ">=20.11.0" + "node": ">=20.19.0" } }, "node_modules/node-releases": { @@ -4648,54 +4493,88 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, + "license": "MIT", "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/oxc-parser": { - "version": "0.78.0", - "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.78.0.tgz", - "integrity": "sha512-Kw6DlVJCG1HwArP3uF9kXc6nnAahpGaW7kZ7x1O7OugxbjSzkQqdKdA9loXCv7OeksFF/DfnLDupwqUjr1EOYQ==", + "version": "0.105.0", + "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.105.0.tgz", + "integrity": "sha512-9O+8zEIC/7Ly519wuKVAFHbcqeZxW8bOHXXE+BZYf8BA/J53SEJNvevMH3VI0ptrs4SMPAaxOW6K1jDJTSl0cg==", "license": "MIT", "peer": true, "dependencies": { - "@oxc-project/types": "^0.78.0" + "@oxc-project/types": "^0.105.0" }, "engines": { - "node": ">=20.0.0" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-parser/binding-android-arm64": "0.105.0", + "@oxc-parser/binding-darwin-arm64": "0.105.0", + "@oxc-parser/binding-darwin-x64": "0.105.0", + "@oxc-parser/binding-freebsd-x64": "0.105.0", + "@oxc-parser/binding-linux-arm-gnueabihf": "0.105.0", + "@oxc-parser/binding-linux-arm64-gnu": "0.105.0", + "@oxc-parser/binding-linux-arm64-musl": "0.105.0", + "@oxc-parser/binding-linux-riscv64-gnu": "0.105.0", + "@oxc-parser/binding-linux-s390x-gnu": "0.105.0", + "@oxc-parser/binding-linux-x64-gnu": "0.105.0", + "@oxc-parser/binding-linux-x64-musl": "0.105.0", + "@oxc-parser/binding-openharmony-arm64": "0.105.0", + "@oxc-parser/binding-wasm32-wasi": "0.105.0", + "@oxc-parser/binding-win32-arm64-msvc": "0.105.0", + "@oxc-parser/binding-win32-x64-msvc": "0.105.0" + } + }, + "node_modules/oxlint": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.35.0.tgz", + "integrity": "sha512-QDX1aUgaiqznkGfTM2qHwva2wtKqhVoqPSVXrnPz+yLUhlNadikD3QRuRtppHl7WGuy3wG6nKAuR8lash3aWSg==", + "dev": true, + "license": "MIT", + "bin": { + "oxc_language_server": "bin/oxc_language_server", + "oxlint": "bin/oxlint" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxc-parser/binding-android-arm64": "0.78.0", - "@oxc-parser/binding-darwin-arm64": "0.78.0", - "@oxc-parser/binding-darwin-x64": "0.78.0", - "@oxc-parser/binding-freebsd-x64": "0.78.0", - "@oxc-parser/binding-linux-arm-gnueabihf": "0.78.0", - "@oxc-parser/binding-linux-arm-musleabihf": "0.78.0", - "@oxc-parser/binding-linux-arm64-gnu": "0.78.0", - "@oxc-parser/binding-linux-arm64-musl": "0.78.0", - "@oxc-parser/binding-linux-riscv64-gnu": "0.78.0", - "@oxc-parser/binding-linux-s390x-gnu": "0.78.0", - "@oxc-parser/binding-linux-x64-gnu": "0.78.0", - "@oxc-parser/binding-linux-x64-musl": "0.78.0", - "@oxc-parser/binding-wasm32-wasi": "0.78.0", - "@oxc-parser/binding-win32-arm64-msvc": "0.78.0", - "@oxc-parser/binding-win32-x64-msvc": "0.78.0" + "@oxlint/darwin-arm64": "1.35.0", + "@oxlint/darwin-x64": "1.35.0", + "@oxlint/linux-arm64-gnu": "1.35.0", + "@oxlint/linux-arm64-musl": "1.35.0", + "@oxlint/linux-x64-gnu": "1.35.0", + "@oxlint/linux-x64-musl": "1.35.0", + "@oxlint/win32-arm64": "1.35.0", + "@oxlint/win32-x64": "1.35.0" + }, + "peerDependencies": { + "oxlint-tsgolint": ">=0.10.0" + }, + "peerDependenciesMeta": { + "oxlint-tsgolint": { + "optional": true + } } }, "node_modules/p-limit": { @@ -4735,19 +4614,6 @@ "dev": true, "license": "BlueOak-1.0.0" }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/parse-json": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", @@ -4814,39 +4680,43 @@ "dev": true, "license": "ISC" }, + "node_modules/periscopic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-4.0.2.tgz", + "integrity": "sha512-sqpQDUy8vgB7ycLkendSKS6HnVz1Rneoc3Rc+ZBUCe2pbqlVuCC5vF52l0NJ1aiMg/r1qfYF9/myz8CZeI2rjA==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "is-reference": "^3.0.2", + "zimmerframe": "^1.0.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, "license": "ISC" }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "bin": { + "pidtree": "bin/pidtree.js" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10" } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -4857,16 +4727,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/read-package-up": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", @@ -5004,16 +4864,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -5023,6 +4873,30 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -5069,6 +4943,52 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -5101,6 +5021,16 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -5197,19 +5127,6 @@ "node": ">=8" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5235,16 +5152,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", @@ -5286,57 +5193,17 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "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==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" + "is-number": "^7.0.0" }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/ts-declaration-location": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", - "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", - "dev": true, - "funding": [ - { - "type": "ko-fi", - "url": "https://ko-fi.com/rebeccastevens" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" - } - ], - "license": "BSD-3-Clause", - "dependencies": { - "picomatch": "^4.0.2" - }, - "peerDependencies": { - "typescript": ">=4.0.0" + "node": ">=8.0" } }, "node_modules/tslib": { @@ -5347,13 +5214,13 @@ "optional": true }, "node_modules/tsx": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz", - "integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.25.0", + "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -5366,18 +5233,6 @@ "fsevents": "~2.3.3" } }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/type-fest": { "version": "4.18.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.3.tgz", @@ -5405,30 +5260,6 @@ "node": ">=14.17" } }, - "node_modules/typescript-eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.48.0.tgz", - "integrity": "sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.48.0", - "@typescript-eslint/parser": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", @@ -5523,16 +5354,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -5572,15 +5393,6 @@ "node": ">= 8" } }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -5697,6 +5509,22 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -5755,6 +5583,12 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "license": "MIT" } } } diff --git a/package.json b/package.json index caaeac4..e18e427 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@knighted/module", - "version": "1.0.0-alpha.10", - "description": "Transforms module differences between ES and CommonJS.", + "version": "1.0.0-beta.0", + "description": "Transforms differences between ES modules and CommonJS.", "type": "module", "main": "dist/module.js", "exports": { @@ -18,13 +18,24 @@ }, "./package.json": "./package.json" }, + "imports": { + "#parse": "./src/parse.js", + "#format": "./src/format.js", + "#utils": "./src/utils.js", + "#walk": "./src/walk.js", + "#helpers/*": "./src/helpers/*.js", + "#formatters/*": "./src/formatters/*.js" + }, "engines": { "node": ">=20.11.0" }, "engineStrict": true, "scripts": { + "check-types": "tsc -p tsconfig.test.json", "prettier": "prettier -w .", - "lint": "eslint --ignore-pattern dist .", + "prettier:check": "prettier -c .", + "lint": "oxlint --config oxlint.json .", + "prepare": "husky install", "test": "c8 --reporter=text --reporter=text-summary --reporter=lcov tsx --test --test-reporter=spec test/*.ts", "build:types": "tsc --emitDeclarationOnly", "build:dual": "babel-dual-package src --extensions .ts", @@ -33,8 +44,14 @@ }, "keywords": [ "transform", - "esm", - "commonjs" + "es module", + "commonjs", + "require", + "require.resolve", + "import.meta.url", + "import.meta.dirname", + "__dirname", + "__filename" ], "files": [ "dist" @@ -49,34 +66,35 @@ "url": "https://github.com/knightedcodemonkey/module/issues" }, "devDependencies": { - "@babel/preset-env": "^7.28.0", - "@babel/preset-typescript": "^7.27.1", - "@babel/types": "^7.28.2", - "@eslint/js": "^9.39.1", - "@types/babel__traverse": "^7.20.7", + "@knighted/dump": "^1.0.3", "@types/node": "^22.13.17", "babel-dual-package": "^1.2.3", "c8": "^10.1.3", - "eslint": "^9.39.1", - "eslint-plugin-n": "^17.23.1", - "prettier": "^3.2.5", - "tsx": "^4.20.3", - "typescript": "^5.9.3", - "typescript-eslint": "^8.48.0" + "husky": "^9.1.7", + "lint-staged": "^16.2.7", + "oxlint": "^1.35.0", + "prettier": "^3.7.4", + "tsx": "^4.21.0", + "typescript": "^5.9.3" }, "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/traverse": "^7.28.0", - "@knighted/specifier": "^2.0.7", - "@knighted/walk": "^1.0.0", - "magic-string": "^0.30.10", - "node-module-type": "^1.0.2", - "oxc-parser": "^0.78.0" + "@knighted/specifier": "^2.0.9", + "magic-string": "^0.30.21", + "node-module-type": "^1.0.4", + "oxc-parser": "^0.105.0", + "periscopic": "^4.0.2" }, "prettier": { "arrowParens": "avoid", - "printWidth": 119, + "printWidth": 90, "semi": false, "singleQuote": true + }, + "lint-staged": { + "*.{js,ts,tsx,jsx,cjs,mjs}": [ + "prettier -c", + "oxlint --config oxlint.json" + ], + "*.{json,md,yml,yaml,css,scss,html}": "prettier -c" } } diff --git a/src/format.ts b/src/format.ts index a885eb3..41f5f44 100644 --- a/src/format.ts +++ b/src/format.ts @@ -1,43 +1,150 @@ +import type { ParseResult } from 'oxc-parser' +import type { FormatterOptions, ExportsMeta } from './types.js' import MagicString from 'magic-string' -import _traverse from '@babel/traverse' -import { moduleType } from 'node-module-type' - -import type { ParseResult } from '@babel/parser' -import type { File } from '@babel/types' -import type { FormatterOptions } from './types.js' import { identifier } from './formatters/identifier.js' import { metaProperty } from './formatters/metaProperty.js' import { memberExpression } from './formatters/memberExpression.js' - -/** - * Runtime hack to prevent issues with babel's default interop while dual building with tsc. - * @see https://github.com/babel/babel/discussions/13093#discussioncomment-12705927 - * Temporary fix until I switch to oxc-parser. - */ -const type = moduleType() -const traverse = ( - typeof _traverse === 'function' || type === 'commonjs' ? _traverse : _traverse.default -) as typeof _traverse.default +import { assignmentExpression } from './formatters/assignmentExpression.js' +import { isValidUrl, exportsRename, collectModuleIdentifiers } from './utils.js' +import { isIdentifierName } from './helpers/identifier.js' +import { ancestorWalk } from './walk.js' /** * Note, there is no specific conversion for `import.meta.main` as it does not exist. * @see https://github.com/nodejs/node/issues/49440 */ -export const format = (code: string, ast: ParseResult, options: FormatterOptions) => { - const src = new MagicString(code) +const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => { + const code = new MagicString(src) + const exportsMeta = { + hasExportsBeenReassigned: false, + defaultExportValue: undefined, + hasDefaultExportBeenReassigned: false, + hasDefaultExportBeenAssigned: false, + } satisfies ExportsMeta + await collectModuleIdentifiers(ast.program) - traverse(ast, { - Identifier(path) { - identifier(path, src, options) - }, - MetaProperty(path) { - metaProperty(path, src, options) - }, - MemberExpression(path) { - memberExpression(path, src, options) + if (opts.target === 'module' && opts.transformSyntax) { + /** + * Prepare ESM output by renaming `exports` to `__exports` and seeding an + * `import.meta.filename` touch so import.meta is present even when the + * original source never referenced it. + */ + code.prepend(`let ${exportsRename} = {}; +void import.meta.filename; +`) + } + + await ancestorWalk(ast.program, { + async enter(node, ancestors) { + const parent = ancestors[ancestors.length - 2] ?? null + + if ( + node.type === 'FunctionDeclaration' || + node.type === 'FunctionExpression' || + node.type === 'ArrowFunctionExpression' + ) { + const skipped = ['__filename', '__dirname'] + const skippedParams = node.params.filter( + param => param.type === 'Identifier' && skipped.includes(param.name), + ) + const skippedFuncIdentifier = + node.id?.type === 'Identifier' && skipped.includes(node.id.name) + + if (skippedParams.length || skippedFuncIdentifier) { + this.skip() + } + } + + /** + * Check for assignment to `import.meta.url`. + */ + if ( + node.type === 'AssignmentExpression' && + node.left.type === 'MemberExpression' && + node.left.object.type === 'MetaProperty' && + node.left.property.type === 'Identifier' && + node.left.property.name === 'url' + ) { + if (node.right.type === 'Literal' && typeof node.right.value === 'string') { + if (!isValidUrl(node.right.value)) { + const rhs = code.snip(node.right.start, node.right.end).toString() + const assignment = code.snip(node.start, node.end).toString() + + code.update( + node.start, + node.end, + `/* Invalid assignment: ${rhs} is not a URL. ${assignment} */`, + ) + this.skip() + } + } + } + + /** + * Skip module scope CJS globals when they are object properties. + * Ignoring `exports` here. + */ + if ( + node.type === 'MemberExpression' && + node.property.type === 'Identifier' && + ['__filename', '__dirname'].includes(node.property.name) + ) { + this.skip() + } + + /** + * Check for bare `module.exports` expressions. + */ + if ( + node.type === 'MemberExpression' && + node.object.type === 'Identifier' && + node.object.name === 'module' && + node.property.type === 'Identifier' && + node.property.name === 'exports' && + parent?.type === 'ExpressionStatement' + ) { + if (opts.target === 'module') { + code.update(node.start, node.end, ';') + // Prevent parsing the `exports` identifier again. + this.skip() + } + } + + /** + * Format `module.exports` and `exports` assignments. + */ + if (node.type === 'AssignmentExpression') { + await assignmentExpression({ + node, + parent, + code, + opts, + meta: exportsMeta, + }) + } + + if (node.type === 'MetaProperty') { + metaProperty(node, parent, code, opts) + } + + if (node.type === 'MemberExpression') { + memberExpression(node, parent, code, opts) + } + + if (isIdentifierName(node)) { + identifier({ + node, + ancestors, + code, + opts, + meta: exportsMeta, + }) + } }, }) - return src + return code.toString() } + +export { format } diff --git a/src/formatters/assignmentExpression.ts b/src/formatters/assignmentExpression.ts new file mode 100644 index 0000000..65c33a9 --- /dev/null +++ b/src/formatters/assignmentExpression.ts @@ -0,0 +1,43 @@ +import MagicString from 'magic-string' +import type { Node, AssignmentExpression } from 'oxc-parser' +import { walk } from '../walk.js' + +import type { FormatterOptions, ExportsMeta } from '../types.js' + +type AssignmentExpressionArg = { + node: AssignmentExpression + parent: Node | null + code: MagicString + opts: FormatterOptions + meta: ExportsMeta +} + +export const assignmentExpression = async ({ + node, + parent: _parent, + code: _code, + opts, + meta: _meta, +}: AssignmentExpressionArg) => { + if (opts.target === 'module' && opts.transformSyntax) { + await walk(node, { + enter(childNode, childParent) { + if (childNode.type === 'Identifier' && childNode.name === 'exports') { + if (childParent === node && node.left === childNode) { + /** + * The code is reassigning `exports` to something else. + * Redeclare it with a new variable name using var. + */ + //meta.hasExportsBeenReassigned = true + //console.log('writing exports reassignment') + //code.update(node.left.start, node.left.end, exportsRename) + //console.log(code.slice(node.start, node.end)) + //code.update(childNode.start, childNode.end, exportsRename) + //console.log('reassigning exports', childParent, code.update(node.left.start, node.left.end, exportsRename)) + } + //console.log('found exports assignment', meta.hasExportsBeenReassigned, expr) + } + }, + }) + } +} diff --git a/src/formatters/expressionStatement.ts b/src/formatters/expressionStatement.ts index 4d592bd..b78e405 100644 --- a/src/formatters/expressionStatement.ts +++ b/src/formatters/expressionStatement.ts @@ -1,72 +1,48 @@ import MagicString from 'magic-string' +import type { Node, ExpressionStatement } from 'oxc-parser' -import type { NodePath } from '@babel/traverse' -import type { ExpressionStatement, MemberExpression } from '@babel/types' import type { FormatterOptions } from '../types.js' export const expressionStatement = ( - nodePath: NodePath, + node: ExpressionStatement, + parent: Node | null, src: MagicString, options: FormatterOptions, ) => { - if (options.type === 'module') { - const { node } = nodePath - const { start, end } = node - - if (typeof start === 'number' && typeof end === 'number') { - const isMemberExpressionModuleExports = (expression: MemberExpression) => { - return ( - expression.object.type === 'Identifier' && - expression.object.name === 'module' && - expression.property.type === 'Identifier' && - expression.property.name === 'exports' - ) - } - - if (node.expression.type === 'Identifier') { - const name = node.expression.name - - // CommonJS globals - switch (name) { - case 'module': - src.update(start, end, 'import.meta') - break - case 'exports': - src.update(start, end, '{}') - break - case '__filename': - src.update(start, end, 'import.meta.filename') - break - case '__dirname': - src.update(start, end, 'import.meta.dirname') - break - } - } - - if (node.expression.type === 'MemberExpression') { - const { expression } = node - - // Check for `module.exports` without an assignment - if (isMemberExpressionModuleExports(expression)) { - /** - * @TODO: Should this depend on `options.modules` being enabled? - * Probably not for the same reason `exports` is converted to an empty object (ReferenceError in ESM). - * This is a standalone reference to `module.exports` without being part of an AssignmentExpression. - */ + if (options.target === 'module') { + if (node.expression.type === 'Identifier') { + const { start, end } = node + const name = node.expression.name + + // CommonJS globals (as bare identifiers) + switch (name) { + case 'require': + src.remove(start, end) + break + case 'module': + src.update(start, end, 'import.meta') + break + case 'exports': src.update(start, end, '{}') - } + break + case '__filename': + src.update(start, end, 'import.meta.filename') + break + case '__dirname': + src.update(start, end, 'import.meta.dirname') + break } + } + } - /* - if ( - options.modules && - node.expression.type === 'AssignmentExpression' && - node.expression.left.type === 'MemberExpression' && - isMemberExpressionModuleExports(node.expression.left) - ) { - // @TODO support `modules` option. - } - */ + if (options.target === 'commonjs') { + if (node.expression.type === 'Identifier') { + const { start, end } = node + const name = node.expression.name + + void start + void end + void name } } } diff --git a/src/formatters/identifier.ts b/src/formatters/identifier.ts index 75c9871..fb59679 100644 --- a/src/formatters/identifier.ts +++ b/src/formatters/identifier.ts @@ -1,39 +1,56 @@ import MagicString from 'magic-string' +import type { Node, IdentifierName } from 'oxc-parser' -import type { NodePath } from '@babel/traverse' -import type { Identifier } from '@babel/types' -import type { FormatterOptions } from '../types.js' +import type { FormatterOptions, ExportsMeta } from '../types.js' +import { exportsRename } from '../utils.js' +import { identifier as ident } from '../helpers/identifier.js' -export const identifier = (nodePath: NodePath, src: MagicString, options: FormatterOptions) => { - if (options.type === 'module') { - const { node } = nodePath - const { start, end } = node +type IdentifierArg = { + node: IdentifierName + ancestors: Node[] + code: MagicString + opts: FormatterOptions + meta: ExportsMeta +} - if (typeof start === 'number' && typeof end === 'number' && node.type === 'Identifier') { - const { name } = node - const isMemberExpression = Boolean(nodePath.findParent(path => path.isMemberExpression())) +export const identifier = ({ node, ancestors, code, opts, meta }: IdentifierArg) => { + if (opts.target === 'module') { + const { start, end, name } = node - // CommonJS globals in expression/statement - switch (name) { - case 'module': { - if (!isMemberExpression) { - src.update(start, end, 'import.meta') - } - break - } - case 'exports': { - if (!isMemberExpression) { - src.update(start, end, '{}') + switch (name) { + case '__filename': + code.update(start, end, 'import.meta.url') + break + case '__dirname': + code.update(start, end, 'import.meta.dirname') + break + case 'exports': + { + const parent = ancestors[ancestors.length - 2] + + if (opts.transformSyntax) { + if (parent.type === 'AssignmentExpression' && parent.left === node) { + // The code is reassigning `exports` to something else. + + meta.hasExportsBeenReassigned = true + code.update(parent.left.start, parent.left.end, exportsRename) + } + + if ( + ident.isModuleScope(ancestors) && + !ident.isFunctionExpressionId(ancestors) && + !ident.isExportSpecifierAlias(ancestors) && + !ident.isClassPropertyKey(ancestors) && + !ident.isMethodDefinitionKey(ancestors) && + !ident.isMemberKey(ancestors) && + !ident.isPropertyKey(ancestors) && + !ident.isIife(ancestors) + ) { + code.update(start, end, exportsRename) + } } - break } - case '__filename': - src.update(start, end, 'import.meta.filename') - break - case '__dirname': - src.update(start, end, 'import.meta.dirname') - break - } + break } } } diff --git a/src/formatters/memberExpression.ts b/src/formatters/memberExpression.ts index ce71929..c2908e8 100644 --- a/src/formatters/memberExpression.ts +++ b/src/formatters/memberExpression.ts @@ -1,31 +1,50 @@ import MagicString from 'magic-string' +import type { MemberExpression, Node } from 'oxc-parser' -import type { NodePath } from '@babel/traverse' -import type { MemberExpression } from '@babel/types' import type { FormatterOptions } from '../types.js' +import { exportsRename } from '../utils.js' export const memberExpression = ( - nodePath: NodePath, + node: MemberExpression, + parent: Node | null, src: MagicString, options: FormatterOptions, ) => { - if (options.type === 'module') { - const { node } = nodePath - const { start, end } = node + if (options.target === 'module') { + if ( + node.object.type === 'Identifier' && + node.property.type === 'Identifier' && + node.object.name === 'module' && + node.property.name === 'exports' + ) { + src.update(node.start, node.end, exportsRename) + return + } if ( - typeof start === 'number' && - typeof end === 'number' && node.object.type === 'Identifier' && - node.object.name === 'require' && - node.property.type === 'Identifier' + node.property.type === 'Identifier' && + node.object.name === 'require' ) { + const { start, end } = node const { name } = node.property // CommonJS properties of `require` switch (name) { case 'main': - src.update(start, end, 'import.meta') + /** + * Node.js team still quibbling over import.meta.main ¯\_(ツ)_/¯ + * @see https://github.com/nodejs/node/pull/32223 + */ + if (parent?.type === 'ExpressionStatement') { + // This is a standalone expression so remove it to not cause run-time errors. + src.remove(start, end) + } + /** + * Transform require.main === module. + */ + if (parent?.type === 'BinaryExpression') { + } break case 'resolve': src.update(start, end, 'import.meta.resolve') diff --git a/src/formatters/metaProperty.ts b/src/formatters/metaProperty.ts index 54342b4..17d8c5a 100644 --- a/src/formatters/metaProperty.ts +++ b/src/formatters/metaProperty.ts @@ -1,52 +1,43 @@ import MagicString from 'magic-string' +import type { Node, MetaProperty } from 'oxc-parser' -import type { NodePath } from '@babel/traverse' -import type { MetaProperty } from '@babel/types' import type { FormatterOptions } from '../types.js' -export const metaProperty = (nodePath: NodePath, src: MagicString, options: FormatterOptions) => { - if (options.type === 'commonjs') { - const path = nodePath.findParent(path => path.isMemberExpression()) - - if (path) { - const { node } = path +export const metaProperty = ( + node: MetaProperty, + parent: Node | null, + src: MagicString, + options: FormatterOptions, +) => { + if (options.target === 'commonjs') { + if (parent?.type !== 'MemberExpression') { + // This is a bare `import.meta` expression const { start, end } = node - if ( - node.type === 'MemberExpression' && - node.property.type === 'Identifier' && - typeof start == 'number' && - typeof end === 'number' - ) { - const name = node.property.name - - switch (name) { - case 'url': - src.update(start, end, 'require("node:url").pathToFileURL(__filename).toString()') - break - case 'filename': - src.update(start, end, '__filename') - break - case 'dirname': - src.update(start, end, '__dirname') - break - case 'resolve': - src.update(start, end, 'require.resolve') - break - } - } - } else { - const { node } = nodePath - const { start, end } = node + src.update(start, end, 'module') + } - if ( - node.property.type === 'Identifier' && - node.property.name === 'meta' && - typeof start === 'number' && - typeof end === 'number' - ) { - // This is an `import.meta` expression - src.update(start, end, 'require.main') + if (parent?.type === 'MemberExpression' && parent.property.type === 'Identifier') { + switch (parent.property.name) { + case 'url': + src.update( + parent.start, + parent.end, + 'require("node:url").pathToFileURL(__filename).href', + ) + break + case 'filename': + src.update(parent.start, parent.end, '__filename') + break + case 'dirname': + src.update(parent.start, parent.end, '__dirname') + break + case 'resolve': + /** + * Should this be `require('node:url').pathToFileURL(require.resolve()).href`? + */ + src.update(parent.start, parent.end, 'require.resolve') + break } } } diff --git a/src/helpers/identifier.ts b/src/helpers/identifier.ts new file mode 100644 index 0000000..f08e67d --- /dev/null +++ b/src/helpers/identifier.ts @@ -0,0 +1,208 @@ +import type { Node, IdentifierName } from 'oxc-parser' +import { analyze, type Scope as PeriscopicScope } from 'periscopic' + +/** + * Focus exclusively on IdentifierName type as it has the name property, + * which is what the identifer utilities are interested in. + * + * Explicitly ignore the TSThisParameter type as it is not a valid identifier name. + */ +const isIdentifierName = (node: Node): node is IdentifierName => { + return ( + node.type === 'Identifier' && typeof node.name === 'string' && node.name !== 'this' + ) +} + +type ScopeContext = { + scope: PeriscopicScope +} + +const scopeCache = new WeakMap() + +const getScopeContext = (program: Node): ScopeContext => { + const cached = scopeCache.get(program) + + if (cached) { + return cached + } + + const { scope } = analyze(program as any) + const context = { scope } + scopeCache.set(program, context) + return context +} + +/** + * All methods receive the full set of ancestors, which + * specifically includes the node itself as the last element. + * The second to last element is the parent node, and so on. + * The first element is the root node. + */ +const identifier = { + isNamed: (node: Node): node is IdentifierName => { + return isIdentifierName(node) + }, + isMetaProperty(ancestors: Node[]) { + const parent = ancestors[ancestors.length - 2] + + return ( + parent.type === 'MetaProperty' || + (parent.type === 'MemberExpression' && parent.object.type === 'MetaProperty') + ) + }, + isModuleScope(ancestors: Node[], includeImports = false) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + const program = ancestors[0] + + if ( + !identifier.isNamed(node) || + identifier.isMetaProperty(ancestors) || + parent.type === 'LabeledStatement' || + parent.type === 'BreakStatement' || + parent.type === 'ContinueStatement' + ) { + return false + } + + if ( + parent.type === 'ImportSpecifier' || + parent.type === 'ImportDefaultSpecifier' || + parent.type === 'ImportNamespaceSpecifier' + ) { + return includeImports && parent.local.name === node.name + } + + if (parent.type === 'Property' && parent.key === node && !parent.computed) { + return false + } + + if ( + parent.type === 'MemberExpression' && + parent.property === node && + !parent.computed + ) { + return false + } + + const { scope: rootScope } = getScopeContext(program) + const owner = rootScope.find_owner(node.name) + + if (!owner) { + return node.name === 'exports' + } + + return owner === rootScope + }, + + isMemberExpressionRoot(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + const grandParent = ancestors[ancestors.length - 3] + + return ( + parent.type === 'MemberExpression' && + parent.object === node && + grandParent.type !== 'MemberExpression' + ) + }, + + isDeclaration(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return ( + (parent.type === 'VariableDeclarator' || + parent.type === 'FunctionDeclaration' || + parent.type === 'ClassDeclaration') && + parent.id === node + ) + }, + + isClassOrFuncDeclarationId(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return ( + (parent.type === 'ClassDeclaration' || parent.type === 'FunctionDeclaration') && + parent.id === node && + ancestors.length <= 3 + ) + }, + + isVarDeclarationInGlobalScope(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + const grandParent = ancestors[ancestors.length - 3] + const varBoundScopes = [ + 'ClassDeclaration', + 'ClassExpression', + 'FunctionDeclaration', + 'FunctionExpression', + 'ArrowFunctionExpression', + ] + + return ( + parent.type === 'VariableDeclarator' && + parent.id === node && + grandParent.type === 'VariableDeclaration' && + grandParent.kind === 'var' && + ancestors.every(ancestor => { + return !varBoundScopes.includes(ancestor.type) + }) + ) + }, + + isIife(ancestors: Node[]) { + const parent = ancestors[ancestors.length - 2] + + return ( + parent.type === 'FunctionExpression' && + ancestors.some(ancestor => ancestor.type === 'ParenthesizedExpression') + ) + }, + + isFunctionExpressionId(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return parent.type === 'FunctionExpression' && parent.id === node + }, + + isExportSpecifierAlias(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return parent.type === 'ExportSpecifier' && parent.exported === node + }, + + isClassPropertyKey(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return parent.type === 'PropertyDefinition' && parent.key === node + }, + + isMethodDefinitionKey(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return parent.type === 'MethodDefinition' && parent.key === node + }, + + isMemberKey(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return parent.type === 'MemberExpression' && parent.property === node + }, + + isPropertyKey(ancestors: Node[]) { + const node = ancestors[ancestors.length - 1] + const parent = ancestors[ancestors.length - 2] + + return parent.type === 'Property' && parent.key === node + }, +} + +export { identifier, isIdentifierName } diff --git a/src/helpers/scope.ts b/src/helpers/scope.ts new file mode 100644 index 0000000..013008e --- /dev/null +++ b/src/helpers/scope.ts @@ -0,0 +1,20 @@ +import type { Node } from 'oxc-parser' + +const scopes = [ + 'BlockStatement', + 'FunctionDeclaration', + 'FunctionExpression', + 'ArrowFunctionExpression', + 'ClassDeclaration', + 'ClassExpression', + 'ClassBody', + 'StaticBlock', +] + +const scope = { + isScope(node: Node) { + return scopes.includes(node.type) + }, +} + +export { scopes, scope } diff --git a/src/module.ts b/src/module.ts index dfb35c3..7bfbb42 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,63 +1,64 @@ -import { resolve, extname } from 'node:path' +import { resolve } from 'node:path' import { readFile, writeFile } from 'node:fs/promises' -import { specifier, type Specifier } from '@knighted/specifier' +import { specifier } from '@knighted/specifier' import { parse } from './parse.js' import { format } from './format.js' +import { getLangFromExt } from './utils.js' import type { ModuleOptions } from './types.js' const defaultOptions = { - type: 'commonjs', + target: 'commonjs', + sourceType: 'auto', + transformSyntax: true, + liveBindings: 'strict', + rewriteSpecifier: undefined, + dirFilename: 'inject', + importMeta: 'shim', + requireSource: 'builtin', + cjsDefault: 'auto', + topLevelAwait: 'error', out: undefined, - modules: false, - specifier: undefined, + inPlace: false, } satisfies ModuleOptions - -type UpdateSrcLang = Parameters[1] -const getLangFromExt = (filename: string): UpdateSrcLang => { - const ext = extname(filename) - - if (/\.js$/.test(ext)) { - return 'js' - } - - if (/\.ts$/.test(ext)) { - return 'ts' - } - - if (ext === '.tsx') { - return 'tsx' - } - - if (ext === '.jsx') { - return 'jsx' - } -} const transform = async (filename: string, options: ModuleOptions = defaultOptions) => { const opts = { ...defaultOptions, ...options } const file = resolve(filename) const code = (await readFile(file)).toString() - const ast = parse(code) - let source = format(code, ast, opts).toString() + const ast = parse(filename, code) + let source = await format(code, ast, opts) + + if (opts.rewriteSpecifier) { + const code = await specifier.updateSrc( + source, + getLangFromExt(filename), + ({ value }) => { + if (typeof opts.rewriteSpecifier === 'function') { + return opts.rewriteSpecifier(value) ?? undefined + } - if (options.specifier) { - const code = await specifier.updateSrc(source, getLangFromExt(filename), ({ value }) => { - // Collapse any BinaryExpression or NewExpression to test for a relative specifier - const collapsed = value.replace(/['"`+)\s]|new String\(/g, '') - const relative = /^(?:\.|\.\.)\// + // Collapse any BinaryExpression or NewExpression to test for a relative specifier + const collapsed = value.replace(/['"`+)\s]|new String\(/g, '') + const relative = /^(?:\.|\.\.)\// - if (relative.test(collapsed)) { - // $2 is for any closing quotation/parens around BE or NE - return value.replace(/(.+)\.(?:m|c)?(?:j|t)s([)'"`]*)?$/, `$1${options.specifier}$2`) - } - }) + if (relative.test(collapsed)) { + // $2 is for any closing quotation/parens around BE or NE + return value.replace( + /(.+)\.(?:m|c)?(?:j|t)s([)'"]*)?$/, + `$1${opts.rewriteSpecifier}$2`, + ) + } + }, + ) source = code } - if (opts.out) { - await writeFile(resolve(opts.out), source) + const outputPath = opts.inPlace ? file : opts.out ? resolve(opts.out) : undefined + + if (outputPath) { + await writeFile(outputPath, source) } return source diff --git a/src/parse.ts b/src/parse.ts index d9490b0..f826cc1 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,15 +1,7 @@ -import { parse as babelParse } from '@babel/parser' +import { parseSync } from 'oxc-parser' -const parse = (source: string, dts = false) => { - const ast = babelParse(source, { - sourceType: 'module', - allowAwaitOutsideFunction: true, - allowReturnOutsideFunction: true, - allowImportExportEverywhere: true, - plugins: ['jsx', ['importAttributes', { deprecatedAssertSyntax: true }], ['typescript', { dts }]], - }) - - return ast +const parse = (filename: string, code: string) => { + return parseSync(filename, code) } export { parse } diff --git a/src/types.ts b/src/types.ts index babef9a..0a7a551 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,12 +1,66 @@ +import type { + Node, + Span, + IdentifierName, + IdentifierReference, + BindingIdentifier, + LabelIdentifier, + TSIndexSignatureName, +} from 'oxc-parser' + +export type RewriteSpecifier = + | '.js' + | '.mjs' + | '.cjs' + | '.ts' + | '.mts' + | '.cts' + | ((value: string) => string | null | undefined) + export type ModuleOptions = { - /* What module system to convert to. */ - type?: 'module' | 'commonjs' - /* Whether import/export and require/exports should be transformed. */ - modules?: boolean - /* Whether to change specifier extensions to the assigned value. If omitted they are left alone. */ - specifier?: '.js' | '.mjs' | '.cjs' | '.ts' | '.mts' | '.cts' - /* What filepath to write the transformed source to. */ + target: 'module' | 'commonjs' + sourceType?: 'auto' | 'module' | 'commonjs' + transformSyntax?: boolean + liveBindings?: 'strict' | 'loose' | 'off' + rewriteSpecifier?: RewriteSpecifier + dirFilename?: 'inject' | 'preserve' | 'error' + importMeta?: 'preserve' | 'shim' | 'error' + requireSource?: 'builtin' | 'create-require' + cjsDefault?: 'module-exports' | 'auto' | 'none' + topLevelAwait?: 'error' | 'wrap' | 'preserve' out?: string + inPlace?: boolean +} + +export type SpannedNode = Node & Span + +export type ExportsMeta = { + hasExportsBeenReassigned: boolean + hasDefaultExportBeenReassigned: boolean + hasDefaultExportBeenAssigned: boolean + defaultExportValue: unknown } -export type FormatterOptions = Omit & Required> +export type IdentMeta = { + /* + `var` can be redeclared in the same scope. + */ + declare: SpannedNode[] + read: SpannedNode[] +} + +export type Scope = { + type: string + name: string + node: Node + idents: Set +} + +export type FormatterOptions = Omit + +export type Identifier = + | IdentifierName + | IdentifierReference + | BindingIdentifier + | LabelIdentifier + | TSIndexSignatureName diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..6bc7b45 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,251 @@ +import { extname } from 'node:path' +import { ancestorWalk } from './walk.js' + +import type { Node } from 'oxc-parser' +import type { Specifier } from '@knighted/specifier' + +import type { IdentMeta, SpannedNode, Scope } from './types.js' +import { scopes as scopeNodes } from './helpers/scope.js' +import { identifier } from './helpers/identifier.js' + +type UpdateSrcLang = Parameters[1] +const getLangFromExt = (filename: string): UpdateSrcLang => { + const ext = extname(filename) + + if (ext.endsWith('.js')) { + return 'js' + } + + if (ext.endsWith('.ts')) { + return 'ts' + } + + if (ext === '.tsx') { + return 'tsx' + } + + if (ext === '.jsx') { + return 'jsx' + } +} +const isValidUrl = (url: string) => { + try { + new URL(url) + return true + } catch { + return false + } +} +const exportsRename = '__exports' +const requireMainRgx = /(require\.main\s*===\s*module|module\s*===\s*require\.main)/g + +const collectScopeIdentifiers = (node: Node, scopes: Scope[]) => { + const { type } = node + + switch (type) { + case 'BlockStatement': + case 'ClassBody': + scopes.push({ node, type: 'Block', name: type, idents: new Set() }) + break + case 'FunctionDeclaration': + case 'FunctionExpression': + case 'ArrowFunctionExpression': + { + const name = node.id ? node.id.name : 'anonymous' + const scope = { node, name, type: 'Function', idents: new Set() } + + node.params + .map(param => { + if (param.type === 'TSParameterProperty') { + return param.parameter + } + + if (param.type === 'RestElement') { + return param.argument + } + + if (param.type === 'AssignmentPattern') { + return param.left + } + + return param + }) + .filter(identifier.isNamed) + .forEach(param => { + scope.idents.add(param.name) + }) + + /** + * If a FunctionExpression has an id, it is a named function expression. + * The function expression name shadows the module scope identifier, so + * we don't want to count reads of module identifers that have the same name. + * They also do not cause a SyntaxError if the function expression name is + * the same as a module scope identifier. + * + * TODO: Is this necessary for FunctionDeclaration? + */ + if (node.type === 'FunctionExpression' && node.id) { + scope.idents.add(node.id.name) + } + + // First add the function to any previous scopes + if (scopes.length > 0) { + scopes[scopes.length - 1].idents.add(name) + } + + // Then add the function scope to the scopes stack + scopes.push(scope) + } + break + case 'ClassDeclaration': + { + const className = node.id ? node.id.name : 'anonymous' + + // First add the class to any previous scopes + if (scopes.length > 0) { + scopes[scopes.length - 1].idents.add(className) + } + + // Then add the class to the scopes stack + scopes.push({ node, name: className, type: 'Class', idents: new Set() }) + } + break + case 'ClassExpression': + { + } + break + case 'VariableDeclaration': + if (scopes.length > 0) { + const scope = scopes[scopes.length - 1] + + node.declarations.forEach(decl => { + if (decl.type === 'VariableDeclarator' && decl.id.type === 'Identifier') { + scope.idents.add(decl.id.name) + } + }) + } + break + } +} + +/** + * Collects all module scope identifiers in the AST. + * + * Ignores identifiers that are in functions or classes. + * Ignores new scopes for StaticBlock nodes (can only reference static class members). + * + * Special case handling for these which create their own scopes, + * but are also valid module scope identifiers: + * - ClassDeclaration + * - FunctionDeclaration + * + * Special case handling for var inside BlockStatement + * which are also valid module scope identifiers. + */ +const collectModuleIdentifiers = async (ast: Node, hoisting: boolean = true) => { + const identifiers = new Map() + const globalReads = new Map() + const scopes: Scope[] = [] + + await ancestorWalk(ast, { + enter(node, ancestors) { + const { type } = node + + collectScopeIdentifiers(node, scopes) + + // Add module scope identifiers to the registry map + + if (type === 'Identifier') { + const { name } = node + const meta = identifiers.get(name) ?? { declare: [], read: [] } + const isDeclaration = identifier.isDeclaration(ancestors) + const inScope = scopes.some( + scope => scope.idents.has(name) || scope.name === name, + ) + + if ( + hoisting && + !identifier.isDeclaration(ancestors) && + !identifier.isFunctionExpressionId(ancestors) && + !identifier.isExportSpecifierAlias(ancestors) && + !identifier.isClassPropertyKey(ancestors) && + !identifier.isMethodDefinitionKey(ancestors) && + !identifier.isMemberKey(ancestors) && + !identifier.isPropertyKey(ancestors) && + !identifier.isIife(ancestors) && + !inScope + ) { + if (globalReads.has(name)) { + globalReads.get(name)?.push(node) + } else { + globalReads.set(name, [node]) + } + } + + if (isDeclaration) { + const isModuleScope = identifier.isModuleScope(ancestors) + const isClassOrFuncDeclaration = + identifier.isClassOrFuncDeclarationId(ancestors) + const isVarDeclarationInGlobalScope = + identifier.isVarDeclarationInGlobalScope(ancestors) + + if ( + isModuleScope || + isClassOrFuncDeclaration || + isVarDeclarationInGlobalScope + ) { + meta.declare.push(node) + + // Check for hoisted reads + if (hoisting && globalReads.has(name)) { + const reads = globalReads.get(name) + + if (reads) { + reads.forEach(read => { + if (!meta.read.includes(read)) { + meta.read.push(read) + } + }) + } + } + + identifiers.set(name, meta) + } + } else { + if ( + identifiers.has(name) && + !inScope && + !identifier.isIife(ancestors) && + !identifier.isFunctionExpressionId(ancestors) && + !identifier.isExportSpecifierAlias(ancestors) && + !identifier.isClassPropertyKey(ancestors) && + !identifier.isMethodDefinitionKey(ancestors) && + !identifier.isMemberKey(ancestors) && + !identifier.isPropertyKey(ancestors) + ) { + // Closure is referencing module scope identifier + meta.read.push(node) + } + } + } + }, + leave(node) { + const { type } = node + + if (scopeNodes.includes(type)) { + scopes.pop() + } + }, + }) + + return identifiers +} + +export { + getLangFromExt, + isValidUrl, + collectScopeIdentifiers, + collectModuleIdentifiers, + exportsRename, + requireMainRgx, +} diff --git a/src/walk.ts b/src/walk.ts new file mode 100644 index 0000000..cc33430 --- /dev/null +++ b/src/walk.ts @@ -0,0 +1,103 @@ +import type { Node } from 'oxc-parser' +import { visitorKeys } from 'oxc-parser' + +/** + * Using visitorKeys instead of oxc Visitor to keep + * an ancestor-aware enter/leave API with this.skip() + * without per-node method boilerplate. + */ + +type AncestorContext = { + skip: () => void +} + +type AncestorVisitor = { + enter?: (this: AncestorContext, node: Node, ancestors: Node[]) => void | Promise + leave?: (this: AncestorContext, node: Node, ancestors: Node[]) => void | Promise +} + +type WalkVisitor = { + enter?: (this: AncestorContext, node: Node, parent: Node | null) => void | Promise + leave?: (this: AncestorContext, node: Node, parent: Node | null) => void | Promise +} + +let skipDepth = -1 + +const isNodeLike = (value: unknown): value is Node => { + return Boolean(value && typeof value === 'object' && 'type' in value) +} + +const traverse = async ( + node: Node, + visitors: AncestorVisitor, + ancestors: Node[], + depth: number, +) => { + if (!node) return + + const keys = visitorKeys[node.type] ?? [] + const ctx: AncestorContext = { + skip: () => { + skipDepth = depth + }, + } + + ancestors.push(node) + + if (visitors.enter) { + await visitors.enter.call(ctx, node, ancestors) + } + + if (skipDepth === -1 || depth < skipDepth) { + const fields = node as unknown as Record + for (const key of keys) { + const child = fields[key] + + if (Array.isArray(child)) { + for (const nested of child) { + if (isNodeLike(nested)) { + await traverse(nested, visitors, ancestors, depth + 1) + } + } + } else if (isNodeLike(child)) { + await traverse(child, visitors, ancestors, depth + 1) + } + } + } + + if (visitors.leave) { + await visitors.leave.call(ctx, node, ancestors) + } + + ancestors.pop() + + if (skipDepth === depth) { + skipDepth = -1 + } +} + +const ancestorWalk = async (node: Node, visitors: AncestorVisitor) => { + skipDepth = -1 + await traverse(node, visitors, [], 0) +} + +const walk = async (node: Node, visitors: WalkVisitor) => { + const wrap: AncestorVisitor = { + enter(current, ancestors) { + const parent = ancestors[ancestors.length - 2] ?? null + if (visitors.enter) { + return visitors.enter.call(this, current, parent) + } + }, + leave(current, ancestors) { + const parent = ancestors[ancestors.length - 2] ?? null + if (visitors.leave) { + return visitors.leave.call(this, current, parent) + } + }, + } + + await ancestorWalk(node, wrap) +} + +export { ancestorWalk, walk } diff --git a/test/fixtures/__dirname.cjs b/test/fixtures/__dirname.cjs new file mode 100644 index 0000000..e620e9f --- /dev/null +++ b/test/fixtures/__dirname.cjs @@ -0,0 +1,36 @@ +__dirname + +const dirname = __dirname +const a = [__dirname, 'foo'] +const obj = new String(__dirname + 'foo') + +if (__dirname === process.argv[1]) { + thing.__dirname = dirname + other.thing.__dirname = 'test' +} + +__dirname + 'foo' + +function bar(__dirname) { + const fn = __dirname + + return fn +} +const foo = __dirname => { + const fn = __dirname + return `${__dirname}${fn}` +} +;(arg => { + return arg +})(__dirname) +const baz = function __dirname(arg, ...rest) { + return rest +} + +foo(__dirname) +foo(`${__dirname}foo`) +bar.call(this, __dirname) +baz.apply(null, [__dirname, a]) + +__dirname = 'foo' +__dirname = { foo: 'bar', bar: __dirname } diff --git a/test/fixtures/__filename.cjs b/test/fixtures/__filename.cjs new file mode 100644 index 0000000..8b3bc25 --- /dev/null +++ b/test/fixtures/__filename.cjs @@ -0,0 +1,36 @@ +__filename + +const filename = __filename +const a = [__filename, 'foo'] +const obj = new String(__filename + 'foo') + +if (__filename === process.argv[1]) { + thing.__filename = filename + other.thing.__filename = 'test' +} + +__filename + 'foo' + +function bar(__filename) { + const fn = __filename + + return fn +} +const foo = __filename => { + const fn = __filename + return `${__filename}${fn}` +} +;(arg => { + return arg +})(__filename) +const baz = function __filename(arg, ...rest) { + return rest +} + +foo(__filename) +foo(`${__filename}foo`) +bar.call(this, __filename) +baz.apply(null, [__filename, a]) + +__filename = 'foo' +__filename = { foo: 'bar', bar: __filename } diff --git a/test/fixtures/exports.cjs b/test/fixtures/exports.cjs new file mode 100644 index 0000000..a80f06e --- /dev/null +++ b/test/fixtures/exports.cjs @@ -0,0 +1,56 @@ +exports + +const filename = exports +const other = exports.other ?? {} +const a = [exports, 'foo'] +const string = new String(exports + 'foo') +const thing = { exports: 'foo' } + +thing.exports = 'boo' + +if (exports === process.argv[1]) { + thing.exports = filename + other.thing.exports = 'test' +} + +exports + 'foo' + +class Foo { + exports = 'foo' + + constructor() { + this.exports = 'foo' + } + + get exports() {} +} +new Foo().exports + +function bar(exports) { + const fn = exports + + return fn +} +const foo = exports => { + const fn = exports + const other = module.exports.other + return `${exports}${fn}${other}` +} +;(arg => { + return arg +})(exports) +const baz = function exports(arg, ...rest) { + return rest +} + +foo(exports) +foo(`${exports}foo`) +bar.call(this, exports) +baz.apply(null, [exports, a]) + +exports = 'foo' +exports = { foo: 'bar', bar: exports } +exports.obj = string +exports.foo = {} +exports.foo.exports = {} +exports.foo.exports.bar = 'baz' diff --git a/test/fixtures/file.cjs b/test/fixtures/file.cjs index 2e1d823..185139a 100644 --- a/test/fixtures/file.cjs +++ b/test/fixtures/file.cjs @@ -1,33 +1,5 @@ -// CommonJS was like the Wild Wild West (require.extensions is deprecated so meh). -// Too much implied behavior without requiring explicitness. - -const { esmodule } = require('./file.mjs') - -__filename -__dirname -require -require.main -require.cache -require.resolve('./file.mjs') -require.resolve(`${__dirname}/other.js`) - const filename = __filename -const detectCalledFromCli = async path => { - const realPath = await realpath(path) - - if (__filename === pathToFileURL(realPath).href) { - stdout.write('invoked as cli') - } else { - throw new Error(require.resolve(filename)) - } -} - -detectCalledFromCli(argv[1]) - -module -module.exports -module.exports = foo +const dirname = __dirname +const resolved = require.resolve('./values.cjs') -exports -exports.commonjs = true -exports.esmodule = esmodule +module.exports = { filename, dirname, resolved } diff --git a/test/fixtures/file.mjs b/test/fixtures/file.mjs index 55d0822..d7cb890 100644 --- a/test/fixtures/file.mjs +++ b/test/fixtures/file.mjs @@ -1,21 +1,7 @@ -import { commonjs } from './file.cjs' +const bare = import.meta +const url = import.meta.url +const filename = import.meta.filename +const dirname = import.meta.dirname +const resolved = import.meta.resolve('./values.mjs') -import.meta -import.meta.url -import.meta.dirname -import.meta.filename -import.meta.resolve('./file.cjs') -import.meta.resolve(`${import.meta.dirname}/other.js`) - -const detectCalledFromCli = async path => { - const realPath = await realpath(path) - - if (import.meta.url === pathToFileURL(realPath).href) { - stdout.write('invoked as cli') - } -} - -detectCalledFromCli(argv[1]) - -export const esmodule = true -export { commonjs } +export { bare, url, filename, dirname, resolved } diff --git a/test/fixtures/identifiers/declarations.js b/test/fixtures/identifiers/declarations.js new file mode 100644 index 0000000..82c4ea2 --- /dev/null +++ b/test/fixtures/identifiers/declarations.js @@ -0,0 +1,78 @@ +var a = 'a' +const b = 'b' +let c = 'c' +const d = (c = 'd') + +function foo() { + const e = 'e' + + function inner() { + const z = 'z' + e + } + + return inner() +} + +const bar = function bar2(a) { + // A read should not be recorded for identifier `a` in the function body (shadowed by the parameter) + const baz = a + // However, `b` should be recorded as a read here + const qux = b + + return baz + qux +} + +// theta should only be declared once +const theta = function theta() { + return 'theta' +} +theta() + +const iota = function a() { + // iota should only be declared once + const iota = function () { + return 'iota' + } + return iota() +} + +class f { + g = 'g' + + constructor() { + this.h = 'h' + } + + i() { + const j = 'j' + + return j + } +} + +// Top-level Block scoped +{ + const k = 'k' + var l = 'l' + class m { + n = 'n' + } +} + +if (b) { + const o = 'o' + var p = 'p' + class q { + r = 'r' + } +} + +let s, + t = 't', + v = 'v' + +// prettier-ignore +;(function c() {}()) + +; +;(function b() {})() diff --git a/test/fixtures/identifiers/hoisting/README.md b/test/fixtures/identifiers/hoisting/README.md new file mode 100644 index 0000000..e9f7d80 --- /dev/null +++ b/test/fixtures/identifiers/hoisting/README.md @@ -0,0 +1,20 @@ +## [JavaScript Hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) + +The JS interpreter hoists `VariableDeclaration` and `FunctionDeclaration` nodes to the top of their containing scope. There are two types that are not subject to runtime errors: + +- Value Hoisting: `function` declarations can be referenced and invoked before their declarations. +- Declaration Hoisting: `var` declarations can be referenced before their declarations with a default value of `undefined`. + +The other types of hoisting are ignored by this package for the following reasons: + +- The [Temporal Dead Zone](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz) (TDZ) causes a runtime error when referencing `let`/`const`/`class` identifiers before their declarations. +- [Hoisting of `import` declarations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#import_declarations_are_hoisted) when converting from ESM to CJS is less subject to identifier collisions because `export` statements are not part of a `MemberExpression` (`exports.foo`) node, so a SyntaxError will be thrown for duplicate identifiers. Hence, it's not as important to track reads of import identifiers before they are imported. + +> [!NOTE] +> In strict mode, function declarations are not hoisted outside of `BlockStatement` nodes, but `var` declarations are. +> +> This package assumes strict mode. + +## Goal + +To correctly record references of identifiers before they are declared to avoid walking the AST twice (once for recording declarations, and again for when they are referenced). diff --git a/test/fixtures/identifiers/hoisting/functionDeclaration.js b/test/fixtures/identifiers/hoisting/functionDeclaration.js new file mode 100644 index 0000000..edbff13 --- /dev/null +++ b/test/fixtures/identifiers/hoisting/functionDeclaration.js @@ -0,0 +1,30 @@ +foo() +foo() + +function foo() { + return bar() +} + +bar() +;(function bar() {})() + +class Baz { + bar + + static bar + + constructor() { + this.bar = bar() + } + + get bar() {} +} + +const thing = { bar: 'baz' } + +function bar() { + return 'bar' +} + +bar() +foo() diff --git a/test/fixtures/identifiers/hoisting/varDeclaration.js b/test/fixtures/identifiers/hoisting/varDeclaration.js new file mode 100644 index 0000000..d33ed42 --- /dev/null +++ b/test/fixtures/identifiers/hoisting/varDeclaration.js @@ -0,0 +1,55 @@ +// Read someVar +const a = someVar + +var someVar = 'someVar' + +// Read otherVar +const b = otherVar + +class C { + // Read c (once) + static c = c + + constructor() { + // Read c (once) + this.c = c + } + + get c() { + // Read c (once) + return c + } +} + +const cee = { c: 'cee' } + +var c = otherVar + +{ + var otherVar = 'otherVar' +} + +// Read otherVar +const d = otherVar + +// Read block +const e = block +// Read innerBlock +const f = innerBlock + +{ + var block = 'block' + + { + var innerBlock = 'innerBlock' + } +} + +// Read catchVar +const g = catchVar + +try { + throw new Error('error') +} catch (err) { + var catchVar = 'catchVar' +} diff --git a/test/fixtures/identifiers/reads.js b/test/fixtures/identifiers/reads.js new file mode 100644 index 0000000..1932d0b --- /dev/null +++ b/test/fixtures/identifiers/reads.js @@ -0,0 +1,171 @@ +let a = 'a' +// Read a +const b = (a = 'b') +// Read a +const c = `${a}foo` + +function alpha() { + const alpha1 = 'alpha1' + + // Read a + return alpha1 + a +} +alpha() + +function beta(a) { + const e = a + + return e +} +beta() + +// Read a (AssignmentPattern) +const gamma = (p = a) => { + const gamma1 = p + + return gamma1 +} +gamma() + +function delta(...a) { + const delta1 = a[0] + + return delta1 +} + +delta() + +// Read a (only the value, not the key) +const thing = { inner: {}, a: a } + +// Read a once (not member expression) +thing.a = a +// Read a once (not member expression) +thing.inner.a = a +// Read a once (not member expression) +gamma.a = a + +class Epsilon { + constructor(a) { + this.a = a + } + + epsilon1() { + // Read a + return a + } +} +new Epsilon('a') + +const zeta = () => { + // Read a + const zeta1 = a + + return zeta1 +} +zeta() +;(a => { + a + // Read a +})(a) +;(function a(p) { + p + // Read a +})(a) + +function eta() { + class a { + constructor() { + const a = () => { + return a + } + this.a = a() + } + } + + return new a() +} +eta() + +const theta = function a() { + const theta1 = a + + return theta1 +} +theta() + +const iota = function () { + const a = () => { + return 'inner a' + } + + return a() +} +iota() + +const kappa = function () { + function a() { + const a = 'inner a' + return a + } + + return a() +} +kappa() + +class Lambda { + a = 'aa' + + static a + + static { + this.a = 'static a' + } + + get a() { + return this.a + } + + lambda1() { + // Read a + return a + } +} +new Lambda('a') + +class Mu { + a = 'aa' + + constructor(a) { + this.a = a + } + + mu1() { + // Read a + return a + } +} +new Mu('passed a') + +class Nu { + a = 'aa' + + constructor() { + // Read a (also shadows the class field) + this.a = a + } + + nu1() { + return this.a + } +} +new Nu('passed a') + +// Read a +export default a + +// Read a (once, the alias is not counted as a read) +export { a as a } + +// Read a +export const f = a diff --git a/test/fixtures/import.meta.dirname.mjs b/test/fixtures/import.meta.dirname.mjs new file mode 100644 index 0000000..83bbf4e --- /dev/null +++ b/test/fixtures/import.meta.dirname.mjs @@ -0,0 +1,35 @@ +import.meta.dirname +import.meta.dirname = 'foo' +import.meta.dirname = 'file:///some/path/to/file.js' + +const filename = import.meta.dirname +const a = [import.meta.dirname, 'foo'] +const obj = new String(import.meta.dirname + 'foo') + +if (import.meta.dirname === process.argv[1]) { + thing.import.meta.dirname = filename + other.thing.import.meta.dirname = 'test' +} + +import.meta.dirname + 'foo' + +const baz = function importMetaFilename(arg, ...rest) { + return rest +} +function bar() { + const fn = import.meta.dirname + + return fn +} +const foo = () => { + const fn = import.meta.dirname + return `${import.meta.dirname}${fn}` +} +;(arg => { + return arg +})(import.meta.dirname) + +foo(import.meta.dirname) +foo(`${import.meta.dirname}foo`) +bar.call(this, import.meta.dirname) +baz.apply(null, [import.meta.dirname, a]) diff --git a/test/fixtures/import.meta.filename.mjs b/test/fixtures/import.meta.filename.mjs new file mode 100644 index 0000000..f0b501a --- /dev/null +++ b/test/fixtures/import.meta.filename.mjs @@ -0,0 +1,35 @@ +import.meta.filename +import.meta.filename = 'foo' +import.meta.filename = 'file:///some/path/to/file.js' + +const filename = import.meta.filename +const a = [import.meta.filename, 'foo'] +const obj = new String(import.meta.filename + 'foo') + +if (import.meta.filename === process.argv[1]) { + thing.import.meta.filename = filename + other.thing.import.meta.filename = 'test' +} + +import.meta.filename + 'foo' + +const baz = function importMetaFilename(arg, ...rest) { + return rest +} +function bar() { + const fn = import.meta.filename + + return fn +} +const foo = () => { + const fn = import.meta.filename + return `${import.meta.filename}${fn}` +} +;(arg => { + return arg +})(import.meta.filename) + +foo(import.meta.filename) +foo(`${import.meta.filename}foo`) +bar.call(this, import.meta.filename) +baz.apply(null, [import.meta.filename, a]) diff --git a/test/fixtures/import.meta.mjs b/test/fixtures/import.meta.mjs new file mode 100644 index 0000000..aaed39c --- /dev/null +++ b/test/fixtures/import.meta.mjs @@ -0,0 +1,31 @@ +import.meta + +const filename = import.meta +const a = [import.meta, 'foo'] + +if (import.meta === process.argv[1]) { + thing.import.meta = filename + thing.import.meta.url = filename + other.thing.import.meta = 'test' +} + +const baz = function importMetaUrl(arg, ...rest) { + return rest +} +function bar() { + const fn = import.meta + + return fn +} +const foo = () => { + const fn = import.meta + + return fn +} +;(arg => { + return arg +})(import.meta) + +foo(import.meta) +bar.call(this, import.meta) +baz.apply(null, [import.meta, a]) diff --git a/test/fixtures/import.meta.resolve.mjs b/test/fixtures/import.meta.resolve.mjs new file mode 100644 index 0000000..9c647c8 --- /dev/null +++ b/test/fixtures/import.meta.resolve.mjs @@ -0,0 +1,37 @@ +import.meta.resolve +const path = import.meta.resolve('./values.cjs') + +const filename = import.meta.resolve +const a = [import.meta.resolve, 'foo'] + +if (import.meta.resolve('./values.cjs') === process.argv[1]) { + thing.import.meta.resolve = filename + other.thing.import.meta.resolve = 'test' +} + +import.meta.resolve + 'foo' + +const baz = function importMetaResolve(arg, ...rest) { + return rest +} +function bar() { + const fn = import.meta.resolve + + return fn +} +const foo = () => { + const fn = import.meta.resolve + return `${import.meta.resolve}${fn}` +} +;(arg => { + return arg +})(import.meta.resolve) + +foo(import.meta.resolve) +bar.call(this, import.meta.resolve) +baz.apply(null, [import.meta.resolve, a]) + +import.meta.resolve = () => { + return import.meta.resolve +} +import.meta.resolve = 'file:///some/path/to/file.js' diff --git a/test/fixtures/import.meta.url.mjs b/test/fixtures/import.meta.url.mjs new file mode 100644 index 0000000..51f1dbf --- /dev/null +++ b/test/fixtures/import.meta.url.mjs @@ -0,0 +1,35 @@ +import.meta.url +import.meta.url = 'foo' +import.meta.url = 'file:///some/path/to/file.js' + +const filename = import.meta.url +const a = [import.meta.url, 'foo'] +const obj = new String(import.meta.url + 'foo') + +if (import.meta.url === process.argv[1]) { + thing.import.meta.url = filename + other.thing.import.meta.url = 'test' +} + +import.meta.url + 'foo' + +const baz = function importMetaUrl(arg, ...rest) { + return rest +} +function bar() { + const fn = import.meta.url + + return fn +} +const foo = () => { + const fn = import.meta.url + return `${import.meta.url}${fn}` +} +;(arg => { + return arg +})(import.meta.url) + +foo(import.meta.url) +foo(`${import.meta.url}foo`) +bar.call(this, import.meta.url) +baz.apply(null, [import.meta.url, a]) diff --git a/test/fixtures/values.cjs b/test/fixtures/values.cjs new file mode 100644 index 0000000..0d976d4 --- /dev/null +++ b/test/fixtures/values.cjs @@ -0,0 +1,5 @@ +module.exports.cjs = 'commonjs' +exports.commonjs = true +exports.foo = 'bar' +exports.require = 'require' +exports.obj = exports diff --git a/test/fixtures/values.mjs b/test/fixtures/values.mjs new file mode 100644 index 0000000..890a62b --- /dev/null +++ b/test/fixtures/values.mjs @@ -0,0 +1,6 @@ +export const esmodule = true +const esm = 'es module' +const foo = 'bar' + +export { foo, esm } +export * as obj from './values.mjs' diff --git a/test/helpers/identifier/isMemberExpressionRoot.ts b/test/helpers/identifier/isMemberExpressionRoot.ts new file mode 100644 index 0000000..e69de29 diff --git a/test/helpers/identifier/isModuleScope.ts b/test/helpers/identifier/isModuleScope.ts new file mode 100644 index 0000000..fc5f085 --- /dev/null +++ b/test/helpers/identifier/isModuleScope.ts @@ -0,0 +1,464 @@ +import { describe, it } from 'node:test' +import assert from 'node:assert/strict' + +import { ancestorWalk } from '#walk' + +import { parse } from '#parse' +import { identifier } from '#helpers/identifier' + +const { isModuleScope } = identifier + +describe('isModuleScope', () => { + it('finds module scope identifiers', async () => { + const ast = parse( + 'file.ts', + ` + import { foo } from 'foo.js' + import * as bar from 'bar.js' + import { bazz as baz } from 'baz.js' + import qux from 'qux.js' + + const a = 1; + let b = 2; + var c = 3; + const d = () => {} + // f should not be global. + const e = function f() {} + // h should not be global. + const g = class h {} + class i {} + function j() {} + `, + ) + + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'g': + case 'i': + case 'j': + assert.equal(isModuleScope(ancestors), true) + assert.equal(isModuleScope(ancestors, true), true) + break + case 'f': + case 'h': + assert.equal(isModuleScope(ancestors), false) + assert.equal(isModuleScope(ancestors, true), false) + break + case 'foo': + case 'bar': + case 'baz': + case 'qux': + assert.equal(isModuleScope(ancestors), false) + assert.equal(isModuleScope(ancestors, true), true) + break + } + } + }, + }) + }) + + it('discerns member expressions, object properties, and destructuring', async () => { + let ast = parse( + 'file.ts', + ` + var x = 'xx' + var y = 'yy' + const a = { b: 'b' } + const { b: c } = a + const { xx: computed } = { [x]: 'e' } + const f = { d: 'g', yy: y } + const { [y]: h } = f + + a.b + f[y] + `, + ) + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'x': + case 'y': + case 'a': + case 'c': + case 'computed': + case 'f': + case 'h': + assert.equal(isModuleScope(ancestors), true) + break + case 'b': + case 'd': + case 'yy': + assert.equal(isModuleScope(ancestors), false) + break + } + } + }, + }) + + ast = parse( + 'file.ts', + ` + function scope() { + var x = 'xx' + var y = 'yy' + const a = { b: 'b' } + const { b: c } = a + const { xx: computed } = { [x]: 'e' } + const f = { d: 'g', yy: y } + const { [y]: h } = f + + a.b + f[y] + } + + { + var x = 'xx' + var y = 'yy' + const a = { b: 'b' } + const { b: c } = a + const { xx: computed } = { [x]: 'e' } + const f = { d: 'g', yy: y } + const { [y]: h } = f + + a.b + f[y] + } + `, + ) + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'x': + case 'y': + case 'a': + case 'b': + case 'c': + case 'd': + case 'yy': + case 'computed': + case 'f': + case 'h': + assert.equal(isModuleScope(ancestors), false) + break + } + } + }, + }) + + ast = parse( + 'file.ts', + ` + const obj = {a: undefined, b: [2], c: 3}; + const e = 'e' + const {g = e, b: d, ...rest} = obj; + const {b: [bb] = 'x'} = obj; + + const scope = () => { + const o = {f: undefined, h: [2], i: 3}; + const j = 'j' + const {k = j, h: l, ...others} = o; + const {h: [m] = 'x'} = o; + } + `, + ) + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'obj': + case 'e': + case 'g': + case 'd': + case 'rest': + case 'bb': + case 'scope': + assert.equal(isModuleScope(ancestors), true) + break + case 'a': + case 'b': + case 'c': + case 'o': + case 'f': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'others': + case 'm': + assert.equal(isModuleScope(ancestors), false) + break + } + } + }, + }) + + ast = parse( + 'file.ts', + ` + const a = ['w', 'x', 'y', 'z'] + const b = 0 + const [c, d, ...rest] = a + const [e = 'w'] = a + const [h, ...{f, g: gg}] = a + let i, j, others + + [...[i, j, ...others]] = a + + a[b] + a[1] + `, + ) + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'a': + case 'b': + case 'c': + case 'd': + case 'rest': + case 'e': + case 'h': + case 'f': + case 'gg': + case 'i': + case 'j': + case 'others': + assert.equal(isModuleScope(ancestors), true) + break + case 'g': + case '1': + assert.equal(isModuleScope(ancestors), false) + break + } + } + }, + }) + + // Not considering meta properties as module scope. + ast = parse( + 'file.ts', + ` + import.meta + import.meta.url + import.meta.resolve('foo.js') + `, + ) + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'import': + case 'meta': + case 'url': + case 'resolve': + assert.equal(isModuleScope(ancestors), false) + break + } + } + }, + }) + }) + + describe('while ignoring', () => { + it('identifiers inside function scopes', async () => { + const ast = parse( + 'file.ts', + ` + const alpha = () => { + const a = 'a' + } + const beta = function () { + let b = 'b' + } + function gamma () { + var c = 'c' + } + `, + ) + + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'alpha': + case 'beta': + case 'gamma': + assert.equal(isModuleScope(ancestors), true) + break + case 'a': + case 'b': + case 'c': + assert.equal(isModuleScope(ancestors), false) + break + } + } + }, + }) + }) + + it('identifiers inside class scopes', async () => { + const ast = parse( + 'file.ts', + ` + class alpha { + static a + static { + const b = 'b' + this.a = 'aa' + } + + c = 'c' + d() { + const e = 'e' + } + } + const beta = class { + constructor() { + this.f = 'f' + } + get g() {} + set h(i) {} + *j() { + yield 1 + } + } + `, + ) + + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'alpha': + case 'beta': + assert.equal(isModuleScope(ancestors), true) + break + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + assert.equal(isModuleScope(ancestors), false) + break + } + } + }, + }) + }) + + it('identifiers inside block scopes', async () => { + const ast = parse( + 'file.ts', + ` + { + const a = 'a' + let b = 'b' + var c = 'c' + } + if (c === 'c') { + const f = 'f' + let g = 'g' + var h = 'h' + c = f + g + h + } + for (let i = 0; i < 10; i++) { + const j = 'j' + var jj = i + j + } + while (false) { + let k = 'k' + var kk = 'kk' + } + do { + const l = 'l' + var ll = 'll' + } while (false) + switch (true) { + case true: + const m = 'm' + var mm = 'mm' + default: + const n = 'n' + var nn = 'nn' + } + + { + var x = 'x' + { + var y = 'y' + + if (x) { + var z = 'z' + } + + function innerFunction() { + var innerVar = 'inner' + return innerVar + } + } + } + `, + ) + + await ancestorWalk(ast.program, { + enter(node, ancestors) { + if (node.type === 'Identifier') { + const { name } = node + switch (name) { + case 'a': + case 'b': + case 'f': + case 'g': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'innerFunction': + case 'innerVar': + assert.equal(isModuleScope(ancestors), false) + break + // var hoisted identifiers + case 'c': + case 'h': + case 'jj': + case 'kk': + case 'll': + case 'mm': + case 'nn': + case 'x': + case 'y': + case 'z': + assert.equal(isModuleScope(ancestors), true) + break + } + } + }, + }) + }) + }) +}) diff --git a/test/module.ts b/test/module.ts index 316f584..d02a5a3 100644 --- a/test/module.ts +++ b/test/module.ts @@ -1,7 +1,8 @@ import { describe, it } from 'node:test' import assert from 'node:assert/strict' +import { spawnSync } from 'node:child_process' import { resolve, join } from 'node:path' -import { rm, stat } from 'node:fs/promises' +import { rm, stat, writeFile } from 'node:fs/promises' import type { Stats } from 'node:fs' import { transform } from '../src/module.js' @@ -24,25 +25,194 @@ const isValidFilename = async (filename: string) => { } describe('@knighted/module', () => { + it('transforms __filename', async t => { + const result = await transform(join(fixtures, '__filename.cjs'), { + target: 'module', + }) + const outFile = join(fixtures, '__filename.mjs') + + t.after(() => { + rm(outFile, { force: true }) + }) + + await writeFile(outFile, result) + + assert.ok(result.indexOf('thing.__filename = filename') > -1) + assert.ok(result.indexOf("other.thing.__filename = 'test'") > -1) + assert.ok(result.indexOf('bar(__filename)') > -1) + assert.equal([...result.matchAll(/const fn = __filename/g)].length, 2) + assert.ok(result.indexOf(')(import.meta.url)') > -1) + assert.ok(result.indexOf('import.meta.url === process.argv[1]') > -1) + assert.ok(result.indexOf('baz.apply(null, [import.meta.url, a])') > -1) + + const { status } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(status, 0) + }) + + it('transforms __dirname', async t => { + const result = await transform(join(fixtures, '__dirname.cjs'), { + target: 'module', + }) + const outFile = join(fixtures, '__dirname.mjs') + + t.after(() => { + rm(outFile, { force: true }) + }) + + await writeFile(outFile, result) + + assert.ok(result.indexOf("other.thing.__dirname = 'test'") > -1) + assert.ok(result.indexOf('thing.__dirname = dirname') > -1) + assert.ok(result.indexOf('bar(__dirname)') > -1) + assert.equal([...result.matchAll(/const fn = __dirname/g)].length, 2) + assert.ok(result.indexOf(')(import.meta.dirname)') > -1) + assert.ok(result.indexOf('import.meta.dirname === process.argv[1]') > -1) + assert.ok(result.indexOf('baz.apply(null, [import.meta.dirname, a])') > -1) + + const { status } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(status, 0) + }) + + it('transforms exports', async t => { + const fixturePath = join(fixtures, 'exports.cjs') + const result = await transform(fixturePath, { + target: 'module', + }) + const outFile = join(fixtures, 'exports.mjs') + const { status: statusIn } = spawnSync('node', [fixturePath], { + stdio: 'inherit', + }) + + t.after(() => { + rm(outFile, { force: true }) + }) + + assert.equal(statusIn, 0) + await writeFile(outFile, result) + + const { status: statusOut } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(statusOut, 0) + }) + + it('transforms import.meta', async t => { + const result = await transform(join(fixtures, 'import.meta.mjs'), { + target: 'commonjs', + }) + const outFile = join(fixtures, 'import.meta.cjs') + + t.after(() => { + rm(outFile, { force: true }) + }) + + await writeFile(outFile, result) + + const { status } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(status, 0) + }) + + it('transforms import.meta.url', async t => { + const result = await transform(join(fixtures, 'import.meta.url.mjs'), { + target: 'commonjs', + }) + const outFile = join(fixtures, 'import.meta.url.cjs') + t.after(() => { + rm(outFile, { force: true }) + }) + + await writeFile(outFile, result) + + assert.ok(result.indexOf("Invalid assignment: 'foo' is not a URL.") > -1) + assert.ok( + result.indexOf('pathToFileURL(__filename).href =') > -1 && + result.indexOf('file:///some/path/to/file.js') > -1, + ) + assert.ok(result.indexOf('thing.import.meta.url = filename') > -1) + + const { status } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(status, 0) + }) + + it('transforms import.meta.filename', async t => { + const result = await transform(join(fixtures, 'import.meta.filename.mjs'), { + target: 'commonjs', + }) + const outFile = join(fixtures, 'import.meta.filename.cjs') + + t.after(() => { + rm(outFile, { force: true }) + }) + + await writeFile(outFile, result) + + assert.ok(result.indexOf('const filename = __filename') > -1) + assert.ok(result.indexOf('thing.import.meta.filename = filename') > -1) + assert.equal([...result.matchAll(/const fn = __filename/g)].length, 2) + assert.ok(result.indexOf('foo(__filename)') > -1) + + const { status } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(status, 0) + }) + + it('transforms import.meta.dirname', async t => { + const result = await transform(join(fixtures, 'import.meta.dirname.mjs'), { + target: 'commonjs', + }) + const outFile = join(fixtures, 'import.meta.dirname.cjs') + + t.after(() => { + rm(outFile, { force: true }) + }) + + await writeFile(outFile, result) + + assert.ok(result.indexOf('const filename = __dirname') > -1) + assert.ok(result.indexOf('thing.import.meta.dirname = filename') > -1) + assert.equal([...result.matchAll(/const fn = __dirname/g)].length, 2) + assert.ok(result.indexOf('foo(__dirname)') > -1) + + const { status } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(status, 0) + }) + + it('transforms import.meta.resolve', async t => { + const result = await transform(join(fixtures, 'import.meta.resolve.mjs'), { + target: 'commonjs', + }) + const outFile = join(fixtures, 'import.meta.resolve.cjs') + + t.after(() => { + rm(outFile, { force: true }) + }) + + await writeFile(outFile, result) + + assert.ok(result.indexOf("const path = require.resolve('./values.cjs')") > -1) + assert.ok(result.indexOf('thing.import.meta.resolve = filename') > -1) + assert.equal([...result.matchAll(/const fn = require.resolve/g)].length, 2) + assert.ok(result.indexOf("require.resolve = 'file:///some/path/to/file.js'") > -1) + + const { status } = spawnSync('node', [outFile], { stdio: 'inherit' }) + assert.equal(status, 0) + }) + it('transforms es module globals to commonjs globals', async () => { - const result = await transform(join(fixtures, 'file.mjs')) + const result = await transform(join(fixtures, 'file.mjs'), { target: 'commonjs' }) assert.equal(result.indexOf('import.meta.url'), -1) assert.equal(result.indexOf('import.meta.filename'), -1) assert.equal(result.indexOf('import.meta.dirname'), -1) assert.equal(result.indexOf('import.meta.resolve'), -1) - assert.ok(result.indexOf('require("node:url").pathToFileURL(__filename).toString()') > -1) + assert.ok(result.indexOf('require("node:url").pathToFileURL(__filename).href') > -1) assert.ok(result.indexOf('__dirname') > -1) assert.ok(result.indexOf('__filename') > -1) assert.ok(result.indexOf('require.resolve(') > -1) - // Check `import.meta` transformation + // Check `import.meta` transformed into `module` assert.equal(/import\.meta\s/.test(result), false) - assert.ok(result.indexOf('require.main') > -1) + assert.ok(/\smodule\s/.test(result)) }) it('transforms commonjs globals to es module globals', async () => { - const result = await transform(join(fixtures, 'file.cjs'), { type: 'module' }) - + const result = await transform(join(fixtures, 'file.cjs'), { target: 'module' }) assert.equal(result.indexOf('__filename'), -1) assert.equal(result.indexOf('__dirname'), -1) assert.equal(result.indexOf('require.resolve'), -1) @@ -53,18 +223,27 @@ describe('@knighted/module', () => { assert.equal(!/\smodule\s/.test(result), true) assert.equal(!/\sexports\s/.test(result), true) assert.equal(result.indexOf('require.cache'), -1) - assert.equal(/import\.meta\s/.test(result), true) + assert.ok(/import\.meta/.test(result)) assert.ok(result.indexOf('{}') > -1) }) it('updates specifiers when option enabled', async () => { - const result = await transform(join(fixtures, 'specifier.mjs'), { specifier: '.js' }) - const cjsResult = await transform(join(fixtures, 'specifier.cjs'), { type: 'module', specifier: '.mjs' }) + const result = await transform(join(fixtures, 'specifier.mjs'), { + target: 'commonjs', + rewriteSpecifier: '.js', + }) + const cjsResult = await transform(join(fixtures, 'specifier.cjs'), { + target: 'module', + rewriteSpecifier: '.mjs', + }) assert.equal((result.match(/\.\/file\.js/g) ?? []).length, 6) assert.equal((result.match(/require\.resolve\('\.\/file\.js'\)/g) ?? []).length, 2) assert.equal((cjsResult.match(/\.\/file\.mjs/g) ?? []).length, 3) - assert.equal((cjsResult.match(/import\.meta\.resolve\('\.\/file\.mjs'\)/g) ?? []).length, 1) + assert.equal( + (cjsResult.match(/import\.meta\.resolve\('\.\/file\.mjs'\)/g) ?? []).length, + 1, + ) }) it('writes transformed source to a file when option enabled', async t => { @@ -76,8 +255,8 @@ describe('@knighted/module', () => { rm(cjs, { force: true }) }) - await transform(join(fixtures, 'file.mjs'), { type: 'commonjs', out: cjs }) - await transform(join(fixtures, 'file.cjs'), { type: 'module', out: mjs }) + await transform(join(fixtures, 'file.mjs'), { target: 'commonjs', out: cjs }) + await transform(join(fixtures, 'file.cjs'), { target: 'module', out: mjs }) assert.equal(await isValidFilename(mjs), true) assert.equal(await isValidFilename(cjs), true) diff --git a/test/utils.ts b/test/utils.ts new file mode 100644 index 0000000..6345b27 --- /dev/null +++ b/test/utils.ts @@ -0,0 +1,141 @@ +import { describe, it } from 'node:test' +import assert from 'node:assert/strict' +import { resolve, join } from 'node:path' +import { readFile } from 'node:fs/promises' +import { spawnSync } from 'node:child_process' + +import { parse } from '../src/parse.js' +import { collectModuleIdentifiers } from '../src/utils.js' + +// Use fixtures to more easily track character offsets and line numbers in test cases. +const fixtures = resolve(import.meta.dirname, 'fixtures') + +describe('collectModuleIdentifiers', () => { + it('collects identifiers declarations in top-level module scope', async () => { + const fixturePath = join(fixtures, 'identifiers', 'declarations.js') + const code = await readFile(fixturePath) + const ast = parse('file.ts', code.toString()) + const idents = await collectModuleIdentifiers(ast.program) + const keys = Array.from(idents.keys()) + const { status } = spawnSync('node', [fixturePath], { stdio: 'inherit' }) + + // Test for valid syntax + assert.equal(status, 0) + + assert.deepEqual(keys, [ + 'a', + 'b', + 'c', + 'd', + 'foo', + 'bar', + 'theta', + 'iota', + 'f', + 'l', + 'p', + 's', + 't', + 'v', + ]) + assert.equal(idents.get('c')!.read.length, 1) + assert.equal(idents.get('b')!.read.length, 2) + assert.equal(idents.get('a')!.read.length, 0) + }) + + it('records subsequent reads of collected identifiers', async () => { + const fixturePath = join(fixtures, 'identifiers', 'reads.js') + const code = await readFile(fixturePath) + const ast = parse('file.ts', code.toString()) + const idents = await collectModuleIdentifiers(ast.program) + const reads: number[] = [] + const { status } = spawnSync('node', [fixturePath], { stdio: 'inherit' }) + + // Test for valid syntax + assert.equal(status, 0) + + idents.get('a')!.read.forEach(read => { + reads.push(read.start) + }) + + assert.equal(idents.get('a')!.read.length, 18) + assert.deepEqual( + reads, + [ + 33, 65, 149, 266, 465, 519, 576, 627, 725, 800, 855, 895, 1489, 1611, 1738, 1824, + 1889, 1926, + ], + ) + }) + + it('correctly counts reads for hoisted function declarations', async () => { + const fixturePath = join( + fixtures, + 'identifiers', + 'hoisting', + 'functionDeclaration.js', + ) + const code = await readFile(fixturePath) + const ast = parse('file.ts', code.toString()) + const idents = await collectModuleIdentifiers(ast.program, true) + const fooReads: number[] = [] + const barReads: number[] = [] + const { status } = spawnSync('node', [fixturePath], { stdio: 'inherit' }) + + // Test for valid syntax + assert.equal(status, 0) + + idents.get('foo')!.read.forEach(read => { + fooReads.push(read.start) + }) + idents.get('bar')!.read.forEach(read => { + barReads.push(read.start) + }) + + assert.deepEqual(fooReads, [0, 6, 244]) + assert.deepEqual(barReads, [39, 48, 144, 238]) + }) + + it('correctly counts reads for hoisted var declarations', async () => { + const fixturePath = join(fixtures, 'identifiers', 'hoisting', 'varDeclaration.js') + const code = await readFile(fixturePath) + const ast = parse('file.ts', code.toString()) + const idents = await collectModuleIdentifiers(ast.program, true) + const someVarReads: number[] = [] + const otherVarReads: number[] = [] + const cVarReads: number[] = [] + const blockVarReads: number[] = [] + const innerBlockVarReads: number[] = [] + const catchVarReads: number[] = [] + const { status } = spawnSync('node', [fixturePath], { stdio: 'inherit' }) + + // Test for valid syntax + assert.equal(status, 0) + + idents.get('someVar')!.read.forEach(read => { + someVarReads.push(read.start) + }) + idents.get('otherVar')!.read.forEach(read => { + otherVarReads.push(read.start) + }) + idents.get('c')!.read.forEach(read => { + cVarReads.push(read.start) + }) + idents.get('block')!.read.forEach(read => { + blockVarReads.push(read.start) + }) + idents.get('innerBlock')!.read.forEach(read => { + innerBlockVarReads.push(read.start) + }) + idents.get('catchVar')!.read.forEach(read => { + catchVarReads.push(read.start) + }) + + assert.deepEqual(someVarReads, [26]) + assert.deepEqual(otherVarReads, [87, 288, 358]) + assert.deepEqual(cVarReads, [139, 194, 245]) + assert.deepEqual(blockVarReads, [392]) + assert.deepEqual(innerBlockVarReads, [427]) + assert.deepEqual(catchVarReads, [536]) + }) +}) diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..029ab97 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "noEmit": true, + "types": ["node"] + }, + "include": ["src", "test"] +}