pax_global_header00006660000000000000000000000064151444657470014533gustar00rootroot0000000000000052 comment=f738c781d14fa7bc06f8e39e062d78f701fde3f1 isaacs-rimraf-4c5e478/000077500000000000000000000000001514446574700146215ustar00rootroot00000000000000isaacs-rimraf-4c5e478/.github/000077500000000000000000000000001514446574700161615ustar00rootroot00000000000000isaacs-rimraf-4c5e478/.github/workflows/000077500000000000000000000000001514446574700202165ustar00rootroot00000000000000isaacs-rimraf-4c5e478/.github/workflows/ci.yml000066400000000000000000000022011514446574700213270ustar00rootroot00000000000000name: CI on: push: branches: ["main"] pull_request_target: paths: - 'src/**' - 'test/**' - '*.json' - '*.js' - '*.ts' - 'lib/**' - 'scripts/**' workflow_dispatch: permissions: contents: read jobs: build: strategy: matrix: node-version: [22.x, 24.x] platform: - os: ubuntu-latest shell: bash - os: macos-latest shell: bash - os: windows-latest shell: bash - os: windows-latest shell: powershell fail-fast: false runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - name: Checkout Repository uses: actions/checkout@v5 - name: Use Nodejs ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} - name: Install dependencies run: npm install - name: Run Tests run: npm test -- -c -t0 env: RIMRAF_TEST_START_CHAR: a RIMRAF_TEST_END_CHAR: f RIMRAF_TEST_DEPTH: 5 isaacs-rimraf-4c5e478/.github/workflows/typedoc.yml000066400000000000000000000016461514446574700224170ustar00rootroot00000000000000name: typedoc on: push: branches: ["main"] workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: true jobs: deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v5 - name: Use Nodejs ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: 20.x - name: Install dependencies run: npm install - name: Generate typedocs run: npm run typedoc - name: Setup Pages uses: actions/configure-pages@v5 - name: Upload artifact uses: actions/upload-pages-artifact@v4 with: path: './docs' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 isaacs-rimraf-4c5e478/.gitignore000066400000000000000000000001671514446574700166150ustar00rootroot00000000000000/node_modules/ /.nyc_output /coverage /dist /.tap !/typedoc.json !/tsconfig-*.json !/.prettierignore /benchmark-*.json isaacs-rimraf-4c5e478/.prettierignore000066400000000000000000000003111514446574700176570ustar00rootroot00000000000000/node_modules /tsconfig.json /package-lock.json /package.json /LICENSE.md /example /.github /dist /.env /tap-snapshots /.nyc_output /coverage /benchmark /.tap /test/fixture /test/fixtures /.tshy /docs isaacs-rimraf-4c5e478/.prettierrc.json000066400000000000000000000003521514446574700177550ustar00rootroot00000000000000{ "experimentalTernaries": true, "semi": false, "printWidth": 75, "tabWidth": 2, "useTabs": false, "singleQuote": true, "jsxSingleQuote": false, "bracketSameLine": true, "arrowParens": "avoid", "endOfLine": "lf" } isaacs-rimraf-4c5e478/.taprc000066400000000000000000000000271514446574700157320ustar00rootroot00000000000000coverage-map: "map.js" isaacs-rimraf-4c5e478/.tshy/000077500000000000000000000000001514446574700156665ustar00rootroot00000000000000isaacs-rimraf-4c5e478/.tshy/build.json000066400000000000000000000002261514446574700176600ustar00rootroot00000000000000{ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "../src", "module": "nodenext", "moduleResolution": "nodenext" } } isaacs-rimraf-4c5e478/.tshy/commonjs.json000066400000000000000000000004301514446574700204030ustar00rootroot00000000000000{ "extends": "./build.json", "include": [ "../src/**/*.ts", "../src/**/*.cts", "../src/**/*.tsx", "../src/**/*.json" ], "exclude": [ "../src/**/*.mts", "../src/package.json" ], "compilerOptions": { "outDir": "../.tshy-build/commonjs" } } isaacs-rimraf-4c5e478/.tshy/esm.json000066400000000000000000000003741514446574700173510ustar00rootroot00000000000000{ "extends": "./build.json", "include": [ "../src/**/*.ts", "../src/**/*.mts", "../src/**/*.tsx", "../src/**/*.json" ], "exclude": [ "../src/package.json" ], "compilerOptions": { "outDir": "../.tshy-build/esm" } } isaacs-rimraf-4c5e478/CHANGELOG.md000066400000000000000000000056201514446574700164350ustar00rootroot00000000000000# 6.1 - Move to native `fs/promises` usage instead of promisifying manually. # 6.0 - Drop support for nodes before v20 - Add `--version` to CLI # 5.0 - No default export, only named exports # 4.4 - Provide Dirent or Stats object as second argument to filter # 4.3 - Return boolean indicating whether the path was fully removed - Add filter option - bin: add --verbose, -v to print files as they are deleted - bin: add --no-verbose, -V to not print files as they are deleted - bin: add -i --interactive to be prompted on each deletion - bin: add -I --no-interactive to not be prompted on each deletion - **4.3.1** Fixed inappropriately following symbolic links to directories # v4.2 - Brought back `glob` support, using the new and improved glob v9 # v4.1 - Improved hybrid module with no need to look at the `.default` dangly bit. `.default` preserved as a reference to `rimraf` for compatibility with anyone who came to rely on it in v4.0. - Accept and ignore `-rf` and `-fr` arguments to the bin. # v4.0 - Remove `glob` dependency entirely. This library now only accepts actual file and folder names to delete. - Accept array of paths or single path. - Windows performance and reliability improved. - All strategies separated into explicitly exported methods. - Drop support for Node.js below version 14 - rewrite in TypeScript - ship CJS/ESM hybrid module - Error on unknown arguments to the bin. (Previously they were silently ignored.) # v3.0 - Add `--preserve-root` option to executable (default true) - Drop support for Node.js below version 6 # v2.7 - Make `glob` an optional dependency # 2.6 - Retry on EBUSY on non-windows platforms as well - Make `rimraf.sync` 10000% more reliable on Windows # 2.5 - Handle Windows EPERM when lstat-ing read-only dirs - Add glob option to pass options to glob # 2.4 - Add EPERM to delay/retry loop - Add `disableGlob` option # 2.3 - Make maxBusyTries and emfileWait configurable - Handle weird SunOS unlink-dir issue - Glob the CLI arg for better Windows support # 2.2 - Handle ENOENT properly on Windows - Allow overriding fs methods - Treat EPERM as indicative of non-empty dir - Remove optional graceful-fs dep - Consistently return null error instead of undefined on success - win32: Treat ENOTEMPTY the same as EBUSY - Add `rimraf` binary # 2.1 - Fix SunOS error code for a non-empty directory - Try rmdir before readdir - Treat EISDIR like EPERM - Remove chmod - Remove lstat polyfill, node 0.7 is not supported # 2.0 - Fix myGid call to check process.getgid - Simplify the EBUSY backoff logic. - Use fs.lstat in node >= 0.7.9 - Remove gently option - remove fiber implementation - Delete files that are marked read-only # 1.0 - Allow ENOENT in sync method - Throw when no callback is provided - Make opts.gently an absolute path - use 'stat' if 'lstat' is not available - Consistent error naming, and rethrow non-ENOENT stat errors - add fiber implementation isaacs-rimraf-4c5e478/LICENSE.md000066400000000000000000000030201514446574700162200ustar00rootroot00000000000000# Blue Oak Model License Version 1.0.0 ## Purpose This license gives everyone as much permission to work with this software as possible, while protecting contributors from liability. ## Acceptance In order to receive this license, you must agree to its rules. The rules of this license are both obligations under that agreement and conditions to your license. You must not do anything with this software that triggers a rule that you cannot or will not follow. ## Copyright Each contributor licenses you to do everything with this software that would otherwise infringe that contributor's copyright in it. ## Notices You must ensure that everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license or a link to . ## Excuse If anyone notifies you in writing that you have not complied with [Notices](#notices), you can keep your license by taking all practical steps to comply within 30 days after the notice. If you do not do so, your license ends immediately. ## Patent Each contributor licenses you to do everything with this software that would otherwise infringe any patent claims they can license or become able to license. ## Reliability No contributor can revoke this license. ## No Liability ***As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim.*** isaacs-rimraf-4c5e478/README.md000066400000000000000000000236221514446574700161050ustar00rootroot00000000000000The [UNIX command]() `rm -rf` for node in a cross-platform implementation. Install with `npm install rimraf`. > [!CAUTION] > > ## Please Be Safe, this tool deletes and moves stuff, by design > > The _intended purpose_ of this tool is to remove files and > directories from the filesystem, aggressively and recursively > removing all items that it can find under a given target. > > It goes without saying that you _must not pass untrusted input > to this function or CLI tool_, just as you would not to the > `rm(1)` command or the `unlink(2)` function. It is very > challenging to guarantee that _any_ user input will be safe to > remove recursively in this way. > > Furthermore, note that if you allow untrusted parties to > provide arguments to the `rimraf` command line tool, they may > also specify the `--tmp=` folder used by the > `--impl=move-remove` strategy, which can move files to an > arbitrary place on disk. > > Because the intended purpose of this tool is the permanent > destruction of filesystem entries, any security reports that > rely on untrusted input being passed to the function or command > line tool will be rejected. > > **It is your responsibility as a user to never pass untrusted > user input to this module, or your system can be destroyed or > compromised.** ## Major Changes ### v5 to v6 - Require node `20` or `>=22` - Add `--version` to CLI ### v4 to v5 - There is no default export anymore. Import the functions directly using, e.g., `import { rimrafSync } from 'rimraf'`. ### v3 to v4 - The function returns a `Promise` instead of taking a callback. - Globbing requires the `--glob` CLI option or `glob` option property to be set. (Removed in 4.0 and 4.1, opt-in support added in 4.2.) - Functions take arrays of paths, as well as a single path. - Native implementation used by default when available, except on Windows, where this implementation is faster and more reliable. - New implementation on Windows, falling back to "move then remove" strategy when exponential backoff for `EBUSY` fails to resolve the situation. - Simplified implementation on POSIX, since the Windows affordances are not necessary there. - As of 4.3, return/resolve value is boolean instead of undefined. ## API Hybrid module, load either with `import` or `require()`. ```js // 'rimraf' export is the one you probably want, but other // strategies exported as well. import { rimraf, rimrafSync, native, nativeSync } from 'rimraf' // or const { rimraf, rimrafSync, native, nativeSync } = require('rimraf') ``` All removal functions return a boolean indicating that all entries were successfully removed. The only case in which this will not return `true` is if something was omitted from the removal via a `filter` option. ### `rimraf(f, [opts]) -> Promise` This first parameter is a path or array of paths. The second argument is an options object. Options: - `preserveRoot`: If set to boolean `false`, then allow the recursive removal of the root directory. Otherwise, this is not allowed. - `tmp`: Windows only. Temp folder to place files and folders for the "move then remove" fallback. Must be on the same physical device as the path being deleted. Defaults to `os.tmpdir()` when that is on the same drive letter as the path being deleted, or `${drive}:\temp` if present, or `${drive}:\` if not. - `maxRetries`: Windows and Native only. Maximum number of retry attempts in case of `EBUSY`, `EMFILE`, and `ENFILE` errors. Default `10` for Windows implementation, `0` for Native implementation. - `backoff`: Windows only. Rate of exponential backoff for async removal in case of `EBUSY`, `EMFILE`, and `ENFILE` errors. Should be a number greater than 1. Default `1.2` - `maxBackoff`: Windows only. Maximum total backoff time in ms to attempt asynchronous retries in case of `EBUSY`, `EMFILE`, and `ENFILE` errors. Default `200`. With the default `1.2` backoff rate, this results in 14 retries, with the final retry being delayed 33ms. - `retryDelay`: Native only. Time to wait between retries, using linear backoff. Default `100`. - `signal` Pass in an AbortSignal to cancel the directory removal. This is useful when removing large folder structures, if you'd like to limit the time spent. Using a `signal` option prevents the use of Node's built-in `fs.rm` because that implementation does not support abort signals. - `glob` Boolean flag to treat path as glob pattern, or an object specifying [`glob` options](https://github.com/isaacs/node-glob). - `filter` Method that returns a boolean indicating whether that path should be deleted. With async `rimraf` methods, this may return a Promise that resolves to a boolean. (Since Promises are truthy, returning a Promise from a sync filter is the same as just not filtering anything.) The first argument to the filter is the path string. The second argument is either a `Dirent` or `Stats` object for that path. (The first path explored will be a `Stats`, the rest will be `Dirent`.) If a filter method is provided, it will _only_ remove entries if the filter returns (or resolves to) a truthy value. Omitting a directory will still allow its children to be removed, unless they are also filtered out, but any parents of a filtered entry will not be removed, since the directory will not be empty in that case. Using a filter method prevents the use of Node's built-in `fs.rm` because that implementation does not support filtering. Any other options are provided to the native Node.js `fs.rm` implementation when that is used. This will attempt to choose the best implementation, based on the Node.js version and `process.platform`. To force a specific implementation, use one of the other functions provided. ### `rimraf.sync(f, [opts])`
`rimraf.rimrafSync(f, [opts])` Synchronous form of `rimraf()` Note that, unlike many file system operations, the synchronous form will typically be significantly _slower_ than the async form, because recursive deletion is extremely parallelizable. ### `rimraf.native(f, [opts])` Uses the built-in `fs.rm` implementation that Node.js provides. This is used by default on Node.js versions greater than or equal to `14.14.0`. ### `rimraf.native.sync(f, [opts])`
`rimraf.nativeSync(f, [opts])` Synchronous form of `rimraf.native` ### `rimraf.manual(f, [opts])` Use the JavaScript implementation appropriate for your operating system. ### `rimraf.manual.sync(f, [opts])`
`rimraf.manualSync(f, opts)` Synchronous form of `rimraf.manual()` ### `rimraf.windows(f, [opts])` JavaScript implementation of file removal appropriate for Windows platforms. Works around `unlink` and `rmdir` not being atomic operations, and `EPERM` when deleting files with certain permission modes. First deletes all non-directory files within the tree, and then removes all directories, which should ideally be empty by that time. When an `ENOTEMPTY` is raised in the second pass, falls back to the `rimraf.moveRemove` strategy as needed. ### `rimraf.windows.sync(path, [opts])`
`rimraf.windowsSync(path, [opts])` Synchronous form of `rimraf.windows()` ### `rimraf.moveRemove(path, [opts])` Moves all files and folders to the parent directory of `path` with a temporary filename prior to attempting to remove them. Note that, in cases where the operation fails, this _may_ leave files lying around in the parent directory with names like `.file-basename.txt.0.123412341`. Until the Windows kernel provides a way to perform atomic `unlink` and `rmdir` operations, this is, unfortunately, unavoidable. To move files to a different temporary directory other than the parent, provide `opts.tmp`. Note that this _must_ be on the same physical device as the folder being deleted, or else the operation will fail. This is the slowest strategy, but most reliable on Windows platforms. Used as a last-ditch fallback by `rimraf.windows()`. ### `rimraf.moveRemove.sync(path, [opts])`
`rimraf.moveRemoveSync(path, [opts])` Synchronous form of `rimraf.moveRemove()` ### Command Line Interface ``` rimraf version 6.0.1 Usage: rimraf [ ...] Deletes all files and folders at "path", recursively. Options: -- Treat all subsequent arguments as paths -h --help Display this usage info --version Display version --preserve-root Do not remove '/' recursively (default) --no-preserve-root Do not treat '/' specially -G --no-glob Treat arguments as literal paths, not globs (default) -g --glob Treat arguments as glob patterns -v --verbose Be verbose when deleting files, showing them as they are removed. Not compatible with --impl=native -V --no-verbose Be silent when deleting files, showing nothing as they are removed (default) -i --interactive Ask for confirmation before deleting anything Not compatible with --impl=native -I --no-interactive Do not ask for confirmation before deleting --impl= Specify the implementation to use: rimraf: choose the best option (default) native: the built-in implementation in Node.js manual: the platform-specific JS implementation posix: the Posix JS implementation windows: the Windows JS implementation (falls back to move-remove on ENOTEMPTY) move-remove: a slow reliable Windows fallback Implementation-specific options: --tmp= Temp file folder for 'move-remove' implementation --max-retries= maxRetries for 'native' and 'windows' implementations --retry-delay= retryDelay for 'native' implementation, default 100 --backoff= Exponential backoff factor for retries (default: 1.2) ``` ## mkdirp If you need to _create_ a directory recursively, check out [mkdirp](https://github.com/isaacs/node-mkdirp). isaacs-rimraf-4c5e478/benchmark/000077500000000000000000000000001514446574700165535ustar00rootroot00000000000000isaacs-rimraf-4c5e478/benchmark/.gitignore000066400000000000000000000000301514446574700205340ustar00rootroot00000000000000/node_modules /fixtures isaacs-rimraf-4c5e478/benchmark/create-fixture.js000066400000000000000000000015231514446574700220410ustar00rootroot00000000000000import { writeFile as writeFile_ } from 'fs' const writeFile = async (path, data) => new Promise((res, rej) => writeFile_(path, data, er => (er ? rej(er) : res())), ) import { mkdirp } from 'mkdirp' import { resolve } from 'path' const create = async (path, start, end, maxDepth, depth = 0) => { await mkdirp(path) const promises = [] for (let i = start; i <= end; i++) { const c = String.fromCharCode(i) if (depth < maxDepth && i - start >= depth) await create(resolve(path, c), start, end, maxDepth, depth + 1) else promises.push(writeFile(resolve(path, c), c)) } await Promise.all(promises) return path } export default async ({ start, end, depth, name }) => { const path = resolve(import.meta.dirname, 'fixtures', name, 'test') return await create(path, start.charCodeAt(0), end.charCodeAt(0), depth) } isaacs-rimraf-4c5e478/benchmark/index.js000066400000000000000000000063101514446574700202200ustar00rootroot00000000000000import rimrafs, { names as rimrafNames } from './rimrafs.js' import runTest, { names as runTestNames } from './run-test.js' import parse from './parse-results.js' import { sync as rimrafSync } from '../dist/esm/index.js' import { parseArgs } from 'util' import assert from 'assert' import { readFileSync, writeFileSync } from 'fs' const parseOptions = () => { const { values } = parseArgs({ options: { cases: { type: 'string', short: 'c', multiple: true, }, 'omit-cases': { type: 'string', short: 'o', multiple: true, }, 'start-char': { type: 'string', default: 'a', }, 'end-char': { type: 'string', default: 'f', }, depth: { type: 'string', default: '5', }, iterations: { type: 'string', default: '7', }, compare: { type: 'string', }, save: { type: 'boolean', }, }, }) if (values.compare) { const { results, options } = JSON.parse( readFileSync(values.compare, 'utf8'), ) return { ...options, save: false, compare: results, } } const allNames = new Set([...rimrafNames, ...runTestNames]) const partition = (name, defaults = [new Set(), new Set()]) => { const options = values[name] ?? [] assert( options.every(c => allNames.has(c)), new TypeError(`invalid ${name}`, { cause: { found: options, wanted: [...allNames], }, }), ) const found = options.reduce( (acc, k) => { acc[rimrafNames.has(k) ? 0 : 1].add(k) return acc }, [new Set(), new Set()], ) return [ found[0].size ? found[0] : defaults[0], found[1].size ? found[1] : defaults[1], ] } const cases = partition('cases', [rimrafNames, runTestNames]) for (const [i, omitCase] of Object.entries(partition('omit-cases'))) { for (const o of omitCase) { cases[i].delete(o) } } return { rimraf: [...cases[0]], runTest: [...cases[1]], start: values['start-char'], end: values['end-char'], depth: +values.depth, iterations: +values.iterations, save: values.save, compare: null, } } const main = async () => { // cleanup first. since the windows impl works on all platforms, // use that. it's only relevant if the folder exists anyway. rimrafSync(import.meta.dirname + '/fixtures') const data = {} const { save, compare, ...options } = parseOptions() for (const [name, rimraf] of Object.entries(rimrafs)) { if (options.rimraf.includes(name)) { data[name] = await runTest(name, rimraf, options) } } rimrafSync(import.meta.dirname + '/fixtures') const { results, entries } = parse(data, compare) if (save) { const f = `benchmark-${Date.now()}.json` writeFileSync(f, JSON.stringify({ options, results }, 0, 2)) console.log(`results saved to ${f}`) } else { console.log(JSON.stringify(results, null, 2)) } console.table( entries .sort(([, { mean: a }], [, { mean: b }]) => a - b) .reduce((set, [key, val]) => { set[key] = val return set }, {}), ) } main() isaacs-rimraf-4c5e478/benchmark/old-rimraf/000077500000000000000000000000001514446574700206075ustar00rootroot00000000000000isaacs-rimraf-4c5e478/benchmark/old-rimraf/CHANGELOG.md000066400000000000000000000027211514446574700224220ustar00rootroot00000000000000# v3.0 - Add `--preserve-root` option to executable (default true) - Drop support for Node.js below version 6 # v2.7 - Make `glob` an optional dependency # 2.6 - Retry on EBUSY on non-windows platforms as well - Make `rimraf.sync` 10000% more reliable on Windows # 2.5 - Handle Windows EPERM when lstat-ing read-only dirs - Add glob option to pass options to glob # 2.4 - Add EPERM to delay/retry loop - Add `disableGlob` option # 2.3 - Make maxBusyTries and emfileWait configurable - Handle weird SunOS unlink-dir issue - Glob the CLI arg for better Windows support # 2.2 - Handle ENOENT properly on Windows - Allow overriding fs methods - Treat EPERM as indicative of non-empty dir - Remove optional graceful-fs dep - Consistently return null error instead of undefined on success - win32: Treat ENOTEMPTY the same as EBUSY - Add `rimraf` binary # 2.1 - Fix SunOS error code for a non-empty directory - Try rmdir before readdir - Treat EISDIR like EPERM - Remove chmod - Remove lstat polyfill, node 0.7 is not supported # 2.0 - Fix myGid call to check process.getgid - Simplify the EBUSY backoff logic. - Use fs.lstat in node >= 0.7.9 - Remove gently option - remove fiber implementation - Delete files that are marked read-only # 1.0 - Allow ENOENT in sync method - Throw when no callback is provided - Make opts.gently an absolute path - use 'stat' if 'lstat' is not available - Consistent error naming, and rethrow non-ENOENT stat errors - add fiber implementation isaacs-rimraf-4c5e478/benchmark/old-rimraf/LICENSE000066400000000000000000000013751514446574700216220ustar00rootroot00000000000000The ISC License Copyright (c) Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. isaacs-rimraf-4c5e478/benchmark/old-rimraf/README.md000066400000000000000000000070201514446574700220650ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/isaacs/rimraf.svg?branch=master)](https://travis-ci.org/isaacs/rimraf) [![Dependency Status](https://david-dm.org/isaacs/rimraf.svg)](https://david-dm.org/isaacs/rimraf) [![devDependency Status](https://david-dm.org/isaacs/rimraf/dev-status.svg)](https://david-dm.org/isaacs/rimraf#info=devDependencies) The [UNIX command](http://en.wikipedia.org/wiki/Rm_(Unix)) `rm -rf` for node. Install with `npm install rimraf`, or just drop rimraf.js somewhere. ## API `rimraf(f, [opts], callback)` The first parameter will be interpreted as a globbing pattern for files. If you want to disable globbing you can do so with `opts.disableGlob` (defaults to `false`). This might be handy, for instance, if you have filenames that contain globbing wildcard characters. The callback will be called with an error if there is one. Certain errors are handled for you: * Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of `opts.maxBusyTries` times before giving up, adding 100ms of wait between each attempt. The default `maxBusyTries` is 3. * `ENOENT` - If the file doesn't exist, rimraf will return successfully, since your desired outcome is already the case. * `EMFILE` - Since `readdir` requires opening a file descriptor, it's possible to hit `EMFILE` if too many file descriptors are in use. In the sync case, there's nothing to be done for this. But in the async case, rimraf will gradually back off with timeouts up to `opts.emfileWait` ms, which defaults to 1000. ## options * unlink, chmod, stat, lstat, rmdir, readdir, unlinkSync, chmodSync, statSync, lstatSync, rmdirSync, readdirSync In order to use a custom file system library, you can override specific fs functions on the options object. If any of these functions are present on the options object, then the supplied function will be used instead of the default fs method. Sync methods are only relevant for `rimraf.sync()`, of course. For example: ```javascript var myCustomFS = require('some-custom-fs') rimraf('some-thing', myCustomFS, callback) ``` * maxBusyTries If an `EBUSY`, `ENOTEMPTY`, or `EPERM` error code is encountered on Windows systems, then rimraf will retry with a linear backoff wait of 100ms longer on each try. The default maxBusyTries is 3. Only relevant for async usage. * emfileWait If an `EMFILE` error is encountered, then rimraf will retry repeatedly with a linear backoff of 1ms longer on each try, until the timeout counter hits this max. The default limit is 1000. If you repeatedly encounter `EMFILE` errors, then consider using [graceful-fs](http://npm.im/graceful-fs) in your program. Only relevant for async usage. * glob Set to `false` to disable [glob](http://npm.im/glob) pattern matching. Set to an object to pass options to the glob module. The default glob options are `{ nosort: true, silent: true }`. Glob version 6 is used in this module. Relevant for both sync and async usage. * disableGlob Set to any non-falsey value to disable globbing entirely. (Equivalent to setting `glob: false`.) ## rimraf.sync It can remove stuff synchronously, too. But that's not so good. Use the async API. It's better. ## CLI If installed with `npm install rimraf -g` it can be used as a global command `rimraf [ ...]` which is useful for cross platform support. ## mkdirp If you need to create a directory recursively, check out [mkdirp](https://github.com/substack/node-mkdirp). isaacs-rimraf-4c5e478/benchmark/old-rimraf/bin.js000077500000000000000000000035261514446574700217260ustar00rootroot00000000000000#!/usr/bin/env node const rimraf = require('./') const path = require('path') const isRoot = arg => /^(\/|[a-zA-Z]:\\)$/.test(path.resolve(arg)) const filterOutRoot = arg => { const ok = preserveRoot === false || !isRoot(arg) if (!ok) { console.error(`refusing to remove ${arg}`) console.error('Set --no-preserve-root to allow this') } return ok } let help = false let dashdash = false let noglob = false let preserveRoot = true const args = process.argv.slice(2).filter(arg => { if (dashdash) return !!arg else if (arg === '--') dashdash = true else if (arg === '--no-glob' || arg === '-G') noglob = true else if (arg === '--glob' || arg === '-g') noglob = false else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/)) help = true else if (arg === '--preserve-root') preserveRoot = true else if (arg === '--no-preserve-root') preserveRoot = false else return !!arg }).filter(arg => !preserveRoot || filterOutRoot(arg)) const go = n => { if (n >= args.length) return const options = noglob ? { glob: false } : {} rimraf(args[n], options, er => { if (er) throw er go(n+1) }) } if (help || args.length === 0) { // If they didn't ask for help, then this is not a "success" const log = help ? console.log : console.error log('Usage: rimraf [ ...]') log('') log(' Deletes all files and folders at "path" recursively.') log('') log('Options:') log('') log(' -h, --help Display this usage info') log(' -G, --no-glob Do not expand glob patterns in arguments') log(' -g, --glob Expand glob patterns in arguments (default)') log(' --preserve-root Do not remove \'/\' (default)') log(' --no-preserve-root Do not treat \'/\' specially') log(' -- Stop parsing flags') process.exit(help ? 0 : 1) } else go(0) isaacs-rimraf-4c5e478/benchmark/old-rimraf/package.json000066400000000000000000000013311514446574700230730ustar00rootroot00000000000000{ "name": "rimraf", "version": "3.0.2", "main": "rimraf.js", "description": "A deep deletion module for node (like `rm -rf`)", "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "license": "ISC", "repository": "git://github.com/isaacs/rimraf.git", "scripts": { "preversion": "npm test", "postversion": "npm publish", "postpublish": "git push origin --follow-tags", "test": "tap test/*.js" }, "bin": "./bin.js", "dependencies": { "glob": "^7.1.3" }, "files": [ "LICENSE", "README.md", "bin.js", "rimraf.js" ], "devDependencies": { "mkdirp": "^0.5.1", "tap": "^12.1.1" }, "funding": { "url": "https://github.com/sponsors/isaacs" } } isaacs-rimraf-4c5e478/benchmark/old-rimraf/rimraf.js000066400000000000000000000212421514446574700224260ustar00rootroot00000000000000const assert = require("assert") const path = require("path") const fs = require("fs") let glob = undefined try { glob = require("glob") } catch (_err) { // treat glob as optional. } const defaultGlobOpts = { nosort: true, silent: true } // for EMFILE handling let timeout = 0 const isWindows = (process.platform === "win32") const defaults = options => { const methods = [ 'unlink', 'chmod', 'stat', 'lstat', 'rmdir', 'readdir' ] methods.forEach(m => { options[m] = options[m] || fs[m] m = m + 'Sync' options[m] = options[m] || fs[m] }) options.maxBusyTries = options.maxBusyTries || 3 options.emfileWait = options.emfileWait || 1000 if (options.glob === false) { options.disableGlob = true } if (options.disableGlob !== true && glob === undefined) { throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') } options.disableGlob = options.disableGlob || false options.glob = options.glob || defaultGlobOpts } const rimraf = (p, options, cb) => { if (typeof options === 'function') { cb = options options = {} } assert(p, 'rimraf: missing path') assert.equal(typeof p, 'string', 'rimraf: path should be a string') assert.equal(typeof cb, 'function', 'rimraf: callback function required') assert(options, 'rimraf: invalid options argument provided') assert.equal(typeof options, 'object', 'rimraf: options should be object') defaults(options) let busyTries = 0 let errState = null let n = 0 const next = (er) => { errState = errState || er if (--n === 0) cb(errState) } const afterGlob = (er, results) => { if (er) return cb(er) n = results.length if (n === 0) return cb() results.forEach(p => { const CB = (er) => { if (er) { if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && busyTries < options.maxBusyTries) { busyTries ++ // try again, with the same exact callback as this one. return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) } // this one won't happen if graceful-fs is used. if (er.code === "EMFILE" && timeout < options.emfileWait) { return setTimeout(() => rimraf_(p, options, CB), timeout ++) } // already gone if (er.code === "ENOENT") er = null } timeout = 0 next(er) } rimraf_(p, options, CB) }) } if (options.disableGlob || !glob.hasMagic(p)) return afterGlob(null, [p]) options.lstat(p, (er, stat) => { if (!er) return afterGlob(null, [p]) glob(p, options.glob, afterGlob) }) } // Two possible strategies. // 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR // 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR // // Both result in an extra syscall when you guess wrong. However, there // are likely far more normal files in the world than directories. This // is based on the assumption that a the average number of files per // directory is >= 1. // // If anyone ever complains about this, then I guess the strategy could // be made configurable somehow. But until then, YAGNI. const rimraf_ = (p, options, cb) => { assert(p) assert(options) assert(typeof cb === 'function') // sunos lets the root user unlink directories, which is... weird. // so we have to lstat here and make sure it's not a dir. options.lstat(p, (er, st) => { if (er && er.code === "ENOENT") return cb(null) // Windows can EPERM on stat. Life is suffering. if (er && er.code === "EPERM" && isWindows) fixWinEPERM(p, options, er, cb) if (st && st.isDirectory()) return rmdir(p, options, er, cb) options.unlink(p, er => { if (er) { if (er.code === "ENOENT") return cb(null) if (er.code === "EPERM") return (isWindows) ? fixWinEPERM(p, options, er, cb) : rmdir(p, options, er, cb) if (er.code === "EISDIR") return rmdir(p, options, er, cb) } return cb(er) }) }) } const fixWinEPERM = (p, options, er, cb) => { assert(p) assert(options) assert(typeof cb === 'function') options.chmod(p, 0o666, er2 => { if (er2) cb(er2.code === "ENOENT" ? null : er) else options.stat(p, (er3, stats) => { if (er3) cb(er3.code === "ENOENT" ? null : er) else if (stats.isDirectory()) rmdir(p, options, er, cb) else options.unlink(p, cb) }) }) } const fixWinEPERMSync = (p, options, er) => { assert(p) assert(options) try { options.chmodSync(p, 0o666) } catch (er2) { if (er2.code === "ENOENT") return else throw er } let stats try { stats = options.statSync(p) } catch (er3) { if (er3.code === "ENOENT") return else throw er } if (stats.isDirectory()) rmdirSync(p, options, er) else options.unlinkSync(p) } const rmdir = (p, options, originalEr, cb) => { assert(p) assert(options) assert(typeof cb === 'function') // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) // if we guessed wrong, and it's not a directory, then // raise the original error. options.rmdir(p, er => { if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) rmkids(p, options, cb) else if (er && er.code === "ENOTDIR") cb(originalEr) else cb(er) }) } const rmkids = (p, options, cb) => { assert(p) assert(options) assert(typeof cb === 'function') options.readdir(p, (er, files) => { if (er) return cb(er) let n = files.length if (n === 0) return options.rmdir(p, cb) let errState files.forEach(f => { rimraf(path.join(p, f), options, er => { if (errState) return if (er) return cb(errState = er) if (--n === 0) options.rmdir(p, cb) }) }) }) } // this looks simpler, and is strictly *faster*, but will // tie up the JavaScript thread and fail on excessively // deep directory trees. const rimrafSync = (p, options) => { options = options || {} defaults(options) assert(p, 'rimraf: missing path') assert.equal(typeof p, 'string', 'rimraf: path should be a string') assert(options, 'rimraf: missing options') assert.equal(typeof options, 'object', 'rimraf: options should be object') let results if (options.disableGlob || !glob.hasMagic(p)) { results = [p] } else { try { options.lstatSync(p) results = [p] } catch (er) { results = glob.sync(p, options.glob) } } if (!results.length) return for (let i = 0; i < results.length; i++) { const p = results[i] let st try { st = options.lstatSync(p) } catch (er) { if (er.code === "ENOENT") return // Windows can EPERM on stat. Life is suffering. if (er.code === "EPERM" && isWindows) fixWinEPERMSync(p, options, er) } try { // sunos lets the root user unlink directories, which is... weird. if (st && st.isDirectory()) rmdirSync(p, options, null) else options.unlinkSync(p) } catch (er) { if (er.code === "ENOENT") return if (er.code === "EPERM") return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) if (er.code !== "EISDIR") throw er rmdirSync(p, options, er) } } } const rmdirSync = (p, options, originalEr) => { assert(p) assert(options) try { options.rmdirSync(p) } catch (er) { if (er.code === "ENOENT") return if (er.code === "ENOTDIR") throw originalEr if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") rmkidsSync(p, options) } } const rmkidsSync = (p, options) => { assert(p) assert(options) options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) // We only end up here once we got ENOTEMPTY at least once, and // at this point, we are guaranteed to have removed all the kids. // So, we know that it won't be ENOENT or ENOTDIR or anything else. // try really hard to delete stuff on windows, because it has a // PROFOUNDLY annoying habit of not closing handles promptly when // files are deleted, resulting in spurious ENOTEMPTY errors. const retries = isWindows ? 100 : 1 let i = 0 do { let threw = true try { const ret = options.rmdirSync(p, options) threw = false return ret } finally { if (++i < retries && threw) continue } } while (true) } module.exports = rimraf rimraf.sync = rimrafSync isaacs-rimraf-4c5e478/benchmark/parse-results.js000066400000000000000000000032601514446574700217230ustar00rootroot00000000000000const sum = list => list.reduce((a, b) => a + b) const mean = list => sum(list) / list.length const median = list => list.sort()[Math.floor(list.length / 2)] const max = list => list.sort()[list.length - 1] const min = list => list.sort()[0] const sqrt = n => Math.pow(n, 0.5) const variance = list => { const m = mean(list) return mean(list.map(n => Math.pow(n - m, 2))) } const stddev = list => { const v = variance(list) if (isNaN(v)) { throw new Error('wat?', { cause: { list, v } }) } return sqrt(variance(list)) } const comp = (v1, v2) => { if (v1 === undefined) { return {} } return { 'old mean': v1.mean, '% +/-': round(((v2.mean - v1.mean) / v1.mean) * 100), } } const round = n => Math.round(n * 1e3) / 1e3 const nums = list => ({ mean: round(mean(list)), median: round(median(list)), stddev: round(stddev(list)), max: round(max(list)), min: round(min(list)), }) const printEr = er => `${er.code ? er.code + ': ' : ''}${er.message}` const parseResults = (data, compare) => { const results = {} const table = {} for (const [rimrafName, rimrafData] of Object.entries(data)) { results[rimrafName] = {} for (const [runTestName, { times, fails }] of Object.entries(rimrafData)) { const result = nums(times) const failures = fails.map(printEr) results[rimrafName][runTestName] = { ...result, times, failures } table[`${rimrafName} ${runTestName}`] = { ...result, ...comp(compare?.[rimrafName]?.[runTestName], result), ...(failures.length ? { failures: failures.join('\n') } : {}), } } } return { results, entries: Object.entries(table), } } export default parseResults isaacs-rimraf-4c5e478/benchmark/rimrafs.js000066400000000000000000000024351514446574700205600ustar00rootroot00000000000000// just disable the glob option, and promisify it, for apples-to-apples comp import { promisify } from 'util' import { createRequire } from 'module' const oldRimraf = () => { const oldRimraf = createRequire(import.meta.filename)('./old-rimraf') const pOldRimraf = promisify(oldRimraf) const rimraf = path => pOldRimraf(path, { disableGlob: true }) const sync = path => oldRimraf.sync(path, { disableGlob: true }) return Object.assign(rimraf, { sync }) } import { spawn, spawnSync } from 'child_process' const systemRmRf = () => { const rimraf = path => new Promise((res, rej) => { const proc = spawn('rm', ['-rf', path]) proc.on('close', (code, signal) => { if (code || signal) rej(Object.assign(new Error('command failed'), { code, signal })) else res() }) }) rimraf.sync = path => { const result = spawnSync('rm', ['-rf', path]) if (result.status || result.signal) { throw Object.assign(new Error('command failed'), { code: result.status, signal: result.signal, }) } } return rimraf } import { native, posix, windows } from 'rimraf' const cases = { native, posix, windows, old: oldRimraf(), system: systemRmRf(), } export const names = new Set(Object.keys(cases)) export default cases isaacs-rimraf-4c5e478/benchmark/run-test.js000066400000000000000000000067161514446574700207040ustar00rootroot00000000000000import create from './create-fixture.js' const TESTS = { sync: 'sync', async: 'async', parallel: 'parallel', } const hrToMS = hr => Math.round(hr[0] * 1e9 + hr[1]) / 1e6 const runTest = async ( type, rimraf, { runTest: cases, start, end, depth, iterations }, ) => { console.error(`\nrunning test for ${type}, %j`, { start, end, depth, iterations, }) // first, create all fixtures const syncPaths = [] const asyncPaths = [] const paraPaths = [] process.stderr.write('creating fixtures') for (let i = 0; i < iterations; i++) { const [syncPath, asyncPath, paraPath] = await Promise.all([ cases.includes(TESTS.sync) ? create({ name: `${type}/sync/${i}`, start, end, depth }) : null, cases.includes(TESTS.async) ? create({ name: `${type}/async/${i}`, start, end, depth }) : null, cases.includes(TESTS.parallel) ? create({ name: `${type}/para/${i}`, start, end, depth }) : null, ]) syncPath && syncPaths.push(syncPath) asyncPath && asyncPaths.push(asyncPath) paraPath && paraPaths.push(paraPath) process.stderr.write('.') } process.stderr.write('done!\n') const syncTimes = [] const syncFails = [] if (syncPaths.length) { process.stderr.write('running sync tests') const startSync = process.hrtime() for (const path of syncPaths) { const start = process.hrtime() try { rimraf.sync(path) syncTimes.push(hrToMS(process.hrtime(start))) } catch (er) { syncFails.push(er) } process.stderr.write('.') } const syncTotal = hrToMS(process.hrtime(startSync)) console.error('done! (%j ms, %j failed)', syncTotal, syncFails.length) } const asyncTimes = [] const asyncFails = [] if (asyncPaths.length) { process.stderr.write('running async tests') const startAsync = process.hrtime() for (const path of asyncPaths) { const start = process.hrtime() await rimraf(path).then( () => asyncTimes.push(hrToMS(process.hrtime(start))), er => asyncFails.push(er), ) process.stderr.write('.') } const asyncTotal = hrToMS(process.hrtime(startAsync)) console.error('done! (%j ms, %j failed)', asyncTotal, asyncFails.length) } const paraTimes = [] const paraFails = [] if (paraPaths.length) { process.stderr.write('running parallel tests') const startPara = process.hrtime() const paraRuns = [] for (const path of paraPaths) { process.stderr.write('.') const start = process.hrtime() paraRuns.push( rimraf(path).then( () => paraTimes.push(hrToMS(process.hrtime(start))), er => paraFails.push(er), ), ) } await Promise.all(paraRuns) const paraTotal = hrToMS(process.hrtime(startPara)) console.error('done! (%j ms, %j failed)', paraTotal, paraFails.length) } process.stderr.write('\n') // wait a tick to let stderr to clear return Promise.resolve().then(() => ({ ...(syncPaths.length ? { sync: { times: syncTimes, fails: syncFails, }, } : {}), ...(asyncPaths.length ? { async: { times: asyncTimes, fails: asyncFails, }, } : {}), ...(paraPaths.length ? { parallel: { times: paraTimes, fails: paraFails, }, } : {}), })) } export const names = new Set(Object.values(TESTS)) export default runTest isaacs-rimraf-4c5e478/map.js000066400000000000000000000002731514446574700157360ustar00rootroot00000000000000export default test => test.startsWith('/test/integration/') ? null : ( (test.endsWith('/bin.ts') ? test.replace(/\.ts$/, '.mts') : test ).replace(/^test/, 'src') ) isaacs-rimraf-4c5e478/package-lock.json000066400000000000000000004630121514446574700200430ustar00rootroot00000000000000{ "name": "rimraf", "version": "6.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rimraf", "version": "6.1.3", "license": "BlueOak-1.0.0", "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" }, "devDependencies": { "@types/node": "^25.2.0", "mkdirp": "^3.0.1", "prettier": "^3.6.2", "tap": "^21.1.1", "tshy": "^3.0.3", "typedoc": "^0.28.14" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@alcalzone/ansi-tokenize": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.1.3.tgz", "integrity": "sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^4.0.0" }, "engines": { "node": ">=14.13.1" } }, "node_modules/@base2/pretty-print-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz", "integrity": "sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, "engines": { "node": ">=12" } }, "node_modules/@gerrit0/mini-shiki": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.22.0.tgz", "integrity": "sha512-jMpciqEVUBKE1QwU64S4saNMzpsSza6diNCk4MWAeCxO2+LFi2FIFmL2S0VDLzEJCxuvCbU783xi8Hp/gkM5CQ==", "dev": true, "license": "MIT", "dependencies": { "@shikijs/engine-oniguruma": "^3.22.0", "@shikijs/langs": "^3.22.0", "@shikijs/themes": "^3.22.0", "@shikijs/types": "^3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@isaacs/cliui": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, "license": "ISC", "dependencies": { "minipass": "^7.0.4" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@isaacs/ts-node-temp-fork-for-pr-2009": { "version": "10.9.7", "resolved": "https://registry.npmjs.org/@isaacs/ts-node-temp-fork-for-pr-2009/-/ts-node-temp-fork-for-pr-2009-10.9.7.tgz", "integrity": "sha512-9f0bhUr9TnwwpgUhEpr3FjxSaH/OHaARkE2F9fM0lS4nIs2GNerrvGwQz493dk0JKlTaGYVrKbq36vA/whZ34g==", "dev": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node14": "*", "@tsconfig/node16": "*", "@tsconfig/node18": "*", "@tsconfig/node20": "*", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1" }, "bin": { "ts-node": "dist/bin.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=4.2" }, "peerDependenciesMeta": { "@swc/core": { "optional": true }, "@swc/wasm": { "optional": true } } }, "node_modules/@isaacs/ts-node-temp-fork-for-pr-2009/node_modules/diff": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" } }, "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, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "node_modules/@npmcli/agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", "dev": true, "license": "ISC", "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^11.2.1", "socks-proxy-agent": "^8.0.3" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/fs": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", "dev": true, "license": "ISC", "dependencies": { "semver": "^7.3.5" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/git": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", "dev": true, "license": "ISC", "dependencies": { "@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": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/git/node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/@npmcli/git/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/installed-package-contents": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", "dev": true, "license": "ISC", "dependencies": { "npm-bundled": "^5.0.0", "npm-normalize-package-bin": "^5.0.0" }, "bin": { "installed-package-contents": "bin/index.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/node-gyp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/package-json": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.4.tgz", "integrity": "sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==", "dev": true, "license": "ISC", "dependencies": { "@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", "validate-npm-package-license": "^3.0.4" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/promise-spawn": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", "dev": true, "license": "ISC", "dependencies": { "which": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/promise-spawn/node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/@npmcli/promise-spawn/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/redact": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/run-script": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", "dev": true, "license": "ISC", "dependencies": { "@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": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/run-script/node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/@npmcli/run-script/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/@shikijs/engine-oniguruma": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.22.0.tgz", "integrity": "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==", "dev": true, "license": "MIT", "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@shikijs/langs": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.22.0.tgz", "integrity": "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==", "dev": true, "license": "MIT", "dependencies": { "@shikijs/types": "3.22.0" } }, "node_modules/@shikijs/themes": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.22.0.tgz", "integrity": "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==", "dev": true, "license": "MIT", "dependencies": { "@shikijs/types": "3.22.0" } }, "node_modules/@shikijs/types": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.22.0.tgz", "integrity": "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==", "dev": true, "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "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/@sigstore/bundle": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", "dev": true, "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@sigstore/core": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.1.0.tgz", "integrity": "sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==", "dev": true, "license": "Apache-2.0", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@sigstore/protobuf-specs": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.0.tgz", "integrity": "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==", "dev": true, "license": "Apache-2.0", "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/@sigstore/sign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.0.tgz", "integrity": "sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@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": "^20.17.0 || >=22.9.0" } }, "node_modules/@sigstore/tuf": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.1.tgz", "integrity": "sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@sigstore/verify": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", "dev": true, "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@tapjs/after": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@tapjs/after/-/after-3.3.1.tgz", "integrity": "sha512-/RZb0DZxfHP74ursSByTpgKU6jVUtNOtoQ3/prf76+5+G7Q7D7QIQtlrH3bUgk84DI89j+4Nc2DTkMCOLy7BWQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "is-actual-promise": "^1.0.1" }, "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/after-each": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/after-each/-/after-each-4.3.1.tgz", "integrity": "sha512-kgRbmhKisIl31FsCxFkDmZLNj0qCdNte0aarVLsaFq1LVJOtpITdBfnuiKigrLj4Go9XiASmIpGrU8h1uYF2Xw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "function-loop": "^4.0.0" }, "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/asserts": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/asserts/-/asserts-4.3.1.tgz", "integrity": "sha512-PyBE1/umvg/o9Ntg3gryWaamCFHhMV0zSdoD6n5saexa8AYUb9XM6XA4y7uXRisdSFVVnD8/yX0OAWsQhryE0g==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/stack": "4.3.0", "is-actual-promise": "^1.0.1", "tcompare": "9.3.0", "trivial-deferred": "^2.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/before": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/before/-/before-4.3.1.tgz", "integrity": "sha512-zxa+DrruCGJhTQCLjYa8nfyYihLsWBWCEgiSvtwOkQKNZhxcaLmH/W85zEWKJ+MnZaa4wVqkyyRkhAM12eq0Lg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "is-actual-promise": "^1.0.1" }, "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/before-each": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/before-each/-/before-each-4.3.1.tgz", "integrity": "sha512-vPCbni80H7/6JtQY2LoO4kiRmuyOwPJXpgR2SRrH9Aq07EVveSlgMkKJxomkbuE5lGr/l6zhO/TZDPnuorSvrg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "function-loop": "^4.0.0" }, "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/chdir": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@tapjs/chdir/-/chdir-3.3.1.tgz", "integrity": "sha512-8awqiQswpJRtlOdag+wV/ezuX1kv9YKiG3DAKcNVr7exkGr61StL7qV1cdHah2rPAXlJv6blgDIYbR80d3s9qA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/config": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/@tapjs/config/-/config-5.4.1.tgz", "integrity": "sha512-ZK1Zs58ALGWx6Zxd0fDlN9VlGNxoudpXZqjlr2asC/Zu6v5oyilN9CX2r9PWHyTHNe6b/TpfpOvt2gTCTpuROA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/core": "4.4.1", "@tapjs/test": "4.3.1", "chalk": "^5.6.2", "jackspeak": "^4.1.2", "polite-json": "^5.0.0", "tap-yaml": "4.3.0", "walk-up-path": "^4.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1", "@tapjs/test": "4.3.1" } }, "node_modules/@tapjs/core": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@tapjs/core/-/core-4.4.1.tgz", "integrity": "sha512-zEeDgt6YNOKXs4NfGGZ1Lz5aLTlHNCUpwvx5hVl7CuL+/noudWZvL39Vy2rKb+zZnTSgF7b34DqGLoy8+jgpfg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/processinfo": "^3.1.9", "@tapjs/stack": "4.3.0", "@tapjs/test": "4.3.1", "async-hook-domain": "^4.0.1", "diff": "^8.0.2", "is-actual-promise": "^1.0.1", "minipass": "^7.0.4", "signal-exit": "4.1", "tap-parser": "18.3.0", "tap-yaml": "4.3.0", "tcompare": "9.3.0", "trivial-deferred": "^2.0.0" }, "engines": { "node": "20 || >=22" } }, "node_modules/@tapjs/error-serdes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@tapjs/error-serdes/-/error-serdes-4.3.0.tgz", "integrity": "sha512-qP266uvPm2G95ClPFpqAN6n4nicLbHrZYbZWl0UO+biOdmvjSSuxeY5f7YFygTl+UuzlyxjlRgHTq8qifnqTcw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "minipass": "^7.0.4" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@tapjs/filter": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/filter/-/filter-4.3.1.tgz", "integrity": "sha512-oyoqmUcHjYvr5f7LOryVB9ruEtjTiABdwZghx3XgeRnaNiVX3J9J8/xvdctnkbDB7cq3g9Ao2DYzweDl6Zfvhg==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/fixture": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/fixture/-/fixture-4.3.1.tgz", "integrity": "sha512-x3w6Ro4H6UAxNSkDTtmz73kVCjZP4TNY2m+wLLiRdi8fa3lCn7WfvHUn9zoATgRFjgOnG4XrXSkjybhqHZ4Ibw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "mkdirp": "^3.0.0", "rimraf": "^6.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/intercept": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/intercept/-/intercept-4.3.1.tgz", "integrity": "sha512-AvfZwFqAh8g+226HRVMUwoHm1ncf6xMHRQfcsPPIMtjnIrbJZjr2S2uM9qTWTnlk2EVgerqfyh3H8R6ykJsGIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/after": "3.3.1", "@tapjs/stack": "4.3.0" }, "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/mock": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/mock/-/mock-4.3.1.tgz", "integrity": "sha512-oiR34RhC0+h0fqLNHkDA5QmQXmVJkujvdGwUEBxR3HzUIKZWp5SfVw4dY2/Lvl33tPBOtsFDFuqnpt3+f6SrXg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/after": "3.3.1", "@tapjs/stack": "4.3.0", "resolve-import": "^2.1.1", "walk-up-path": "^4.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/node-serialize": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/node-serialize/-/node-serialize-4.3.1.tgz", "integrity": "sha512-dOsTr75HFESskVvuv8L6SAw23c2WtF6aoNkaD9SwtbTQZxvZQNGMechWPWYGaMsHB+aB+6EBg1MVnqWHQrOVcw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/error-serdes": "4.3.0", "@tapjs/stack": "4.3.0", "tap-parser": "18.3.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/processinfo": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/@tapjs/processinfo/-/processinfo-3.1.9.tgz", "integrity": "sha512-yIbYH9ROI5m5F2B5Hpk6t89OkHBrDbL3qncPO9OfPuSvJsvAIDG91I0hxGQNohdaxmqz5L4QiIYc5Y0KmtLzCQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "node-options-to-argv": "^1.0.0", "pirates": "^4.0.5", "process-on-spawn": "^1.0.0", "signal-exit": "^4.0.2", "uuid": "^8.3.2" }, "engines": { "node": ">=16.17" } }, "node_modules/@tapjs/reporter": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@tapjs/reporter/-/reporter-4.4.1.tgz", "integrity": "sha512-kOppWVcv3sa0fmsBrpzwJiUZbwEdhixBAg0J39dUDMDdNIYrefVUSJsi7f1Agi9uRRXeJfZlUw23tII4CV06rQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/config": "5.4.1", "@tapjs/stack": "4.3.0", "chalk": "^5.6.2", "ink": "^5.2.1", "minipass": "^7.0.4", "ms": "^2.1.3", "patch-console": "^2.0.0", "prismjs-terminal": "^1.2.3", "react": "^18.2.0", "string-length": "^6.0.0", "tap-parser": "18.3.0", "tap-yaml": "4.3.0", "tcompare": "9.3.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/run": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@tapjs/run/-/run-4.4.1.tgz", "integrity": "sha512-mVD9FCknr1mkkCv1vMKL2x4pmpka8ArqHufMP8Mb3Etj6blfePNv0Mu75RWVN9bKYzKAkqPGLenDBPb9hnbUgg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/after": "3.3.1", "@tapjs/before": "4.3.1", "@tapjs/config": "5.4.1", "@tapjs/processinfo": "^3.1.9", "@tapjs/reporter": "4.4.1", "@tapjs/spawn": "4.3.1", "@tapjs/stdin": "4.3.1", "@tapjs/test": "4.3.1", "c8": "^10.1.3", "chalk": "^5.6.2", "chokidar": "^4.0.2", "foreground-child": "^4.0.0", "glob": "^13.0.0", "minipass": "^7.0.4", "mkdirp": "^3.0.1", "node-options-to-argv": "^1.0.0", "opener": "^1.5.2", "pacote": "^21.0.4", "path-scurry": "^2.0.0", "resolve-import": "^2.0.0", "rimraf": "^6.0.0", "semver": "^7.7.2", "signal-exit": "^4.1.0", "tap-parser": "18.3.0", "tap-yaml": "4.3.0", "tcompare": "9.3.0", "trivial-deferred": "^2.0.0", "which": "^5.0.0" }, "bin": { "tap-run": "dist/esm/index.js" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/snapshot": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/snapshot/-/snapshot-4.3.1.tgz", "integrity": "sha512-xPE5yxnck9EhpbH2i60xIB9HxgG39wSyn6Hj+UQal/lDgprbdYNG+36Owdp52TNHOL14GcVO3aiqyOy4UdkN6A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "is-actual-promise": "^1.0.1", "tcompare": "9.3.0", "trivial-deferred": "^2.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/spawn": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/spawn/-/spawn-4.3.1.tgz", "integrity": "sha512-bQ5Mb0F8Vm07TDe3DYFEzuIN1aCbRyFPYjM6cD62iszT0B4znaXL4PseRXB0VoL9cxJICeNm6AiT0G9PF09z4Q==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/stack": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@tapjs/stack/-/stack-4.3.0.tgz", "integrity": "sha512-SFASe4YaVBzMr/FXTm/QsSzbzXZOmgDNpmY3EU0JNiDCN4izHMUnoXY+Kh0EY35hx9C4JDvRjgv2MSIM7bBygg==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@tapjs/stdin": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/stdin/-/stdin-4.3.1.tgz", "integrity": "sha512-wD4bJM+1LmnDkBpR7aLJ6tlwDM/OT0RaiHPFgRrpDv7FB50LeR3h9wh7s+c+Ysc9OgZDkLNLkvG9jIhb937bZA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/test": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/test/-/test-4.3.1.tgz", "integrity": "sha512-NOsYB1VhaSPmWqrvsdeVnUuklNtJwFEQnybPHjVCqq0ecjP/SZKW+nnVzt9ISAPF+FDtQisqgJV2/Y54jzhpgA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/ts-node-temp-fork-for-pr-2009": "^10.9.7", "@tapjs/after": "3.3.1", "@tapjs/after-each": "4.3.1", "@tapjs/asserts": "4.3.1", "@tapjs/before": "4.3.1", "@tapjs/before-each": "4.3.1", "@tapjs/chdir": "3.3.1", "@tapjs/filter": "4.3.1", "@tapjs/fixture": "4.3.1", "@tapjs/intercept": "4.3.1", "@tapjs/mock": "4.3.1", "@tapjs/node-serialize": "4.3.1", "@tapjs/snapshot": "4.3.1", "@tapjs/spawn": "4.3.1", "@tapjs/stdin": "4.3.1", "@tapjs/typescript": "3.5.1", "@tapjs/worker": "4.3.1", "glob": "^13.0.0", "jackspeak": "^4.1.2", "mkdirp": "^3.0.0", "package-json-from-dist": "^1.0.0", "resolve-import": "^2.1.1", "rimraf": "^6.0.0", "sync-content": "^2.0.1", "tap-parser": "18.3.0", "tshy": "^3.1.3", "typescript": "5.9", "walk-up-path": "^4.0.0" }, "bin": { "generate-tap-test-class": "dist/esm/build.mjs" }, "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/typescript": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/@tapjs/typescript/-/typescript-3.5.1.tgz", "integrity": "sha512-4clGpzF1OTjLZYlavI167rCseSVsLpd5ygBAf297o468VEtpRAJPYx1IjoPrnGWC/M5iJadsCrTlIuBYABw81g==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/ts-node-temp-fork-for-pr-2009": "^10.9.7" }, "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tapjs/worker": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@tapjs/worker/-/worker-4.3.1.tgz", "integrity": "sha512-RInbFaGUH+KsAl/ozRVCMhpXaQPsvwEQ7PiKprpXgKjxjUrzwlkAbFAxo4K79axCWWdm6JUD5pH93n0FJ75jYQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" }, "peerDependencies": { "@tapjs/core": "4.4.1" } }, "node_modules/@tsconfig/node14": { "version": "14.1.8", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-14.1.8.tgz", "integrity": "sha512-SjGT+qPvh8Uhc849yNMD0ZIPr69AyB7Z46nMqhrI3gCVocd6mhI0jP4YE4onO/ufpmengRfTxNMpdpKEp2xRIg==", "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "16.1.8", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-16.1.8.tgz", "integrity": "sha512-T/CfdwFry660WjZor56z0F3pxeCllt8KOxWcHFW6ZEuULKUObTDEMdgtctyuJPxwqyWDsvHRfxHaJ4FIICyoqQ==", "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node18": { "version": "18.2.6", "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.6.tgz", "integrity": "sha512-eAWQzAjPj18tKnDzmWstz4OyWewLUNBm9tdoN9LayzoboRktYx3Enk1ZXPmThj55L7c4VWYq/Bzq0A51znZfhw==", "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node20": { "version": "20.1.9", "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.9.tgz", "integrity": "sha512-IjlTv1RsvnPtUcjTqtVsZExKVq+KQx4g5pCP5tI7rAs6Xesl2qFwSz/tPDBC4JajkL/MlezBu3gPUwqRHl+RIg==", "dev": true, "license": "MIT" }, "node_modules/@tufjs/canonical-json": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", "dev": true, "license": "MIT", "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/@tufjs/models": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", "dev": true, "license": "MIT", "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^10.1.1" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@types/hast": { "version": "3.0.4", "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": "*" } }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { "version": "25.2.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~7.16.0" } }, "node_modules/@types/unist": { "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/abbrev": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-walk": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" }, "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { "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, "license": "MIT", "engines": { "node": ">= 14" } }, "node_modules/ansi-escapes": { "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" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/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/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true, "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/async-hook-domain": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-4.0.1.tgz", "integrity": "sha512-bSktexGodAjfHWIrSrrqxqWzf1hWBZBpmPNZv+TYUMyWa2eoefFc6q6H1+KtdHYSz35lrhWdmXt/XK9wNEZvww==", "dev": true, "license": "ISC", "engines": { "node": ">=16" } }, "node_modules/auto-bind": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", "dev": true, "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/balanced-match": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "license": "MIT", "dependencies": { "jackspeak": "^4.2.3" }, "engines": { "node": "20 || >=22" } }, "node_modules/brace-expansion": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { "node": "20 || >=22" } }, "node_modules/c8": { "version": "10.1.3", "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz", "integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==", "dev": true, "license": "ISC", "dependencies": { "@bcoe/v8-coverage": "^1.0.1", "@istanbuljs/schema": "^0.1.3", "find-up": "^5.0.0", "foreground-child": "^3.1.1", "istanbul-lib-coverage": "^3.2.0", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.1.6", "test-exclude": "^7.0.1", "v8-to-istanbul": "^9.0.0", "yargs": "^17.7.2", "yargs-parser": "^21.1.1" }, "bin": { "c8": "bin/c8.js" }, "engines": { "node": ">=18" }, "peerDependencies": { "monocart-coverage-reports": "^2" }, "peerDependenciesMeta": { "monocart-coverage-reports": { "optional": true } } }, "node_modules/c8/node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/cacache": { "version": "20.0.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", "dev": true, "license": "ISC", "dependencies": { "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", "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": "^7.0.2", "ssri": "^13.0.0", "unique-filename": "^5.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, "engines": { "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, "node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } }, "node_modules/cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^4.0.0" }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-truncate": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", "dev": true, "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-truncate/node_modules/slice-ansi": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/cliui/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/code-excerpt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", "dev": true, "license": "MIT", "dependencies": { "convert-to-spaces": "^2.0.1" }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/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/convert-to-spaces": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", "dev": true, "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/cross-spawn/node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/diff": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, "license": "MIT" }, "node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "iconv-lite": "^0.6.2" } }, "node_modules/entities": { "version": "4.5.0", "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" }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "dev": true, "license": "MIT" }, "node_modules/es-toolkit": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.44.0.tgz", "integrity": "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==", "dev": true, "license": "MIT", "workspaces": [ "docs", "benchmarks" ] }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/events-to-array": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-2.0.3.tgz", "integrity": "sha512-f/qE2gImHRa4Cp2y1stEOSgw8wTFyUdVJX7G//bMwbaV9JqISFxg99NbmVQeP7YLnDUZ2un851jlaDrlpmGehQ==", "dev": true, "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/exponential-backoff": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "dev": true, "license": "Apache-2.0" }, "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/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/foreground-child": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-4.0.3.tgz", "integrity": "sha512-yeXZaNbCBGaT9giTpLPBdtedzjwhlJBUoL/R4BVQU5mn0TQXOHwVIl1Q2DMuBIdNno4ktA1abZ7dQFVxD6uHxw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "signal-exit": "^4.0.1" }, "engines": { "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "license": "MIT" }, "node_modules/fs-minipass": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/function-loop": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-4.0.0.tgz", "integrity": "sha512-f34iQBedYF3XcI93uewZZOnyscDragxgTK/eTvVB74k3fCD0ZorOi5BV9GS4M8rz/JoNi0Kl3qX5Y9MH3S/CLQ==", "dev": true, "license": "ISC" }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-east-asian-width": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, "license": "MIT", "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/glob": { "version": "13.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.3.tgz", "integrity": "sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==", "license": "BlueOak-1.0.0", "dependencies": { "minimatch": "^10.2.0", "minipass": "^7.1.2", "path-scurry": "^2.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "license": "ISC" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/hosted-git-info": { "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": "^11.1.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, "license": "MIT" }, "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/http-proxy-agent": { "version": "7.0.2", "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" }, "engines": { "node": ">= 14" } }, "node_modules/https-proxy-agent": { "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.1.2", "debug": "4" }, "engines": { "node": ">= 14" } }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ignore-walk": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", "dev": true, "license": "ISC", "dependencies": { "minimatch": "^10.0.3" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/indent-string": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ini": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/ink": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ink/-/ink-5.2.1.tgz", "integrity": "sha512-BqcUyWrG9zq5HIwW6JcfFHsIYebJkWWb4fczNah1goUO0vv5vneIlfwuS85twyJ5hYR/y18FlAYUxrO9ChIWVg==", "dev": true, "license": "MIT", "dependencies": { "@alcalzone/ansi-tokenize": "^0.1.3", "ansi-escapes": "^7.0.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^4.0.0", "code-excerpt": "^4.0.0", "es-toolkit": "^1.22.0", "indent-string": "^5.0.0", "is-in-ci": "^1.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.29.0", "scheduler": "^0.23.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^7.2.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "engines": { "node": ">=18" }, "peerDependencies": { "@types/react": ">=18.0.0", "react": ">=18.0.0", "react-devtools-core": "^4.19.1" }, "peerDependenciesMeta": { "@types/react": { "optional": true }, "react-devtools-core": { "optional": true } } }, "node_modules/ink/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, "license": "ISC" }, "node_modules/ip-address": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "dev": true, "license": "MIT", "engines": { "node": ">= 12" } }, "node_modules/is-actual-promise": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-actual-promise/-/is-actual-promise-1.0.2.tgz", "integrity": "sha512-xsFiO1of0CLsQnPZ1iXHNTyR9YszOeWKYv+q6n8oSFW3ipooFJ1j1lbRMgiMCr+pp2gLruESI4zb5Ak6eK5OnQ==", "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-in-ci": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-1.0.0.tgz", "integrity": "sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==", "dev": true, "license": "MIT", "bin": { "is-in-ci": "cli.js" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/isexe": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" } }, "node_modules/istanbul-reports": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/jackspeak": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^9.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", "dev": true, "license": "MIT", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/jsonc-simple-parser": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/jsonc-simple-parser/-/jsonc-simple-parser-3.0.0.tgz", "integrity": "sha512-0qi9Kuj4JPar4/3b9wZteuPZrTeFzXsQyOZj7hksnReCZN3Vr17Doz7w/i3E9XH7vRkVTHhHES+r1h97I+hfww==", "dev": true, "dependencies": { "reghex": "^3.0.2" } }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, "engines": [ "node >= 0.2.0" ], "license": "MIT" }, "node_modules/linkify-it": { "version": "5.0.0", "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" } }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "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==", "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", "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true, "license": "MIT" }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true, "license": "ISC" }, "node_modules/make-fetch-happen": { "version": "15.0.3", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", "dev": true, "license": "ISC", "dependencies": { "@npmcli/agent": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "promise-retry": "^2.0.1", "ssri": "^13.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/markdown-it": { "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", "linkify-it": "^5.0.0", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true, "license": "MIT" }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/minimatch": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/minipass-collect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/minipass-fetch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.1.tgz", "integrity": "sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw==", "dev": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "engines": { "node": "^20.17.0 || >=22.9.0" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "node_modules/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, "engines": { "node": ">= 8" } }, "node_modules/minipass-flush/node_modules/minipass": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/minipass-flush/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, "license": "ISC" }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/minipass-pipeline/node_modules/minipass": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/minipass-pipeline/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, "license": "ISC" }, "node_modules/minipass-sized": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", "dev": true, "license": "ISC", "dependencies": { "minipass": "^7.1.2" }, "engines": { "node": ">=8" } }, "node_modules/minizlib": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, "license": "MIT", "dependencies": { "minipass": "^7.1.2" }, "engines": { "node": ">= 18" } }, "node_modules/mkdirp": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true, "license": "MIT", "bin": { "mkdirp": "dist/cjs/src/bin.js" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/node-gyp": { "version": "12.2.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.2.0.tgz", "integrity": "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==", "dev": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", "which": "^6.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/node-gyp/node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/node-gyp/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/node-options-to-argv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-options-to-argv/-/node-options-to-argv-1.0.0.tgz", "integrity": "sha512-99rLlP+Cn/FsSV9kjpk2UmF2Ltmrpv/L9U7fUfws/MVXkeZWPpPDsQkMr79qCvSF/oTKVVJBTm5sHzmK2j6IIg==", "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/nopt": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", "dev": true, "license": "ISC", "dependencies": { "abbrev": "^4.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-bundled": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", "dev": true, "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^5.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-install-checks": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "semver": "^7.1.1" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-normalize-package-bin": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-package-arg": { "version": "13.0.2", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.2.tgz", "integrity": "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==", "dev": true, "license": "ISC", "dependencies": { "hosted-git-info": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^7.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-packlist": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", "dev": true, "license": "ISC", "dependencies": { "ignore-walk": "^8.0.0", "proc-log": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-pick-manifest": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", "dev": true, "license": "ISC", "dependencies": { "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": "^20.17.0 || >=22.9.0" } }, "node_modules/npm-registry-fetch": { "version": "19.1.1", "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", "dev": true, "license": "ISC", "dependencies": { "@npmcli/redact": "^4.0.0", "jsonparse": "^1.3.1", "make-fetch-happen": "^15.0.0", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minizlib": "^3.0.1", "npm-package-arg": "^13.0.0", "proc-log": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true, "license": "(WTFPL OR MIT)", "bin": { "opener": "bin/opener-bin.js" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { "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" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, "node_modules/pacote": { "version": "21.3.1", "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.3.1.tgz", "integrity": "sha512-O0EDXi85LF4AzdjG74GUwEArhdvawi/YOHcsW6IijKNj7wm8IvEWNF5GnfuxNpQ/ZpO3L37+v8hqdVh8GgWYhg==", "dev": true, "license": "ISC", "dependencies": { "@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": "^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": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" }, "bin": { "pacote": "bin/index.js" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/patch-console": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", "dev": true, "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-scurry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "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/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/polite-json": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/polite-json/-/polite-json-5.0.0.tgz", "integrity": "sha512-OLS/0XeUAcE8a2fdwemNja+udKgXNnY6yKVIXqAD2zVRx1KvY6Ato/rZ2vdzbxqYwPW0u6SCNC/bAMPNzpzxbw==", "dev": true, "license": "MIT", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/prettier": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prismjs": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/prismjs-terminal": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/prismjs-terminal/-/prismjs-terminal-1.2.4.tgz", "integrity": "sha512-S2nsjy6s2x2jF4uTW8ulX19rvmRfe9R1wmnNwI5wmBgQEErB0vuKueVPMzN6KsFRCCJ2IQrWUS0BqhcNsrR9xg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "chalk": "^5.2.0", "prismjs": "^1.30.0", "string-length": "^6.0.0" }, "engines": { "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/process-on-spawn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.1.0.tgz", "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==", "dev": true, "license": "MIT", "dependencies": { "fromentries": "^1.2.0" }, "engines": { "node": ">=8" } }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, "license": "MIT", "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" }, "engines": { "node": ">=10" } }, "node_modules/punycode.js": { "version": "2.3.1", "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" } }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "node_modules/react-element-to-jsx-string": { "version": "15.0.0", "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz", "integrity": "sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==", "dev": true, "license": "MIT", "dependencies": { "@base2/pretty-print-object": "1.0.1", "is-plain-object": "5.0.0", "react-is": "18.1.0" }, "peerDependencies": { "react": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", "react-dom": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0" } }, "node_modules/react-is": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", "dev": true, "license": "MIT" }, "node_modules/react-reconciler": { "version": "0.29.2", "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz", "integrity": "sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==", "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { "react": "^18.3.1" } }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", "engines": { "node": ">= 14.18.0" }, "funding": { "type": "individual", "url": "https://paulmillr.com/funding/" } }, "node_modules/reghex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/reghex/-/reghex-3.0.2.tgz", "integrity": "sha512-Zb9DJ5u6GhgqRSBnxV2QSnLqEwcKxHWFA1N2yUa4ZUAO1P8jlWKYtWZ6/ooV6yylspGXJX0O/uNzEv0xrCtwaA==", "dev": true, "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve-import": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/resolve-import/-/resolve-import-2.1.1.tgz", "integrity": "sha512-pgTo41KMWjSZNNA4Ptgs+AtB+/w+a2/MDm6VzZiEnt2op2rXHYK/EYdRYhBsPlGN1naYMogJopBoJxtHgGTHEA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "glob": "^13.0.0", "walk-up-path": "^4.0.0" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/restore-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/restore-cursor/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, "license": "ISC" }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/rimraf": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "glob": "^13.0.0", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "license": "MIT", "optional": true }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/sigstore": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@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": "^20.17.0 || >=22.9.0" } }, "node_modules/slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, "license": "MIT", "dependencies": { "get-east-asian-width": "^1.3.1" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks": { "version": "2.8.7", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "dev": true, "license": "MIT", "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "engines": { "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks-proxy-agent": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, "engines": { "node": ">= 14" } }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { "version": "3.0.22", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", "dev": true, "license": "CC0-1.0" }, "node_modules/ssri": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", "dev": true, "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, "engines": { "node": ">=10" } }, "node_modules/string-length": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz", "integrity": "sha512-1U361pxZHEQ+FeSjzqRpV+cu2vTzYeWeafXFLykiFlv4Vc0n3njgU8HrMbyik5uwm77naWMuVG8fhEF+Ovb1Kg==", "dev": true, "license": "MIT", "dependencies": { "strip-ansi": "^7.1.0" }, "engines": { "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/string-width-cjs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/sync-content": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/sync-content/-/sync-content-2.0.4.tgz", "integrity": "sha512-w3ioiBmbaogob33WdLnuwFk+8tpePI58CTWKqtdAgEqc2hfGuSwP02gPETqNX/3PLS5skv5a1wQR0gbaa2W0XQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "glob": "^13.0.1", "mkdirp": "^3.0.1", "path-scurry": "^2.0.0", "rimraf": "^6.0.0" }, "bin": { "sync-content": "dist/esm/bin.mjs" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/tap": { "version": "21.5.1", "resolved": "https://registry.npmjs.org/tap/-/tap-21.5.1.tgz", "integrity": "sha512-uhS20sTR4Q+/T2ovawxgVLjdsTQuU+xFz9htRwlx5jwkaWiv+1xes/0ZW5IlO+hlQp9iQH3rj30FNRlnN2ZVtw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@tapjs/after": "3.3.1", "@tapjs/after-each": "4.3.1", "@tapjs/asserts": "4.3.1", "@tapjs/before": "4.3.1", "@tapjs/before-each": "4.3.1", "@tapjs/chdir": "3.3.1", "@tapjs/core": "4.4.1", "@tapjs/filter": "4.3.1", "@tapjs/fixture": "4.3.1", "@tapjs/intercept": "4.3.1", "@tapjs/mock": "4.3.1", "@tapjs/node-serialize": "4.3.1", "@tapjs/run": "4.4.1", "@tapjs/snapshot": "4.3.1", "@tapjs/spawn": "4.3.1", "@tapjs/stdin": "4.3.1", "@tapjs/test": "4.3.1", "@tapjs/typescript": "3.5.1", "@tapjs/worker": "4.3.1", "resolve-import": "^2.1.1" }, "bin": { "tap": "dist/esm/run.mjs" }, "engines": { "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/tap-parser": { "version": "18.3.0", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-18.3.0.tgz", "integrity": "sha512-sa0M18e6RARfO0Lrm1zbQvb+7G4G/ThkFIJFvjeH1DKenl4xwyUgpRUCb5Jq64Xe086p4auiLvRzfpRjGd3Zow==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "events-to-array": "^2.0.3", "tap-yaml": "4.3.0" }, "bin": { "tap-parser": "bin/cmd.cjs" }, "engines": { "node": "20 || >=22" } }, "node_modules/tap-yaml": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-4.3.0.tgz", "integrity": "sha512-48BiwXj3cUa1Lt6BLzfawJGZVihfRCY19gyjaHftQpe8ulEmB9gZW9kChQkdb0+L4YUlGWUJMpWRAJ/9bPSgVA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "yaml": "^2.8.1", "yaml-types": "^0.4.0" }, "engines": { "node": "20 || >=22" } }, "node_modules/tar": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.8.tgz", "integrity": "sha512-SYkBtK99u0yXa+IWL0JRzzcl7RxNpvX/U08Z+8DKnysfno7M+uExnTZH8K+VGgShf2qFPKtbNr9QBl8n7WBP6Q==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "engines": { "node": ">=18" } }, "node_modules/tcompare": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-9.3.0.tgz", "integrity": "sha512-6kFTU2xlXNFU88/DAAIQvjBu5znTGx8QPnFtaKiLin2OtspHXyevSu0iUTZt4UrSfuRC6fIahRCqaQIhXlsTVQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "diff": "^8.0.2", "react-element-to-jsx-string": "^15.0.0" }, "engines": { "node": "20 || >=22" } }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^10.4.1", "minimatch": "^9.0.4" }, "engines": { "node": ">=18" } }, "node_modules/test-exclude/node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": 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/test-exclude/node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/test-exclude/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/test-exclude/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, "node_modules/test-exclude/node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/test-exclude/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "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" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/test-exclude/node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/test-exclude/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/test-exclude/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/test-exclude/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/test-exclude/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": 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/test-exclude/node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": 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/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/trivial-deferred": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-2.0.0.tgz", "integrity": "sha512-iGbM7X2slv9ORDVj2y2FFUq3cP/ypbtu2nQ8S38ufjL0glBABvmR9pTdsib1XtS2LUhhLMbelaBUaf/s5J3dSw==", "dev": true, "license": "ISC", "engines": { "node": ">= 8" } }, "node_modules/tshy": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/tshy/-/tshy-3.2.0.tgz", "integrity": "sha512-/HqAZP+2lAn3P6t4IwnkseP6WPiRmv5fNirXzGA4YB15XJ3YXM7maQd1OBAEKlU3kek2iEO3VzQ/gzMhXlvAIA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "chalk": "^5.6.2", "chokidar": "^4.0.3", "foreground-child": "^4.0.0", "jsonc-simple-parser": "^3.0.0", "minimatch": "^10.0.3", "mkdirp": "^3.0.1", "polite-json": "^5.0.0", "resolve-import": "^2.1.1", "rimraf": "^6.1.2", "sync-content": "^2.0.3", "typescript": "^5.9.3", "walk-up-path": "^4.0.0" }, "bin": { "tshy": "dist/esm/bin-min.mjs" }, "engines": { "node": "20 || >=22" } }, "node_modules/tuf-js": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", "dev": true, "license": "MIT", "dependencies": { "@tufjs/models": "4.1.0", "debug": "^4.4.3", "make-fetch-happen": "^15.0.1" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "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/typedoc": { "version": "0.28.17", "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.17.tgz", "integrity": "sha512-ZkJ2G7mZrbxrKxinTQMjFqsCoYY6a5Luwv2GKbTnBCEgV2ihYm5CflA9JnJAwH0pZWavqfYxmDkFHPt4yx2oDQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@gerrit0/mini-shiki": "^3.17.0", "lunr": "^2.3.9", "markdown-it": "^14.1.0", "minimatch": "^9.0.5", "yaml": "^2.8.1" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { "node": ">= 18", "pnpm": ">= 10" }, "peerDependencies": { "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" } }, "node_modules/typedoc/node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/typedoc/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/typedoc/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/uc.micro": { "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, "license": "MIT" }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, "node_modules/unique-filename": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", "dev": true, "license": "ISC", "dependencies": { "unique-slug": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/unique-slug": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^2.0.0" }, "engines": { "node": ">=10.12.0" } }, "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/validate-npm-package-name": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", "dev": true, "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/walk-up-path": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", "dev": true, "license": "ISC", "engines": { "node": "20 || >=22" } }, "node_modules/which": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/widest-line": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", "dev": true, "license": "MIT", "dependencies": { "string-width": "^7.0.0" }, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "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/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/ws": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } }, "node_modules/yaml": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14.6" }, "funding": { "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yaml-types": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/yaml-types/-/yaml-types-0.4.0.tgz", "integrity": "sha512-XfbA30NUg4/LWUiplMbiufUiwYhgB9jvBhTWel7XQqjV+GaB79c2tROu/8/Tu7jO0HvDvnKWtBk5ksWRrhQ/0g==", "dev": true, "license": "ISC", "engines": { "node": ">= 16", "npm": ">= 7" }, "peerDependencies": { "yaml": "^2.3.0" } }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" } }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/yargs/node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, "license": "MIT" }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/yargs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yoga-layout": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", "dev": true, "license": "MIT" } } } isaacs-rimraf-4c5e478/package.json000066400000000000000000000034421514446574700171120ustar00rootroot00000000000000{ "name": "rimraf", "version": "6.1.3", "type": "module", "tshy": { "main": true, "exports": { "./package.json": "./package.json", ".": "./src/index.ts" } }, "bin": "./dist/esm/bin.mjs", "main": "./dist/commonjs/index.js", "types": "./dist/commonjs/index.d.ts", "exports": { "./package.json": "./package.json", ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" }, "require": { "types": "./dist/commonjs/index.d.ts", "default": "./dist/commonjs/index.js" } } }, "files": [ "dist" ], "description": "A deep deletion module for node (like `rm -rf`)", "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "license": "BlueOak-1.0.0", "repository": "git@github.com:isaacs/rimraf.git", "scripts": { "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", "prepare": "tshy", "pretest": "npm run prepare", "presnap": "npm run prepare", "test": "tap", "snap": "tap", "format": "prettier --write . --log-level warn", "benchmark": "node benchmark/index.js", "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" }, "devDependencies": { "@types/node": "^25.2.0", "mkdirp": "^3.0.1", "prettier": "^3.6.2", "tap": "^21.1.1", "tshy": "^3.0.3", "typedoc": "^0.28.14" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "engines": { "node": "20 || >=22" }, "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "keywords": [ "rm", "rm -rf", "rm -fr", "remove", "directory", "cli", "rmdir", "recursive" ], "module": "./dist/esm/index.js" } isaacs-rimraf-4c5e478/src/000077500000000000000000000000001514446574700154105ustar00rootroot00000000000000isaacs-rimraf-4c5e478/src/bin.mts000077500000000000000000000175221514446574700167170ustar00rootroot00000000000000#!/usr/bin/env node import type { RimrafAsyncOptions } from './index.js' import { rimraf } from './index.js' import { loadPackageJson } from 'package-json-from-dist' const { version } = loadPackageJson( import.meta.url, '../package.json', ) as { version: string } const runHelpForUsage = () => console.error('run `rimraf --help` for usage information') const help = `rimraf version ${version} Usage: rimraf [ ...] Deletes all files and folders at "path", recursively. Options: -- Treat all subsequent arguments as paths -h --help Display this usage info --version Display version --preserve-root Do not remove '/' recursively (default) --no-preserve-root Do not treat '/' specially -G --no-glob Treat arguments as literal paths, not globs (default) -g --glob Treat arguments as glob patterns -v --verbose Be verbose when deleting files, showing them as they are removed. Not compatible with --impl=native -V --no-verbose Be silent when deleting files, showing nothing as they are removed (default) -i --interactive Ask for confirmation before deleting anything Not compatible with --impl=native -I --no-interactive Do not ask for confirmation before deleting --impl= Specify the implementation to use: rimraf: choose the best option (default) native: the built-in implementation in Node.js manual: the platform-specific JS implementation posix: the Posix JS implementation windows: the Windows JS implementation (falls back to move-remove on ENOTEMPTY) move-remove: a slow reliable Windows fallback Implementation-specific options: --tmp= Temp file folder for 'move-remove' implementation --max-retries= maxRetries for 'native' and 'windows' implementations --retry-delay= retryDelay for 'native' implementation, default 100 --backoff= Exponential backoff factor for retries (default: 1.2) ` import { parse, relative, resolve } from 'path' const cwd = process.cwd() import { Dirent, Stats } from 'fs' import { createInterface, Interface } from 'readline' const prompt = async (rl: Interface, q: string) => new Promise(res => rl.question(q, res)) const interactiveRimraf = async ( impl: ( path: string | string[], opt?: RimrafAsyncOptions, ) => Promise, paths: string[], opt: RimrafAsyncOptions, ) => { const existingFilter = opt.filter || (() => true) let allRemaining = false let noneRemaining = false const queue: (() => Promise)[] = [] let processing = false const processQueue = async () => { if (processing) return processing = true let next: (() => Promise) | undefined while ((next = queue.shift())) { await next() } processing = false } const oneAtATime = (fn: (s: string, e: Dirent | Stats) => Promise) => async (s: string, e: Dirent | Stats): Promise => { const p = new Promise(res => { queue.push(async () => { const result = await fn(s, e) res(result) return result }) }) void processQueue() return p } const rl = createInterface({ input: process.stdin, output: process.stdout, }) opt.filter = oneAtATime( async (path: string, ent: Dirent | Stats): Promise => { if (noneRemaining) { return false } while (!allRemaining) { const a = ( await prompt( rl, `rm? ${relative(cwd, path)}\n[(Yes)/No/All/Quit] > `, ) ).trim() if (/^n/i.test(a)) { return false } else if (/^a/i.test(a)) { allRemaining = true break } else if (/^q/i.test(a)) { noneRemaining = true return false } else if (a === '' || /^y/i.test(a)) { break } else { continue } } return existingFilter(path, ent) }, ) await impl(paths, opt) rl.close() } const main = async (...args: string[]) => { const verboseFilter = (s: string) => { console.log(relative(cwd, s)) return true } const opt: RimrafAsyncOptions = {} const paths: string[] = [] let dashdash = false let impl: ( path: string | string[], opt?: RimrafAsyncOptions, ) => Promise = rimraf let interactive = false for (const arg of args) { if (dashdash) { paths.push(arg) continue } if (arg === '--') { dashdash = true continue } else if (arg === '-rf' || arg === '-fr') { // this never did anything, but people put it there I guess continue } else if (arg === '-h' || arg === '--help') { console.log(help) return 0 } else if (arg === '--version') { console.log(version) return 0 } else if (arg === '--interactive' || arg === '-i') { interactive = true continue } else if (arg === '--no-interactive' || arg === '-I') { interactive = false continue } else if (arg === '--verbose' || arg === '-v') { opt.filter = verboseFilter continue } else if (arg === '--no-verbose' || arg === '-V') { opt.filter = undefined continue } else if (arg === '-g' || arg === '--glob') { opt.glob = true continue } else if (arg === '-G' || arg === '--no-glob') { opt.glob = false continue } else if (arg === '--preserve-root') { opt.preserveRoot = true continue } else if (arg === '--no-preserve-root') { opt.preserveRoot = false continue } else if (/^--tmp=/.test(arg)) { const val = arg.substring('--tmp='.length) opt.tmp = val continue } else if (/^--max-retries=/.test(arg)) { const val = +arg.substring('--max-retries='.length) opt.maxRetries = val continue } else if (/^--retry-delay=/.test(arg)) { const val = +arg.substring('--retry-delay='.length) opt.retryDelay = val continue } else if (/^--backoff=/.test(arg)) { const val = +arg.substring('--backoff='.length) opt.backoff = val continue } else if (/^--impl=/.test(arg)) { const val = arg.substring('--impl='.length) switch (val) { case 'rimraf': impl = rimraf continue case 'native': case 'manual': case 'posix': case 'windows': impl = rimraf[val] continue case 'move-remove': impl = rimraf.moveRemove continue default: console.error(`unknown implementation: ${val}`) runHelpForUsage() return 1 } } else if (/^-/.test(arg)) { console.error(`unknown option: ${arg}`) runHelpForUsage() return 1 } else { paths.push(arg) } } if (opt.preserveRoot !== false) { for (const path of paths.map(p => resolve(p))) { if (path === parse(path).root) { console.error( `rimraf: it is dangerous to operate recursively on '/'`, ) console.error('use --no-preserve-root to override this failsafe') return 1 } } } if (!paths.length) { console.error('rimraf: must provide a path to remove') runHelpForUsage() return 1 } if (impl === rimraf.native && (interactive || opt.filter)) { console.error('native implementation does not support -v or -i') runHelpForUsage() return 1 } if (interactive) { await interactiveRimraf(impl, paths, opt) } else { await impl(paths, opt) } return 0 } main(...process.argv.slice(2)).then( code => process.exit(code), er => { console.error(er) process.exit(1) }, ) isaacs-rimraf-4c5e478/src/default-tmp.ts000066400000000000000000000037341514446574700202110ustar00rootroot00000000000000// The default temporary folder location for use in the windows algorithm. // It's TEMPting to use dirname(path), since that's guaranteed to be on the // same device. However, this means that: // rimraf(path).then(() => rimraf(dirname(path))) // will often fail with EBUSY, because the parent dir contains // marked-for-deletion directory entries (which do not show up in readdir). // The approach here is to use os.tmpdir() if it's on the same drive letter, // or resolve(path, '\\temp') if it exists, or the root of the drive if not. // On Posix (not that you'd be likely to use the windows algorithm there), // it uses os.tmpdir() always. import { tmpdir } from 'os' import { parse, resolve } from 'path' import { promises, statSync } from './fs.js' const { stat } = promises const isDirSync = (path: string) => { try { return statSync(path).isDirectory() } catch { return false } } const isDir = (path: string) => stat(path).then( st => st.isDirectory(), () => false, ) const win32DefaultTmp = async (path: string) => { const { root } = parse(path) const tmp = tmpdir() const { root: tmpRoot } = parse(tmp) if (root.toLowerCase() === tmpRoot.toLowerCase()) { return tmp } const driveTmp = resolve(root, '/temp') if (await isDir(driveTmp)) { return driveTmp } return root } const win32DefaultTmpSync = (path: string) => { const { root } = parse(path) const tmp = tmpdir() const { root: tmpRoot } = parse(tmp) if (root.toLowerCase() === tmpRoot.toLowerCase()) { return tmp } const driveTmp = resolve(root, '/temp') if (isDirSync(driveTmp)) { return driveTmp } return root } // eslint-disable-next-line @typescript-eslint/require-await const posixDefaultTmp = async () => tmpdir() const posixDefaultTmpSync = () => tmpdir() export const defaultTmp = process.platform === 'win32' ? win32DefaultTmp : posixDefaultTmp export const defaultTmpSync = process.platform === 'win32' ? win32DefaultTmpSync : posixDefaultTmpSync isaacs-rimraf-4c5e478/src/error.ts000066400000000000000000000007261514446574700171160ustar00rootroot00000000000000const isRecord = (o: unknown): o is Record => !!o && typeof o === 'object' const hasString = (o: Record, key: string) => key in o && typeof o[key] === 'string' export const isFsError = ( o: unknown, ): o is NodeJS.ErrnoException & { code: string path: string } => isRecord(o) && hasString(o, 'code') && hasString(o, 'path') export const errorCode = (er: unknown) => isRecord(er) && hasString(er, 'code') ? er.code : null isaacs-rimraf-4c5e478/src/fix-eperm.ts000066400000000000000000000017741514446574700176650ustar00rootroot00000000000000import { errorCode } from './error.js' import { chmodSync, promises } from './fs.js' import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js' const { chmod } = promises export const fixEPERM = (fn: (path: string) => Promise) => async (path: string): Promise => { try { return void (await ignoreENOENT(fn(path))) } catch (er) { if (errorCode(er) === 'EPERM') { if ( !(await ignoreENOENT( chmod(path, 0o666).then(() => true), er, )) ) { return } return void (await fn(path)) } throw er } } export const fixEPERMSync = (fn: (path: string) => unknown) => (path: string): void => { try { return void ignoreENOENTSync(() => fn(path)) } catch (er) { if (errorCode(er) === 'EPERM') { if (!ignoreENOENTSync(() => (chmodSync(path, 0o666), true), er)) { return } return void fn(path) } throw er } } isaacs-rimraf-4c5e478/src/fs.ts000066400000000000000000000013401514446574700163660ustar00rootroot00000000000000import fs, { Dirent, readdirSync as rdSync } from 'fs' import fsPromises from 'fs/promises' // sync ones just take the sync version from node // readdir forces withFileTypes: true export { chmodSync, mkdirSync, renameSync, rmdirSync, rmSync, statSync, lstatSync, unlinkSync, } from 'fs' export const readdirSync = (path: fs.PathLike): Dirent[] => rdSync(path, { withFileTypes: true }) export const promises = { chmod: fsPromises.chmod, mkdir: fsPromises.mkdir, readdir: (path: fs.PathLike) => fsPromises.readdir(path, { withFileTypes: true }), rename: fsPromises.rename, rm: fsPromises.rm, rmdir: fsPromises.rmdir, stat: fsPromises.stat, lstat: fsPromises.lstat, unlink: fsPromises.unlink, } isaacs-rimraf-4c5e478/src/ignore-enoent.ts000066400000000000000000000006451514446574700205360ustar00rootroot00000000000000import { errorCode } from './error.js' export const ignoreENOENT = async (p: Promise, rethrow?: unknown) => p.catch(er => { if (errorCode(er) === 'ENOENT') { return } throw rethrow ?? er }) export const ignoreENOENTSync = (fn: () => T, rethrow?: unknown) => { try { return fn() } catch (er) { if (errorCode(er) === 'ENOENT') { return } throw rethrow ?? er } } isaacs-rimraf-4c5e478/src/index.ts000066400000000000000000000056311514446574700170740ustar00rootroot00000000000000import { glob, globSync } from 'glob' import { optArg, optArgSync, RimrafAsyncOptions, RimrafSyncOptions, } from './opt-arg.js' import pathArg from './path-arg.js' import { rimrafManual, rimrafManualSync } from './rimraf-manual.js' import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js' import { rimrafNative, rimrafNativeSync } from './rimraf-native.js' import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js' import { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js' import { useNative, useNativeSync } from './use-native.js' export { assertRimrafOptions, isRimrafOptions, type RimrafAsyncOptions, type RimrafOptions, type RimrafSyncOptions, } from './opt-arg.js' const wrap = (fn: (p: string, o: RimrafAsyncOptions) => Promise) => async ( path: string | string[], opt?: RimrafAsyncOptions, ): Promise => { const options = optArg(opt) if (options.glob) { path = await glob(path, options.glob) } if (Array.isArray(path)) { return !!( await Promise.all(path.map(p => fn(pathArg(p, options), options))) ).reduce((a, b) => a && b, true) } else { return !!(await fn(pathArg(path, options), options)) } } const wrapSync = (fn: (p: string, o: RimrafSyncOptions) => boolean) => (path: string | string[], opt?: RimrafSyncOptions): boolean => { const options = optArgSync(opt) if (options.glob) { path = globSync(path, options.glob) } if (Array.isArray(path)) { return !!path .map(p => fn(pathArg(p, options), options)) .reduce((a, b) => a && b, true) } else { return !!fn(pathArg(path, options), options) } } export const nativeSync = wrapSync(rimrafNativeSync) export const native = Object.assign(wrap(rimrafNative), { sync: nativeSync, }) export const manualSync = wrapSync(rimrafManualSync) export const manual = Object.assign(wrap(rimrafManual), { sync: manualSync, }) export const windowsSync = wrapSync(rimrafWindowsSync) export const windows = Object.assign(wrap(rimrafWindows), { sync: windowsSync, }) export const posixSync = wrapSync(rimrafPosixSync) export const posix = Object.assign(wrap(rimrafPosix), { sync: posixSync }) export const moveRemoveSync = wrapSync(rimrafMoveRemoveSync) export const moveRemove = Object.assign(wrap(rimrafMoveRemove), { sync: moveRemoveSync, }) export const rimrafSync = wrapSync((path, opt) => useNativeSync(opt) ? rimrafNativeSync(path, opt) : rimrafManualSync(path, opt), ) export const sync = rimrafSync const rimraf_ = wrap((path, opt) => useNative(opt) ? rimrafNative(path, opt) : rimrafManual(path, opt), ) export const rimraf = Object.assign(rimraf_, { rimraf: rimraf_, sync: rimrafSync, rimrafSync: rimrafSync, manual, manualSync, native, nativeSync, posix, posixSync, windows, windowsSync, moveRemove, moveRemoveSync, }) rimraf.rimraf = rimraf isaacs-rimraf-4c5e478/src/opt-arg.ts000066400000000000000000000043151514446574700173340ustar00rootroot00000000000000import { Dirent, Stats } from 'fs' import { GlobOptions } from 'glob' const typeOrUndef = (val: any, t: string) => typeof val === 'undefined' || typeof val === t export const isRimrafOptions = (o: any): o is RimrafOptions => !!o && typeof o === 'object' && typeOrUndef(o.preserveRoot, 'boolean') && typeOrUndef(o.tmp, 'string') && typeOrUndef(o.maxRetries, 'number') && typeOrUndef(o.retryDelay, 'number') && typeOrUndef(o.backoff, 'number') && typeOrUndef(o.maxBackoff, 'number') && (typeOrUndef(o.glob, 'boolean') || (o.glob && typeof o.glob === 'object')) && typeOrUndef(o.filter, 'function') export const assertRimrafOptions: (o: any) => void = ( o: any, ): asserts o is RimrafOptions => { if (!isRimrafOptions(o)) { throw new Error('invalid rimraf options') } } export interface RimrafAsyncOptions { preserveRoot?: boolean tmp?: string maxRetries?: number retryDelay?: number backoff?: number maxBackoff?: number signal?: AbortSignal glob?: boolean | GlobOptions filter?: | ((path: string, ent: Dirent | Stats) => boolean) | ((path: string, ent: Dirent | Stats) => Promise) } export interface RimrafSyncOptions extends RimrafAsyncOptions { filter?: (path: string, ent: Dirent | Stats) => boolean } export type RimrafOptions = RimrafSyncOptions | RimrafAsyncOptions const optArgT = ( opt: T, ): | (T & { glob: GlobOptions & { withFileTypes: false } }) | (T & { glob: undefined }) => { assertRimrafOptions(opt) const { glob, ...options } = opt if (!glob) { return options as T & { glob: undefined } } const globOpt = glob === true ? opt.signal ? { signal: opt.signal } : {} : opt.signal ? { signal: opt.signal, ...glob, } : glob return { ...options, glob: { ...globOpt, // always get absolute paths from glob, to ensure // that we are referencing the correct thing. absolute: true, withFileTypes: false, }, } as T & { glob: GlobOptions & { withFileTypes: false } } } export const optArg = (opt: RimrafAsyncOptions = {}) => optArgT(opt) export const optArgSync = (opt: RimrafSyncOptions = {}) => optArgT(opt) isaacs-rimraf-4c5e478/src/path-arg.ts000066400000000000000000000027561514446574700174750ustar00rootroot00000000000000import { parse, resolve } from 'path' import { inspect } from 'util' import { RimrafAsyncOptions } from './index.js' const pathArg = (path: string, opt: RimrafAsyncOptions = {}) => { const type = typeof path if (type !== 'string') { const ctor = path && type === 'object' && path.constructor const received = ctor && ctor.name ? `an instance of ${ctor.name}` : type === 'object' ? inspect(path) : `type ${type} ${path}` const msg = 'The "path" argument must be of type string. ' + `Received ${received}` throw Object.assign(new TypeError(msg), { path, code: 'ERR_INVALID_ARG_TYPE', }) } if (/\0/.test(path)) { // simulate same failure that node raises const msg = 'path must be a string without null bytes' throw Object.assign(new TypeError(msg), { path, code: 'ERR_INVALID_ARG_VALUE', }) } path = resolve(path) const { root } = parse(path) if (path === root && opt.preserveRoot !== false) { const msg = 'refusing to remove root directory without preserveRoot:false' throw Object.assign(new Error(msg), { path, code: 'ERR_PRESERVE_ROOT', }) } if (process.platform === 'win32') { const badWinChars = /[*|"<>?:]/ const { root } = parse(path) if (badWinChars.test(path.substring(root.length))) { throw Object.assign(new Error('Illegal characters in path.'), { path, code: 'EINVAL', }) } } return path } export default pathArg isaacs-rimraf-4c5e478/src/readdir-or-error.ts000066400000000000000000000006211514446574700211360ustar00rootroot00000000000000// returns an array of entries if readdir() works, // or the error that readdir() raised if not. import { promises, readdirSync } from './fs.js' const { readdir } = promises export const readdirOrError = (path: string) => readdir(path).catch(er => er as Error) export const readdirOrErrorSync = (path: string) => { try { return readdirSync(path) } catch (er) { return er as Error } } isaacs-rimraf-4c5e478/src/retry-busy.ts000066400000000000000000000033241514446574700201070ustar00rootroot00000000000000// note: max backoff is the maximum that any *single* backoff will do import { setTimeout } from 'timers/promises' import { RimrafAsyncOptions, RimrafOptions } from './index.js' import { isFsError } from './error.js' export const MAXBACKOFF = 200 export const RATE = 1.2 export const MAXRETRIES = 10 export const codes = new Set(['EMFILE', 'ENFILE', 'EBUSY']) export const retryBusy = (fn: (path: string) => Promise) => { const method = async ( path: string, opt: RimrafAsyncOptions, backoff = 1, total = 0, ) => { const mbo = opt.maxBackoff || MAXBACKOFF const rate = opt.backoff || RATE const max = opt.maxRetries || MAXRETRIES let retries = 0 while (true) { try { return await fn(path) } catch (er) { if (isFsError(er) && er.path === path && codes.has(er.code)) { backoff = Math.ceil(backoff * rate) total = backoff + total if (total < mbo) { await setTimeout(backoff) return method(path, opt, backoff, total) } if (retries < max) { retries++ continue } } throw er } } } return method } // just retries, no async so no backoff export const retryBusySync = (fn: (path: string) => T) => { const method = (path: string, opt: RimrafOptions) => { const max = opt.maxRetries || MAXRETRIES let retries = 0 while (true) { try { return fn(path) } catch (er) { if ( isFsError(er) && er.path === path && codes.has(er.code) && retries < max ) { retries++ continue } throw er } } } return method } isaacs-rimraf-4c5e478/src/rimraf-manual.ts000066400000000000000000000005071514446574700205150ustar00rootroot00000000000000import { rimrafPosix, rimrafPosixSync } from './rimraf-posix.js' import { rimrafWindows, rimrafWindowsSync } from './rimraf-windows.js' export const rimrafManual = process.platform === 'win32' ? rimrafWindows : rimrafPosix export const rimrafManualSync = process.platform === 'win32' ? rimrafWindowsSync : rimrafPosixSync isaacs-rimraf-4c5e478/src/rimraf-move-remove.ts000066400000000000000000000123431514446574700215020ustar00rootroot00000000000000// https://youtu.be/uhRWMGBjlO8?t=537 // // 1. readdir // 2. for each entry // a. if a non-empty directory, recurse // b. if an empty directory, move to random hidden file name in $TEMP // c. unlink/rmdir $TEMP // // This works around the fact that unlink/rmdir is non-atomic and takes // a non-deterministic amount of time to complete. // // However, it is HELLA SLOW, like 2-10x slower than a naive recursive rm. import { basename, parse, resolve } from 'path' import { defaultTmp, defaultTmpSync } from './default-tmp.js' import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js' import { lstatSync, promises, renameSync, rmdirSync, unlinkSync, } from './fs.js' import { Dirent, Stats } from 'fs' import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js' import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js' import { fixEPERM, fixEPERMSync } from './fix-eperm.js' import { errorCode } from './error.js' const { lstat, rename, unlink, rmdir } = promises // crypto.randomBytes is much slower, and Math.random() is enough here const uniqueFilename = (path: string) => `.${basename(path)}.${Math.random()}` const unlinkFixEPERM = fixEPERM(unlink) const unlinkFixEPERMSync = fixEPERMSync(unlinkSync) export const rimrafMoveRemove = async ( path: string, opt: RimrafAsyncOptions, ) => { opt?.signal?.throwIfAborted() return ( (await ignoreENOENT( lstat(path).then(stat => rimrafMoveRemoveDir(path, opt, stat)), )) ?? true ) } const rimrafMoveRemoveDir = async ( path: string, opt: RimrafAsyncOptions, ent: Dirent | Stats, ): Promise => { opt?.signal?.throwIfAborted() if (!opt.tmp) { return rimrafMoveRemoveDir( path, { ...opt, tmp: await defaultTmp(path) }, ent, ) } if (path === opt.tmp && parse(path).root !== path) { throw new Error('cannot delete temp directory used for deletion') } const entries = ent.isDirectory() ? await readdirOrError(path) : null if (!Array.isArray(entries)) { // this can only happen if lstat/readdir lied, or if the dir was // swapped out with a file at just the right moment. /* c8 ignore start */ if (entries) { if (errorCode(entries) === 'ENOENT') { return true } if (errorCode(entries) !== 'ENOTDIR') { throw entries } } /* c8 ignore stop */ if (opt.filter && !(await opt.filter(path, ent))) { return false } await ignoreENOENT(tmpUnlink(path, opt.tmp, unlinkFixEPERM)) return true } const removedAll = ( await Promise.all( entries.map(ent => rimrafMoveRemoveDir(resolve(path, ent.name), opt, ent), ), ) ).every(v => v === true) if (!removedAll) { return false } // we don't ever ACTUALLY try to unlink /, because that can never work // but when preserveRoot is false, we could be operating on it. // No need to check if preserveRoot is not false. if (opt.preserveRoot === false && path === parse(path).root) { return false } if (opt.filter && !(await opt.filter(path, ent))) { return false } await ignoreENOENT(tmpUnlink(path, opt.tmp, rmdir)) return true } const tmpUnlink = async ( path: string, tmp: string, rm: (p: string) => Promise, ) => { const tmpFile = resolve(tmp, uniqueFilename(path)) await rename(path, tmpFile) return await rm(tmpFile) } export const rimrafMoveRemoveSync = ( path: string, opt: RimrafSyncOptions, ) => { opt?.signal?.throwIfAborted() return ( ignoreENOENTSync(() => rimrafMoveRemoveDirSync(path, opt, lstatSync(path)), ) ?? true ) } const rimrafMoveRemoveDirSync = ( path: string, opt: RimrafSyncOptions, ent: Dirent | Stats, ): boolean => { opt?.signal?.throwIfAborted() if (!opt.tmp) { return rimrafMoveRemoveDirSync( path, { ...opt, tmp: defaultTmpSync(path) }, ent, ) } const tmp: string = opt.tmp if (path === opt.tmp && parse(path).root !== path) { throw new Error('cannot delete temp directory used for deletion') } const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null if (!Array.isArray(entries)) { // this can only happen if lstat/readdir lied, or if the dir was // swapped out with a file at just the right moment. /* c8 ignore start */ if (entries) { if (errorCode(entries) === 'ENOENT') { return true } if (errorCode(entries) !== 'ENOTDIR') { throw entries } } /* c8 ignore stop */ if (opt.filter && !opt.filter(path, ent)) { return false } ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, unlinkFixEPERMSync)) return true } let removedAll = true for (const ent of entries) { const p = resolve(path, ent.name) removedAll = rimrafMoveRemoveDirSync(p, opt, ent) && removedAll } if (!removedAll) { return false } if (opt.preserveRoot === false && path === parse(path).root) { return false } if (opt.filter && !opt.filter(path, ent)) { return false } ignoreENOENTSync(() => tmpUnlinkSync(path, tmp, rmdirSync)) return true } const tmpUnlinkSync = ( path: string, tmp: string, rmSync: (p: string) => void, ) => { const tmpFile = resolve(tmp, uniqueFilename(path)) renameSync(path, tmpFile) return rmSync(tmpFile) } isaacs-rimraf-4c5e478/src/rimraf-native.ts000066400000000000000000000007761514446574700205360ustar00rootroot00000000000000import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js' import { promises, rmSync } from './fs.js' const { rm } = promises export const rimrafNative = async ( path: string, opt: RimrafAsyncOptions, ): Promise => { await rm(path, { ...opt, force: true, recursive: true, }) return true } export const rimrafNativeSync = ( path: string, opt: RimrafSyncOptions, ): boolean => { rmSync(path, { ...opt, force: true, recursive: true, }) return true } isaacs-rimraf-4c5e478/src/rimraf-posix.ts000066400000000000000000000072031514446574700204020ustar00rootroot00000000000000// the simple recursive removal, where unlink and rmdir are atomic // Note that this approach does NOT work on Windows! // We stat first and only unlink if the Dirent isn't a directory, // because sunos will let root unlink a directory, and some // SUPER weird breakage happens as a result. import { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js' import { parse, resolve } from 'path' import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js' import { Dirent, Stats } from 'fs' import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js' import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js' import { errorCode } from './error.js' const { lstat, rmdir, unlink } = promises export const rimrafPosix = async ( path: string, opt: RimrafAsyncOptions, ) => { opt?.signal?.throwIfAborted() return ( (await ignoreENOENT( lstat(path).then(stat => rimrafPosixDir(path, opt, stat)), )) ?? true ) } export const rimrafPosixSync = (path: string, opt: RimrafSyncOptions) => { opt?.signal?.throwIfAborted() return ( ignoreENOENTSync(() => rimrafPosixDirSync(path, opt, lstatSync(path)), ) ?? true ) } const rimrafPosixDir = async ( path: string, opt: RimrafAsyncOptions, ent: Dirent | Stats, ): Promise => { opt?.signal?.throwIfAborted() const entries = ent.isDirectory() ? await readdirOrError(path) : null if (!Array.isArray(entries)) { // this can only happen if lstat/readdir lied, or if the dir was // swapped out with a file at just the right moment. /* c8 ignore start */ if (entries) { if (errorCode(entries) === 'ENOENT') { return true } if (errorCode(entries) !== 'ENOTDIR') { throw entries } } /* c8 ignore stop */ if (opt.filter && !(await opt.filter(path, ent))) { return false } await ignoreENOENT(unlink(path)) return true } const removedAll = ( await Promise.all( entries.map(ent => rimrafPosixDir(resolve(path, ent.name), opt, ent), ), ) ).every(v => v === true) if (!removedAll) { return false } // we don't ever ACTUALLY try to unlink /, because that can never work // but when preserveRoot is false, we could be operating on it. // No need to check if preserveRoot is not false. if (opt.preserveRoot === false && path === parse(path).root) { return false } if (opt.filter && !(await opt.filter(path, ent))) { return false } await ignoreENOENT(rmdir(path)) return true } const rimrafPosixDirSync = ( path: string, opt: RimrafSyncOptions, ent: Dirent | Stats, ): boolean => { opt?.signal?.throwIfAborted() const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null if (!Array.isArray(entries)) { // this can only happen if lstat/readdir lied, or if the dir was // swapped out with a file at just the right moment. /* c8 ignore start */ if (entries) { if (errorCode(entries) === 'ENOENT') { return true } if (errorCode(entries) !== 'ENOTDIR') { throw entries } } /* c8 ignore stop */ if (opt.filter && !opt.filter(path, ent)) { return false } ignoreENOENTSync(() => unlinkSync(path)) return true } let removedAll: boolean = true for (const ent of entries) { const p = resolve(path, ent.name) removedAll = rimrafPosixDirSync(p, opt, ent) && removedAll } if (opt.preserveRoot === false && path === parse(path).root) { return false } if (!removedAll) { return false } if (opt.filter && !opt.filter(path, ent)) { return false } ignoreENOENTSync(() => rmdirSync(path)) return true } isaacs-rimraf-4c5e478/src/rimraf-windows.ts000066400000000000000000000131631514446574700207340ustar00rootroot00000000000000// This is the same as rimrafPosix, with the following changes: // // 1. EBUSY, ENFILE, EMFILE trigger retries and/or exponential backoff // 2. All non-directories are removed first and then all directories are // removed in a second sweep. // 3. If we hit ENOTEMPTY in the second sweep, fall back to move-remove on // the that folder. // // Note: "move then remove" is 2-10 times slower, and just as unreliable. import { Dirent, Stats } from 'fs' import { parse, resolve } from 'path' import { RimrafAsyncOptions, RimrafSyncOptions } from './index.js' import { fixEPERM, fixEPERMSync } from './fix-eperm.js' import { lstatSync, promises, rmdirSync, unlinkSync } from './fs.js' import { ignoreENOENT, ignoreENOENTSync } from './ignore-enoent.js' import { readdirOrError, readdirOrErrorSync } from './readdir-or-error.js' import { retryBusy, retryBusySync } from './retry-busy.js' import { rimrafMoveRemove, rimrafMoveRemoveSync, } from './rimraf-move-remove.js' import { errorCode } from './error.js' const { unlink, rmdir, lstat } = promises const rimrafWindowsFile = retryBusy(fixEPERM(unlink)) const rimrafWindowsFileSync = retryBusySync(fixEPERMSync(unlinkSync)) const rimrafWindowsDirRetry = retryBusy(fixEPERM(rmdir)) const rimrafWindowsDirRetrySync = retryBusySync(fixEPERMSync(rmdirSync)) const rimrafWindowsDirMoveRemoveFallback = async ( path: string, // already filtered, remove from options so we don't call unnecessarily // eslint-disable-next-line @typescript-eslint/no-unused-vars { filter, ...opt }: RimrafAsyncOptions, ): Promise => { /* c8 ignore next */ opt?.signal?.throwIfAborted() try { await rimrafWindowsDirRetry(path, opt) return true } catch (er) { if (errorCode(er) === 'ENOTEMPTY') { return rimrafMoveRemove(path, opt) } throw er } } const rimrafWindowsDirMoveRemoveFallbackSync = ( path: string, // already filtered, remove from options so we don't call unnecessarily // eslint-disable-next-line @typescript-eslint/no-unused-vars { filter, ...opt }: RimrafSyncOptions, ): boolean => { opt?.signal?.throwIfAborted() try { rimrafWindowsDirRetrySync(path, opt) return true } catch (er) { if (errorCode(er) === 'ENOTEMPTY') { return rimrafMoveRemoveSync(path, opt) } throw er } } const START = Symbol('start') const CHILD = Symbol('child') const FINISH = Symbol('finish') export const rimrafWindows = async ( path: string, opt: RimrafAsyncOptions, ) => { opt?.signal?.throwIfAborted() return ( (await ignoreENOENT( lstat(path).then(stat => rimrafWindowsDir(path, opt, stat, START)), )) ?? true ) } export const rimrafWindowsSync = ( path: string, opt: RimrafSyncOptions, ) => { opt?.signal?.throwIfAborted() return ( ignoreENOENTSync(() => rimrafWindowsDirSync(path, opt, lstatSync(path), START), ) ?? true ) } const rimrafWindowsDir = async ( path: string, opt: RimrafAsyncOptions, ent: Dirent | Stats, state = START, ): Promise => { opt?.signal?.throwIfAborted() const entries = ent.isDirectory() ? await readdirOrError(path) : null if (!Array.isArray(entries)) { // this can only happen if lstat/readdir lied, or if the dir was // swapped out with a file at just the right moment. /* c8 ignore start */ if (entries) { if (errorCode(entries) === 'ENOENT') { return true } if (errorCode(entries) !== 'ENOTDIR') { throw entries } } /* c8 ignore stop */ if (opt.filter && !(await opt.filter(path, ent))) { return false } // is a file await ignoreENOENT(rimrafWindowsFile(path, opt)) return true } const s = state === START ? CHILD : state const removedAll = ( await Promise.all( entries.map(ent => rimrafWindowsDir(resolve(path, ent.name), opt, ent, s), ), ) ).every(v => v === true) if (state === START) { return rimrafWindowsDir(path, opt, ent, FINISH) } else if (state === FINISH) { if (opt.preserveRoot === false && path === parse(path).root) { return false } if (!removedAll) { return false } if (opt.filter && !(await opt.filter(path, ent))) { return false } await ignoreENOENT(rimrafWindowsDirMoveRemoveFallback(path, opt)) } return true } const rimrafWindowsDirSync = ( path: string, opt: RimrafSyncOptions, ent: Dirent | Stats, state = START, ): boolean => { const entries = ent.isDirectory() ? readdirOrErrorSync(path) : null if (!Array.isArray(entries)) { // this can only happen if lstat/readdir lied, or if the dir was // swapped out with a file at just the right moment. /* c8 ignore start */ if (entries) { if (errorCode(entries) === 'ENOENT') { return true } if (errorCode(entries) !== 'ENOTDIR') { throw entries } } /* c8 ignore stop */ if (opt.filter && !opt.filter(path, ent)) { return false } // is a file ignoreENOENTSync(() => rimrafWindowsFileSync(path, opt)) return true } let removedAll = true for (const ent of entries) { const s = state === START ? CHILD : state const p = resolve(path, ent.name) removedAll = rimrafWindowsDirSync(p, opt, ent, s) && removedAll } if (state === START) { return rimrafWindowsDirSync(path, opt, ent, FINISH) } else if (state === FINISH) { if (opt.preserveRoot === false && path === parse(path).root) { return false } if (!removedAll) { return false } if (opt.filter && !opt.filter(path, ent)) { return false } ignoreENOENTSync(() => rimrafWindowsDirMoveRemoveFallbackSync(path, opt), ) } return true } isaacs-rimraf-4c5e478/src/use-native.ts000066400000000000000000000013371514446574700200440ustar00rootroot00000000000000import { RimrafAsyncOptions, RimrafOptions } from './index.js' /* c8 ignore next */ const [major = 0, minor = 0] = process.version .replace(/^v/, '') .split('.') .map(v => parseInt(v, 10)) const hasNative = major > 14 || (major === 14 && minor >= 14) // we do NOT use native by default on Windows, because Node's native // rm implementation is less advanced. Change this code if that changes. export const useNative: (opt?: RimrafAsyncOptions) => boolean = !hasNative || process.platform === 'win32' ? () => false : opt => !opt?.signal && !opt?.filter export const useNativeSync: (opt?: RimrafOptions) => boolean = !hasNative || process.platform === 'win32' ? () => false : opt => !opt?.signal && !opt?.filter isaacs-rimraf-4c5e478/tap-snapshots/000077500000000000000000000000001514446574700174255ustar00rootroot00000000000000isaacs-rimraf-4c5e478/tap-snapshots/test/000077500000000000000000000000001514446574700204045ustar00rootroot00000000000000isaacs-rimraf-4c5e478/tap-snapshots/test/bin.ts.test.cjs000066400000000000000000000021721514446574700232620ustar00rootroot00000000000000/* IMPORTANT * This snapshot file is auto-generated, but designed for humans. * It should be checked into source control and tracked carefully. * Re-generate by setting TAP_SNAPSHOT=1 and running tests. * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' exports[`test/bin.ts > TAP > interactive deletes > -v > a > had any leftover 1`] = ` false ` exports[`test/bin.ts > TAP > interactive deletes > -V > a > had any leftover 1`] = ` false ` exports[`test/bin.ts > TAP > interactive deletes > -v > hehaha, yes i think so, , A > had any leftover 1`] = ` false ` exports[`test/bin.ts > TAP > interactive deletes > -V > hehaha, yes i think so, , A > had any leftover 1`] = ` false ` exports[`test/bin.ts > TAP > interactive deletes > -v > no, n, N, N, Q > had any leftover 1`] = ` true ` exports[`test/bin.ts > TAP > interactive deletes > -V > no, n, N, N, Q > had any leftover 1`] = ` true ` exports[`test/bin.ts > TAP > interactive deletes > -v > y, YOLO, no, quit > had any leftover 1`] = ` true ` exports[`test/bin.ts > TAP > interactive deletes > -V > y, YOLO, no, quit > had any leftover 1`] = ` true ` isaacs-rimraf-4c5e478/tap-snapshots/test/index.ts.test.cjs000066400000000000000000000070771514446574700236320ustar00rootroot00000000000000/* IMPORTANT * This snapshot file is auto-generated, but designed for humans. * It should be checked into source control and tracked carefully. * Re-generate by setting TAP_SNAPSHOT=1 and running tests. * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' exports[`test/index.ts > TAP > mocky unit tests to select the correct function > main function, useNative=false > must match snapshot 1`] = ` Array [ Array [ "optArg", Object { "a": 1, }, ], Array [ "pathArg", "path", ], Array [ "useNative", Object { "a": 1, }, ], Array [ "rimrafPosix", "path", Object { "a": 1, }, ], Array [ "optArg", Object { "a": 2, }, ], Array [ "pathArg", "path", ], Array [ "useNativeSync", Object { "a": 2, }, ], Array [ "rimrafPosixSync", "path", Object { "a": 2, }, ], ] ` exports[`test/index.ts > TAP > mocky unit tests to select the correct function > main function, useNative=true > must match snapshot 1`] = ` Array [ Array [ "optArg", Object { "a": 1, }, ], Array [ "pathArg", "path", ], Array [ "useNative", Object { "a": 1, }, ], Array [ "rimrafNative", "path", Object { "a": 1, }, ], Array [ "optArg", Object { "a": 2, }, ], Array [ "pathArg", "path", ], Array [ "useNativeSync", Object { "a": 2, }, ], Array [ "rimrafNativeSync", "path", Object { "a": 2, }, ], ] ` exports[`test/index.ts > TAP > mocky unit tests to select the correct function > manual > must match snapshot 1`] = ` Array [ Array [ "optArg", Object { "a": 3, }, ], Array [ "pathArg", "path", ], Array [ "rimrafPosix", "path", Object { "a": 3, }, ], Array [ "optArg", Object { "a": 4, }, ], Array [ "pathArg", "path", ], Array [ "rimrafPosixSync", "path", Object { "a": 4, }, ], ] ` exports[`test/index.ts > TAP > mocky unit tests to select the correct function > native > must match snapshot 1`] = ` Array [ Array [ "optArg", Object { "a": 5, }, ], Array [ "pathArg", "path", ], Array [ "rimrafNative", "path", Object { "a": 5, }, ], Array [ "optArg", Object { "a": 6, }, ], Array [ "pathArg", "path", ], Array [ "rimrafNativeSync", "path", Object { "a": 6, }, ], ] ` exports[`test/index.ts > TAP > mocky unit tests to select the correct function > posix > must match snapshot 1`] = ` Array [ Array [ "optArg", Object { "a": 7, }, ], Array [ "pathArg", "path", ], Array [ "rimrafPosix", "path", Object { "a": 7, }, ], Array [ "optArg", Object { "a": 8, }, ], Array [ "pathArg", "path", ], Array [ "rimrafPosixSync", "path", Object { "a": 8, }, ], ] ` exports[`test/index.ts > TAP > mocky unit tests to select the correct function > windows > must match snapshot 1`] = ` Array [ Array [ "optArg", Object { "a": 9, }, ], Array [ "pathArg", "path", ], Array [ "rimrafWindows", "path", Object { "a": 9, }, ], Array [ "optArg", Object { "a": 10, }, ], Array [ "pathArg", "path", ], Array [ "rimrafWindowsSync", "path", Object { "a": 10, }, ], ] ` isaacs-rimraf-4c5e478/tap-snapshots/test/retry-busy.ts.test.cjs000066400000000000000000000007421514446574700246400ustar00rootroot00000000000000/* IMPORTANT * This snapshot file is auto-generated, but designed for humans. * It should be checked into source control and tracked carefully. * Re-generate by setting TAP_SNAPSHOT=1 and running tests. * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' exports[`test/retry-busy.ts > TAP > default settings 1`] = ` Object { "codes": Set { "EMFILE", "ENFILE", "EBUSY", }, "MAXBACKOFF": 200, "MAXRETRIES": 10, "RATE": 1.2, } ` isaacs-rimraf-4c5e478/tap-snapshots/test/rimraf-move-remove.ts.test.cjs000066400000000000000000000210651514446574700262330ustar00rootroot00000000000000/* IMPORTANT * This snapshot file is auto-generated, but designed for humans. * It should be checked into source control and tracked carefully. * Re-generate by setting TAP_SNAPSHOT=1 and running tests. * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' exports[`test/rimraf-move-remove.ts > TAP > filter function > filter=i > async > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/a", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/b", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/d", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/e", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/g", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/h", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/i", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/i/j", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/i/k", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/i/l", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/i/m", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/i/m/n", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async/c/f/i/m/o", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > filter function > filter=i > async filter > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/a", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/b", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/d", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/e", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/g", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/h", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/i", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/i/j", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/i/k", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/i/l", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/i/m", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/i/m/n", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-async-filter/c/f/i/m/o", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > filter function > filter=i > sync > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/a", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/b", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/d", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/e", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/g", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/h", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/i", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/i/j", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/i/k", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/i/l", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/i/m", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/i/m/n", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-i-sync/c/f/i/m/o", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > filter function > filter=j > async > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/a", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/b", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/d", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/e", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/g", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/h", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/i/j", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/i/k", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/i/l", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/i/m", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/i/m/n", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async/c/f/i/m/o", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > filter function > filter=j > async filter > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/a", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/b", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/d", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/e", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/g", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/h", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/i/j", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/i/k", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/i/l", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/i/m", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/i/m/n", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-async-filter/c/f/i/m/o", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > filter function > filter=j > sync > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/a", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/b", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/d", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/e", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/g", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/h", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/i/j", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/i/k", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/i/l", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/i/m", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/i/m/n", ".tap/fixtures/test-rimraf-move-remove.ts-filter-function-filter-j-sync/c/f/i/m/o", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > handle EPERMs on unlink by trying to chmod 0o666 > async > must match snapshot 1`] = ` Array [ Array [ "chmod", "{tmpfile}", "438", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > handle EPERMs on unlink by trying to chmod 0o666 > sync > must match snapshot 1`] = ` Array [ Array [ "chmodSync", "{tmpfile}", "438", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > handle EPERMs, chmod raises something other than ENOENT > async > must match snapshot 1`] = ` Array [] ` exports[`test/rimraf-move-remove.ts > TAP > handle EPERMs, chmod raises something other than ENOENT > sync > must match snapshot 1`] = ` Array [ Array [ "chmodSync", "{tmpfile}", "438", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > handle EPERMs, chmod returns ENOENT > async > must match snapshot 1`] = ` Array [ Array [ "chmod", "{tmpfile}", "438", ], ] ` exports[`test/rimraf-move-remove.ts > TAP > handle EPERMs, chmod returns ENOENT > sync > must match snapshot 1`] = ` Array [ Array [ "chmodSync", "{tmpfile}", "438", ], ] ` isaacs-rimraf-4c5e478/tap-snapshots/test/rimraf-native.ts.test.cjs000066400000000000000000000012021514446574700252470ustar00rootroot00000000000000/* IMPORTANT * This snapshot file is auto-generated, but designed for humans. * It should be checked into source control and tracked carefully. * Re-generate by setting TAP_SNAPSHOT=1 and running tests. * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' exports[`test/rimraf-native.ts > TAP > calls the right node function > must match snapshot 1`] = ` Array [ Array [ "rm", "path", Object { "force": true, "recursive": true, "x": "y", }, ], Array [ "rmSync", "path", Object { "a": "b", "force": true, "recursive": true, }, ], ] ` isaacs-rimraf-4c5e478/tap-snapshots/test/rimraf-posix.ts.test.cjs000066400000000000000000000153531514446574700251370ustar00rootroot00000000000000/* IMPORTANT * This snapshot file is auto-generated, but designed for humans. * It should be checked into source control and tracked carefully. * Re-generate by setting TAP_SNAPSHOT=1 and running tests. * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' exports[`test/rimraf-posix.ts > TAP > filter function > filter=i > async > paths seen 1`] = ` Array [ ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/a", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/b", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/d", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/e", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/g", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/h", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/i", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/i/j", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/i/k", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/i/l", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/i/m", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/i/m/n", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async/c/f/i/m/o", ] ` exports[`test/rimraf-posix.ts > TAP > filter function > filter=i > async filter > paths seen 1`] = ` Array [ ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/a", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/b", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/d", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/e", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/g", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/h", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/i", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/i/j", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/i/k", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/i/l", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/i/m", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/i/m/n", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-async-filter/c/f/i/m/o", ] ` exports[`test/rimraf-posix.ts > TAP > filter function > filter=i > sync > paths seen 1`] = ` Array [ ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/a", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/b", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/d", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/e", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/g", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/h", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/i", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/i/j", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/i/k", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/i/l", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/i/m", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/i/m/n", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-i-sync/c/f/i/m/o", ] ` exports[`test/rimraf-posix.ts > TAP > filter function > filter=j > async > paths seen 1`] = ` Array [ ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/a", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/b", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/d", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/e", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/g", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/h", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/i/j", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/i/k", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/i/l", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/i/m", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/i/m/n", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async/c/f/i/m/o", ] ` exports[`test/rimraf-posix.ts > TAP > filter function > filter=j > async filter > paths seen 1`] = ` Array [ ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/a", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/b", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/d", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/e", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/g", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/h", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/i/j", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/i/k", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/i/l", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/i/m", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/i/m/n", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-async-filter/c/f/i/m/o", ] ` exports[`test/rimraf-posix.ts > TAP > filter function > filter=j > sync > paths seen 1`] = ` Array [ ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/a", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/b", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/d", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/e", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/g", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/h", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/i/j", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/i/k", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/i/l", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/i/m", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/i/m/n", ".tap/fixtures/test-rimraf-posix.ts-filter-function-filter-j-sync/c/f/i/m/o", ] ` isaacs-rimraf-4c5e478/tap-snapshots/test/rimraf-windows.ts.test.cjs000066400000000000000000000200671514446574700254650ustar00rootroot00000000000000/* IMPORTANT * This snapshot file is auto-generated, but designed for humans. * It should be checked into source control and tracked carefully. * Re-generate by setting TAP_SNAPSHOT=1 and running tests. * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' exports[`test/rimraf-windows.ts > TAP > filter function > filter=i > async > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/a", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/b", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/d", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/e", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/g", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/h", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/i", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/i/k", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/i/l", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/i/m", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/i/m/n", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async/c/f/i/m/o", ], ] ` exports[`test/rimraf-windows.ts > TAP > filter function > filter=i > async filter > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/a", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/b", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/d", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/e", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/g", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/h", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/i", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/i/k", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/i/l", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/i/m", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/i/m/n", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-async-filter/c/f/i/m/o", ], ] ` exports[`test/rimraf-windows.ts > TAP > filter function > filter=i > sync > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/a", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/b", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/d", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/e", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/g", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/h", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/i", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/i/k", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/i/l", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/i/m", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/i/m/n", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-i-sync/c/f/i/m/o", ], ] ` exports[`test/rimraf-windows.ts > TAP > filter function > filter=j > async > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/a", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/b", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/d", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/e", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/g", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/h", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/i/k", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/i/l", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/i/m", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/i/m/n", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async/c/f/i/m/o", ], ] ` exports[`test/rimraf-windows.ts > TAP > filter function > filter=j > async filter > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/a", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/b", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/d", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/e", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/g", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/h", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/i/k", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/i/l", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/i/m", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/i/m/n", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-async-filter/c/f/i/m/o", ], ] ` exports[`test/rimraf-windows.ts > TAP > filter function > filter=j > sync > paths seen 1`] = ` Array [ Array [ ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/a", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/b", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/d", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/e", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/g", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/h", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/i/j", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/i/k", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/i/l", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/i/m", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/i/m/n", ".tap/fixtures/test-rimraf-windows.ts-filter-function-filter-j-sync/c/f/i/m/o", ], ] ` exports[`test/rimraf-windows.ts > TAP > handle EPERMs on unlink by trying to chmod 0o666 > async > chmods 1`] = ` 1 ` exports[`test/rimraf-windows.ts > TAP > handle EPERMs on unlink by trying to chmod 0o666 > sync > chmods 1`] = ` 1 ` exports[`test/rimraf-windows.ts > TAP > handle EPERMs, chmod raises something other than ENOENT > async > chmods 1`] = ` 0 ` exports[`test/rimraf-windows.ts > TAP > handle EPERMs, chmod raises something other than ENOENT > sync > chmods 1`] = ` 1 ` exports[`test/rimraf-windows.ts > TAP > handle EPERMs, chmod returns ENOENT > async > chmods 1`] = ` 1 ` exports[`test/rimraf-windows.ts > TAP > handle EPERMs, chmod returns ENOENT > sync > chmods 1`] = ` 1 ` isaacs-rimraf-4c5e478/test/000077500000000000000000000000001514446574700156005ustar00rootroot00000000000000isaacs-rimraf-4c5e478/test/bin.ts000066400000000000000000000260111514446574700167200ustar00rootroot00000000000000import { spawn, spawnSync } from 'child_process' import { Dirent, readdirSync, statSync } from 'fs' import t from 'tap' import { RimrafOptions } from '../src/index.js' import { basename, join, resolve } from 'path' import { loadPackageJson } from 'package-json-from-dist' const { version } = loadPackageJson( import.meta.url, '../package.json', ) as { version: string } // Have to use the dist file otherwise coverage doesn't work // Could be a tap bug or misconfiguration? const SRC_DIR = '../dist/esm' const binDist = join(SRC_DIR, 'bin.mjs') const spawnSyncBin = (args: string[]) => spawnSync( process.execPath, [resolve(import.meta.dirname, binDist), ...args], { encoding: 'utf8', timeout: 10_000, }, ) const spawnBin = (args: string[]) => { const child = spawn( process.execPath, [resolve(import.meta.dirname, binDist), ...args], { stdio: 'pipe', signal: AbortSignal.timeout(10_000), }, ) child.stdout.setEncoding('utf8') child.stderr.setEncoding('utf8') return child } const mockBin = async ( argv: string[], mocks: Record, ): Promise => new Promise(res => { t.intercept(process, 'argv', { value: [process.execPath, basename(binDist), ...argv], }) t.intercept(process, 'exit', { value: (code: number) => res(code) }) void t.mockImport(binDist, mocks) }) t.test('basic arg parsing stuff', async t => { const impls = new Map([ ['rimraf', 'rimraf'], ['native', 'native'], ['manual', 'manual'], ['posix', 'posix'], ['windows', 'windows'], ['moveRemove', 'move-remove'], ]) const CALLS: [string, string, RimrafOptions][] = [] t.afterEach(() => (CALLS.length = 0)) const { rimraf, ...mocks } = [...impls.entries()].reduce< Record Promise> >((acc, [k, v]) => { acc[k] = async (path, opt) => CALLS.push([v, path, opt]) return acc }, {}) const logs = t.capture(console, 'log').args const errs = t.capture(console, 'error').args const bin = (...argv: string[]) => mockBin(argv, { [join(SRC_DIR, 'index.js')]: { rimraf: Object.assign(rimraf!, mocks), ...mocks, }, }) t.test('binary version', t => { const cases = [['--version'], ['a', 'b', '--version', 'c']] for (const c of cases) { t.test(c.join(' '), async t => { t.equal(await bin(...c), 0) t.strictSame(logs(), [[version]]) t.strictSame(errs(), []) t.same(CALLS, []) }) } t.end() }) t.test('helpful output', t => { const cases = [['-h'], ['--help'], ['a', 'b', '--help', 'c']] for (const c of cases) { t.test(c.join(' '), async t => { t.equal(await bin(...c), 0) const l = logs() t.equal(l.length, 1) t.match(l[0]![0], `rimraf version ${version}`) t.strictSame(errs(), []) t.same(CALLS, []) }) } t.end() }) t.test('no paths', async t => { t.equal(await bin(), 1) t.strictSame(logs(), []) t.strictSame(errs(), [ ['rimraf: must provide a path to remove'], ['run `rimraf --help` for usage information'], ]) }) t.test('unnecessary -rf', async t => { t.equal(await bin('-rf', 'foo'), 0) t.equal(await bin('-fr', 'foo'), 0) t.equal(await bin('foo', '-rf'), 0) t.equal(await bin('foo', '-fr'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [ ['rimraf', ['foo'], {}], ['rimraf', ['foo'], {}], ['rimraf', ['foo'], {}], ['rimraf', ['foo'], {}], ]) }) t.test('verbose', async t => { t.equal(await bin('-v', 'foo'), 0) t.equal(await bin('--verbose', 'foo'), 0) t.equal(await bin('-v', '-V', '--verbose', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) for (const c of CALLS) { t.equal(c[0], 'rimraf') t.same(c[1], ['foo']) t.type(c[2].filter, 'function') t.equal(c[2].filter?.('x', new Dirent()), true) t.strictSame(logs(), [['x']]) } }) t.test('silent', async t => { t.equal(await bin('-V', 'foo'), 0) t.equal(await bin('--no-verbose', 'foo'), 0) t.equal(await bin('-V', '-v', '--no-verbose', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) for (const c of CALLS) { t.equal(c[0], 'rimraf') t.same(c[1], ['foo']) t.type(c[2].filter, 'undefined') t.strictSame(logs(), []) } }) t.test('glob true', async t => { t.equal(await bin('-g', 'foo'), 0) t.equal(await bin('--glob', 'foo'), 0) t.equal(await bin('-G', '-g', 'foo'), 0) t.equal(await bin('-g', '-G', 'foo'), 0) t.equal(await bin('-G', 'foo'), 0) t.equal(await bin('--no-glob', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [ ['rimraf', ['foo'], { glob: true }], ['rimraf', ['foo'], { glob: true }], ['rimraf', ['foo'], { glob: true }], ['rimraf', ['foo'], { glob: false }], ['rimraf', ['foo'], { glob: false }], ['rimraf', ['foo'], { glob: false }], ]) }) t.test('dashdash', async t => { t.equal(await bin('--', '-h'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['-h'], {}]]) }) t.test('no preserve root', async t => { t.equal(await bin('--no-preserve-root', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['foo'], { preserveRoot: false }]]) }) t.test('yes preserve root', async t => { t.equal(await bin('--preserve-root', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['foo'], { preserveRoot: true }]]) }) t.test('yes preserve root, remove root', async t => { t.equal(await bin('/'), 1) t.strictSame(logs(), []) t.strictSame(errs(), [ [`rimraf: it is dangerous to operate recursively on '/'`], ['use --no-preserve-root to override this failsafe'], ]) t.same(CALLS, []) }) t.test('no preserve root, remove root', async t => { t.equal(await bin('/', '--no-preserve-root'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['/'], { preserveRoot: false }]]) }) t.test('--tmp=', async t => { t.equal(await bin('--tmp=some-path', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['foo'], { tmp: 'some-path' }]]) }) t.test('--tmp=', async t => { t.equal(await bin('--backoff=1.3', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['foo'], { backoff: 1.3 }]]) }) t.test('--max-retries=n', async t => { t.equal(await bin('--max-retries=100', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['foo'], { maxRetries: 100 }]]) }) t.test('--retry-delay=n', async t => { t.equal(await bin('--retry-delay=100', 'foo'), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [['rimraf', ['foo'], { retryDelay: 100 }]]) }) t.test('--uknown-option', async t => { t.equal(await bin('--unknown-option=100', 'foo'), 1) t.strictSame(logs(), []) t.strictSame(errs(), [ ['unknown option: --unknown-option=100'], ['run `rimraf --help` for usage information'], ]) t.same(CALLS, []) }) t.test('--impl=asdf', async t => { t.equal(await bin('--impl=asdf', 'foo'), 1) t.strictSame(logs(), []) t.strictSame(errs(), [ ['unknown implementation: asdf'], ['run `rimraf --help` for usage information'], ]) t.same(CALLS, []) }) t.test('native cannot do filters', async t => { t.equal(await bin('--impl=native', '-v', 'foo'), 1) t.strictSame(errs(), [ ['native implementation does not support -v or -i'], ['run `rimraf --help` for usage information'], ]) t.strictSame(errs(), []) t.equal(await bin('--impl=native', '-i', 'foo'), 1) t.strictSame(errs(), [ ['native implementation does not support -v or -i'], ['run `rimraf --help` for usage information'], ]) t.same(CALLS, []) t.strictSame(logs(), []) // ok to turn it on and back off though t.equal(await bin('--impl=native', '-i', '-I', 'foo'), 0) t.same(CALLS, [['native', ['foo'], {}]]) }) for (const impl of impls.values()) { t.test(`--impl=${impl}`, async t => { t.equal(await bin('foo', `--impl=${impl}`), 0) t.strictSame(logs(), []) t.strictSame(errs(), []) t.same(CALLS, [[impl, ['foo'], {}]]) }) } t.end() }) t.test('actually delete something with it', async t => { const path = t.testdir({ a: { b: { c: '1', }, }, }) const res = spawnSyncBin([path]) t.throws(() => statSync(path)) t.equal(res.status, 0) }) t.test('print failure when impl throws', async t => { const path = t.testdir({ a: { b: { c: '1', }, }, }) const err = new Error('simulated rimraf failure') const logs = t.capture(console, 'log').args const errs = t.capture(console, 'error').args const code = await mockBin([path], { [join(SRC_DIR, 'index.js')]: { rimraf: async () => { throw err }, }, }) t.strictSame(logs(), []) t.strictSame(errs(), [[err]]) t.equal(code, 1) t.equal(statSync(path).isDirectory(), true) }) t.test('interactive deletes', t => { const scripts = [ ['a'], ['y', 'YOLO', 'no', 'quit'], ['hehaha', 'yes i think so', '', 'A'], ['no', 'n', 'N', 'N', 'Q'], ] const fixture = { a: { b: '', c: '', d: '' }, b: { c: '', d: '', e: '' }, c: { d: '', e: '', f: '' }, } const verboseOpt = ['-v', '-V'] const leftovers = (d: string) => { try { readdirSync(d) return true } catch { return false } } for (const verbose of verboseOpt) { t.test(verbose, async t => { for (const s of scripts) { const script = s.slice() t.test(script.join(', '), async t => { const d = t.testdir(fixture) const child = spawnBin(['-i', verbose, d]) const out: string[] = [] const err: string[] = [] const last = '' child.stdout.on('data', (c: string) => { out.push(c.trim()) const s = script.shift() if (s !== undefined) { out.push(s.trim()) child.stdin.write(s + '\n') } else { // keep writing whatever the last option was child.stdin.write(last + '\n') } }) child.stderr.on('data', (c: string) => err.push(c)) return new Promise(res => { child.on( 'close', (code: number | null, signal: NodeJS.Signals | null) => { t.same(err, [], 'should not see any stderr') t.equal(code, 0, 'code') t.equal(signal, null, 'signal') t.matchSnapshot(leftovers(d), 'had any leftover') res() }, ) }) }) } t.end() }) } t.end() }) isaacs-rimraf-4c5e478/test/default-tmp.ts000066400000000000000000000033071514446574700203750ustar00rootroot00000000000000import t from 'tap' import { tmpdir } from 'os' import { win32 } from 'path' t.test('posix platform', async t => { t.intercept(process, 'platform', { value: 'posix' }) const { defaultTmp, defaultTmpSync } = (await t.mockImport( '../src/default-tmp.js', )) as typeof import('../src/default-tmp.js') t.equal(defaultTmpSync('anything'), tmpdir()) t.equal(await defaultTmp('anything').then(t => t), tmpdir()) }) t.test('windows', async t => { const tempDirCheck = (path: string) => { switch (path.toLowerCase()) { case 'd:\\temp': return { isDirectory: () => true } case 'e:\\temp': return { isDirectory: () => false } default: throw Object.assign(new Error('no ents here'), { code: 'ENOENT' }) } } t.intercept(process, 'platform', { value: 'win32' }) const { defaultTmp, defaultTmpSync } = (await t.mockImport( '../src/default-tmp.js', { os: { tmpdir: () => 'C:\\Windows\\Temp', }, path: win32, '../src/fs.js': { statSync: tempDirCheck, promises: { stat: async (path: string) => tempDirCheck(path), }, }, }, )) as typeof import('../src/default-tmp.js') const expect = { 'c:\\some\\path': 'C:\\Windows\\Temp', 'C:\\some\\path': 'C:\\Windows\\Temp', 'd:\\some\\path': 'd:\\temp', 'D:\\some\\path': 'D:\\temp', 'e:\\some\\path': 'e:\\', 'E:\\some\\path': 'E:\\', 'f:\\some\\path': 'f:\\', 'F:\\some\\path': 'F:\\', } for (const [path, tmp] of Object.entries(expect)) { t.test(`${path} -> ${tmp}`, async t => { t.equal(defaultTmpSync(path), tmp, 'sync') t.equal(await defaultTmp(path), tmp, 'async') }) } t.end() }) isaacs-rimraf-4c5e478/test/fix-eperm.ts000066400000000000000000000113541514446574700200500ustar00rootroot00000000000000import t from 'tap' t.test('works if it works', async t => { const { fixEPERM, fixEPERMSync } = (await t.mockImport( '../src/fix-eperm.js', )) as typeof import('../src/fix-eperm.js') let res: null | number = null await fixEPERM(async () => (res = 1))('x') t.equal(res, 1) fixEPERMSync(() => (res = 2))('x') t.equal(res, 2) }) t.test('throw non-EPERM just throws', async t => { const { fixEPERM, fixEPERMSync } = (await t.mockImport( '../src/fix-eperm.js', )) as typeof import('../src/fix-eperm.js') const fixed = fixEPERM(() => { throw new Error('oops') }) await t.rejects(fixed('x'), new Error('oops')) const fixedSync = fixEPERMSync(() => { throw new Error('oops') }) t.throws(() => fixedSync('x'), new Error('oops')) }) t.test('throw ENOENT returns void', async t => { const er = Object.assign(new Error('no ents'), { code: 'ENOENT' }) const { fixEPERM, fixEPERMSync } = (await t.mockImport( '../src/fix-eperm.js', )) as typeof import('../src/fix-eperm.js') const fixed = fixEPERM(async () => { throw er }) await fixed('x').then(n => t.equal(n, undefined)) const fixedSync = fixEPERMSync(() => { throw er }) t.equal(fixedSync('x'), undefined) }) t.test('chmod and try again', async t => { const seen = new Set() const finished = new Set() const eperm = Object.assign(new Error('perm'), { code: 'EPERM' }) const method = (p: string) => { if (!seen.has(p)) { seen.add(p) throw eperm } else { t.equal(chmods.has(p), true) t.equal(finished.has(p), false) finished.add(p) } } const asyncMethod = async (p: string) => method(p) const chmods = new Set() const chmodSync = (p: string, mode: number) => { t.equal(chmods.has(p), false) chmods.add(p) t.equal(mode, 0o666) } const chmod = async (p: string, mode: number) => chmodSync(p, mode) const { fixEPERM, fixEPERMSync } = (await t.mockImport( '../src/fix-eperm.js', { '../src/fs.js': { promises: { chmod }, chmodSync, }, }, )) as typeof import('../src/fix-eperm.js') const fixed = fixEPERM(asyncMethod) const fixedSync = fixEPERMSync(method) await fixed('async').then(n => t.equal(n, undefined)) t.equal(fixedSync('sync'), undefined) t.equal(chmods.size, 2) t.equal(seen.size, 2) t.equal(finished.size, 2) }) t.test('chmod ENOENT is fine, abort', async t => { const seen = new Set() const finished = new Set() const eperm = Object.assign(new Error('perm'), { code: 'EPERM' }) const method = (p: string) => { if (!seen.has(p)) { seen.add(p) throw eperm } else { t.equal(chmods.has(p), true) t.equal(finished.has(p), false) finished.add(p) } } const asyncMethod = async (p: string) => method(p) const chmods = new Set() const chmodSync = (p: string, mode: number) => { t.equal(chmods.has(p), false) chmods.add(p) t.equal(mode, 0o666) throw Object.assign(new Error('no ent'), { code: 'ENOENT' }) } const chmod = async (p: string, mode: number) => chmodSync(p, mode) const { fixEPERM, fixEPERMSync } = (await t.mockImport( '../src/fix-eperm.js', { '../src/fs.js': { promises: { chmod }, chmodSync, }, }, )) as typeof import('../src/fix-eperm.js') const fixed = fixEPERM(asyncMethod) const fixedSync = fixEPERMSync(method) await fixed('async').then(n => t.equal(n, undefined)) t.equal(fixedSync('sync'), undefined) t.equal(chmods.size, 2) t.equal(seen.size, 2) t.equal(finished.size, 0) }) t.test('chmod other than ENOENT is failure', async t => { const seen = new Set() const finished = new Set() const eperm = Object.assign(new Error('perm'), { code: 'EPERM' }) const method = (p: string) => { if (!seen.has(p)) { seen.add(p) throw eperm } else { t.equal(chmods.has(p), true) t.equal(finished.has(p), false) finished.add(p) } } const asyncMethod = async (p: string) => method(p) const chmods = new Set() const chmodSync = (p: string, mode: number) => { t.equal(chmods.has(p), false) chmods.add(p) t.equal(mode, 0o666) throw Object.assign(new Error('ent bro'), { code: 'OHNO' }) } const chmod = async (p: string, mode: number) => chmodSync(p, mode) const { fixEPERM, fixEPERMSync } = (await t.mockImport( '../src/fix-eperm.js', { '../src/fs.js': { promises: { chmod }, chmodSync, }, }, )) as typeof import('../src/fix-eperm.js') const fixed = fixEPERM(asyncMethod) const fixedSync = fixEPERMSync(method) await t.rejects(fixed('async'), { code: 'EPERM' }) t.throws(() => fixedSync('sync'), { code: 'EPERM' }) t.equal(chmods.size, 2) t.equal(seen.size, 2) t.equal(finished.size, 0) }) isaacs-rimraf-4c5e478/test/fs.ts000066400000000000000000000066321514446574700165670ustar00rootroot00000000000000import t, { Test } from 'tap' // verify that every function in the root is *Sync, and every // function is fs.promises is the promisified version of fs[method], // and that when the cb returns an error, the promised version fails, // and when the cb returns data, the promisified version resolves to it. import realFS from 'fs' import realFSP from 'fs/promises' import * as fs from '../src/fs.js' import { useNative } from '../src/use-native.js' type MockCb = (e: Error | null, m?: string) => void type MockFsCb = Record void> type MockFsPromise = Record Promise> const mockFs = async ( t: Test, fs: MockFsCb = {}, fsp: MockFsPromise = {}, ) => (await t.mockImport('../src/fs.js', { fs: t.createMock(realFS, fs), 'fs/promises': t.createMock(realFSP, fsp), })) as typeof import('../src/fs.js') const mockFSMethodPass = (method: string) => (...args: unknown[]) => { process.nextTick(() => (args.at(-1) as MockCb)(null, method)) } const mockFSPromiseMethodPass = (_method: string) => () => new Promise((resolve, _reject) => { resolve() }) const mockFSMethodFail = (_: string) => (...args: unknown[]) => { process.nextTick(() => (args.at(-1) as MockCb)(new Error('oops'))) } const mockFSPromiseMethodFail = (_method: string) => () => new Promise((_resolve, reject) => { reject(new Error('oops')) }) t.type(fs.promises, Object) const mockFSPass: MockFsCb = {} const mockFSFail: MockFsCb = {} const mockFSPromisesFail: MockFsPromise = {} const mockFSPromisesPass: MockFsPromise = {} for (const method of Object.keys(fs.promises)) { // of course fs.rm is missing when we shouldn't use native :) // also, readdirSync is clubbed to always return file types if (method !== 'rm' || useNative()) { t.type( (realFS as unknown as MockFsCb)[method], Function, `real fs.${method} is a function`, ) if (method !== 'readdir') { t.equal( (fs as unknown as MockFsCb)[`${method}Sync`], (realFS as unknown as MockFsCb)[`${method}Sync`], `has ${method}Sync`, ) } } // set up our pass/fails for the next tests mockFSPass[method] = mockFSMethodPass(method) mockFSPromisesPass[method] = mockFSPromiseMethodPass(method) mockFSFail[method] = mockFSMethodFail(method) mockFSPromisesFail[method] = mockFSPromiseMethodFail(method) } // doesn't have any sync versions that aren't promisified for (const method of Object.keys(fs)) { if (method === 'promises') { continue } const m = method.replace(/Sync$/, '') t.type( (fs.promises as unknown as MockFsCb)[m], Function, `fs.promises.${m} is a function`, ) } t.test('passing resolves promise', async t => { const fs = await mockFs(t, mockFSPass, mockFSPromisesPass) for (const [m, fn] of Object.entries( fs.promises as unknown as MockFsPromise, )) { t.same(await fn(), undefined, `${m} is a Promise method`) } }) t.test('failing rejects promise', async t => { const fs = await mockFs(t, mockFSFail, mockFSPromisesFail) for (const [m, fn] of Object.entries( fs.promises as unknown as MockFsPromise, )) { t.rejects(fn(), { message: 'oops' }, `got expected value for ${m}`) } }) t.test('readdirSync', async t => { const args: unknown[][] = [] const fs = await mockFs(t, { readdirSync: (...a) => args.push(a) }) fs.readdirSync('x') t.strictSame(args, [['x', { withFileTypes: true }]]) }) isaacs-rimraf-4c5e478/test/ignore-enoent.ts000066400000000000000000000021111514446574700207140ustar00rootroot00000000000000import t from 'tap' import { ignoreENOENT, ignoreENOENTSync } from '../src/ignore-enoent.js' const enoent = () => Object.assign(new Error('no ent'), { code: 'ENOENT' }) const eperm = () => Object.assign(new Error('eperm'), { code: 'EPERM' }) t.test('async', async t => { t.resolves(ignoreENOENT(Promise.reject(enoent())), 'enoent is fine') t.rejects( ignoreENOENT(Promise.reject(eperm())), { code: 'EPERM' }, 'eperm is not', ) const rethrow = new Error('rethrow') t.rejects( ignoreENOENT(Promise.reject(eperm()), rethrow), rethrow, 'or rethrows passed in error', ) }) t.test('sync', t => { const throwEnoent = () => { throw enoent() } const throwEperm = () => { throw eperm() } t.doesNotThrow( () => ignoreENOENTSync(throwEnoent), 'enoent is fine sync', ) t.throws( () => ignoreENOENTSync(throwEperm), { code: 'EPERM' }, 'eperm is not fine sync', ) const rethrow = new Error('rethrow') t.throws( () => ignoreENOENTSync(throwEperm, rethrow), rethrow, 'or rethrows passed in error', ) t.end() }) isaacs-rimraf-4c5e478/test/index.ts000066400000000000000000000145211514446574700172620ustar00rootroot00000000000000import { statSync } from 'fs' import { resolve } from 'path' import t from 'tap' import { rimraf, RimrafAsyncOptions, RimrafOptions, rimrafSync, RimrafSyncOptions, } from '../src/index.js' import * as OPTARG from '../dist/esm/opt-arg.js' t.test('mocky unit tests to select the correct function', async t => { // don't mock rimrafManual, so we can test the platform switch const CALLS: any[] = [] let USE_NATIVE = true const mocks = { '../dist/esm/use-native.js': { useNative: (opt: RimrafOptions) => { CALLS.push(['useNative', opt]) return USE_NATIVE }, useNativeSync: (opt: RimrafOptions) => { CALLS.push(['useNativeSync', opt]) return USE_NATIVE }, }, '../dist/esm/path-arg.js': (path: string) => { CALLS.push(['pathArg', path]) return path }, '../dist/esm/opt-arg.js': { ...OPTARG, optArg: (opt: RimrafOptions) => { CALLS.push(['optArg', opt]) return opt }, optArgSync: (opt: RimrafOptions) => { CALLS.push(['optArg', opt]) return opt }, }, '../dist/esm/rimraf-posix.js': { rimrafPosix: async (path: string, opt: RimrafOptions) => { CALLS.push(['rimrafPosix', path, opt]) }, rimrafPosixSync: async (path: string, opt: RimrafOptions) => { CALLS.push(['rimrafPosixSync', path, opt]) }, }, '../dist/esm/rimraf-windows.js': { rimrafWindows: async (path: string, opt: RimrafOptions) => { CALLS.push(['rimrafWindows', path, opt]) }, rimrafWindowsSync: async (path: string, opt: RimrafOptions) => { CALLS.push(['rimrafWindowsSync', path, opt]) }, }, '../dist/esm/rimraf-native.js': { rimrafNative: async (path: string, opt: RimrafOptions) => { CALLS.push(['rimrafNative', path, opt]) }, rimrafNativeSync: async (path: string, opt: RimrafOptions) => { CALLS.push(['rimrafNativeSync', path, opt]) }, }, } t.intercept(process, 'platform', { value: 'posix' }) const { rimraf } = (await t.mockImport( '../dist/esm/index.js', mocks, )) as typeof import('../dist/esm/index.js') t.afterEach(() => (CALLS.length = 0)) for (const useNative of [true, false]) { t.test(`main function, useNative=${useNative}`, t => { USE_NATIVE = useNative rimraf('path', { a: 1 } as unknown as RimrafAsyncOptions) rimraf.sync('path', { a: 2 } as unknown as RimrafSyncOptions) t.equal(rimraf.rimraf, rimraf) t.equal(rimraf.rimrafSync, rimraf.sync) t.matchSnapshot(CALLS) t.end() }) } t.test('manual', t => { rimraf.manual('path', { a: 3 } as unknown as RimrafAsyncOptions) rimraf.manual.sync('path', { a: 4 } as unknown as RimrafSyncOptions) t.equal(rimraf.manualSync, rimraf.manual.sync) t.matchSnapshot(CALLS) t.end() }) t.test('native', t => { rimraf.native('path', { a: 5 } as unknown as RimrafAsyncOptions) rimraf.native.sync('path', { a: 6 } as unknown as RimrafSyncOptions) t.equal(rimraf.nativeSync, rimraf.native.sync) t.matchSnapshot(CALLS) t.end() }) t.test('posix', t => { rimraf.posix('path', { a: 7 } as unknown as RimrafAsyncOptions) rimraf.posix.sync('path', { a: 8 } as unknown as RimrafSyncOptions) t.equal(rimraf.posixSync, rimraf.posix.sync) t.matchSnapshot(CALLS) t.end() }) t.test('windows', t => { rimraf.windows('path', { a: 9 } as unknown as RimrafAsyncOptions) rimraf.windows.sync('path', { a: 10 } as unknown as RimrafSyncOptions) t.equal(rimraf.windowsSync, rimraf.windows.sync) t.matchSnapshot(CALLS) t.end() }) t.end() }) t.test('actually delete some stuff', t => { const fixture = { a: 'a', b: 'b', c: { d: 'd', e: 'e', f: { g: 'g', h: 'h', i: { j: 'j', k: 'k', l: 'l', m: { n: 'n', o: 'o', }, }, }, }, } t.test('sync', t => { const path = t.testdir(fixture) rimraf.sync(path) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') t.end() }) t.test('async', async t => { const path = t.testdir(fixture) await rimraf(path) t.throws(() => statSync(path), { code: 'ENOENT' }) }) t.end() }) t.test('accept array of paths as first arg', async t => { const ASYNC_CALLS: any[] = [] const SYNC_CALLS: any[] = [] const { rimraf, rimrafSync } = (await t.mockImport( '../dist/esm/index.js', { '../dist/esm/use-native.js': { useNative: () => true, useNativeSync: () => true, }, '../dist/esm/rimraf-native.js': { rimrafNative: async (path: string, opt: RimrafOptions) => ASYNC_CALLS.push([path, opt]), rimrafNativeSync: (path: string, opt: RimrafOptions) => SYNC_CALLS.push([path, opt]), }, }, )) as typeof import('../dist/esm/index.js') t.equal(await rimraf(['a', 'b', 'c']), true) t.equal( await rimraf(['i', 'j', 'k'], { x: 'ya' } as unknown as RimrafOptions), true, ) t.same(ASYNC_CALLS, [ [resolve('a'), {}], [resolve('b'), {}], [resolve('c'), {}], [resolve('i'), { x: 'ya' }], [resolve('j'), { x: 'ya' }], [resolve('k'), { x: 'ya' }], ]) t.equal(rimrafSync(['x', 'y', 'z']), true) t.equal( rimrafSync(['m', 'n', 'o'], { cat: 'chai', } as unknown as RimrafSyncOptions), true, ) t.same(SYNC_CALLS, [ [resolve('x'), {}], [resolve('y'), {}], [resolve('z'), {}], [resolve('m'), { cat: 'chai' }], [resolve('n'), { cat: 'chai' }], [resolve('o'), { cat: 'chai' }], ]) }) t.test('deleting globs', async t => { const fixture = { a: 'a', b: 'b', c: { d: 'd', e: 'e', f: { g: 'g', h: 'h', i: { j: 'j', k: 'k', l: 'l', m: { n: 'n', o: 'o', }, }, }, }, } t.test('sync', t => { const cwd = t.testdir(fixture) rimrafSync('**/f/**/m', { glob: { cwd } }) t.throws(() => statSync(cwd + '/c/f/i/m')) statSync(cwd + '/c/f/i/l') t.end() }) t.test('async', async t => { const cwd = t.testdir(fixture) await rimraf('**/f/**/m', { glob: { cwd } }) t.throws(() => statSync(cwd + '/c/f/i/m')) statSync(cwd + '/c/f/i/l') }) t.end() }) isaacs-rimraf-4c5e478/test/integration/000077500000000000000000000000001514446574700201235ustar00rootroot00000000000000isaacs-rimraf-4c5e478/test/integration/delete-many-files.ts000066400000000000000000000044741514446574700240100ustar00rootroot00000000000000// this isn't for coverage. it's basically a smoke test, to ensure that // we can delete a lot of files on CI in multiple platforms and node versions. import t from 'tap' import { statSync, mkdirSync, readdirSync } from '../../src/fs.js' import { writeFileSync } from 'fs' import { resolve, dirname } from 'path' import { manual } from '../../src/index.js' import { setTimeout } from 'timers/promises' const cases = { manual } // run with RIMRAF_TEST_START_CHAR/_END_CHAR/_DEPTH environs to // make this more or less aggressive. const START = (process.env.RIMRAF_TEST_START_CHAR || 'a').charCodeAt(0) const END = (process.env.RIMRAF_TEST_END_CHAR || 'f').charCodeAt(0) const DEPTH = +(process.env.RIMRAF_TEST_DEPTH || '') || 4 const create = (path: string, depth = 0) => { mkdirSync(path) for (let i = START; i <= END; i++) { const c = String.fromCharCode(i) if (depth < DEPTH && i - START >= depth) { create(resolve(path, c), depth + 1) } else { writeFileSync(resolve(path, c), c) } } return path } const base = t.testdir( Object.fromEntries( Object.entries(cases).map(([name]) => [ name, { sync: {}, async: {}, }, ]), ), ) t.test('create all fixtures', async t => { for (const name of Object.keys(cases)) { for (const type of ['sync', 'async']) { const path = `${base}/${name}/${type}/test` create(path) t.equal( statSync(path).isDirectory(), true, `${name}/${type} created`, ) } } await setTimeout(3000) }) t.test('delete all fixtures', t => { for (const [name, rimraf] of Object.entries(cases)) { t.test(name, t => { t.test('async', async t => { const path = `${base}/${name}/async/test` await rimraf(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'fully removed') t.same( readdirSync(dirname(path)), [], 'no temp entries left behind', ) }) t.test('sync', t => { const path = `${base}/${name}/sync/test` rimraf.sync(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'fully removed') t.same( readdirSync(dirname(path)), [], 'no temp entries left behind', ) t.end() }) t.end() }) } t.end() }) isaacs-rimraf-4c5e478/test/opt-arg.ts000066400000000000000000000102161514446574700175210ustar00rootroot00000000000000import t from 'tap' import { optArg as oa, optArgSync as oas } from '../dist/esm/opt-arg.js' import { RimrafAsyncOptions, RimrafSyncOptions } from '../src/index.js' const asyncOpt = { a: 1 } as unknown as RimrafAsyncOptions const syncOpt = { s: 1 } as unknown as RimrafSyncOptions t.same(oa(asyncOpt), asyncOpt, 'returns equivalent object if provided') t.same(oas(syncOpt), oa(syncOpt), 'optArgSync does the same thing') t.same(oa(), {}, 'returns new object otherwise') t.same(oas(), {}, 'returns new object otherwise, sync') //@ts-expect-error t.throws(() => oa(true)) //@ts-expect-error t.throws(() => oa(null)) //@ts-expect-error t.throws(() => oa('hello')) //@ts-expect-error t.throws(() => oa({ maxRetries: 'banana' })) t.test('every kind of invalid option value', t => { // skip them when it's undefined, and skip the case // where they're all undefined, otherwise try every // possible combination of the values here. const badBool = [undefined, 1, null, 'x', {}] const badNum = [undefined, true, false, null, 'x', '1', {}] const badStr = [ undefined, { toString: () => 'hi' }, /hi/, Symbol.for('hi'), ] for (const preserveRoot of badBool) { for (const tmp of badStr) { for (const maxRetries of badNum) { for (const retryDelay of badNum) { for (const backoff of badNum) { for (const maxBackoff of badNum) { if ( preserveRoot === undefined && maxRetries === undefined && retryDelay === undefined && backoff === undefined && maxBackoff === undefined && tmp === undefined ) { continue } t.throws(() => oa({ //@ts-expect-error preserveRoot, //@ts-expect-error maxRetries, //@ts-expect-error retryDelay, //@ts-expect-error backoff, //@ts-expect-error maxBackoff, //@ts-expect-error tmp, }), ) } } } } } } t.end() }) t.test('test every allowed combination', t => { const goodBool = [undefined, true, false] // note that a few of these actually aren't *valid*, // but it's verifying what the initial opt checker does. const goodNum = [undefined, 1, Math.pow(2, 32), -1] const goodStr = [undefined, 'hi'] for (const preserveRoot of goodBool) { for (const tmp of goodStr) { for (const maxRetries of goodNum) { for (const retryDelay of goodNum) { for (const backoff of goodNum) { for (const maxBackoff of goodNum) { t.ok( oa({ preserveRoot, maxRetries, retryDelay, backoff, maxBackoff, tmp, }), ) } } } } } } t.end() }) t.test('glob option handling', t => { t.same(oa({ glob: true }), { glob: { absolute: true, withFileTypes: false }, }) const gws = oa({ signal: { x: 1 } as unknown as AbortSignal, glob: true, }) t.same(gws, { signal: { x: 1 }, glob: { absolute: true, signal: { x: 1 }, withFileTypes: false }, }) t.equal(gws.signal, gws.glob?.signal) t.same(oa({ glob: { nodir: true } }), { glob: { absolute: true, nodir: true, withFileTypes: false }, }) const gwsg = oa({ signal: { x: 1 } as unknown as AbortSignal, glob: { nodir: true }, }) t.same(gwsg, { signal: { x: 1 }, glob: { absolute: true, nodir: true, withFileTypes: false, signal: { x: 1 }, }, }) t.equal(gwsg.signal, gwsg.glob?.signal) t.same( oa({ signal: { x: 1 } as unknown as AbortSignal, glob: { nodir: true, signal: { y: 1 } as unknown as AbortSignal }, }), { signal: { x: 1 }, glob: { absolute: true, nodir: true, signal: { y: 1 }, withFileTypes: false, }, }, ) t.end() }) isaacs-rimraf-4c5e478/test/path-arg.ts000066400000000000000000000044641514446574700176630ustar00rootroot00000000000000import * as PATH from 'path' import t from 'tap' import { inspect } from 'util' for (const platform of ['win32', 'posix'] as const) { t.test(platform, async t => { t.intercept(process, 'platform', { value: platform }) const path = PATH[platform] || PATH const { default: pathArg } = (await t.mockImport( '../src/path-arg.js', { path, }, )) as typeof import('../src/path-arg.js') t.equal(pathArg('a/b/c'), path.resolve('a/b/c')) t.throws( () => pathArg('a\0b'), Error('path must be a string without null bytes'), ) if (platform === 'win32') { const badPaths = [ 'c:\\a\\b:c', 'c:\\a\\b*c', 'c:\\a\\b?c', 'c:\\a\\bc', 'c:\\a\\b|c', 'c:\\a\\b"c', ] for (const path of badPaths) { const er = Object.assign(new Error('Illegal characters in path'), { path, code: 'EINVAL', }) t.throws(() => pathArg(path), er) } } t.throws(() => pathArg('/'), { code: 'ERR_PRESERVE_ROOT' }) t.throws(() => pathArg('/', { preserveRoot: undefined }), { code: 'ERR_PRESERVE_ROOT', }) t.equal(pathArg('/', { preserveRoot: false }), path.resolve('/')) //@ts-expect-error t.throws(() => pathArg({}), { code: 'ERR_INVALID_ARG_TYPE', path: {}, message: 'The "path" argument must be of type string. ' + 'Received an instance of Object', name: 'TypeError', }) //@ts-expect-error t.throws(() => pathArg([]), { code: 'ERR_INVALID_ARG_TYPE', path: [], message: 'The "path" argument must be of type string. ' + 'Received an instance of Array', name: 'TypeError', }) //@ts-expect-error t.throws(() => pathArg(Object.create(null) as object), { code: 'ERR_INVALID_ARG_TYPE', path: Object.create(null) as object, message: 'The "path" argument must be of type string. ' + `Received ${inspect(Object.create(null))}`, name: 'TypeError', }) //@ts-expect-error t.throws(() => pathArg(true), { code: 'ERR_INVALID_ARG_TYPE', path: true, message: 'The "path" argument must be of type string. ' + `Received type boolean true`, name: 'TypeError', }) }) } isaacs-rimraf-4c5e478/test/readdir-or-error.ts000066400000000000000000000021631514446574700213310ustar00rootroot00000000000000import t from 'tap' import { readdirOrError, readdirOrErrorSync, } from '../src/readdir-or-error.js' const path = t.testdir({ file: 'file', empty: {}, full: { x: 'x', y: 'y', z: 'z', }, }) // [path, expected] const cases: [string, string[] | { code: string }][] = [ ['file', { code: 'ENOTDIR' }], ['empty', []], ['full', ['x', 'y', 'z']], ] for (const [c, expect] of cases) { t.test(c, async t => { const p = `${path}/${c}` const resAsync = await readdirOrError(p) const resSync = readdirOrErrorSync(p) if (Array.isArray(expect)) { if (!Array.isArray(resAsync)) { throw new Error('expected array async result') } if (!Array.isArray(resSync)) { throw new Error('expected array sync result') } t.same( resAsync.map(e => e.name).sort(), expect.sort(), 'got async result', ) t.same( resSync.map(e => e.name).sort(), expect.sort(), 'got sync result', ) } else { t.match(resAsync, expect, 'got async result') t.match(resSync, expect, 'got sync result') } }) } isaacs-rimraf-4c5e478/test/retry-busy.ts000066400000000000000000000060111514446574700202730ustar00rootroot00000000000000import { codes, MAXBACKOFF, MAXRETRIES, RATE, retryBusy, retryBusySync, } from '../src/retry-busy.js' import t from 'tap' t.matchSnapshot( { MAXBACKOFF, RATE, MAXRETRIES, codes, }, 'default settings', ) t.test('basic working operation when no errors happen', async t => { let calls = 0 const arg: string = 'path' const opt = {} const method = (a: string, b?: unknown) => { t.equal(a, arg, 'got first argument') t.equal(b, undefined, 'did not get another argument') calls++ } const asyncMethod = async (a: string, b?: unknown) => method(a, b) const rBS = retryBusySync(method) rBS(arg, opt) t.equal(calls, 1) const rB = retryBusy(asyncMethod) await rB(arg, opt).then(() => t.equal(calls, 2)) }) t.test('retry when known error code thrown', t => { t.plan(codes.size) for (const code of codes) { t.test(code, async t => { let thrown = false let calls = 0 const arg = 'path' const opt = {} const method = (a: string, b?: unknown) => { t.equal(a, arg, 'got first argument') t.equal(b, undefined, 'did not get another argument') if (!thrown) { thrown = true t.equal(calls, 0, 'first call') calls++ throw Object.assign(new Error(code), { path: a, code }) } else { t.equal(calls, 1, 'second call') calls++ thrown = false } } const asyncMethod = async (a: string, b?: unknown) => method(a, b) const rBS = retryBusySync(method) rBS(arg, opt) t.equal(calls, 2) calls = 0 const rB = retryBusy(asyncMethod) await rB(arg, opt).then(() => t.equal(calls, 2)) }) } }) t.test('retry and eventually give up', t => { t.plan(codes.size) const opt = { maxBackoff: 2, maxRetries: 2, } for (const code of codes) { t.test(code, async t => { let calls = 0 const arg = 'path' const method = (a: string, b?: unknown) => { t.equal(a, arg, 'got first argument') t.equal(b, undefined, 'did not get another argument') calls++ throw Object.assign(new Error(code), { path: a, code }) } const asyncMethod = async (a: string, b?: unknown) => method(a, b) const rBS = retryBusySync(method) t.throws(() => rBS(arg, opt), { path: arg, code }) t.equal(calls, 3) calls = 0 const rB = retryBusy(asyncMethod) await t.rejects(rB(arg, opt)).then(() => t.equal(calls, 3)) }) } }) t.test('throw unknown error gives up right away', async t => { const arg = 'path' const opt = {} const method = (a: string, b?: unknown) => { t.equal(a, arg, 'got first argument') t.equal(b, undefined, 'did not get another argument') throw Object.assign(new Error('nope')) } const asyncMethod = async (a: string, b?: unknown) => method(a, b) const rBS = retryBusySync(method) t.throws(() => rBS(arg, opt), { message: 'nope' }) const rB = retryBusy(asyncMethod) await t.rejects(rB(arg, opt), { message: 'nope' }) }) isaacs-rimraf-4c5e478/test/rimraf-manual.ts000066400000000000000000000014321514446574700207030ustar00rootroot00000000000000import t from 'tap' import { rimrafPosix, rimrafPosixSync } from '../src/rimraf-posix.js' import { rimrafWindows, rimrafWindowsSync } from '../src/rimraf-windows.js' for (const platform of ['win32', 'posix']) { t.test(platform, async t => { t.intercept(process, 'platform', { value: platform }) const { rimrafManual, rimrafManualSync } = (await t.mockImport( '../src/rimraf-manual.js', )) as typeof import('../src/rimraf-manual.js') const [expectManual, expectManualSync] = platform === 'win32' ? [rimrafWindows, rimrafWindowsSync] : [rimrafPosix, rimrafPosixSync] t.equal(rimrafManual, expectManual, 'got expected implementation') t.equal( rimrafManualSync, expectManualSync, 'got expected implementation', ) }) } isaacs-rimraf-4c5e478/test/rimraf-move-remove.ts000066400000000000000000000533721514446574700217010ustar00rootroot00000000000000import t from 'tap' import { Dirent, Mode, Stats, statSync } from 'fs' import * as PATH from 'path' import { basename, parse, relative } from 'path' import * as FS from '../src/fs.js' import { rimrafMoveRemove, rimrafMoveRemoveSync, } from '../src/rimraf-move-remove.js' t.formatSnapshot = (calls: string[][]) => calls.map(args => args.map(arg => String(arg) .split(process.cwd()) .join('{CWD}') .replace(/\\/g, '/') .replace(/.*\/(\.[a-z]\.)[^/]*$/, '{tmpfile}'), ), ) const fixture = { a: 'a', b: 'b', c: { d: 'd', e: 'e', f: { g: 'g', h: 'h', i: { j: 'j', k: 'k', l: 'l', m: { n: 'n', o: 'o', }, }, }, }, } t.test('actually delete some stuff', async t => { // eslint-disable-next-line @typescript-eslint/no-explicit-any type MockFs = (...args: any[]) => Promise // eslint-disable-next-line @typescript-eslint/no-explicit-any type MockFsSync = (...args: any[]) => any const fsMock: { [k in Exclude]: MockFsSync } & { promises: Record } = { ...FS, promises: { ...(FS.promises as Record), }, } // simulate annoying windows semantics, where an unlink or rmdir // may take an arbitrary amount of time. we only delay unlinks, // to ensure that we will get an error when we try to rmdir. const { statSync, promises: { unlink }, } = FS const danglers: Promise[] = [] const unlinkLater = (path: string) => { const p = new Promise(res => { setTimeout(() => void unlink(path).then(res, res)) }) danglers.push(p) } fsMock.unlinkSync = (path: string) => unlinkLater(path) fsMock.promises.unlink = async (path: string) => unlinkLater(path) // but actually do wait to clean them up, though t.teardown(() => Promise.all(danglers)) const { rimrafPosix, rimrafPosixSync } = (await t.mockImport( '../src/rimraf-posix.js', { '../src/fs.js': fsMock }, )) as typeof import('../src/rimraf-posix.js') const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/fs.js': fsMock }, )) as typeof import('../src/rimraf-move-remove.js') t.test('posix does not work here', t => { t.test('sync', t => { const path = t.testdir(fixture) t.throws(() => rimrafPosixSync(path, {})) t.end() }) t.test('async', t => { const path = t.testdir(fixture) t.rejects(() => rimrafPosix(path, {})) t.end() }) t.end() }) t.test('sync', t => { const path = t.testdir(fixture) rimrafMoveRemoveSync(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') t.doesNotThrow( () => rimrafMoveRemoveSync(path, {}), 'deleting a second time is OK', ) t.end() }) t.test('async', async t => { const path = t.testdir(fixture) await rimrafMoveRemove(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') t.resolves(rimrafMoveRemove(path, {}), 'deleting a second time is OK') }) t.end() }) t.test('throw unlink errors', async t => { const fs = await import('../src/fs.js') // only throw once here, or else it messes with tap's fixture cleanup // that's probably a bug in t.mock? let threwAsync = false let threwSync = false const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/fs.js': t.createMock(fs, { unlinkSync: (path: string) => { if (threwSync) { return fs.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'FOO' }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return fs.promises.unlink(path) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'FOO', }) }, }, }), }, )) as typeof import('../src/rimraf-move-remove.js') // nest to clean up the mess t.test('sync', t => { const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafMoveRemoveSync(path, {}), { code: 'FOO' }) t.end() }) t.test('async', t => { const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafMoveRemove(path, {}), { code: 'FOO' }) t.end() }) t.end() }) t.test('ignore ENOENT unlink errors', async t => { const fs = await import('../src/fs.js') const threwAsync = false let threwSync = false const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/fs.js': t.createMock(fs, { unlinkSync: (path: string) => { fs.unlinkSync(path) if (threwSync) { return } threwSync = true fs.unlinkSync(path) }, promises: { unlink: async (path: string) => { fs.unlinkSync(path) if (threwAsync) { return } threwSync = true fs.unlinkSync(path) }, }, }), }, )) as typeof import('../src/rimraf-move-remove.js') // nest to clean up the mess t.test('sync', t => { const path = t.testdir({ test: fixture }) + '/test' t.doesNotThrow( () => void rimrafMoveRemoveSync(path, {}), 'enoent no problems', ) t.end() }) t.test('async', t => { const path = t.testdir({ test: fixture }) + '/test' t.resolves(() => rimrafMoveRemove(path, {}), 'enoent no problems') t.end() }) t.end() }) t.test('throw rmdir errors', async t => { const fs = await import('../src/fs.js') const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/fs.js': t.createMock(fs, { rmdirSync: () => { throw Object.assign(new Error('cannot rmdir'), { code: 'FOO' }) }, promises: { rmdir: async () => { throw Object.assign(new Error('cannot rmdir'), { code: 'FOO' }) }, }, }), }, )) as typeof import('../src/rimraf-move-remove.js') t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafMoveRemoveSync(path, {}), { code: 'FOO' }) t.end() }) t.test('async', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafMoveRemove(path, {}), { code: 'FOO' }) t.end() }) t.end() }) t.test('throw unexpected readdir errors', async t => { const fs = await import('../src/fs.js') const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/readdir-or-error.js': (await t.mockImport( '../src/readdir-or-error.js', { '../src/fs.js': t.createMock(fs, { readdirSync: () => { throw Object.assign(new Error('cannot readdir'), { code: 'FOO', }) }, promises: { readdir: async () => { throw Object.assign(new Error('cannot readdir'), { code: 'FOO', }) }, }, }), }, )) as typeof import('../src/readdir-or-error.js'), }, )) as typeof import('../src/rimraf-move-remove.js') t.test('sync', t => { // nest to clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafMoveRemoveSync(path, {}), { code: 'FOO' }) t.end() }) t.test('async', t => { // nest to clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafMoveRemove(path, {}), { code: 'FOO' }) t.end() }) t.end() }) t.test('refuse to delete the root dir', async t => { const path = await import('path') const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { path: t.createMock(path, { dirname: (path: string) => path, }), }, )) as typeof import('../src/rimraf-move-remove.js') const d = t.testdir({}) // not brave enough to pass the actual c:\\ here... t.throws(() => rimrafMoveRemoveSync(d, { tmp: d }), { message: 'cannot delete temp directory used for deletion', }) t.rejects(() => rimrafMoveRemove(d, { tmp: d }), { message: 'cannot delete temp directory used for deletion', }) }) t.test('handle EPERMs on unlink by trying to chmod 0o666', async t => { const fs = await import('../src/fs.js') const CHMODS: unknown[] = [] let threwAsync = false let threwSync = false const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/fix-eperm.js': (await t.mockImport('../src/fix-eperm.js', { '../src/fs.js': t.createMock(fs, { chmodSync: (path: string, mode: Mode) => { CHMODS.push(['chmodSync', path, mode]) return fs.chmodSync(path, mode) }, promises: { chmod: async (path: string, mode: Mode) => { CHMODS.push(['chmod', path, mode]) return fs.promises.chmod(path, mode) }, }, }), })) as typeof import('../src/fix-eperm.js'), '../src/fs.js': t.createMock(fs, { unlinkSync: (path: string) => { if (threwSync) { return fs.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return fs.promises.unlink(path) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, }, }), }, )) as typeof import('../src/rimraf-move-remove.js') t.afterEach(() => (CHMODS.length = 0)) t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' rimrafMoveRemoveSync(path, {}) t.matchSnapshot(CHMODS) t.end() }) t.test('async', async t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' await rimrafMoveRemove(path, {}) t.matchSnapshot(CHMODS) t.end() }) t.end() }) t.test('handle EPERMs, chmod returns ENOENT', async t => { const fs = await import('../src/fs.js') const CHMODS: unknown[] = [] let threwAsync = false let threwSync = false const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/fix-eperm.js': (await t.mockImport('../src/fix-eperm.js', { '../src/fs.js': t.createMock(fs, { chmodSync: (path: string, mode: Mode) => { CHMODS.push(['chmodSync', path, mode]) try { fs.unlinkSync(path) } catch {} return fs.chmodSync(path, mode) }, promises: { chmod: async (path: string, mode: Mode) => { CHMODS.push(['chmod', path, mode]) try { fs.unlinkSync(path) } catch {} return fs.promises.chmod(path, mode) }, }, }), })) as typeof import('../src/fix-eperm.js'), '../src/fs.js': t.createMock(fs, { unlinkSync: (path: string) => { if (threwSync) { return fs.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return fs.promises.unlink(path) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, }, }), }, )) as typeof import('../src/rimraf-move-remove.js') t.afterEach(() => (CHMODS.length = 0)) t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' rimrafMoveRemoveSync(path, {}) t.matchSnapshot(CHMODS) t.end() }) t.test('async', async t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' await rimrafMoveRemove(path, {}) t.matchSnapshot(CHMODS) t.end() }) t.end() }) t.test( 'handle EPERMs, chmod raises something other than ENOENT', async t => { const fs = await import('../src/fs.js') const CHMODS: unknown[] = [] let threwAsync = false let threwSync = false const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { '../src/fix-eperm.js': (await t.mockImport('../src/fix-eperm.js', { '../src/fs.js': t.createMock(fs, { chmodSync: (path: string, mode: Mode) => { CHMODS.push(['chmodSync', path, mode]) try { fs.unlinkSync(path) } catch {} throw Object.assign(new Error('cannot chmod'), { code: 'FOO', }) }, promises: { chmod: async (path: string, mode: Mode) => { CHMODS.push(['chmod', path, mode]) try { fs.unlinkSync(path) } catch {} throw Object.assign(new Error('cannot chmod'), { code: 'FOO', }) }, }, }), })) as typeof import('../src/fix-eperm.js'), '../src/fs.js': t.createMock(fs, { unlinkSync: (path: string) => { if (threwSync) { return fs.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return fs.promises.unlink(path) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, }, }), }, )) as typeof import('../src/rimraf-move-remove.js') t.afterEach(() => (CHMODS.length = 0)) t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafMoveRemoveSync(path, {}), { code: 'EPERM' }) t.matchSnapshot(CHMODS) t.end() }) t.test('async', async t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafMoveRemove(path, {}), { code: 'EPERM' }) t.matchSnapshot(CHMODS) t.end() }) t.end() }, ) t.test('rimraffing root, do not actually rmdir root', async t => { const fs = await import('../src/fs.js') let ROOT: undefined | string = undefined const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', { path: t.createMock(PATH, { parse: (path: string) => { const p = parse(path) if (path === ROOT) { p.root = path } return p }, }), }, )) as typeof import('../src/rimraf-move-remove.js') t.test('async', async t => { ROOT = t.testdir(fixture) await rimrafMoveRemove(ROOT, { preserveRoot: false }) t.equal(fs.statSync(ROOT).isDirectory(), true, 'root still present') t.same(fs.readdirSync(ROOT), [], 'entries all gone') }) t.test('sync', async t => { ROOT = t.testdir(fixture) rimrafMoveRemoveSync(ROOT, { preserveRoot: false }) t.equal(fs.statSync(ROOT).isDirectory(), true, 'root still present') t.same(fs.readdirSync(ROOT), [], 'entries all gone') }) t.end() }) t.test( 'abort if the signal says to', { skip: typeof AbortController === 'undefined' }, async t => { const { rimrafMoveRemove, rimrafMoveRemoveSync } = (await t.mockImport( '../src/rimraf-move-remove.js', )) as typeof import('../src/rimraf-move-remove.js') t.test('sync', t => { const ac = new AbortController() const { signal } = ac ac.abort(new Error('aborted rimraf')) const d = t.testdir(fixture) t.throws(() => rimrafMoveRemoveSync(d, { signal })) t.end() }) t.test('sync abort in filter', t => { const d = t.testdir(fixture) const ac = new AbortController() const { signal } = ac const opt = { signal, filter: (p: string, st: Stats | Dirent) => { if (basename(p) === 'g' && st.isFile()) { ac.abort(new Error('done')) } return true }, } t.throws(() => rimrafMoveRemoveSync(d, opt), { message: 'done' }) t.end() }) t.test('async', async t => { const ac = new AbortController() const { signal } = ac const d = t.testdir(fixture) const p = t.rejects(() => rimrafMoveRemove(d, { signal })) ac.abort(new Error('aborted rimraf')) await p }) t.test('async, pre-aborted', async t => { const ac = new AbortController() const { signal } = ac const d = t.testdir(fixture) ac.abort(new Error('aborted rimraf')) await t.rejects(() => rimrafMoveRemove(d, { signal })) }) t.end() }, ) t.test('filter function', async t => { for (const f of ['i', 'j']) { t.test(`filter=${f}`, t => { t.test('sync', t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) return basename(p) !== f } rimrafMoveRemoveSync(dir, { filter }) t.matchSnapshot( [saw.sort((a, b) => a.localeCompare(b, 'en'))], 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) t.end() }) t.test('async', async t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) return basename(p) !== f } await rimrafMoveRemove(dir, { filter }) t.matchSnapshot( [saw.sort((a, b) => a.localeCompare(b, 'en'))], 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) }) t.test('async filter', async t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = async (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) await new Promise(setImmediate) return basename(p) !== f } await rimrafMoveRemove(dir, { filter }) t.matchSnapshot( [saw.sort((a, b) => a.localeCompare(b, 'en'))], 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) }) t.end() }) } t.end() }) t.test('do not follow symlinks', t => { const fixture = { x: { y: t.fixture('symlink', '../z'), z: '', }, z: { a: '', b: { c: '' }, }, } t.test('sync', t => { const d = t.testdir(fixture) t.equal(rimrafMoveRemoveSync(d + '/x', {}), true) statSync(d + '/z') statSync(d + '/z/a') statSync(d + '/z/b/c') t.end() }) t.test('async', async t => { const d = t.testdir(fixture) t.equal(await rimrafMoveRemove(d + '/x', {}), true) statSync(d + '/z') statSync(d + '/z/a') statSync(d + '/z/b/c') }) t.end() }) isaacs-rimraf-4c5e478/test/rimraf-native.ts000066400000000000000000000013611514446574700207150ustar00rootroot00000000000000import t from 'tap' import { RimrafAsyncOptions, RimrafSyncOptions } from '../src/index.js' const CALLS: any[] = [] const fs = { rmSync: (path: string, options: any) => { CALLS.push(['rmSync', path, options]) }, promises: { rm: async (path: string, options: any) => { CALLS.push(['rm', path, options]) }, }, } const { rimrafNative, rimrafNativeSync } = (await t.mockImport( '../dist/esm/rimraf-native.js', { '../dist/esm/fs.js': fs, }, )) as typeof import('../dist/esm/rimraf-native.js') t.test('calls the right node function', async t => { await rimrafNative('path', { x: 'y' } as unknown as RimrafAsyncOptions) rimrafNativeSync('path', { a: 'b' } as unknown as RimrafSyncOptions) t.matchSnapshot(CALLS) }) isaacs-rimraf-4c5e478/test/rimraf-posix.ts000066400000000000000000000257121514446574700205770ustar00rootroot00000000000000import { Dirent, Stats, statSync } from 'fs' import * as PATH from 'path' import { basename, parse, relative } from 'path' import t from 'tap' import { rimrafPosix, rimrafPosixSync } from '../src/rimraf-posix.js' import * as fs from '../src/fs.js' const fixture = { a: 'a', b: 'b', c: { d: 'd', e: 'e', f: { g: 'g', h: 'h', i: { j: 'j', k: 'k', l: 'l', m: { n: 'n', o: 'o', }, }, }, }, } t.test('actually delete some stuff', t => { const { statSync } = fs t.test('sync', t => { const path = t.testdir(fixture) rimrafPosixSync(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') t.doesNotThrow( () => rimrafPosixSync(path, {}), 'deleting a second time is OK', ) t.end() }) t.test('async', async t => { const path = t.testdir(fixture) await rimrafPosix(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') t.resolves(rimrafPosix(path, {}), 'deleting a second time is OK') }) t.end() }) t.test('throw unlink errors', async t => { const { rimrafPosix, rimrafPosixSync } = (await t.mockImport( '../src/rimraf-posix.js', { '../src/fs.js': t.createMock(fs, { unlinkSync: () => { throw Object.assign(new Error('cannot unlink'), { code: 'FOO' }) }, promises: { unlink: async () => { throw Object.assign(new Error('cannot unlink'), { code: 'FOO', }) }, }, }), }, )) as typeof import('../src/rimraf-posix.js') const path = t.testdir(fixture) t.throws(() => rimrafPosixSync(path, {}), { code: 'FOO' }) t.rejects(rimrafPosix(path, {}), { code: 'FOO' }) }) t.test('throw rmdir errors', async t => { const { rimrafPosix, rimrafPosixSync } = (await t.mockImport( '../src/rimraf-posix.js', { '../src/fs.js': t.createMock(fs, { rmdirSync: () => { throw Object.assign(new Error('cannot rmdir'), { code: 'FOO' }) }, promises: { rmdir: async () => { throw Object.assign(new Error('cannot rmdir'), { code: 'FOO' }) }, }, }), }, )) as typeof import('../src/rimraf-posix.js') const path = t.testdir(fixture) t.throws(() => rimrafPosixSync(path, {}), { code: 'FOO' }) t.rejects(rimrafPosix(path, {}), { code: 'FOO' }) }) t.test('throw unexpected readdir errors', async t => { const { rimrafPosix, rimrafPosixSync } = (await t.mockImport( '../src/rimraf-posix.js', { '../src/readdir-or-error.js': (await t.mockImport( '../src/readdir-or-error.js', { '../src/fs.js': t.createMock(fs, { readdirSync: () => { throw Object.assign(new Error('cannot readdir'), { code: 'FOO', }) }, promises: { readdir: async () => { throw Object.assign(new Error('cannot readdir'), { code: 'FOO', }) }, }, }), }, )) as typeof import('../src/readdir-or-error.js'), }, )) as typeof import('../src/rimraf-posix.js') const path = t.testdir(fixture) t.throws(() => rimrafPosixSync(path, {}), { code: 'FOO' }) t.rejects(rimrafPosix(path, {}), { code: 'FOO' }) }) t.test('ignore ENOENTs from unlink/rmdir', async t => { const { rimrafPosix, rimrafPosixSync } = (await t.mockImport( '../src/rimraf-posix.js', { '../src/fs.js': t.createMock(fs, { // simulate a case where two rimrafs are happening in parallel, // so the deletion happens AFTER the readdir, but before ours. rmdirSync: (path: string) => { fs.rmdirSync(path) fs.rmdirSync(path) }, unlinkSync: (path: string) => { fs.unlinkSync(path) fs.unlinkSync(path) }, promises: { rmdir: async (path: string) => { fs.rmdirSync(path) return fs.promises.rmdir(path) }, unlink: async (path: string) => { fs.unlinkSync(path) return fs.promises.unlink(path) }, }, }), }, )) as typeof import('../src/rimraf-posix.js') const { statSync } = fs t.test('sync', t => { const path = t.testdir(fixture) rimrafPosixSync(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') t.end() }) t.test('async', async t => { const path = t.testdir(fixture) await rimrafPosix(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') }) t.end() }) t.test('rimraffing root, do not actually rmdir root', async t => { let ROOT: undefined | string = undefined const { rimrafPosix, rimrafPosixSync } = (await t.mockImport( '../src/rimraf-posix.js', { path: t.createMock(PATH, { parse: (path: string) => { const p = parse(path) if (path === ROOT) { p.root = path } return p }, }), }, )) as typeof import('../src/rimraf-posix.js') t.test('async', async t => { ROOT = t.testdir(fixture) await rimrafPosix(ROOT, { preserveRoot: false }) t.equal(fs.statSync(ROOT).isDirectory(), true, 'root still present') t.same(fs.readdirSync(ROOT), [], 'entries all gone') }) t.test('sync', async t => { ROOT = t.testdir(fixture) rimrafPosixSync(ROOT, { preserveRoot: false }) t.equal(fs.statSync(ROOT).isDirectory(), true, 'root still present') t.same(fs.readdirSync(ROOT), [], 'entries all gone') }) t.end() }) t.test( 'abort on signal', { skip: typeof AbortController === 'undefined' }, t => { t.test('sync', t => { const d = t.testdir(fixture) const ac = new AbortController() const { signal } = ac ac.abort(new Error('aborted rimraf')) t.throws(() => rimrafPosixSync(d, { signal })) t.end() }) t.test('sync abort in filter', t => { const d = t.testdir(fixture) const ac = new AbortController() const { signal } = ac const opt = { signal, filter: (p: string, st: Stats | Dirent) => { if (basename(p) === 'g' && st.isFile()) { ac.abort(new Error('done')) } return true }, } t.throws(() => rimrafPosixSync(d, opt), { message: 'done' }) t.end() }) t.test('async', async t => { const d = t.testdir(fixture) const ac = new AbortController() const { signal } = ac const p = t.rejects(() => rimrafPosix(d, { signal })) ac.abort(new Error('aborted rimraf')) await p }) t.test('async preaborted', async t => { const d = t.testdir(fixture) const ac = new AbortController() ac.abort(new Error('aborted rimraf')) const { signal } = ac await t.rejects(() => rimrafPosix(d, { signal })) }) t.end() }, ) t.test('filter function', t => { t.formatSnapshot = undefined for (const f of ['i', 'j']) { t.test(`filter=${f}`, t => { t.test('sync', t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) return basename(p) !== f } rimrafPosixSync(dir, { filter }) t.matchSnapshot( saw.sort((a, b) => a.localeCompare(b, 'en')), 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) t.end() }) t.test('async', async t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) return basename(p) !== f } await rimrafPosix(dir, { filter }) t.matchSnapshot( saw.sort((a, b) => a.localeCompare(b, 'en')), 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) }) t.test('async filter', async t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = async (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) await new Promise(setImmediate) return basename(p) !== f } await rimrafPosix(dir, { filter }) t.matchSnapshot( saw.sort((a, b) => a.localeCompare(b, 'en')), 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) }) t.end() }) } t.end() }) t.test('do not follow symlinks', t => { const fixture = { x: { y: t.fixture('symlink', '../z'), z: '', }, z: { a: '', b: { c: '' }, }, } t.test('sync', t => { const d = t.testdir(fixture) t.equal(rimrafPosixSync(d + '/x', {}), true) statSync(d + '/z') statSync(d + '/z/a') statSync(d + '/z/b/c') t.end() }) t.test('async', async t => { const d = t.testdir(fixture) t.equal(await rimrafPosix(d + '/x', {}), true) statSync(d + '/z') statSync(d + '/z/a') statSync(d + '/z/b/c') }) t.end() }) isaacs-rimraf-4c5e478/test/rimraf-windows.ts000066400000000000000000000510501514446574700211210ustar00rootroot00000000000000import { Dirent, Mode, PathLike, Stats, statSync } from 'fs' import * as PATH from 'path' import { basename, parse, relative } from 'path' import t from 'tap' import * as FS from '../src/fs.js' import { rimrafWindows, rimrafWindowsSync } from '../src/rimraf-windows.js' t.formatSnapshot = (calls: string[][]) => Array.isArray(calls) ? calls.map(args => args.map(arg => String(arg) .split(process.cwd()) .join('{CWD}') .replace(/\\/g, '/') .replace(/.*\/(\.[a-z]\.)[^/]*$/, '{tmpfile}'), ), ) : calls const fixture = { a: 'a', b: 'b', c: { d: 'd', e: 'e', f: { g: 'g', h: 'h', i: { j: 'j', k: 'k', l: 'l', m: { n: 'n', o: 'o', }, }, }, }, } t.test('actually delete some stuff', async t => { // eslint-disable-next-line @typescript-eslint/no-explicit-any type MockFs = (...args: any[]) => Promise // eslint-disable-next-line @typescript-eslint/no-explicit-any type MockFsSync = (...args: any[]) => any const fsMock: { [k in Exclude]: MockFsSync } & { promises: Record } = { ...FS, promises: { ...(FS.promises as Record), }, } // simulate annoying windows semantics, where an unlink or rmdir // may take an arbitrary amount of time. we only delay unlinks, // to ensure that we will get an error when we try to rmdir. const { statSync, promises: { unlink }, } = FS const danglers: Promise[] = [] const unlinkLater = (path: string) => { const p = new Promise(res => { setTimeout(() => void unlink(path).then(res, res), 100) }) danglers.push(p) } fsMock.unlinkSync = (path: string) => unlinkLater(path) fsMock.promises.unlink = async (path: string) => unlinkLater(path) // but actually do wait to clean them up, though t.teardown(async () => { await Promise.all(danglers) }) const { rimrafPosix, rimrafPosixSync } = (await t.mockImport( '../src/rimraf-posix.js', { '../src/fs.js': fsMock }, )) as typeof import('../src/rimraf-posix.js') const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/fs.js': fsMock }, )) as typeof import('../src/rimraf-windows.js') t.test('posix does not work here', t => { t.test('sync', t => { const path = t.testdir(fixture) t.throws(() => rimrafPosixSync(path, {})) t.end() }) t.test('async', async t => { const path = t.testdir(fixture) await t.rejects(() => rimrafPosix(path, {})) t.end() }) t.end() }) t.test('sync', t => { const path = t.testdir(fixture) rimrafWindowsSync(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') t.doesNotThrow( () => rimrafWindowsSync(path, {}), 'deleting a second time is OK', ) t.end() }) t.test('async', async t => { const path = t.testdir(fixture) await rimrafWindows(path, {}) t.throws(() => statSync(path), { code: 'ENOENT' }, 'deleted') await t.resolves( rimrafWindows(path, {}), 'deleting a second time is OK', ) }) t.end() }) t.test('throw unlink errors', async t => { // only throw once here, or else it messes with tap's fixture cleanup // that's probably a bug in t.mock? let threwAsync = false let threwSync = false const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/fs.js': t.createMock(FS, { unlinkSync: (path: string) => { if (threwSync) { return FS.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'FOO' }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return FS.promises.unlink(path) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'FOO', }) }, }, }), }, )) as typeof import('../src/rimraf-windows.js') // nest to clean up the mess t.test('sync', t => { const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafWindowsSync(path, {}), { code: 'FOO' }) t.end() }) t.test('async', t => { const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafWindows(path, {}), { code: 'FOO' }) t.end() }) t.end() }) t.test('ignore ENOENT unlink errors', async t => { const threwAsync = false let threwSync = false const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/fs.js': t.createMock(FS, { unlinkSync: (path: string) => { FS.unlinkSync(path) if (threwSync) { return } threwSync = true FS.unlinkSync(path) }, promises: { unlink: async (path: string) => { FS.unlinkSync(path) if (threwAsync) { return } threwSync = true FS.unlinkSync(path) }, }, }), }, )) as typeof import('../src/rimraf-windows.js') // nest to clean up the mess t.test('sync', t => { const path = t.testdir({ test: fixture }) + '/test' t.doesNotThrow(() => rimrafWindowsSync(path, {}), 'enoent no problems') t.end() }) t.test('async', t => { const path = t.testdir({ test: fixture }) + '/test' t.resolves(() => rimrafWindows(path, {}), 'enoent no problems') t.end() }) t.end() }) t.test('throw rmdir errors', async t => { const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/fs.js': { ...FS, rmdirSync: () => { throw Object.assign(new Error('cannot rmdir'), { code: 'FOO' }) }, promises: { ...FS.promises, rmdir: async () => { throw Object.assign(new Error('cannot rmdir'), { code: 'FOO' }) }, }, }, }, )) as typeof import('../src/rimraf-windows.js') t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafWindowsSync(path, {}), { code: 'FOO' }) t.end() }) t.test('async', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafWindows(path, {}), { code: 'FOO' }) t.end() }) t.end() }) t.test('throw unexpected readdir errors', async t => { const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/readdir-or-error.js': (await t.mockImport( '../src/readdir-or-error.js', { '../src/fs.js': t.createMock(FS, { readdirSync: () => { throw Object.assign(new Error('cannot readdir'), { code: 'FOO', }) }, promises: { readdir: async () => { throw Object.assign(new Error('cannot readdir'), { code: 'FOO', }) }, }, }), }, )) as typeof import('../src/readdir-or-error.js'), }, )) as typeof import('../src/rimraf-windows.js') t.test('sync', t => { // nest to clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafWindowsSync(path, {}), { code: 'FOO' }) t.end() }) t.test('async', t => { // nest to clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafWindows(path, {}), { code: 'FOO' }) t.end() }) t.end() }) t.test('handle EPERMs on unlink by trying to chmod 0o666', async t => { const CHMODS = [] let threwAsync = false let threwSync = false const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/fix-eperm.js': (await t.mockImport('../src/fix-eperm.js', { '../src/fs.js': t.createMock(FS, { chmodSync: (path: string, mode: Mode) => { CHMODS.push(['chmodSync', path, mode]) return FS.chmodSync(path, mode) }, promises: { chmod: async (path: string, mode: Mode) => { CHMODS.push(['chmod', path, mode]) return FS.promises.chmod(path, mode) }, }, }), })) as typeof import('../src/fix-eperm.js'), '../src/fs.js': t.createMock(FS, { unlinkSync: (path: string) => { if (threwSync) { return FS.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return FS.promises.unlink(path as PathLike) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, }, }), }, )) as typeof import('../src/rimraf-windows.js') t.afterEach(() => (CHMODS.length = 0)) t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' rimrafWindowsSync(path, {}) t.matchSnapshot(CHMODS.length, 'chmods') t.end() }) t.test('async', async t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' await rimrafWindows(path, {}) t.matchSnapshot(CHMODS.length, 'chmods') t.end() }) t.end() }) t.test('handle EPERMs, chmod returns ENOENT', async t => { const CHMODS = [] let threwAsync = false let threwSync = false const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/fix-eperm.js': (await t.mockImport('../src/fix-eperm.js', { '../src/fs.js': t.createMock(FS, { chmodSync: (path: string, mode: Mode) => { CHMODS.push(['chmodSync', path, mode]) try { FS.unlinkSync(path) } catch {} return FS.chmodSync(path, mode) }, promises: { chmod: async (path: string, mode: Mode) => { CHMODS.push(['chmod', path, mode]) try { FS.unlinkSync(path) } catch {} return FS.promises.chmod(path, mode) }, }, }), })) as typeof import('../src/fix-eperm.js'), '../src/fs.js': t.createMock(FS, { unlinkSync: (path: string) => { if (threwSync) { return FS.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return FS.promises.unlink(path) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, }, }), }, )) as typeof import('../src/rimraf-windows.js') t.afterEach(() => (CHMODS.length = 0)) t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' rimrafWindowsSync(path, {}) t.matchSnapshot(CHMODS.length, 'chmods') t.end() }) t.test('async', async t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' await rimrafWindows(path, {}) t.matchSnapshot(CHMODS.length, 'chmods') t.end() }) t.end() }) t.test( 'handle EPERMs, chmod raises something other than ENOENT', async t => { const CHMODS = [] let threwAsync = false let threwSync = false const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { '../src/fix-eperm.js': (await t.mockImport('../src/fix-eperm.js', { '../src/fs.js': t.createMock(FS, { chmodSync: (path: string, mode: Mode) => { CHMODS.push(['chmodSync', path, mode]) try { FS.unlinkSync(path) } catch {} throw Object.assign(new Error('cannot chmod'), { code: 'FOO', }) }, promises: { chmod: async (path: string, mode: Mode) => { CHMODS.push(['chmod', path, mode]) try { FS.unlinkSync(path) } catch {} throw Object.assign(new Error('cannot chmod'), { code: 'FOO', }) }, }, }), })) as typeof import('../src/fix-eperm.js'), '../src/fs.js': t.createMock(FS, { unlinkSync: (path: string) => { if (threwSync) { return FS.unlinkSync(path) } threwSync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, promises: { unlink: async (path: string) => { if (threwAsync) { return FS.promises.unlink(path) } threwAsync = true throw Object.assign(new Error('cannot unlink'), { code: 'EPERM', }) }, }, }), }, )) as typeof import('../src/rimraf-windows.js') t.afterEach(() => (CHMODS.length = 0)) t.test('sync', t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.throws(() => rimrafWindowsSync(path, {}), { code: 'EPERM' }) t.matchSnapshot(CHMODS.length, 'chmods') t.end() }) t.test('async', async t => { // nest it so that we clean up the mess const path = t.testdir({ test: fixture }) + '/test' t.rejects(rimrafWindows(path, {}), { code: 'EPERM' }) t.matchSnapshot(CHMODS.length, 'chmods') t.end() }) t.end() }, ) t.test('rimraffing root, do not actually rmdir root', async t => { let ROOT: string | undefined = undefined const { rimrafWindows, rimrafWindowsSync } = (await t.mockImport( '../src/rimraf-windows.js', { path: t.createMock(PATH, { parse: (path: string) => { const p = parse(path) if (path === ROOT) { p.root = path } return p }, }), }, )) as typeof import('../src/rimraf-windows.js') t.test('async', async t => { ROOT = t.testdir(fixture) await rimrafWindows(ROOT, { preserveRoot: false }) t.equal(FS.statSync(ROOT).isDirectory(), true, 'root still present') t.same(FS.readdirSync(ROOT), [], 'entries all gone') }) t.test('sync', async t => { ROOT = t.testdir(fixture) rimrafWindowsSync(ROOT, { preserveRoot: false }) t.equal(FS.statSync(ROOT).isDirectory(), true, 'root still present') t.same(FS.readdirSync(ROOT), [], 'entries all gone') }) t.end() }) t.test( 'abort on signal', { skip: typeof AbortController === 'undefined' }, t => { t.test('sync', t => { const d = t.testdir(fixture) const ac = new AbortController() const { signal } = ac ac.abort(new Error('aborted rimraf')) t.throws(() => rimrafWindowsSync(d, { signal })) t.end() }) t.test('sync abort in filter', t => { const d = t.testdir(fixture) const ac = new AbortController() const { signal } = ac const opt = { signal, filter: (p: string, st: Stats | Dirent) => { if (basename(p) === 'g' && st.isFile()) { ac.abort(new Error('done')) } return true }, } t.throws(() => rimrafWindowsSync(d, opt), { message: 'done' }) t.end() }) t.test('async', async t => { const d = t.testdir(fixture) const ac = new AbortController() const { signal } = ac const p = t.rejects(() => rimrafWindows(d, { signal })) ac.abort(new Error('aborted rimraf')) await p }) t.test('async, pre-aborted', async t => { const ac = new AbortController() const { signal } = ac const d = t.testdir(fixture) ac.abort(new Error('aborted rimraf')) await t.rejects(() => rimrafWindows(d, { signal })) }) t.end() }, ) t.test('filter function', t => { for (const f of ['i', 'j']) { t.test(`filter=${f}`, t => { t.test('sync', t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) return basename(p) !== f } rimrafWindowsSync(dir, { filter }) t.matchSnapshot( [saw.sort((a, b) => a.localeCompare(b, 'en'))], 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) t.end() }) t.test('async', async t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) return basename(p) !== f } await rimrafWindows(dir, { filter }) t.matchSnapshot( [saw.sort((a, b) => a.localeCompare(b, 'en'))], 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) }) t.test('async filter', async t => { const dir = t.testdir(fixture) const saw: string[] = [] const filter = async (p: string) => { saw.push(relative(process.cwd(), p).replace(/\\/g, '/')) await new Promise(setImmediate) return basename(p) !== f } await rimrafWindows(dir, { filter }) t.matchSnapshot( [saw.sort((a, b) => a.localeCompare(b, 'en'))], 'paths seen', ) statSync(dir) statSync(dir + '/c') statSync(dir + '/c/f') statSync(dir + '/c/f/i') if (f === 'j') { statSync(dir + '/c/f/i/j') } else { t.throws(() => statSync(dir + '/c/f/i/j')) } t.throws(() => statSync(dir + '/a')) t.throws(() => statSync(dir + '/b')) t.throws(() => statSync(dir + '/c/d')) t.throws(() => statSync(dir + '/c/e')) t.throws(() => statSync(dir + '/c/f/g')) t.throws(() => statSync(dir + '/c/f/h')) t.throws(() => statSync(dir + '/c/f/i/k')) t.throws(() => statSync(dir + '/c/f/i/l')) t.throws(() => statSync(dir + '/c/f/i/m')) }) t.end() }) } t.end() }) t.test('do not follow symlinks', t => { const fixture = { x: { y: t.fixture('symlink', '../z'), z: '', }, z: { a: '', b: { c: '' }, }, } t.test('sync', t => { const d = t.testdir(fixture) t.equal(rimrafWindowsSync(d + '/x', {}), true) statSync(d + '/z') statSync(d + '/z/a') statSync(d + '/z/b/c') t.end() }) t.test('async', async t => { const d = t.testdir(fixture) t.equal(await rimrafWindows(d + '/x', {}), true) statSync(d + '/z') statSync(d + '/z/a') statSync(d + '/z/b/c') }) t.end() }) isaacs-rimraf-4c5e478/test/use-native.ts000066400000000000000000000016731514446574700202370ustar00rootroot00000000000000import t from 'tap' for (const [platform, version, expect] of [ ['darwin', 'v14.14.0', true], ['darwin', 'v14.13.9', false], ['win32', 'v14.14.0', false], ['win32', 'v14.13.9', false], ] as const) { t.test(platform, async t => { t.intercept(process, 'platform', { value: platform }) t.intercept(process, 'version', { value: version }) const { useNative, useNativeSync } = (await t.mockImport( '../src/use-native.js', )) as typeof import('../src/use-native.js') if (expect) { // always need manual if a signal is passed in const { signal } = new AbortController() t.equal(useNative({ signal }), false) t.equal(useNativeSync({ signal }), false) // always need manual if a filter is provided t.equal(useNative({ filter: () => true }), false) t.equal(useNativeSync({ filter: () => true }), false) } t.equal(useNative(), expect) t.equal(useNativeSync(), expect) }) } isaacs-rimraf-4c5e478/tsconfig.json000066400000000000000000000006551514446574700173360ustar00rootroot00000000000000{ "compilerOptions": { "declaration": true, "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "inlineSources": true, "jsx": "react", "module": "nodenext", "moduleResolution": "nodenext", "noUncheckedIndexedAccess": true, "resolveJsonModule": true, "skipLibCheck": true, "sourceMap": true, "strict": true, "target": "es2022" } } isaacs-rimraf-4c5e478/typedoc.json000066400000000000000000000003311514446574700171600ustar00rootroot00000000000000{ "tsconfig": "./.tshy/esm.json", "entryPoints": ["./src/**/*.+(ts|tsx|mts|cts)"], "navigationLinks": { "GitHub": "https://github.com/isaacs/rimraf", "isaacs projects": "https://isaacs.github.io/" } }