diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01a8adf..067dc6d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,8 @@ jobs: path: npm-debug.log - name: Lint run: npm run lint + - name: Check cycles + run: npm run cycles - name: Type Check run: npm run check-types - name: Test diff --git a/README.md b/README.md index da261c1..b4b5b97 100644 --- a/README.md +++ b/README.md @@ -229,9 +229,3 @@ for (const file of files) { ``` This pre-`tsc` step removes the flagged globals in the compiled orientation; runtime semantics still match the target build. - -## Roadmap - -- Emit source maps and clearer diagnostics for transform choices. -- Broaden fixtures covering live-binding and top-level await edge cases across Node versions. -- Benchmark scope analysis choices: compare `periscopic`, `scope-analyzer`, and `eslint-scope` on fixtures and pick the final adapter. diff --git a/docs/roadmap.md b/docs/roadmap.md index a802cd5..76bb57f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -11,12 +11,6 @@ Next: - Explore a true `'aggressive'` mode (mixed exports/module.exports, limited reassignments, identifier-safe computed keys) with guarded semantics and explicit diagnostics. - Consider a constrained ESM → CJS “pretty” path where live-binding and TLA semantics permit it. -## Documentation & UX - -- Note Node runtime floor (current package.json: Node >=22.21.1 <23 || >=24 <25) for `import.meta.*` support in generated code. -- Document diagnostics behavior when `pretty` cannot be applied. -- Consider a README section on “migration mode” describing pretty output trade-offs and when to avoid it. - ## CLI - Deliver a `knighted-module` CLI that wraps the core transform with parity to API options (targets, rewriteSpecifier, appendJsExtension/appendDirectoryIndex, detectCircularRequires, topLevelAwait, cjsDefault, diagnostics hooks, out/in-place). @@ -25,8 +19,7 @@ Next: - Performance ergonomics: batch parse/format where possible, optional concurrency flag, and a `--watch` mode that rebuilds on change with minimal restarts. - DX: `--dry-run` to preview planned rewrites, `--list` to show which files would change, `--summary` to print counts of transformed specifiers/globals, and `--help`/`--version` aligned with package metadata. -## Next Steps +## Tooling & Diagnostics -- Prototype CJS→ESM `pretty: 'safe'` path with fixtures and diagnostics. -- Evaluate surface area for ESM→CJS pretty mode; decide if it ships initially or stays experimental. -- Add CLI/API option plumbing and docs once behavior solidifies. +- Emit source maps and clearer diagnostics for transform choices. +- Benchmark scope analysis choices: compare `periscopic`, `scope-analyzer`, and `eslint-scope` on fixtures and pick the final adapter. diff --git a/oxlint.json b/oxlint.json index 52ec73c..85c88d4 100644 --- a/oxlint.json +++ b/oxlint.json @@ -4,6 +4,7 @@ "rules": { "no-console": "error", "unicorn/filename-case": ["error", { "case": "camelCase" }], + "@typescript-eslint/no-explicit-any": "error", "import/no-unused-modules": [ "warn", { "missingExports": true, "unusedExports": true } @@ -28,6 +29,12 @@ "rules": { "no-unused-vars": "off" } + }, + { + "files": ["test/**"], + "rules": { + "@typescript-eslint/no-explicit-any": "off" + } } ] } diff --git a/package-lock.json b/package-lock.json index 128ae45..4d55016 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@knighted/module", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@knighted/module", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT", "dependencies": { "magic-string": "^0.30.21", @@ -21,6 +21,7 @@ "c8": "^10.1.3", "husky": "^9.1.7", "lint-staged": "^16.2.7", + "madge": "^8.0.0", "oxlint": "^1.35.0", "prettier": "^3.7.4", "tsx": "^4.21.0", @@ -1760,6 +1761,20 @@ "node": ">=18" } }, + "node_modules/@dependents/detective-less": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-5.0.1.tgz", + "integrity": "sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@emnapi/core": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", @@ -2755,6 +2770,96 @@ "node": ">=14" } }, + "node_modules/@ts-graphviz/adapter": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ts-graphviz/adapter/-/adapter-2.0.6.tgz", + "integrity": "sha512-kJ10lIMSWMJkLkkCG5gt927SnGZcBuG0s0HHswGzcHTgvtUe7yk5/3zTEr0bafzsodsOq5Gi6FhQeV775nC35Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/ast": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@ts-graphviz/ast/-/ast-2.0.7.tgz", + "integrity": "sha512-e6+2qtNV99UT6DJSoLbHfkzfyqY84aIuoV8Xlb9+hZAjgpum8iVHprGeAMQ4rF6sKUAxrmY8rfF/vgAwoPc3gw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/common": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ts-graphviz/common/-/common-2.1.5.tgz", + "integrity": "sha512-S6/9+T6x8j6cr/gNhp+U2olwo1n0jKj/682QVqsh7yXWV6ednHYqxFw0ZsY3LyzT0N8jaZ6jQY9YD99le3cmvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/core": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@ts-graphviz/core/-/core-2.0.7.tgz", + "integrity": "sha512-w071DSzP94YfN6XiWhOxnLpYT3uqtxJBDYdh6Jdjzt+Ce6DNspJsPQgpC7rbts/B8tEkq0LHoYuIF/O5Jh5rPg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/ast": "^2.0.7", + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", @@ -2793,6 +2898,166 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.50.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.1.tgz", + "integrity": "sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.50.1", + "@typescript-eslint/types": "^8.50.1", + "debug": "^4.3.4" + }, + "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_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.50.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.1.tgz", + "integrity": "sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==", + "dev": true, + "license": "MIT", + "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_modules/@typescript-eslint/types": { + "version": "8.50.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.1.tgz", + "integrity": "sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.50.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.1.tgz", + "integrity": "sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.50.1", + "@typescript-eslint/tsconfig-utils": "8.50.1", + "@typescript-eslint/types": "8.50.1", + "@typescript-eslint/visitor-keys": "8.50.1", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "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_modules/@typescript-eslint/visitor-keys": { + "version": "8.50.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.1.tgz", + "integrity": "sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.1", + "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" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", + "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.26", + "entities": "^7.0.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", + "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.26", + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz", + "integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.26", + "@vue/compiler-dom": "3.5.26", + "@vue/compiler-ssr": "3.5.26", + "@vue/shared": "3.5.26", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz", + "integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.26", + "@vue/shared": "3.5.26" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", + "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", + "dev": true, + "license": "MIT" + }, "node_modules/ansi-escapes": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", @@ -2833,6 +3098,30 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/ast-module-types": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-6.0.1.tgz", + "integrity": "sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/babel-dual-package": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/babel-dual-package/-/babel-dual-package-1.2.3.tgz", @@ -2973,7 +3262,51 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "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, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } }, "node_modules/braces": { "version": "3.0.3", @@ -3022,6 +3355,31 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/c8": { "version": "10.1.3", "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", @@ -3057,9 +3415,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "version": "1.0.30001761", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", + "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", "dev": true, "funding": [ { @@ -3077,6 +3435,23 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/cli-cursor": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", @@ -3093,6 +3468,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "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", @@ -3207,6 +3595,16 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3242,6 +3640,13 @@ "node": ">=20" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3295,27 +3700,247 @@ } } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } }, - "node_modules/electron-to-chromium": { - "version": "1.5.191", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz", - "integrity": "sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==", + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dependency-tree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-11.2.0.tgz", + "integrity": "sha512-+C1H3mXhcvMCeu5i2Jpg9dc0N29TWTuT6vJD7mHLAfVmAbo9zW8NlkvQ1tYd3PDMab0IRQM0ccoyX68EZtx9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0", + "filing-cabinet": "^5.0.3", + "precinct": "^12.2.0", + "typescript": "^5.8.3" + }, + "bin": { + "dependency-tree": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/dependency-tree/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-amd": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-6.0.1.tgz", + "integrity": "sha512-TtyZ3OhwUoEEIhTFoc1C9IyJIud3y+xYkSRjmvCt65+ycQuc3VcBrPRTMWoO/AnuCyOB8T5gky+xf7Igxtjd3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "escodegen": "^2.1.0", + "get-amd-module-type": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "bin": { + "detective-amd": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-cjs": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-6.0.1.tgz", + "integrity": "sha512-tLTQsWvd2WMcmn/60T2inEJNhJoi7a//PQ7DwRKEj1yEeiQs4mrONgsUtEJKnZmrGWBBmE0kJ1vqOG/NAxwaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-es6": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-5.0.1.tgz", + "integrity": "sha512-XusTPuewnSUdoxRSx8OOI6xIA/uld/wMQwYsouvFN2LAg7HgP06NF1lHRV3x6BZxyL2Kkoih4ewcq8hcbGtwew==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-postcss": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-7.0.1.tgz", + "integrity": "sha512-bEOVpHU9picRZux5XnwGsmCN4+8oZo7vSW0O0/Enq/TO5R2pIAP2279NsszpJR7ocnQt4WXU0+nnh/0JuK4KHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-url": "^1.2.4", + "postcss-values-parser": "^6.0.2" + }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.47" + } + }, + "node_modules/detective-sass": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-6.0.1.tgz", + "integrity": "sha512-jSGPO8QDy7K7pztUmGC6aiHkexBQT4GIH+mBAL9ZyBmnUIOFbkfZnO8wPRRJFP/QP83irObgsZHCoDHZ173tRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-scss": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-5.0.1.tgz", + "integrity": "sha512-MAyPYRgS6DCiS6n6AoSBJXLGVOydsr9huwXORUlJ37K3YLyiN0vYHpzs3AdJOgHobBfispokoqrEon9rbmKacg==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-stylus": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-5.0.1.tgz", + "integrity": "sha512-Dgn0bUqdGbE3oZJ+WCKf8Dmu7VWLcmRJGc6RCzBgG31DLIyai9WAoEhYRgIHpt/BCRMrnXLbGWGPQuBUrnF0TA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-typescript": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-14.0.0.tgz", + "integrity": "sha512-pgN43/80MmWVSEi5LUuiVvO/0a9ss5V7fwVfrJ4QzAQRd3cwqU1SfWGXJFcNKUqoD5cS+uIovhw5t/0rSeC5Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "^8.23.0", + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/detective-vue2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/detective-vue2/-/detective-vue2-2.2.0.tgz", + "integrity": "sha512-sVg/t6O2z1zna8a/UIV6xL5KUa2cMTQbdTIIvqNM0NIPswp52fe43Nwmbahzj3ww4D844u/vC2PYfiGLvD3zFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dependents/detective-less": "^5.0.1", + "@vue/compiler-sfc": "^3.5.13", + "detective-es6": "^5.0.1", + "detective-sass": "^6.0.1", + "detective-scss": "^5.0.1", + "detective-stylus": "^5.0.1", + "detective-typescript": "^14.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.191", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz", + "integrity": "sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, + "node_modules/enhanced-resolve": { + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", + "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -3381,6 +4006,72 @@ "node": ">=6" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "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/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "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, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -3397,6 +4088,60 @@ "dev": true, "license": "MIT" }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filing-cabinet": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-5.0.3.tgz", + "integrity": "sha512-PlPcMwVWg60NQkhvfoxZs4wEHjhlOO/y7OAm4sKM60o1Z9nttRY4mcdQxp/iZ+kg/Vv6Hw1OAaTbYVM9DA9pYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-module-path": "^2.2.0", + "commander": "^12.1.0", + "enhanced-resolve": "^5.18.0", + "module-definition": "^6.0.1", + "module-lookup-amd": "^9.0.3", + "resolve": "^1.22.10", + "resolve-dependency-path": "^4.0.1", + "sass-lookup": "^6.1.0", + "stylus-lookup": "^6.1.0", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.7.3" + }, + "bin": { + "filing-cabinet": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/filing-cabinet/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -3455,6 +4200,13 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3487,6 +4239,20 @@ "node": ">=6.9.0" } }, + "node_modules/get-amd-module-type": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-6.0.1.tgz", + "integrity": "sha512-MtjsmYiCXcYDDrGqtNbeIYdAl85n+5mSv2r3FbzER/YV3ZILw4HNNIw34HuV5pyl0jzs6GFYU1VHVEefhgcNHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3509,6 +4275,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true, + "license": "ISC" + }, "node_modules/get-tsconfig": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", @@ -3543,32 +4316,29 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/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", - "dependencies": { - "brace-expansion": "^2.0.1" + "minimist": "^1.2.5" }, - "engines": { - "node": ">=16 || 14 >=14.17" + "bin": { + "gonzales": "bin/gonzales.js" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=0.6.0" } }, + "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/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3633,6 +4403,27 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/index-to-position": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", @@ -3645,8 +4436,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-core-module": { - "version": "2.16.1", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-core-module": { + "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, @@ -3670,6 +4475,16 @@ "node": ">=8" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3680,6 +4495,16 @@ "node": ">=0.12.0" } }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-reference": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", @@ -3689,6 +4514,49 @@ "@types/estree": "^1.0.6" } }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3929,6 +4797,23 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/log-update": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", @@ -4043,6 +4928,55 @@ "yallist": "^3.0.2" } }, + "node_modules/madge": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/madge/-/madge-8.0.0.tgz", + "integrity": "sha512-9sSsi3TBPhmkTCIpVQF0SPiChj1L7Rq9kU2KDG1o6v2XH9cCw086MopjVCD+vuoL5v8S77DTbVopTO8OUiQpIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^7.2.0", + "commondir": "^1.0.1", + "debug": "^4.3.4", + "dependency-tree": "^11.0.0", + "ora": "^5.4.1", + "pluralize": "^8.0.0", + "pretty-ms": "^7.0.1", + "rc": "^1.2.8", + "stream-to-array": "^2.3.0", + "ts-graphviz": "^2.1.2", + "walkdir": "^0.4.1" + }, + "bin": { + "madge": "bin/cli.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/pahen" + }, + "peerDependencies": { + "typescript": "^5.4.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/madge/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -4094,6 +5028,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", @@ -4107,6 +5051,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -4117,6 +5087,97 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/module-definition": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-6.0.1.tgz", + "integrity": "sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/module-lookup-amd": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-9.0.5.tgz", + "integrity": "sha512-Rs5FVpVcBYRHPLuhHOjgbRhosaQYLtEo3JIeDIbmNo7mSssi1CTzwMh8v36gAzpbzLGXI9wB/yHh+5+3fY1QVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0", + "glob": "^7.2.3", + "requirejs": "^2.3.7", + "requirejs-config-file": "^4.0.0" + }, + "bin": { + "lookup-amd": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/module-lookup-amd/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/module-lookup-amd/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/module-lookup-amd/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/module-lookup-amd/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4137,6 +5198,25 @@ "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" } }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/node-module-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/node-module-type/-/node-module-type-1.0.4.tgz", @@ -4158,6 +5238,19 @@ "dev": true, "license": "MIT" }, + "node_modules/node-source-walk": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-7.0.1.tgz", + "integrity": "sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.7" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/normalize-package-data": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.1.tgz", @@ -4189,6 +5282,80 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/oxc-parser": { "version": "0.105.0", "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.105.0.tgz", @@ -4310,6 +5477,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4335,59 +5512,171 @@ "dev": true, "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "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==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-values-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz", + "integrity": "sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MPL-2.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": ">=10" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "postcss": "^8.2.9" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "node_modules/precinct": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-12.2.0.tgz", + "integrity": "sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w==", "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" + "@dependents/detective-less": "^5.0.1", + "commander": "^12.1.0", + "detective-amd": "^6.0.1", + "detective-cjs": "^6.0.1", + "detective-es6": "^5.0.1", + "detective-postcss": "^7.0.1", + "detective-sass": "^6.0.1", + "detective-scss": "^5.0.1", + "detective-stylus": "^5.0.1", + "detective-typescript": "^14.0.0", + "detective-vue2": "^2.2.0", + "module-definition": "^6.0.1", + "node-source-walk": "^7.0.1", + "postcss": "^8.5.1", + "typescript": "^5.7.3" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": ">=18" } }, - "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/pidtree": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "node_modules/precinct/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "license": "MIT", - "bin": { - "pidtree": "bin/pidtree.js" - }, "engines": { - "node": ">=0.10" + "node": ">=18" } }, "node_modules/prettier": { @@ -4406,6 +5695,45 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, "node_modules/read-package-up": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", @@ -4442,6 +5770,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -4522,6 +5865,34 @@ "node": ">=0.10.0" } }, + "node_modules/requirejs": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.8.tgz", + "integrity": "sha512-7/cTSLOdYkNBNJcDMWf+luFvMriVm7eYxp4BcFCsAX0wF421Vyce5SXP17c+Jd5otXKGNehIonFlyQXSowL6Mw==", + "dev": true, + "license": "MIT", + "bin": { + "r_js": "bin/r.js", + "r.js": "bin/r.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -4543,6 +5914,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-dependency-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-4.0.1.tgz", + "integrity": "sha512-YQftIIC4vzO9UMhO/sCgXukNyiwVRCVaxiWskCBy7Zpqkplm8kTAISZ8O1MoKW1ca6xzgLUBjZTcDgypXvXxiQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -4576,6 +5957,54 @@ "dev": true, "license": "MIT" }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/sass-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-6.1.0.tgz", + "integrity": "sha512-Zx+lVyoWqXZxHuYWlTA17Z5sczJ6braNT2C7rmClw+c4E7r/n911Zwss3h1uHI9reR5AgHZyNHF7c2+VIp5AUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0", + "enhanced-resolve": "^5.18.0" + }, + "bin": { + "sass-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sass-lookup/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -4668,6 +6097,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -4700,6 +6150,26 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, + "node_modules/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -4780,6 +6250,21 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4806,6 +6291,52 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylus-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-6.1.0.tgz", + "integrity": "sha512-5QSwgxAzXPMN+yugy61C60PhoANdItfdjSEZR8siFwz7yL9jTmV0UBKDCfn3K8GkGB4g0Y9py7vTCX8rFu4/pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0" + }, + "bin": { + "stylus-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/stylus-lookup/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4831,6 +6362,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", @@ -4846,30 +6391,21 @@ "node": ">=18" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/test-exclude/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", - "dependencies": { - "brace-expansion": "^2.0.1" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=12.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/SuperchupuDev" } }, "node_modules/to-regex-range": { @@ -4885,6 +6421,60 @@ "node": ">=8.0" } }, + "node_modules/ts-api-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.3.0.tgz", + "integrity": "sha512-6eg3Y9SF7SsAvGzRHQvvc1skDAhwI4YQ32ui1scxD1Ccr0G5qIIbUBT3pFTKX8kmWIQClHobtUdNuaBgwdfdWg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-graphviz": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-2.1.6.tgz", + "integrity": "sha512-XyLVuhBVvdJTJr2FJJV2L1pc4MwSjMhcunRVgDE9k4wbb2ee7ORYnPewxMWUav12vxyfUM686MSGsqnVRIInuw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/adapter": "^2.0.6", + "@ts-graphviz/ast": "^2.0.7", + "@ts-graphviz/common": "^2.1.5", + "@ts-graphviz/core": "^2.0.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -4930,6 +6520,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5032,6 +6623,13 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -5056,6 +6654,26 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index abb74d6..5c3491c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@knighted/module", - "version": "1.1.0", + "version": "1.1.1", "description": "Bidirectional transform for ES modules and CommonJS.", "type": "module", "main": "dist/module.js", @@ -18,14 +18,6 @@ }, "./package.json": "./package.json" }, - "imports": { - "#parse": "./src/parse.js", - "#format": "./src/format.js", - "#utils/*.js": "./src/utils/*.js", - "#walk": "./src/walk.js", - "#helpers/*.js": "./src/helpers/*.js", - "#formatters/*.js": "./src/formatters/*.js" - }, "engines": { "node": ">=22.21.1 <23 || >=24 <25" }, @@ -40,8 +32,8 @@ "build:types": "tsc --emitDeclarationOnly", "build:dual": "babel-dual-package src --extensions .ts", "build": "npm run build:types && npm run build:dual", - "prepack": "npm run build && node scripts/setImportsToDist.js", - "postpack": "node scripts/restoreImportsToSrc.js" + "cycles": "madge --circular src --extensions ts,js --ts-config tsconfig.json", + "prepack": "npm run build" }, "keywords": [ "esm", @@ -72,6 +64,7 @@ "c8": "^10.1.3", "husky": "^9.1.7", "lint-staged": "^16.2.7", + "madge": "^8.0.0", "oxlint": "^1.35.0", "prettier": "^3.7.4", "tsx": "^4.21.0", @@ -83,6 +76,11 @@ "oxc-parser": "^0.105.0", "periscopic": "^4.0.2" }, + "overrides": { + "module-lookup-amd": { + "glob": "^9.0.0" + } + }, "prettier": { "arrowParens": "avoid", "printWidth": 90, diff --git a/scripts/restoreImportsToSrc.js b/scripts/restoreImportsToSrc.js deleted file mode 100644 index 5c0bcfd..0000000 --- a/scripts/restoreImportsToSrc.js +++ /dev/null @@ -1,38 +0,0 @@ -import { readFile, writeFile } from 'node:fs/promises' -import { resolve } from 'node:path' - -const pkgPath = resolve('package.json') -const srcImports = { - '#parse': './src/parse.js', - '#format': './src/format.js', - '#utils/*.js': './src/utils/*.js', - '#walk': './src/walk.js', - '#helpers/*.js': './src/helpers/*.js', - '#formatters/*.js': './src/formatters/*.js', -} - -const main = async () => { - try { - const raw = await readFile(pkgPath, 'utf8') - const pkg = JSON.parse(raw) - pkg.imports ||= {} - - let changed = false - for (const [key, value] of Object.entries(srcImports)) { - if (pkg.imports[key] !== value) { - pkg.imports[key] = value - changed = true - } - } - - if (changed) { - await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`) - process.stdout.write('Restored package.json imports to src after pack.\n') - } - } catch (error) { - process.stderr.write(`Failed to restore imports to src: ${error}\n`) - process.exitCode = 1 - } -} - -main() diff --git a/scripts/setImportsToDist.js b/scripts/setImportsToDist.js deleted file mode 100644 index af0d5e2..0000000 --- a/scripts/setImportsToDist.js +++ /dev/null @@ -1,38 +0,0 @@ -import { readFile, writeFile } from 'node:fs/promises' -import { resolve } from 'node:path' - -const pkgPath = resolve('package.json') -const distImports = { - '#parse': './dist/parse.js', - '#format': './dist/format.js', - '#utils/*.js': './dist/utils/*.js', - '#walk': './dist/walk.js', - '#helpers/*.js': './dist/helpers/*.js', - '#formatters/*.js': './dist/formatters/*.js', -} - -const main = async () => { - try { - const raw = await readFile(pkgPath, 'utf8') - const pkg = JSON.parse(raw) - pkg.imports ||= {} - - let changed = false - for (const [key, value] of Object.entries(distImports)) { - if (pkg.imports[key] !== value) { - pkg.imports[key] = value - changed = true - } - } - - if (changed) { - await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`) - process.stdout.write('Updated package.json imports to dist for publish.\n') - } - } catch (error) { - process.stderr.write(`Failed to set imports to dist: ${error}\n`) - process.exitCode = 1 - } -} - -main() diff --git a/src/format.ts b/src/format.ts index 0972265..c15971f 100644 --- a/src/format.ts +++ b/src/format.ts @@ -1,28 +1,45 @@ -import type { ParseResult } from 'oxc-parser' +import type { Node, ParseResult } from 'oxc-parser' +import { + getModuleExportName, + isAstNode, + isCallExpressionNode, + isIdentifierNode, + isMemberExpressionNode, +} from './helpers/ast.js' +import type { + CallExpressionNode, + LiteralNode, + ModuleExportNameNode, + ProgramNode, + ImportDefaultSpecifierNode, + ImportNamespaceSpecifierNode, + ImportSpecifierNode, + ExportsMap, +} from './helpers/ast.js' import type { FormatterOptions, ExportsMeta, Diagnostic } from './types.js' import MagicString from 'magic-string' -import { identifier } from '#formatters/identifier.js' -import { metaProperty } from '#formatters/metaProperty.js' -import { memberExpression } from '#formatters/memberExpression.js' -import { assignmentExpression } from '#formatters/assignmentExpression.js' -import { isValidUrl } from '#utils/url.js' -import { exportsRename, collectCjsExports } from '#utils/exports.js' -import { collectModuleIdentifiers } from '#utils/identifiers.js' -import { isIdentifierName } from '#helpers/identifier.js' -import { ancestorWalk } from '#walk' +import { identifier } from './formatters/identifier.js' +import { metaProperty } from './formatters/metaProperty.js' +import { memberExpression } from './formatters/memberExpression.js' +import { assignmentExpression } from './formatters/assignmentExpression.js' +import { isValidUrl } from './utils/url.js' +import { exportsRename, collectCjsExports } from './utils/exports.js' +import { collectModuleIdentifiers } from './utils/identifiers.js' +import { isIdentifierName } from './helpers/identifier.js' +import { ancestorWalk } from './walk.js' const isValidIdent = (name: string) => /^[$A-Z_a-z][$\w]*$/.test(name) -const expressionHasRequireCall = (node: any, shadowed: Set) => { +const expressionHasRequireCall = (node: Node, shadowed: Set) => { let found = false - const walkNode = (n: any) => { - if (!n || found) return + const walkNode = (n: unknown) => { + if (!isAstNode(n) || found) return if ( - n.type === 'CallExpression' && - n.callee?.type === 'Identifier' && + isCallExpressionNode(n) && + isIdentifierNode(n.callee) && n.callee.name === 'require' && !shadowed.has('require') ) { @@ -31,9 +48,9 @@ const expressionHasRequireCall = (node: any, shadowed: Set) => { } if ( - n.type === 'CallExpression' && - n.callee?.type === 'MemberExpression' && - n.callee.object?.type === 'Identifier' && + isCallExpressionNode(n) && + isMemberExpressionNode(n.callee) && + isIdentifierNode(n.callee.object) && n.callee.object.name === 'require' && !shadowed.has('require') ) { @@ -41,9 +58,10 @@ const expressionHasRequireCall = (node: any, shadowed: Set) => { return } - const keys = Object.keys(n) + const record = n as unknown as Record + const keys = Object.keys(record) for (const key of keys) { - const value = (n as any)[key] + const value = record[key] if (!value) continue if (Array.isArray(value)) { for (const item of value) { @@ -79,7 +97,7 @@ const interopHelper = `const ${defaultInteropName} = mod => (mod && mod.__esModu const requireInteropName = '__requireDefault' const requireInteropHelper = `const ${requireInteropName} = mod => (mod && typeof mod === 'object' && 'default' in mod ? mod.default : mod);\n` -const isRequireCallee = (callee: any, shadowed: Set) => { +const isRequireCallee = (callee: Node, shadowed: Set) => { if ( callee.type === 'Identifier' && callee.name === 'require' && @@ -102,14 +120,14 @@ const isRequireCallee = (callee: any, shadowed: Set) => { return false } -const isStaticRequire = (node: any, shadowed: Set) => +const isStaticRequire = (node: Node, shadowed: Set) => node.type === 'CallExpression' && isRequireCallee(node.callee, shadowed) && node.arguments.length === 1 && node.arguments[0].type === 'Literal' && - typeof node.arguments[0].value === 'string' + typeof (node.arguments[0] as LiteralNode).value === 'string' -const isRequireCall = (node: any, shadowed: Set) => +const isRequireCall = (node: Node, shadowed: Set) => node.type === 'CallExpression' && isRequireCallee(node.callee, shadowed) type RequireTransform = { @@ -119,7 +137,7 @@ type RequireTransform = { } const lowerCjsRequireToImports = ( - program: any, + program: ProgramNode, code: MagicString, shadowed: Set, ) => { @@ -135,19 +153,23 @@ const lowerCjsRequireToImports = ( return base.endsWith('.json') } - for (const stmt of program.body as any[]) { + for (const stmt of program.body) { if (stmt.type === 'VariableDeclaration') { const decls = stmt.declarations const allStatic = decls.length > 0 && - decls.every((decl: any) => decl.init && isStaticRequire(decl.init, shadowed)) + decls.every(decl => decl.init && isStaticRequire(decl.init, shadowed)) if (allStatic) { for (const decl of decls) { - const init = decl.init! + const init = decl.init as CallExpressionNode | null + if (!init || !isCallExpressionNode(init)) { + needsCreateRequire = true + continue + } const arg = init.arguments[0] const source = code.slice(arg.start, arg.end) - const value = (arg as any).value as string + const value = (arg as LiteralNode).value const isJson = typeof value === 'string' && isJsonSpecifier(value) const ns = `__cjsImport${nsIndex++}` @@ -203,9 +225,14 @@ const lowerCjsRequireToImports = ( const expr = stmt.expression if (expr && isStaticRequire(expr, shadowed)) { + if (!isCallExpressionNode(expr)) { + needsCreateRequire = true + continue + } + const arg = expr.arguments[0] const source = code.slice(arg.start, arg.end) - const value = (arg as any).value as string + const value = (arg as LiteralNode).value const isJson = typeof value === 'string' && isJsonSpecifier(value) const jsonImport = isJson ? `${source} with { type: "json" }` : source @@ -224,8 +251,7 @@ const lowerCjsRequireToImports = ( return { transforms, imports, hoisted, needsCreateRequire, needsInteropHelper } } -const isRequireMainMember = (node: any, shadowed: Set) => - node && +const isRequireMainMember = (node: Node, shadowed: Set) => node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'require' && @@ -233,12 +259,14 @@ const isRequireMainMember = (node: any, shadowed: Set) => node.property.type === 'Identifier' && node.property.name === 'main' -const hasTopLevelAwait = (program: any) => { +const hasTopLevelAwait = (program: ProgramNode) => { let found = false - const walkNode = (node: any, inFunction: boolean) => { + const walkNode = (node: unknown, inFunction: boolean) => { if (found) return + if (!isAstNode(node)) return + switch (node.type) { case 'FunctionDeclaration': case 'FunctionExpression': @@ -254,9 +282,10 @@ const hasTopLevelAwait = (program: any) => { return } - const keys = Object.keys(node) + const record = node as unknown as Record + const keys = Object.keys(record) for (const key of keys) { - const value = (node as any)[key] + const value = record[key] if (!value) continue if (Array.isArray(value)) { @@ -277,7 +306,7 @@ const hasTopLevelAwait = (program: any) => { return found } -const isAsyncContext = (ancestors: any[]) => { +const isAsyncContext = (ancestors: Node[]) => { for (let i = ancestors.length - 1; i >= 0; i -= 1) { const node = ancestors[i] if ( @@ -298,7 +327,7 @@ const isAsyncContext = (ancestors: any[]) => { } const lowerEsmToCjs = ( - program: any, + program: ProgramNode, code: MagicString, opts: FormatterOptions, containsTopLevelAwait: boolean, @@ -309,15 +338,19 @@ const lowerEsmToCjs = ( let needsInterop = false let importIndex = 0 - for (const node of program.body as any[]) { + for (const node of program.body) { if (node.type === 'ImportDeclaration') { const srcLiteral = code.slice(node.source.start, node.source.end) const specifiers = node.specifiers ?? [] - const defaultSpec = specifiers.find((s: any) => s.type === 'ImportDefaultSpecifier') + const defaultSpec = specifiers.find( + (s): s is ImportDefaultSpecifierNode => s.type === 'ImportDefaultSpecifier', + ) const namespaceSpec = specifiers.find( - (s: any) => s.type === 'ImportNamespaceSpecifier', + (s): s is ImportNamespaceSpecifierNode => s.type === 'ImportNamespaceSpecifier', + ) + const namedSpecs = specifiers.filter( + (s): s is ImportSpecifierNode => s.type === 'ImportSpecifier', ) - const namedSpecs = specifiers.filter((s: any) => s.type === 'ImportSpecifier') // Side-effect import if (!specifiers.length) { @@ -358,8 +391,9 @@ const lowerEsmToCjs = ( } if (namedSpecs.length) { - const pairs = namedSpecs.map((s: any) => { - const imported = s.imported.name + const pairs = namedSpecs.map(s => { + const imported = getModuleExportName(s.imported as ModuleExportNameNode) + if (!imported) return s.local.name const local = s.local.name return imported === local ? imported : `${imported}: ${local}` }) @@ -387,13 +421,11 @@ const lowerEsmToCjs = ( exportedNames.push(d.id.name) } } - } else if ((decl as any).id?.type === 'Identifier') { - exportedNames.push((decl as any).id.name) + } else if ('id' in decl && decl.id?.type === 'Identifier') { + exportedNames.push(decl.id.name) } - const exportLines = exportedNames.map(name => - exportAssignment(name, name, live as any), - ) + const exportLines = exportedNames.map(name => exportAssignment(name, name, live)) exportTransforms.push({ start: node.start, @@ -412,8 +444,9 @@ const lowerEsmToCjs = ( for (const spec of node.specifiers) { if (spec.type !== 'ExportSpecifier') continue - const exported = spec.exported.name - const imported = spec.local.name + const exported = getModuleExportName(spec.exported as ModuleExportNameNode) + const imported = getModuleExportName(spec.local as ModuleExportNameNode) + if (!exported || !imported) continue let rhs = `${modIdent}.${imported}` if (imported === 'default') { @@ -421,7 +454,7 @@ const lowerEsmToCjs = ( needsInterop = true } - lines.push(exportAssignment(exported, rhs, live as any)) + lines.push(exportAssignment(exported, rhs, live)) } exportTransforms.push({ @@ -434,9 +467,11 @@ const lowerEsmToCjs = ( const lines: string[] = [] for (const spec of node.specifiers) { if (spec.type !== 'ExportSpecifier') continue - const exported = spec.exported.name - const local = spec.local.name - lines.push(exportAssignment(exported, local, live as any)) + const exported = getModuleExportName(spec.exported as ModuleExportNameNode) + const local = getModuleExportName(spec.local as ModuleExportNameNode) + if (!exported || !local) continue + + lines.push(exportAssignment(exported, local, live)) } exportTransforms.push({ start: node.start, @@ -487,12 +522,15 @@ const lowerEsmToCjs = ( if (node.type === 'ExportAllDeclaration') { const srcLiteral = code.slice(node.source.start, node.source.end) - if ((node as any).exported) { - const exported = (node as any).exported.name + if ('exported' in node && node.exported) { + const exported = getModuleExportName(node.exported as ModuleExportNameNode) + if (!exported) { + continue + } const modIdent = `__mod${importIndex++}` const lines = [ `const ${modIdent} = require(${srcLiteral});`, - exportAssignment(exported, modIdent, live as any), + exportAssignment(exported, modIdent, live), ] exportTransforms.push({ start: node.start, @@ -592,7 +630,7 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => } } - const exportTable = + const exportTable: ExportsMap | null = opts.target === 'module' ? await collectCjsExports(ast.program) : null const idiomaticMode = opts.target === 'module' && fullTransform ? (opts.idiomaticExports ?? 'safe') : 'off' @@ -675,7 +713,7 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => ]) const isValidExportName = (name: string) => /^[$A-Z_a-z][$\w]*$/.test(name) && !reservedExports.has(name) - const isAllowedRhs = (node: any) => { + const isAllowedRhs = (node: Node) => { return ( node.type === 'Identifier' || node.type === 'Literal' || @@ -691,7 +729,7 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => const entries = [...exportTable.values()] if (!entries.length) return { ok: false, reason: 'no-exports' } - if ((exportTable as any).hasUnsupportedExportWrite) { + if (exportTable.hasUnsupportedExportWrite) { return { ok: false, reason: 'unsupported-left' } } @@ -714,7 +752,7 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => const requireShadowed = shadowedBindings - const rhsSourceFor = (node: any) => { + const rhsSourceFor = (node: Node) => { const raw = code.slice(node.start, node.end) return raw .replace(/\b__dirname\b/g, 'import.meta.dirname') @@ -722,7 +760,7 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => } for (const entry of entries) { - const write = entry.writes[0] as any + const write = entry.writes[0] if (write.type !== 'AssignmentExpression') { return { ok: false, reason: 'unsupported-write-kind' } } @@ -937,7 +975,7 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => if (asyncCapable) { const arg = node.arguments[0] const argSrc = arg ? code.slice(arg.start, arg.end) : 'undefined' - const literalVal = (arg as any)?.value + const literalVal = (arg as LiteralNode | undefined)?.value const isJson = arg?.type === 'Literal' && typeof literalVal === 'string' && @@ -1064,7 +1102,7 @@ const format = async (src: string, ast: ParseResult, opts: FormatterOptions) => } if (shouldRaiseEsm && node.type === 'ThisExpression') { - const bindsThis = (ancestor: any) => { + const bindsThis = (ancestor: Node) => { return ( ancestor.type === 'FunctionDeclaration' || ancestor.type === 'FunctionExpression' || diff --git a/src/formatters/assignmentExpression.ts b/src/formatters/assignmentExpression.ts index 390ac54..65c33a9 100644 --- a/src/formatters/assignmentExpression.ts +++ b/src/formatters/assignmentExpression.ts @@ -1,6 +1,6 @@ import MagicString from 'magic-string' import type { Node, AssignmentExpression } from 'oxc-parser' -import { walk } from '#walk' +import { walk } from '../walk.js' import type { FormatterOptions, ExportsMeta } from '../types.js' diff --git a/src/formatters/identifier.ts b/src/formatters/identifier.ts index 855bb9e..2a7ddfd 100644 --- a/src/formatters/identifier.ts +++ b/src/formatters/identifier.ts @@ -2,8 +2,8 @@ import MagicString from 'magic-string' import type { Node, IdentifierName } from 'oxc-parser' import type { FormatterOptions, ExportsMeta } from '../types.js' -import { exportsRename } from '#utils/exports.js' -import { identifier as ident } from '#helpers/identifier.js' +import { exportsRename } from '../utils/exports.js' +import { identifier as ident } from '../helpers/identifier.js' type IdentifierArg = { node: IdentifierName diff --git a/src/formatters/memberExpression.ts b/src/formatters/memberExpression.ts index 62a87fa..0473f88 100644 --- a/src/formatters/memberExpression.ts +++ b/src/formatters/memberExpression.ts @@ -2,7 +2,7 @@ import MagicString from 'magic-string' import type { MemberExpression, Node } from 'oxc-parser' import type { FormatterOptions } from '../types.js' -import { exportsRename } from '#utils/exports.js' +import { exportsRename } from '../utils/exports.js' type MemberExpressionExtras = { onRequireResolve?: () => void diff --git a/src/helpers/ast.ts b/src/helpers/ast.ts new file mode 100644 index 0000000..7855405 --- /dev/null +++ b/src/helpers/ast.ts @@ -0,0 +1,47 @@ +import type { Node } from 'oxc-parser' +import type { CjsExport } from '../types.js' + +export type IdentifierNode = Extract +export type LiteralNode = Extract +export type MemberExpressionNode = Extract +export type CallExpressionNode = Extract +export type ProgramNode = Extract +export type ModuleExportNameNode = Extract +export type ImportDefaultSpecifierNode = Extract +export type ImportNamespaceSpecifierNode = Extract< + Node, + { type: 'ImportNamespaceSpecifier' } +> +export type ImportSpecifierNode = Extract +export type ExportsMap = Map & { hasUnsupportedExportWrite?: boolean } + +export const isAstNode = (value: unknown): value is Node => { + return Boolean(value) && typeof value === 'object' && 'type' in (value as object) +} + +export const isIdentifierNode = ( + node: Node | null | undefined, +): node is IdentifierNode => { + return node?.type === 'Identifier' +} + +export const isMemberExpressionNode = ( + node: Node | null | undefined, +): node is MemberExpressionNode => { + return node?.type === 'MemberExpression' +} + +export const isCallExpressionNode = ( + node: Node | null | undefined, +): node is CallExpressionNode => { + return node?.type === 'CallExpression' +} + +export const getModuleExportName = ( + name: ModuleExportNameNode | null | undefined, +): string | null => { + if (!name) return null + if (name.type === 'Identifier') return name.name + if (name.type === 'Literal' && typeof name.value === 'string') return name.value + return null +} diff --git a/src/helpers/identifier.ts b/src/helpers/identifier.ts index 0cf9c92..b20c988 100644 --- a/src/helpers/identifier.ts +++ b/src/helpers/identifier.ts @@ -1,5 +1,6 @@ import type { Node, IdentifierName } from 'oxc-parser' import { analyze, type Scope as PeriscopicScope } from 'periscopic' +import type { Program as EstreeProgram } from 'estree' /** * Focus exclusively on IdentifierName type as it has the name property, @@ -26,7 +27,7 @@ const getScopeContext = (program: Node): ScopeContext => { return cached } - const { scope } = analyze(program as any) + const { scope } = analyze(program as unknown as EstreeProgram) const context = { scope } scopeCache.set(program, context) return context @@ -179,24 +180,24 @@ const identifier = { ] const declaratorIndex = ancestors.findIndex(ancestor => { - return ( - ancestor.type === 'VariableDeclarator' && - (ancestor === node || isInBindingPattern((ancestor as any).id, node)) - ) + if (ancestor.type !== 'VariableDeclarator') return false + return ancestor === node || isInBindingPattern(ancestor.id, node) }) if (declaratorIndex === -1) return false - const declarator = ancestors[declaratorIndex] as any + const declaratorNode = ancestors[declaratorIndex] const declaration = ancestors[declaratorIndex - 1] + if (declaratorNode?.type !== 'VariableDeclarator') return false + return ( declaration?.type === 'VariableDeclaration' && declaration.kind === 'var' && ancestors.every(ancestor => { return !varBoundScopes.includes(ancestor.type) }) && - (declarator.id === node || isInBindingPattern(declarator.id, node)) + (declaratorNode.id === node || isInBindingPattern(declaratorNode.id, node)) ) }, diff --git a/src/module.ts b/src/module.ts index f87a0c2..eb2f1cb 100644 --- a/src/module.ts +++ b/src/module.ts @@ -5,15 +5,15 @@ import { specifier } from './specifier.js' import type { Spec } from './specifier.js' import type { TemplateLiteral } from 'oxc-parser' -import { parse } from '#parse' -import { format } from '#format' -import { getLangFromExt } from '#utils/lang.js' +import { parse } from './parse.js' +import { format } from './format.js' +import { getLangFromExt } from './utils/lang.js' import type { ModuleOptions } from './types.js' import { builtinModules } from 'node:module' import { resolve as pathResolve, dirname as pathDirname, extname, join } from 'node:path' import { readFile as fsReadFile, stat } from 'node:fs/promises' -import { parse as parseModule } from '#parse' -import { walk } from '#walk' +import { parse as parseModule } from './parse.js' +import { walk } from './walk.js' type AppendJsExtensionMode = NonNullable type DetectCircularRequires = NonNullable diff --git a/src/specifier.ts b/src/specifier.ts index c6a6c90..baa0a99 100644 --- a/src/specifier.ts +++ b/src/specifier.ts @@ -19,7 +19,7 @@ import type { } from 'oxc-parser' import { parseSync } from 'oxc-parser' -import { walk } from '#walk' +import { walk } from './walk.js' type Spec = { type: 'StringLiteral' | 'TemplateLiteral' | 'BinaryExpression' | 'NewExpression' @@ -206,7 +206,7 @@ const formatSpecifiers = async (src: string, ast: ParseResult, cb: Callback) => } if (node.type === 'TSImportType') { - const source = (node as any).source + const source = (node as { source?: Node }).source if (source && isStringLiteral(source)) { const { start, end, value } = source diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index ea69f55..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,324 +0,0 @@ -import { ancestorWalk } from './walk.js' - -import type { Node } from 'oxc-parser' - -import type { IdentMeta, SpannedNode, Scope, CjsExport } from './types.js' -import { identifier } from './helpers/identifier.js' -import { scopeNodes } from './utils/scopeNodes.js' - -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 resolveExportTarget = (node: Node) => { - if (node.type !== 'MemberExpression') return null - - const base = node.object - const prop = node.property - - if (prop.type !== 'Identifier') return null - - if (base.type === 'Identifier' && base.name === 'exports') { - return { key: prop.name, via: 'exports' as const } - } - - if ( - base.type === 'MemberExpression' && - base.object.type === 'Identifier' && - base.object.name === 'module' && - base.property.type === 'Identifier' && - base.property.name === 'exports' - ) { - return { key: prop.name, via: 'module.exports' as const } - } - - if ( - base.type === 'Identifier' && - base.name === 'module' && - prop.type === 'Identifier' && - prop.name === 'exports' - ) { - return { key: 'default', via: 'module.exports' as const } - } - - return null -} - -const collectCjsExports = async (ast: Node) => { - const exportsMap = new Map() - const localToExport = new Map>() - - await ancestorWalk(ast, { - enter(node) { - if (node.type === 'AssignmentExpression') { - const target = resolveExportTarget(node.left) - - if (target) { - const entry = exportsMap.get(target.key) ?? { - key: target.key, - writes: [], - via: new Set(), - reassignments: [], - } - - entry.via.add(target.via) - entry.writes.push(node) - - if (node.right.type === 'Identifier') { - entry.fromIdentifier ??= node.right.name - if (entry.fromIdentifier) { - const set = localToExport.get(entry.fromIdentifier) ?? new Set() - set.add(target.key) - localToExport.set(entry.fromIdentifier, set) - } - } - - exportsMap.set(target.key, entry) - return - } - - if (node.left.type === 'Identifier') { - const keys = localToExport.get(node.left.name) - - if (keys) { - keys.forEach(key => { - const entry = exportsMap.get(key) - if (entry) { - entry.reassignments.push(node) - exportsMap.set(key, entry) - } - }) - } - } - } - }, - }) - - return exportsMap -} - -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) - - const parent = ancestors[ancestors.length - 2] - const grandParent = ancestors[ancestors.length - 3] - const hoistSafe = - parent.type === 'FunctionDeclaration' || - (parent.type === 'VariableDeclarator' && - grandParent?.type === 'VariableDeclaration' && - grandParent.kind === 'var') - - if ( - isModuleScope || - isClassOrFuncDeclaration || - isVarDeclarationInGlobalScope - ) { - meta.declare.push(node) - - // Check for hoisted reads - if (hoisting && hoistSafe && 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 { - isValidUrl, - collectScopeIdentifiers, - collectModuleIdentifiers, - collectCjsExports, - exportsRename, - requireMainRgx, -} diff --git a/src/utils/exports.ts b/src/utils/exports.ts index 3eb5f3a..3767b48 100644 --- a/src/utils/exports.ts +++ b/src/utils/exports.ts @@ -1,7 +1,7 @@ import type { Node } from 'oxc-parser' -import type { CjsExport } from '../types.js' -import { ancestorWalk } from '#walk' +import type { CjsExport, SpannedNode } from '../types.js' +import { ancestorWalk } from '../walk.js' const exportsRename = '__exports' const requireMainRgx = /(require\.main\s*===\s*module|module\s*===\s*require\.main)/g @@ -103,8 +103,12 @@ const resolveBase = ( return null } +type ExportsMap = Map & { + hasUnsupportedExportWrite?: boolean +} + const collectCjsExports = async (ast: Node) => { - const exportsMap = new Map() + const exportsMap: ExportsMap = new Map() const localToExport = new Map>() const aliases = new Map() const literals = new Map() @@ -133,7 +137,7 @@ const collectCjsExports = async (ast: Node) => { } entry.via.add(ref.via) - entry.writes.push(node as any) + entry.writes.push(node as SpannedNode) if (options?.hasGetter) { entry.hasGetter = true @@ -214,7 +218,7 @@ const collectCjsExports = async (ast: Node) => { keys.forEach(key => { const entry = exportsMap.get(key) if (entry) { - entry.reassignments.push(node as any) + entry.reassignments.push(node as SpannedNode) exportsMap.set(key, entry) } }) @@ -389,7 +393,7 @@ const collectCjsExports = async (ast: Node) => { } }, }) - ;(exportsMap as any).hasUnsupportedExportWrite = hasUnsupportedExportWrite + exportsMap.hasUnsupportedExportWrite = hasUnsupportedExportWrite return exportsMap } diff --git a/src/utils/identifiers.ts b/src/utils/identifiers.ts index 9f4935d..34f8175 100644 --- a/src/utils/identifiers.ts +++ b/src/utils/identifiers.ts @@ -1,11 +1,11 @@ import type { Node } from 'oxc-parser' import type { IdentMeta, SpannedNode, Scope } from '../types.js' -import { ancestorWalk } from '#walk' -import { identifier } from '#helpers/identifier.js' +import { ancestorWalk } from '../walk.js' +import { identifier } from '../helpers/identifier.js' import { scopeNodes } from './scopeNodes.js' -const addBindingNames = (pattern: any, into: Set) => { +const addBindingNames = (pattern: Node | null | undefined, into: Set) => { if (!pattern) return switch (pattern.type) { diff --git a/test/helpers/identifier/isMemberExpressionRoot.ts b/test/helpers/identifier/isMemberExpressionRoot.ts deleted file mode 100644 index e69de29..0000000 diff --git a/test/helpers/identifier/isModuleScope.ts b/test/helpers/identifier/isModuleScope.ts deleted file mode 100644 index 71be92f..0000000 --- a/test/helpers/identifier/isModuleScope.ts +++ /dev/null @@ -1,464 +0,0 @@ -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.js' - -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/utils.ts b/test/utils.ts index eb83d77..f7da4c6 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -4,10 +4,10 @@ import { resolve, join } from 'node:path' import { readFile } from 'node:fs/promises' import { spawnSync } from 'node:child_process' -import { parse } from '#parse' -import { collectModuleIdentifiers } from '#utils/identifiers.js' -import { collectCjsExports } from '#utils/exports.js' -import { getLangFromExt } from '#utils/lang.js' +import { parse } from '../src/parse.js' +import { collectModuleIdentifiers } from '../src/utils/identifiers.js' +import { collectCjsExports } from '../src/utils/exports.js' +import { getLangFromExt } from '../src/utils/lang.js' // Use fixtures to more easily track character offsets and line numbers in test cases. const fixtures = resolve(import.meta.dirname, 'fixtures') diff --git a/tsconfig.json b/tsconfig.json index 76f9bd1..dc92479 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "rootDir": ".", + "rootDir": "src", "module": "NodeNext", "moduleResolution": "NodeNext", "declaration": true, diff --git a/tsconfig.test.json b/tsconfig.test.json index a7b74cb..f63b1f4 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -1,6 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { + "rootDir": ".", "noEmit": true, "types": ["node"], "jsx": "preserve"