diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 445310e..caa787d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: - name: Install modules run: npm ci --ignore-scripts - name: Build - run: npm run build + run: npm run build:prod - name: Test run: npm run test - name: Generate docs @@ -66,7 +66,6 @@ jobs: - name: Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npx semantic-release - name: Set npm package url to GITHUB_OUTPUT diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 652f105..cf25a9a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,6 @@ jobs: - name: ESLint run: npm run lint - name: TypeScript validity - run: npm run build + run: npm run build:prod - name: Run Tests run: npm run test diff --git a/.gitignore b/.gitignore index fb2605e..3aafda2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,8 @@ node_modules /.eslintcache /test/utils/files/big-image.jpg /test/utils/files/big-file.jpg + +# tests +test/utils/files/big-file.bin +file.gguf +fileCreateToken.gguf \ No newline at end of file diff --git a/README.md b/README.md index 665f1d7..6bff656 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,11 @@ import {downloadFileBrowser} from "ipull/dist/browser.js"; const downloader = await downloadFileBrowser({ url: 'https://example.com/file.large', - acceptRangeIsKnown: true // cors origin request will not return the range header, but we can force it to be true (multi-connection download) + acceptRangeIsKnown: true, // overcome CORS, force multi-connection download (use only if you know the server supports range requests) + // defaultFetchDownloadInfo: { // set download info manually to overcome CORS issues && prevent multiple requests + // acceptRange: true, + // length: 40789822, + // } }); await downloader.download(); diff --git a/package-lock.json b/package-lock.json index 286627c..fd50b31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,25 +9,23 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@tinyhttp/content-disposition": "^2.2.0", + "@tinyhttp/content-disposition": "^2.2.4", "async-retry": "^1.3.3", "chalk": "^5.3.0", - "ci-info": "^4.0.0", - "cli-spinners": "^2.9.2", - "commander": "^10.0.0", - "eventemitter3": "^5.0.1", - "filenamify": "^6.0.0", - "fs-extra": "^11.1.1", - "is-unicode-supported": "^2.0.0", - "lifecycle-utils": "^1.3.1", + "ci-info": "^4.4.0", + "cli-spinners": "^3.4.0", + "commander": "^14.0.3", + "eventemitter3": "^5.0.4", + "filenamify": "^7.0.1", + "fs-extra": "^11.3.4", + "is-unicode-supported": "^2.1.0", + "lifecycle-utils": "^3.1.1", "lodash.debounce": "^4.0.8", "lowdb": "^7.0.1", - "pretty-bytes": "^6.1.0", - "pretty-ms": "^8.0.0", "sleep-promise": "^9.1.0", - "slice-ansi": "^7.1.0", + "slice-ansi": "^7.1.2", "stdout-update": "^4.0.1", - "strip-ansi": "^7.1.0", + "strip-ansi": "^7.2.0", "uid": "^2.0.2" }, "bin": { @@ -41,11 +39,10 @@ "@types/express": "^5.0.0", "@types/fs-extra": "^11.0.1", "@types/lodash.debounce": "^4.0.9", - "@types/node": "^20.4.9", + "@types/node": "^20.19.37", "@types/stream-throttle": "^0.1.4", "@typescript-eslint/eslint-plugin": "^6.3.0", "@typescript-eslint/parser": "^6.3.0", - "@vitest/ui": "^1.6.0", "dotenv": "^16.3.1", "eslint": "^8.46.0", "eslint-plugin-import": "^2.28.0", @@ -55,15 +52,15 @@ "express": "^4.21.1", "hash.js": "^1.1.7", "husky": "^8.0.3", - "semantic-release": "^24.0.0", + "semantic-release": "^25.0.3", "stream-throttle": "^0.1.3", "tslib": "^2.6.1", - "typedoc": "^0.26.3", - "typedoc-material-theme": "^1.1.0", - "typedoc-plugin-missing-exports": "^3.0.0", - "typescript": "^5.5.3", - "vitest": "^1.6.0", - "xmlhttprequest-ssl": "^2.1.1" + "typedoc": "^0.28.18", + "typedoc-material-theme": "^1.4.1", + "typedoc-plugin-missing-exports": "^4.1.3", + "typescript": "^5.9.3", + "vitest": "^4.1.0", + "xmlhttprequest-ssl": "^4.0.0" }, "engines": { "node": ">=18.0.0" @@ -85,112 +82,78 @@ "node": ">=0.10.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "node_modules/@actions/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", + "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" + "@actions/exec": "^3.0.0", + "@actions/http-client": "^4.0.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "node_modules/@actions/exec": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", + "integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" + "@actions/io": "^3.0.2" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@actions/http-client": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz", + "integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==", "dev": true, + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "tunnel": "^0.0.6", + "undici": "^6.23.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@actions/http-client/node_modules/undici": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", + "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, + "license": "MIT", "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" + "node": ">=18.17" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/@actions/io": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", + "integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==", "dev": true, - "engines": { - "node": ">=0.8.0" - } + "license": "MIT" }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, "node_modules/@colors/colors": { @@ -198,6 +161,7 @@ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.1.90" @@ -742,6 +706,40 @@ "node": ">=12" } }, + "node_modules/@emnapi/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", + "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@es-joy/jsdoccomment": { "version": "0.42.0", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", @@ -756,489 +754,124 @@ "node": ">=16" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "optional": true, - "os": [ - "aix" - ], + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], + "node_modules/@eslint-community/regexpp": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "dev": true, - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=12" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], + "node_modules/@eslint/js": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true, - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], + "node_modules/@gerrit0/mini-shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz", + "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^3.23.0", + "@shikijs/langs": "^3.23.0", + "@shikijs/themes": "^3.23.0", + "@shikijs/types": "^3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, "engines": { - "node": ">=12" + "node": ">=10.10.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], "engines": { - "node": ">=12" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=12" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", @@ -1260,10 +893,28 @@ } }, "node_modules/@material/material-color-utilities": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.2.7.tgz", - "integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==", - "dev": true + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.3.0.tgz", + "integrity": "sha512-ztmtTd6xwnuh2/xu+Vb01btgV8SQWYCaK56CkRK8gEkWe5TuDyBcYJ0wgkMRn+2VcE9KUmhvkz+N9GHrqw/C0g==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1301,147 +952,169 @@ } }, "node_modules/@octokit/auth-token": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz", - "integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 18" + "node": ">= 20" } }, "node_modules/@octokit/core": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz", - "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/auth-token": "^5.0.0", - "@octokit/graphql": "^8.0.0", - "@octokit/request": "^9.0.0", - "@octokit/request-error": "^6.0.1", - "@octokit/types": "^13.0.0", - "before-after-hook": "^3.0.2", + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 20" } }, "node_modules/@octokit/endpoint": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", - "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", + "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^13.0.0", + "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" }, "engines": { - "node": ">= 18" + "node": ">= 20" } }, "node_modules/@octokit/graphql": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.1.tgz", - "integrity": "sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/request": "^9.0.0", - "@octokit/types": "^13.0.0", + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 20" } }, "node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", - "dev": true + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "dev": true, + "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.3.tgz", - "integrity": "sha512-o4WRoOJZlKqEEgj+i9CpcmnByvtzoUYC6I8PD2SA95M+BJ2x8h7oLcVOg9qcowWXBOdcTRsMZiwvM3EyLm9AfA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^13.5.0" + "@octokit/types": "^16.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 20" }, "peerDependencies": { "@octokit/core": ">=6" } }, "node_modules/@octokit/plugin-retry": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.1.tgz", - "integrity": "sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.1.0.tgz", + "integrity": "sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/request-error": "^6.0.0", - "@octokit/types": "^13.0.0", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", "bottleneck": "^2.15.3" }, "engines": { - "node": ">= 18" + "node": ">= 20" }, "peerDependencies": { - "@octokit/core": ">=6" + "@octokit/core": ">=7" } }, "node_modules/@octokit/plugin-throttling": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.1.tgz", - "integrity": "sha512-Qd91H4liUBhwLB2h6jZ99bsxoQdhgPk6TdwnClPyTBSDAdviGPceViEgUwj+pcQDmB/rfAXAXK7MTochpHM3yQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.3.tgz", + "integrity": "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^13.0.0", + "@octokit/types": "^16.0.0", "bottleneck": "^2.15.3" }, "engines": { - "node": ">= 18" + "node": ">= 20" }, "peerDependencies": { - "@octokit/core": "^6.0.0" + "@octokit/core": "^7.0.0" } }, "node_modules/@octokit/request": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", - "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz", + "integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/endpoint": "^10.0.0", - "@octokit/request-error": "^6.0.1", - "@octokit/types": "^13.1.0", + "@octokit/endpoint": "^11.0.2", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "fast-content-type-parse": "^3.0.0", "universal-user-agent": "^7.0.2" }, "engines": { - "node": ">= 18" + "node": ">= 20" } }, "node_modules/@octokit/request-error": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.4.tgz", - "integrity": "sha512-VpAhIUxwhWZQImo/dWAN/NpPqqojR6PSLgLYAituLM6U+ddx9hCioFGwBr5Mi+oi5CLeJkcAs3gJ0PYYzU6wUg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/types": "^13.0.0" + "@octokit/types": "^16.0.0" }, "engines": { - "node": ">= 18" + "node": ">= 20" } }, "node_modules/@octokit/types": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", - "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^22.2.0" + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.120.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.120.0.tgz", + "integrity": "sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" } }, "node_modules/@pnpm/config.env-replace": { @@ -1449,6 +1122,7 @@ "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.22.0" } @@ -1458,6 +1132,7 @@ "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "4.2.10" }, @@ -1469,13 +1144,15 @@ "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-3.0.2.tgz", + "integrity": "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==", "dev": true, + "license": "MIT", "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", @@ -1485,12 +1162,6 @@ "node": ">=12" } }, - "node_modules/@polka/url": { - "version": "1.0.0-next.24", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", - "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", - "dev": true - }, "node_modules/@reflink/reflink": { "version": "0.1.16", "resolved": "https://registry.npmjs.org/@reflink/reflink/-/reflink-0.1.16.tgz", @@ -1630,232 +1301,288 @@ "node": ">= 10" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", - "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", - "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.10.tgz", + "integrity": "sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", - "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.10.tgz", + "integrity": "sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", - "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.10.tgz", + "integrity": "sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", - "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.10.tgz", + "integrity": "sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==", "cpu": [ - "arm" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" - ] + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", - "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.10.tgz", + "integrity": "sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", - "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.10.tgz", + "integrity": "sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", - "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.10.tgz", + "integrity": "sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", - "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.10.tgz", + "integrity": "sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", - "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.10.tgz", + "integrity": "sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==", "cpu": [ - "riscv64" + "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", - "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.10.tgz", + "integrity": "sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==", "cpu": [ - "s390x" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", - "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.10.tgz", + "integrity": "sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", - "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.10.tgz", + "integrity": "sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", - "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.10.tgz", + "integrity": "sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==", "cpu": [ - "arm64" + "wasm32" ], "dev": true, + "license": "MIT", "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", - "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.10.tgz", + "integrity": "sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==", "cpu": [ - "ia32" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", - "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.10.tgz", + "integrity": "sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.10.tgz", + "integrity": "sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==", + "dev": true, + "license": "MIT" }, "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@semantic-release/commit-analyzer": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.0.tgz", - "integrity": "sha512-KtXWczvTAB1ZFZ6B4O+w8HkfYm/OgQb1dUGNFZtDgQ0csggrmkq8sTxhd+lwGF8kMb59/RnG9o4Tn7M/I8dQ9Q==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.1.tgz", + "integrity": "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==", "dev": true, + "license": "MIT", "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", - "import-from-esm": "^1.0.3", + "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "micromatch": "^4.0.2" }, @@ -1867,10 +1594,11 @@ } }, "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-changelog-angular": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.0.0.tgz", - "integrity": "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.1.0.tgz", + "integrity": "sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==", "dev": true, + "license": "ISC", "dependencies": { "compare-func": "^2.0.0" }, @@ -1879,10 +1607,11 @@ } }, "node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.0.0.tgz", - "integrity": "sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.2.1.tgz", + "integrity": "sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==", "dev": true, + "license": "MIT", "dependencies": { "meow": "^13.0.0" }, @@ -1898,6 +1627,7 @@ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -1910,6 +1640,7 @@ "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } @@ -2064,123 +1795,73 @@ } }, "node_modules/@semantic-release/github": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-10.1.0.tgz", - "integrity": "sha512-g4RHBaCWJjGcEy95TeTdajlmUoP5jAaF5trGkFXHKsT/VpCwawhZbNW66+sUr0c2CIAdfpCxxmK+E7GyWBWJDw==", + "version": "12.0.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-12.0.6.tgz", + "integrity": "sha512-aYYFkwHW3c6YtHwQF0t0+lAjlU+87NFOZuH2CvWFD0Ylivc7MwhZMiHOJ0FMpIgPpCVib/VUAcOwvrW0KnxQtA==", "dev": true, + "license": "MIT", "dependencies": { - "@octokit/core": "^6.0.0", - "@octokit/plugin-paginate-rest": "^11.0.0", - "@octokit/plugin-retry": "^7.0.0", - "@octokit/plugin-throttling": "^9.0.0", + "@octokit/core": "^7.0.0", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-retry": "^8.0.0", + "@octokit/plugin-throttling": "^11.0.0", "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", "debug": "^4.3.4", "dir-glob": "^3.0.1", - "globby": "^14.0.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "issue-parser": "^7.0.0", "lodash-es": "^4.17.21", "mime": "^4.0.0", "p-filter": "^4.0.0", + "tinyglobby": "^0.2.14", + "undici": "^7.0.0", "url-join": "^5.0.0" }, "engines": { - "node": ">=20.8.1" + "node": "^22.14.0 || >= 24.10.0" }, "peerDependencies": { - "semantic-release": ">=20.1.0" - } - }, - "node_modules/@semantic-release/github/node_modules/@sindresorhus/merge-streams": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/globby": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", - "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", - "dev": true, - "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "semantic-release": ">=24.1.0" } }, "node_modules/@semantic-release/npm": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.1.tgz", - "integrity": "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw==", + "version": "13.1.4", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-13.1.4.tgz", + "integrity": "sha512-z5Fn9ftK1QQgFxMSuOd3DtYbTl4hWI2trCEvZcEJMQJy1/OBR0WHcxqzfVun455FSkHML8KgvPxJEa9MtZIBsg==", "dev": true, + "license": "MIT", "dependencies": { + "@actions/core": "^3.0.0", "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", + "env-ci": "^11.2.0", "execa": "^9.0.0", "fs-extra": "^11.0.0", "lodash-es": "^4.17.21", "nerf-dart": "^1.0.0", "normalize-url": "^8.0.0", - "npm": "^10.5.0", + "npm": "^11.6.2", "rc": "^1.2.8", - "read-pkg": "^9.0.0", + "read-pkg": "^10.0.0", "registry-auth-token": "^5.0.0", "semver": "^7.1.2", "tempy": "^3.0.0" }, "engines": { - "node": ">=20.8.1" + "node": "^22.14.0 || >= 24.10.0" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "node_modules/@semantic-release/release-notes-generator": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.0.1.tgz", - "integrity": "sha512-K0w+5220TM4HZTthE5dDpIuFrnkN1NfTGPidJFm04ULT1DEZ9WG89VNXN7F0c+6nMEpWgqmPvb7vY7JkB2jyyA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.1.0.tgz", + "integrity": "sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA==", "dev": true, + "license": "MIT", "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", @@ -2188,7 +1869,7 @@ "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "get-stream": "^7.0.0", - "import-from-esm": "^1.0.3", + "import-from-esm": "^2.0.0", "into-stream": "^7.0.0", "lodash-es": "^4.17.21", "read-package-up": "^11.0.0" @@ -2201,10 +1882,11 @@ } }, "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-changelog-angular": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.0.0.tgz", - "integrity": "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.1.0.tgz", + "integrity": "sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==", "dev": true, + "license": "ISC", "dependencies": { "compare-func": "^2.0.0" }, @@ -2213,10 +1895,11 @@ } }, "node_modules/@semantic-release/release-notes-generator/node_modules/conventional-commits-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.0.0.tgz", - "integrity": "sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.2.1.tgz", + "integrity": "sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==", "dev": true, + "license": "MIT", "dependencies": { "meow": "^13.0.0" }, @@ -2232,6 +1915,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -2239,11 +1923,129 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@semantic-release/release-notes-generator/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/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/@semantic-release/release-notes-generator/node_modules/meow": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -2251,26 +2053,61 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@shikijs/core": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.3.tgz", - "integrity": "sha512-D45PMaBaeDHxww+EkcDQtDAtzv00Gcsp72ukBtaLSmqRvh0WgGMq3Al0rl1QQBZfuneO75NXMIzEZGFitThWbg==", + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", "dev": true, + "license": "MIT", "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2283,6 +2120,7 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -2290,12 +2128,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, "node_modules/@tinyhttp/content-disposition": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@tinyhttp/content-disposition/-/content-disposition-2.2.0.tgz", - "integrity": "sha512-w1dJaSAtcCinOlT/YQg35RnFCOBbCHBGDVhH4yLoiJVtecRAJ2cYMf5HP+UhfbXURa38GC8fkRXO0vODDTjmeg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tinyhttp/content-disposition/-/content-disposition-2.2.4.tgz", + "integrity": "sha512-5Kc5CM2Ysn3vTTArBs2vESUt0AQiWZA86yc1TI3B+lxXmtEq133C1nxXNOgnzhrivdPZIh3zLj5gDnZjoLL5GA==", + "license": "MIT", "engines": { - "node": ">=12.20.0" + "node": ">=12.17.0" }, "funding": { "type": "individual", @@ -2326,6 +2172,17 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/async-retry": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.4.8.tgz", @@ -2345,6 +2202,17 @@ "@types/node": "*" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -2354,11 +2222,19 @@ "@types/node": "*" } }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/express": { "version": "5.0.0", @@ -2399,6 +2275,7 @@ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -2458,10 +2335,14 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", - "dev": true + "version": "20.19.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", + "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", @@ -2525,10 +2406,11 @@ } }, "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.4.0", @@ -2720,117 +2602,113 @@ } }, "node_modules/@vitest/expect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", - "dev": true, - "dependencies": { - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "chai": "^4.3.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.0.tgz", + "integrity": "sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/utils": "1.6.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.0", + "@vitest/utils": "4.1.0", + "chai": "^6.2.2", + "tinyrainbow": "^3.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "node_modules/@vitest/mocker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.0.tgz", + "integrity": "sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==", "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "node_modules/@vitest/pretty-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.0.tgz", + "integrity": "sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==", "dev": true, - "engines": { - "node": ">=12.20" + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/snapshot": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", + "node_modules/@vitest/runner": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.0.tgz", + "integrity": "sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==", "dev": true, + "license": "MIT", "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" + "@vitest/utils": "4.1.0", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/spy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", + "node_modules/@vitest/snapshot": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.0.tgz", + "integrity": "sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==", "dev": true, + "license": "MIT", "dependencies": { - "tinyspy": "^2.2.0" + "@vitest/pretty-format": "4.1.0", + "@vitest/utils": "4.1.0", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/ui": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.6.0.tgz", - "integrity": "sha512-k3Lyo+ONLOgylctiGovRKy7V4+dIN2yxstX3eY5cWFXH6WP+ooVX79YSyi0GagdTQzLmT43BF27T0s6dOIPBXA==", + "node_modules/@vitest/spy": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.0.tgz", + "integrity": "sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==", "dev": true, - "dependencies": { - "@vitest/utils": "1.6.0", - "fast-glob": "^3.3.2", - "fflate": "^0.8.1", - "flatted": "^3.2.9", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "sirv": "^2.0.4" - }, + "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "vitest": "1.6.0" } }, "node_modules/@vitest/utils": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.0.tgz", + "integrity": "sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==", "dev": true, + "license": "MIT", "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" + "@vitest/pretty-format": "4.1.0", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.0.3" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2880,13 +2758,11 @@ } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, + "license": "MIT", "engines": { "node": ">= 14" } @@ -2896,6 +2772,7 @@ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, + "license": "MIT", "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" @@ -2949,9 +2826,10 @@ } }, "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -2978,7 +2856,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/are-docs-informative": { "version": "0.0.2", @@ -3145,12 +3024,13 @@ } }, "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12" } }, "node_modules/async-retry": { @@ -3180,10 +3060,11 @@ "dev": true }, "node_modules/before-after-hook": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", - "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/body-parser": { "version": "1.20.3", @@ -3228,7 +3109,8 @@ "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -3282,15 +3164,6 @@ "node": ">= 0.8" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -3346,27 +3219,20 @@ } }, "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" } }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -3379,41 +3245,32 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, "node_modules/ci-info": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", - "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.3.0.tgz", + "integrity": "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "5.0.0" }, @@ -3429,6 +3286,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -3441,6 +3299,7 @@ "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", "dev": true, + "license": "ISC", "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", @@ -3462,6 +3321,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3471,6 +3331,7 @@ "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" @@ -3487,6 +3348,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -3497,13 +3359,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cli-highlight/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3518,6 +3382,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3530,6 +3395,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -3544,11 +3410,12 @@ } }, "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==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", + "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=18.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3559,6 +3426,7 @@ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dev": true, + "license": "MIT", "dependencies": { "string-width": "^4.2.0" }, @@ -3574,6 +3442,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3582,13 +3451,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cli-table3/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3603,6 +3474,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3684,11 +3556,12 @@ "dev": true }, "node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=20" } }, "node_modules/comment-parser": { @@ -3721,43 +3594,12 @@ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, + "license": "MIT", "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-disposition/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" - } - ] - }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", @@ -3792,12 +3634,12 @@ } }, "node_modules/conventional-changelog-writer": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.0.0.tgz", - "integrity": "sha512-TQcoYGRatlAnT2qEWDON/XSfnVG38JzA7E0wcGScu7RElQBkg9WWgZd1peCWFcWDh1xfb2CfsrcvOn1bbSzztA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.2.0.tgz", + "integrity": "sha512-Y2aW4596l9AEvFJRwFGJGiQjt2sBYTjPD18DdvxX9Vpz0Z7HQ+g1Z+6iYDAm1vR3QOJrDBkRHixHK/+FhkR6Pw==", "dev": true, + "license": "MIT", "dependencies": { - "@types/semver": "^7.5.5", "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", @@ -3815,6 +3657,7 @@ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -3827,6 +3670,7 @@ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } @@ -3861,6 +3705,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/cookie": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", @@ -3922,10 +3773,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3940,6 +3792,7 @@ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^1.0.1" }, @@ -3955,6 +3808,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -4022,23 +3876,12 @@ "node": ">=0.10.0" } }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, "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", "engines": { "node": ">=4.0.0" } @@ -4101,6 +3944,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -4110,15 +3963,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4191,7 +4035,8 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", @@ -4207,6 +4052,7 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -4215,10 +4061,11 @@ } }, "node_modules/env-ci": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.0.0.tgz", - "integrity": "sha512-apikxMgkipkgTvMdRT9MNqWx5VLOci79F4VBd7Op/7OPjjoanjdAvn6fglMCCEf/1bAh8eOiuEVCUs4V3qP3nQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.2.0.tgz", + "integrity": "sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^8.0.0", "java-properties": "^1.0.2" @@ -4297,6 +4144,7 @@ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -4387,6 +4235,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "dev": true, + "license": "MIT" + }, "node_modules/es-set-tostringtag": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", @@ -4427,44 +4282,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -4965,6 +4782,7 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } @@ -4988,28 +4806,30 @@ } }, "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" }, "node_modules/execa": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.3.0.tgz", - "integrity": "sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", - "human-signals": "^7.0.0", + "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", - "npm-run-path": "^5.2.0", - "pretty-ms": "^9.0.0", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", - "yoctocolors": "^2.0.0" + "yoctocolors": "^2.1.1" }, "engines": { "node": "^18.19.0 || >=20.5.0" @@ -5023,6 +4843,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, + "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" @@ -5039,6 +4860,7 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5051,6 +4873,24 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, "engines": { "node": ">=18" }, @@ -5063,6 +4903,7 @@ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -5070,11 +4911,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/execa/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/execa/node_modules/pretty-ms": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.0.0.tgz", - "integrity": "sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", "dev": true, + "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" }, @@ -5090,6 +4945,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -5097,11 +4953,25 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/execa/node_modules/strip-final-newline": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", - "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "node_modules/execa/node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa/node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -5109,6 +4979,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { "version": "4.21.1", "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", @@ -5151,6 +5031,19 @@ "node": ">= 0.10.0" } }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5186,6 +5079,23 @@ } ] }, + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", + "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5241,17 +5151,12 @@ "reusify": "^1.0.4" } }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "dev": true - }, "node_modules/figures": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", "dev": true, + "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0" }, @@ -5275,25 +5180,27 @@ } }, "node_modules/filename-reserved-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", - "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-4.0.0.tgz", + "integrity": "sha512-9ZT504KxEQDamsOogZImAWGEN24R1uFAxU3ZS4AZqn2ooidmN68Olh7n4/RcA4lLatZztjA0ZSuxeLHVoCc8JA==", + "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/filenamify": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", - "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-7.0.1.tgz", + "integrity": "sha512-9b4rfnaX2MkJCgp27wypV6DAMvj4WMOSgJ+TdcpJIO84Dql+Cv6iJjdG4XDTLubOWkfNiBv3joO59sau/TXw+Q==", + "license": "MIT", "dependencies": { - "filename-reserved-regex": "^3.0.0" + "filename-reserved-regex": "^4.0.0" }, "engines": { - "node": ">=16" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5361,10 +5268,11 @@ } }, "node_modules/find-up-simple": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", - "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -5439,15 +5347,17 @@ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, "node_modules/fs-extra": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5469,6 +5379,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -5545,15 +5456,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -5800,6 +5702,7 @@ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -5933,40 +5836,37 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": "*" } }, "node_modules/hook-std": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", - "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-4.0.0.tgz", + "integrity": "sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "dev": true, + "license": "ISC", "dependencies": { - "lru-cache": "^10.0.1" + "lru-cache": "^11.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/hosted-git-info/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 - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -5988,6 +5888,7 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -5997,12 +5898,13 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -6010,10 +5912,11 @@ } }, "node_modules/human-signals": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-7.0.0.tgz", - "integrity": "sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18.0" } @@ -6071,23 +5974,25 @@ } }, "node_modules/import-from-esm": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", - "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-2.0.0.tgz", + "integrity": "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4", "import-meta-resolve": "^4.0.0" }, "engines": { - "node": ">=16.20" + "node": ">=18.20" } }, "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6107,6 +6012,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6115,10 +6021,11 @@ } }, "node_modules/index-to-position": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", - "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -6167,6 +6074,7 @@ "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", "dev": true, + "license": "MIT", "dependencies": { "from2": "^2.3.0", "p-is-promise": "^3.0.0" @@ -6480,9 +6388,10 @@ } }, "node_modules/is-unicode-supported": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", - "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", "engines": { "node": ">=18" }, @@ -6519,6 +6428,7 @@ "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.1.tgz", "integrity": "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==", "dev": true, + "license": "MIT", "dependencies": { "lodash.capitalize": "^4.2.1", "lodash.escaperegexp": "^4.1.2", @@ -6543,7 +6453,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -6602,12 +6513,6 @@ "json5": "lib/cli.js" } }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -6641,35 +6546,297 @@ "JSONStream": "bin.js" }, "engines": { - "node": "*" + "node": "*" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lifecycle-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lifecycle-utils/-/lifecycle-utils-3.1.1.tgz", + "integrity": "sha512-gNd3OvhFNjHykJE3uGntz7UuPzWlK9phrIdXxU9Adis0+ExkwnZibfxCJWiWWZ+a6VbKiZrb+9D9hCQWd4vjTg==", + "license": "MIT" + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.8.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/lifecycle-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/lifecycle-utils/-/lifecycle-utils-1.3.1.tgz", - "integrity": "sha512-Vo3cw99hNk95lG+dxmaA9kfpsYXW/0g9MwvnO0zpvfstiC0ds8fAIzCa9M+hVPnFF5dvx9oy4nlEbIFChdL7RA==" + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, "node_modules/limiter": { "version": "1.1.5", @@ -6688,6 +6855,7 @@ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, + "license": "MIT", "dependencies": { "uc.micro": "^2.0.0" } @@ -6720,22 +6888,6 @@ "node": ">=4" } }, - "node_modules/local-pkg": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", - "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", - "dev": true, - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -6758,10 +6910,11 @@ "dev": true }, "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", + "dev": true, + "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -6773,7 +6926,8 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -6784,7 +6938,8 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isfunction": { "version": "3.0.9", @@ -6802,7 +6957,8 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.kebabcase": { "version": "4.1.1", @@ -6844,7 +7000,8 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.upperfirst": { "version": "4.3.1", @@ -6852,15 +7009,6 @@ "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", "dev": true }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, "node_modules/lowdb": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-7.0.1.tgz", @@ -6875,6 +7023,16 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/lunr": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", @@ -6882,12 +7040,13 @@ "dev": true }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/make-error": { @@ -6909,10 +7068,11 @@ } }, "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -6926,10 +7086,11 @@ } }, "node_modules/marked": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", - "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", "dev": true, + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -6938,30 +7099,33 @@ } }, "node_modules/marked-terminal": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.1.0.tgz", - "integrity": "sha512-+pvwa14KZL74MVXjYdPR3nSInhGhNvPce/3mqLVZT2oUvt654sL1XImFuLZ1pkA866IYZ3ikDTOFUIC7XzpZZg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^7.0.0", - "chalk": "^5.3.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", - "node-emoji": "^2.1.3", - "supports-hyperlinks": "^3.0.0" + "node-emoji": "^2.2.0", + "supports-hyperlinks": "^3.1.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "marked": ">=1 <14" + "marked": ">=1 <16" } }, "node_modules/marked-terminal/node_modules/ansi-escapes": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", - "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", "dev": true, + "license": "MIT", "dependencies": { "environment": "^1.0.0" }, @@ -6976,7 +7140,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/media-typer": { "version": "0.3.0", @@ -7200,13 +7365,14 @@ } }, "node_modules/mime": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.4.tgz", - "integrity": "sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz", + "integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==", "dev": true, "funding": [ "https://github.com/sponsors/broofa" ], + "license": "MIT", "bin": { "mime": "bin/cli.js" }, @@ -7297,27 +7463,6 @@ "node": ">= 6" } }, - "node_modules/mlly": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.0.tgz", - "integrity": "sha512-YOvg9hfYQmnaB56Yb+KrJE2u0Yzz5zR+sLejEvF4fzwzV1Al6hkf2vyHTwqCRyv0hCi9rVCqVoXpyYevQIRwLQ==", - "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.0.3", - "ufo": "^1.3.2" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7329,12 +7474,32 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, + "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/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7354,19 +7519,22 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nerf-dart": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", "dev": true, + "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", @@ -7417,10 +7585,11 @@ } }, "node_modules/normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -7429,15 +7598,16 @@ } }, "node_modules/npm": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.2.tgz", - "integrity": "sha512-x/AIjFIKRllrhcb48dqUNAAZl0ig9+qMuN91RpZo3Cb2+zuibfh+KISl6+kVVyktDz230JKc208UkQwwMqyB+w==", + "version": "11.10.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-11.10.1.tgz", + "integrity": "sha512-woavuY2OgDFQ1K/tB9QHsUuW989nKfvsKTN/h5qGyS+3+BhvXN/DA2TNzx569JaFfTqrET5bEQNHwVhFk+U1gg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", "@npmcli/config", "@npmcli/fs", "@npmcli/map-workspaces", + "@npmcli/metavuln-calculator", "@npmcli/package-json", "@npmcli/promise-spawn", "@npmcli/redact", @@ -7448,7 +7618,6 @@ "cacache", "chalk", "ci-info", - "cli-columns", "fastest-levenshtein", "fs-minipass", "glob", @@ -7462,7 +7631,6 @@ "libnpmdiff", "libnpmexec", "libnpmfund", - "libnpmhook", "libnpmorg", "libnpmpack", "libnpmpublish", @@ -7476,7 +7644,6 @@ "ms", "node-gyp", "nopt", - "normalize-package-data", "npm-audit-report", "npm-install-checks", "npm-package-arg", @@ -7499,10 +7666,10 @@ "tiny-relative-date", "treeverse", "validate-npm-package-name", - "which", - "write-file-atomic" + "which" ], "dev": true, + "license": "Artistic-2.0", "workspaces": [ "docs", "smoke-tests", @@ -7512,80 +7679,77 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.5.4", - "@npmcli/config": "^8.3.4", - "@npmcli/fs": "^3.1.1", - "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.2.0", - "@npmcli/promise-spawn": "^7.0.2", - "@npmcli/redact": "^2.0.1", - "@npmcli/run-script": "^8.1.0", - "@sigstore/tuf": "^2.3.4", - "abbrev": "^2.0.0", + "@npmcli/arborist": "^9.3.1", + "@npmcli/config": "^10.7.1", + "@npmcli/fs": "^5.0.0", + "@npmcli/map-workspaces": "^5.0.3", + "@npmcli/metavuln-calculator": "^9.0.3", + "@npmcli/package-json": "^7.0.5", + "@npmcli/promise-spawn": "^9.0.1", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.3", + "@sigstore/tuf": "^4.0.1", + "abbrev": "^4.0.0", "archy": "~1.0.0", - "cacache": "^18.0.3", - "chalk": "^5.3.0", - "ci-info": "^4.0.0", - "cli-columns": "^4.0.0", + "cacache": "^20.0.3", + "chalk": "^5.6.2", + "ci-info": "^4.4.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.4.2", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.2", - "ini": "^4.1.3", - "init-package-json": "^6.0.3", - "is-cidr": "^5.1.0", - "json-parse-even-better-errors": "^3.0.2", - "libnpmaccess": "^8.0.6", - "libnpmdiff": "^6.1.4", - "libnpmexec": "^8.1.3", - "libnpmfund": "^5.0.12", - "libnpmhook": "^10.0.5", - "libnpmorg": "^6.0.6", - "libnpmpack": "^7.0.4", - "libnpmpublish": "^9.0.9", - "libnpmsearch": "^7.0.6", - "libnpmteam": "^6.0.5", - "libnpmversion": "^6.0.3", - "make-fetch-happen": "^13.0.1", - "minimatch": "^9.0.5", - "minipass": "^7.1.1", + "hosted-git-info": "^9.0.2", + "ini": "^6.0.0", + "init-package-json": "^8.2.5", + "is-cidr": "^6.0.3", + "json-parse-even-better-errors": "^5.0.0", + "libnpmaccess": "^10.0.3", + "libnpmdiff": "^8.1.2", + "libnpmexec": "^10.2.2", + "libnpmfund": "^7.0.16", + "libnpmorg": "^8.0.1", + "libnpmpack": "^9.1.2", + "libnpmpublish": "^11.1.3", + "libnpmsearch": "^9.0.1", + "libnpmteam": "^8.0.2", + "libnpmversion": "^8.0.3", + "make-fetch-happen": "^15.0.3", + "minimatch": "^10.2.2", + "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.1.0", - "nopt": "^7.2.1", - "normalize-package-data": "^6.0.2", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.1.0", - "npm-profile": "^10.0.0", - "npm-registry-fetch": "^17.1.0", - "npm-user-validate": "^2.0.1", - "p-map": "^4.0.0", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.1", - "proc-log": "^4.2.0", + "node-gyp": "^12.2.0", + "nopt": "^9.0.0", + "npm-audit-report": "^7.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.2", + "npm-pick-manifest": "^11.0.3", + "npm-profile": "^12.0.1", + "npm-registry-fetch": "^19.1.1", + "npm-user-validate": "^4.0.0", + "p-map": "^7.0.4", + "pacote": "^21.3.1", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", - "read": "^3.0.1", - "semver": "^7.6.2", + "read": "^5.0.1", + "semver": "^7.7.4", "spdx-expression-parse": "^4.0.0", - "ssri": "^10.0.6", - "supports-color": "^9.4.0", - "tar": "^6.2.1", + "ssri": "^13.0.1", + "supports-color": "^10.2.2", + "tar": "^7.5.9", "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", + "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.1", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" + "validate-npm-package-name": "^7.0.2", + "which": "^6.0.1" }, "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-run-path": { @@ -7615,71 +7779,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm/node_modules/@isaacs/cliui": { - "version": "8.0.2", + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" + "minipass": "^7.0.4" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=18.0.0" } }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { @@ -7689,7 +7798,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7697,83 +7806,81 @@ "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", + "lru-cache": "^11.2.1", "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.5.4", + "version": "9.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.1", - "@npmcli/installed-package-contents": "^2.1.0", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.1.1", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.1.0", - "@npmcli/query": "^3.1.0", - "@npmcli/redact": "^2.0.0", - "@npmcli/run-script": "^8.1.0", - "bin-links": "^4.0.4", - "cacache": "^18.0.3", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.2", - "json-parse-even-better-errors": "^3.0.2", + "@npmcli/fs": "^5.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/metavuln-calculator": "^9.0.2", + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/query": "^5.0.0", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.0", + "bin-links": "^6.0.0", + "cacache": "^20.0.1", + "common-ancestor-path": "^2.0.0", + "hosted-git-info": "^9.0.0", "json-stringify-nice": "^1.1.4", - "lru-cache": "^10.2.2", - "minimatch": "^9.0.4", - "nopt": "^7.2.1", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.0.1", - "npm-registry-fetch": "^17.0.1", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.0", - "proc-log": "^4.2.0", - "proggy": "^2.0.0", + "lru-cache": "^11.2.1", + "minimatch": "^10.0.3", + "nopt": "^9.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.0", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "pacote": "^21.0.2", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.0.0", + "proggy": "^4.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", - "read-package-json-fast": "^3.0.2", "semver": "^7.3.7", - "ssri": "^10.0.6", + "ssri": "^13.0.0", "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" + "walk-up-path": "^4.0.0" }, "bin": { "arborist": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.3.4", + "version": "10.7.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/package-json": "^5.1.1", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/package-json": "^7.0.0", "ci-info": "^4.0.0", - "ini": "^4.1.2", - "nopt": "^7.2.1", - "proc-log": "^4.2.0", + "ini": "^6.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5", - "walk-up-path": "^3.0.1" + "walk-up-path": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.1", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7781,244 +7888,233 @@ "semver": "^7.3.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.8", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "ini": "^4.1.3", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^4.0.0", - "promise-inflight": "^1.0.1", + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", "promise-retry": "^2.0.1", "semver": "^7.3.5", - "which": "^4.0.0" + "which": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" }, "bin": { "installed-package-contents": "bin/index.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.6", + "version": "5.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.1.1", + "version": "9.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^18.0.0", - "proc-log": "^4.1.0", + "cacache": "^20.0.0", + "json-parse-even-better-errors": "^5.0.0", + "pacote": "^21.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "3.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.2.0", + "version": "7.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^4.0.0", - "semver": "^7.5.3" + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "spdx-expression-parse": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.2", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "which": "^4.0.0" + "which": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.1.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "2.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "8.1.0", + "version": "10.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "proc-log": "^4.0.0", - "which": "^4.0.0" + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0", + "which": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.3.2", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" + "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@sigstore/core": { - "version": "1.1.0", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", + "version": "0.5.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.3.2", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.3", + "proc-log": "^6.1.0", "promise-retry": "^2.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.3.4", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^2.2.1" + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@sigstore/verify": { - "version": "1.2.1", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.2" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@tufjs/canonical-json": { @@ -8031,75 +8127,38 @@ } }, "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.1", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" + "minimatch": "^10.1.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/agent-base": { - "version": "7.1.1", + "version": "7.1.4", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, "engines": { "node": ">= 14" } }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", + "version": "2.1.0", "dev": true, "inBundle": true, "license": "ISC" @@ -8111,72 +8170,78 @@ "license": "MIT" }, "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", + "version": "4.0.3", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "20 || >=22" + } }, "node_modules/npm/node_modules/bin-links": { - "version": "4.0.4", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" + "cmd-shim": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "proc-log": "^6.0.0", + "read-cmd-shim": "^6.0.0", + "write-file-atomic": "^7.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/binary-extensions": { - "version": "2.3.0", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", + "version": "5.0.2", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.3", + "version": "20.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/fs": "^3.1.0", + "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" + "p-map": "^7.0.2", + "ssri": "^13.0.0", + "unique-filename": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/chalk": { - "version": "5.3.0", + "version": "5.6.2", "dev": true, "inBundle": true, "license": "MIT", @@ -8188,16 +8253,16 @@ } }, "node_modules/npm/node_modules/chownr": { - "version": "2.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", + "version": "4.4.0", "dev": true, "funding": [ { @@ -8212,99 +8277,30 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.1.1", + "version": "5.0.3", "dev": true, "inBundle": true, "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^5.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">= 10" + "node": ">=20" } }, "node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.3", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 8" + "node": ">= 18" } }, "node_modules/npm/node_modules/cssesc": { @@ -8320,12 +8316,12 @@ } }, "node_modules/npm/node_modules/debug": { - "version": "4.3.5", + "version": "4.4.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -8336,14 +8332,8 @@ } } }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/diff": { - "version": "5.2.0", + "version": "8.0.3", "dev": true, "inBundle": true, "license": "BSD-3-Clause", @@ -8351,18 +8341,6 @@ "node": ">=0.3.1" } }, - "node_modules/npm/node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/encoding": { "version": "0.1.13", "dev": true, @@ -8389,7 +8367,7 @@ "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", + "version": "3.1.3", "dev": true, "inBundle": true, "license": "Apache-2.0" @@ -8403,22 +8381,6 @@ "node": ">= 4.9.1" } }, - "node_modules/npm/node_modules/foreground-child": { - "version": "3.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/npm/node_modules/fs-minipass": { "version": "3.0.3", "dev": true, @@ -8432,23 +8394,17 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "10.4.2", + "version": "13.0.6", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8461,19 +8417,19 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.2", + "version": "9.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "lru-cache": "^10.0.1" + "lru-cache": "^11.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", + "version": "4.2.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause" @@ -8492,12 +8448,12 @@ } }, "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.5", + "version": "7.0.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -8518,15 +8474,15 @@ } }, "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.5", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "minimatch": "^9.0.0" + "minimatch": "^10.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/imurmurhash": { @@ -8538,131 +8494,69 @@ "node": ">=0.8.19" } }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/ini": { - "version": "4.1.3", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.3", + "version": "8.2.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/package-json": "^5.0.0", - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^3.0.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/ip-address": { - "version": "9.0.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/npm/node_modules/ip-regex": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/is-cidr": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "cidr-regex": "^4.1.1" + "@npmcli/package-json": "^7.0.0", + "npm-package-arg": "^13.0.0", + "promzard": "^3.0.1", + "read": "^5.0.1", + "semver": "^7.7.2", + "validate-npm-package-name": "^7.0.0" }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "node_modules/npm/node_modules/isexe": { - "version": "2.0.0", + "node_modules/npm/node_modules/ip-address": { + "version": "10.1.0", "dev": true, "inBundle": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": ">= 12" + } }, - "node_modules/npm/node_modules/jackspeak": { - "version": "3.4.0", + "node_modules/npm/node_modules/is-cidr": { + "version": "6.0.3", "dev": true, "inBundle": true, - "license": "BlueOak-1.0.0", + "license": "BSD-2-Clause", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "cidr-regex": "^5.0.1" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "node": ">=20" } }, - "node_modules/npm/node_modules/jsbn": { - "version": "1.1.0", + "node_modules/npm/node_modules/isexe": { + "version": "4.0.0", "dev": true, "inBundle": true, - "license": "MIT" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.2", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/json-stringify-nice": { @@ -8696,223 +8590,211 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.6", + "version": "10.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1" + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.1.4", + "version": "8.1.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/installed-package-contents": "^2.1.0", - "binary-extensions": "^2.3.0", - "diff": "^5.1.0", - "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", - "tar": "^6.2.1" + "@npmcli/arborist": "^9.3.1", + "@npmcli/installed-package-contents": "^4.0.0", + "binary-extensions": "^3.0.0", + "diff": "^8.0.2", + "minimatch": "^10.0.3", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "tar": "^7.5.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "8.1.3", + "version": "10.2.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/run-script": "^8.1.0", + "@npmcli/arborist": "^9.3.1", + "@npmcli/package-json": "^7.0.0", + "@npmcli/run-script": "^10.0.0", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6", - "proc-log": "^4.2.0", - "read": "^3.0.1", - "read-package-json-fast": "^3.0.2", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "read": "^5.0.1", "semver": "^7.3.7", - "walk-up-path": "^3.0.1" + "signal-exit": "^4.1.0", + "walk-up-path": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.12", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.5.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.5", + "version": "7.0.16", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "@npmcli/arborist": "^9.3.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.6", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "7.0.4", + "version": "9.1.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.5.4", - "@npmcli/run-script": "^8.1.0", - "npm-package-arg": "^11.0.2", - "pacote": "^18.0.6" + "@npmcli/arborist": "^9.3.1", + "@npmcli/run-script": "^10.0.0", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.9", + "version": "11.1.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@npmcli/package-json": "^7.0.0", "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.1", - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.2.0", + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.7", - "sigstore": "^2.2.0", - "ssri": "^10.0.6" + "sigstore": "^4.0.0", + "ssri": "^13.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.6", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.5", + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^17.0.1" + "npm-registry-fetch": "^19.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "6.0.3", + "version": "8.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.7", - "@npmcli/run-script": "^8.1.0", - "json-parse-even-better-errors": "^3.0.2", - "proc-log": "^4.2.0", + "@npmcli/git": "^7.0.0", + "@npmcli/run-script": "^10.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.7" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.2.2", + "version": "11.2.6", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": "14 || >=16.14" + "node": "20 || >=22" } }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.1", + "version": "15.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", + "@npmcli/agent": "^4.0.0", + "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", + "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", "promise-retry": "^2.0.1", - "ssri": "^10.0.0" + "ssri": "^13.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.5", + "version": "10.2.2", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/npm/node_modules/minipass": { - "version": "7.1.2", + "version": "7.1.3", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -8930,17 +8812,17 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.5", + "version": "5.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" }, "optionalDependencies": { "encoding": "^0.1.13" @@ -8970,6 +8852,12 @@ "node": ">=8" } }, + "node_modules/npm/node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", "dev": true, @@ -8994,65 +8882,34 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", + "node_modules/npm/node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "ISC" }, - "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", + "node_modules/npm/node_modules/minipass-sized": { + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { "node": ">=8" } }, "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" + "minipass": "^7.1.2" }, "engines": { - "node": ">=10" + "node": ">= 18" } }, "node_modules/npm/node_modules/ms": { @@ -9062,16 +8919,16 @@ "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", + "version": "1.0.0", "dev": true, "inBundle": true, "license": "MIT", @@ -9080,90 +8937,67 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.1.0", + "version": "12.2.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "make-fetch-happen": "^15.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^4.0.0" + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "which": "^6.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/nopt": { - "version": "7.2.1", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "abbrev": "^2.0.0" + "abbrev": "^4.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.1", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-normalize-package-bin": "^3.0.0" + "npm-normalize-package-bin": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "6.3.0", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -9171,194 +9005,177 @@ "semver": "^7.1.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.2", + "version": "13.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "validate-npm-package-name": "^7.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.2", + "version": "10.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.4" + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.1.0", + "version": "11.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-profile": { - "version": "10.0.0", + "version": "12.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.0.0" + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0" }, "engines": { - "node": ">=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "17.1.0", + "version": "19.1.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/redact": "^2.0.0", + "@npmcli/redact": "^4.0.0", "jsonparse": "^1.3.1", - "make-fetch-happen": "^13.0.0", + "make-fetch-happen": "^15.0.0", "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^4.0.0" + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", + "version": "7.0.4", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm/node_modules/package-json-from-dist": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0" - }, "node_modules/npm/node_modules/pacote": { - "version": "18.0.6", + "version": "21.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/package-json": "^5.1.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^8.0.0", - "cacache": "^18.0.0", + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^17.0.0", - "proc-log": "^4.0.0", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", "promise-retry": "^2.0.1", - "sigstore": "^2.2.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" }, "bin": { "pacote": "bin/index.js" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", + "version": "5.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", + "json-parse-even-better-errors": "^5.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/path-scurry": { - "version": "1.11.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.1.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -9371,21 +9188,21 @@ } }, "node_modules/npm/node_modules/proc-log": { - "version": "4.2.0", + "version": "6.1.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/proggy": { - "version": "2.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/promise-all-reject-late": { @@ -9398,7 +9215,7 @@ } }, "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.1", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -9406,12 +9223,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", "dev": true, @@ -9426,15 +9237,15 @@ } }, "node_modules/npm/node_modules/promzard": { - "version": "1.0.2", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "read": "^3.0.1" + "read": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/qrcode-terminal": { @@ -9446,37 +9257,24 @@ } }, "node_modules/npm/node_modules/read": { - "version": "3.0.1", + "version": "5.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "mute-stream": "^1.0.0" + "mute-stream": "^3.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/read-cmd-shim": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/retry": { @@ -9496,36 +9294,15 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.6.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/shebang-regex": { - "version": "3.0.0", + "version": "7.7.4", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/npm/node_modules/signal-exit": { @@ -9541,20 +9318,20 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.3.1", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^2.3.2", - "@sigstore/tuf": "^2.3.4", - "@sigstore/verify": "^1.2.1" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.0", + "@sigstore/tuf": "^4.0.1", + "@sigstore/verify": "^3.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/smart-buffer": { @@ -9568,12 +9345,12 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.3", + "version": "2.8.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", + "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -9582,12 +9359,12 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.4", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -9595,26 +9372,6 @@ "node": ">= 14" } }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/npm/node_modules/spdx-exceptions": { "version": "2.5.0", "dev": true, @@ -9632,19 +9389,13 @@ } }, "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.18", + "version": "3.0.22", "dev": true, "inBundle": true, "license": "CC0-1.0" }, - "node_modules/npm/node_modules/sprintf-js": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause" - }, "node_modules/npm/node_modules/ssri": { - "version": "10.0.6", + "version": "13.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -9652,137 +9403,94 @@ "minipass": "^7.0.3" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", + "node_modules/npm/node_modules/supports-color": { + "version": "10.2.2", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/npm/node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", + "node_modules/npm/node_modules/tar": { + "version": "7.5.9", "dev": true, "inBundle": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/npm/node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "2.0.2", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/npm/node_modules/supports-color": { - "version": "9.4.0", + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.15", "dev": true, "inBundle": true, "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, "engines": { - "node": ">=12" + "node": ">=12.0.0" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/npm/node_modules/tar": { - "version": "6.2.1", + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" + "node": ">=12.0.0" }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" + "peerDependencies": { + "picomatch": "^3 || ^4" }, - "engines": { - "node": ">=8" + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/npm/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", "dev": true, @@ -9793,33 +9501,33 @@ } }, "node_modules/npm/node_modules/tuf-js": { - "version": "2.2.1", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "unique-slug": "^4.0.0" + "unique-slug": "^6.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -9827,7 +9535,7 @@ "imurmurhash": "^0.1.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/util-deprecate": { @@ -9836,167 +9544,41 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.1", + "version": "7.0.2", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/walk-up-path": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/which": { "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/which/node_modules/isexe": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/npm/node_modules/wrap-ansi": { - "version": "8.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "20 || >=22" } }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", + "node_modules/npm/node_modules/which": { + "version": "6.0.1", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ansi-regex": "^6.0.1" + "isexe": "^4.0.0" }, - "engines": { - "node": ">=12" + "bin": { + "node-which": "bin/which.js" }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -10005,20 +9587,24 @@ "signal-exit": "^4.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10108,6 +9694,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -10178,6 +9775,7 @@ "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", "dev": true, + "license": "MIT", "dependencies": { "p-map": "^7.0.1" }, @@ -10193,6 +9791,7 @@ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -10228,10 +9827,11 @@ } }, "node_modules/p-map": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", - "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -10290,28 +9890,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-ms": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", - "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, + "license": "MIT", "dependencies": { "parse5": "^6.0.1" } @@ -10320,7 +9911,8 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/parseurl": { "version": "1.3.3", @@ -10380,25 +9972,18 @@ } }, "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, - "engines": { - "node": "*" - } + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "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": "2.3.1", @@ -10501,21 +10086,10 @@ "node": ">=4" } }, - "node_modules/pkg-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", - "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", - "dev": true, - "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { @@ -10531,34 +10105,16 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", - "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/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -10568,57 +10124,6 @@ "node": ">= 0.8.0" } }, - "node_modules/pretty-bytes": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", - "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/pretty-ms": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", - "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", - "dependencies": { - "parse-ms": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -10629,7 +10134,8 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -10658,6 +10164,7 @@ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -10735,6 +10242,7 @@ "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", @@ -10750,87 +10258,90 @@ "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/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true - }, "node_modules/read-package-up": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", - "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-12.0.0.tgz", + "integrity": "sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==", "dev": true, + "license": "MIT", "dependencies": { - "find-up-simple": "^1.0.0", - "read-pkg": "^9.0.0", - "type-fest": "^4.6.0" + "find-up-simple": "^1.0.1", + "read-pkg": "^10.0.0", + "type-fest": "^5.2.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-package-up/node_modules/type-fest": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.22.1.tgz", - "integrity": "sha512-9tHNEa0Ov81YOopiVkcCJVz5TM6AEQ+CHHjFIktqPnE3NV0AHIkx+gh9tiCl58m/66wWxkOC9eltpa75J4lQPA==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.4.tgz", + "integrity": "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==", "dev": true, + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, "engines": { - "node": ">=16" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", - "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.1.0.tgz", + "integrity": "sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/normalize-package-data": "^2.4.3", - "normalize-package-data": "^6.0.0", - "parse-json": "^8.0.0", - "type-fest": "^4.6.0", - "unicorn-magic": "^0.1.0" + "@types/normalize-package-data": "^2.4.4", + "normalize-package-data": "^8.0.0", + "parse-json": "^8.3.0", + "type-fest": "^5.4.4", + "unicorn-magic": "^0.4.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", - "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "hosted-git-info": "^7.0.0", + "hosted-git-info": "^9.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/read-pkg/node_modules/parse-json": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", - "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "index-to-position": "^0.1.2", - "type-fest": "^4.7.1" + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" }, "engines": { "node": ">=18" @@ -10839,11 +10350,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.22.1.tgz", - "integrity": "sha512-9tHNEa0Ov81YOopiVkcCJVz5TM6AEQ+CHHjFIktqPnE3NV0AHIkx+gh9tiCl58m/66wWxkOC9eltpa75J4lQPA==", + "node_modules/read-pkg/node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" }, @@ -10851,6 +10363,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.4.tgz", + "integrity": "sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -10924,12 +10452,13 @@ } }, "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.1.tgz", + "integrity": "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==", "dev": true, + "license": "MIT", "dependencies": { - "@pnpm/npm-conf": "^2.1.0" + "@pnpm/npm-conf": "^3.0.2" }, "engines": { "node": ">=14" @@ -11033,39 +10562,38 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rollup": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", - "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", + "node_modules/rolldown": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.10.tgz", + "integrity": "sha512-q7j6vvarRFmKpgJUT8HCAUljkgzEp4LAhPlJUvQhA5LA1SUL36s5QCysMutErzL3EbNOZOkoziSx9iZC4FddKA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@oxc-project/types": "=0.120.0", + "@rolldown/pluginutils": "1.0.0-rc.10" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.1", - "@rollup/rollup-android-arm64": "4.18.1", - "@rollup/rollup-darwin-arm64": "4.18.1", - "@rollup/rollup-darwin-x64": "4.18.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", - "@rollup/rollup-linux-arm-musleabihf": "4.18.1", - "@rollup/rollup-linux-arm64-gnu": "4.18.1", - "@rollup/rollup-linux-arm64-musl": "4.18.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", - "@rollup/rollup-linux-riscv64-gnu": "4.18.1", - "@rollup/rollup-linux-s390x-gnu": "4.18.1", - "@rollup/rollup-linux-x64-gnu": "4.18.1", - "@rollup/rollup-linux-x64-musl": "4.18.1", - "@rollup/rollup-win32-arm64-msvc": "4.18.1", - "@rollup/rollup-win32-ia32-msvc": "4.18.1", - "@rollup/rollup-win32-x64-msvc": "4.18.1", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm64": "1.0.0-rc.10", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.10", + "@rolldown/binding-darwin-x64": "1.0.0-rc.10", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.10", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.10", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.10", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.10", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.10", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.10", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.10", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.10", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.10", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.10", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.10", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.10" } }, "node_modules/run-parallel": { @@ -11136,16 +10664,17 @@ "dev": true }, "node_modules/semantic-release": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.0.0.tgz", - "integrity": "sha512-v46CRPw+9eI3ZuYGF2oAjqPqsfbnfFTwLBgQsv/lch4goD09ytwOTESMN4QIrx/wPLxUGey60/NMx+ANQtWRsA==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-25.0.3.tgz", + "integrity": "sha512-WRgl5GcypwramYX4HV+eQGzUbD7UUbljVmS+5G1uMwX/wLgYuJAxGeerXJDMO2xshng4+FXqCgyB5QfClV6WjA==", "dev": true, + "license": "MIT", "dependencies": { - "@semantic-release/commit-analyzer": "^13.0.0-beta.1", + "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/error": "^4.0.0", - "@semantic-release/github": "^10.0.0", - "@semantic-release/npm": "^12.0.0", - "@semantic-release/release-notes-generator": "^14.0.0-beta.1", + "@semantic-release/github": "^12.0.0", + "@semantic-release/npm": "^13.1.1", + "@semantic-release/release-notes-generator": "^14.1.0", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", @@ -11155,27 +10684,54 @@ "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", - "hook-std": "^3.0.0", - "hosted-git-info": "^7.0.0", - "import-from-esm": "^1.3.1", + "hook-std": "^4.0.0", + "hosted-git-info": "^9.0.0", + "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", - "marked": "^12.0.0", - "marked-terminal": "^7.0.0", + "marked": "^15.0.0", + "marked-terminal": "^7.3.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", - "read-package-up": "^11.0.0", + "read-package-up": "^12.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", - "semver-diff": "^4.0.0", "signale": "^1.2.1", - "yargs": "^17.5.1" + "yargs": "^18.0.0" }, "bin": { "semantic-release": "bin/semantic-release.js" }, "engines": { - "node": ">=20.8.1" + "node": "^22.14.0 || >= 24.10.0" + } + }, + "node_modules/semantic-release/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/semantic-release/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" } }, "node_modules/semantic-release/node_modules/cosmiconfig": { @@ -11213,6 +10769,52 @@ "node": ">=8" } }, + "node_modules/semantic-release/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/semantic-release/node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/semantic-release/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -11228,21 +10830,6 @@ "node": ">=10" } }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semver-regex": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", @@ -11392,16 +10979,6 @@ "node": ">=8" } }, - "node_modules/shiki": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.3.tgz", - "integrity": "sha512-eneCLncGuvPdTutJuLyUGS8QNPAVFO5Trvld2wgEq1e002mwctAhJKeMGWtWVXOIEzmlcLRqcgPSorR6AVzOmQ==", - "dev": true, - "dependencies": { - "@shikijs/core": "1.10.3", - "@types/hast": "^3.0.4" - } - }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -11424,7 +11001,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/signal-exit": { "version": "3.0.7", @@ -11529,25 +11107,12 @@ "node": ">=4" } }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dev": true, - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/skin-tone": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", "dev": true, + "license": "MIT", "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" }, @@ -11570,9 +11135,10 @@ "integrity": "sha512-UHYzVpz9Xn8b+jikYSD6bqvf754xL2uBUzDFwiU6NcdZeifPr6UfgU43xpkPu67VMS88+TI2PSI7Eohgqf2fKA==" }, "node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" @@ -11614,15 +11180,17 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "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" } @@ -11692,7 +11260,8 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", @@ -11704,10 +11273,11 @@ } }, "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", + "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", + "dev": true, + "license": "MIT" }, "node_modules/stdout-update": { "version": "4.0.1", @@ -11789,9 +11359,10 @@ } }, "node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -11850,11 +11421,12 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -11908,24 +11480,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", - "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", - "dev": true, - "dependencies": { - "js-tokens": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", - "dev": true - }, "node_modules/super-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.0.0.tgz", @@ -11955,16 +11509,20 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" }, "engines": { "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -11979,20 +11537,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/temp-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" } }, "node_modules/tempy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", - "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.2.0.tgz", + "integrity": "sha512-d79HhZya5Djd7am0q+W4RTsSU+D/aJzM+4Y4AGJGuGlgM2L6sx5ZvOYTmZjqPhrDrV6xJTtRSm1JCLj6V6LHLQ==", "dev": true, + "license": "MIT", "dependencies": { "is-stream": "^3.0.0", "temp-dir": "^3.0.0", @@ -12011,6 +11584,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -12038,6 +11612,7 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -12047,6 +11622,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -12086,25 +11662,76 @@ } }, "node_modules/tinybench": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", - "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", - "dev": true + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" }, - "node_modules/tinypool": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "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": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/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/tinyglobby/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", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -12130,15 +11757,6 @@ "node": ">=0.6" } }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", @@ -12230,6 +11848,16 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -12242,15 +11870,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -12342,31 +11961,33 @@ } }, "node_modules/typedoc": { - "version": "0.26.4", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.4.tgz", - "integrity": "sha512-FlW6HpvULDKgc3rK04V+nbFyXogPV88hurarDPOjuuB5HAwuAlrCMQ5NeH7Zt68a/ikOKu6Z/0hFXAeC9xPccQ==", + "version": "0.28.18", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.18.tgz", + "integrity": "sha512-NTWTUOFRQ9+SGKKTuWKUioUkjxNwtS3JDRPVKZAXGHZy2wCA8bdv2iJiyeePn0xkmK+TCCqZFT0X7+2+FLjngA==", "dev": true, + "license": "Apache-2.0", "dependencies": { + "@gerrit0/mini-shiki": "^3.23.0", "lunr": "^2.3.9", - "markdown-it": "^14.1.0", - "minimatch": "^9.0.5", - "shiki": "^1.9.1", - "yaml": "^2.4.5" + "markdown-it": "^14.1.1", + "minimatch": "^10.2.4", + "yaml": "^2.8.2" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 18" + "node": ">= 18", + "pnpm": ">= 10" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" } }, "node_modules/typedoc-material-theme": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/typedoc-material-theme/-/typedoc-material-theme-1.1.0.tgz", - "integrity": "sha512-LLWGVb8w+i+QGnsu/a0JKjcuzndFQt/UeGVOQz0HFFGGocROEHv5QYudIACrj+phL2LDwH05tJx0Ob3pYYH2UA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/typedoc-material-theme/-/typedoc-material-theme-1.4.1.tgz", + "integrity": "sha512-/inKZw8SqZPt+pmawpMhDmXCJQyIm+fHFuGChioyJQICZcX2FyzpwZnyPWcZHmJ09upttWFhti4ZI3hESJNkSA==", "dev": true, "funding": [ { @@ -12378,54 +11999,71 @@ "url": "https://commerce.coinbase.com/checkout/56cbdf28-e323-48d8-9c98-7019e72c97f3" } ], + "license": "MIT", "dependencies": { - "@material/material-color-utilities": "^0.2.7" + "@material/material-color-utilities": "^0.3.0" }, "engines": { "node": ">=18.0.0", "npm": ">=8.6.0" }, "peerDependencies": { - "typedoc": "^0.25.13 || ^0.26.3" + "typedoc": "^0.25.13 || ^0.26.x || ^0.27.x || ^0.28.x" } }, "node_modules/typedoc-plugin-missing-exports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-3.0.0.tgz", - "integrity": "sha512-R7D8fYrK34mBFZSlF1EqJxfqiUSlQSmyrCiQgTQD52nNm6+kUtqwiaqaNkuJ2rA2wBgWFecUA8JzHT7x2r7ePg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-4.1.3.tgz", + "integrity": "sha512-tgrlnwzXbqMP2/3BaZk0atddPsD7UnpCoeQ0cUCtk624gODT1bLYOLBEJLXQyVmbnP8HZCMhHpRiR+rxSdZqhg==", "dev": true, + "license": "MIT", "peerDependencies": { - "typedoc": "0.26.x" + "typedoc": "^0.28.1" + } + }, + "node_modules/typedoc/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/typedoc/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==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/typedoc/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -12440,19 +12078,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true - }, - "node_modules/ufo": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", - "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/uglify-js": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.0.tgz", - "integrity": "sha512-wNKHUY2hYYkf6oSFfhwwiHo4WCHzHmzcXsqXYTN9ja3iApYIFbb2U6ics9hBcYLHcYGQoAlwnZlTrf3oF+BL/Q==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, + "license": "BSD-2-Clause", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -12488,22 +12122,41 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "node_modules/unicode-emoji-modifier-base": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -12514,6 +12167,7 @@ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "dev": true, + "license": "MIT", "dependencies": { "crypto-random-string": "^4.0.0" }, @@ -12525,10 +12179,11 @@ } }, "node_modules/universal-user-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", - "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==", - "dev": true + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "dev": true, + "license": "ISC" }, "node_modules/universalify": { "version": "2.0.0", @@ -12561,6 +12216,7 @@ "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } @@ -12606,20 +12262,23 @@ } }, "node_modules/vite": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", - "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.1.tgz", + "integrity": "sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.8", + "rolldown": "1.0.0-rc.10", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -12628,27 +12287,41 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, - "less": { + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -12657,83 +12330,94 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, - "node_modules/vite-node": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", - "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, + "license": "MIT", "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": ">=12" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/vitest": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", - "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.0.tgz", + "integrity": "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/expect": "1.6.0", - "@vitest/runner": "1.6.0", - "@vitest/snapshot": "1.6.0", - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", - "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.3", - "vite": "^5.0.0", - "vite-node": "1.6.0", - "why-is-node-running": "^2.2.2" + "@vitest/expect": "4.1.0", + "@vitest/mocker": "4.1.0", + "@vitest/pretty-format": "4.1.0", + "@vitest/runner": "4.1.0", + "@vitest/snapshot": "4.1.0", + "@vitest/spy": "4.1.0", + "@vitest/utils": "4.1.0", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0", + "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.6.0", - "@vitest/ui": "1.6.0", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.0", + "@vitest/browser-preview": "4.1.0", + "@vitest/browser-webdriverio": "4.1.0", + "@vitest/ui": "4.1.0", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, + "@opentelemetry/api": { + "optional": true + }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { "optional": true }, "@vitest/ui": { @@ -12744,63 +12428,23 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, - "node_modules/vitest/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/vitest/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/vitest/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/vitest/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", "engines": { - "node": ">=14" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/which": { @@ -12854,10 +12498,11 @@ } }, "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, + "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -12873,7 +12518,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -12940,12 +12586,12 @@ "dev": true }, "node_modules/xmlhttprequest-ssl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.1.tgz", - "integrity": "sha512-ptjR8YSJIXoA3Mbv5po7RtSYHO6mZr8s7i5VGmEk7QY2pQWyT1o0N+W1gKbOyJPUCGXGnuw0wqe8f0L6Y0ny7g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-4.0.0.tgz", + "integrity": "sha512-b7DXzbCm8VWmII2mQiQHy5VG1L6YBUnNxuCooldWpMUXTwa08uXEz1q5Nv6wlULnSI5GiHuwBIq6pNJrqRh/8Q==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=13.0.0" } }, "node_modules/xtend": { @@ -12973,15 +12619,19 @@ "dev": true }, "node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, + "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { @@ -13083,10 +12733,11 @@ } }, "node_modules/yoctocolors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", - "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, diff --git a/package.json b/package.json index d929398..db247b6 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "scripts": { "generate-docs": "typedoc", "build": "tsc --build tsconfig.json", + "build:prod": "tsc --build tsconfig.prod.json", "cli": "npm run build && node -r dotenv/config ./dist/cli/cli.js", "format": "npm run lint:eslint -- --fix", "prepack": "npm run build", @@ -103,11 +104,10 @@ "@types/express": "^5.0.0", "@types/fs-extra": "^11.0.1", "@types/lodash.debounce": "^4.0.9", - "@types/node": "^20.4.9", + "@types/node": "^20.19.37", "@types/stream-throttle": "^0.1.4", "@typescript-eslint/eslint-plugin": "^6.3.0", "@typescript-eslint/parser": "^6.3.0", - "@vitest/ui": "^1.6.0", "dotenv": "^16.3.1", "eslint": "^8.46.0", "eslint-plugin-import": "^2.28.0", @@ -117,39 +117,37 @@ "express": "^4.21.1", "hash.js": "^1.1.7", "husky": "^8.0.3", - "semantic-release": "^24.0.0", + "semantic-release": "^25.0.3", "stream-throttle": "^0.1.3", "tslib": "^2.6.1", - "typedoc": "^0.26.3", - "typedoc-material-theme": "^1.1.0", - "typedoc-plugin-missing-exports": "^3.0.0", - "typescript": "^5.5.3", - "vitest": "^1.6.0", - "xmlhttprequest-ssl": "^2.1.1" + "typedoc": "^0.28.18", + "typedoc-material-theme": "^1.4.1", + "typedoc-plugin-missing-exports": "^4.1.3", + "typescript": "^5.9.3", + "vitest": "^4.1.0", + "xmlhttprequest-ssl": "^4.0.0" }, "optionalDependencies": { "@reflink/reflink": "^0.1.16" }, "dependencies": { - "@tinyhttp/content-disposition": "^2.2.0", + "@tinyhttp/content-disposition": "^2.2.4", "async-retry": "^1.3.3", "chalk": "^5.3.0", - "ci-info": "^4.0.0", - "cli-spinners": "^2.9.2", - "commander": "^10.0.0", - "eventemitter3": "^5.0.1", - "filenamify": "^6.0.0", - "fs-extra": "^11.1.1", - "is-unicode-supported": "^2.0.0", - "lifecycle-utils": "^1.3.1", + "ci-info": "^4.4.0", + "cli-spinners": "^3.4.0", + "commander": "^14.0.3", + "eventemitter3": "^5.0.4", + "filenamify": "^7.0.1", + "fs-extra": "^11.3.4", + "is-unicode-supported": "^2.1.0", + "lifecycle-utils": "^3.1.1", "lodash.debounce": "^4.0.8", "lowdb": "^7.0.1", - "pretty-bytes": "^6.1.0", - "pretty-ms": "^8.0.0", "sleep-promise": "^9.1.0", - "slice-ansi": "^7.1.0", + "slice-ansi": "^7.1.2", "stdout-update": "^4.0.1", - "strip-ansi": "^7.1.0", + "strip-ansi": "^7.2.0", "uid": "^2.0.2" } } diff --git a/src/cli/cli.ts b/src/cli/cli.ts index 71c359e..16b0441 100644 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -4,9 +4,9 @@ import {Command, Option} from "commander"; import {packageJson} from "../const.js"; import {downloadFile, downloadSequence} from "../download/node-download.js"; import {setCommand} from "./commands/set.js"; -import findDownloadDir, {downloadToDirectory, findFileName} from "./utils/find-download-dir.js"; +import findDownloadDir, {findFileName} from "./utils/find-download-dir.js"; import {AvailableCLIProgressStyle} from "../download/transfer-visualize/transfer-cli/progress-bars/switch-cli-progress-style.js"; - +import fs from "fs/promises"; const pullCommand = new Command(); pullCommand @@ -14,7 +14,7 @@ pullCommand .argument("[files...]", "Files to pull/copy") .option("-s --save [path]", "Save location (directory/file)") .option("-c --connections [number]", "Number of parallel connections", "4") - .addOption(new Option("-st --style [type]", "The style of the CLI progress bar").choices(["basic", "fancy", "ci", "summary"])) + .addOption(new Option("--style [type]", "The style of the CLI progress bar").choices(["basic", "fancy", "ci", "summary"])) .addOption(new Option("-p --program [type]", "The download strategy").choices(["stream", "chunks"])) .option("-t --truncate-name", "Truncate file names in the CLI status to make them appear shorter") .action(async (files: string[] = [], {save: saveLocation, truncateName, number, program, style}: { @@ -29,11 +29,33 @@ pullCommand process.exit(0); } + let saveLocationIsDirectory = false; + if (saveLocation) { + try { + const stat = await fs.lstat(saveLocation); + saveLocationIsDirectory = stat.isDirectory(); + } catch { + saveLocationIsDirectory = saveLocation.endsWith(path.sep); + } + } + const fileDownloads = await Promise.all( - files.map(async (file) => { - const isDirectory = saveLocation && await downloadToDirectory(saveLocation); - const directory = isDirectory ? saveLocation : await findDownloadDir(findFileName(file)); - const fileName = isDirectory || !saveLocation ? "" : path.basename(saveLocation); + files.map(async (file, index) => { + + let fileName: string | undefined; + let directory = await findDownloadDir(findFileName(file)); + + if (saveLocation) { + if (saveLocationIsDirectory) { + directory = saveLocation; + } else { + directory = path.dirname(saveLocation); + + const basename = path.basename(saveLocation); + const fileIndex = files.length > 1 ? ((index + 1) + "-") : ""; + fileName = fileIndex + basename; + } + } return await downloadFile({ url: file, diff --git a/src/download/download-engine/download-file/download-engine-file.ts b/src/download/download-engine/download-file/download-engine-file.ts index 90bb825..7b1845b 100644 --- a/src/download/download-engine/download-file/download-engine-file.ts +++ b/src/download/download-engine/download-file/download-engine-file.ts @@ -1,30 +1,29 @@ -import ProgressStatusFile, {DownloadFlags, DownloadStatus, ProgressStatus} from "./progress-status-file.js"; -import {ChunkStatus, DownloadFile, SaveProgressInfo} from "../types.js"; -import BaseDownloadEngineFetchStream from "../streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js"; -import BaseDownloadEngineWriteStream from "../streams/download-engine-write-stream/base-download-engine-write-stream.js"; -import retry from "async-retry"; import {EventEmitter} from "eventemitter3"; -import {withLock} from "lifecycle-utils"; -import switchProgram, {AvailablePrograms} from "./download-programs/switch-program.js"; -import BaseDownloadProgram from "./download-programs/base-download-program.js"; -import {pushComment} from "./utils/push-comment.js"; import {uid} from "uid"; +import BaseDownloadEngineWriteStream from "../streams/download-engine-write-stream/base-download-engine-write-stream.js"; +import {ChunkStatus, DownloadFile, SaveProgressInfo} from "../types.js"; +import BaseDownloadProgram from "./download-programs/base-download-program.js"; +import switchProgram, {AvailablePrograms} from "./download-programs/switch-program.js"; import {DownloaderProgramManager} from "./downloaderProgramManager.js"; +import {DownloadFlags, DownloadStatus, ProgressStatus} from "./progress-status-file.js"; +import {pushComment} from "./utils/push-comment.js"; + +export type DownloadEngineFilePerPartOptions = { + parallelStreams: number; + autoIncreaseParallelStreams: boolean; + programType: AvailablePrograms; +}; export type DownloadEngineFileOptions = { chunkSize?: number; - parallelStreams?: number; - retry?: retry.Options - comment?: string - fetchStream: BaseDownloadEngineFetchStream, + comment?: string; writeStream: BaseDownloadEngineWriteStream, - onFinishAsync?: () => Promise - onStartedAsync?: () => Promise - onCloseAsync?: () => Promise - onPausedAsync?: () => Promise - onSaveProgressAsync?: (progress: SaveProgressInfo) => Promise - programType?: AvailablePrograms - autoIncreaseParallelStreams?: boolean + onFinishAsync?: () => Promise; + onStartedAsync?: () => Promise; + onCloseAsync?: () => Promise; + onPausedAsync?: () => Promise; + onSaveProgress?: (progress: SaveProgressInfo) => void; + progressThrottleMs?: number; /** @internal */ skipExisting?: boolean; @@ -32,18 +31,18 @@ export type DownloadEngineFileOptions = { export type DownloadEngineFileOptionsWithDefaults = DownloadEngineFileOptions & { chunkSize: number; - parallelStreams: number; + progressThrottleMs: number; }; export type DownloadEngineFileEvents = { - start: () => void - paused: () => void - resumed: () => void - progress: (progress: ProgressStatus) => void - save: (progress: SaveProgressInfo) => void - finished: () => void - closed: () => void - [key: string]: any + start: () => void; + paused: () => void; + resumed: () => void; + progress: (progress: ProgressStatus) => void; + save: (progress: SaveProgressInfo) => void; + finished: () => void; + closed: () => void; + [key: string]: any; }; const DEFAULT_CHUNKS_SIZE_FOR_CHUNKS_PROGRAM = 1024 * 1024 * 5; // 5MB @@ -51,8 +50,13 @@ const DEFAULT_CHUNKS_SIZE_FOR_STREAM_PROGRAM = 1024 * 1024; // 1MB const DEFAULT_OPTIONS: Omit = { chunkSize: 0, + progressThrottleMs: 10 +}; + +export const DEFAULT_DOWNLOAD_ENGINE_FILE_PER_PART_OPTIONS: DownloadEngineFilePerPartOptions = { parallelStreams: 3, - autoIncreaseParallelStreams: true + autoIncreaseParallelStreams: true, + programType: "stream" }; export default class DownloadEngineFile extends EventEmitter { @@ -63,19 +67,18 @@ export default class DownloadEngineFile extends EventEmitter; protected _activeStreamContext: { [key: number]: { streamBytes: number, - retryingAttempts: number + retryingAttempts: number; isRetrying?: boolean, - isStreamNotResponding?: boolean - } + isStreamNotResponding?: boolean; + }; } = {}; protected _activeProgram?: BaseDownloadProgram; @@ -86,7 +89,11 @@ export default class DownloadEngineFile extends EventEmitter acc + part.size, 0); + return this.file.parts.reduce((acc, part) => acc + part.downloadSize, 0); } public get fileName() { @@ -125,11 +132,21 @@ export default class DownloadEngineFile extends EventEmitter c.isRetrying); - thisStatus.retryingTotalAttempts = Math.max(...streamContexts.map(x => x.retryingAttempts)); + thisStatus.retryingTotalAttempts = Math.max(0, ...streamContexts.map(x => x.retryingAttempts)); thisStatus.streamsNotResponding = streamContexts.reduce((acc, cur) => acc + (cur.isStreamNotResponding ? 1 : 0), 0); return thisStatus; @@ -141,7 +158,7 @@ export default class DownloadEngineFile extends EventEmitter acc + part.size, 0); + .reduce((acc, part) => acc + part.downloadSize, 0); } private get _activeDownloadedChunkSize() { @@ -157,27 +174,28 @@ export default class DownloadEngineFile extends EventEmitter acc + cur.streamBytes, 0); const streamBytes = this._activeDownloadedChunkSize + streamingBytes; - const streamBytesMin = Math.min(streamBytes, this._activePart.size || streamBytes); + const streamBytesMin = Math.min(streamBytes, this._activePart.downloadSize || streamBytes); const allBytes = streamBytesMin + this._downloadedPartsSize; return Math.min(allBytes, this.downloadSize || allBytes); } - protected get _programType() { - if (this.options.programType && this.options.fetchStream.availablePrograms.includes(this.options.programType)) { - return this.options.programType; + protected get _thisPartProgramType() { + const part = this._activePart; + if (part.programType && part.acceptRange && part.fetchStream.availablePrograms.includes(part.programType)) { + return part.programType; } - return this.options.fetchStream.defaultProgramType; + return part.fetchStream.defaultProgramType; } - protected _emptyChunksForPart(part: number) { + protected _chunksForPart(part: number, fill = ChunkStatus.NOT_STARTED) { const partInfo = this.file.parts[part]; - if (partInfo.size === 0) { + if (partInfo.downloadSize === 0) { return [ChunkStatus.NOT_STARTED]; } - const chunksCount = Math.ceil(partInfo.size / this.options.chunkSize); - return new Array(chunksCount).fill(ChunkStatus.NOT_STARTED); + const chunksCount = Math.ceil(partInfo.downloadSize / this.options.chunkSize); + return new Array(chunksCount).fill(fill); } private _initEventReloadStatus() { @@ -189,19 +207,18 @@ export default class DownloadEngineFile extends EventEmitter this._progress.part || !this._activePart.acceptRange) { this._progress.part = i; this._progress.chunkSize = this.options.chunkSize; - this._progress.parallelStreams = this.options.parallelStreams; - this._progress.chunks = this._emptyChunksForPart(i); + this._progress.chunks = this._chunksForPart(i); } // Reset in progress chunks @@ -234,15 +251,17 @@ export default class DownloadEngineFile extends EventEmitter 0 ? this._progress.chunks.length : Infinity; + const chunksToRead = this._activePart.downloadSize > 0 ? this._progress.chunks.length : Infinity; await this._downloadSlice(0, chunksToRead); } + + this._activePart.fetchStream.close(); } // All parts are downloaded, we can clear the progress @@ -263,7 +284,7 @@ export default class DownloadEngineFile extends EventEmitter this._activeStreamContext[startChunk] ??= {streamBytes: 0, retryingAttempts: 0}; - const fetchState = this.options.fetchStream.withSubState({ + const fetchState = this._activePart.fetchStream.withSubState({ chunkSize: this._progress.chunkSize, startChunk, endChunk: endChunk, @@ -281,7 +302,7 @@ export default class DownloadEngineFile extends EventEmitter { getContext().streamBytes = length; - this._sendProgressDownloadPart(); + this._throttledSendProgress(); } }); @@ -324,7 +345,7 @@ export default class DownloadEngineFile extends EventEmitter c === ChunkStatus.COMPLETE); } @@ -359,18 +381,13 @@ export default class DownloadEngineFile extends EventEmitter { - if (thisProgress === this._latestProgressDate && !this._closed && this._downloadStatus !== DownloadStatus.Finished) { - await this.options.onSaveProgressAsync?.(this._progress); - } - }); + this.options.onSaveProgress?.(this._progress); } protected _sendProgressDownloadPart() { @@ -378,24 +395,34 @@ export default class DownloadEngineFile extends EventEmitter= this.options.progressThrottleMs) { + this._sendProgressDownloadPart(); + this._latestProgressDate = Date.now(); + return; + } + } + public async pause() { - if (this.options.fetchStream.paused) { + if (this._activePart.fetchStream.paused) { return; } this._downloadStatus = DownloadStatus.Paused; - this.options.fetchStream.emit("paused"); + this._activePart.fetchStream.emit("paused"); await this.options.onPausedAsync?.(); this._sendProgressDownloadPart(); } public resume() { - if (!this.options.fetchStream.paused) { + if (!this._activePart.fetchStream.paused) { return; } this._downloadStatus = DownloadStatus.Active; - this.options.fetchStream.emit("resumed"); + this._activePart.fetchStream.emit("resumed"); this.emit("resumed"); this._sendProgressDownloadPart(); } @@ -403,15 +430,15 @@ export default class DownloadEngineFile extends EventEmitter void; protected _activeDownloads: Promise[] = []; - protected constructor(_savedProgress: SaveProgressInfo, _downloadSlice: DownloadSlice) { + protected constructor(_savedProgress: SaveProgressInfo, parallelStreams: number, _downloadSlice: DownloadSlice) { this._downloadSlice = _downloadSlice; this.savedProgress = _savedProgress; - this._parallelStreams = this.savedProgress.parallelStreams; + this._parallelStreams = parallelStreams; } get parallelStreams() { @@ -47,10 +47,6 @@ export default abstract class BaseDownloadProgram { } public async download(): Promise { - if (this._parallelStreams === 1) { - return await this._downloadSlice(0, this.savedProgress.chunks.length); - } - this._createFirstSlices(); while (!this._aborted) { diff --git a/src/download/download-engine/download-file/download-programs/download-program-chunks.ts b/src/download/download-engine/download-file/download-programs/download-program-chunks.ts index eb98009..d8f1935 100644 --- a/src/download/download-engine/download-file/download-programs/download-program-chunks.ts +++ b/src/download/download-engine/download-file/download-programs/download-program-chunks.ts @@ -2,8 +2,8 @@ import {ChunkStatus, SaveProgressInfo} from "../../types.js"; import BaseDownloadProgram, {DownloadSlice, ProgramSlice} from "./base-download-program.js"; export default class DownloadProgramChunks extends BaseDownloadProgram { - public constructor(savedProgress: SaveProgressInfo, downloadSlice: DownloadSlice) { - super(savedProgress, downloadSlice); + public constructor(savedProgress: SaveProgressInfo, parallelStreams: number, downloadSlice: DownloadSlice) { + super(savedProgress, parallelStreams, downloadSlice); } protected _createOneSlice(): ProgramSlice | null { diff --git a/src/download/download-engine/download-file/download-programs/download-program-stream.ts b/src/download/download-engine/download-file/download-programs/download-program-stream.ts index 4d3e0b1..7bf04e3 100644 --- a/src/download/download-engine/download-file/download-programs/download-program-stream.ts +++ b/src/download/download-engine/download-file/download-programs/download-program-stream.ts @@ -3,8 +3,8 @@ import BaseDownloadProgram, {DownloadSlice, ProgramSlice} from "./base-download- export default class DownloadProgramStream extends BaseDownloadProgram { - public constructor(savedProgress: SaveProgressInfo, downloadSlice: DownloadSlice) { - super(savedProgress, downloadSlice); + public constructor(savedProgress: SaveProgressInfo, parallelStreams: number, downloadSlice: DownloadSlice) { + super(savedProgress, parallelStreams, downloadSlice); } protected _createOneSlice(): ProgramSlice | null { @@ -40,4 +40,12 @@ export default class DownloadProgramStream extends BaseDownloadProgram { return chunksSlices.sort((a, b) => (b.end - b.start) - (a.end - a.start)); } + + override async download(): Promise { + if (this._parallelStreams === 1) { + return await this._downloadSlice(0, this.savedProgress.chunks.length); + } + + return await super.download(); + } } diff --git a/src/download/download-engine/download-file/download-programs/switch-program.ts b/src/download/download-engine/download-file/download-programs/switch-program.ts index 5bfb064..80c15f8 100644 --- a/src/download/download-engine/download-file/download-programs/switch-program.ts +++ b/src/download/download-engine/download-file/download-programs/switch-program.ts @@ -5,12 +5,12 @@ import DownloadProgramStream from "./download-program-stream.js"; export type AvailablePrograms = "stream" | "chunks"; -export default function switchProgram(savedProgress: SaveProgressInfo, downloadSlice: DownloadSlice, name?: AvailablePrograms) { +export default function switchProgram(savedProgress: SaveProgressInfo, parallelStreams: number, downloadSlice: DownloadSlice, name?: AvailablePrograms) { switch (name) { case "chunks": - return new DownloadProgramChunks(savedProgress, downloadSlice); + return new DownloadProgramChunks(savedProgress, parallelStreams, downloadSlice); case "stream": default: - return new DownloadProgramStream(savedProgress, downloadSlice); + return new DownloadProgramStream(savedProgress, parallelStreams, downloadSlice); } } diff --git a/src/download/download-engine/download-file/progress-status-file.ts b/src/download/download-engine/download-file/progress-status-file.ts index d07359d..0e22e47 100644 --- a/src/download/download-engine/download-file/progress-status-file.ts +++ b/src/download/download-engine/download-file/progress-status-file.ts @@ -31,74 +31,21 @@ export enum DownloadFlags { DownloadSequence = "DownloadSequence" } -export default class ProgressStatusFile { - public readonly totalDownloadParts: number; - public readonly fileName: string; - public readonly comment?: string; - public readonly downloadPart: number; - public readonly transferredBytes: number; - public readonly transferAction: string; - public downloadStatus: DownloadStatus = DownloadStatus.Active; - public downloadFlags: DownloadFlags[] = []; - public totalBytes: number = 0; - public startTime: number = 0; - public endTime: number = 0; - public downloadId: string = ""; - public retrying = false; - public retryingTotalAttempts = 0; - public streamsNotResponding = 0; - public constructor( - totalDownloadParts: number, - fileName: string, - transferAction = "Transferring", - downloadFlags: DownloadFlags[] = [], - comment?: string, - downloadPart = 0, - transferredBytes = 0, - downloadStatus = DownloadStatus.Active - ) { - this.transferAction = transferAction; - this.transferredBytes = transferredBytes; - this.downloadPart = downloadPart; - this.comment = comment; - this.fileName = fileName; - this.totalDownloadParts = totalDownloadParts; - this.downloadFlags = downloadFlags; - this.downloadStatus = downloadStatus; - } - - public started() { - this.startTime = Date.now(); - } - - public finished() { - this.endTime = Date.now(); - } - - public createStatus( - downloadPart: number, - transferredBytes: number, - totalBytes = this.totalBytes, - downloadStatus = DownloadStatus.Active, - comment = this.comment - ): ProgressStatusFile { - const newStatus = new ProgressStatusFile( - this.totalDownloadParts, - this.fileName, - this.transferAction, - this.downloadFlags, - comment, - downloadPart, - transferredBytes, - downloadStatus - ); - - newStatus.totalBytes = totalBytes; - newStatus.startTime = this.startTime; - newStatus.endTime = this.endTime; - newStatus.downloadId = this.downloadId; - - return newStatus; - } -} +export const EMPTY_PROGRESS_STATUS: ProgressStatus = { + transferAction: "Transferring", + downloadStatus: DownloadStatus.Loading, + downloadFlags: [], + retrying: false, + retryingTotalAttempts: 0, + streamsNotResponding: 0, + downloadId: "", + totalBytes: 0, + totalDownloadParts: 0, + fileName: "???", + comment: "", + downloadPart: 0, + transferredBytes: 0, + startTime: 0, + endTime: 0 +}; diff --git a/src/download/download-engine/engine/base-download-engine.ts b/src/download/download-engine/engine/base-download-engine.ts index 47672d1..8aa8594 100644 --- a/src/download/download-engine/engine/base-download-engine.ts +++ b/src/download/download-engine/engine/base-download-engine.ts @@ -1,5 +1,5 @@ import {DownloadFile, SaveProgressInfo} from "../types.js"; -import DownloadEngineFile, {DownloadEngineFileOptions} from "../download-file/download-engine-file.js"; +import DownloadEngineFile, {DEFAULT_DOWNLOAD_ENGINE_FILE_PER_PART_OPTIONS, DownloadEngineFileOptions} from "../download-file/download-engine-file.js"; import BaseDownloadEngineFetchStream, {BaseDownloadEngineFetchStreamOptions} from "../streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js"; import UrlInputError from "./error/url-input-error.js"; import {EventEmitter} from "eventemitter3"; @@ -10,32 +10,46 @@ import StatusCodeError from "../streams/download-engine-fetch-stream/errors/stat import {InvalidOptionError} from "./error/InvalidOptionError.js"; import {FormattedStatus} from "../../transfer-visualize/format-transfer-status.js"; import {promiseWithResolvers} from "../utils/promiseWithResolvers.js"; +import {RangeOutOfPartLengthError} from "./error/RangeOutOfPartLengthError.js"; const IGNORE_HEAD_STATUS_CODES = [405, 501, 404]; -export type InputURLOptions = { partURLs: string[] } | { url: string }; + +export type InputRange = { start: number; end: number; }; +export type FullPartURL = ({ + url: string, + range?: InputRange; + fetchStream?: BaseDownloadEngineFetchStream; +} & BaseDownloadEngineFetchStreamOptions); + +export type FullPartURLInternal = FullPartURL & { + fetchStream: BaseDownloadEngineFetchStream; +}; + +export type InputURLOptions = + { partURLs: string[]; } & BaseDownloadEngineFetchStreamOptions | FullPartURL | { partURLs: FullPartURL[]; }; export type CreateDownloadFileOptions = { - reuseRedirectURL?: boolean + reuseRedirectURL?: boolean; }; export type BaseDownloadEngineOptions = CreateDownloadFileOptions & InputURLOptions & BaseDownloadEngineFetchStreamOptions & { chunkSize?: number; parallelStreams?: number; - retry?: retry.Options + retry?: retry.Options; comment?: string; programType?: AvailablePrograms, - autoIncreaseParallelStreams?: boolean + autoIncreaseParallelStreams?: boolean; }; export type BaseDownloadEngineEvents = { - start: () => void - paused: () => void - resumed: () => void - progress: (progress: FormattedStatus) => void - save: (progress: SaveProgressInfo) => void - finished: () => void - closed: () => void - [key: string]: any + start: () => void; + paused: () => void; + resumed: () => void; + progress: (progress: FormattedStatus) => void; + save: (progress: SaveProgressInfo) => void; + finished: () => void; + closed: () => void; + [key: string]: any; }; export const DEFAULT_BASE_DOWNLOAD_ENGINE_OPTIONS: Partial = { @@ -147,8 +161,8 @@ export default class BaseDownloadEngine extends EventEmitter { try { - const {length, acceptRange, newURL, fileName} = await fetchStream.fetchDownloadInfo(part); - const downloadURL = reuseRedirectURL ? (newURL ?? part) : part; - const size = length || 0; + const {length, acceptRange, newURL, fileName} = await part.fetchStream.fetchDownloadInfo(part.url); + const downloadURL = reuseRedirectURL ? (newURL ?? part.url) : part.url; + const remoteFileSize = length || 0; + + const downloadSize = part.range ? (part.range.end - part.range.start + 1) : remoteFileSize; + if (downloadSize > remoteFileSize) { + throw new RangeOutOfPartLengthError(part.url, part.range!.end, remoteFileSize); + } - downloadFile.totalSize += size; + downloadFile.totalSize += downloadSize; if (index === 0 && fileName) { downloadFile.localFileName = fileName; } return { downloadURL, - originalURL: part, + originalURL: part.url, downloadURLUpdateDate: Date.now(), - size, - acceptRange: size > 0 && acceptRange + remoteFileSize, + downloadSize, + acceptRange: remoteFileSize > 0 && acceptRange, + range: part.range ?? {start: 0, end: remoteFileSize - 1}, + ...DEFAULT_DOWNLOAD_ENGINE_FILE_PER_PART_OPTIONS, + ...part }; } catch (error: any) { if (error instanceof StatusCodeError && IGNORE_HEAD_STATUS_CODES.includes(error.statusCode)) { - // if the server does not support HEAD request, we will skip that step + // if the server does not have info assume the server does not support range requests return { - downloadURL: part, - originalURL: part, + downloadURL: part.url, + originalURL: part.url, downloadURLUpdateDate: Date.now(), - size: 0, - acceptRange: false + remoteFileSize: 0, + downloadSize: 0, + acceptRange: false, + range: part.range ?? {start: 0, end: -1}, + ...DEFAULT_DOWNLOAD_ENGINE_FILE_PER_PART_OPTIONS, + ...part }; } throw error; @@ -192,6 +219,20 @@ export default class BaseDownloadEngine extends EventEmitter 0) { + fullPartURLs = options.partURLs.map((partURL) => + (typeof partURL === "string" ? {url: partURL, ...options} : partURL) + ); + } else if ("url" in options) { + fullPartURLs = [options]; + } + + return fullPartURLs; + } + protected static _validateURL(options: InputURLOptions) { if ("partURLs" in options && "url" in options) { throw new UrlInputError("Either `partURLs` or `url` should be provided, not both"); diff --git a/src/download/download-engine/engine/download-engine-browser.ts b/src/download/download-engine/engine/download-engine-browser.ts index cae83a5..e292e9f 100644 --- a/src/download/download-engine/engine/download-engine-browser.ts +++ b/src/download/download-engine/engine/download-engine-browser.ts @@ -1,11 +1,10 @@ -import {SaveProgressInfo} from "../types.js"; import DownloadEngineFile from "../download-file/download-engine-file.js"; import DownloadEngineFetchStreamFetch from "../streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; import DownloadEngineFetchStreamXhr from "../streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.js"; -import DownloadEngineWriteStreamBrowser, {DownloadEngineWriteStreamBrowserWriter} from "../streams/download-engine-write-stream/download-engine-write-stream-browser.js"; -import BaseDownloadEngine, {BaseDownloadEngineOptions, DEFAULT_BASE_DOWNLOAD_ENGINE_OPTIONS} from "./base-download-engine.js"; import BaseDownloadEngineWriteStream from "../streams/download-engine-write-stream/base-download-engine-write-stream.js"; -import BaseDownloadEngineFetchStream from "../streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js"; +import DownloadEngineWriteStreamBrowser, {DownloadEngineWriteStreamBrowserWriter} from "../streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import {SaveProgressInfo} from "../types.js"; +import BaseDownloadEngine, {BaseDownloadEngineOptions, DEFAULT_BASE_DOWNLOAD_ENGINE_OPTIONS, FullPartURLInternal} from "./base-download-engine.js"; export type DownloadEngineOptionsBrowser = BaseDownloadEngineOptions & { onWrite?: DownloadEngineWriteStreamBrowserWriter, @@ -14,15 +13,14 @@ export type DownloadEngineOptionsBrowser = BaseDownloadEngineOptions & { }; export type DownloadEngineOptionsCustomFetchBrowser = DownloadEngineOptionsBrowser & { - partURLs: string[]; - fetchStream: BaseDownloadEngineFetchStream + fullPartURLInternal: FullPartURLInternal[]; }; export type DownloadEngineOptionsBrowserConstructor = DownloadEngineOptionsCustomFetchBrowser & { - writeStream: WriteStream -}; + writeStream: WriteStream; + }; /** @@ -47,17 +45,17 @@ export default class DownloadEngineBrowser ({...part, fetchStream: part.fetchStream || new FetchStream(part)})); + return DownloadEngineBrowser._createFromOptionsWithCustomFetch({...options, fullPartURLInternal}); } protected static async _createFromOptionsWithCustomFetch(options: DownloadEngineOptionsCustomFetchBrowser) { - const downloadFile = await DownloadEngineBrowser._createDownloadFile(options.partURLs, options.fetchStream); + const downloadFile = await DownloadEngineBrowser._createDownloadFile(options.fullPartURLInternal, options); downloadFile.downloadProgress = options.progress; const writeStream = new DownloadEngineWriteStreamBrowser(options.onWrite, { diff --git a/src/download/download-engine/engine/download-engine-multi-download.ts b/src/download/download-engine/engine/download-engine-multi-download.ts index 110f667..052e0d5 100644 --- a/src/download/download-engine/engine/download-engine-multi-download.ts +++ b/src/download/download-engine/engine/download-engine-multi-download.ts @@ -231,13 +231,14 @@ export default class DownloadEngineMultiDownload = DownloadEngineOptionsNodejsCustomFetch & { - writeStream: WriteStream -}; + writeStream: WriteStream; + }; /** * Download engine for Node.js @@ -49,9 +46,9 @@ export default class DownloadEngineNodejs { + this._engine.options.onSaveProgress = (progress) => { if (this.options.skipExisting) return; - await this.options.writeStream.saveMetadataAfterFile(progress); + this.options.writeStream.saveMetadataAfterFlush(progress); }; this._engine.options.onPausedAsync = async () => { @@ -60,15 +57,15 @@ export default class DownloadEngineNodejs { - if (this.options.skipExisting || this.options.fetchStrategy !== "local" || this.options.partURLs.length !== 1) return; + if (this.options.skipExisting || this.options.fetchStrategy !== "local" || this.options.fullPartURLInternal.length !== 1 || this.options.fullPartURLInternal[0].range) return; try { const {reflinkFile} = await import("@reflink/reflink"); await fs.remove(this.options.writeStream.path); - await reflinkFile(this.options.partURLs[0], this.options.writeStream.path); + await reflinkFile(this.options.fullPartURLInternal[0].url, this.options.writeStream.path); this._engine.finished("cloned"); - } catch {} + } catch { } }; this._engine.options.onFinishAsync = async () => { @@ -117,13 +114,13 @@ export default class DownloadEngineNodejs { + override async close({deleteTempFile, deleteFile}: { deleteTempFile?: boolean, deleteFile?: boolean; } = {}): Promise { await super.close(); if (deleteFile || deleteTempFile && this.status.downloadStatus != DownloadStatus.Finished) { try { await fs.unlink(this.fileAbsolutePath); - } catch {} + } catch { } } } @@ -137,20 +134,33 @@ export default class DownloadEngineNodejs { + const fetchStrategy = part.fetchStream || options.fetchStrategy || DownloadEngineNodejs._guessFetchStrategy(part.url); + const fetchStream = part.fetchStream || ( + fetchStrategy === "local" ? + new DownloadEngineFetchStreamLocalFile(part) : + new DownloadEngineFetchStreamFetch(part) + ); + return {...part, fetchStream}; + }); + + return DownloadEngineNodejs._createFromOptionsWithCustomFetch({...options, fullPartURLInternal}); } protected static async _createFromOptionsWithCustomFetch(options: DownloadEngineOptionsNodejsCustomFetch) { - const downloadFile = await DownloadEngineNodejs._createDownloadFile(options.partURLs, options.fetchStream, options); - const downloadLocation = DownloadEngineNodejs._createDownloadLocation(downloadFile, options); - downloadFile.localFileName = path.basename(downloadLocation); + const downloadFile = await DownloadEngineNodejs._createDownloadFile(options.fullPartURLInternal, options); + let downloadLocation = "", fileName = ""; + + if ("savePath" in options) { + downloadLocation = options.savePath; + fileName = path.basename(options.savePath); + } else { + fileName = filenamify(options.fileName || downloadFile.localFileName); + downloadLocation = path.join(options.directory, fileName); + } + + downloadFile.localFileName = fileName; const writeStream = new DownloadEngineWriteStreamNodejs(downloadLocation + PROGRESS_FILE_EXTENSION, downloadLocation, options); writeStream.fileSize = downloadFile.totalSize; @@ -165,7 +175,7 @@ export default class DownloadEngineNodejs + retryOnServerError?: boolean; + headers?: Record; /** * If true, parallel download will be enabled even if the server does not return `accept-range` header, this is good when using cross-origin requests */ - acceptRangeIsKnown?: boolean - ignoreIfRangeWithQueryParams?: boolean + acceptRangeIsKnown?: boolean; + ignoreIfRangeWithQueryParams?: boolean; } & ( { - defaultFetchDownloadInfo?: { length: number, acceptRange: boolean } + defaultFetchDownloadInfo?: { length: number, acceptRange: boolean; }; } | { /** * Try different headers to see if any authentication is needed */ - tryHeaders?: Record[] + tryHeaders?: Record[]; /** * Delay between trying different headers */ - tryHeadersDelay?: number + tryHeadersDelay?: number; }); export type DownloadInfoResponse = { length: number, acceptRange: boolean, newURL?: string, - fileName?: string + fileName?: string; }; export type FetchSubState = { @@ -56,25 +63,26 @@ export type FetchSubState = { endChunk: number, lastChunkEndsFile: boolean, chunkSize: number, - onProgress?: (length: number) => void, + onProgress?: (downloadSize: number) => void, activePart: { - size: number, + remoteFileSize: number; + downloadSize: number, acceptRange?: boolean, downloadURL: string, originalURL: string, - downloadURLUpdateDate: number - } + downloadURLUpdateDate: number; + }; }; export type BaseDownloadEngineFetchStreamEvents = { - paused: () => void - resumed: () => void - aborted: () => void - errorCountIncreased: (errorCount: number, error: Error) => void - retryingOn: (error: Error, attempt: number) => void - retryingOff: () => void - streamNotRespondingOn: () => void - streamNotRespondingOff: () => void + paused: () => void; + resumed: () => void; + aborted: () => void; + errorCountIncreased: (errorCount: number, error: Error) => void; + retryingOn: (error: Error, attempt: number) => void; + retryingOff: () => void; + streamNotRespondingOn: () => void; + streamNotRespondingOff: () => void; }; export type WriteCallback = (data: Uint8Array[], position: number, index: number) => void; @@ -82,6 +90,7 @@ export type WriteCallback = (data: Uint8Array[], position: number, index: number const DEFAULT_OPTIONS: BaseDownloadEngineFetchStreamOptions = { retryOnServerError: true, maxStreamWait: 1000 * 15, + headersTimeout: 1000 * 30, retry: { retries: 50, factor: 1.5, @@ -94,7 +103,11 @@ const DEFAULT_OPTIONS: BaseDownloadEngineFetchStreamOptions = { minTimeout: 200, maxTimeout: 5_000 }, - tryHeadersDelay: 50 + tryHeadersDelay: 50, + range: { + start: 0, + end: -1 + } }; export default abstract class BaseDownloadEngineFetchStream extends EventEmitter { @@ -103,12 +116,15 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter public readonly abstract transferAction: string; public readonly supportDynamicStreamLength: boolean = false; public readonly options: Partial = {}; + public noRangeFetchSize = 0; public state: FetchSubState = null!; public paused?: Promise; public aborted = false; protected _pausedResolve?: () => void; + protected _cleanupClonedStateListeners?: () => void; public errorCount = {value: 0}; public lastFetchTime = 0; + private _closed = false; constructor(options: Partial = {}) { super(); @@ -117,11 +133,12 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter } protected get _startSize() { - return this.state.startChunk * this.state.chunkSize; + return this.state.startChunk * this.state.chunkSize + this.options.range!.start; } protected get _endSize() { - return Math.min(this.state.endChunk * this.state.chunkSize, this.state.activePart.size); + const rangeEnd = this.options.range!.end >= 0 ? this.options.range!.end + 1 : Infinity; + return Math.min(this._startSize + this.state.endChunk * this.state.chunkSize, rangeEnd, this.state.activePart.remoteFileSize); } protected initEvents() { @@ -148,11 +165,23 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter protected cloneState(state: FetchSubState, fetchStream: Fetcher): Fetcher { fetchStream.state = state; fetchStream.errorCount = this.errorCount; - fetchStream.on("errorCountIncreased", this.emit.bind(this, "errorCountIncreased")); - - this.on("aborted", fetchStream.emit.bind(fetchStream, "aborted")); - this.on("paused", fetchStream.emit.bind(fetchStream, "paused")); - this.on("resumed", fetchStream.emit.bind(fetchStream, "resumed")); + const forwardErrorCount = this.emit.bind(this, "errorCountIncreased"); + const forwardAborted = fetchStream.emit.bind(fetchStream, "aborted"); + const forwardPaused = fetchStream.emit.bind(fetchStream, "paused"); + const forwardResumed = fetchStream.emit.bind(fetchStream, "resumed"); + + fetchStream.on("errorCountIncreased", forwardErrorCount); + this.on("aborted", forwardAborted); + this.on("paused", forwardPaused); + this.on("resumed", forwardResumed); + + fetchStream._cleanupClonedStateListeners = () => { + fetchStream.off("errorCountIncreased", forwardErrorCount); + this.off("aborted", forwardAborted); + this.off("paused", forwardPaused); + this.off("resumed", forwardResumed); + fetchStream._cleanupClonedStateListeners = undefined; + }; return fetchStream; } @@ -172,6 +201,11 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter } return response; } catch (error: any) { + if (error?.name === "AbortError" && this.aborted) { + throwErr = error; + return null; + } + this.errorCount.value++; this.emit("errorCountIncreased", this.errorCount.value, error); @@ -214,45 +248,49 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter let retryResolvers = retryAsyncStatementSimple(this.options.retry); let retryingOn = false; - // eslint-disable-next-line no-constant-condition - while (true) { - try { - this.lastFetchTime = Date.now(); - return await this.fetchWithoutRetryChunks((...args) => { - if (retryingOn) { - retryingOn = false; - this.emit("retryingOff"); + try { + // eslint-disable-next-line no-constant-condition + while (true) { + try { + this.lastFetchTime = Date.now(); + return await this.fetchWithoutRetryChunks((...args) => { + if (retryingOn) { + retryingOn = false; + this.emit("retryingOff"); + } + callback(...args); + }); + } catch (error: any) { + if (error?.name === "AbortError" && this.aborted) return; + + this.errorCount.value++; + this.emit("errorCountIncreased", this.errorCount.value, error); + + const needToRecreateURL = this.shouldRecreateURL(error); + if (!needToRecreateURL && error instanceof HttpError && !this.retryOnServerError(error)) { + throw error; } - callback(...args); - }); - } catch (error: any) { - if (error?.name === "AbortError") return; - - this.errorCount.value++; - this.emit("errorCountIncreased", this.errorCount.value, error); - const needToRecreateURL = this.shouldRecreateURL(error); - if (!needToRecreateURL && error instanceof HttpError && !this.retryOnServerError(error)) { - throw error; - } + retryingOn = true; + this.emit("retryingOn", error, this.errorCount.value); + if (error instanceof StatusCodeError && error.retryAfter) { + await sleep(error.retryAfter * 1000); + continue; + } - retryingOn = true; - this.emit("retryingOn", error, this.errorCount.value); - if (error instanceof StatusCodeError && error.retryAfter) { - await sleep(error.retryAfter * 1000); - continue; - } + if (lastStartLocation !== this.state.startChunk) { + lastStartLocation = this.state.startChunk; + retryResolvers = retryAsyncStatementSimple(this.options.retry); + } - if (lastStartLocation !== this.state.startChunk) { - lastStartLocation = this.state.startChunk; - retryResolvers = retryAsyncStatementSimple(this.options.retry); + await Promise.all([ + retryResolvers(error), + needToRecreateURL && this.recreateDownloadURL() + ]); } - - await Promise.all([ - retryResolvers(error), - needToRecreateURL && this.recreateDownloadURL() - ]); } + } finally { + this._cleanupClonedStateListeners?.(); } } @@ -262,7 +300,7 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter } recreateDownloadURL() { - return withLock(this.state.activePart, "_recreateURLLock", async () => { + return withLock([this.state.activePart, "_recreateURLLock"], async () => { if (this.state.activePart.downloadURLUpdateDate > this.lastFetchTime) { return; // The URL was updated while we were waiting for the lock } @@ -276,6 +314,10 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter protected abstract fetchWithoutRetryChunks(callback: WriteCallback): Promise | void; public close(): void | Promise { + if (this._closed) return; + this._closed = true; + + this._cleanupClonedStateListeners?.(); this.emit("aborted"); } @@ -294,4 +336,22 @@ export default abstract class BaseDownloadEngineFetchStream extends EventEmitter return Boolean(this.options.retryOnServerError) && error instanceof StatusCodeError && (error.statusCode >= 500 || error.statusCode === 429); } + + static timeoutAbortController(timeout: number) { + const abortController = new AbortController(); + let headersTimeout: null | ReturnType = setTimeout(() => { + abortController.abort(`Fetch headers timeout after ${prettyMillisecondsCompact(timeout)}`); + }, timeout); + + return { + signal: abortController.signal, + abort: (reason?: string) => abortController.abort(reason), + clearAbortTimeout: () => { + if (headersTimeout != null) { + clearTimeout(headersTimeout); + headersTimeout = null; + } + } + }; + } } diff --git a/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts b/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts index 6cd77a0..5a25723 100644 --- a/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts +++ b/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.ts @@ -12,12 +12,12 @@ import StatusCodeError from "./errors/status-code-error.js"; import {parseHttpContentRange} from "./utils/httpRange.js"; import {browserCheck} from "./utils/browserCheck.js"; import {EmptyStreamTimeoutError} from "./errors/EmptyStreamTimeoutError.js"; -import prettyMilliseconds from "pretty-ms"; +import prettyMillisecondsCompact from "../../../transfer-visualize/utils/prettyMSFast.js"; type GetNextChunk = () => Promise> | ReadableStreamReadResult; export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFetchStream { private _fetchDownloadInfoWithHEAD = false; - private _activeController?: AbortController; + private _activeController?: { signal: AbortSignal; abort: () => void; }; public override transferAction = "Downloading"; public override readonly supportDynamicStreamLength = true; @@ -27,12 +27,13 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe } protected override async fetchWithoutRetryChunks(callback: WriteCallback) { - const headers: { [key: string]: any } = { + const headers: { [key: string]: any; } = { accept: "*/*", ...this.options.headers }; - if (this.state.activePart.acceptRange) { + const expectedContentLength = this._endSize - this._startSize; + if (this.state.activePart.acceptRange && expectedContentLength > 0) { headers.range = `bytes=${this._startSize}-${this._endSize - 1}`; } @@ -40,32 +41,32 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe this._activeController?.abort(); } - let response: Response | null = null; - this._activeController = new AbortController(); - this.on("aborted", () => { - if (!response) { - this._activeController?.abort(); - } - }); + const {signal, abort, clearAbortTimeout} = DownloadEngineFetchStreamFetch.timeoutAbortController(this.options.headersTimeout!); + this._activeController = {abort, signal}; + this.on("aborted", abort); + try { + const response = await fetch(this.appendToURL(this.state.activePart.downloadURL), { + headers, + signal + }); - response = await fetch(this.appendToURL(this.state.activePart.downloadURL), { - headers, - signal: this._activeController.signal - }); + clearAbortTimeout(); - if (response.status < 200 || response.status >= 300) { - throw new StatusCodeError(this.state.activePart.downloadURL, response.status, response.statusText, headers); - } + if (response.status < 200 || response.status >= 300) { + throw new StatusCodeError(this.state.activePart.downloadURL, response.status, response.statusText, headers); + } - const contentLength = parseHttpContentRange(response.headers.get("content-range"))?.length ?? parseInt(response.headers.get("content-length")!); - const expectedContentLength = this._endSize - this._startSize; - if (this.state.activePart.acceptRange && contentLength !== expectedContentLength) { - throw new InvalidContentLengthError(expectedContentLength, contentLength); - } + const contentLength = parseHttpContentRange(response.headers.get("content-range"))?.length ?? parseInt(response.headers.get("content-length")!); + if (this._endSize > 0 && (this.state.activePart.acceptRange && contentLength !== expectedContentLength || contentLength && contentLength < expectedContentLength)) { + throw new InvalidContentLengthError(expectedContentLength, contentLength); + } - const reader = response.body!.getReader(); - return await this.chunkGenerator(callback, () => reader.read()); + const reader = response.body!.getReader(); + return await this.chunkGenerator(callback, () => reader.read()); + } finally { + this.off("aborted", abort); + } } protected override async fetchDownloadInfoWithoutRetry(url: string): Promise { @@ -84,14 +85,22 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe } protected async fetchDownloadInfoWithoutRetryByMethod(url: string, method: "HEAD" | "GET" = "HEAD"): Promise { + const {signal, abort, clearAbortTimeout} = DownloadEngineFetchStreamFetch.timeoutAbortController(this.options.headersTimeout!); + const response = await fetch(url, { method: method, headers: { "Accept-Encoding": "identity", ...this.options.headers - } + }, + signal }); + clearAbortTimeout(); + + if (response.body) { + abort(); + } if (response.status < 200 || response.status >= 300) { throw new StatusCodeError(url, response.status, response.statusText, this.options.headers, DownloadEngineFetchStreamFetch.convertHeadersToRecord(response.headers)); @@ -101,8 +110,20 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe const fileName = parseContentDisposition(response.headers.get("content-disposition")); let length = parseInt(response.headers.get("content-length")!) || 0; - if (response.headers.get("content-encoding") || browserCheck() && MIN_LENGTH_FOR_MORE_INFO_REQUEST < length) { - length = acceptRange ? await this.fetchDownloadInfoWithoutRetryContentRange(url, method === "GET" ? response : undefined) : 0; + const someLengthInfo = length; + + const contentEncoding = response.headers.get("content-encoding"); + if (contentEncoding && contentEncoding !== "identity") { + length = 0; // If content is encoded, we cannot determine the length reliably + } + + if (length === 0 && (acceptRange || browserCheck() && (method === "GET" || MIN_LENGTH_FOR_MORE_INFO_REQUEST < someLengthInfo))) { + if (method !== "GET") { + return this.fetchDownloadInfoWithoutRetryByMethod(url, "GET"); + } + + const contentRange = response.headers.get("content-range"); + length = parseHttpContentRange(contentRange)?.size || 0; } return { @@ -113,31 +134,42 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe }; } - protected async fetchDownloadInfoWithoutRetryContentRange(url: string, response?: Response) { - const responseGet = response ?? await fetch(url, { - method: "GET", - headers: { - accept: "*/*", - ...this.options.headers, - range: "bytes=0-0" - } - }); - - const contentRange = responseGet.headers.get("content-range"); - return parseHttpContentRange(contentRange)?.size || 0; - } - async chunkGenerator(callback: WriteCallback, getNextChunk: GetNextChunk) { const smartSplit = new SmartChunkSplit(callback, this.state); + let dynamicContentLengthReached = false; // eslint-disable-next-line no-constant-condition while (true) { const chunkInfo = await this._wrapperStreamNotResponding(getNextChunk()); + await this.paused; if (!chunkInfo || this.aborted || chunkInfo.done) break; - smartSplit.addChunk(chunkInfo.value); + let value = chunkInfo.value; + + this.noRangeFetchSize += chunkInfo.value.length; + + if (!this.state.activePart.acceptRange && this._startSize > 0) { + if (!dynamicContentLengthReached) { + if (this._startSize > this.noRangeFetchSize) { + this.state.onProgress?.(this.noRangeFetchSize); + continue; + } + + const skipBytes = chunkInfo.value.length - (this.noRangeFetchSize - this._startSize); + value = chunkInfo.value.subarray(skipBytes); + + dynamicContentLengthReached = true; + } + } + + smartSplit.addChunk(value); this.state.onProgress?.(smartSplit.savedLength); + + if (dynamicContentLengthReached && this._endSize && this.noRangeFetchSize >= this._endSize) { + this._activeController?.abort(); + break; + } } smartSplit.closeAndSendLeftoversIfLengthIsUnknown(); @@ -158,7 +190,7 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe const timeoutMaxStreamWait = setTimeout(() => { timeoutMaxStreamWaitThrows = true; - reject(new EmptyStreamTimeoutError(`Stream timeout after ${prettyMilliseconds(this.options.maxStreamWait!)}`)); + reject(new EmptyStreamTimeoutError(`Stream timeout after ${prettyMillisecondsCompact(this.options.maxStreamWait!)}`)); this._activeController?.abort(); }, this.options.maxStreamWait); @@ -167,9 +199,12 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe promise .then(resolve) .catch(error => { - if (timeoutMaxStreamWaitThrows || this.aborted) { + if (timeoutMaxStreamWaitThrows) { return; } + if (this.aborted) { + return resolve(); + } reject(error); }) .finally(() => { @@ -184,8 +219,8 @@ export default class DownloadEngineFetchStreamFetch extends BaseDownloadEngineFe } - protected static convertHeadersToRecord(headers: Headers): { [key: string]: string } { - const headerObj: { [key: string]: string } = {}; + protected static convertHeadersToRecord(headers: Headers): { [key: string]: string; } { + const headerObj: { [key: string]: string; } = {}; headers.forEach((value, key) => { headerObj[key] = value; }); diff --git a/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-local-file.ts b/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-local-file.ts index b75612b..18ca78b 100644 --- a/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-local-file.ts +++ b/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-local-file.ts @@ -12,6 +12,7 @@ export default class DownloadEngineFetchStreamLocalFile extends BaseDownloadEngi public override transferAction = "Copying"; private _fd: FileHandle | null = null; private _fsPath: string | null = null; + private _fileOpenLock = {}; override withSubState(state: FetchSubState): this { const fetchStream = new DownloadEngineFetchStreamLocalFile(this.options); @@ -19,7 +20,7 @@ export default class DownloadEngineFetchStreamLocalFile extends BaseDownloadEngi } private async _ensureFileOpen(path: string) { - return await withLock(this, "_lock", async () => { + return await withLock([this._fileOpenLock, "_lock"], async () => { if (this._fd && this._fsPath === path) { return this._fd; } diff --git a/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts b/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts index 61860ac..b666dd6 100644 --- a/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts +++ b/src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.ts @@ -1,3 +1,6 @@ +import retry from "async-retry"; +import prettyMillisecondsCompact from "../../../transfer-visualize/utils/prettyMSFast.js"; +import {AvailablePrograms} from "../../download-file/download-programs/switch-program.js"; import BaseDownloadEngineFetchStream, { DownloadInfoResponse, FetchSubState, @@ -6,15 +9,13 @@ import BaseDownloadEngineFetchStream, { WriteCallback } from "./base-download-engine-fetch-stream.js"; import EmptyResponseError from "./errors/empty-response-error.js"; +import {EmptyStreamTimeoutError} from "./errors/EmptyStreamTimeoutError.js"; +import InvalidContentLengthError from "./errors/invalid-content-length-error.js"; import StatusCodeError from "./errors/status-code-error.js"; import XhrError from "./errors/xhr-error.js"; -import InvalidContentLengthError from "./errors/invalid-content-length-error.js"; -import retry from "async-retry"; -import {AvailablePrograms} from "../../download-file/download-programs/switch-program.js"; import {parseContentDisposition} from "./utils/content-disposition.js"; import {parseHttpContentRange} from "./utils/httpRange.js"; -import prettyMilliseconds from "pretty-ms"; -import {EmptyStreamTimeoutError} from "./errors/EmptyStreamTimeoutError.js"; + export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetchStream { @@ -37,15 +38,18 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc protected fetchBytesWithoutRetry(url: string, start: number, end: number, onProgress?: (length: number) => void): Promise { return new Promise((resolve, reject) => { - const headers: { [key: string]: any } = { + const headers: { [key: string]: any; } = { accept: "*/*", ...this.options.headers }; - if (this.state.activePart.acceptRange) { + const expectedContentLength = end - start; + if (this.state.activePart.acceptRange && expectedContentLength > 0) { headers.range = `bytes=${start}-${end - 1}`; } + const {signal, clearAbortTimeout} = DownloadEngineFetchStreamXhr.timeoutAbortController(this.options.headersTimeout!); + const xhr = new XMLHttpRequest(); xhr.responseType = "arraybuffer"; xhr.open("GET", this.appendToURL(url), true); @@ -80,27 +84,40 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc }, STREAM_NOT_RESPONDING_TIMEOUT); lastMaxStreamWaitTimeoutIndex = setTimeout(() => { - reject(new EmptyStreamTimeoutError(`Stream timeout after ${prettyMilliseconds(this.options.maxStreamWait!)}`)); - xhr.abort(); + abortXhr(new EmptyStreamTimeoutError(`Stream timeout after ${prettyMillisecondsCompact(this.options.maxStreamWait!)}`)); }, this.options.maxStreamWait); }; + const abortXhr = (throwError = new XhrError(`Aborted fetching ${url}`)) => { + clearStreamTimeout(); + clearAbortTimeout(); + xhr.abort(); + this.off("aborted", abortXhr); + + reject(throwError); + }; + xhr.onload = () => { clearStreamTimeout(); - const contentLength = parseInt(xhr.getResponseHeader("content-length")!); - - if (this.state.activePart.acceptRange && contentLength !== end - start) { - throw new InvalidContentLengthError(end - start, contentLength); - } + clearAbortTimeout(); if (xhr.status >= 200 && xhr.status < 300) { - if (xhr.response.length != contentLength) { - throw new InvalidContentLengthError(contentLength, xhr.response.length); - } - - const arrayBuffer = xhr.response; + const arrayBuffer: ArrayBuffer = xhr.response; if (arrayBuffer) { + if (this._endSize > 0) { + if (this.state.activePart.acceptRange) { + if (expectedContentLength != arrayBuffer.byteLength) { + return reject(new InvalidContentLengthError(expectedContentLength, arrayBuffer.byteLength)); + } + } else if (arrayBuffer.byteLength < expectedContentLength) { + return reject(new InvalidContentLengthError(expectedContentLength, arrayBuffer.byteLength)); + } else { + const newExpectedContentLength = this._endSize - start; // recalculate expected content length in case it was changed since the request was sent (e.g. due to retries with different range) + return resolve(new Uint8Array(arrayBuffer, start, Math.min(arrayBuffer.byteLength - start, newExpectedContentLength))); + } + } + resolve(new Uint8Array(arrayBuffer)); } else { reject(new EmptyResponseError(url, headers)); @@ -111,23 +128,39 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc }; xhr.onerror = () => { - clearStreamTimeout(); - reject(new XhrError(`Failed to fetch ${url}`)); + abortXhr(new XhrError(`Failed to fetch ${url}`)); }; xhr.onprogress = (event) => { createStreamTimeout(); if (event.lengthComputable) { onProgress?.(event.loaded); + this.noRangeFetchSize = event.loaded; + } + }; + + xhr.onreadystatechange = () => { + if (xhr.readyState != XMLHttpRequest.HEADERS_RECEIVED) { + return; } + + clearAbortTimeout(); + + const contentLength = parseHttpContentRange(xhr.getResponseHeader("content-range"))?.length ?? parseInt(xhr.getResponseHeader("content-length")!); + if (this.state.activePart.acceptRange && contentLength !== expectedContentLength || contentLength && expectedContentLength && contentLength < expectedContentLength) { + abortXhr(new InvalidContentLengthError(expectedContentLength, contentLength)); + } + }; + + xhr.onloadend = () => { + this.off("aborted", abortXhr); }; xhr.send(); createStreamTimeout(); - - this.on("aborted", () => { - clearStreamTimeout(); - xhr.abort(); + this.on("aborted", abortXhr); + signal.addEventListener("abort", () => { + abortXhr(new XhrError(signal.reason)); }); }); } @@ -192,9 +225,23 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc protected async fetchDownloadInfoWithoutRetryByMethod(url: string, method: "HEAD" | "GET" = "HEAD"): Promise { return new Promise((resolve, reject) => { + const {signal, abort, clearAbortTimeout} = DownloadEngineFetchStreamXhr.timeoutAbortController(this.options.headersTimeout!); + const xhr = new XMLHttpRequest(); xhr.open(method, url, true); + signal.addEventListener("abort", () => { + reject(new XhrError(signal.reason)); + xhr.abort(); + }); + + const abortXhr = () => { + abort(); + this.off("aborted", abortXhr); + }; + + this.on("aborted", abortXhr); + const allHeaders = { ...this.options.headers }; @@ -202,16 +249,44 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc xhr.setRequestHeader(key, value); } - xhr.onload = async () => { + xhr.onreadystatechange = () => { + if (xhr.readyState != XMLHttpRequest.HEADERS_RECEIVED) { + return; + } + + this.off("aborted", abortXhr); + + if (method != "HEAD") { + xhr.abort(); + } + + clearAbortTimeout(); + if (xhr.status >= 200 && xhr.status < 300) { - const contentLength = parseInt(xhr.getResponseHeader("content-length")!); - const length = MIN_LENGTH_FOR_MORE_INFO_REQUEST < contentLength ? await this.fetchDownloadInfoWithoutRetryContentRange(url, method === "GET" ? xhr : undefined) : 0; const fileName = parseContentDisposition(xhr.getResponseHeader("content-disposition")); const acceptRange = this.options.acceptRangeIsKnown ?? xhr.getResponseHeader("Accept-Ranges") === "bytes"; + const contentEncoding = xhr.getResponseHeader("content-encoding"); + + let length = parseInt(xhr.getResponseHeader("content-length")!) || 0; + const someLengthInfo = length; + + if (contentEncoding && contentEncoding !== "identity") { + length = 0; // If content is encoded, we cannot determine the length reliably + } + + if (length === 0 && (acceptRange || method === "GET" || MIN_LENGTH_FOR_MORE_INFO_REQUEST < someLengthInfo)) { + if (method !== "GET") { + resolve(this.fetchDownloadInfoWithoutRetryByMethod(url, "GET")); + return; + } + + const contentRange = xhr.getResponseHeader("Content-Range"); + length = parseHttpContentRange(contentRange)?.size || 0; + } resolve({ - length, acceptRange, + length, newURL: xhr.responseURL, fileName }); @@ -220,55 +295,21 @@ export default class DownloadEngineFetchStreamXhr extends BaseDownloadEngineFetc } }; - xhr.onerror = function () { - reject(new XhrError(`Failed to fetch ${url}`)); - }; - - xhr.send(); - }); - - } - - protected fetchDownloadInfoWithoutRetryContentRange(url: string, xhrResponse?: XMLHttpRequest) { - const getSize = (xhr: XMLHttpRequest) => { - const contentRange = xhr.getResponseHeader("Content-Range"); - return parseHttpContentRange(contentRange)?.size || 0; - }; - - if (xhrResponse) { - return getSize(xhrResponse); - } - - return new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - xhr.open("GET", url, true); - - const allHeaders = { - accept: "*/*", - ...this.options.headers, - range: "bytes=0-0" - }; - for (const [key, value] of Object.entries(allHeaders)) { - xhr.setRequestHeader(key, value); - } - - xhr.onload = () => { - resolve(getSize(xhr)); - }; - xhr.onerror = () => { + this.off("aborted", abortXhr); reject(new XhrError(`Failed to fetch ${url}`)); }; xhr.send(); }); + } protected static convertXHRHeadersToRecord(xhr: XMLHttpRequest): Record { const headersString = xhr.getAllResponseHeaders(); const headersArray = headersString.trim() .split(/[\r\n]+/); - const headersObject: { [key: string]: string } = {}; + const headersObject: { [key: string]: string; } = {}; headersArray.forEach(line => { const parts = line.split(": "); diff --git a/src/download/download-engine/streams/download-engine-fetch-stream/utils/content-disposition.ts b/src/download/download-engine/streams/download-engine-fetch-stream/utils/content-disposition.ts index 16c7463..abc895f 100644 --- a/src/download/download-engine/streams/download-engine-fetch-stream/utils/content-disposition.ts +++ b/src/download/download-engine/streams/download-engine-fetch-stream/utils/content-disposition.ts @@ -5,6 +5,10 @@ export function parseContentDisposition(header?: string | null): string | undefi return undefined; } + if (header.endsWith(";")){ + header = header.slice(0, -1).trimEnd(); + } + try { return String(parse(header).parameters.filename || "") || undefined; } catch {} diff --git a/src/download/download-engine/streams/download-engine-fetch-stream/utils/smart-chunk-split.ts b/src/download/download-engine/streams/download-engine-fetch-stream/utils/smart-chunk-split.ts index e60409c..e7223fa 100644 --- a/src/download/download-engine/streams/download-engine-fetch-stream/utils/smart-chunk-split.ts +++ b/src/download/download-engine/streams/download-engine-fetch-stream/utils/smart-chunk-split.ts @@ -6,7 +6,7 @@ export type SmartChunkSplitOptions = { endChunk: number; lastChunkEndsFile: boolean; activePart: { - size: number; + downloadSize: number; } }; @@ -27,7 +27,7 @@ export default class SmartChunkSplit { } public calcLastChunkSize() { - return this._options.activePart.size - Math.max(this._options.endChunk - 1, 0) * this._options.chunkSize; + return this._options.activePart.downloadSize - Math.max(this._options.endChunk - 1, 0) * this._options.chunkSize; } public addChunk(data: Uint8Array) { diff --git a/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.ts b/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.ts index 8099ac0..fc58e73 100644 --- a/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.ts +++ b/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.ts @@ -71,7 +71,7 @@ export default class DownloadEngineWriteStreamBrowser extends BaseDownloadEngine } public resultAsBlobURL() { - const blob = new Blob([this._memory]); + const blob = new Blob([this._memory as unknown as Uint8Array]); return URL.createObjectURL(blob); } diff --git a/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts b/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts index 12bfa73..ff620d5 100644 --- a/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts +++ b/src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-nodejs.ts @@ -1,58 +1,69 @@ -import fs, {FileHandle} from "fs/promises"; -import fsExtra from "fs-extra"; import retry from "async-retry"; +import fsExtra from "fs-extra"; +import fs, {FileHandle} from "fs/promises"; import {withLock} from "lifecycle-utils"; import BaseDownloadEngineWriteStream from "./base-download-engine-write-stream.js"; -import WriterIsClosedError from "./errors/writer-is-closed-error.js"; -import {BytesWriteDebounce} from "./utils/BytesWriteDebounce.js"; +import WriteQueue from "./utils/WriteQueue.js"; export type DownloadEngineWriteStreamOptionsNodeJS = { - retry?: retry.Options + retry?: retry.Options; mode: string; + /** @deprecated Use writeBufferMaxBytes instead */ debounceWrite?: { - maxTime?: number - maxSize?: number - } + maxTime?: number; + maxSize?: number; + }; + + /** Maximum bytes to buffer before flushing to disk (default: adaptive 5% of file size, min 2MB, max 64MB) */ + writeBufferMaxBytes?: number; }; -const DEFAULT_OPTIONS = { - mode: "r+", - debounceWrite: { - maxTime: 1000 * 5, // 5 seconds - maxSize: 1024 * 1024 * 2 // 2 MB - } -} satisfies DownloadEngineWriteStreamOptionsNodeJS; -const MAX_AUTO_DEBOUNCE_SIZE = 1024 * 1024 * 100; // 100 MB -const AUTO_DEBOUNCE_SIZE_PERCENT = 0.05; const MAX_META_SIZE = 10485760; // 10 MB -const NOT_ENOUGH_SPACE_ERROR_CODE = "ENOSPC"; +const DEFAULT_OPTIONS = { + mode: "r+" +} satisfies DownloadEngineWriteStreamOptionsNodeJS; export default class DownloadEngineWriteStreamNodejs extends BaseDownloadEngineWriteStream { + private static _allFd = new Set(); + private static _finalizationRegistry = new FinalizationRegistry((fd: FileHandle) => { + if (fd.fd != null) { + fd.close().catch(() => { }) + .finally(() => { + DownloadEngineWriteStreamNodejs._allFd.delete(fd); + }); + } + }); + + private _finalToken = {}; private _fd: FileHandle | null = null; - private _fileWriteFinished = false; - private _writeDebounce: BytesWriteDebounce; private _fileSize = 0; + private _writeQueue: WriteQueue; + private _metadataToSave: any = null; + private _fileOpenLock = {}; public readonly options: DownloadEngineWriteStreamOptionsNodeJS; - public autoDebounceMaxSize = false; constructor(public path: string, public finalPath: string, options: Partial = {}) { super(); - this.autoDebounceMaxSize = !options.debounceWrite?.maxSize; - const optionsWithDefaults = this.options = { + this.options = { ...DEFAULT_OPTIONS, - ...options, - debounceWrite: { - ...DEFAULT_OPTIONS.debounceWrite, - ...options.debounceWrite - } + ...options }; - this._writeDebounce = new BytesWriteDebounce({ - ...optionsWithDefaults.debounceWrite, - writev: (cursor, buffers) => this._writeWithoutDebounce(cursor, buffers) + this._writeQueue = new WriteQueue({ + getFd: this._ensureFileOpen.bind(this), + writeBufferMaxBytes: this.options.writeBufferMaxBytes || this.options.debounceWrite?.maxSize, + flushMetadata: () => { + if (this._metadataToSave) { + const metadata = this._metadataToSave; + this._metadataToSave = null; + return this._saveMetadata(metadata); + } + + return Promise.resolve(); + } }); } @@ -62,76 +73,61 @@ export default class DownloadEngineWriteStreamNodejs extends BaseDownloadEngineW public set fileSize(value) { this._fileSize = value; + this._writeQueue.setFileSize(value); + } - if (this.autoDebounceMaxSize) { - this.options.debounceWrite!.maxSize = Math.max( - Math.min(value * AUTO_DEBOUNCE_SIZE_PERCENT, MAX_AUTO_DEBOUNCE_SIZE), - DEFAULT_OPTIONS.debounceWrite.maxSize - ); + private _ensureFileOpen() { + if (this._fd) { + return this._fd; } - } - private async _ensureFileOpen() { - return await withLock(this, "_lock", async () => { + return withLock([this._fileOpenLock, "_lock"], async () => { if (this._fd) { return this._fd; } return await retry(async () => { await fsExtra.ensureFile(this.path); - return this._fd = await fs.open(this.path, this.options.mode); + this._fd = await fs.open(this.path, this.options.mode); + DownloadEngineWriteStreamNodejs._allFd.add(this._fd); + DownloadEngineWriteStreamNodejs._finalizationRegistry.register(this, this._fd, this._finalToken); + return this._fd; }, this.options.retry); }); } - async write(cursor: number, buffers: Uint8Array[]) { - await this._writeDebounce.addChunk(cursor, buffers); + /** + * Buffer a write for the given cursor position. + * Fragments are concatenated into a single Buffer, contiguous regions merged, + * and auto-flushed when the adaptive threshold is exceeded. + */ + write(cursor: number, buffers: Uint8Array[]) { + return this._writeQueue.addWrite(cursor, buffers); } - async _writeWithoutDebounce(cursor: number, buffers: Uint8Array[]) { - let throwError: Error | false = false; - - await retry(async () => { - try { - return await this._writeWithoutRetry(cursor, buffers); - } catch (error: any) { - if (error?.code === NOT_ENOUGH_SPACE_ERROR_CODE) { - throwError = error; - return; - } - throw error; - } - }, this.options.retry); - - if (throwError) { - throw throwError; - } - } - - async ensureBytesSynced() { - await this._writeDebounce.writeAll(); + ensureBytesSynced() { + return this._writeQueue.drain(); } async ftruncate(size = this._fileSize) { await this.ensureBytesSynced(); - this._fileWriteFinished = true; await retry(async () => { const fd = await this._ensureFileOpen(); await fd.truncate(size); }, this.options.retry); } - async saveMetadataAfterFile(data: any) { - if (this._fileWriteFinished) { - throw new WriterIsClosedError(); - } + saveMetadataAfterFlush(data: any) { + this._metadataToSave = data; + } + private async _saveMetadata(data: any) { const jsonString = JSON.stringify(data); + const uint8Array = new TextEncoder().encode(jsonString); - const encoder = new TextEncoder(); - const uint8Array = encoder.encode(jsonString); - - await this.write(this._fileSize, [uint8Array]); + const fdResult = this._ensureFileOpen(); + const fd = fdResult instanceof Promise ? await fdResult : fdResult; + await fd.write(uint8Array, 0, uint8Array.length, this._fileSize); } async loadMetadataAfterFileWithoutRetry() { @@ -157,23 +153,28 @@ export default class DownloadEngineWriteStreamNodejs extends BaseDownloadEngineW try { return JSON.parse(metadataString); - } catch {} + } catch { } } finally { - this._fd = null; - await fd.close(); + await this._closeFd(); } } - private async _writeWithoutRetry(cursor: number, buffers: Uint8Array[]) { - return await withLock(this, "lockWriteOperation", async () => { - const fd = await this._ensureFileOpen(); - const {bytesWritten} = await fd.writev(buffers, cursor); - return bytesWritten; - }); + override async close() { + this._writeQueue.close(); + await this._writeQueue.drain(); + await this._closeFd(); } - override async close() { - await this._fd?.close(); + private async _closeFd() { + if (!this._fd) { + return; + } + + if (this._fd.fd != null) { + await this._fd.close(); + } + DownloadEngineWriteStreamNodejs._allFd.delete(this._fd); + DownloadEngineWriteStreamNodejs._finalizationRegistry.unregister(this._finalToken); this._fd = null; } } diff --git a/src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts b/src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts new file mode 100644 index 0000000..bf58299 --- /dev/null +++ b/src/download/download-engine/streams/download-engine-write-stream/utils/WriteQueue.ts @@ -0,0 +1,182 @@ +import {FileHandle} from "fs/promises"; +import WriterIsClosedError from "../errors/writer-is-closed-error.js"; + +const MIN_BUFFER_SIZE = 2 * 1024 * 1024; // 2 MB +const MAX_BUFFER_SIZE = 64 * 1024 * 1024; // 64 MB +const ADAPTIVE_PERCENT = 0.05; + +export type WriteQueueOptions = { + writeBufferMaxBytes?: number; + flushMetadata: () => Promise; + getFd: () => Promise | FileHandle; +}; + +type PendingRegion = { + cursor: number; + buffers: Uint8Array[]; + length: number; +}; + +/** + * High-performance write buffer that coalesces contiguous writes + * and flushes them as parallel positional writes to the file descriptor. + * + * Design principles: + * - No locks — parallel positional writes (`fd.write` with offset) are safe for non-overlapping regions + * - Contiguous buffer merging — sequential writes from the same stream are combined + * - Adaptive threshold — flush size scales with file size (5%, min 2MB, max 64MB) + * - Data-driven flushes — threshold exceeded → immediate flush + * - Explicit drain on pause/close/truncate — no timers needed + */ +export default class WriteQueue { + private _options: WriteQueueOptions; + private _regions: PendingRegion[] = []; + private _totalBuffered = 0; + private _maxBufferedBytes: number = MIN_BUFFER_SIZE; + private _inFlightWrites = new Set>(); + private _closed = false; + + constructor(options: WriteQueueOptions) { + this._options = options; + + if (options?.writeBufferMaxBytes) { + this._maxBufferedBytes = options.writeBufferMaxBytes; + } + } + + setFileSize(fileSize: number) { + if (this._options?.writeBufferMaxBytes) return; + + this._maxBufferedBytes = Math.min( + Math.max(fileSize * ADAPTIVE_PERCENT, MIN_BUFFER_SIZE), + MAX_BUFFER_SIZE + ); + } + + /** + * Buffer a write. Concatenates fragments into a single Buffer, + * merges with adjacent regions, and flushes when threshold is exceeded. + */ + addWrite(cursor: number, buffers: Uint8Array[]): void | Promise { + if (this._closed) { + throw new WriterIsClosedError("Cannot add write to closed WriteQueue"); + } + + const length = buffers.reduce((sum, buf) => sum + buf.length, 0); + + const merged = this._tryMerge(cursor, buffers, length); + if (!merged) { + this._regions.push({cursor, buffers, length}); + } + + this._totalBuffered += length; + if (this._inFlightWrites.size === 0 && this._totalBuffered >= this._maxBufferedBytes) { + return this._flushNow(); + } + } + + /** + * Try to merge the new buffer with an existing region if contiguous. + */ + private _tryMerge(cursor: number, buffers: Uint8Array[], length: number): boolean { + for (let i = 0; i < this._regions.length; i++) { + const region = this._regions[i]; + const regionEnd = region.cursor + region.length; + + if (cursor === regionEnd) { + region.buffers.push(...buffers); + region.length += length; + } else if (cursor + length === region.cursor) { + region.cursor = cursor; + region.buffers.unshift(...buffers); + region.length += length; + } else { + continue; + } + + if (this._tryMerge(region.cursor, region.buffers, region.length)) { + this._regions.splice(i, 1); + } + } + + return false; + } + + /** + * Flush all buffered regions to disk as parallel positional writes. + * Non-overlapping positional writes via fd.write(buf, 0, len, position) are safe concurrently. + */ + private _flushNow(flushMetadata = true, flashAll = false): void | Promise { + if (this._regions.length === 0) return; + + const regionsToFlush = this._regions; + this._regions = []; + this._totalBuffered = 0; + + const flushPromise = this._doFlush(regionsToFlush, flushMetadata) + .finally(() => this._inFlightWrites.delete(flushPromise)); + + this._inFlightWrites.add(flushPromise); + + return flushPromise.then(async () => { + if (this._inFlightWrites.size > 0) { + await this._waitForInFlight(); + } + + if (this._totalBuffered >= this._maxBufferedBytes || flashAll && this._regions.length > 0) { + return this._flushNow(flushMetadata, flashAll); + } + }); + } + + private async _doFlush(regions: PendingRegion[], flushMetadata = true): Promise { + const fdResult = this._options.getFd(); + const fd = fdResult instanceof Promise ? await fdResult : fdResult; + + // Write all non-overlapping regions in parallel + const writes: Promise[] = regions.map(region => + fd.writev(region.buffers, region.cursor) + ); + + await Promise.all(writes); + + if (flushMetadata) { + await this._options.flushMetadata(); + } + } + + /** + * Flush all buffered data and wait for all in-flight writes to complete, after it flushes metadata. + * Called by ensureBytesSynced(), close(), ftruncate(). + */ + async drain(): Promise { + if (this._inFlightWrites.size > 0) { + await this._waitForInFlight(); + } + + await this._flushNow(false, true); + await this._options.flushMetadata(); + } + + private async _waitForInFlight(): Promise { + while (this._inFlightWrites.size > 0) { + await Promise.all(this._inFlightWrites); + } + } + + close() { + this._closed = true; + } + + get bufferedBytes(): number { + return this._totalBuffered; + } + + get pendingRegions(): number { + return this._regions.length; + } + + get inFlightCount(): number { + return this._inFlightWrites.size; + } +} diff --git a/src/download/download-engine/types.ts b/src/download/download-engine/types.ts index bdade31..d3f194c 100644 --- a/src/download/download-engine/types.ts +++ b/src/download/download-engine/types.ts @@ -1,9 +1,16 @@ -export type DownloadFilePart = { +import {DownloadEngineFilePerPartOptions} from "./download-file/download-engine-file.js"; +import {InputRange} from "./engine/base-download-engine.js"; +import BaseDownloadEngineFetchStream from "./streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js"; + +export type DownloadFilePart = DownloadEngineFilePerPartOptions & { downloadURL: string originalURL: string acceptRange: boolean - size: number + remoteFileSize: number; + downloadSize: number downloadURLUpdateDate: number + fetchStream: BaseDownloadEngineFetchStream; + range: InputRange; }; export enum ChunkStatus { @@ -16,8 +23,7 @@ export type SaveProgressInfo = { downloadId: string, part: number, chunks: ChunkStatus[], - chunkSize: number, - parallelStreams: number + chunkSize: number; }; export type DownloadFile = { diff --git a/src/download/transfer-visualize/format-transfer-status.ts b/src/download/transfer-visualize/format-transfer-status.ts index 126360d..5c41c90 100644 --- a/src/download/transfer-visualize/format-transfer-status.ts +++ b/src/download/transfer-visualize/format-transfer-status.ts @@ -1,9 +1,7 @@ -import {TransferProgressInfo} from "./transfer-statistics.js"; -import prettyBytes, {Options as PrettyBytesOptions} from "pretty-bytes"; -import prettyMilliseconds, {Options as PrettyMsOptions} from "pretty-ms"; import {DownloadStatus, ProgressStatus} from "../download-engine/download-file/progress-status-file.js"; - -const DEFAULT_LOCALIZATION: Intl.LocalesArgument = "en-US"; +import {TransferProgressInfo} from "./transfer-statistics.js"; +import prettyBytes, {PrettyBytesOptions, formatTrunc} from "./utils/prettyBytesFast.js"; +import prettyMillisecondsCompact from "./utils/prettyMSFast.js"; export type CliInfoStatus = TransferProgressInfo & { fileName?: string, @@ -26,14 +24,9 @@ const NUMBER_FORMAT_OPTIONS: Intl.NumberFormatOptions = { minimumIntegerDigits: 3 }; -export const PRETTY_MS_OPTIONS: PrettyMsOptions = { - ...NUMBER_FORMAT_OPTIONS, - keepDecimalsOnWholeSeconds: true, - secondsDecimalDigits: 2, - compact: true -}; +const PERCENTAGE_FRACTION_DIGITS = 4; -const PRETTY_BYTES_OPTIONS: PrettyBytesOptions = {...NUMBER_FORMAT_OPTIONS, space: false, locale: DEFAULT_LOCALIZATION}; +const PRETTY_BYTES_OPTIONS: PrettyBytesOptions = {...NUMBER_FORMAT_OPTIONS, space: false}; const DEFAULT_CLI_INFO_STATUS: CliInfoStatus = { speed: 0, @@ -58,12 +51,8 @@ export function createFormattedStatus(status: ProgressStatus | FormattedStatus): const formatTransferred = prettyBytes(fullStatus.transferredBytes, PRETTY_BYTES_OPTIONS); const formatTotal = fullStatus.totalBytes === 0 ? "???" : prettyBytes(fullStatus.totalBytes, PRETTY_BYTES_OPTIONS); const formatTransferredOfTotal = `${formatTransferred}/${formatTotal}`; - const formatTimeLeft = fullStatus.totalBytes === 0 ? "unknown time" : prettyMilliseconds(fullStatus.timeLeft, PRETTY_MS_OPTIONS); - const formattedPercentage = fullStatus.percentage.toLocaleString(DEFAULT_LOCALIZATION, { - minimumIntegerDigits: 1, - minimumFractionDigits: 4 - }) - .slice(0, 5) + "%"; + const formatTimeLeft = fullStatus.totalBytes === 0 ? "unknown time" : prettyMillisecondsCompact(fullStatus.timeLeft); + const formattedPercentage = formatTrunc(fullStatus.percentage, PERCENTAGE_FRACTION_DIGITS, PERCENTAGE_FRACTION_DIGITS).slice(0, 5) + "%"; let fullComment = fullStatus.comment; if (status.downloadStatus === DownloadStatus.Cancelled || status.downloadStatus === DownloadStatus.Paused) { diff --git a/src/download/transfer-visualize/progress-statistics-builder.ts b/src/download/transfer-visualize/progress-statistics-builder.ts index 978fb2b..ad1c720 100644 --- a/src/download/transfer-visualize/progress-statistics-builder.ts +++ b/src/download/transfer-visualize/progress-statistics-builder.ts @@ -3,7 +3,7 @@ import {EventEmitter} from "eventemitter3"; import TransferStatistics from "./transfer-statistics.js"; import {createFormattedStatus, FormattedStatus} from "./format-transfer-status.js"; import DownloadEngineFile from "../download-engine/download-file/download-engine-file.js"; -import ProgressStatusFile, {DownloadStatus, ProgressStatus} from "../download-engine/download-file/progress-status-file.js"; +import {DownloadStatus, EMPTY_PROGRESS_STATUS, ProgressStatus} from "../download-engine/download-file/progress-status-file.js"; import DownloadEngineMultiDownload from "../download-engine/engine/download-engine-multi-download.js"; import {DownloadEngineRemote} from "../download-engine/engine/DownloadEngineRemote.js"; @@ -18,7 +18,7 @@ interface CliProgressBuilderEvents { export type AnyEngine = DownloadEngineFile | BaseDownloadEngine | DownloadEngineMultiDownload | DownloadEngineRemote; export default class ProgressStatisticsBuilder extends EventEmitter { private _engines = new Set(); - private _activeTransfers: { [index: number]: number } = {}; + private _activeTransfers: { [index: number]: number; } = {}; private _totalBytes = 0; private _transferredBytes = 0; private _latestEngine: AnyEngine | null = null; @@ -37,6 +37,8 @@ export default class ProgressStatisticsBuilder extends EventEmitter = {}; + private _commonTransferAction = ""; constructor() { super(); @@ -55,6 +57,7 @@ export default class ProgressStatisticsBuilder extends EventEmitter { + if (addFileName){ + this._allFileNames += this._allFileNames ? ", " + latestStatus.fileName : latestStatus.fileName; + } + }; + + if (engine instanceof DownloadEngineMultiDownload) { + addFileNameFunc(); + + for (const subEngine of engine._flatEngines) { + this.add(subEngine, sendProgress, false); + } + return; + } this._engines.add(engine); this._latestEngine = engine; @@ -85,12 +106,16 @@ export default class ProgressStatisticsBuilder extends EventEmitter { + this._commonTransferActionMap[latestStatus.transferAction]--; + this._calcCommonTransferAction(); + delete this._activeTransfers[index]; this._transferredBytes += engine.downloadSize; }); @@ -118,6 +146,10 @@ export default class ProgressStatisticsBuilder extends EventEmitter (a[1] >= b[1] ? a : b))[0]; + } + /** * @internal */ @@ -128,7 +160,6 @@ export default class ProgressStatisticsBuilder extends EventEmitter string) + cliStyle?: AvailableCLIProgressStyle | ((status: CliFormattedStatus) => string); cliName?: string; - loadingAnimation?: cliSpinners.SpinnerName; + loadingAnimation?: SpinnerName; }; class GlobalCLI { @@ -28,6 +29,8 @@ class GlobalCLI { private _transferCLI = GlobalCLI._createOptions({}); private _cliActive = false; private _downloadOptions = new WeakMap(); + private _cachedCliEngines: AllowedDownloadEngine[] = []; + private _isCliEnginesCacheDirty = true; constructor() { this._registerCLIEvents(); @@ -53,7 +56,8 @@ class GlobalCLI { unpackInnerMultiDownloadsStatues: true, finalizeDownloadAfterAllSettled: false, naturalDownloadStart: true, - parallelDownloads: Number.MAX_VALUE + parallelDownloads: Number.MAX_VALUE, + downloadName: "Global CLI" }); } @@ -97,11 +101,6 @@ class GlobalCLI { } }; - this._multiDownloadEngine.on("finished", () => { - this._multiDownloadEngine = this._createMultiDownloadEngine(); - this._eventsRegistered = new Set(); - }); - const eventsRegistered = this._eventsRegistered; this._multiDownloadEngine.on("childDownloadStarted", function registerEngineStatus(engine) { if (eventsRegistered.has(engine)) return; @@ -118,30 +117,75 @@ class GlobalCLI { } }); - const getCLIEngines = (multiEngine: DownloadEngineMultiDownload) => { - const enginesToShow: AllowedDownloadEngine[] = []; - for (const engine of multiEngine.activeDownloads) { - const isShowEngine = this._downloadOptions.get(engine)?.cliProgress; - if (engine instanceof DownloadEngineMultiDownload) { - if (isShowEngine) { - enginesToShow.push(...engine._flatEngines); - continue; - } - enginesToShow.push(...getCLIEngines(engine)); - } else if (isShowEngine) { - enginesToShow.push(engine); + + const invalidateCache = () => this._isCliEnginesCacheDirty = true; + this._multiDownloadEngine.on("downloadAdded", function onDownloadAdded(engine) { + if (engine instanceof DownloadEngineMultiDownload) { + for (const flatEngine of engine._flatEngines) { + onDownloadAdded(flatEngine); } + + engine.on("downloadAdded", onDownloadAdded); } - return enginesToShow.filter((engine, index, self) => self.indexOf(engine) === index); - }; + invalidateCache(); + }); + + const printProgress = (progress: FormattedStatus, debounce = true) => + this._transferCLI.updateStatues(() => [ + this._getCLIStatuses(), + progress, + this._multiDownloadEngine.loadingDownloads + ], debounce); this._multiDownloadEngine.on("progress", (progress) => { if (!this._cliActive) return; - const statues = getCLIEngines(this._multiDownloadEngine) - .map(x => x.status); - this._transferCLI.updateStatues(statues, progress, this._multiDownloadEngine.loadingDownloads); + printProgress(progress); }); + + this._multiDownloadEngine.on("finished", () => { + printProgress(this._multiDownloadEngine.status, false); + this._multiDownloadEngine = this._createMultiDownloadEngine(); + this._eventsRegistered = new Set(); + this._cachedCliEngines = []; + this._isCliEnginesCacheDirty = true; + this._registerCLIEvents(); + }); + } + + private _collectCLIEngines(multiEngine: DownloadEngineMultiDownload, engines: Set) { + for (const engine of multiEngine.downloads) { + const isShowEngine = this._downloadOptions.get(engine)?.cliProgress; + if (engine instanceof DownloadEngineMultiDownload) { + if (isShowEngine) { + for (const flatEngine of engine._flatEngines) { + engines.add(flatEngine); + } + continue; + } + this._collectCLIEngines(engine, engines); + } else if (isShowEngine) { + engines.add(engine); + } + } + } + + private _getCLIEngines() { + if (!this._isCliEnginesCacheDirty) { + return this._cachedCliEngines; + } + + const engines = new Set(); + this._collectCLIEngines(this._multiDownloadEngine, engines); + this._cachedCliEngines = Array.from(engines); + this._isCliEnginesCacheDirty = false; + + return this._cachedCliEngines; + } + + private _getCLIStatuses() { + return this._getCLIEngines() + .map(engine => engine.status); } private static _createOptions(options: CliProgressDownloadEngineOptions) { diff --git a/src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts b/src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts index d4c5086..dba5754 100644 --- a/src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts +++ b/src/download/transfer-visualize/transfer-cli/multiProgressBars/BaseMultiProgressBar.ts @@ -2,13 +2,13 @@ import {TransferCliProgressBar} from "../progress-bars/base-transfer-cli-progres import {FormattedStatus} from "../../format-transfer-status.js"; import {DownloadStatus} from "../../../download-engine/download-file/progress-status-file.js"; import chalk from "chalk"; -import prettyBytes from "pretty-bytes"; -import cliSpinners from "cli-spinners"; +import {SpinnerName} from "cli-spinners"; +import prettyBytes from "../../utils/prettyBytesFast.js"; export type MultiProgressBarOptions = { maxViewDownloads: number; createProgressBar: TransferCliProgressBar - loadingAnimation: cliSpinners.SpinnerName, + loadingAnimation: SpinnerName, }; export type CLIProgressPrintType = "update" | "log"; diff --git a/src/download/transfer-visualize/transfer-cli/progress-bars/base-transfer-cli-progress-bar.ts b/src/download/transfer-visualize/transfer-cli/progress-bars/base-transfer-cli-progress-bar.ts index 17b8284..945d245 100644 --- a/src/download/transfer-visualize/transfer-cli/progress-bars/base-transfer-cli-progress-bar.ts +++ b/src/download/transfer-visualize/transfer-cli/progress-bars/base-transfer-cli-progress-bar.ts @@ -6,7 +6,7 @@ import {DownloadStatus} from "../../../download-engine/download-file/progress-st import {BaseMultiProgressBar} from "../multiProgressBars/BaseMultiProgressBar.js"; import {STATUS_ICONS} from "../../utils/progressBarIcons.js"; import {DataLine, DataPart, renderDataLine} from "../../utils/data-line.js"; -import cliSpinners, {Spinner} from "cli-spinners"; +import cliSpinners, {Spinner, SpinnerName} from "cli-spinners"; const SKIP_ETA_START_TIME = 1000 * 2; const MIN_NAME_LENGTH = 20; @@ -19,7 +19,7 @@ export type CliFormattedStatus = FormattedStatus & { export type BaseCliOptions = { truncateName?: boolean | number - loadingSpinner?: cliSpinners.SpinnerName + loadingSpinner?: SpinnerName }; export interface TransferCliProgressBar { diff --git a/src/download/transfer-visualize/transfer-cli/progress-bars/fancy-transfer-cli-progress-bar.ts b/src/download/transfer-visualize/transfer-cli/progress-bars/fancy-transfer-cli-progress-bar.ts index e54648e..d26921d 100644 --- a/src/download/transfer-visualize/transfer-cli/progress-bars/fancy-transfer-cli-progress-bar.ts +++ b/src/download/transfer-visualize/transfer-cli/progress-bars/fancy-transfer-cli-progress-bar.ts @@ -1,12 +1,11 @@ import chalk from "chalk"; -import {PRETTY_MS_OPTIONS} from "../../format-transfer-status.js"; -import {DataLine, renderDataLine} from "../../utils/data-line.js"; -import prettyMilliseconds from "pretty-ms"; import sliceAnsi from "slice-ansi"; import stripAnsi from "strip-ansi"; import {DownloadStatus} from "../../../download-engine/download-file/progress-status-file.js"; -import BaseTransferCliProgressBar from "./base-transfer-cli-progress-bar.js"; +import {DataLine, renderDataLine} from "../../utils/data-line.js"; +import prettyMillisecondsCompact from "../../utils/prettyMSFast.js"; import {STATUS_ICONS} from "../../utils/progressBarIcons.js"; +import BaseTransferCliProgressBar from "./base-transfer-cli-progress-bar.js"; /** * A class to display transfer progress in the terminal, with a progress bar and other information. @@ -79,8 +78,8 @@ export default class FancyTransferCliProgressBar extends BaseTransferCliProgress const downloadTime = (endTime || Date.now()) - startTime; const finishedText = wasSuccessful - ? `downloaded ${this.status.formatTransferred} in ${prettyMilliseconds(downloadTime, PRETTY_MS_OPTIONS)}` - : `failed downloading after ${prettyMilliseconds(endTime - startTime, PRETTY_MS_OPTIONS)}`; + ? `downloaded ${this.status.formatTransferred} in ${prettyMillisecondsCompact(downloadTime)}` + : `failed downloading after ${prettyMillisecondsCompact(endTime - startTime)}`; return renderDataLine([{ type: "status", diff --git a/src/download/transfer-visualize/transfer-cli/transfer-cli.ts b/src/download/transfer-visualize/transfer-cli/transfer-cli.ts index a4e8052..1df21bb 100644 --- a/src/download/transfer-visualize/transfer-cli/transfer-cli.ts +++ b/src/download/transfer-visualize/transfer-cli/transfer-cli.ts @@ -1,27 +1,24 @@ +import {SpinnerName} from "cli-spinners"; import UpdateManager from "stdout-update"; -import debounce from "lodash.debounce"; -import {TransferCliProgressBar} from "./progress-bars/base-transfer-cli-progress-bar.js"; -import cliSpinners from "cli-spinners"; import {FormattedStatus} from "../format-transfer-status.js"; -import switchCliProgressStyle from "./progress-bars/switch-cli-progress-style.js"; import {BaseMultiProgressBar} from "./multiProgressBars/BaseMultiProgressBar.js"; +import {TransferCliProgressBar} from "./progress-bars/base-transfer-cli-progress-bar.js"; +import switchCliProgressStyle from "./progress-bars/switch-cli-progress-style.js"; export type TransferCliOptions = { name?: string, maxViewDownloads: number; truncateName: boolean | number; debounceWait: number; - maxDebounceWait: number; createProgressBar: TransferCliProgressBar; createMultiProgressBar: typeof BaseMultiProgressBar, - loadingAnimation: cliSpinners.SpinnerName, + loadingAnimation: SpinnerName, }; export const DEFAULT_TRANSFER_CLI_OPTIONS: TransferCliOptions = { maxViewDownloads: 10, truncateName: true, - debounceWait: 20, - maxDebounceWait: process.platform === "win32" ? 500 : 100, + debounceWait: process.platform === "win32" ? 500 : 45, createProgressBar: switchCliProgressStyle("auto", {truncateName: true}), loadingAnimation: "dots", createMultiProgressBar: BaseMultiProgressBar @@ -31,21 +28,20 @@ export default class TransferCli { protected options: TransferCliOptions; protected stdoutManager = UpdateManager.getInstance(); protected latestProgress: [FormattedStatus[], FormattedStatus, number] = null!; + protected latestProgressGetter: (() => [FormattedStatus[], FormattedStatus, number]) | null = null; private _cliStopped = true; - private readonly _updateStatuesDebounce: () => void; private _multiProgressBar: BaseMultiProgressBar; - private _isFirstPrint = true; private _lastProgressLong = ""; + private _lastUpdateTime = 0; + private _shouldExitOnSIGINT = false; + private _debounceWait: number; public constructor(options: Partial) { this.options = {...DEFAULT_TRANSFER_CLI_OPTIONS, ...options}; this._multiProgressBar = new this.options.createProgressBar.multiProgressBar(this.options); + this._debounceWait = this._multiProgressBar.updateIntervalMs || this.options.debounceWait; - const maxDebounceWait = this._multiProgressBar.updateIntervalMs || this.options.maxDebounceWait; - this._updateStatuesDebounce = debounce(this._updateStatues.bind(this), maxDebounceWait, { - maxWait: maxDebounceWait - }); - + this.updateStatues = this.updateStatues.bind(this); this._processExit = this._processExit.bind(this); } @@ -55,13 +51,14 @@ export default class TransferCli { if (this._multiProgressBar.printType === "update") { this.stdoutManager.hook(); } + + this._shouldExitOnSIGINT = process.listenerCount("SIGINT") === 0; process.on("SIGINT", this._processExit); } stop() { if (this._cliStopped) return; this._cliStopped = true; - this._updateStatues(); if (this._multiProgressBar.printType === "update") { this.stdoutManager.unhook(false); } @@ -70,23 +67,27 @@ export default class TransferCli { private _processExit() { this.stop(); - process.exit(0); + + if (this._shouldExitOnSIGINT) { + process.exit(0); + } } - updateStatues(statues: FormattedStatus[], oneStatus: FormattedStatus, loadingDownloads = 0) { - this.latestProgress = [statues, oneStatus, loadingDownloads]; + updateStatues(getLatestProgress: () => [FormattedStatus[], FormattedStatus, number], debounce = true) { + this.latestProgressGetter = getLatestProgress; - if (this._isFirstPrint) { - this._isFirstPrint = false; - this._updateStatues(); - } else { - this._updateStatuesDebounce(); + if (debounce && Date.now() - this._lastUpdateTime < this._debounceWait) { + return; } + + this._lastUpdateTime = Date.now(); + this._updateStatues(); } private _updateStatues() { - if (!this.latestProgress) return; - const printLog = this._multiProgressBar.createMultiProgressBar(...this.latestProgress); + const latestProgress = this.latestProgressGetter?.() ?? this.latestProgress; + if (!latestProgress) return; + const printLog = this._multiProgressBar.createMultiProgressBar(...latestProgress); if (printLog && this._lastProgressLong != printLog) { this._lastProgressLong = printLog; this._logUpdate(printLog); diff --git a/src/download/transfer-visualize/transfer-statistics.ts b/src/download/transfer-visualize/transfer-statistics.ts index bbe517c..75980c6 100644 --- a/src/download/transfer-visualize/transfer-statistics.ts +++ b/src/download/transfer-visualize/transfer-statistics.ts @@ -56,7 +56,7 @@ export default class TransferStatistics { const speed = clamp(this._calculateSpeed(transferred)); const timeLeft = (total - transferred) / speed; const timeLeftFinalNumber = clamp((timeLeft || 0) * 1000, 0, MAX_TIME_LEFT); - const percentage = clamp(((transferred / total) * 100), 0, 100); + const percentage = total === 0 ? 0 : clamp(((transferred / total) * 100), 0, 100); return this._latestProgress = { transferredBytes: clamp(transferred), diff --git a/src/download/transfer-visualize/utils/prettyBytesFast.ts b/src/download/transfer-visualize/utils/prettyBytesFast.ts new file mode 100644 index 0000000..67046ed --- /dev/null +++ b/src/download/transfer-visualize/utils/prettyBytesFast.ts @@ -0,0 +1,259 @@ +export interface PrettyBytesOptions { + bits?: boolean; + binary?: boolean; + space?: boolean; + nonBreakingSpace?: boolean; + signed?: boolean; + locale?: string | string[] | boolean; + minimumFractionDigits?: number; + maximumFractionDigits?: number; + fixedWidth?: number; +} + +const BYTE_UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; +const BIBYTE_UNITS = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]; +const BIT_UNITS = ["b", "kbit", "Mbit", "Gbit", "Tbit", "Pbit", "Ebit", "Zbit", "Ybit"]; +const BIBIT_UNITS = ["b", "kibit", "Mibit", "Gibit", "Tibit", "Pibit", "Eibit", "Zibit", "Yibit"]; + +const DECIMAL_DIVISORS = [1, 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24]; +const BINARY_DIVISORS = Array.from({length: 9}, (_, i) => 1024 ** i); +const DECIMAL_DIVISORS_BIGINT = [1n, 1000n, 1000000n, 1000000000n, 1000000000000n, 1000000000000000n, 1000000000000000000n, 1000000000000000000000n, 1000000000000000000000000n]; +const BINARY_DIVISORS_BIGINT = [1n, 1024n, 1048576n, 1073741824n, 1099511627776n, 1125899906842624n, 1152921504606846976n, 1180591620717411303424n, 1208925819614629174706176n]; + +const LOG10_1024 = Math.log10(1024); + +const SIG3_GE100 = new Array(901); +const SIG3_GE10 = new Array(901); +const SIG3_GE1 = new Array(901); + +for (let i = 0; i <= 900; i++) { + const v = i + 100; + + SIG3_GE100[i] = String(v); + + const hi10 = (v / 10) | 0; + const lo10 = v - hi10 * 10; + SIG3_GE10[i] = lo10 === 0 ? String(hi10) : hi10 + "." + lo10; + + const hi1 = (v / 100) | 0; + const rem1 = v - hi1 * 100; + const d1 = (rem1 / 10) | 0; + const d2 = rem1 - d1 * 10; + SIG3_GE1[i] = d2 === 0 + ? (d1 === 0 ? String(hi1) : hi1 + "." + d1) + : hi1 + "." + d1 + "" + d2; +} + +function sig3(n: number): string { + if (n >= 100) { + const i = (n + 0.5) | 0; + return SIG3_GE100[(i <= 999 ? i : 1000) - 100]; + } + if (n >= 10) { + const i = (n * 10 + 0.5) | 0; + return SIG3_GE10[(i <= 999 ? i : 1000) - 100]; + } + const i = (n * 100 + 0.5) | 0; + return SIG3_GE1[(i <= 999 ? i : 1000) - 100]; +} + +function sig3Binary(n: number): string { + if (n >= 1000) return String((n + 0.5) | 0); + return sig3(n); +} + +// Fast trunc-mode fraction formatter — avoids toLocaleString when no locale is set +const TRUNC_POWERS = [1, 10, 100, 1000, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10]; + +function getTruncScale(maxFrac: number): number { + return maxFrac < TRUNC_POWERS.length ? TRUNC_POWERS[maxFrac] : 10 ** maxFrac; +} + +export function formatTrunc(n: number, minFrac: number, maxFrac: number): string { + const intPart = Math.trunc(n); + const frac = n - intPart; + + if (maxFrac === 0 || (frac === 0 && minFrac === 0)) return String(intPart); + + const scale = getTruncScale(maxFrac); + let fracInt = Math.trunc(frac * scale); + + let digits = maxFrac; + while (digits > minFrac && fracInt % 10 === 0) { + fracInt = Math.trunc(fracInt / 10); + digits--; + } + + if (digits === 0) return String(intPart); + + let fracStr = String(fracInt); + while (fracStr.length < digits) fracStr = "0" + fracStr; + return intPart + "." + fracStr; +} + +function toLocaleStr( + num: number, + locale: string | string[] | boolean, + opts: Intl.NumberFormatOptions | undefined +): string { + if (typeof locale === "string" || Array.isArray(locale)) { + return num.toLocaleString(locale as string | string[], opts); + } + return num.toLocaleString(undefined, opts); +} + +function applyFixedWidth(result: string, fixedWidth: number): string { + if (typeof fixedWidth !== "number" || !Number.isSafeInteger(fixedWidth) || fixedWidth < 0) { + throw new TypeError(`Expected fixedWidth to be a non-negative integer, got ${typeof fixedWidth}: ${fixedWidth}`); + } + return fixedWidth > 0 && result.length < fixedWidth ? result.padStart(fixedWidth, " ") : result; +} + +function decimalExp(n: number): number { + if (n < 1e6) return n < 1e3 ? 0 : 1; + if (n < 1e12) return n < 1e9 ? 2 : 3; + if (n < 1e18) return n < 1e15 ? 4 : 5; + return n < 1e21 ? 6 : n < 1e24 ? 7 : 8; +} + +function binaryExp(n: number): number { + if (n < 1048576) return n < 1024 ? 0 : 1; + if (n < 1099511627776) return n < 1073741824 ? 2 : 3; + if (n < 1125899906842624) return 4; + if (n < BINARY_DIVISORS[6]) return 5; + if (n < BINARY_DIVISORS[7]) return 6; + if (n < BINARY_DIVISORS[8]) return 7; + return 8; +} + +function bigintLog10(n: bigint): number { + const s = n.toString(10); + return s.length + Math.log10(Number("0." + s.slice(0, 15))); +} + +function bigintDivide(n: bigint, divisor: bigint): number { + return Number(n / divisor) + (Number(n % divisor) / Number(divisor)); +} + +export default function prettyBytes(number: number | bigint, options?: PrettyBytesOptions): string { + if (options === undefined && typeof number === "number") { + if (!Number.isFinite(number)) { + throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`); + } + const neg = number < 0; + if (neg) number = -number; + + let s: string; + if (number < 1) { + s = number + " B"; + } else if (number < 1e3) { + s = sig3(number) + " B"; + } else if (number < 1e6) { + s = sig3(number / 1e3) + " kB"; + } else if (number < 1e9) { + s = sig3(number / 1e6) + " MB"; + } else if (number < 1e12) { + s = sig3(number / 1e9) + " GB"; + } else if (number < 1e15) { + s = sig3(number / 1e12) + " TB"; + } else if (number < 1e18) { + s = sig3(number / 1e15) + " PB"; + } else if (number < 1e21) { + s = sig3(number / 1e18) + " EB"; + } else if (number < 1e24) { + s = sig3(number / 1e21) + " ZB"; + } else { + s = sig3(number / 1e24) + " YB"; + } + return neg ? "-" + s : s; + } + + return prettyBytesFull(number, options); +} + +function prettyBytesFull(number: number | bigint, options: PrettyBytesOptions | undefined): string { + if (typeof number !== "bigint" && !Number.isFinite(number)) { + throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`); + } + + const bits = options?.bits ?? false; + const binary = options?.binary ?? false; + const space = options?.space ?? true; + const signed = options?.signed ?? false; + const locale = options?.locale; + const fixedWidth = options?.fixedWidth; + const minimumFractionDigits = options?.minimumFractionDigits; + const maximumFractionDigits = options?.maximumFractionDigits; + + const units = bits + ? (binary ? BIBIT_UNITS : BIT_UNITS) + : (binary ? BIBYTE_UNITS : BYTE_UNITS); + const separator = space ? (options?.nonBreakingSpace ? "\u00A0" : " ") : ""; + + const isZero = typeof number === "number" ? number === 0 : number === 0n; + if (signed && isZero) { + const result = ` 0${separator}${units[0]}`; + return fixedWidth !== undefined ? applyFixedWidth(result, fixedWidth) : result; + } + + const isNegative = number < 0; + const prefix = isNegative ? "-" : (signed ? "+" : ""); + if (isNegative) { + number = typeof number === "bigint" ? -number : -(number as number); + } + + const hasFracOpts = minimumFractionDigits !== undefined || maximumFractionDigits !== undefined; + const useLocale = locale !== undefined; + + let result: string; + + const ltOne = typeof number === "bigint" ? number < 1n : (number as number) < 1; + if (ltOne) { + const n = Number(number); + let ns: string; + if (useLocale) { + const localeOpts = hasFracOpts ? { + ...(minimumFractionDigits !== undefined && {minimumFractionDigits}), + ...(maximumFractionDigits !== undefined && {maximumFractionDigits}), + roundingMode: "trunc" + } as Intl.NumberFormatOptions : undefined; + ns = toLocaleStr(n, locale, localeOpts); + } else if (hasFracOpts) { + ns = formatTrunc(n, minimumFractionDigits ?? 0, maximumFractionDigits ?? 20); + } else { + ns = String(n); + } + result = prefix + ns + separator + units[0]; + } else { + let exp: number; + let divided: number; + + if (typeof number === "bigint") { + const l = bigintLog10(number); + exp = Math.min(Math.floor(binary ? l / LOG10_1024 : l / 3), units.length - 1); + divided = bigintDivide(number, binary ? BINARY_DIVISORS_BIGINT[exp] : DECIMAL_DIVISORS_BIGINT[exp]); + } else { + exp = binary ? binaryExp(number as number) : decimalExp(number as number); + divided = (number as number) / (binary ? BINARY_DIVISORS[exp] : DECIMAL_DIVISORS[exp]); + } + + let ns: string; + if (useLocale) { + const localeOpts = hasFracOpts ? { + ...(minimumFractionDigits !== undefined && {minimumFractionDigits}), + ...(maximumFractionDigits !== undefined && {maximumFractionDigits}), + roundingMode: "trunc" + } as Intl.NumberFormatOptions : undefined; + const val = hasFracOpts ? divided : Number(binary ? sig3Binary(divided) : sig3(divided)); + ns = toLocaleStr(val, locale, localeOpts); + } else if (hasFracOpts) { + ns = formatTrunc(divided, minimumFractionDigits ?? 0, maximumFractionDigits ?? 20); + } else { + ns = binary ? sig3Binary(divided) : sig3(divided); + } + + result = prefix + ns + separator + units[exp]; + } + + return fixedWidth !== undefined ? applyFixedWidth(result, fixedWidth) : result; +} diff --git a/src/download/transfer-visualize/utils/prettyMSFast.ts b/src/download/transfer-visualize/utils/prettyMSFast.ts new file mode 100644 index 0000000..221e498 --- /dev/null +++ b/src/download/transfer-visualize/utils/prettyMSFast.ts @@ -0,0 +1,47 @@ +const SECOND = 1000; +const MINUTE = 60 * SECOND; +const HOUR = 60 * MINUTE; +const DAY = 24 * HOUR; +const YEAR = 365 * DAY; + +const SECOND_BIGINT = 1000n; +const MINUTE_BIGINT = 60n * SECOND_BIGINT; +const HOUR_BIGINT = 60n * MINUTE_BIGINT; +const DAY_BIGINT = 24n * HOUR_BIGINT; +const YEAR_BIGINT = 365n * DAY_BIGINT; + +function prettyMillisecondsCompactNumber(milliseconds: number): string { + if (!Number.isFinite(milliseconds)) { + throw new TypeError("Expected a finite number or bigint"); + } + + const sign = milliseconds < 0 ? "-" : ""; + const value = milliseconds < 0 ? -milliseconds : milliseconds; + + if (value >= YEAR) return sign + Math.trunc(value / YEAR) + "y"; + if (value >= DAY) return sign + Math.trunc(value / DAY) + "d"; + if (value >= HOUR) return sign + Math.trunc(value / HOUR) + "h"; + if (value >= MINUTE) return sign + Math.trunc(value / MINUTE) + "m"; + if (value >= SECOND) return sign + Math.trunc(value / SECOND) + "s"; + + const roundedMilliseconds = value >= 1 ? Math.round(value) : Math.ceil(value); + return sign + roundedMilliseconds + "ms"; +} + +function prettyMillisecondsCompactBigInt(milliseconds: bigint): string { + const sign = milliseconds < 0n ? "-" : ""; + const value = milliseconds < 0n ? -milliseconds : milliseconds; + + if (value >= YEAR_BIGINT) return sign + String(value / YEAR_BIGINT) + "y"; + if (value >= DAY_BIGINT) return sign + String(value / DAY_BIGINT) + "d"; + if (value >= HOUR_BIGINT) return sign + String(value / HOUR_BIGINT) + "h"; + if (value >= MINUTE_BIGINT) return sign + String(value / MINUTE_BIGINT) + "m"; + if (value >= SECOND_BIGINT) return sign + String(value / SECOND_BIGINT) + "s"; + return sign + String(value) + "ms"; +} + +export default function prettyMillisecondsCompact(milliseconds: number | bigint): string { + return typeof milliseconds === "bigint" + ? prettyMillisecondsCompactBigInt(milliseconds) + : prettyMillisecondsCompactNumber(milliseconds); +} diff --git a/test/accept-range-false.test.ts b/test/accept-range-false.test.ts new file mode 100644 index 0000000..e52d359 --- /dev/null +++ b/test/accept-range-false.test.ts @@ -0,0 +1,73 @@ +import {afterAll, beforeAll, describe, test} from "vitest"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import {DownloadFile} from "../src/download/download-engine/types.js"; +import {startLocalTestServer, LocalTestServer} from "./utils/local-server.js"; + +let baseURL: string; +let server: LocalTestServer; + +beforeAll(async () => { + server = await startLocalTestServer(); + baseURL = server.baseURL; +}); + +afterAll(async () => { + await server.close(); +}); + +describe("Accept-Range False & Non-Standard Servers", () => { + test("should fallback to single stream if accept-range is false", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "test.png", + parts: [ + { + downloadURL: `${baseURL}/no-range-file.png`, + originalURL: `${baseURL}/no-range-file.png`, + acceptRange: false, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 3, + autoIncreaseParallelStreams: true, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + await expect(downloader.download()).resolves.not.toThrow(); + }); + + test("should handle content-length 0 but still stream data", async ({expect}) => { + // This is a synthetic test: we simulate a part with content-length 0 but expect data + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "test.bin", + parts: [ + { + downloadURL: `${baseURL}/no-range-zero.png`, + originalURL: `${baseURL}/no-range-zero.png`, + acceptRange: false, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + await expect(downloader.download()).resolves.not.toThrow(); + }); +}); diff --git a/test/browser.test.ts b/test/browser.test.ts index 251e4b5..e343227 100644 --- a/test/browser.test.ts +++ b/test/browser.test.ts @@ -9,7 +9,7 @@ import fs from "fs-extra"; globalThis.XMLHttpRequest = await import("xmlhttprequest-ssl").then(m => m.XMLHttpRequest); describe("Browser Fetch API", () => { - test.concurrent("Download file browser - memory", async (context) => { + test.concurrent("Download file browser - memory", async ({expect}) => { const downloader = await downloadFileBrowser({ url: BIG_FILE, parallelStreams: 2, @@ -18,11 +18,11 @@ describe("Browser Fetch API", () => { await downloader.download(); const hash = hashBuffer(downloader.writeStream.result); - context.expect(hash) - .toMatchInlineSnapshot("\"9ae3ff19ee04fc02e9c60ce34e42858d16b46eeb88634d2035693c1ae9dbcbc9\""); + expect(hash) + .toMatchInlineSnapshot("\"0e1a20347e130a168a5c555826915a1302e3fae467b85db6aae53c243c2b0a26\""); }); - test.concurrent("Download file browser", async (context) => { + test.concurrent("Download file browser", {repeats: 4, concurrent: true}, async ({expect}) => { const response = await ensureLocalFile(BIG_FILE, BIG_FILE_EXAMPLE); const bufferIsCorrect = Buffer.from(await fs.readFile(response)); @@ -49,27 +49,27 @@ describe("Browser Fetch API", () => { await downloader.download(); const diff = bigBuffer.findIndex((value, index) => value !== bufferIsCorrect[index]); - context.expect(diff) + expect(diff) .toBe(-1); - context.expect(lastWrite) + expect(lastWrite) .toBe(downloader.file.totalSize); - context.expect(hashBuffer(bigBuffer)) - .toMatchInlineSnapshot("\"9ae3ff19ee04fc02e9c60ce34e42858d16b46eeb88634d2035693c1ae9dbcbc9\""); - }, {repeats: 4, concurrent: true}); -}, {timeout: 1000 * 60 * 3}); + expect(hashBuffer(bigBuffer)) + .toMatchInlineSnapshot("\"0e1a20347e130a168a5c555826915a1302e3fae467b85db6aae53c243c2b0a26\""); + }); +}); describe("Browser Fetch memory", () => { - test.sequential("Download file for tests", async (context) => { + test.sequential("Download file for tests", async ({expect}) => { const response = await ensureLocalFile(BIG_FILE, BIG_FILE_EXAMPLE); const buffer = Buffer.from(await fs.readFile(response)); const hash = hashBuffer(buffer); - context.expect(hash) - .toMatchInlineSnapshot("\"9ae3ff19ee04fc02e9c60ce34e42858d16b46eeb88634d2035693c1ae9dbcbc9\""); + expect(hash) + .toMatchInlineSnapshot("\"0e1a20347e130a168a5c555826915a1302e3fae467b85db6aae53c243c2b0a26\""); }); - test.sequential("Download file browser - memory (xhr)", async (context) => { + test.skip("Download file browser - memory (xhr)", async ({expect}) => { const originalFile = await ensureLocalFile(BIG_FILE, BIG_FILE_EXAMPLE); const originalFileBuffer = new Uint8Array(await fs.readFile(originalFile)); @@ -79,15 +79,15 @@ describe("Browser Fetch memory", () => { }); await downloader.download(); - context.expect(originalFileBuffer.length) + expect(originalFileBuffer.length) .toBe(downloader.downloadSize); const diff = originalFileBuffer.findIndex((value, index) => value !== downloader.writeStream.result[index]); - context.expect(diff) + expect(diff) .toBe(-1); }); - test.sequential("Download file browser - chunks, memory (fetch)", async (context) => { + test.sequential("Download file browser - chunks, memory (fetch)", async ({expect}) => { const originalFile = await ensureLocalFile(BIG_FILE, BIG_FILE_EXAMPLE); const originalFileBuffer = new Uint8Array(await fs.readFile(originalFile)); @@ -100,11 +100,11 @@ describe("Browser Fetch memory", () => { }); await downloader.download(); - context.expect(originalFileBuffer.length) + expect(originalFileBuffer.length) .toBe(downloader.downloadSize); const diff = originalFileBuffer.findIndex((value, index) => value !== downloader.writeStream.result[index]); - context.expect(diff) + expect(diff) .toBe(-1); }); -}, {timeout: 1000 * 60 * 3}); +}); diff --git a/test/content-length-mismatch.test.ts b/test/content-length-mismatch.test.ts new file mode 100644 index 0000000..0cd75e8 --- /dev/null +++ b/test/content-length-mismatch.test.ts @@ -0,0 +1,91 @@ +import {describe, test, beforeAll, afterAll} from "vitest"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +import InvalidContentLengthError from "../src/download/download-engine/streams/download-engine-fetch-stream/errors/invalid-content-length-error.js"; +import {DownloadFile} from "../src/download/download-engine/types.js"; +import {startLocalTestServer, LocalTestServer, TEST_FILE_SIZE} from "./utils/local-server.js"; + +let server: LocalTestServer; +let baseURL: string; + +beforeAll(async () => { + server = await startLocalTestServer(); + baseURL = server.baseURL; +}); + +afterAll(async () => { + await server.close(); +}); + +describe("Content-Length Mismatch", () => { + test("should download a real 8MB+ file using the engine", async ({expect}) => { + const url = `${baseURL}/range-file.bin`; + const file = await fetch(url, {method: "HEAD"}); + expect(file.status).toBe(200); + + const fetchStream = new DownloadEngineFetchStreamFetch(); + let totalBytes = 0; + const writeStream = new DownloadEngineWriteStreamBrowser((_cursor, buffers) => { + totalBytes += buffers.reduce((sum, buffer) => sum + buffer.length, 0); + }); + + const downloadFile: DownloadFile = { + totalSize: TEST_FILE_SIZE, + localFileName: "file.bin", + parts: [ + { + downloadURL: url, + originalURL: url, + acceptRange: true, + remoteFileSize: TEST_FILE_SIZE, + downloadSize: TEST_FILE_SIZE, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: TEST_FILE_SIZE - 1} + } + ] + }; + + const downloader = new DownloadEngineFile(downloadFile, {writeStream, chunkSize: 1024 * 512}); + await downloader.download(); + + expect(totalBytes).toBe(TEST_FILE_SIZE); + }); + + test("should throw InvalidContentLengthError if server responds with wrong Content-Length", async ({expect}) => { + const url = `${baseURL}/bad-length.bin`; + const fetchStream = new DownloadEngineFetchStreamFetch(); + let totalBytes = 0; + const writeStream = new DownloadEngineWriteStreamBrowser((_cursor, buffers) => { + totalBytes += buffers.reduce((sum, buffer) => sum + buffer.length, 0); + }); + + const downloadFile: DownloadFile = { + totalSize: TEST_FILE_SIZE, + localFileName: "bad-length.bin", + parts: [ + { + downloadURL: url, + originalURL: url, + acceptRange: true, + remoteFileSize: TEST_FILE_SIZE, + downloadSize: TEST_FILE_SIZE, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: TEST_FILE_SIZE - 1} + } + ] + }; + + const downloader = new DownloadEngineFile(downloadFile, {writeStream, chunkSize: 1024 * 512}); + await expect(downloader.download()).rejects.toThrow(InvalidContentLengthError); + expect(totalBytes).toBe(0); + }); +}); diff --git a/test/copy-file.test.ts b/test/copy-file.test.ts index b867404..226c772 100644 --- a/test/copy-file.test.ts +++ b/test/copy-file.test.ts @@ -8,7 +8,7 @@ import {BIG_FILE} from "./utils/files.js"; describe("File Copy", async () => { - test.concurrent("copy text parallel streams", async (context) => { + test.concurrent("copy text parallel streams", async ({expect}) => { const {originalFileHash, fileToCopy, copyFileToName} = await copyFileInfo(TEXT_FILE_EXAMPLE); const engine = await downloadFile({ @@ -25,11 +25,11 @@ describe("File Copy", async () => { const copiedFileHash = await fileHash(copyFileToName); await fs.remove(copyFileToName); - context.expect(copiedFileHash) + expect(copiedFileHash) .toBe(originalFileHash); }); - test.concurrent("copy image one stream", async (context) => { + test.concurrent("copy image one stream", async ({expect}) => { const imagePath = await ensureLocalFile(BIG_FILE, BIG_FILE_EXAMPLE); const {originalFileHash, fileToCopy, copyFileToName} = await copyFileInfo(imagePath); @@ -46,7 +46,7 @@ describe("File Copy", async () => { const copiedFileHash = await fileHash(copyFileToName); await fs.remove(copyFileToName); - context.expect(copiedFileHash) + expect(copiedFileHash) .toBe(originalFileHash); }); -}, {timeout: 1000 * 60 * 3}); +}); diff --git a/test/daynamic-content-length.test.ts b/test/daynamic-content-length.test.ts index e821d38..2fb2aac 100644 --- a/test/daynamic-content-length.test.ts +++ b/test/daynamic-content-length.test.ts @@ -24,7 +24,7 @@ describe("Dynamic content download", async () => { }); - test.concurrent("Nodejs Download", async (context) => { + test.concurrent("Nodejs Download", async ({expect}) => { const downloader = await downloadFile({ url: DYNAMIC_DOWNLOAD_FILE, directory: ".", @@ -39,11 +39,11 @@ describe("Dynamic content download", async () => { const ipullFileHash = await fileHash(downloader.fileAbsolutePath); await fs.remove(downloader.fileAbsolutePath); - context.expect(ipullFileHash) + expect(ipullFileHash) .toBe(originalFileHash); }); - test.concurrent("Browser Download", async (context) => { + test.concurrent("Browser Download", async ({expect}) => { const downloader = await downloadFileBrowser({ url: DYNAMIC_DOWNLOAD_FILE, defaultFetchDownloadInfo: { @@ -55,7 +55,7 @@ describe("Dynamic content download", async () => { await downloader.download(); const ipullFileHash = hashBuffer(downloader.writeStream.result); - context.expect(ipullFileHash) + expect(ipullFileHash) .toBe(originalFileHash); }); }); diff --git a/test/download.test.ts b/test/download.test.ts index 53099c3..fa55877 100644 --- a/test/download.test.ts +++ b/test/download.test.ts @@ -1,30 +1,23 @@ import {describe, test} from "vitest"; -import {ChunkStatus} from "../src/download/download-engine/types.js"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; -import {BIG_FILE} from "./utils/files.js"; +import {ChunkStatus} from "../src/download/download-engine/types.js"; import {createDownloadFile} from "./utils/download.js"; -import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; -import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import {BIG_FILE} from "./utils/files.js"; describe("File Download", () => { - test.concurrent("Parallel connection download", async (context) => { + test("Parallel connection download", async ({expect}) => { const MIN_PARALLEL_CONNECTIONS = 4; const randomNumber = Math.max(MIN_PARALLEL_CONNECTIONS, Math.floor(Math.random() * 30)); - const fetchStream = new DownloadEngineFetchStreamFetch({ - acceptRangeIsKnown: true - }); const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); - const file = await createDownloadFile(BIG_FILE); + const file = await createDownloadFile(BIG_FILE, {parallelStreams: randomNumber, autoIncreaseParallelStreams: false}); let saveProgressCalledLength = 0; let maxInParallelConnections = 0; const downloader = new DownloadEngineFile(file, { - parallelStreams: randomNumber, - chunkSize: 1024 ** 2, - autoIncreaseParallelStreams: false, - fetchStream, + chunkSize: 1024 ** 1.5, writeStream }); @@ -36,16 +29,15 @@ describe("File Download", () => { }); await downloader.download(); - context.expect(saveProgressCalledLength) + expect(saveProgressCalledLength) .toBeGreaterThan(randomNumber); - context.expect(maxInParallelConnections) + expect(maxInParallelConnections) .toBe(randomNumber - 1); }); - test.concurrent("Total bytes written", async (context) => { + test("Total bytes written", async ({expect}) => { let totalBytesWritten = 0; - const fetchStream = new DownloadEngineFetchStreamFetch(); const writeStream = new DownloadEngineWriteStreamBrowser((cursor, data) => { totalBytesWritten += data.reduce((sum, buffer) => sum + buffer.length, 0); }); @@ -53,12 +45,11 @@ describe("File Download", () => { const file = await createDownloadFile(BIG_FILE); const downloader = new DownloadEngineFile(file, { chunkSize: 1024 * 1024 * 25, - fetchStream, writeStream }); await downloader.download(); - context.expect(totalBytesWritten) + expect(totalBytesWritten) .toBe(file.totalSize); }); -}, {timeout: 1000 * 60 * 3}); +}); diff --git a/test/fetchDownloadInfo.test.ts b/test/fetchDownloadInfo.test.ts index ba8a5b2..e895595 100644 --- a/test/fetchDownloadInfo.test.ts +++ b/test/fetchDownloadInfo.test.ts @@ -1,82 +1,33 @@ -import {beforeAll, describe, test} from "vitest"; -import express from "express"; +import {afterAll, beforeAll, describe, test} from "vitest"; import {downloadFile} from "../src/index.js"; -import {packageJson} from "../src/const.js"; import fsPromise from "fs/promises"; -import {Throttle} from "stream-throttle"; -import {Readable} from "node:stream"; +import {startLocalTestServer, LocalTestServer, TEST_FILE_SIZE} from "./utils/local-server.js"; -const TEMP_MODEL_TO_DOWNLOAD = "https://huggingface.co/mradermacher/arwkv-qwen-r1-1b5-i1-GGUF/resolve/main/arwkv-qwen-r1-1b5.i1-IQ1_M.gguf?download=true"; -const MAX_SPEED_BYTES = 5 * 1024 * 1024; // 5 MB/s +let baseURL: string; +let server: LocalTestServer; -describe("Fetch download info", () => { - beforeAll(async () => { - const server = express(); - server.get("/file.json", (req, res) => { - res.json(packageJson); - }); - - server.get("/fileCreateToken.gguf", (req, res) => { - res.redirect(`/file.gguf?token=${Date.now() + 1000 * 3}`); - }); - - server.get("/file.gguf", async (req, res) => { - const token = req.query.token as string; - if (!token || Date.now() > parseInt(token)) { - res.status(403) - .send("Token expired"); - return; - } - - // proxy to huggingface model with throttling - const throttledStream = new Throttle({ - rate: MAX_SPEED_BYTES // 5 MB/s - }); +beforeAll(async () => { + server = await startLocalTestServer(); + baseURL = server.baseURL; +}); - const response = await fetch(TEMP_MODEL_TO_DOWNLOAD, { - headers: { - range: req.header("range")! - } - }); +afterAll(async () => { + await server.close(); +}); - if (!response.ok) { - res.status(response.status) - .send("Error fetching file"); - return; - } - res.setHeader("Content-Type", "application/octet-stream"); - res.setHeader("Content-Disposition", `attachment; filename="file.gguf"`); - res.setHeader("Accept-Ranges", "bytes"); - res.setHeader("Content-Length", response.headers.get("Content-Length") || "0"); - Readable.fromWeb(response.body as any) - .pipe(throttledStream) - .pipe(res) - .on("error", (err) => { - console.error("Error piping response:", err); - res.status(500) - .send("Internal Server Error"); - }); - }); - - await new Promise(resolve => { - console.log("File Server Listening on 3000"); - server.listen(3000, resolve); - }); - }, 0); - - test("Fetch download info GET", async (context) => { +describe("Fetch download info", () => { + test("Fetch download info GET", async ({expect}) => { const downloader = await downloadFile({ - url: "http://localhost:3000/file.json", + url: `${baseURL}/file.json`, directory: "." }); - context.expect(downloader.file.totalSize > 0) - .toBeTruthy(); + expect(downloader.file.totalSize > 0).toBeTruthy(); }); - test("Refetch download info when token is expired", async (context) => { + test("Refetch download info when token is expired", async ({expect}) => { const downloader = await downloadFile({ - url: "http://localhost:3000/fileCreateToken.gguf", + url: `${baseURL}/fileCreateToken.gguf`, directory: ".", programType: "chunks", parallelStreams: 3 @@ -84,7 +35,6 @@ describe("Fetch download info", () => { await downloader.download(); const fileSize = (await fsPromise.stat(downloader.finalFileAbsolutePath)).size; - context.expect(fileSize) - .toMatchInlineSnapshot(`599171040`); + expect(fileSize).toBe(TEST_FILE_SIZE); }); -}, {timeout: 0}); +}); diff --git a/test/fetchstream-error-propagation.test.ts b/test/fetchstream-error-propagation.test.ts new file mode 100644 index 0000000..b4d5c5a --- /dev/null +++ b/test/fetchstream-error-propagation.test.ts @@ -0,0 +1,80 @@ +import {describe, test} from "vitest"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import {DownloadFile} from "../src/download/download-engine/types.js"; + +class FailingFetchStream { + aborted = false; + paused = false; + availablePrograms = ["stream", "chunks"]; + defaultProgramType = "stream"; + on() { } + emit() { } + close() { + this.aborted = true; + } + withSubState() { + return { + addListener: () => { }, + chunkSize: 10, + startChunk: 0, + endChunk: 1, + lastChunkEndsFile: true, + activePart: { + remoteFileSize: 0, + downloadSize: 0, + acceptRange: true, + downloadURL: "http://localhost/fail.bin", + originalURL: "http://localhost/fail.bin", + downloadURLUpdateDate: Date.now() + }, + onProgress: () => { }, + fetchChunks: async () => { + throw new Error("Simulated network error"); + } + }; + } + async fetchDownloadInfo() { + throw new Error("Simulated network error"); + } + async chunkGenerator() { + throw new Error("Simulated network error"); + } + get transferAction() { + return "Downloading"; + } + get supportDynamicStreamLength() { + return false; + } + get options() { + return {}; + } +} + +describe("FetchStream Error Propagation", () => { + test("should propagate fetchStream errors and not hang", async ({expect}) => { + const fetchStream = new FailingFetchStream(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "fail.bin", + parts: [ + { + downloadURL: "http://localhost/fail.bin", + originalURL: "http://localhost/fail.bin", + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + await expect(downloader.download()).rejects.toThrow("Simulated network error"); + }); +}); diff --git a/test/mixed-parts.test.ts b/test/mixed-parts.test.ts new file mode 100644 index 0000000..dde85aa --- /dev/null +++ b/test/mixed-parts.test.ts @@ -0,0 +1,60 @@ +import {afterAll, beforeAll, describe, test} from "vitest"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +import {DownloadFile} from "../src/download/download-engine/types.js"; +import {startLocalTestServer, LocalTestServer} from "./utils/local-server.js"; + +let baseURL: string; +let server: LocalTestServer; + +beforeAll(async () => { + server = await startLocalTestServer(); + baseURL = server.baseURL; +}); + +afterAll(async () => { + await server.close(); +}); + +describe("Mixed Parts (Range + Non-Range)", () => { + test("should download with mixed range and non-range parts", async ({expect}) => { + const fetchStream1 = new DownloadEngineFetchStreamFetch(); + const fetchStream2 = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "mixed.png", + parts: [ + { + downloadURL: `${baseURL}/range-file.bin`, + originalURL: `${baseURL}/range-file.bin`, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream: fetchStream1, + parallelStreams: 2, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + }, + { + downloadURL: `${baseURL}/no-range-file.png`, + originalURL: `${baseURL}/no-range-file.png`, + acceptRange: false, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream: fetchStream2, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + await expect(downloader.download()).resolves.not.toThrow(); + }); +}); diff --git a/test/parallel-streams-edge.test.ts b/test/parallel-streams-edge.test.ts new file mode 100644 index 0000000..f5e0745 --- /dev/null +++ b/test/parallel-streams-edge.test.ts @@ -0,0 +1,98 @@ +import {afterAll, beforeAll, describe, test} from "vitest"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +import {DownloadFile} from "../src/download/download-engine/types.js"; +import {startLocalTestServer, LocalTestServer} from "./utils/local-server.js"; + +let baseURL: string; +let server: LocalTestServer; + +beforeAll(async () => { + server = await startLocalTestServer(); + baseURL = server.baseURL; +}); + +afterAll(async () => { + await server.close(); +}); + +describe("Parallel Streams Edge Cases", () => { + test("should download with parallelStreams=1 (no parallelism)", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "single.png", + parts: [ + { + downloadURL: `${baseURL}/range-file.bin`, + originalURL: `${baseURL}/range-file.bin`, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + await expect(downloader.download()).resolves.not.toThrow(); + }); + + test("should download with high parallelStreams (stress test)", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "multi.png", + parts: [ + { + downloadURL: `${baseURL}/range-file.bin`, + originalURL: `${baseURL}/range-file.bin`, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 20, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + await expect(downloader.download()).resolves.not.toThrow(); + }); + + test("should not increase parallel streams if autoIncreaseParallelStreams=false", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "noauto.png", + parts: [ + { + downloadURL: `${baseURL}/range-file.bin`, + originalURL: `${baseURL}/range-file.bin`, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 3, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + await expect(downloader.download()).resolves.not.toThrow(); + }); +}); diff --git a/test/pause-resume-abort.test.ts b/test/pause-resume-abort.test.ts new file mode 100644 index 0000000..7df3336 --- /dev/null +++ b/test/pause-resume-abort.test.ts @@ -0,0 +1,77 @@ +import {afterAll, beforeAll, describe, test} from "vitest"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +import {DownloadFile} from "../src/download/download-engine/types.js"; +import {startLocalTestServer, LocalTestServer} from "./utils/local-server.js"; + +let baseURL: string; +let server: LocalTestServer; + +beforeAll(async () => { + server = await startLocalTestServer(); + baseURL = server.baseURL; +}); + +afterAll(async () => { + await server.close(); +}); + +describe("Pause/Resume/Abort Logic", () => { + test("should pause and resume download and preserve data integrity", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "pause.png", + parts: [ + { + downloadURL: `${baseURL}/range-file.bin`, + originalURL: `${baseURL}/range-file.bin`, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + const downloadPromise = downloader.download(); + setTimeout(() => downloader.pause(), 100); // Pause after 100ms + setTimeout(() => downloader.resume(), 200); // Resume after 200ms + await expect(downloadPromise).resolves.not.toThrow(); + }); + + test("should abort download and cleanup resources", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "abort.png", + parts: [ + { + downloadURL: `${baseURL}/range-file.bin`, + originalURL: `${baseURL}/range-file.bin`, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream}); + const downloadPromise = downloader.download(); + setTimeout(() => downloader.close(), 100); // Abort after 100ms + await expect(downloadPromise).resolves.not.toThrow(); + }); +}); diff --git a/test/progress-events.test.ts b/test/progress-events.test.ts new file mode 100644 index 0000000..02e0f25 --- /dev/null +++ b/test/progress-events.test.ts @@ -0,0 +1,53 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import {describe, test} from "vitest"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +import {DownloadFile} from "../src/download/download-engine/types.js"; + +const TEST_URL = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_light_color_92x30dp.png"; + +describe("Progress & Event Emission", () => { + test("should emit all progress events in order", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file: DownloadFile = { + totalSize: 0, + localFileName: "events.png", + parts: [ + { + downloadURL: TEST_URL, + originalURL: TEST_URL, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const events: string[] = []; + const downloader = new DownloadEngineFile(file, { + writeStream, + onFinishAsync: async () => events.push("onFinishAsync"), + onStartedAsync: async () => events.push("onStartedAsync"), + onPausedAsync: async () => events.push("onPausedAsync"), + onSaveProgress: () => events.push("onSaveProgress") + }); + downloader.on("progress", () => events.push("progress")); + downloader.on("save", () => events.push("save")); + downloader.on("paused", () => events.push("paused")); + downloader.on("resumed", () => events.push("resumed")); + downloader.on("finished", () => events.push("finished")); + downloader.on("closed", () => events.push("closed")); + await downloader.download(); + expect(events.length).toBeGreaterThan(0); + expect(events).toContain("onFinishAsync"); + expect(events).toContain("progress"); + expect(events).toContain("finished"); + }); +}); diff --git a/test/range-download-parts.test.ts b/test/range-download-parts.test.ts new file mode 100644 index 0000000..148301d --- /dev/null +++ b/test/range-download-parts.test.ts @@ -0,0 +1,55 @@ +import {afterAll, beforeAll, describe, test} from "vitest"; +import {fetchRangeDownloadParts} from "./utils/fetchRangeDownloadParts.js"; +import {downloadFileBrowser} from "../src/browser.js"; +import {startLocalTestServer, LocalTestServer, TEST_FILE_SIZE} from "./utils/local-server.js"; + +let baseURL: string; +let server: LocalTestServer; +let DOWNLOAD_URLS: Array<{ url: string; range: { start: number; end: number; }; }> = []; + +let downloadResults: Uint8Array[] = [], totalLength = 0; +describe("Range download parts", () => { + beforeAll(async () => { + server = await startLocalTestServer(); + baseURL = server.baseURL; + + DOWNLOAD_URLS = [ + {url: `${baseURL}/range-file.bin`, range: {start: 0, end: 1024 * 1024 * 3 - 1}}, + {url: `${baseURL}/range-file.bin`, range: {start: 1024 * 1024 * 3, end: 1024 * 1024 * 6 - 1}}, + {url: `${baseURL}/range-file.bin`, range: {start: 1024 * 1024 * 6, end: TEST_FILE_SIZE - 1}} + ]; + + downloadResults = await fetchRangeDownloadParts(DOWNLOAD_URLS); + totalLength = downloadResults.reduce((acc, part) => acc + part.length, 0); + }, 1000 * 30); + + afterAll(async () => { + await server.close(); + }); + + test.concurrent("Download from 3 urls different parts and connect into one file", async ({expect}) => { + const downloader = await downloadFileBrowser({ + partURLs: DOWNLOAD_URLS + }); + + if (totalLength !== downloader.file.totalSize) { + throw new Error(`Total length mismatch. Expected: ${totalLength}, Got: ${downloader.file.totalSize}`); + } + + await downloader.download(); + + let cursor = 0, partIndex = 0; + for (const part of downloadResults) { + for (let i = 0; i < part.length; i++, cursor++) { + const expectedByte = part[i]; + const actualByte = downloader.writeStream.result[cursor]; + if (expectedByte !== actualByte) { + throw new Error(`Byte mismatch at position ${cursor} (part: ${partIndex}). Expected: ${expectedByte}, Got: ${actualByte}`); + } + } + partIndex++; + } + + expect(cursor).toBe(totalLength); + }); +}); diff --git a/test/range-validation-error.test.ts b/test/range-validation-error.test.ts new file mode 100644 index 0000000..c6bb5ee --- /dev/null +++ b/test/range-validation-error.test.ts @@ -0,0 +1,56 @@ + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import {describe, test} from "vitest"; +import {RangeOutOfPartLengthError} from "../src/download/download-engine/engine/error/RangeOutOfPartLengthError.js"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +// import {DownloadFile} from "../src/download/download-engine/types.js"; + +const TEST_URL = "https://huggingface.co/giladgd/Qwen3-Reranker-0.6B-GGUF/resolve/main/Qwen3-Reranker-0.6B.Q2_K.gguf?download=true"; + +function createPartWithRange(url: string, range: { start: number, end: number; }, remoteFileSize: number) { + return { + downloadURL: url, + originalURL: url, + acceptRange: true, + remoteFileSize, + downloadSize: range.end - range.start + 1, + downloadURLUpdateDate: Date.now(), + fetchStream: new DownloadEngineFetchStreamFetch(), + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range + }; +} + +describe("Range Validation & Error Handling", () => { + test("should throw RangeOutOfPartLengthError if range exceeds remoteFileSize", async ({expect}) => { + const remoteFileSize = 1000; + const part = createPartWithRange(TEST_URL, {start: 0, end: 2000}, remoteFileSize); + expect(() => { + if (part.downloadSize > part.remoteFileSize) { + throw new RangeOutOfPartLengthError(part.downloadURL, part.range.end, part.remoteFileSize); + } + }).toThrow(RangeOutOfPartLengthError); + }); + + test("should throw if start > end", async ({expect}) => { + const remoteFileSize = 1000; + const part = createPartWithRange(TEST_URL, {start: 900, end: 800}, remoteFileSize); + expect(() => { + if (part.range.start > part.range.end) { + throw new Error("Start of range is greater than end"); + } + }).toThrow("Start of range is greater than end"); + }); + + test("should throw if range is negative", async ({expect}) => { + const remoteFileSize = 1000; + const part = createPartWithRange(TEST_URL, {start: -10, end: 100}, remoteFileSize); + expect(() => { + if (part.range.start < 0) { + throw new Error("Range start is negative"); + } + }).toThrow("Range start is negative"); + }); +}); diff --git a/test/redirect-handling.test.ts b/test/redirect-handling.test.ts new file mode 100644 index 0000000..eb4c6f7 --- /dev/null +++ b/test/redirect-handling.test.ts @@ -0,0 +1,63 @@ +import {describe, test} from "vitest"; +import DownloadEngineFetchStreamFetch from "../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; +import DownloadEngineFile from "../src/download/download-engine/download-file/download-engine-file.js"; +import DownloadEngineWriteStreamBrowser from "../src/download/download-engine/streams/download-engine-write-stream/download-engine-write-stream-browser.js"; + +// This URL should redirect. Replace with a known redirecting URL if needed. +const REDIRECT_URL = "https://httpbin.org/redirect-to?url=https://www.google.com/images/branding/googlelogo/2x/googlelogo_light_color_92x30dp.png"; + + +describe("Redirect Handling", () => { + test("should follow redirect and use newURL", async ({expect}) => { + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file = { + totalSize: 0, + localFileName: "redirect.png", + parts: [ + { + downloadURL: REDIRECT_URL, + originalURL: REDIRECT_URL, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream, comment: "test redirect"}); + await expect(downloader.download()).resolves.not.toThrow(); + }); + + test("should respect reuseRedirectURL option", async ({expect}) => { + // This test assumes the engine will use the newURL for subsequent requests if reuseRedirectURL is true + const fetchStream = new DownloadEngineFetchStreamFetch(); + const writeStream = new DownloadEngineWriteStreamBrowser(() => { }); + const file = { + totalSize: 0, + localFileName: "redirect2.png", + parts: [ + { + downloadURL: REDIRECT_URL, + originalURL: REDIRECT_URL, + acceptRange: true, + remoteFileSize: 0, + downloadSize: 0, + downloadURLUpdateDate: Date.now(), + fetchStream, + parallelStreams: 1, + autoIncreaseParallelStreams: false, + programType: "stream", + range: {start: 0, end: -1} + } + ] + }; + const downloader = new DownloadEngineFile(file, {writeStream, comment: "test redirect", reuseRedirectURL: true}); + await expect(downloader.download()).resolves.not.toThrow(); + }); +}); diff --git a/test/utils/download.ts b/test/utils/download.ts index 4ebc447..de75146 100644 --- a/test/utils/download.ts +++ b/test/utils/download.ts @@ -1,21 +1,21 @@ -import path from "path"; -import {fileURLToPath} from "url"; import fs from "fs-extra"; import fsPromise from "fs/promises"; +import {withLock} from "lifecycle-utils"; +import path from "path"; +import {fileURLToPath} from "url"; +import {AvailablePrograms} from "../../src/download/download-engine/download-file/download-programs/switch-program.js"; +import DownloadEngineFetchStreamFetch from "../../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; import {DownloadFile} from "../../src/download/download-engine/types.js"; import {BIG_FILE} from "./files.js"; -import BaseDownloadEngineFetchStream from "../../src/download/download-engine/streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js"; -import DownloadEngineFetchStreamFetch from "../../src/download/download-engine/streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js"; -import {withLock} from "lifecycle-utils"; const __dirname = fileURLToPath(new URL(".", import.meta.url)); -export const BIG_FILE_EXAMPLE = path.join(__dirname, "files", "big-file.jpg"); +export const BIG_FILE_EXAMPLE = path.join(__dirname, "files", "big-file.bin"); export const TEXT_FILE_EXAMPLE = path.join(__dirname, "files", "example.txt"); const lockScope = {}; export async function ensureLocalFile(download: string, local: string) { - return await withLock(lockScope, local, async function ensureLocalFileWithoutLock() { + return await withLock([lockScope, local], async function ensureLocalFileWithoutLock() { if (await fs.pathExists(local)) { return local; } @@ -27,8 +27,20 @@ export async function ensureLocalFile(download: string, local: string) { }); } +type CreateDownloadFileOptions = { + parallelStreams?: number; + autoIncreaseParallelStreams?: boolean; + programType?: AvailablePrograms; +}; +export async function createDownloadFile(file = BIG_FILE, {parallelStreams = 3, autoIncreaseParallelStreams = true, programType = "stream"}: CreateDownloadFileOptions = {}): Promise { + const fetchStream = new DownloadEngineFetchStreamFetch(); + fetchStream.addListener("streamNotRespondingOn", () => { + console.warn("Stream is not responding, but ignoring since it's expected in tests"); + }); + fetchStream.addListener("errorCountIncreased", (error) => { + console.warn("Error count increased, but ignoring since it's expected in tests", error); + }); -export async function createDownloadFile(file = BIG_FILE, fetchStream: BaseDownloadEngineFetchStream = new DownloadEngineFetchStreamFetch()): Promise { const fileInfo = await fetchStream.fetchDownloadInfo(file); return { @@ -38,7 +50,18 @@ export async function createDownloadFile(file = BIG_FILE, fetchStream: BaseDownl { downloadURL: file, acceptRange: fileInfo.acceptRange, - size: fileInfo.length + remoteFileSize: fileInfo.length, + originalURL: file, + downloadURLUpdateDate: Date.now(), + parallelStreams, + autoIncreaseParallelStreams, + fetchStream, + programType, + range: { + start: 0, + end: fileInfo.length - 1 + }, + downloadSize: fileInfo.length } ] }; diff --git a/test/utils/fetchRangeDownloadParts.ts b/test/utils/fetchRangeDownloadParts.ts new file mode 100644 index 0000000..848eb7f --- /dev/null +++ b/test/utils/fetchRangeDownloadParts.ts @@ -0,0 +1,28 @@ +type FetchRangeDownloadPartsOptions = { + url: string; + range: { + start: number; + end: number; + } +}[]; + +export async function fetchRangeDownloadParts(params: FetchRangeDownloadPartsOptions) { + const results = await Promise.all(params.map(async ({url, range}) => { + const response = await fetch(url, { + method: "GET", + headers: { + Range: `bytes=${range.start}-${range.end}` + } + }); + + if (response.status < 200 || response.status >= 300) { + throw new Error(`Failed to fetch range ${range.start}-${range.end} from ${url}. Status: ${response.status}`); + } + + const arrayBuffer = await response.arrayBuffer(); + return new Uint8Array(arrayBuffer); + })); + + + return results; +} diff --git a/test/utils/files.ts b/test/utils/files.ts index 125fb95..1f5aeca 100644 --- a/test/utils/files.ts +++ b/test/utils/files.ts @@ -1 +1 @@ -export const BIG_FILE = "https://upload.wikimedia.org/wikipedia/commons/9/9e/1_dubrovnik_pano_-_edit1.jpg"; // 40mb +export const BIG_FILE = "https://huggingface.co/datasets/ChaoticNeutrals/Creative_Writing-ShareGPT/resolve/main/Creative_Writing-ShareGPT.jsonl?download=true"; // 27.5mb diff --git a/test/utils/local-server.ts b/test/utils/local-server.ts new file mode 100644 index 0000000..73af1bf --- /dev/null +++ b/test/utils/local-server.ts @@ -0,0 +1,215 @@ +import express from "express"; +import http from "http"; + +export const TEST_FILE_SIZE = 8 * 1024 * 1024; // 8MB +export const TEST_FILE_DATA = Buffer.alloc(TEST_FILE_SIZE, 0x61); // 'a' bytes + +export type LocalTestServer = { + baseURL: string; + close: () => Promise; +}; + +const parseRange = (rangeHeader: string | undefined) => { + if (!rangeHeader) return null; + const match = /bytes=(\d+)-(\d+)?/.exec(rangeHeader); + if (!match) return null; + + const start = Number(match[1]); + const end = typeof match[2] === "undefined" ? TEST_FILE_SIZE - 1 : Number(match[2]); + return {start, end}; +}; + +const setCommonHeaders = (res: express.Response, withRange: boolean, length: number) => { + if (withRange) { + res.setHeader("Accept-Ranges", "bytes"); + } + res.setHeader("Content-Length", String(length)); +}; + +const handleRangeRequest = (req: express.Request, res: express.Response, data: Buffer) => { + const rangeHeader = req.header("range"); + if (!rangeHeader) { + setCommonHeaders(res, true, TEST_FILE_SIZE); + res.status(200).send(data); + return; + } + + const range = parseRange(rangeHeader); + if (!range || range.start > range.end || range.start < 0 || range.end >= TEST_FILE_SIZE) { + res.status(416).end(); + return; + } + + const chunk = data.slice(range.start, range.end + 1); + res.status(206); + res.setHeader("Accept-Ranges", "bytes"); + res.setHeader("Content-Range", `bytes ${range.start}-${range.end}/${TEST_FILE_SIZE}`); + res.setHeader("Content-Length", String(chunk.length)); + res.send(chunk); +}; + +const setupRangeFileRoutes = (app: express.Express) => { + app.head("/range-file.bin", (req, res) => { + setCommonHeaders(res, true, TEST_FILE_SIZE); + res.status(200).end(); + }); + + app.get("/range-file.bin", (req, res) => { + handleRangeRequest(req, res, TEST_FILE_DATA); + }); +}; + +const setupNoRangeRoutes = (app: express.Express) => { + app.head("/no-range-file.png", (req, res) => { + setCommonHeaders(res, false, TEST_FILE_SIZE); + res.status(200).end(); + }); + + app.get("/no-range-file.png", (req, res) => { + setCommonHeaders(res, false, TEST_FILE_SIZE); + res.status(200).send(TEST_FILE_DATA); + }); + + app.head("/no-range-zero.png", (req, res) => { + res.setHeader("Content-Length", "0"); + res.status(200).end(); + }); + + app.get("/no-range-zero.png", (req, res) => { + res.setHeader("Content-Length", "0"); + res.status(200).send(TEST_FILE_DATA); + }); +}; + +const setupMismatchRoutes = (app: express.Express) => { + app.head("/bad-content-range.bin", (req, res) => { + setCommonHeaders(res, true, TEST_FILE_SIZE); + res.status(200).end(); + }); + + app.get("/bad-content-range.bin", (req, res) => { + const rangeHeader = req.header("range"); + if (!rangeHeader) { + setCommonHeaders(res, true, TEST_FILE_SIZE + 1); // wrong length deliberately + res.status(200).send(TEST_FILE_DATA); + return; + } + + const range = parseRange(rangeHeader); + if (!range || range.start > range.end || range.start < 0 || range.end >= TEST_FILE_SIZE) { + res.status(416).end(); + return; + } + + const chunk = TEST_FILE_DATA.slice(range.start, range.end + 1); + res.status(206); + res.setHeader("Accept-Ranges", "bytes"); + // intentionally provide mismatched content-range and content-length + res.setHeader("Content-Range", `bytes ${range.start}-${range.end + 1}/${TEST_FILE_SIZE}`); + res.setHeader("Content-Length", String(chunk.length)); + res.send(chunk); + }); +}; + +const setupContentLengthMismatchRoutes = (app: express.Express) => { + app.head("/bad-length.bin", (req, res) => { + setCommonHeaders(res, true, TEST_FILE_SIZE); + res.status(200).end(); + }); + + app.get("/bad-length.bin", (req, res) => { + const rangeHeader = req.header("range"); + if (!rangeHeader) { + setCommonHeaders(res, true, TEST_FILE_SIZE + 1000); // wrong length deliberately + res.status(200).send(TEST_FILE_DATA.slice(0, TEST_FILE_SIZE + 1000)); // but send correct data? Wait, to mismatch, send less or more. + // To mismatch, perhaps send TEST_FILE_DATA, but header wrong. + // But to make it throw, send TEST_FILE_DATA, header wrong, but in fetch, header wrong, throw. + // In xhr, data length correct, header wrong, but xhr checks data vs expected, expected from header? No, expected is calculated, data is correct, so no throw. + // For no range, the expected is the totalSize, contentLength from header. + // So for no range, if header wrong, in fetch, contentLength !== expected, throw. + // In xhr, the check is if expected !== arrayBuffer.byteLength, but expected is from header? No, in xhr, expectedContentLength is calculated from range, same as fetch. + // In xhr, the check is expectedContentLength !== arrayBuffer.byteLength + // So for no range, expected = total, data length = total, header wrong, but check is data vs expected, not header. + // So for no range, it won't throw in xhr. + // For range, in xhr, data length = sent length = chunk.length - 1, expected = chunk.length, throw. + // For fetch, for range, header = chunk.length - 1, expected = chunk.length, throw. + // For no range, in fetch, header = TEST_FILE_SIZE + 1000, expected = TEST_FILE_SIZE, throw. + // In xhr, for no range, data length = TEST_FILE_SIZE, expected = TEST_FILE_SIZE, no throw. + // So to make it throw in both, for no range, send wrong data length. + // So set header to TEST_FILE_SIZE + 1000, send TEST_FILE_DATA (length TEST_FILE_SIZE). + // In fetch, header wrong, throw. + // In xhr, data length = TEST_FILE_SIZE, expected = TEST_FILE_SIZE + 1000, throw. + // Yes. + res.status(200).send(TEST_FILE_DATA); + return; + } + + const range = parseRange(rangeHeader); + if (!range || range.start > range.end || range.start < 0 || range.end >= TEST_FILE_SIZE) { + res.status(416).end(); + return; + } + + const chunk = TEST_FILE_DATA.slice(range.start, range.end + 1); + const wrongChunk = chunk.slice(0, Math.max(0, chunk.length - 1)); + res.status(206); + res.setHeader("Accept-Ranges", "bytes"); + res.setHeader("Content-Length", String(Math.max(0, chunk.length - 1))); // wrong length + res.send(wrongChunk); + }); +}; + +const setupTokenRoutes = (app: express.Express) => { + let authToken = ""; + app.get("/fileCreateToken.gguf", (req, res) => { + authToken = String(Date.now() + 1000 * 3); + res.redirect(`/file.gguf?token=${authToken}`); + }); + + app.get("/file.gguf", (req, res) => { + const token = String(req.query.token || ""); + if (!token || Number(token) < Date.now()) { + res.status(403).send("Token expired"); + return; + } + + handleRangeRequest(req, res, TEST_FILE_DATA); + }); +}; + +const setupOtherRoutes = (app: express.Express) => { + app.get("/file.json", (req, res) => { + res.json({hello: "world", value: 42}); + }); +}; + +export async function startLocalTestServer(): Promise { + const app = express(); + + setupRangeFileRoutes(app); + setupNoRangeRoutes(app); + setupMismatchRoutes(app); + setupContentLengthMismatchRoutes(app); + setupTokenRoutes(app); + setupOtherRoutes(app); + + const server = http.createServer(app); + await new Promise((resolve) => { + server.listen(0, "127.0.0.1", resolve); + }); + + const address = server.address(); + if (!address || typeof address === "string") { + throw new Error("Failed to start test server"); + } + + const baseURL = `http://127.0.0.1:${address.port}`; + + return { + baseURL, + close: async () => new Promise((resolve, reject) => server.close((err) => (err ? reject(err) : resolve()))) + }; +} + + + diff --git a/tsconfig.prod.json b/tsconfig.prod.json new file mode 100644 index 0000000..0b634c8 --- /dev/null +++ b/tsconfig.prod.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "lib": [ + "es2022", + "DOM" + ], + "module": "NodeNext", + "target": "es2022", + "esModuleInterop": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitOverride": true, + "removeComments": false, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "moduleResolution": "NodeNext", + "resolveJsonModule": true, + "strictNullChecks": true, + "isolatedModules": true, + "noEmit": false, + "outDir": "./dist", + "strict": true, + "sourceMap": false, + "composite": false, + "declaration": true, + "stripInternal": true + }, + "files": [ + "./src/index.ts" + ], + "include": [ + "./src" + ] +} diff --git a/vitest.config.ts b/vitest.config.ts index a2a07e9..1738914 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -3,13 +3,6 @@ import {defineConfig} from "vitest/config"; export default defineConfig({ test: { pool: "threads", - maxWorkers: 1, - minWorkers: 1, - poolOptions: { - threads: { - minThreads: 1, - maxThreads: 1 - } - } + testTimeout: 1000 * 60 * 3 } });