pax_global_header 0000666 0000000 0000000 00000000064 14751162414 0014517 g ustar 00root root 0000000 0000000 52 comment=288e9435a1cf9fbbd96f7ef0d666abb593488565
mock-fs-5.5.0/ 0000775 0000000 0000000 00000000000 14751162414 0013065 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/.github/ 0000775 0000000 0000000 00000000000 14751162414 0014425 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/.github/dependabot.yml 0000664 0000000 0000000 00000000401 14751162414 0017250 0 ustar 00root root 0000000 0000000 version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
versioning-strategy: increase-if-necessary
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
mock-fs-5.5.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14751162414 0016462 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/.github/workflows/test.yml 0000664 0000000 0000000 00000001411 14751162414 0020161 0 ustar 00root root 0000000 0000000 name: Test
on:
push:
branches:
- main
pull_request:
branches:
- main
env:
CI: true
jobs:
run:
name: Node ${{ matrix.node }} / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
node:
- 18
- 20
- 22
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Set Node.js version
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: node --version
- run: npm --version
- name: Install npm dependencies
run: npm ci
- name: Run tests
run: npm test
mock-fs-5.5.0/.gitignore 0000664 0000000 0000000 00000000025 14751162414 0015052 0 ustar 00root root 0000000 0000000 /node_modules/
.idea
mock-fs-5.5.0/benchmarks/ 0000775 0000000 0000000 00000000000 14751162414 0015202 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/benchmarks/read-integration-mock.js 0000664 0000000 0000000 00000000746 14751162414 0021732 0 ustar 00root root 0000000 0000000 const assert = require('assert');
const fs = require('fs');
const mock = require('../lib/index.js');
/**
* Timed test. This includes the mock setup and teardown as part of the overall
* test time.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
mock({
'foo-mock.txt': 'foo',
});
fs.readFile('foo-mock.txt', 'utf8', function (err, str) {
assert.ifError(err);
assert.equal(str, 'foo');
mock.restore();
done();
});
};
mock-fs-5.5.0/benchmarks/read-integration-real.js 0000664 0000000 0000000 00000001332 14751162414 0021714 0 ustar 00root root 0000000 0000000 const assert = require('assert');
const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const tmpPath = '.tmp';
/**
* Timed test. This includes the setup and teardown as part of the overall
* test time.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
fs.mkdir(tmpPath, function (mkdirErr) {
assert.ifError(mkdirErr);
const tmpFile = path.join(tmpPath, 'foo-real.txt');
fs.writeFile(tmpFile, 'foo', function (writeErr) {
assert.ifError(writeErr);
fs.readFile(tmpFile, 'utf8', function (readErr, str) {
assert.ifError(readErr);
assert.equal(str, 'foo');
rimraf(tmpPath, done);
});
});
});
};
mock-fs-5.5.0/benchmarks/read-mock.js 0000664 0000000 0000000 00000001050 14751162414 0017376 0 ustar 00root root 0000000 0000000 const assert = require('assert');
const fs = require('fs');
const mock = require('../lib/index.js');
/**
* Test setup. Not timed.
*/
exports.afterEach = function () {
mock.restore();
};
/**
* Test teardown. Not timed.
*/
exports.beforeEach = function () {
mock({
'foo-mock.txt': 'foo',
});
};
/**
* Timed test.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
fs.readFile('foo-mock.txt', 'utf8', function (err, str) {
assert.ifError(err);
assert.equal(str, 'foo');
done();
});
};
mock-fs-5.5.0/benchmarks/read-real.js 0000664 0000000 0000000 00000001514 14751162414 0017375 0 ustar 00root root 0000000 0000000 const assert = require('assert');
const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const tmpPath = '.tmp';
/**
* Test setup. Not timed.
* @param {function(Error):void} done Callback.
*/
exports.afterEach = function (done) {
rimraf(tmpPath, done);
};
/**
* Test teardown. Not timed.
* @param {function(Error):void} done Callback.
*/
exports.beforeEach = function (done) {
fs.mkdir(tmpPath, function (err) {
if (err) {
return done(err);
}
fs.writeFile(path.join(tmpPath, 'foo-real.txt'), 'foo', done);
});
};
/**
* Timed test.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
fs.readFile(path.join(tmpPath, 'foo-real.txt'), 'utf8', function (err, str) {
assert.ifError(err);
assert.equal(str, 'foo');
done();
});
};
mock-fs-5.5.0/benchmarks/write-integration-mock.js 0000664 0000000 0000000 00000000643 14751162414 0022145 0 ustar 00root root 0000000 0000000 const assert = require('assert');
const fs = require('fs');
const mock = require('../lib/index.js');
/**
* Timed test. This includes the mock setup and teardown as part of the overall
* test time.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
mock();
fs.writeFile('foo-mock.txt', 'foo', function (err) {
assert.ifError(err);
mock.restore();
done();
});
};
mock-fs-5.5.0/benchmarks/write-integration-real.js 0000664 0000000 0000000 00000001047 14751162414 0022136 0 ustar 00root root 0000000 0000000 const assert = require('assert');
const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const tmpPath = '.tmp';
/**
* Timed test. This includes the setup and teardown as part of the overall
* test time.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
fs.mkdir(tmpPath, function (mkdirErr) {
assert.ifError(mkdirErr);
fs.writeFile(path.join(tmpPath, 'foo-real.txt'), 'foo', function (err) {
assert.ifError(err);
rimraf(tmpPath, done);
});
});
};
mock-fs-5.5.0/benchmarks/write-mock.js 0000664 0000000 0000000 00000000616 14751162414 0017624 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const mock = require('../lib/index.js');
/**
* Test setup. Not timed.
*/
exports.afterEach = function () {
mock.restore();
};
/**
* Test teardown. Not timed.
*/
exports.beforeEach = function () {
mock();
};
/**
* Timed test.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
fs.writeFile('foo-mock.txt', 'foo', done);
};
mock-fs-5.5.0/benchmarks/write-real.js 0000664 0000000 0000000 00000001123 14751162414 0017610 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const tmpPath = '.tmp';
/**
* Test setup. Not timed.
* @param {function(Error):void} done Callback.
*/
exports.afterEach = function (done) {
rimraf(tmpPath, done);
};
/**
* Test teardown. Not timed.
* @param {function(Error):void} done Callback.
*/
exports.beforeEach = function (done) {
fs.mkdir(tmpPath, done);
};
/**
* Timed test.
* @param {function(Error):void} done Callback.
*/
exports.test = function (done) {
fs.writeFile(path.join(tmpPath, 'foo-real.txt'), 'foo', done);
};
mock-fs-5.5.0/changelog.md 0000664 0000000 0000000 00000035070 14751162414 0015343 0 ustar 00root root 0000000 0000000 # Change Log
## 5.5.0
* Add test and fix exists behaviour for relative symlinks (thanks @timvahlbrock, see [#415][#415])
* Add test showing `fs.createWriteStream()` with append (see [#412][#412])
* encoding utf8 strings in node 20 (thanks @everett1992, see [#409][#409])
Dependency Updates
* bump semver from 7.6.3 to 7.7.0 (see [#413][#413])
* bump eslint-config-tschaub from 14.1.2 to 15.2.0 (see [#408][#408])
* bump mocha from 11.0.1 to 11.1.0 (see [#410][#410])
* bump mocha from 10.8.2 to 11.0.1 (see [#407][#407])
* bump mocha from 10.7.3 to 10.8.2 (see [#402][#402])
## 5.4.1
* Avoid errors in `fs.existsSync` (see [#401][#401])
## 5.4.0
* Use setImmediate instead of process.nextTick (thanks @regseb, see [#360][#360])
Dependency Updates
* bump chai from 4.3.4 to 4.5.0
* bump eslint from 8.21.0 to 8.57.1
## 5.3.0
* Remove conditions for untested versions
* Remove disabled tests for mock.fs (thanks @everett1992, see [#391][#391])
* Fix tests on node 20 (thanks @everett1992, see [#387][#387])
* Fix timeout in failing test (thanks @everett1992, see [#390][#390])
* Stop testing on Node 12 and 14
Dependency Updates
* chore(deps-dev): bump rimraf from 3.0.2 to 6.0.1
* chore(deps): bump actions/checkout from 2 to 4
* chore(deps-dev): bump mocha from 9.2.2 to 10.7.3
* chore(deps-dev): bump braces from 3.0.2 to 3.0.3
* chore(deps-dev): bump word-wrap from 1.2.3 to 1.2.4
* chore(deps): bump json5 from 1.0.1 to 1.0.2
## 5.2.0
* Fix EACCES error on access by root user (thanks @danielkatz, see [#369][#369])
* Fix bug on utimes and futimes; add support of lutimes (thanks @3cp, see [#366][#366])
## 5.1.4
* Fix for BigInt stats in Node 16.7 (thanks @ahippler, see [#363][#363])
## 5.1.3
* Fix for BigInt stats in Node 18.7 (thanks @3cp, see [#361][#361])
## 5.1.2
* Avoid open `FSREQCALLBACK` file handles (thanks @jloleysens, see [#342][#342])
## 5.1.1
* Added `engines` to `package.json` to clarify that Node >= 12 is required (thanks @tillig, see [#337][#337])
## 5.1.0
* Added support for Node >= 16.3 (thanks @Rugvip, see [#335][#335])
## 5.0.0
Breaking change:
* Remove support for Node < 12. If you want to use mock-fs to test on Node 10 or lower, stick with mock-fs@4.
New features:
* Support for BigInt file stats - required for Node 15+ (thanks @3cp, see [#325][#325])
## 4.14.0
* Attempt to fix logging when using `mock-fs` with `tape` (see [#322][#322])
* Minor fix for `bypass()` (thanks @3cp, see [#320][#320])
## 4.13.0
* Make `process.chdir()`, `process.cwd()`, and `fs.createWriteStream()` work with `bypass()` (thanks @3cp, see [#307][#307])
* Fix memory leak associated with Node 10 (thanks @3cp, see [#303][#303])
* Async function handling in `bypass()` (see [#306][#306])
* Big new feature! Temporarily bypass the mocked filesystem with the `bypass()` function (thanks @nonara, see [#304][#304])
## 4.12.0
* Check permissions in `readdir` and `readdirSync` (thanks @warpdesign, see [#295][#295])
* Add support for `Buffer` arg on many `fs` functions (thanks @3cp, see [#293][#293])
* Fix checks for read permission (thanks @3cp, see [#289][#289])
* Correct error code for `readFile` on a directory (thanks @3cp, see [#286][#286])
## 4.11.0
* Support `withFileTypes` when reading directories (thanks @mrmlnc, see [#287][#287])
## 4.10.4
* Throw ENOTDIR when trying to open an incorrect path (thanks @niieani, see [#282][#282])
* Fix maybeCallback return (thanks @3cp, see [#281][#281])
## 4.10.3
* Fix bad promise rejection on some fs.promises methods (thanks @3cp, see [#279][#279])
## 4.10.2
* Fix timestamps for Node > 12.10 (thanks @3cp, see [#277][#277])
## 4.10.1
* Fix for `fs.mkdir` with the `recursive` option on existing directories (thanks @3cp, see [#271][#271])
## 4.10.0
* Support the `recursive` option for `fs.mkdir` (thanks @3cp, see [#268][#268])
## 4.9.0
* Improve `readFile` support for Node 10+ (thanks @huochunpeng, see [#265][#265])
* Updated dev dependencies (see [#267][#267])
## 4.8.0
* Fix compatibility issues with Node 10 and 11 (thanks @huochunpeng [#260][#260])
* Support experimental `fs.promises` (thanks @huochunpeng [#260][#260])
## 4.7.0
* Fix for readdir on Node 10.10 (thanks @maxwellgerber [#251][#251])
* Fix for reading and writing using Uint8Array (thanks @maxwellgerber [#249][#249])
* Document how to properly restore the fs with Jest snapshot testing (thanks @tricoder42 [#247][#247])
* More informative error when opening a directory (thanks @maxwellgerber [#242][#242])
## 4.6.0
Note that the mocked fs.createReadStream and fs.createWriteStream are not working properly with Node 10.5+.
* Implement binding.copyFile ([#243][#243])
* Stat fixes for Node 10.5 (thanks @tomhughes, see [#241][#241])
## 4.5.0
* Updates for Node 10 compatibility ([#237][#237])
* Throw ENOENT in readlink when item is missing (thanks @deployable, see [#232][#232])
* Add path to errors when it exists (thanks @deployable, see [#230][#230])
## 4.4.2
* Throw if item content is invalid in config (thanks @mutantcornholio, see [#221][#221])
* Use const in readme (thanks @denar90, see [#222][#222])
## 4.4.1
* Document that tests are run on Node 8.x as well.
## 4.4.0
* Fix stat issue with Node 8 (thanks @AGrzes, see [#209][#209])
* Make code prettier (see [#210][#210])
## 4.3.0
* Add support for fs.mkdtemp() and fs.mkdtempSync (see [#207][#207])
## 4.2.0
* Update fs.stat(), fs.lstat(), and fs.fstat() for Node 7.7+ (thanks @not-an-aardvark, see [#198][#198])
## 4.1.0
* Correctly follow a symlink chain in `binding.open()` (thanks @vlindhol, see [#195][#195])
## 4.0.0
In earlier versions of `mock-fs`, a monkey-patched version of the `fs` module was used to provide an in-memory filesystem. With each major release of Node, the `mock-fs` package needed to include a modified copy of the `fs` module. With the `mock-fs@4` release, this package no longer includes a modified copy of the `fs` module. Instead, this package overrides `process.binding('fs')`. While this is not part of Node's stable API, it has proven to be a more stable interface than the `fs` module itself (based on experience implementing it with Node 0.8 through 7.0).
Upgrading from 3.x to 4.0 should be straightforward for most applications. There are several breaking changes that may be restored in future releases:
* The `mock.fs()` function has been removed.
* The object created by `fs.stat()` and friends is no longer an instance of `fs.Stats` (though it behaves as one).
* Lazy `require()` calls do not work consistently.
Detailed changes:
* Only override `process.binding('fs')` ([#182][#182])
* Expose the root of the mocked filesystem (thanks @ciaranj, see [#194][#194])
## 3.12.1
* Revert the require cache clearing behavior ([#181][#181]).
## 3.12.0
* Support for Node 7.x (thanks @goliney, see [#174][#174]).
* Remove calls to `printDeprecation` ([#175][#175]).
* Break early when checking version (thanks @isiahmeadows, see [#157][#157]).
* Add a note about restoring `fs` (thanks @matheuss, see [#147][#147]).
* Clear the require cache before overriding fs functions ([#141][#141])
## 3.11.0
* Make `require()` calls use the real filesystem ([#139][#139]).
* Reduce the manual `fs` module patching ([#140][#140]).
## 3.10.0
* Fixes for Node 6.3 ([#138][#138]).
* Fix permissions issues on directories (thanks @as3richa, see [#105][#105]).
## 3.9.0
* Support for Node 6.x (thanks @tmcw, see [#107][#107]).
## 3.8.0
* Implement `binding.writeBuffers()` (see [#94][#94]).
## 3.7.0
* Add support for `fs.access()` and `fs.accessSync()` (thanks @shyiko, see [#78][#78] and [#80][#80]).
## 3.6.0
* Add `createCwd` and `createTmp` options to control the creation of `process.cwd()` and `os.tmpdir()` directories in the mocked filesystem (see [#72][#72]).
* Update Travis and AppVeyor configurations (see [#73][#73])
* Remove unused dev dependency (see [#75][#75])
## 3.5.0
* Support for Node 5.x (thanks @tmcw, see [#69][#69]).
## 3.4.0
* Support for Node 4.x (thanks @AlexMeah, see [#65][#65]).
## 3.3.0
* Traverse symlinks recursively (thanks @caitp, see [#57][#57]).
* Upgrade to rewire@2.3.4 (thanks @mbarlock, see [#60][#60]).
## 3.2.0
* Support for io.js 3.0 (thanks @JustBlackBird, see [#61][#61]).
## 3.1.0
* Follow symlinks in `readdir()` and `readdirSync()` (thanks @caitp, see [#56][#56]).
## 3.0.0
* Override `process.cwd()` and `process.chdir()` to work with mocked filesystem (thanks @timkendrick, see [#41][#41]).
* Add note about known incompatibilities (thanks @psalaets, see [#45][#45]).
## 2.7.0
* Support for io.js 2.0 (thanks @jwilsson, see [#38][#38]).
## 2.6.0
* Add `birthtime` to `Stats` objects (thanks @meandmycode, see [#33][#33]).
## 2.5.0
* Support for io.js 1.1 (thanks @andrewblond, see [#21][#21]).
* Testing on Windows with AppVeyor (thanks @andrewblond, see [#22][#22]).
## 2.4.0
* Support for Node 0.12 (thanks @mlegenhausen, see [#18][#18]).
## 2.3.1
* Preserve arity of callbacks (see [#11][#11]).
## 2.3.0
* Fixes for Node 0.11.13 (see [#9][#9]).
## 2.2.0
* Respect file mode on POSIX-compliant systems (see [#7][#7]).
* Add benchmarks comparing mock-fs and fs modules (see [#6][#6]).
## 2.1.2
* Added more complete license text.
* Test on Node 0.9 and 0.11 in addition to 0.8 and 0.10.
## 2.1.1
* Added this changelog.
* Removed unused gruntfile.js.
## 2.1.0
* Directory mtime is now updated when items are added, removed, or modified ([#2][#2]).
* Fixed several issues on Windows (see [#3][#3]). One issue remains on Windows with Node 0.8 (see [#4][#4]).
* Swapped out Grunt with a single script to run tasks (see [#5][#5]).
## 2.0.0
* Simplified API (see [#1][#1]).
[#1]: https://github.com/tschaub/mock-fs/pull/1
[#2]: https://github.com/tschaub/mock-fs/pull/2
[#3]: https://github.com/tschaub/mock-fs/pull/3
[#4]: https://github.com/tschaub/mock-fs/issues/4
[#5]: https://github.com/tschaub/mock-fs/pull/5
[#6]: https://github.com/tschaub/mock-fs/pull/6
[#7]: https://github.com/tschaub/mock-fs/pull/7
[#9]: https://github.com/tschaub/mock-fs/issues/9
[#11]: https://github.com/tschaub/mock-fs/pull/11
[#18]: https://github.com/tschaub/mock-fs/pull/18
[#21]: https://github.com/tschaub/mock-fs/pull/21
[#22]: https://github.com/tschaub/mock-fs/pull/22
[#33]: https://github.com/tschaub/mock-fs/pull/33
[#38]: https://github.com/tschaub/mock-fs/pull/38
[#41]: https://github.com/tschaub/mock-fs/pull/41
[#45]: https://github.com/tschaub/mock-fs/pull/45
[#56]: https://github.com/tschaub/mock-fs/pull/56
[#61]: https://github.com/tschaub/mock-fs/pull/61
[#60]: https://github.com/tschaub/mock-fs/pull/60
[#57]: https://github.com/tschaub/mock-fs/pull/57
[#65]: https://github.com/tschaub/mock-fs/pull/65
[#69]: https://github.com/tschaub/mock-fs/pull/69
[#72]: https://github.com/tschaub/mock-fs/pull/72
[#73]: https://github.com/tschaub/mock-fs/pull/73
[#75]: https://github.com/tschaub/mock-fs/pull/75
[#78]: https://github.com/tschaub/mock-fs/pull/78
[#80]: https://github.com/tschaub/mock-fs/pull/80
[#94]: https://github.com/tschaub/mock-fs/pull/94
[#107]: https://github.com/tschaub/mock-fs/pull/107
[#105]: https://github.com/tschaub/mock-fs/pull/105
[#138]: https://github.com/tschaub/mock-fs/pull/138
[#139]: https://github.com/tschaub/mock-fs/pull/139
[#140]: https://github.com/tschaub/mock-fs/pull/140
[#141]: https://github.com/tschaub/mock-fs/pull/141
[#147]: https://github.com/tschaub/mock-fs/pull/147
[#157]: https://github.com/tschaub/mock-fs/pull/157
[#174]: https://github.com/tschaub/mock-fs/pull/174
[#175]: https://github.com/tschaub/mock-fs/pull/175
[#181]: https://github.com/tschaub/mock-fs/pull/181
[#182]: https://github.com/tschaub/mock-fs/pull/182
[#194]: https://github.com/tschaub/mock-fs/pull/194
[#195]: https://github.com/tschaub/mock-fs/pull/195
[#198]: https://github.com/tschaub/mock-fs/pull/198
[#207]: https://github.com/tschaub/mock-fs/pull/207
[#209]: https://github.com/tschaub/mock-fs/pull/209
[#210]: https://github.com/tschaub/mock-fs/pull/210
[#221]: https://github.com/tschaub/mock-fs/pull/221
[#222]: https://github.com/tschaub/mock-fs/pull/222
[#230]: https://github.com/tschaub/mock-fs/pull/230
[#232]: https://github.com/tschaub/mock-fs/pull/232
[#237]: https://github.com/tschaub/mock-fs/pull/237
[#243]: https://github.com/tschaub/mock-fs/pull/243
[#242]: https://github.com/tschaub/mock-fs/pull/242
[#247]: https://github.com/tschaub/mock-fs/pull/247
[#249]: https://github.com/tschaub/mock-fs/pull/249
[#251]: https://github.com/tschaub/mock-fs/pull/251
[#260]: https://github.com/tschaub/mock-fs/pull/260
[#265]: https://github.com/tschaub/mock-fs/pull/265
[#267]: https://github.com/tschaub/mock-fs/pull/267
[#268]: https://github.com/tschaub/mock-fs/pull/268
[#271]: https://github.com/tschaub/mock-fs/pull/271
[#277]: https://github.com/tschaub/mock-fs/pull/277
[#279]: https://github.com/tschaub/mock-fs/pull/279
[#281]: https://github.com/tschaub/mock-fs/pull/281
[#282]: https://github.com/tschaub/mock-fs/pull/282
[#286]: https://github.com/tschaub/mock-fs/pull/286
[#287]: https://github.com/tschaub/mock-fs/pull/287
[#289]: https://github.com/tschaub/mock-fs/pull/289
[#293]: https://github.com/tschaub/mock-fs/pull/293
[#295]: https://github.com/tschaub/mock-fs/pull/295
[#303]: https://github.com/tschaub/mock-fs/pull/303
[#304]: https://github.com/tschaub/mock-fs/pull/304
[#306]: https://github.com/tschaub/mock-fs/pull/306
[#307]: https://github.com/tschaub/mock-fs/pull/307
[#320]: https://github.com/tschaub/mock-fs/pull/320
[#322]: https://github.com/tschaub/mock-fs/pull/322
[#325]: https://github.com/tschaub/mock-fs/pull/325
[#335]: https://github.com/tschaub/mock-fs/pull/335
[#337]: https://github.com/tschaub/mock-fs/pull/337
[#342]: https://github.com/tschaub/mock-fs/pull/342
[#361]: https://github.com/tschaub/mock-fs/pull/361
[#363]: https://github.com/tschaub/mock-fs/pull/363
[#366]: https://github.com/tschaub/mock-fs/pull/366
[#369]: https://github.com/tschaub/mock-fs/pull/369
[#387]: https://github.com/tschaub/mock-fs/pull/387
[#390]: https://github.com/tschaub/mock-fs/pull/390
[#391]: https://github.com/tschaub/mock-fs/pull/391
[#360]: https://github.com/tschaub/mock-fs/pull/360
[#401]: https://github.com/tschaub/mock-fs/pull/401
[#402]: https://github.com/tschaub/mock-fs/pull/402
[#407]: https://github.com/tschaub/mock-fs/pull/407
[#408]: https://github.com/tschaub/mock-fs/pull/408
[#409]: https://github.com/tschaub/mock-fs/pull/409
[#410]: https://github.com/tschaub/mock-fs/pull/410
[#412]: https://github.com/tschaub/mock-fs/pull/412
[#413]: https://github.com/tschaub/mock-fs/pull/413
[#415]: https://github.com/tschaub/mock-fs/pull/415
mock-fs-5.5.0/eslint.config.mjs 0000664 0000000 0000000 00000000111 14751162414 0016333 0 ustar 00root root 0000000 0000000 import config from 'eslint-config-tschaub';
export default [...config];
mock-fs-5.5.0/lib/ 0000775 0000000 0000000 00000000000 14751162414 0013633 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/lib/binding.js 0000664 0000000 0000000 00000134754 14751162414 0015621 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const path = require('path');
const FileDescriptor = require('./descriptor.js');
const Directory = require('./directory.js');
const {FSError} = require('./error.js');
const File = require('./file.js');
const {getPathParts, getRealPath} = require('./filesystem.js');
const SymbolicLink = require('./symlink.js');
const MODE_TO_KTYPE = {
[constants.S_IFREG]: constants.UV_DIRENT_FILE,
[constants.S_IFDIR]: constants.UV_DIRENT_DIR,
[constants.S_IFBLK]: constants.UV_DIRENT_BLOCK,
[constants.S_IFCHR]: constants.UV_DIRENT_CHAR,
[constants.S_IFLNK]: constants.UV_DIRENT_LINK,
[constants.S_IFIFO]: constants.UV_DIRENT_FIFO,
[constants.S_IFSOCK]: constants.UV_DIRENT_SOCKET,
};
/** Workaround for optimizations in node 8+ */
const fsBinding = process.binding('fs');
const kUsePromises = fsBinding.kUsePromises;
let statValues;
let bigintStatValues;
if (fsBinding.statValues) {
statValues = fsBinding.statValues; // node 10+
bigintStatValues = fsBinding.bigintStatValues;
}
const MAX_LINKS = 50;
/**
* Call the provided function and either return the result or call the callback
* with it (depending on if a callback is provided).
* @param {function():void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @param {Object} thisArg This argument for the following function.
* @param {function():any} func Function to call.
* @return {*} Return (if callback is not provided).
*/
function maybeCallback(callback, ctx, thisArg, func) {
let err = null;
let val;
if (usePromises(callback)) {
// support nodejs v10+ fs.promises
try {
val = func.call(thisArg);
} catch (e) {
err = e;
}
return new Promise(function (resolve, reject) {
setImmediate(function () {
if (err) {
reject(err);
} else {
resolve(val);
}
});
});
} else if (callback && typeof callback === 'function') {
try {
val = func.call(thisArg);
} catch (e) {
err = e;
}
setImmediate(function () {
if (val === undefined) {
callback(err);
} else {
callback(err, val);
}
});
} else if (ctx && typeof ctx === 'object') {
try {
return func.call(thisArg);
} catch (e) {
// default to errno for UNKNOWN
ctx.code = e.code || 'UNKNOWN';
ctx.errno = e.errno || FSError.codes.UNKNOWN.errno;
}
} else {
return func.call(thisArg);
}
}
function usePromises(callback) {
return kUsePromises && callback === kUsePromises;
}
/**
* set syscall property on context object, only for nodejs v10+.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @param {string} syscall Name of syscall.
*/
function markSyscall(ctx, syscall) {
if (ctx && typeof ctx === 'object') {
ctx.syscall = syscall;
}
}
/**
* Handle FSReqWrap oncomplete.
* @param {Function} callback The callback.
* @return {Function} The normalized callback.
*/
function normalizeCallback(callback) {
if (callback && typeof callback.oncomplete === 'function') {
// Unpack callback from FSReqWrap
callback = callback.oncomplete.bind(callback);
}
return callback;
}
function getDirentType(mode) {
const ktype = MODE_TO_KTYPE[mode & constants.S_IFMT];
if (ktype === undefined) {
return constants.UV_DIRENT_UNKNOWN;
}
return ktype;
}
function notImplemented() {
throw new Error('Method not implemented');
}
function deBuffer(p) {
return Buffer.isBuffer(p) ? p.toString() : p;
}
/**
* Create a new binding with the given file system.
* @param {FileSystem} system Mock file system.
* @class
*/
function Binding(system) {
/**
* Mock file system.
* @type {FileSystem}
*/
this._system = system;
/**
* Lookup of open files.
* @type {Object}
*/
this._openFiles = {};
/**
* Counter for file descriptors.
* @type {number}
*/
this._counter = -1;
const stdin = new FileDescriptor(constants.O_RDWR);
stdin.setItem(new File.StandardInput());
this.trackDescriptor(stdin);
const stdout = new FileDescriptor(constants.O_RDWR);
stdout.setItem(new File.StandardOutput());
this.trackDescriptor(stdout);
const stderr = new FileDescriptor(constants.O_RDWR);
stderr.setItem(new File.StandardError());
this.trackDescriptor(stderr);
}
/**
* Get the file system underlying this binding.
* @return {FileSystem} The underlying file system.
*/
Binding.prototype.getSystem = function () {
return this._system;
};
/**
* Reset the file system underlying this binding.
* @param {FileSystem} system The new file system.
*/
Binding.prototype.setSystem = function (system) {
this._system = system;
};
/**
* Get a file descriptor.
* @param {number} fd File descriptor identifier.
* @return {FileDescriptor} File descriptor.
*/
Binding.prototype.getDescriptorById = function (fd) {
if (!this._openFiles.hasOwnProperty(fd)) {
throw new FSError('EBADF');
}
return this._openFiles[fd];
};
/**
* Keep track of a file descriptor as open.
* @param {FileDescriptor} descriptor The file descriptor.
* @return {number} Identifier for file descriptor.
*/
Binding.prototype.trackDescriptor = function (descriptor) {
const fd = ++this._counter;
this._openFiles[fd] = descriptor;
return fd;
};
/**
* Stop tracking a file descriptor as open.
* @param {number} fd Identifier for file descriptor.
*/
Binding.prototype.untrackDescriptorById = function (fd) {
if (!this._openFiles.hasOwnProperty(fd)) {
throw new FSError('EBADF');
}
delete this._openFiles[fd];
};
/**
* Resolve the canonicalized absolute pathname.
* @param {string|Buffer} filepath The file path.
* @param {string} encoding The encoding for the return.
* @param {Function} callback The callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {string|Buffer} The real path.
*/
Binding.prototype.realpath = function (filepath, encoding, callback, ctx) {
markSyscall(ctx, 'realpath');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
let realPath;
filepath = deBuffer(filepath);
const resolved = path.resolve(filepath);
const parts = getPathParts(resolved);
let item = this._system.getRoot();
let itemPath = '/';
let name, i, ii;
for (i = 0, ii = parts.length; i < ii; ++i) {
name = parts[i];
while (item instanceof SymbolicLink) {
itemPath = path.resolve(path.dirname(itemPath), item.getPath());
item = this._system.getItem(itemPath);
}
if (!item) {
throw new FSError('ENOENT', filepath);
}
if (item instanceof Directory) {
itemPath = path.resolve(itemPath, name);
item = item.getItem(name);
} else {
throw new FSError('ENOTDIR', filepath);
}
}
if (item) {
while (item instanceof SymbolicLink) {
itemPath = path.resolve(path.dirname(itemPath), item.getPath());
item = this._system.getItem(itemPath);
}
realPath = itemPath;
} else {
throw new FSError('ENOENT', filepath);
}
// Remove win32 file namespace prefix \\?\
realPath = getRealPath(realPath);
if (encoding === 'buffer') {
realPath = Buffer.from(realPath);
}
return realPath;
});
};
function fillStats(stats, bigint) {
const target = bigint ? bigintStatValues : statValues;
for (let i = 0; i < 36; i++) {
target[i] = stats[i];
}
}
/**
* Stat an item.
* @param {string} filepath Path.
* @param {boolean} bigint Use BigInt.
* @param {function(Error, Float64Array|BigUint64Array):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined (if sync).
*/
Binding.prototype.stat = function (filepath, bigint, callback, ctx) {
markSyscall(ctx, 'stat');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
filepath = deBuffer(filepath);
let item = this._system.getItem(filepath);
if (item instanceof SymbolicLink) {
item = this._system.getItem(
path.resolve(path.dirname(filepath), item.getPath()),
);
}
if (!item) {
throw new FSError('ENOENT', filepath);
}
const stats = item.getStats(bigint);
fillStats(stats, bigint);
return stats;
});
};
/**
* Stat an item.
* @param {string} filepath Path.
* @param {boolean} bigint Use BigInt.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined if sync.
*/
Binding.prototype.statSync = function (filepath, bigint, ctx) {
return this.stat(filepath, bigint, undefined, ctx);
};
/**
* Stat an item.
* @param {number} fd File descriptor.
* @param {boolean} bigint Use BigInt.
* @param {function(Error, Float64Array|BigUint64Array):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined (if sync).
*/
Binding.prototype.fstat = function (fd, bigint, callback, ctx) {
markSyscall(ctx, 'fstat');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
const item = descriptor.getItem();
const stats = item.getStats(bigint);
fillStats(stats, bigint);
return stats;
});
};
/**
* Close a file descriptor.
* @param {number} fd File descriptor.
* @param {function(Error):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback.
*/
Binding.prototype.close = function (fd, callback, ctx) {
markSyscall(ctx, 'close');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
this.untrackDescriptorById(fd);
});
};
/**
* Close a file descriptor.
* @param {number} fd File descriptor.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return.
*/
Binding.prototype.closeSync = function (fd, ctx) {
return this.close(fd, undefined, ctx);
};
/**
* Open and possibly create a file.
* @param {string} pathname File path.
* @param {number} flags Flags.
* @param {number} mode Mode.
* @param {function(Error, string):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {string} File descriptor (if sync).
*/
Binding.prototype.open = function (pathname, flags, mode, callback, ctx) {
markSyscall(ctx, 'open');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const descriptor = new FileDescriptor(flags, usePromises(callback));
let item = this._system.getItem(pathname);
while (item instanceof SymbolicLink) {
item = this._system.getItem(
path.resolve(path.dirname(pathname), item.getPath()),
);
}
if (descriptor.isExclusive() && item) {
throw new FSError('EEXIST', pathname);
}
if (descriptor.isCreate() && !item) {
const parent = this._system.getItem(path.dirname(pathname));
if (!parent) {
throw new FSError('ENOENT', pathname);
}
if (!(parent instanceof Directory)) {
throw new FSError('ENOTDIR', pathname);
}
item = new File();
if (mode) {
item.setMode(mode);
}
parent.addItem(path.basename(pathname), item);
}
if (descriptor.isRead()) {
if (!item) {
throw new FSError('ENOENT', pathname);
}
if (!item.canRead()) {
throw new FSError('EACCES', pathname);
}
}
if (descriptor.isWrite() && !item.canWrite()) {
throw new FSError('EACCES', pathname);
}
if (
item instanceof Directory &&
(descriptor.isTruncate() || descriptor.isAppend())
) {
throw new FSError('EISDIR', pathname);
}
if (descriptor.isTruncate()) {
if (!(item instanceof File)) {
throw new FSError('EBADF');
}
item.setContent('');
}
if (descriptor.isTruncate() || descriptor.isAppend()) {
descriptor.setPosition(item.getContent().length);
}
descriptor.setItem(item);
return this.trackDescriptor(descriptor);
});
};
/**
* Open and possibly create a file.
* @param {string} pathname File path.
* @param {number} flags Flags.
* @param {number} mode Mode.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {string} File descriptor.
*/
Binding.prototype.openSync = function (pathname, flags, mode, ctx) {
return this.open(pathname, flags, mode, undefined, ctx);
};
/**
* Open a file handler. A new api in nodejs v10+ for fs.promises
* @param {string} pathname File path.
* @param {number} flags Flags.
* @param {number} mode Mode.
* @param {Function} callback Callback (optional), expecting kUsePromises in nodejs v10+.
* @return {string} The file handle.
*/
Binding.prototype.openFileHandle = function (pathname, flags, mode, callback) {
const self = this;
return this.open(pathname, flags, mode, kUsePromises).then(function (fd) {
// nodejs v10+ fs.promises FileHandler constructor only ask these three properties.
return {
getAsyncId: notImplemented,
fd: fd,
close: function () {
return self.close(fd, kUsePromises);
},
};
});
};
/**
* Read from a file descriptor.
* @param {string} fd File descriptor.
* @param {Buffer} buffer Buffer that the contents will be written to.
* @param {number} offset Offset in the buffer to start writing to.
* @param {number} length Number of bytes to read.
* @param {?number} position Where to begin reading in the file. If null,
* data will be read from the current file position.
* @param {function(Error, number, Buffer):void} callback Callback (optional) called
* with any error, number of bytes read, and the buffer.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {number} Number of bytes read (if sync).
*/
Binding.prototype.read = function (
fd,
buffer,
offset,
length,
position,
callback,
ctx,
) {
markSyscall(ctx, 'read');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
if (!descriptor.isRead()) {
throw new FSError('EBADF');
}
const file = descriptor.getItem();
if (file instanceof Directory) {
throw new FSError('EISDIR');
}
if (!(file instanceof File)) {
// deleted or not a regular file
throw new FSError('EBADF');
}
if (typeof position !== 'number' || position < 0) {
position = descriptor.getPosition();
}
const content = file.getContent();
const start = Math.min(position, content.length);
const end = Math.min(position + length, content.length);
const read = start < end ? content.copy(buffer, offset, start, end) : 0;
descriptor.setPosition(position + read);
return read;
});
};
/**
* Write to a file descriptor given a buffer.
* @param {string} src Source file.
* @param {string} dest Destination file.
* @param {number} flags Modifiers for copy operation.
* @param {function(Error):void} callback Callback (optional) called
* with any error.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.copyFile = function (src, dest, flags, callback, ctx) {
markSyscall(ctx, 'copyfile');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
src = deBuffer(src);
dest = deBuffer(dest);
const srcFd = this.open(src, constants.O_RDONLY);
try {
const srcDescriptor = this.getDescriptorById(srcFd);
if (!srcDescriptor.isRead()) {
throw new FSError('EBADF');
}
const srcFile = srcDescriptor.getItem();
if (!(srcFile instanceof File)) {
throw new FSError('EBADF');
}
const srcContent = srcFile.getContent();
let destFlags =
constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC;
if ((flags & constants.COPYFILE_EXCL) === constants.COPYFILE_EXCL) {
destFlags |= constants.O_EXCL;
}
const destFd = this.open(dest, destFlags);
try {
this.writeBuffer(destFd, srcContent, 0, srcContent.length, 0);
} finally {
this.close(destFd);
}
} finally {
this.close(srcFd);
}
});
};
/**
* Write to a file descriptor given a buffer.
* @param {string} src Source file.
* @param {string} dest Destination file.
* @param {number} flags Modifiers for copy operation.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.copyFileSync = function (src, dest, flags, ctx) {
return this.copyFile(src, dest, flags, undefined, ctx);
};
/**
* Write to a file descriptor given a buffer.
* @param {string} fd File descriptor.
* @param {Array} buffers Array of buffers with contents to write.
* @param {?number} position Where to begin writing in the file. If null,
* data will be written to the current file position.
* @param {function(Error, number, Buffer):void} callback Callback (optional) called
* with any error, number of bytes written, and the buffer.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {number} Number of bytes written (if sync).
*/
Binding.prototype.writeBuffers = function (
fd,
buffers,
position,
callback,
ctx,
) {
markSyscall(ctx, 'write');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
if (!descriptor.isWrite()) {
throw new FSError('EBADF');
}
const file = descriptor.getItem();
if (!(file instanceof File)) {
// not a regular file
throw new FSError('EBADF');
}
if (typeof position !== 'number' || position < 0) {
position = descriptor.getPosition();
}
let content = file.getContent();
const newContent = Buffer.concat(buffers);
const newLength = position + newContent.length;
if (content.length < newLength) {
const tempContent = Buffer.alloc(newLength);
content.copy(tempContent);
content = tempContent;
}
const written = newContent.copy(content, position);
file.setContent(content);
descriptor.setPosition(newLength);
return written;
});
};
/**
* Write to a file descriptor given a buffer.
* @param {string} fd File descriptor.
* @param {Buffer} buffer Buffer with contents to write.
* @param {number} offset Offset in the buffer to start writing from.
* @param {number} length Number of bytes to write.
* @param {?number} position Where to begin writing in the file. If null,
* data will be written to the current file position.
* @param {function(Error, number, Buffer):void} callback Callback (optional) called
* with any error, number of bytes written, and the buffer.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {number} Number of bytes written (if sync).
*/
Binding.prototype.writeBuffer = function (
fd,
buffer,
offset,
length,
position,
callback,
ctx,
) {
markSyscall(ctx, 'write');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
if (!descriptor.isWrite()) {
throw new FSError('EBADF');
}
const file = descriptor.getItem();
if (!(file instanceof File)) {
// not a regular file
throw new FSError('EBADF');
}
if (typeof position !== 'number' || position < 0) {
position = descriptor.getPosition();
}
let content = file.getContent();
const newLength = position + length;
if (content.length < newLength) {
const newContent = Buffer.alloc(newLength);
content.copy(newContent);
content = newContent;
}
const sourceEnd = Math.min(offset + length, buffer.length);
const written = Buffer.from(buffer).copy(
content,
position,
offset,
sourceEnd,
);
file.setContent(content);
descriptor.setPosition(newLength);
// If we're in fs.promises / FileHandle we need to return a promise
// Both fs.promises.open().then(fd => fs.write())
// and fs.openSync().writeSync() use this function
// without a callback, so we have to check if the descriptor was opened
// with kUsePromises
return descriptor.isPromise() ? Promise.resolve(written) : written;
});
};
/**
* Write to a file descriptor given a string.
* @param {string} fd File descriptor.
* @param {string} string String with contents to write.
* @param {number} position Where to begin writing in the file. If null,
* data will be written to the current file position.
* @param {string} encoding String encoding.
* @param {function(Error, number, string):void} callback Callback (optional) called
* with any error, number of bytes written, and the string.
* @param {Object} ctx The context.
* @return {number} Number of bytes written (if sync).
*/
Binding.prototype.writeString = function (
fd,
string,
position,
encoding,
callback,
ctx,
) {
markSyscall(ctx, 'write');
const buffer = Buffer.from(string, encoding);
let wrapper;
if (callback && callback !== kUsePromises) {
if (callback.oncomplete) {
callback = callback.oncomplete.bind(callback);
}
wrapper = function (err, written, returned) {
callback(err, written, returned && string);
};
}
return this.writeBuffer(fd, buffer, 0, buffer.length, position, wrapper, ctx);
};
/**
* Rename a file.
* @param {string} oldPath Old pathname.
* @param {string} newPath New pathname.
* @param {function(Error):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {undefined}
*/
Binding.prototype.rename = function (oldPath, newPath, callback, ctx) {
markSyscall(ctx, 'rename');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
oldPath = deBuffer(oldPath);
newPath = deBuffer(newPath);
const oldItem = this._system.getItem(oldPath);
if (!oldItem) {
throw new FSError('ENOENT', oldPath);
}
const oldParent = this._system.getItem(path.dirname(oldPath));
const oldName = path.basename(oldPath);
const newItem = this._system.getItem(newPath);
const newParent = this._system.getItem(path.dirname(newPath));
const newName = path.basename(newPath);
if (newItem) {
// make sure they are the same type
if (oldItem instanceof File) {
if (newItem instanceof Directory) {
throw new FSError('EISDIR', newPath);
}
} else if (oldItem instanceof Directory) {
if (!(newItem instanceof Directory)) {
throw new FSError('ENOTDIR', newPath);
}
if (newItem.list().length > 0) {
throw new FSError('ENOTEMPTY', newPath);
}
}
newParent.removeItem(newName);
} else {
if (!newParent) {
throw new FSError('ENOENT', newPath);
}
if (!(newParent instanceof Directory)) {
throw new FSError('ENOTDIR', newPath);
}
}
oldParent.removeItem(oldName);
newParent.addItem(newName, oldItem);
});
};
/**
* Rename a file.
* @param {string} oldPath Old pathname.
* @param {string} newPath New pathname.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {undefined}
*/
Binding.prototype.renameSync = function (oldPath, newPath, ctx) {
return this.rename(oldPath, newPath, undefined, ctx);
};
/**
* Read a directory.
* @param {string} dirpath Path to directory.
* @param {string} encoding The encoding ('utf-8' or 'buffer').
* @param {boolean} withFileTypes whether or not to return fs.Dirent objects
* @param {function(Error, (Array | Array)): void} callback Callback
* (optional) called with any error or array of items in the directory.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {Array | Array} Array of items in directory (if sync).
*/
Binding.prototype.readdir = function (
dirpath,
encoding,
withFileTypes,
callback,
ctx,
) {
markSyscall(ctx, 'scandir');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
dirpath = deBuffer(dirpath);
let dpath = dirpath;
let dir = this._system.getItem(dirpath);
while (dir instanceof SymbolicLink) {
dpath = path.resolve(path.dirname(dpath), dir.getPath());
dir = this._system.getItem(dpath);
}
if (!dir) {
throw new FSError('ENOENT', dirpath);
}
if (!(dir instanceof Directory)) {
throw new FSError('ENOTDIR', dirpath);
}
if (!dir.canRead()) {
throw new FSError('EACCES', dirpath);
}
let list = dir.list();
if (encoding === 'buffer') {
list = list.map(function (item) {
return Buffer.from(item);
});
}
if (withFileTypes === true) {
const types = list.map(function (name) {
const stats = dir.getItem(name).getStats();
return getDirentType(stats.mode);
});
list = [list, types];
}
return list;
});
};
/**
* Read file as utf8 string.
* @param {string} name file to write.
* @param {number} flags Flags.
* @return {string} the file content.
*/
Binding.prototype.readFileUtf8 = function (name, flags) {
const fd = this.open(name, flags);
const descriptor = this.getDescriptorById(fd);
if (!descriptor.isRead()) {
throw new FSError('EBADF');
}
const file = descriptor.getItem();
if (file instanceof Directory) {
throw new FSError('EISDIR');
}
if (!(file instanceof File)) {
// deleted or not a regular file
throw new FSError('EBADF');
}
const content = file.getContent();
return content.toString('utf8');
};
/**
* Write a utf8 string.
* @param {string} filepath file to write.
* @param {string} data data to write to filepath.
* @param {number} flags Flags.
* @param {number} mode Mode.
*/
Binding.prototype.writeFileUtf8 = function (filepath, data, flags, mode) {
const destFd = this.open(filepath, flags, mode);
this.writeString(destFd, data, null, 'utf8');
};
/**
* Create a directory.
* @param {string} pathname Path to new directory.
* @param {number} mode Permissions.
* @param {boolean} recursive Recursively create deep directory. (added in nodejs v10+)
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.mkdir = function (pathname, mode, recursive, callback, ctx) {
markSyscall(ctx, 'mkdir');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const item = this._system.getItem(pathname);
if (item) {
if (recursive && item instanceof Directory) {
// silently pass existing folder in recursive mode
return;
}
throw new FSError('EEXIST', pathname);
}
const _mkdir = function (_pathname) {
const parentDir = path.dirname(_pathname);
let parent = this._system.getItem(parentDir);
if (!parent) {
if (!recursive) {
throw new FSError('ENOENT', _pathname);
}
parent = _mkdir(parentDir, true);
}
this.access(parentDir, parseInt('0002', 8));
const dir = new Directory();
if (mode) {
dir.setMode(mode);
}
return parent.addItem(path.basename(_pathname), dir);
}.bind(this);
_mkdir(pathname);
});
};
/**
* Remove a directory.
* @param {string} pathname Path to directory.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.rmdir = function (pathname, callback, ctx) {
markSyscall(ctx, 'rmdir');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const item = this._system.getItem(pathname);
if (!item) {
throw new FSError('ENOENT', pathname);
}
if (!(item instanceof Directory)) {
throw new FSError('ENOTDIR', pathname);
}
if (item.list().length > 0) {
throw new FSError('ENOTEMPTY', pathname);
}
this.access(path.dirname(pathname), parseInt('0002', 8));
const parent = this._system.getItem(path.dirname(pathname));
parent.removeItem(path.basename(pathname));
});
};
const PATH_CHARS =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
const MAX_ATTEMPTS = 62 * 62 * 62;
/**
* Create a directory based on a template.
* See http://web.mit.edu/freebsd/head/lib/libc/stdio/mktemp.c
* @param {string} prefix Path template (trailing Xs will be replaced).
* @param {string} encoding The encoding ('utf-8' or 'buffer').
* @param {function(Error, string):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.mkdtemp = function (prefix, encoding, callback, ctx) {
if (encoding && typeof encoding !== 'string') {
callback = encoding;
encoding = 'utf-8';
}
markSyscall(ctx, 'mkdtemp');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
prefix = prefix.replace(/X{0,6}$/, 'XXXXXX');
const parentPath = path.dirname(prefix);
const parent = this._system.getItem(parentPath);
if (!parent) {
throw new FSError('ENOENT', prefix);
}
if (!(parent instanceof Directory)) {
throw new FSError('ENOTDIR', prefix);
}
this.access(parentPath, parseInt('0002', 8));
const template = path.basename(prefix);
let unique = false;
let count = 0;
let name;
while (!unique && count < MAX_ATTEMPTS) {
let position = template.length - 1;
let replacement = '';
while (template.charAt(position) === 'X') {
replacement += PATH_CHARS.charAt(
Math.floor(PATH_CHARS.length * Math.random()),
);
position -= 1;
}
const candidate = template.slice(0, position + 1) + replacement;
if (!parent.getItem(candidate)) {
name = candidate;
unique = true;
}
count += 1;
}
if (!name) {
throw new FSError('EEXIST', prefix);
}
const dir = new Directory();
parent.addItem(name, dir);
let uniquePath = path.join(parentPath, name);
if (encoding === 'buffer') {
uniquePath = Buffer.from(uniquePath);
}
return uniquePath;
});
};
/**
* Truncate a file.
* @param {number} fd File descriptor.
* @param {number} len Number of bytes.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.ftruncate = function (fd, len, callback, ctx) {
markSyscall(ctx, 'ftruncate');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
if (!descriptor.isWrite()) {
throw new FSError('EINVAL');
}
const file = descriptor.getItem();
if (!(file instanceof File)) {
throw new FSError('EINVAL');
}
const content = file.getContent();
const newContent = Buffer.alloc(len);
content.copy(newContent);
file.setContent(newContent);
});
};
/**
* Legacy support.
* @param {number} fd File descriptor.
* @param {number} len Number of bytes.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
*/
Binding.prototype.truncate = Binding.prototype.ftruncate;
/**
* Change user and group owner.
* @param {string} pathname Path.
* @param {number} uid User id.
* @param {number} gid Group id.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.chown = function (pathname, uid, gid, callback, ctx) {
markSyscall(ctx, 'chown');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const item = this._system.getItem(pathname);
if (!item) {
throw new FSError('ENOENT', pathname);
}
item.setUid(uid);
item.setGid(gid);
});
};
/**
* Change user and group owner.
* @param {number} fd File descriptor.
* @param {number} uid User id.
* @param {number} gid Group id.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.fchown = function (fd, uid, gid, callback, ctx) {
markSyscall(ctx, 'fchown');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
const item = descriptor.getItem();
item.setUid(uid);
item.setGid(gid);
});
};
/**
* Change permissions.
* @param {string} pathname Path.
* @param {number} mode Mode.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.chmod = function (pathname, mode, callback, ctx) {
markSyscall(ctx, 'chmod');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const item = this._system.getItem(pathname);
if (!item) {
throw new FSError('ENOENT', pathname);
}
item.setMode(mode);
});
};
/**
* Change permissions.
* @param {number} fd File descriptor.
* @param {number} mode Mode.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.fchmod = function (fd, mode, callback, ctx) {
markSyscall(ctx, 'fchmod');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
const item = descriptor.getItem();
item.setMode(mode);
});
};
/**
* Delete a named item.
* @param {string} pathname Path to item.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.unlink = function (pathname, callback, ctx) {
markSyscall(ctx, 'unlink');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const item = this._system.getItem(pathname);
if (!item) {
throw new FSError('ENOENT', pathname);
}
if (item instanceof Directory) {
throw new FSError('EPERM', pathname);
}
const parent = this._system.getItem(path.dirname(pathname));
parent.removeItem(path.basename(pathname));
});
};
/**
* Delete a named item.
* @param {string} pathname Path to item.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.unlinkSync = function (pathname, ctx) {
return this.unlink(pathname, undefined, ctx);
};
/**
* Update timestamps.
* @param {string} pathname Path to item.
* @param {number} atime Access time (in seconds).
* @param {number} mtime Modification time (in seconds).
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.utimes = function (pathname, atime, mtime, callback, ctx) {
markSyscall(ctx, 'utimes');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
let filepath = deBuffer(pathname);
let item = this._system.getItem(filepath);
let links = 0;
while (item instanceof SymbolicLink) {
if (links > MAX_LINKS) {
throw new FSError('ELOOP', filepath);
}
filepath = path.resolve(path.dirname(filepath), item.getPath());
item = this._system.getItem(filepath);
++links;
}
if (!item) {
throw new FSError('ENOENT', pathname);
}
item.setATime(new Date(atime * 1000));
item.setMTime(new Date(mtime * 1000));
});
};
/**
* Update timestamps.
* @param {string} pathname Path to item.
* @param {number} atime Access time (in seconds).
* @param {number} mtime Modification time (in seconds).
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.lutimes = function (pathname, atime, mtime, callback, ctx) {
markSyscall(ctx, 'utimes');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const item = this._system.getItem(pathname);
if (!item) {
throw new FSError('ENOENT', pathname);
}
// lutimes doesn't follow symlink
item.setATime(new Date(atime * 1000));
item.setMTime(new Date(mtime * 1000));
});
};
/**
* Update timestamps.
* @param {number} fd File descriptor.
* @param {number} atime Access time (in seconds).
* @param {number} mtime Modification time (in seconds).
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.futimes = function (fd, atime, mtime, callback, ctx) {
markSyscall(ctx, 'futimes');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
const descriptor = this.getDescriptorById(fd);
let item = descriptor.getItem();
let filepath = this._system.getFilepath(item);
let links = 0;
while (item instanceof SymbolicLink) {
if (links > MAX_LINKS) {
throw new FSError('ELOOP', filepath);
}
filepath = path.resolve(path.dirname(filepath), item.getPath());
item = this._system.getItem(filepath);
++links;
}
item.setATime(new Date(atime * 1000));
item.setMTime(new Date(mtime * 1000));
});
};
/**
* Synchronize in-core state with storage device.
* @param {number} fd File descriptor.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.fsync = function (fd, callback, ctx) {
markSyscall(ctx, 'fsync');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
this.getDescriptorById(fd);
});
};
/**
* Synchronize in-core metadata state with storage device.
* @param {number} fd File descriptor.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.fdatasync = function (fd, callback, ctx) {
markSyscall(ctx, 'fdatasync');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
this.getDescriptorById(fd);
});
};
/**
* Create a hard link.
* @param {string} srcPath The existing file.
* @param {string} destPath The new link to create.
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.link = function (srcPath, destPath, callback, ctx) {
markSyscall(ctx, 'link');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
srcPath = deBuffer(srcPath);
destPath = deBuffer(destPath);
const item = this._system.getItem(srcPath);
if (!item) {
throw new FSError('ENOENT', srcPath);
}
if (item instanceof Directory) {
throw new FSError('EPERM', srcPath);
}
if (this._system.getItem(destPath)) {
throw new FSError('EEXIST', destPath);
}
const parent = this._system.getItem(path.dirname(destPath));
if (!parent) {
throw new FSError('ENOENT', destPath);
}
if (!(parent instanceof Directory)) {
throw new FSError('ENOTDIR', destPath);
}
parent.addItem(path.basename(destPath), item);
});
};
/**
* Create a symbolic link.
* @param {string} srcPath Path from link to the source file.
* @param {string} destPath Path for the generated link.
* @param {string} type Ignored (used for Windows only).
* @param {function(Error):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.symlink = function (srcPath, destPath, type, callback, ctx) {
markSyscall(ctx, 'symlink');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
srcPath = deBuffer(srcPath);
destPath = deBuffer(destPath);
if (this._system.getItem(destPath)) {
throw new FSError('EEXIST', destPath);
}
const parent = this._system.getItem(path.dirname(destPath));
if (!parent) {
throw new FSError('ENOENT', destPath);
}
if (!(parent instanceof Directory)) {
throw new FSError('ENOTDIR', destPath);
}
const link = new SymbolicLink();
link.setPath(srcPath);
parent.addItem(path.basename(destPath), link);
});
};
/**
* Create a symbolic link.
* @param {string} srcPath Path from link to the source file.
* @param {string} destPath Path for the generated link.
* @param {string} type Ignored (used for Windows only).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.symlinkSync = function (srcPath, destPath, type, ctx) {
return this.symlink(srcPath, destPath, type, undefined, ctx);
};
/**
* Read the contents of a symbolic link.
* @param {string} pathname Path to symbolic link.
* @param {string} encoding The encoding ('utf-8' or 'buffer').
* @param {function(Error, (string|Buffer)):void} callback Optional callback.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {string|Buffer} Symbolic link contents (path to source).
*/
Binding.prototype.readlink = function (pathname, encoding, callback, ctx) {
if (encoding && typeof encoding !== 'string') {
// this would not happend in nodejs v10+
callback = encoding;
encoding = 'utf-8';
}
markSyscall(ctx, 'readlink');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
pathname = deBuffer(pathname);
const link = this._system.getItem(pathname);
if (!link) {
throw new FSError('ENOENT', pathname);
}
if (!(link instanceof SymbolicLink)) {
throw new FSError('EINVAL', pathname);
}
let linkPath = link.getPath();
if (encoding === 'buffer') {
linkPath = Buffer.from(linkPath);
}
return linkPath;
});
};
/**
* Stat an item.
* @param {string} filepath Path.
* @param {boolean} bigint Use BigInt.
* @param {function(Error, Float64Array|BigUint64Array):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {Float64Array|BigUint64Array|undefined} Stats or undefined (if sync).
*/
Binding.prototype.lstat = function (filepath, bigint, callback, ctx) {
markSyscall(ctx, 'lstat');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
filepath = deBuffer(filepath);
const item = this._system.getItem(filepath);
if (!item) {
throw new FSError('ENOENT', filepath);
}
const stats = item.getStats(bigint);
fillStats(stats, bigint);
return stats;
});
};
/**
* Tests user permissions.
* @param {string} filepath Path.
* @param {number} mode Mode.
* @param {function(Error):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.access = function (filepath, mode, callback, ctx) {
markSyscall(ctx, 'access');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
filepath = deBuffer(filepath);
let item = this._system.getItem(filepath);
let links = 0;
while (item instanceof SymbolicLink) {
if (links > MAX_LINKS) {
throw new FSError('ELOOP', filepath);
}
filepath = path.resolve(path.dirname(filepath), item.getPath());
item = this._system.getItem(filepath);
++links;
}
if (!item) {
throw new FSError('ENOENT', filepath);
}
if (mode && process.getuid && process.getgid) {
if (mode & constants.R_OK && !item.canRead()) {
throw new FSError('EACCES', filepath);
}
if (mode & constants.W_OK && !item.canWrite()) {
throw new FSError('EACCES', filepath);
}
if (mode & constants.X_OK && !item.canExecute()) {
throw new FSError('EACCES', filepath);
}
}
});
};
/**
* Tests user permissions.
* @param {string} filepath Path.
* @param {number} mode Mode.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.accessSync = function (filepath, mode, ctx) {
return this.access(filepath, mode, undefined, ctx);
};
/**
* Tests whether or not the given path exists.
* @param {string} filepath Path.
* @param {function(Error):void} callback Callback (optional).
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.exists = function (filepath, callback, ctx) {
markSyscall(ctx, 'exists');
return maybeCallback(normalizeCallback(callback), ctx, this, function () {
filepath = deBuffer(filepath);
let item;
try {
item = this._system.getItem(filepath);
} catch {
// ignore errors
// see https://github.com/nodejs/node/blob/v22.11.0/lib/fs.js#L255-L257
return false;
}
if (item) {
if (item instanceof SymbolicLink) {
return this.exists(
path.resolve(path.dirname(filepath), item.getPath()),
callback,
ctx,
);
}
return true;
}
return false;
});
};
/**
* Tests whether or not the given path exists.
* @param {string} filepath Path.
* @param {Object} ctx Context object (optional), only for nodejs v10+.
* @return {*} The return if no callback is provided.
*/
Binding.prototype.existsSync = function (filepath, ctx) {
return this.exists(filepath, undefined, ctx);
};
/**
* Not yet implemented.
*/
Binding.prototype.StatWatcher = notImplemented;
/**
* Export the binding constructor.
*/
module.exports = Binding;
mock-fs-5.5.0/lib/bypass.js 0000775 0000000 0000000 00000002411 14751162414 0015473 0 ustar 00root root 0000000 0000000 const realBinding = process.binding('fs');
let storedBinding;
/**
* Perform action, bypassing mock FS
* @param {Function} fn The function.
* @example
* // This file exists on the real FS, not on the mocked FS
* const filePath = '/path/file.json';
* const data = mock.bypass(() => fs.readFileSync(filePath, 'utf-8'));
* @return {*} The return.
*/
module.exports = function bypass(fn) {
if (typeof fn !== 'function') {
throw new Error(`Must provide a function to perform for mock.bypass()`);
}
disable();
let result;
try {
result = fn();
if (result && typeof result.then === 'function') {
return result.then(
(r) => {
enable();
return r;
},
(err) => {
enable();
throw err;
},
);
} else {
enable();
return result;
}
} catch (err) {
enable();
throw err;
}
};
/**
* Temporarily disable Mocked FS
*/
function disable() {
if (realBinding._mockedBinding) {
storedBinding = realBinding._mockedBinding;
delete realBinding._mockedBinding;
}
}
/**
* Enables Mocked FS after being disabled by disable()
*/
function enable() {
if (storedBinding) {
realBinding._mockedBinding = storedBinding;
storedBinding = undefined;
}
}
mock-fs-5.5.0/lib/descriptor.js 0000664 0000000 0000000 00000005231 14751162414 0016350 0 ustar 00root root 0000000 0000000 const constants = require('constants');
/**
* Create a new file descriptor.
* @param {number} flags Flags.
* @param {boolean} isPromise descriptor was opened via fs.promises
* @class
*/
function FileDescriptor(flags, isPromise = false) {
/**
* Flags.
* @type {number}
*/
this._flags = flags;
/**
* File system item.
* @type {Item}
*/
this._item = null;
/**
* Current file position.
* @type {number}
*/
this._position = 0;
this._isPromise = isPromise;
}
/**
* Set the item.
* @param {Item} item File system item.
*/
FileDescriptor.prototype.setItem = function (item) {
this._item = item;
};
/**
* Get the item.
* @return {Item} File system item.
*/
FileDescriptor.prototype.getItem = function () {
return this._item;
};
/**
* Get the current file position.
* @return {number} File position.
*/
FileDescriptor.prototype.getPosition = function () {
return this._position;
};
/**
* Set the current file position.
* @param {number} position File position.
*/
FileDescriptor.prototype.setPosition = function (position) {
this._position = position;
};
/**
* Check if file opened for appending.
* @return {boolean} Opened for appending.
*/
FileDescriptor.prototype.isAppend = function () {
return (this._flags & constants.O_APPEND) === constants.O_APPEND;
};
/**
* Check if file opened for creation.
* @return {boolean} Opened for creation.
*/
FileDescriptor.prototype.isCreate = function () {
return (this._flags & constants.O_CREAT) === constants.O_CREAT;
};
/**
* Check if file opened for reading.
* @return {boolean} Opened for reading.
*/
FileDescriptor.prototype.isRead = function () {
return (this._flags & constants.O_WRONLY) !== constants.O_WRONLY;
};
/**
* Check if file opened for writing.
* @return {boolean} Opened for writing.
*/
FileDescriptor.prototype.isWrite = function () {
return (
(this._flags & constants.O_WRONLY) === constants.O_WRONLY ||
(this._flags & constants.O_RDWR) === constants.O_RDWR
);
};
/**
* Check if file opened for truncating.
* @return {boolean} Opened for truncating.
*/
FileDescriptor.prototype.isTruncate = function () {
return (this._flags & constants.O_TRUNC) === constants.O_TRUNC;
};
/**
* Check if file opened with exclusive flag.
* @return {boolean} Opened with exclusive.
*/
FileDescriptor.prototype.isExclusive = function () {
return (this._flags & constants.O_EXCL) === constants.O_EXCL;
};
/**
* Check if the file descriptor was opened as a promise
* @return {boolean} Opened from fs.promise
*/
FileDescriptor.prototype.isPromise = function () {
return this._isPromise;
};
/**
* Export the constructor.
*/
module.exports = FileDescriptor;
mock-fs-5.5.0/lib/directory.js 0000664 0000000 0000000 00000004531 14751162414 0016200 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const util = require('util');
const Item = require('./item.js');
/**
* A directory.
* @class
*/
function Directory() {
Item.call(this);
/**
* Items in this directory.
* @type {Object}
*/
this._items = {};
/**
* Permissions.
*/
this._mode = 511; // 0777
}
util.inherits(Directory, Item);
/**
* Add an item to the directory.
* @param {string} name The name to give the item.
* @param {Item} item The item to add.
* @return {Item} The added item.
*/
Directory.prototype.addItem = function (name, item) {
if (this._items.hasOwnProperty(name)) {
throw new Error('Item with the same name already exists: ' + name);
}
this._items[name] = item;
++item.links;
if (item instanceof Directory) {
// for '.' entry
++item.links;
// for subdirectory
++this.links;
}
this.setMTime(new Date());
return item;
};
/**
* Get a named item.
* @param {string} name Item name.
* @return {Item} The named item (or null if none).
*/
Directory.prototype.getItem = function (name) {
let item = null;
if (this._items.hasOwnProperty(name)) {
item = this._items[name];
}
return item;
};
/**
* Remove an item.
* @param {string} name Name of item to remove.
* @return {Item} The orphan item.
*/
Directory.prototype.removeItem = function (name) {
if (!this._items.hasOwnProperty(name)) {
throw new Error('Item does not exist in directory: ' + name);
}
const item = this._items[name];
delete this._items[name];
--item.links;
if (item instanceof Directory) {
// for '.' entry
--item.links;
// for subdirectory
--this.links;
}
this.setMTime(new Date());
return item;
};
/**
* Get list of item names in this directory.
* @return {Array} Item names.
*/
Directory.prototype.list = function () {
return Object.keys(this._items).sort();
};
/**
* Get directory stats.
* @param {bolean} bigint Use BigInt.
* @return {Object} Stats properties.
*/
Directory.prototype.getStats = function (bigint) {
const stats = Item.prototype.getStats.call(this, bigint);
const convert = bigint ? (v) => BigInt(v) : (v) => v;
stats[1] = convert(this.getMode() | constants.S_IFDIR); // mode
stats[8] = convert(1); // size
stats[9] = convert(1); // blocks
return stats;
};
/**
* Export the constructor.
*/
module.exports = Directory;
mock-fs-5.5.0/lib/error.js 0000664 0000000 0000000 00000002443 14751162414 0015325 0 ustar 00root root 0000000 0000000 const uvBinding = process.binding('uv');
/**
* Error codes from libuv.
* @enum {number}
*/
const codes = {};
uvBinding.getErrorMap().forEach(function (value, errno) {
const code = value[0];
const message = value[1];
codes[code] = {errno: errno, message: message};
});
/**
* Create an error.
* @param {string} code Error code.
* @param {string} path Path (optional).
* @class
*/
function FSError(code, path) {
if (!codes.hasOwnProperty(code)) {
throw new Error('Programmer error, invalid error code: ' + code);
}
Error.call(this);
const details = codes[code];
let message = code + ', ' + details.message;
if (path) {
message += " '" + path + "'";
}
this.message = message;
this.code = code;
this.errno = details.errno;
if (path !== undefined) {
this.path = path;
}
Error.captureStackTrace(this, FSError);
}
FSError.prototype = new Error();
FSError.codes = codes;
/**
* Create an abort error for when an asynchronous task was aborted.
* @class
*/
function AbortError() {
Error.call(this);
this.code = 'ABORT_ERR';
this.name = 'AbortError';
Error.captureStackTrace(this, AbortError);
}
AbortError.prototype = new Error();
/**
* FSError constructor.
*/
exports.AbortError = AbortError;
exports.FSError = FSError;
/**
* AbortError constructor.
*/
mock-fs-5.5.0/lib/file.js 0000664 0000000 0000000 00000004705 14751162414 0015116 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const util = require('util');
const Item = require('./item.js');
const EMPTY = Buffer.alloc(0);
/**
* A file.
* @class
*/
function File() {
Item.call(this);
/**
* File content.
* @type {Buffer}
*/
this._content = EMPTY;
}
util.inherits(File, Item);
/**
* Get the file contents.
* @return {Buffer} File contents.
*/
File.prototype.getContent = function () {
this.setATime(new Date());
return this._content;
};
/**
* Set the file contents.
* @param {string|Buffer} content File contents.
*/
File.prototype.setContent = function (content) {
if (typeof content === 'string') {
content = Buffer.from(content);
} else if (!Buffer.isBuffer(content)) {
throw new Error('File content must be a string or buffer');
}
this._content = content;
const now = Date.now();
this.setCTime(new Date(now));
this.setMTime(new Date(now));
};
/**
* Get file stats.
* @param {boolean} bigint Use BigInt.
* @return {Object} Stats properties.
*/
File.prototype.getStats = function (bigint) {
const size = this._content.length;
const stats = Item.prototype.getStats.call(this, bigint);
const convert = bigint ? (v) => BigInt(v) : (v) => v;
stats[1] = convert(this.getMode() | constants.S_IFREG); // mode
stats[8] = convert(size); // size
stats[9] = convert(Math.ceil(size / 512)); // blocks
return stats;
};
/**
* Export the constructor.
*/
module.exports = File;
exports = module.exports;
/**
* Standard input.
* @class
*/
function StandardInput() {
File.call(this);
this.setMode(438); // 0666
}
util.inherits(StandardInput, File);
exports.StandardError = StandardError;
exports.StandardInput = StandardInput;
/**
* Standard output.
* @class
*/
function StandardOutput() {
File.call(this);
this.setMode(438); // 0666
}
util.inherits(StandardOutput, File);
/**
* Write the contents to stdout.
* @param {string|Buffer} content File contents.
*/
StandardOutput.prototype.setContent = function (content) {
if (process.stdout.isTTY) {
process.stdout.write(content);
}
};
exports.StandardOutput = StandardOutput;
/**
* Standard error.
* @class
*/
function StandardError() {
File.call(this);
this.setMode(438); // 0666
}
util.inherits(StandardError, File);
/**
* Write the contents to stderr.
* @param {string|Buffer} content File contents.
*/
StandardError.prototype.setContent = function (content) {
if (process.stderr.isTTY) {
process.stderr.write(content);
}
};
mock-fs-5.5.0/lib/filesystem.js 0000664 0000000 0000000 00000026363 14751162414 0016367 0 ustar 00root root 0000000 0000000 const os = require('os');
const path = require('path');
const Directory = require('./directory.js');
const {FSError} = require('./error.js');
const File = require('./file.js');
const SymbolicLink = require('./symlink.js');
const isWindows = process.platform === 'win32';
// on Win32, change filepath from \\?\c:\a\b to C:\a\b
function getRealPath(filepath) {
if (isWindows && filepath.startsWith('\\\\?\\')) {
// Remove win32 file namespace prefix \\?\
return filepath[4].toUpperCase() + filepath.slice(5);
}
return filepath;
}
function getPathParts(filepath) {
// path.toNamespacedPath is only for Win32 system.
// on other platform, it returns the path unmodified.
const parts = path.toNamespacedPath(path.resolve(filepath)).split(path.sep);
parts.shift();
if (isWindows) {
// parts currently looks like ['', '?', 'c:', ...]
parts.shift();
const q = parts.shift(); // should be '?'
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#win32-file-namespaces
// Win32 File Namespaces prefix \\?\
const base = '\\\\' + q + '\\' + parts.shift().toLowerCase();
parts.unshift(base);
}
if (parts[parts.length - 1] === '') {
parts.pop();
}
return parts;
}
/**
* Create a new file system.
* @param {Object} options Any filesystem options.
* @param {boolean} options.createCwd Create a directory for `process.cwd()`
* (defaults to `true`).
* @param {boolean} options.createTmp Create a directory for `os.tmpdir()`
* (defaults to `true`).
* @class
*/
function FileSystem(options) {
options = options || {};
const createCwd = 'createCwd' in options ? options.createCwd : true;
const createTmp = 'createTmp' in options ? options.createTmp : true;
const root = new Directory();
// populate with default directories
const defaults = [];
if (createCwd) {
defaults.push(process.cwd());
}
if (createTmp) {
defaults.push((os.tmpdir && os.tmpdir()) || os.tmpDir());
}
defaults.forEach(function (dir) {
const parts = getPathParts(dir);
let directory = root;
for (let i = 0, ii = parts.length; i < ii; ++i) {
const name = parts[i];
const candidate = directory.getItem(name);
if (!candidate) {
directory = directory.addItem(name, new Directory());
} else if (candidate instanceof Directory) {
directory = candidate;
} else {
throw new Error('Failed to create directory: ' + dir);
}
}
});
/**
* Root directory.
* @type {Directory}
*/
this._root = root;
}
/**
* Get the root directory.
* @return {Directory} The root directory.
*/
FileSystem.prototype.getRoot = function () {
return this._root;
};
/**
* Get a file system item.
* @param {string} filepath Path to item.
* @return {Item} The item (or null if not found).
*/
FileSystem.prototype.getItem = function (filepath) {
const parts = getPathParts(filepath);
const currentParts = getPathParts(process.cwd());
let item = this._root;
let itemPath = '/';
for (let i = 0, ii = parts.length; i < ii; ++i) {
const name = parts[i];
while (item instanceof SymbolicLink) {
// Symbolic link being traversed as a directory --- If link targets
// another symbolic link, resolve target's path relative to the original
// link's target, otherwise relative to the current item.
itemPath = path.resolve(path.dirname(itemPath), item.getPath());
item = this.getItem(itemPath);
}
if (item) {
if (item instanceof Directory && name !== currentParts[i]) {
// make sure traversal is allowed
// This fails for Windows directories which do not have execute permission, by default. It may be a good idea
// to change this logic to windows-friendly. See notes in mock.createDirectoryInfoFromPaths()
if (!item.canExecute()) {
throw new FSError('EACCES', filepath);
}
}
if (item instanceof File) {
throw new FSError('ENOTDIR', filepath);
}
item = item.getItem(name);
}
if (!item) {
break;
}
itemPath = path.resolve(itemPath, name);
}
return item;
};
function _getFilepath(item, itemPath, wanted) {
if (item === wanted) {
return itemPath;
}
if (item instanceof Directory) {
for (const name of item.list()) {
const got = _getFilepath(
item.getItem(name),
path.join(itemPath, name),
wanted,
);
if (got) {
return got;
}
}
}
return null;
}
/**
* Get file path from a file system item.
* @param {Item} item a file system item.
* @return {string} file path for the item (or null if not found).
*/
FileSystem.prototype.getFilepath = function (item) {
const namespacedPath = _getFilepath(this._root, isWindows ? '' : '/', item);
return getRealPath(namespacedPath);
};
/**
* Populate a directory with an item.
* @param {Directory} directory The directory to populate.
* @param {string} name The name of the item.
* @param {string | Buffer | Function | object} obj Instructions for creating the
* item.
*/
function populate(directory, name, obj) {
let item;
if (typeof obj === 'string' || Buffer.isBuffer(obj)) {
// contents for a file
item = new File();
item.setContent(obj);
} else if (typeof obj === 'function') {
// item factory
item = obj();
} else if (typeof obj === 'object') {
// directory with more to populate
item = new Directory();
for (const key in obj) {
populate(item, key, obj[key]);
}
} else {
throw new Error('Unsupported type: ' + typeof obj + ' of item ' + name);
}
/**
* Special exception for redundant adding of empty directories.
*/
if (
item instanceof Directory &&
item.list().length === 0 &&
directory.getItem(name) instanceof Directory
) {
// pass
} else {
directory.addItem(name, item);
}
}
/**
* Configure a mock file system.
* @param {Object} paths Config object.
* @param {Object} options Any filesystem options.
* @param {boolean} options.createCwd Create a directory for `process.cwd()`
* (defaults to `true`).
* @param {boolean} options.createTmp Create a directory for `os.tmpdir()`
* (defaults to `true`).
* @return {FileSystem} Mock file system.
*/
FileSystem.create = function (paths, options) {
const system = new FileSystem(options);
for (const filepath in paths) {
const parts = getPathParts(filepath);
let directory = system._root;
for (let i = 0, ii = parts.length - 1; i < ii; ++i) {
const name = parts[i];
const candidate = directory.getItem(name);
if (!candidate) {
directory = directory.addItem(name, new Directory());
} else if (candidate instanceof Directory) {
directory = candidate;
} else {
throw new Error('Failed to create directory: ' + filepath);
}
}
populate(directory, parts[parts.length - 1], paths[filepath]);
}
return system;
};
/**
* Generate a factory for new files.
* @param {Object} config File config.
* @return {function():File} Factory that creates a new file.
*/
FileSystem.file = function (config) {
config = config || {};
return function () {
const file = new File();
if (config.hasOwnProperty('content')) {
file.setContent(config.content);
}
if (config.hasOwnProperty('mode')) {
file.setMode(config.mode);
} else {
file.setMode(438); // 0666
}
if (config.hasOwnProperty('uid')) {
file.setUid(config.uid);
}
if (config.hasOwnProperty('gid')) {
file.setGid(config.gid);
}
if (config.hasOwnProperty('atime')) {
file.setATime(config.atime);
} else if (config.hasOwnProperty('atimeMs')) {
file.setATime(new Date(config.atimeMs));
}
if (config.hasOwnProperty('ctime')) {
file.setCTime(config.ctime);
} else if (config.hasOwnProperty('ctimeMs')) {
file.setCTime(new Date(config.ctimeMs));
}
if (config.hasOwnProperty('mtime')) {
file.setMTime(config.mtime);
} else if (config.hasOwnProperty('mtimeMs')) {
file.setMTime(new Date(config.mtimeMs));
}
if (config.hasOwnProperty('birthtime')) {
file.setBirthtime(config.birthtime);
} else if (config.hasOwnProperty('birthtimeMs')) {
file.setBirthtime(new Date(config.birthtimeMs));
}
return file;
};
};
/**
* Generate a factory for new symbolic links.
* @param {Object} config File config.
* @return {function():File} Factory that creates a new symbolic link.
*/
FileSystem.symlink = function (config) {
config = config || {};
return function () {
const link = new SymbolicLink();
if (config.hasOwnProperty('mode')) {
link.setMode(config.mode);
} else {
link.setMode(438); // 0666
}
if (config.hasOwnProperty('uid')) {
link.setUid(config.uid);
}
if (config.hasOwnProperty('gid')) {
link.setGid(config.gid);
}
if (config.hasOwnProperty('path')) {
link.setPath(config.path);
} else {
throw new Error('Missing "path" property');
}
if (config.hasOwnProperty('atime')) {
link.setATime(config.atime);
} else if (config.hasOwnProperty('atimeMs')) {
link.setATime(new Date(config.atimeMs));
}
if (config.hasOwnProperty('ctime')) {
link.setCTime(config.ctime);
} else if (config.hasOwnProperty('ctimeMs')) {
link.setCTime(new Date(config.ctimeMs));
}
if (config.hasOwnProperty('mtime')) {
link.setMTime(config.mtime);
} else if (config.hasOwnProperty('mtimeMs')) {
link.setMTime(new Date(config.mtimeMs));
}
if (config.hasOwnProperty('birthtime')) {
link.setBirthtime(config.birthtime);
} else if (config.hasOwnProperty('birthtimeMs')) {
link.setBirthtime(new Date(config.birthtimeMs));
}
return link;
};
};
/**
* Generate a factory for new directories.
* @param {Object} config File config.
* @return {function():Directory} Factory that creates a new directory.
*/
FileSystem.directory = function (config) {
config = config || {};
return function () {
const dir = new Directory();
if (config.hasOwnProperty('mode')) {
dir.setMode(config.mode);
}
if (config.hasOwnProperty('uid')) {
dir.setUid(config.uid);
}
if (config.hasOwnProperty('gid')) {
dir.setGid(config.gid);
}
if (config.hasOwnProperty('items')) {
for (const name in config.items) {
populate(dir, name, config.items[name]);
}
}
if (config.hasOwnProperty('atime')) {
dir.setATime(config.atime);
} else if (config.hasOwnProperty('atimeMs')) {
dir.setATime(new Date(config.atimeMs));
}
if (config.hasOwnProperty('ctime')) {
dir.setCTime(config.ctime);
} else if (config.hasOwnProperty('ctimeMs')) {
dir.setCTime(new Date(config.ctimeMs));
}
if (config.hasOwnProperty('mtime')) {
dir.setMTime(config.mtime);
} else if (config.hasOwnProperty('mtimeMs')) {
dir.setMTime(new Date(config.mtimeMs));
}
if (config.hasOwnProperty('birthtime')) {
dir.setBirthtime(config.birthtime);
} else if (config.hasOwnProperty('birthtimeMs')) {
dir.setBirthtime(new Date(config.birthtimeMs));
}
return dir;
};
};
/**
* Module exports.
* @type {Function}
*/
module.exports = FileSystem;
exports = module.exports;
exports.getPathParts = getPathParts;
exports.getRealPath = getRealPath;
mock-fs-5.5.0/lib/index.js 0000664 0000000 0000000 00000013373 14751162414 0015307 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const Binding = require('./binding.js');
const bypass = require('./bypass.js');
const {FSError} = require('./error.js');
const FileSystem = require('./filesystem.js');
const realBinding = process.binding('fs');
const loader = require('./loader.js');
const {
getReadFileContextPrototype,
patchReadFileContext,
} = require('./readfilecontext.js');
const realProcessProps = {
cwd: process.cwd,
chdir: process.chdir,
};
const realCreateWriteStream = fs.createWriteStream;
const realStats = realBinding.Stats;
const realStatWatcher = realBinding.StatWatcher;
/**
* Pre-patch fs binding.
* This allows mock-fs to work properly under nodejs v10+ readFile
* As ReadFileContext nodejs v10+ implementation traps original binding methods:
* const { FSReqWrap, close, read } = process.binding('fs');
* Note this patch only solves issue for readFile, as the require of
* ReadFileContext is delayed by readFile implementation.
* if (!ReadFileContext) ReadFileContext = require('internal/fs/read_file_context')
* @param {string} key Property name.
*/
function patch(key) {
const existingMethod = realBinding[key];
realBinding[key] = function () {
if (this._mockedBinding) {
return this._mockedBinding[key].apply(this._mockedBinding, arguments);
} else {
return existingMethod.apply(this, arguments);
}
}.bind(realBinding);
}
for (const key in Binding.prototype) {
if (typeof realBinding[key] === 'function') {
// Stats and StatWatcher are constructors
if (key !== 'Stats' && key !== 'StatWatcher') {
patch(key);
}
}
}
const readFileContextPrototype = getReadFileContextPrototype();
patchReadFileContext(readFileContextPrototype);
function overrideBinding(binding) {
realBinding._mockedBinding = binding;
}
function overrideProcess(cwd, chdir) {
process.cwd = cwd;
process.chdir = chdir;
}
/**
* Have to disable write stream _writev on nodejs v10+.
*
* nodejs v8 lib/fs.js
* note binding.writeBuffers will use mock-fs patched writeBuffers.
*
* const binding = process.binding('fs');
* function writev(fd, chunks, position, callback) {
* // ...
* binding.writeBuffers(fd, chunks, position, req);
* }
*
* nodejs v10+ lib/internal/fs/streams.js
* note it uses original writeBuffers, bypassed mock-fs patched writeBuffers.
*
* const {writeBuffers} = internalBinding('fs');
* function writev(fd, chunks, position, callback) {
* // ...
* writeBuffers(fd, chunks, position, req);
* }
*
* Luckily _writev is an optional method on Writeable stream implementation.
* When _writev is missing, it will fall back to make multiple _write calls.
*/
function overrideCreateWriteStream() {
fs.createWriteStream = function (path, options) {
const output = realCreateWriteStream(path, options);
// disable _writev, this will over shadow WriteStream.prototype._writev
if (realBinding._mockedBinding) {
output._writev = undefined;
}
return output;
};
}
function overrideReadFileContext(binding) {
readFileContextPrototype._mockedBinding = binding;
}
function restoreBinding() {
delete realBinding._mockedBinding;
realBinding.Stats = realStats;
realBinding.StatWatcher = realStatWatcher;
}
function restoreProcess() {
for (const key in realProcessProps) {
process[key] = realProcessProps[key];
}
}
function restoreCreateWriteStream() {
fs.createWriteStream = realCreateWriteStream;
}
function restoreReadFileContext(binding) {
delete readFileContextPrototype._mockedBinding;
}
/**
* Swap out the fs bindings for a mock file system.
* @param {Object} config Mock file system configuration.
* @param {Object} [options] Any filesystem options.
* @param {boolean} options.createCwd Create a directory for `process.cwd()`
* (defaults to `true`).
* @param {boolean} options.createTmp Create a directory for `os.tmpdir()`
* (defaults to `true`).
*/
module.exports = function mock(config, options = {}) {
const system = FileSystem.create(config, options);
const binding = new Binding(system);
overrideBinding(binding);
overrideReadFileContext(binding);
let currentPath = process.cwd();
overrideProcess(
function cwd() {
if (realBinding._mockedBinding) {
return currentPath;
}
return realProcessProps.cwd();
},
function chdir(directory) {
if (realBinding._mockedBinding) {
if (!fs.statSync(path.toNamespacedPath(directory)).isDirectory()) {
throw new FSError('ENOTDIR');
}
currentPath = path.resolve(currentPath, directory);
} else {
return realProcessProps.chdir(directory);
}
},
);
overrideCreateWriteStream();
};
exports = module.exports;
/**
* Get hold of the mocked filesystem's 'root'
* If fs hasn't currently been replaced, this will return an empty object
* @return {Object} The mock root.
*/
exports.bypass = bypass;
exports.directory = FileSystem.directory;
exports.file = FileSystem.file;
exports.getMockRoot = function () {
if (realBinding._mockedBinding) {
return realBinding._mockedBinding.getSystem().getRoot();
} else {
return {};
}
};
/**
* Restore the fs bindings for the real file system.
*/
exports.load = loader.load;
exports.restore = function () {
restoreBinding();
restoreProcess();
restoreCreateWriteStream();
restoreReadFileContext();
};
/**
* Create a file factory.
*/
/**
* Create a directory factory.
*/
/**
* Create a symbolic link factory.
*/
exports.symlink = FileSystem.symlink;
/**
* Automatically maps specified paths (for use with `mock()`)
*/
/**
* Perform action, bypassing mock FS
* @example
* // This file exists on the real FS, not on the mocked FS
* const filePath = '/path/file.json';
* const data = mock.bypass(() => fs.readFileSync(filePath, 'utf-8'));
*/
mock-fs-5.5.0/lib/item.js 0000664 0000000 0000000 00000016445 14751162414 0015141 0 ustar 00root root 0000000 0000000 const fsBinding = process.binding('fs');
const statsConstructor = fsBinding.statValues
? fsBinding.statValues.constructor
: Float64Array;
// Nodejs v18.7.0 changed bigint stats type from BigUint64Array to BigInt64Array
// https://github.com/nodejs/node/pull/43714
const bigintStatsConstructor = fsBinding.bigintStatValues
? fsBinding.bigintStatValues.constructor
: BigUint64Array;
let counter = 0;
/**
* Permissions.
* @enum {number}
*/
const permissions = {
USER_READ: 256, // 0400
USER_WRITE: 128, // 0200
USER_EXEC: 64, // 0100
GROUP_READ: 32, // 0040
GROUP_WRITE: 16, // 0020
GROUP_EXEC: 8, // 0010
OTHER_READ: 4, // 0004
OTHER_WRITE: 2, // 0002
OTHER_EXEC: 1, // 0001
};
function getUid() {
// force 0 on windows.
return process.getuid ? process.getuid() : 0;
}
function getGid() {
// force 0 on windows.
return process.getgid ? process.getgid() : 0;
}
/**
* A filesystem item.
* @class
*/
function Item() {
const now = Date.now();
/**
* Access time.
* @type {Date}
*/
this._atime = new Date(now);
/**
* Change time.
* @type {Date}
*/
this._ctime = new Date(now);
/**
* Birth time.
* @type {Date}
*/
this._birthtime = new Date(now);
/**
* Modification time.
* @type {Date}
*/
this._mtime = new Date(now);
/**
* Permissions.
*/
this._mode = 438; // 0666
/**
* User id.
* @type {number}
*/
this._uid = getUid();
/**
* Group id.
* @type {number}
*/
this._gid = getGid();
/**
* Item number.
* @type {number}
*/
this._id = ++counter;
/**
* Number of links to this item.
*/
this.links = 0;
}
/**
* Add execute if read allowed
* See notes in index.js -> mapping#addDir
* @param {number} mode The file mode.
* @return {number} The modified mode.
*/
Item.fixWin32Permissions = (mode) =>
process.platform !== 'win32'
? mode
: mode |
(mode & permissions.USER_READ && permissions.USER_EXEC) |
(mode & permissions.GROUP_READ && permissions.GROUP_EXEC) |
(mode & permissions.OTHER_READ && permissions.OTHER_EXEC);
/**
* Determine if the current user has read permission.
* @return {boolean} The current user can read.
*/
Item.prototype.canRead = function () {
const uid = getUid();
const gid = getGid();
let can = false;
if (process.getuid && uid === 0) {
can = true;
} else if (uid === this._uid) {
can = (permissions.USER_READ & this._mode) === permissions.USER_READ;
} else if (gid === this._gid) {
can = (permissions.GROUP_READ & this._mode) === permissions.GROUP_READ;
} else {
can = (permissions.OTHER_READ & this._mode) === permissions.OTHER_READ;
}
return can;
};
/**
* Determine if the current user has write permission.
* @return {boolean} The current user can write.
*/
Item.prototype.canWrite = function () {
const uid = getUid();
const gid = getGid();
let can = false;
if (process.getuid && uid === 0) {
can = true;
} else if (uid === this._uid) {
can = (permissions.USER_WRITE & this._mode) === permissions.USER_WRITE;
} else if (gid === this._gid) {
can = (permissions.GROUP_WRITE & this._mode) === permissions.GROUP_WRITE;
} else {
can = (permissions.OTHER_WRITE & this._mode) === permissions.OTHER_WRITE;
}
return can;
};
/**
* Determine if the current user has execute permission.
* @return {boolean} The current user can execute.
*/
Item.prototype.canExecute = function () {
const uid = getUid();
const gid = getGid();
let can = false;
if (process.getuid && uid === 0) {
can = true;
} else if (uid === this._uid) {
can = (permissions.USER_EXEC & this._mode) === permissions.USER_EXEC;
} else if (gid === this._gid) {
can = (permissions.GROUP_EXEC & this._mode) === permissions.GROUP_EXEC;
} else {
can = (permissions.OTHER_EXEC & this._mode) === permissions.OTHER_EXEC;
}
return can;
};
/**
* Get access time.
* @return {Date} Access time.
*/
Item.prototype.getATime = function () {
return this._atime;
};
/**
* Set access time.
* @param {Date} atime Access time.
*/
Item.prototype.setATime = function (atime) {
this._atime = atime;
};
/**
* Get change time.
* @return {Date} Change time.
*/
Item.prototype.getCTime = function () {
return this._ctime;
};
/**
* Set change time.
* @param {Date} ctime Change time.
*/
Item.prototype.setCTime = function (ctime) {
this._ctime = ctime;
};
/**
* Get birth time.
* @return {Date} Birth time.
*/
Item.prototype.getBirthtime = function () {
return this._birthtime;
};
/**
* Set change time.
* @param {Date} birthtime Birth time.
*/
Item.prototype.setBirthtime = function (birthtime) {
this._birthtime = birthtime;
};
/**
* Get modification time.
* @return {Date} Modification time.
*/
Item.prototype.getMTime = function () {
return this._mtime;
};
/**
* Set modification time.
* @param {Date} mtime Modification time.
*/
Item.prototype.setMTime = function (mtime) {
this._mtime = mtime;
};
/**
* Get mode (permission only, e.g 0666).
* @return {number} Mode.
*/
Item.prototype.getMode = function () {
return this._mode;
};
/**
* Set mode (permission only, e.g 0666).
* @param {Date} mode Mode.
*/
Item.prototype.setMode = function (mode) {
this.setCTime(new Date());
this._mode = mode;
};
/**
* Get user id.
* @return {number} User id.
*/
Item.prototype.getUid = function () {
return this._uid;
};
/**
* Set user id.
* @param {number} uid User id.
*/
Item.prototype.setUid = function (uid) {
this.setCTime(new Date());
this._uid = uid;
};
/**
* Get group id.
* @return {number} Group id.
*/
Item.prototype.getGid = function () {
return this._gid;
};
/**
* Set group id.
* @param {number} gid Group id.
*/
Item.prototype.setGid = function (gid) {
this.setCTime(new Date());
this._gid = gid;
};
/**
* Get item stats.
* @param {boolean} bigint Use BigInt.
* @return {Object} Stats properties.
*/
Item.prototype.getStats = function (bigint) {
const stats = bigint
? new bigintStatsConstructor(36)
: new statsConstructor(36);
const convert = bigint ? (v) => BigInt(v) : (v) => v;
stats[0] = convert(8675309); // dev
// [1] is mode
stats[2] = convert(this.links); // nlink
stats[3] = convert(this.getUid()); // uid
stats[4] = convert(this.getGid()); // gid
stats[5] = convert(0); // rdev
stats[6] = convert(4096); // blksize
stats[7] = convert(this._id); // ino
// [8] is size
// [9] is blocks
const atimeMs = +this.getATime();
stats[10] = convert(Math.floor(atimeMs / 1000)); // atime seconds
stats[11] = convert((atimeMs % 1000) * 1000000); // atime nanoseconds
const mtimeMs = +this.getMTime();
stats[12] = convert(Math.floor(mtimeMs / 1000)); // atime seconds
stats[13] = convert((mtimeMs % 1000) * 1000000); // atime nanoseconds
const ctimeMs = +this.getCTime();
stats[14] = convert(Math.floor(ctimeMs / 1000)); // atime seconds
stats[15] = convert((ctimeMs % 1000) * 1000000); // atime nanoseconds
const birthtimeMs = +this.getBirthtime();
stats[16] = convert(Math.floor(birthtimeMs / 1000)); // atime seconds
stats[17] = convert((birthtimeMs % 1000) * 1000000); // atime nanoseconds
return stats;
};
/**
* Get the item's string representation.
* @return {string} String representation.
*/
Item.prototype.toString = function () {
return '[' + this.constructor.name + ']';
};
/**
* Export the constructor.
*/
module.exports = Item;
mock-fs-5.5.0/lib/loader.js 0000775 0000000 0000000 00000006346 14751162414 0015453 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const bypass = require('./bypass.js');
const FileSystem = require('./filesystem.js');
const {fixWin32Permissions} = require('./item.js');
const createContext = ({output, options = {}, target}, newContext) =>
Object.assign(
{
// Assign options and set defaults if needed
options: {
recursive: options.recursive !== false,
lazy: options.lazy !== false,
},
output,
target,
},
newContext,
);
function addFile(context, stats, isRoot) {
const {output, target} = context;
const {lazy} = context.options;
if (!stats.isFile()) {
throw new Error(`${target} is not a valid file!`);
}
const outputPropKey = isRoot ? target : path.basename(target);
output[outputPropKey] = () => {
const content = !lazy ? fs.readFileSync(target) : '';
const file = FileSystem.file(Object.assign({}, stats, {content}))();
if (lazy) {
Object.defineProperty(file, '_content', {
get() {
const res = bypass(() => fs.readFileSync(target));
Object.defineProperty(file, '_content', {
value: res,
writable: true,
});
return res;
},
set(data) {
Object.defineProperty(file, '_content', {
value: data,
writable: true,
});
},
configurable: true,
});
}
return file;
};
return output[outputPropKey];
}
function addDir(context, stats, isRoot) {
const {target, output} = context;
const {recursive} = context.options;
if (!stats.isDirectory()) {
throw new Error(`${target} is not a valid directory!`);
}
stats = Object.assign({}, stats);
const outputPropKey = isRoot ? target : path.basename(target);
// On windows platforms, directories do not have the executable flag, which causes FileSystem.prototype.getItem
// to think that the directory cannot be traversed. This is a workaround, however, a better solution may be to
// re-think the logic in FileSystem.prototype.getItem
// This workaround adds executable privileges if read privileges are found
stats.mode = fixWin32Permissions(stats.mode);
// Create directory factory
const directoryItems = {};
output[outputPropKey] = FileSystem.directory(
Object.assign(stats, {items: directoryItems}),
);
fs.readdirSync(target).forEach((p) => {
const absPath = path.join(target, p);
const stats = fs.statSync(absPath);
const newContext = createContext(context, {
target: absPath,
output: directoryItems,
});
if (recursive && stats.isDirectory()) {
addDir(newContext, stats);
} else if (stats.isFile()) {
addFile(newContext, stats);
}
});
return output[outputPropKey];
}
/**
* Load directory or file from real FS
* @param {string} p The path.
* @param {Object} options The options.
* @return {*} The return.
*/
exports.load = function (p, options) {
return bypass(() => {
p = path.resolve(p);
const stats = fs.statSync(p);
const context = createContext({output: {}, options, target: p});
if (stats.isDirectory()) {
return addDir(context, stats, true);
} else if (stats.isFile()) {
return addFile(context, stats, true);
}
});
};
mock-fs-5.5.0/lib/readfilecontext.js 0000664 0000000 0000000 00000010227 14751162414 0017353 0 ustar 00root root 0000000 0000000 const {AbortError} = require('./error.js');
const {FSReqCallback} = process.binding('fs');
/**
* This is a workaround for getting access to the ReadFileContext
* prototype, which we need to be able to patch its methods.
* @return {Object} The prototype.
*/
exports.getReadFileContextPrototype = function () {
const fs = require('fs');
const fsBinding = process.binding('fs');
const originalOpen = fsBinding.open;
let proto;
fsBinding.open = (_path, _flags, _mode, req) => {
proto = Object.getPrototypeOf(req.context);
return originalOpen.apply(fsBinding, [_path, _flags, _mode, req]);
};
fs.readFile('/ignored.txt', () => {});
fsBinding.open = originalOpen;
return proto;
};
/**
* This patches the ReadFileContext prototype to use mocked bindings
* when available. This entire implementation is more or less fully
* copied over from Node.js's /lib/internal/fs/read_file_context.js
*
* This patch is required to support Node.js v16+, where the ReadFileContext
* closes directly over the internal fs bindings, and is also eagerly loader.
*
* See https://github.com/tschaub/mock-fs/issues/332 for more information.
* @param {Object} prototype The ReadFileContext prototype object to patch.
*/
exports.patchReadFileContext = function (prototype) {
const origRead = prototype.read;
const origClose = prototype.close;
const kReadFileUnknownBufferLength = 64 * 1024;
const kReadFileBufferLength = 512 * 1024;
function readFileAfterRead(err, bytesRead) {
const context = this.context;
if (err) {
return context.close(err);
}
context.pos += bytesRead;
if (context.pos === context.size || bytesRead === 0) {
context.close();
} else {
if (context.size === 0) {
// Unknown size, just read until we don't get bytes.
const buffer =
bytesRead === kReadFileUnknownBufferLength
? context.buffer
: context.buffer.slice(0, bytesRead);
context.buffers.push(buffer);
}
context.read();
}
}
function readFileAfterClose(err) {
const context = this.context;
const callback = context.callback;
let buffer = null;
if (context.err || err) {
// This is a simplification from Node.js, where we don't bother merging the errors
return callback(context.err || err);
}
try {
if (context.size === 0) {
buffer = Buffer.concat(context.buffers, context.pos);
} else if (context.pos < context.size) {
buffer = context.buffer.slice(0, context.pos);
} else {
buffer = context.buffer;
}
if (context.encoding) {
buffer = buffer.toString(context.encoding);
}
} catch (err) {
return callback(err);
}
callback(null, buffer);
}
prototype.read = function read() {
if (!prototype._mockedBinding) {
return origRead.apply(this, arguments);
}
let buffer;
let offset;
let length;
if (this.signal && this.signal.aborted) {
return this.close(new AbortError());
}
if (this.size === 0) {
buffer = Buffer.allocUnsafeSlow(kReadFileUnknownBufferLength);
offset = 0;
length = kReadFileUnknownBufferLength;
this.buffer = buffer;
} else {
buffer = this.buffer;
offset = this.pos;
length = Math.min(kReadFileBufferLength, this.size - this.pos);
}
const req = new FSReqCallback();
req.oncomplete = readFileAfterRead;
req.context = this;
// This call and the one in close() is what we want to change, the
// rest is pretty much the same as Node.js except we don't have access
// to some of the internal optimizations.
prototype._mockedBinding.read(this.fd, buffer, offset, length, -1, req);
};
prototype.close = function close(err) {
if (!prototype._mockedBinding) {
return origClose.apply(this, arguments);
}
if (this.isUserFd) {
process.nextTick(function tick(context) {
readFileAfterClose.apply({context}, [null]);
}, this);
return;
}
const req = new FSReqCallback();
req.oncomplete = readFileAfterClose;
req.context = this;
this.err = err;
prototype._mockedBinding.close(this.fd, req);
};
};
mock-fs-5.5.0/lib/symlink.js 0000664 0000000 0000000 00000002244 14751162414 0015661 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const util = require('util');
const Item = require('./item.js');
/**
* A directory.
* @class
*/
function SymbolicLink() {
Item.call(this);
/**
* Relative path to source.
* @type {string}
*/
this._path = undefined;
}
util.inherits(SymbolicLink, Item);
/**
* Set the path to the source.
* @param {string} pathname Path to source.
*/
SymbolicLink.prototype.setPath = function (pathname) {
this._path = pathname;
};
/**
* Get the path to the source.
* @return {string} Path to source.
*/
SymbolicLink.prototype.getPath = function () {
return this._path;
};
/**
* Get symbolic link stats.
* @param {boolean} bigint Use BigInt.
* @return {Object} Stats properties.
*/
SymbolicLink.prototype.getStats = function (bigint) {
const size = this._path.length;
const stats = Item.prototype.getStats.call(this, bigint);
const convert = bigint ? (v) => BigInt(v) : (v) => v;
stats[1] = convert(this.getMode() | constants.S_IFLNK); // mode
stats[8] = convert(size); // size
stats[9] = convert(Math.ceil(size / 512)); // blocks
return stats;
};
/**
* Export the constructor.
*/
module.exports = SymbolicLink;
mock-fs-5.5.0/license.md 0000664 0000000 0000000 00000004655 14751162414 0015043 0 ustar 00root root 0000000 0000000 # License for mock-fs
The mock-fs module is distributed under the MIT license. Find the full source
here: http://tschaub.mit-license.org/
Copyright Tim Schaub.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Node's license
This module includes parts of the Node library itself (specifically, the fs
module is included from several different versions of Node). Find Node's
license below:
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
mock-fs-5.5.0/package-lock.json 0000664 0000000 0000000 00000747341 14751162414 0016321 0 ustar 00root root 0000000 0000000 {
"name": "mock-fs",
"version": "5.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "mock-fs",
"version": "5.5.0",
"license": "MIT",
"devDependencies": {
"chai": "^4.3.4",
"eslint": "^9.19.0",
"eslint-config-tschaub": "^15.3.0",
"mocha": "^11.0.1",
"rimraf": "^6.0.1",
"semver": "^7.3.5"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/@es-joy/jsdoccomment": {
"version": "0.49.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz",
"integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==",
"dev": true,
"dependencies": {
"comment-parser": "1.4.1",
"esquery": "^1.6.0",
"jsdoc-type-pratt-parser": "~4.1.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
"dev": true,
"dependencies": {
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
"node_modules/@eslint-community/regexpp": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
"integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
"node_modules/@eslint/config-array": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
"integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/object-schema": "^2.1.6",
"debug": "^4.3.1",
"minimatch": "^3.1.2"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/core": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz",
"integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@types/json-schema": "^7.0.15"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/eslintrc": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
"integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
"dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^10.0.1",
"globals": "^14.0.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
"minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@eslint/js": {
"version": "9.19.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz",
"integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/object-schema": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/plugin-kit": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz",
"integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.10.0",
"levn": "^0.4.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18.0"
}
},
"node_modules/@humanfs/node": {
"version": "0.16.6",
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
"integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@humanfs/core": "^0.19.1",
"@humanwhocodes/retry": "^0.3.0"
},
"engines": {
"node": ">=18.18.0"
}
},
"node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
"integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@humanwhocodes/module-importer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true,
"engines": {
"node": ">=12.22"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@humanwhocodes/retry": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
"integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/nzakas"
}
},
"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,
"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/@isaacs/cliui/node_modules/ansi-regex": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"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/@isaacs/cliui/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"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/@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,
"optional": true,
"engines": {
"node": ">=14"
}
},
"node_modules/@pkgr/core": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
"integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
"dev": true
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
"node_modules/acorn": {
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
"integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"dev": true,
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/are-docs-informative": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
"integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
"dev": true,
"engines": {
"node": ">=14"
}
},
"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
},
"node_modules/array-buffer-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
"integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.5",
"is-array-buffer": "^3.0.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array-includes": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
"integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2",
"es-object-atoms": "^1.0.0",
"get-intrinsic": "^1.2.4",
"is-string": "^1.0.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array.prototype.findlastindex": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
"integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array.prototype.flat": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
"integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array.prototype.flatmap": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
"integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-shim-unscopables": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/arraybuffer.prototype.slice": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
"integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
"dev": true,
"dependencies": {
"array-buffer-byte-length": "^1.0.1",
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"is-array-buffer": "^3.0.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"dev": true,
"dependencies": {
"possible-typed-array-names": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
"integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
"dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/camelcase": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/chai": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
"integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
"dev": true,
"dependencies": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.3",
"deep-eql": "^4.1.3",
"get-func-name": "^2.0.2",
"loupe": "^2.3.6",
"pathval": "^1.1.1",
"type-detect": "^4.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/check-error": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
"integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
"dev": true,
"dependencies": {
"get-func-name": "^2.0.2"
},
"engines": {
"node": "*"
}
},
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
],
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"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/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,
"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
},
"node_modules/comment-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
"dev": true,
"engines": {
"node": ">= 12.0.0"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"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/data-view-buffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
"integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.6",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/data-view-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
"integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/data-view-byte-offset": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
"integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.6",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/decamelize": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
"integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/deep-eql": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
"integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
"dev": true,
"dependencies": {
"type-detect": "^4.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dev": true,
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/diff": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
"integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
"dev": true,
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/dunder-proto": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz",
"integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==",
"dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
"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
},
"node_modules/es-abstract": {
"version": "1.23.5",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz",
"integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==",
"dev": true,
"dependencies": {
"array-buffer-byte-length": "^1.0.1",
"arraybuffer.prototype.slice": "^1.0.3",
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"data-view-buffer": "^1.0.1",
"data-view-byte-length": "^1.0.1",
"data-view-byte-offset": "^1.0.0",
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"es-set-tostringtag": "^2.0.3",
"es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.6",
"get-intrinsic": "^1.2.4",
"get-symbol-description": "^1.0.2",
"globalthis": "^1.0.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
"hasown": "^2.0.2",
"internal-slot": "^1.0.7",
"is-array-buffer": "^3.0.4",
"is-callable": "^1.2.7",
"is-data-view": "^1.0.1",
"is-negative-zero": "^2.0.3",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.3",
"is-string": "^1.0.7",
"is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
"object-inspect": "^1.13.3",
"object-keys": "^1.1.1",
"object.assign": "^4.1.5",
"regexp.prototype.flags": "^1.5.3",
"safe-array-concat": "^1.1.2",
"safe-regex-test": "^1.0.3",
"string.prototype.trim": "^1.2.9",
"string.prototype.trimend": "^1.0.8",
"string.prototype.trimstart": "^1.0.8",
"typed-array-buffer": "^1.0.2",
"typed-array-byte-length": "^1.0.1",
"typed-array-byte-offset": "^1.0.2",
"typed-array-length": "^1.0.6",
"unbox-primitive": "^1.0.2",
"which-typed-array": "^1.1.15"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-module-lexer": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
"integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
"dev": true
},
"node_modules/es-object-atoms": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
"integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
"integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.2.4",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.1"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-shim-unscopables": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
"integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
"dev": true,
"dependencies": {
"hasown": "^2.0.0"
}
},
"node_modules/es-to-primitive": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
"integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
"dev": true,
"dependencies": {
"is-callable": "^1.2.7",
"is-date-object": "^1.0.5",
"is-symbol": "^1.0.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint": {
"version": "9.19.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz",
"integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.0",
"@eslint/core": "^0.10.0",
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "9.19.0",
"@eslint/plugin-kit": "^0.2.5",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.1",
"@types/estree": "^1.0.6",
"@types/json-schema": "^7.0.15",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.2.0",
"eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0",
"esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^8.0.0",
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
"ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"lodash.merge": "^4.6.2",
"minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
"optionator": "^0.9.3"
},
"bin": {
"eslint": "bin/eslint.js"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://eslint.org/donate"
},
"peerDependencies": {
"jiti": "*"
},
"peerDependenciesMeta": {
"jiti": {
"optional": true
}
}
},
"node_modules/eslint-config-prettier": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
"integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
"dev": true,
"license": "MIT",
"bin": {
"eslint-config-prettier": "build/bin/cli.js"
},
"peerDependencies": {
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-config-tschaub": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/eslint-config-tschaub/-/eslint-config-tschaub-15.3.0.tgz",
"integrity": "sha512-SGdxfMszyhXJR12IqC7z1PE56lCm0V1EiftlmzTFKwnXeZSD+J0vWcEE6MjXE6WeScwwMb/0AqQ3zLKCtaXAqw==",
"dev": true,
"license": "MIT",
"dependencies": {
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsdoc": "^50.5.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
"prettier": "^3.3.3"
}
},
"node_modules/eslint-import-resolver-node": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
"integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
"dev": true,
"dependencies": {
"debug": "^3.2.7",
"is-core-module": "^2.13.0",
"resolve": "^1.22.4"
}
},
"node_modules/eslint-import-resolver-node/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/eslint-module-utils": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
"integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"dev": true,
"dependencies": {
"debug": "^3.2.7"
},
"engines": {
"node": ">=4"
},
"peerDependenciesMeta": {
"eslint": {
"optional": true
}
}
},
"node_modules/eslint-module-utils/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/eslint-plugin-import": {
"version": "2.31.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
"array.prototype.findlastindex": "^1.2.5",
"array.prototype.flat": "^1.3.2",
"array.prototype.flatmap": "^1.3.2",
"debug": "^3.2.7",
"doctrine": "^2.1.0",
"eslint-import-resolver-node": "^0.3.9",
"eslint-module-utils": "^2.12.0",
"hasown": "^2.0.2",
"is-core-module": "^2.15.1",
"is-glob": "^4.0.3",
"minimatch": "^3.1.2",
"object.fromentries": "^2.0.8",
"object.groupby": "^1.0.3",
"object.values": "^1.2.0",
"semver": "^6.3.1",
"string.prototype.trimend": "^1.0.8",
"tsconfig-paths": "^3.15.0"
},
"engines": {
"node": ">=4"
},
"peerDependencies": {
"eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
}
},
"node_modules/eslint-plugin-import/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/eslint-plugin-import/node_modules/doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
"dev": true,
"dependencies": {
"esutils": "^2.0.2"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/eslint-plugin-import/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/eslint-plugin-jsdoc": {
"version": "50.6.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.1.tgz",
"integrity": "sha512-UWyaYi6iURdSfdVVqvfOs2vdCVz0J40O/z/HTsv2sFjdjmdlUI/qlKLOTmwbPQ2tAfQnE5F9vqx+B+poF71DBQ==",
"dev": true,
"dependencies": {
"@es-joy/jsdoccomment": "~0.49.0",
"are-docs-informative": "^0.0.2",
"comment-parser": "1.4.1",
"debug": "^4.3.6",
"escape-string-regexp": "^4.0.0",
"espree": "^10.1.0",
"esquery": "^1.6.0",
"parse-imports": "^2.1.1",
"semver": "^7.6.3",
"spdx-expression-parse": "^4.0.0",
"synckit": "^0.9.1"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-prettier": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
"integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
"dev": true,
"dependencies": {
"prettier-linter-helpers": "^1.0.0",
"synckit": "^0.9.1"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint-plugin-prettier"
},
"peerDependencies": {
"@types/eslint": ">=8.0.0",
"eslint": ">=8.0.0",
"eslint-config-prettier": "*",
"prettier": ">=3.0.0"
},
"peerDependenciesMeta": {
"@types/eslint": {
"optional": true
},
"eslint-config-prettier": {
"optional": true
}
}
},
"node_modules/eslint-plugin-sort-imports-es6-autofix": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-sort-imports-es6-autofix/-/eslint-plugin-sort-imports-es6-autofix-0.6.0.tgz",
"integrity": "sha512-2NVaBGF9NN+727Fyq+jJYihdIeegjXeUUrZED9Q8FVB8MsV3YQEyXG96GVnXqWt0pmn7xfCZOZf3uKnIhBrfeQ==",
"dev": true,
"peerDependencies": {
"eslint": ">=7.7.0"
}
},
"node_modules/eslint-scope": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
"integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.3"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/espree": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
"integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.14.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^4.2.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/espree/node_modules/eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/esquery": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"dependencies": {
"estraverse": "^5.1.0"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/esrecurse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
},
"engines": {
"node": ">=4.0"
}
},
"node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"engines": {
"node": ">=4.0"
}
},
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-diff": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
"node_modules/file-entry-cache": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"flat-cache": "^4.0.0"
},
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"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,
"dependencies": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/flat": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
"dev": true,
"bin": {
"flat": "cli.js"
}
},
"node_modules/flat-cache": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
"dev": true,
"license": "MIT",
"dependencies": {
"flatted": "^3.2.9",
"keyv": "^4.5.4"
},
"engines": {
"node": ">=16"
}
},
"node_modules/flatted": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
"dev": true,
"license": "ISC"
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dev": true,
"dependencies": {
"is-callable": "^1.1.3"
}
},
"node_modules/foreground-child": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/function.prototype.name": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.7.tgz",
"integrity": "sha512-2g4x+HqTJKM9zcJqBSpjoRmdcPFtJM60J3xJisTQSXBWka5XqyBN/2tNUgma1mztTXyDuUsEtYe5qcs7xYzYQA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"functions-have-names": "^1.2.3",
"hasown": "^2.0.2",
"is-callable": "^1.2.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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-func-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
"integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
"integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
"dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"dunder-proto": "^1.0.0",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-symbol-description": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
"integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.5",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/glob": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz",
"integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==",
"dev": true,
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^4.0.1",
"minimatch": "^10.0.0",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/glob/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globalthis": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
"integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
"dev": true,
"dependencies": {
"define-properties": "^1.2.1",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-bigints": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
"integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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,
"engines": {
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
"integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
"dev": true,
"dependencies": {
"dunder-proto": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true,
"bin": {
"he": "bin/he"
}
},
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true,
"engines": {
"node": ">=0.8.19"
}
},
"node_modules/internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
"integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"hasown": "^2.0.2",
"side-channel": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/is-array-buffer": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
"integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-async-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
"integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
"dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-bigint": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
"integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
"dev": true,
"dependencies": {
"has-bigints": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-boolean-object": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
"integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-core-module": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz",
"integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==",
"dev": true,
"dependencies": {
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-data-view": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
"integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"get-intrinsic": "^1.2.6",
"is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-date-object": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-finalizationregistry": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz",
"integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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,
"engines": {
"node": ">=8"
}
},
"node_modules/is-generator-function": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
"integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
"dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-map": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-negative-zero": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
"integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/is-number-object": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.0.tgz",
"integrity": "sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"gopd": "^1.2.0",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-set": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-shared-array-buffer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
"integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-string": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz",
"integrity": "sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-symbol": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
"integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"has-symbols": "^1.1.0",
"safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-typed-array": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
"integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
"dev": true,
"dependencies": {
"which-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-weakmap": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-weakref": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
"integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-weakset": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
"integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"node_modules/jackspeak": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
"integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
"dev": true,
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/jsdoc-type-pratt-parser": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
"integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
"dev": true,
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true,
"license": "MIT"
},
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"node_modules/json5": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
},
"bin": {
"json5": "lib/cli.js"
}
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
"license": "MIT",
"dependencies": {
"json-buffer": "3.0.1"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"dependencies": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"dependencies": {
"p-locate": "^5.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"node_modules/log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dev": true,
"dependencies": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/loupe": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
"integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
"dev": true,
"dependencies": {
"get-func-name": "^2.0.1"
}
},
"node_modules/lru-cache": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz",
"integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==",
"dev": true,
"engines": {
"node": "20 || >=22"
}
},
"node_modules/math-intrinsics": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz",
"integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/mocha": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
"integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-colors": "^4.1.3",
"browser-stdout": "^1.3.1",
"chokidar": "^3.5.3",
"debug": "^4.3.5",
"diff": "^5.2.0",
"escape-string-regexp": "^4.0.0",
"find-up": "^5.0.0",
"glob": "^10.4.5",
"he": "^1.2.0",
"js-yaml": "^4.1.0",
"log-symbols": "^4.1.0",
"minimatch": "^5.1.6",
"ms": "^2.1.3",
"serialize-javascript": "^6.0.2",
"strip-json-comments": "^3.1.1",
"supports-color": "^8.1.1",
"workerpool": "^6.5.1",
"yargs": "^17.7.2",
"yargs-parser": "^21.1.1",
"yargs-unparser": "^2.0.0"
},
"bin": {
"_mocha": "bin/_mocha",
"mocha": "bin/mocha.js"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/mocha/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/mocha/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"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/mocha/node_modules/glob/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/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,
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
"optionalDependencies": {
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/mocha/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true
},
"node_modules/mocha/node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/mocha/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,
"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/mocha/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"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
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-inspect": {
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.assign": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
"integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.5",
"define-properties": "^1.2.1",
"has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object.fromentries": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
"integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object.groupby": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
"integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.values": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
"integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"dependencies": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
"word-wrap": "^1.2.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
"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,
"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,
"dependencies": {
"p-limit": "^3.0.2"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/package-json-from-dist": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
"integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
"dev": true
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/parse-imports": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz",
"integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==",
"dev": true,
"dependencies": {
"es-module-lexer": "^1.5.3",
"slashes": "^3.0.12"
},
"engines": {
"node": ">= 18"
}
},
"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,
"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,
"engines": {
"node": ">=8"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"node_modules/path-scurry": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
"dev": true,
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/pathval": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/possible-typed-array-names": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/prettier": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"dependencies": {
"fast-diff": "^1.1.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"dependencies": {
"safe-buffer": "^5.1.0"
}
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz",
"integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"dunder-proto": "^1.0.0",
"es-abstract": "^1.23.5",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"gopd": "^1.2.0",
"which-builtin-type": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
"integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-errors": "^1.3.0",
"set-function-name": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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": {
"version": "1.22.9",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz",
"integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==",
"dev": true,
"dependencies": {
"is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/rimraf": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
"integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
"dev": true,
"dependencies": {
"glob": "^11.0.0",
"package-json-from-dist": "^1.0.0"
},
"bin": {
"rimraf": "dist/esm/bin.mjs"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/safe-array-concat": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
"integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
"get-intrinsic": "^1.2.6",
"has-symbols": "^1.1.0",
"isarray": "^2.0.5"
},
"engines": {
"node": ">=0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/safe-regex-test": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
"integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"is-regex": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/semver": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz",
"integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/serialize-javascript": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
"dependencies": {
"randombytes": "^2.1.0"
}
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/set-function-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"dev": true,
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"functions-have-names": "^1.2.3",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"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,
"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,
"engines": {
"node": ">=8"
}
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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,
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/slashes": {
"version": "3.0.12",
"resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz",
"integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==",
"dev": true
},
"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
},
"node_modules/spdx-expression-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
"dev": true,
"dependencies": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-license-ids": {
"version": "3.0.20",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz",
"integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==",
"dev": true
},
"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/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,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/string.prototype.trim": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
"integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
"define-data-property": "^1.1.4",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-object-atoms": "^1.0.0",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimend": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
"integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
"integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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,
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/synckit": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz",
"integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==",
"dev": true,
"dependencies": {
"@pkgr/core": "^0.1.0",
"tslib": "^2.6.2"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/unts"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/tsconfig-paths": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
"integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
"dev": true,
"dependencies": {
"@types/json5": "^0.0.29",
"json5": "^1.0.2",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"dependencies": {
"prelude-ls": "^1.2.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/type-detect": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
"integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/typed-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
"integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
"integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-proto": "^1.0.3",
"is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typed-array-byte-offset": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz",
"integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==",
"dev": true,
"dependencies": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-proto": "^1.0.3",
"is-typed-array": "^1.1.13",
"reflect.getprototypeof": "^1.0.6"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typed-array-length": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
"integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"is-typed-array": "^1.1.13",
"possible-typed-array-names": "^1.0.0",
"reflect.getprototypeof": "^1.0.6"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"has-bigints": "^1.0.2",
"has-symbols": "^1.0.3",
"which-boxed-primitive": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/which-boxed-primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.0.tgz",
"integrity": "sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==",
"dev": true,
"dependencies": {
"is-bigint": "^1.1.0",
"is-boolean-object": "^1.2.0",
"is-number-object": "^1.1.0",
"is-string": "^1.1.0",
"is-symbol": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-builtin-type": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
"integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"function.prototype.name": "^1.1.6",
"has-tostringtag": "^1.0.2",
"is-async-function": "^2.0.0",
"is-date-object": "^1.1.0",
"is-finalizationregistry": "^1.1.0",
"is-generator-function": "^1.0.10",
"is-regex": "^1.2.1",
"is-weakref": "^1.0.2",
"isarray": "^2.0.5",
"which-boxed-primitive": "^1.1.0",
"which-collection": "^1.0.2",
"which-typed-array": "^1.1.16"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-collection": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
"dependencies": {
"is-map": "^2.0.3",
"is-set": "^2.0.3",
"is-weakmap": "^2.0.2",
"is-weakset": "^2.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-typed-array": {
"version": "1.1.16",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz",
"integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==",
"dev": true,
"dependencies": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/word-wrap": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/workerpool": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
"integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
"dev": true
},
"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/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,
"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/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/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-unparser": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
"integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
"dev": true,
"dependencies": {
"camelcase": "^6.0.0",
"decamelize": "^4.0.0",
"flat": "^5.0.2",
"is-plain-obj": "^2.1.0"
},
"engines": {
"node": ">=10"
}
},
"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,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
}
},
"dependencies": {
"@es-joy/jsdoccomment": {
"version": "0.49.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz",
"integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==",
"dev": true,
"requires": {
"comment-parser": "1.4.1",
"esquery": "^1.6.0",
"jsdoc-type-pratt-parser": "~4.1.0"
}
},
"@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^3.3.0"
}
},
"@eslint-community/regexpp": {
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
"integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"dev": true
},
"@eslint/config-array": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
"integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
"dev": true,
"requires": {
"@eslint/object-schema": "^2.1.6",
"debug": "^4.3.1",
"minimatch": "^3.1.2"
}
},
"@eslint/core": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz",
"integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.15"
}
},
"@eslint/eslintrc": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
"integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^10.0.1",
"globals": "^14.0.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
"minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
}
},
"@eslint/js": {
"version": "9.19.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz",
"integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==",
"dev": true
},
"@eslint/object-schema": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
"dev": true
},
"@eslint/plugin-kit": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz",
"integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==",
"dev": true,
"requires": {
"@eslint/core": "^0.10.0",
"levn": "^0.4.1"
}
},
"@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
"dev": true
},
"@humanfs/node": {
"version": "0.16.6",
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
"integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
"dev": true,
"requires": {
"@humanfs/core": "^0.19.1",
"@humanwhocodes/retry": "^0.3.0"
},
"dependencies": {
"@humanwhocodes/retry": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
"integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
"dev": true
}
}
},
"@humanwhocodes/module-importer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true
},
"@humanwhocodes/retry": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
"integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
"dev": true
},
"@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,
"requires": {
"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"
},
"dependencies": {
"ansi-regex": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"dev": true
},
"ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true
},
"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
},
"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,
"requires": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
}
},
"strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"requires": {
"ansi-regex": "^6.0.1"
}
},
"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,
"requires": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
}
}
}
},
"@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,
"optional": true
},
"@pkgr/core": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
"dev": true
},
"@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
"integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
"dev": true
},
"@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true
},
"@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
"acorn": {
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"dev": true
},
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
"requires": {}
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
"integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
"dev": true
},
"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
},
"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,
"requires": {
"color-convert": "^2.0.1"
}
},
"anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
}
},
"are-docs-informative": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
"integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
"dev": true
},
"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
},
"array-buffer-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
"integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
"dev": true,
"requires": {
"call-bind": "^1.0.5",
"is-array-buffer": "^3.0.4"
}
},
"array-includes": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
"integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2",
"es-object-atoms": "^1.0.0",
"get-intrinsic": "^1.2.4",
"is-string": "^1.0.7"
}
},
"array.prototype.findlastindex": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
"integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"es-shim-unscopables": "^1.0.2"
}
},
"array.prototype.flat": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
"integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
"dev": true,
"requires": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-shim-unscopables": "^1.0.2"
}
},
"array.prototype.flatmap": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
"integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
"dev": true,
"requires": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-shim-unscopables": "^1.0.2"
}
},
"arraybuffer.prototype.slice": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
"integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
"dev": true,
"requires": {
"array-buffer-byte-length": "^1.0.1",
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"is-array-buffer": "^3.0.4"
}
},
"assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true
},
"available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"dev": true,
"requires": {
"possible-typed-array-names": "^1.0.0"
}
},
"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
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"requires": {
"fill-range": "^7.1.1"
}
},
"browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"dev": true,
"requires": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.2"
}
},
"call-bind-apply-helpers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
"integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"dev": true,
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
}
},
"call-bound": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
"dev": true,
"requires": {
"call-bind-apply-helpers": "^1.0.1",
"get-intrinsic": "^1.2.6"
}
},
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"camelcase": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
"dev": true
},
"chai": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
"integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
"dev": true,
"requires": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.3",
"deep-eql": "^4.1.3",
"get-func-name": "^2.0.2",
"loupe": "^2.3.6",
"pathval": "^1.1.1",
"type-detect": "^4.1.0"
}
},
"chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"check-error": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
"integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
"dev": true,
"requires": {
"get-func-name": "^2.0.2"
}
},
"chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"dev": true,
"requires": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
}
},
"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,
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
}
},
"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,
"requires": {
"color-name": "~1.1.4"
}
},
"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
},
"comment-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"data-view-buffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
"integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
"dev": true,
"requires": {
"call-bind": "^1.0.6",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
}
},
"data-view-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
"integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
}
},
"data-view-byte-offset": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
"integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
"dev": true,
"requires": {
"call-bind": "^1.0.6",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
}
},
"debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"requires": {
"ms": "^2.1.3"
}
},
"decamelize": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
"integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
"dev": true
},
"deep-eql": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
"integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
"dev": true,
"requires": {
"type-detect": "^4.0.0"
}
},
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
"define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
}
},
"define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dev": true,
"requires": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
}
},
"diff": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
"integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
"dev": true
},
"dunder-proto": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz",
"integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==",
"dev": true,
"requires": {
"call-bind-apply-helpers": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
}
},
"eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
"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
},
"es-abstract": {
"version": "1.23.5",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz",
"integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==",
"dev": true,
"requires": {
"array-buffer-byte-length": "^1.0.1",
"arraybuffer.prototype.slice": "^1.0.3",
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"data-view-buffer": "^1.0.1",
"data-view-byte-length": "^1.0.1",
"data-view-byte-offset": "^1.0.0",
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"es-set-tostringtag": "^2.0.3",
"es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.6",
"get-intrinsic": "^1.2.4",
"get-symbol-description": "^1.0.2",
"globalthis": "^1.0.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
"hasown": "^2.0.2",
"internal-slot": "^1.0.7",
"is-array-buffer": "^3.0.4",
"is-callable": "^1.2.7",
"is-data-view": "^1.0.1",
"is-negative-zero": "^2.0.3",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.3",
"is-string": "^1.0.7",
"is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
"object-inspect": "^1.13.3",
"object-keys": "^1.1.1",
"object.assign": "^4.1.5",
"regexp.prototype.flags": "^1.5.3",
"safe-array-concat": "^1.1.2",
"safe-regex-test": "^1.0.3",
"string.prototype.trim": "^1.2.9",
"string.prototype.trimend": "^1.0.8",
"string.prototype.trimstart": "^1.0.8",
"typed-array-buffer": "^1.0.2",
"typed-array-byte-length": "^1.0.1",
"typed-array-byte-offset": "^1.0.2",
"typed-array-length": "^1.0.6",
"unbox-primitive": "^1.0.2",
"which-typed-array": "^1.1.15"
}
},
"es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true
},
"es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true
},
"es-module-lexer": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
"integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
"dev": true
},
"es-object-atoms": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
"integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
"dev": true,
"requires": {
"es-errors": "^1.3.0"
}
},
"es-set-tostringtag": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
"integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
"dev": true,
"requires": {
"get-intrinsic": "^1.2.4",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.1"
}
},
"es-shim-unscopables": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
"integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
"dev": true,
"requires": {
"hasown": "^2.0.0"
}
},
"es-to-primitive": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
"integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
"dev": true,
"requires": {
"is-callable": "^1.2.7",
"is-date-object": "^1.0.5",
"is-symbol": "^1.0.4"
}
},
"escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true
},
"escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
"eslint": {
"version": "9.19.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz",
"integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.0",
"@eslint/core": "^0.10.0",
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "9.19.0",
"@eslint/plugin-kit": "^0.2.5",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.1",
"@types/estree": "^1.0.6",
"@types/json-schema": "^7.0.15",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.2.0",
"eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0",
"esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^8.0.0",
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
"ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"lodash.merge": "^4.6.2",
"minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
"optionator": "^0.9.3"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"dev": true
},
"glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"requires": {
"is-glob": "^4.0.3"
}
}
}
},
"eslint-config-prettier": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
"integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
"dev": true,
"requires": {}
},
"eslint-config-tschaub": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/eslint-config-tschaub/-/eslint-config-tschaub-15.3.0.tgz",
"integrity": "sha512-SGdxfMszyhXJR12IqC7z1PE56lCm0V1EiftlmzTFKwnXeZSD+J0vWcEE6MjXE6WeScwwMb/0AqQ3zLKCtaXAqw==",
"dev": true,
"requires": {
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsdoc": "^50.5.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
"prettier": "^3.3.3"
}
},
"eslint-import-resolver-node": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
"integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
"dev": true,
"requires": {
"debug": "^3.2.7",
"is-core-module": "^2.13.0",
"resolve": "^1.22.4"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
}
}
},
"eslint-module-utils": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
"integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"dev": true,
"requires": {
"debug": "^3.2.7"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
}
}
},
"eslint-plugin-import": {
"version": "2.31.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
"requires": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
"array.prototype.findlastindex": "^1.2.5",
"array.prototype.flat": "^1.3.2",
"array.prototype.flatmap": "^1.3.2",
"debug": "^3.2.7",
"doctrine": "^2.1.0",
"eslint-import-resolver-node": "^0.3.9",
"eslint-module-utils": "^2.12.0",
"hasown": "^2.0.2",
"is-core-module": "^2.15.1",
"is-glob": "^4.0.3",
"minimatch": "^3.1.2",
"object.fromentries": "^2.0.8",
"object.groupby": "^1.0.3",
"object.values": "^1.2.0",
"semver": "^6.3.1",
"string.prototype.trimend": "^1.0.8",
"tsconfig-paths": "^3.15.0"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
"dev": true,
"requires": {
"esutils": "^2.0.2"
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
},
"eslint-plugin-jsdoc": {
"version": "50.6.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.1.tgz",
"integrity": "sha512-UWyaYi6iURdSfdVVqvfOs2vdCVz0J40O/z/HTsv2sFjdjmdlUI/qlKLOTmwbPQ2tAfQnE5F9vqx+B+poF71DBQ==",
"dev": true,
"requires": {
"@es-joy/jsdoccomment": "~0.49.0",
"are-docs-informative": "^0.0.2",
"comment-parser": "1.4.1",
"debug": "^4.3.6",
"escape-string-regexp": "^4.0.0",
"espree": "^10.1.0",
"esquery": "^1.6.0",
"parse-imports": "^2.1.1",
"semver": "^7.6.3",
"spdx-expression-parse": "^4.0.0",
"synckit": "^0.9.1"
}
},
"eslint-plugin-prettier": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
"integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0",
"synckit": "^0.9.1"
}
},
"eslint-plugin-sort-imports-es6-autofix": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-sort-imports-es6-autofix/-/eslint-plugin-sort-imports-es6-autofix-0.6.0.tgz",
"integrity": "sha512-2NVaBGF9NN+727Fyq+jJYihdIeegjXeUUrZED9Q8FVB8MsV3YQEyXG96GVnXqWt0pmn7xfCZOZf3uKnIhBrfeQ==",
"dev": true,
"requires": {}
},
"eslint-scope": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
"integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",
"estraverse": "^5.2.0"
}
},
"eslint-visitor-keys": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true
},
"espree": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
"integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
"dev": true,
"requires": {
"acorn": "^8.14.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^4.2.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"dev": true
}
}
},
"esquery": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
}
},
"esrecurse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
"requires": {
"estraverse": "^5.2.0"
}
},
"estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-diff": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
"dev": true
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
"file-entry-cache": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
"dev": true,
"requires": {
"flat-cache": "^4.0.0"
}
},
"fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"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,
"requires": {
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
}
},
"flat": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
"dev": true
},
"flat-cache": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
"dev": true,
"requires": {
"flatted": "^3.2.9",
"keyv": "^4.5.4"
}
},
"flatted": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
"dev": true
},
"for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dev": true,
"requires": {
"is-callable": "^1.1.3"
}
},
"foreground-child": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
}
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true
},
"function.prototype.name": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.7.tgz",
"integrity": "sha512-2g4x+HqTJKM9zcJqBSpjoRmdcPFtJM60J3xJisTQSXBWka5XqyBN/2tNUgma1mztTXyDuUsEtYe5qcs7xYzYQA==",
"dev": true,
"requires": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"functions-have-names": "^1.2.3",
"hasown": "^2.0.2",
"is-callable": "^1.2.7"
}
},
"functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"dev": true
},
"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
},
"get-func-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
"integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
"dev": true
},
"get-intrinsic": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
"integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
"dev": true,
"requires": {
"call-bind-apply-helpers": "^1.0.1",
"dunder-proto": "^1.0.0",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.0.0"
}
},
"get-symbol-description": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
"integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
"dev": true,
"requires": {
"call-bind": "^1.0.5",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4"
}
},
"glob": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz",
"integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==",
"dev": true,
"requires": {
"foreground-child": "^3.1.0",
"jackspeak": "^4.0.1",
"minimatch": "^10.0.0",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"minimatch": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
}
}
},
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"dev": true
},
"globalthis": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
"integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
"dev": true,
"requires": {
"define-properties": "^1.2.1",
"gopd": "^1.0.1"
}
},
"gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true
},
"has-bigints": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
"integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
"dev": true
},
"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
},
"has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
"requires": {
"es-define-property": "^1.0.0"
}
},
"has-proto": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
"integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
"dev": true,
"requires": {
"dunder-proto": "^1.0.0"
}
},
"has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true
},
"has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"requires": {
"has-symbols": "^1.0.3"
}
},
"hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"requires": {
"function-bind": "^1.1.2"
}
},
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true
},
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
}
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
"integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
"dev": true,
"requires": {
"es-errors": "^1.3.0",
"hasown": "^2.0.2",
"side-channel": "^1.1.0"
}
},
"is-array-buffer": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
"integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.1"
}
},
"is-async-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
"integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
"dev": true,
"requires": {
"has-tostringtag": "^1.0.0"
}
},
"is-bigint": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
"integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
"dev": true,
"requires": {
"has-bigints": "^1.0.2"
}
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
},
"is-boolean-object": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
"integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
}
},
"is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"dev": true
},
"is-core-module": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz",
"integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==",
"dev": true,
"requires": {
"hasown": "^2.0.2"
}
},
"is-data-view": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
"integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"get-intrinsic": "^1.2.6",
"is-typed-array": "^1.1.13"
}
},
"is-date-object": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"has-tostringtag": "^1.0.2"
}
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-finalizationregistry": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz",
"integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==",
"dev": true,
"requires": {
"call-bind": "^1.0.7"
}
},
"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
},
"is-generator-function": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
"integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
"dev": true,
"requires": {
"has-tostringtag": "^1.0.0"
}
},
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-map": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
"integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
"dev": true
},
"is-negative-zero": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
"integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
"dev": true
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"is-number-object": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.0.tgz",
"integrity": "sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"has-tostringtag": "^1.0.2"
}
},
"is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
"dev": true
},
"is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"gopd": "^1.2.0",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
}
},
"is-set": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
"integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
"dev": true
},
"is-shared-array-buffer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
"integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
"dev": true,
"requires": {
"call-bind": "^1.0.7"
}
},
"is-string": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz",
"integrity": "sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"has-tostringtag": "^1.0.2"
}
},
"is-symbol": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
"integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"has-symbols": "^1.1.0",
"safe-regex-test": "^1.1.0"
}
},
"is-typed-array": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
"integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
"dev": true,
"requires": {
"which-typed-array": "^1.1.14"
}
},
"is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
"dev": true
},
"is-weakmap": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
"integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
"dev": true
},
"is-weakref": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
"integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
"dev": true,
"requires": {
"call-bound": "^1.0.2"
}
},
"is-weakset": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
"integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"get-intrinsic": "^1.2.4"
}
},
"isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"jackspeak": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
"integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
"dev": true,
"requires": {
"@isaacs/cliui": "^8.0.2"
}
},
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"requires": {
"argparse": "^2.0.1"
}
},
"jsdoc-type-pratt-parser": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
"integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
"dev": true
},
"json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"json5": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
}
},
"keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
"requires": {
"json-buffer": "3.0.1"
}
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
}
},
"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,
"requires": {
"p-locate": "^5.0.0"
}
},
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dev": true,
"requires": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
}
},
"loupe": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
"integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
"dev": true,
"requires": {
"get-func-name": "^2.0.1"
}
},
"lru-cache": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz",
"integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==",
"dev": true
},
"math-intrinsics": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz",
"integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==",
"dev": true
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true
},
"minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true
},
"mocha": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
"integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
"dev": true,
"requires": {
"ansi-colors": "^4.1.3",
"browser-stdout": "^1.3.1",
"chokidar": "^3.5.3",
"debug": "^4.3.5",
"diff": "^5.2.0",
"escape-string-regexp": "^4.0.0",
"find-up": "^5.0.0",
"glob": "^10.4.5",
"he": "^1.2.0",
"js-yaml": "^4.1.0",
"log-symbols": "^4.1.0",
"minimatch": "^5.1.6",
"ms": "^2.1.3",
"serialize-javascript": "^6.0.2",
"strip-json-comments": "^3.1.1",
"supports-color": "^8.1.1",
"workerpool": "^6.5.1",
"yargs": "^17.7.2",
"yargs-parser": "^21.1.1",
"yargs-unparser": "^2.0.0"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"requires": {
"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"
},
"dependencies": {
"minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
}
}
},
"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,
"requires": {
"@isaacs/cliui": "^8.0.2",
"@pkgjs/parseargs": "^0.11.0"
}
},
"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
},
"minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
},
"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,
"requires": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
}
},
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"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
},
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"object-inspect": {
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"dev": true
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
},
"object.assign": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
"integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.5",
"define-properties": "^1.2.1",
"has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
}
},
"object.fromentries": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
"integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2",
"es-object-atoms": "^1.0.0"
}
},
"object.groupby": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
"integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.2"
}
},
"object.values": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
"integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
}
},
"optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"requires": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
"word-wrap": "^1.2.5"
}
},
"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,
"requires": {
"yocto-queue": "^0.1.0"
}
},
"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,
"requires": {
"p-limit": "^3.0.2"
}
},
"package-json-from-dist": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
"integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
"dev": true
},
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"requires": {
"callsites": "^3.0.0"
}
},
"parse-imports": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz",
"integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==",
"dev": true,
"requires": {
"es-module-lexer": "^1.5.3",
"slashes": "^3.0.12"
}
},
"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
},
"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
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-scurry": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
"dev": true,
"requires": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
}
},
"pathval": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
"dev": true
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
"possible-typed-array-names": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
"dev": true
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"prettier": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true
},
"prettier-linter-helpers": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"requires": {
"fast-diff": "^1.1.2"
}
},
"punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true
},
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"requires": {
"safe-buffer": "^5.1.0"
}
},
"readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
}
},
"reflect.getprototypeof": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz",
"integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"dunder-proto": "^1.0.0",
"es-abstract": "^1.23.5",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"gopd": "^1.2.0",
"which-builtin-type": "^1.2.0"
}
},
"regexp.prototype.flags": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
"integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-errors": "^1.3.0",
"set-function-name": "^2.0.2"
}
},
"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
},
"resolve": {
"version": "1.22.9",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz",
"integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==",
"dev": true,
"requires": {
"is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
},
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
"rimraf": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
"integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
"dev": true,
"requires": {
"glob": "^11.0.0",
"package-json-from-dist": "^1.0.0"
}
},
"safe-array-concat": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
"integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
"dev": true,
"requires": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
"get-intrinsic": "^1.2.6",
"has-symbols": "^1.1.0",
"isarray": "^2.0.5"
}
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
"safe-regex-test": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
"integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"is-regex": "^1.2.1"
}
},
"semver": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz",
"integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==",
"dev": true
},
"serialize-javascript": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
}
},
"set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"requires": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
}
},
"set-function-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"dev": true,
"requires": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"functions-have-names": "^1.2.3",
"has-property-descriptors": "^1.0.2"
}
},
"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,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"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
},
"side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"requires": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
}
},
"side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"dev": true,
"requires": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
}
},
"side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
}
},
"side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
}
},
"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
},
"slashes": {
"version": "3.0.12",
"resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz",
"integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==",
"dev": true
},
"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
},
"spdx-expression-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
"dev": true,
"requires": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
}
},
"spdx-license-ids": {
"version": "3.0.20",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz",
"integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==",
"dev": true
},
"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,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
},
"string-width-cjs": {
"version": "npm:string-width@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,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
},
"string.prototype.trim": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
"integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
"dev": true,
"requires": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
"define-data-property": "^1.1.4",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.5",
"es-object-atoms": "^1.0.0",
"has-property-descriptors": "^1.0.2"
}
},
"string.prototype.trimend": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
"integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.8",
"call-bound": "^1.0.2",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
}
},
"string.prototype.trimstart": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
"integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
}
},
"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,
"requires": {
"ansi-regex": "^5.0.1"
}
},
"strip-ansi-cjs": {
"version": "npm:strip-ansi@6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.1"
}
},
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"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,
"requires": {
"has-flag": "^4.0.0"
}
},
"supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true
},
"synckit": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz",
"integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==",
"dev": true,
"requires": {
"@pkgr/core": "^0.1.0",
"tslib": "^2.6.2"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
},
"tsconfig-paths": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
"integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
"dev": true,
"requires": {
"@types/json5": "^0.0.29",
"json5": "^1.0.2",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
}
},
"tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true
},
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1"
}
},
"type-detect": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
"integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
"dev": true
},
"typed-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
"integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"is-typed-array": "^1.1.13"
}
},
"typed-array-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
"integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-proto": "^1.0.3",
"is-typed-array": "^1.1.13"
}
},
"typed-array-byte-offset": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz",
"integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==",
"dev": true,
"requires": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-proto": "^1.0.3",
"is-typed-array": "^1.1.13",
"reflect.getprototypeof": "^1.0.6"
}
},
"typed-array-length": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
"integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
"dev": true,
"requires": {
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"is-typed-array": "^1.1.13",
"possible-typed-array-names": "^1.0.0",
"reflect.getprototypeof": "^1.0.6"
}
},
"unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
"has-bigints": "^1.0.2",
"has-symbols": "^1.0.3",
"which-boxed-primitive": "^1.0.2"
}
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
"which-boxed-primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.0.tgz",
"integrity": "sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==",
"dev": true,
"requires": {
"is-bigint": "^1.1.0",
"is-boolean-object": "^1.2.0",
"is-number-object": "^1.1.0",
"is-string": "^1.1.0",
"is-symbol": "^1.1.0"
}
},
"which-builtin-type": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
"integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
"dev": true,
"requires": {
"call-bound": "^1.0.2",
"function.prototype.name": "^1.1.6",
"has-tostringtag": "^1.0.2",
"is-async-function": "^2.0.0",
"is-date-object": "^1.1.0",
"is-finalizationregistry": "^1.1.0",
"is-generator-function": "^1.0.10",
"is-regex": "^1.2.1",
"is-weakref": "^1.0.2",
"isarray": "^2.0.5",
"which-boxed-primitive": "^1.1.0",
"which-collection": "^1.0.2",
"which-typed-array": "^1.1.16"
}
},
"which-collection": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
"integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
"requires": {
"is-map": "^2.0.3",
"is-set": "^2.0.3",
"is-weakmap": "^2.0.2",
"is-weakset": "^2.0.3"
}
},
"which-typed-array": {
"version": "1.1.16",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz",
"integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==",
"dev": true,
"requires": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.2"
}
},
"word-wrap": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true
},
"workerpool": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
"integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
"dev": true
},
"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,
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"wrap-ansi-cjs": {
"version": "npm:wrap-ansi@7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true
},
"yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"requires": {
"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"
}
},
"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
},
"yargs-unparser": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
"integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
"dev": true,
"requires": {
"camelcase": "^6.0.0",
"decamelize": "^4.0.0",
"flat": "^5.0.2",
"is-plain-obj": "^2.1.0"
}
},
"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
}
}
}
mock-fs-5.5.0/package.json 0000664 0000000 0000000 00000001677 14751162414 0015366 0 ustar 00root root 0000000 0000000 {
"name": "mock-fs",
"description": "A configurable mock file system. You know, for testing.",
"version": "5.5.0",
"main": "lib/index.js",
"homepage": "https://github.com/tschaub/mock-fs",
"author": {
"name": "Tim Schaub",
"url": "http://tschaub.net/"
},
"keywords": [
"mock",
"fs",
"test",
"fixtures",
"file system",
"memory"
],
"repository": {
"type": "git",
"url": "git://github.com/tschaub/mock-fs.git"
},
"bugs": {
"url": "https://github.com/tschaub/mock-fs/issues"
},
"license": "MIT",
"files": [
"lib"
],
"scripts": {
"lint": "eslint benchmarks lib test tasks",
"pretest": "npm run lint",
"test": "mocha --recursive test"
},
"devDependencies": {
"chai": "^4.3.4",
"eslint": "^9.19.0",
"eslint-config-tschaub": "^15.3.0",
"mocha": "^11.0.1",
"rimraf": "^6.0.1",
"semver": "^7.3.5"
},
"engines": {
"node": ">=12.0.0"
}
}
mock-fs-5.5.0/readme.md 0000664 0000000 0000000 00000030162 14751162414 0014646 0 ustar 00root root 0000000 0000000 [](https://github.com/tschaub/mock-fs/actions?workflow=Test)
# `mock-fs`
The `mock-fs` module allows Node's built-in [`fs` module](http://nodejs.org/api/fs.html) to be backed temporarily by an in-memory, mock file system. This lets you run tests against a set of mock files and directories instead of lugging around a bunch of test fixtures.
## Example
The code below makes it so the `fs` module is temporarily backed by a mock file system with a few files and directories.
```js
const mock = require('mock-fs');
mock({
'path/to/fake/dir': {
'some-file.txt': 'file content here',
'empty-dir': {/** empty directory */}
},
'path/to/some.png': Buffer.from([8, 6, 7, 5, 3, 0, 9]),
'some/other/path': {/** another empty directory */}
});
```
When you are ready to restore the `fs` module (so that it is backed by your real file system), call [`mock.restore()`](#mockrestore). Note that calling this may be **mandatory** in some cases. See [istanbuljs/nyc#324](https://github.com/istanbuljs/nyc/issues/324#issuecomment-234018654)
```js
// after a test runs
mock.restore();
```
## Upgrading to version 4
Instead of overriding all methods of the built-in `fs` module, the library now overrides `process.binding('fs')`. The purpose of this change is to avoid conflicts with other libraries that override `fs` methods (e.g. `graceful-fs`) and to make it possible to work with multiple Node releases without maintaining copied and slightly modified versions of Node's `fs` module.
Breaking changes:
* The `mock.fs()` function has been removed. This returned an object with `fs`-like methods without overriding the built-in `fs` module.
* The object created by `fs.Stats` is no longer an instance of `fs.Stats` (though it has all the same properties and methods).
* Lazy `require()` do not use the real filesystem.
* Tests are no longer run in Node < 4.
Some of these breaking changes may be restored in a future release.
## Docs
### `mock(config, options)`
Configure the `fs` module so it is backed by an in-memory file system.
Calling `mock` sets up a mock file system with two directories by default: `process.cwd()` and `os.tmpdir()` (or `os.tmpDir()` for older Node). When called with no arguments, just these two directories are created. When called with a `config` object, additional files, directories, and symlinks are created. To avoid creating a directory for `process.cwd()` and `os.tmpdir()`, see the [`options`](#options) below.
Property names of the `config` object are interpreted as relative paths to resources (relative from `process.cwd()`). Property values of the `config` object are interpreted as content or configuration for the generated resources.
*Note that paths should always use forward slashes (`/`) - even on Windows.*
### `options`
The second (optional) argument may include the properties below.
* `createCwd` - `boolean` Create a directory for `process.cwd()`. This is `true` by default.
* `createTmp` - `boolean` Create a directory for `os.tmpdir()`. This is `true` by default.
### Loading real files & directories
You can load real files and directories into the mock system using `mock.load()`
#### Notes
- All stat information is duplicated (dates, permissions, etc)
- By default, all files are lazy-loaded, unless you specify the `{lazy: false}` option
#### options
| Option | Type | Default | Description |
| --------- | ------- | ------- | ------------
| lazy | boolean | true | File content isn't loaded until explicitly read
| recursive | boolean | true | Load all files and directories recursively
#### `mock.load(path, options)`
```js
mock({
// Lazy-load file
'my-file.txt': mock.load(path.resolve(__dirname, 'assets/special-file.txt')),
// Pre-load js file
'ready.js': mock.load(path.resolve(__dirname, 'scripts/ready.js'), {lazy: false}),
// Recursively loads all node_modules
'node_modules': mock.load(path.resolve(__dirname, '../node_modules')),
// Creates a directory named /tmp with only the files in /tmp/special_tmp_files (no subdirectories), pre-loading all content
'/tmp': mock.load('/tmp/special_tmp_files', {recursive: false, lazy:false}),
'fakefile.txt': 'content here'
});
```
### Creating files
When `config` property values are a `string` or `Buffer`, a file is created with the provided content. For example, the following configuration creates a single file with string content (in addition to the two default directories).
```js
mock({
'path/to/file.txt': 'file content here'
});
```
To create a file with additional properties (owner, permissions, atime, etc.), use the [`mock.file()`](#mockfileproperties) function described below.
### `mock.file(properties)`
Create a factory for new files. Supported properties:
* **content** - `string|Buffer` File contents.
* **mode** - `number` File mode (permission and sticky bits). Defaults to `0666`.
* **uid** - `number` The user id. Defaults to `process.getuid()`.
* **gid** - `number` The group id. Defaults to `process.getgid()`.
* **atime** - `Date` The last file access time. Defaults to `new Date()`. Updated when file contents are accessed.
* **ctime** - `Date` The last file change time. Defaults to `new Date()`. Updated when file owner or permissions change.
* **mtime** - `Date` The last file modification time. Defaults to `new Date()`. Updated when file contents change.
* **birthtime** - `Date` The time of file creation. Defaults to `new Date()`.
To create a mock filesystem with a very old file named `foo`, you could do something like this:
```js
mock({
foo: mock.file({
content: 'file content here',
ctime: new Date(1),
mtime: new Date(1)
})
});
```
Note that if you want to create a file with the default properties, you can provide a `string` or `Buffer` directly instead of calling `mock.file()`.
### Creating directories
When `config` property values are an `Object`, a directory is created. The structure of the object is the same as the `config` object itself. So an empty directory can be created with a simple object literal (`{}`). The following configuration creates a directory containing two files (in addition to the two default directories):
```js
// note that this could also be written as
// mock({'path/to/dir': { /** config */ }})
mock({
path: {
to: {
dir: {
file1: 'text content',
file2: Buffer.from([1, 2, 3, 4])
}
}
}
});
```
To create a directory with additional properties (owner, permissions, atime, etc.), use the [`mock.directory()`](mockdirectoryproperties) function described below.
### `mock.directory(properties)`
Create a factory for new directories. Supported properties:
* **mode** - `number` Directory mode (permission and sticky bits). Defaults to `0777`.
* **uid** - `number` The user id. Defaults to `process.getuid()`.
* **gid** - `number` The group id. Defaults to `process.getgid()`.
* **atime** - `Date` The last directory access time. Defaults to `new Date()`.
* **ctime** - `Date` The last directory change time. Defaults to `new Date()`. Updated when owner or permissions change.
* **mtime** - `Date` The last directory modification time. Defaults to `new Date()`. Updated when an item is added, removed, or renamed.
* **birthtime** - `Date` The time of directory creation. Defaults to `new Date()`.
* **items** - `Object` Directory contents. Members will generate additional files, directories, or symlinks.
To create a mock filesystem with a directory with the relative path `some/dir` that has a mode of `0755` and two child files, you could do something like this:
```js
mock({
'some/dir': mock.directory({
mode: 0755,
items: {
file1: 'file one content',
file2: Buffer.from([8, 6, 7, 5, 3, 0, 9])
}
})
});
```
Note that if you want to create a directory with the default properties, you can provide an `Object` directly instead of calling `mock.directory()`.
### Creating symlinks
Using a `string` or a `Buffer` is a shortcut for creating files with default properties. Using an `Object` is a shortcut for creating a directory with default properties. There is no shortcut for creating symlinks. To create a symlink, you need to call the [`mock.symlink()`](#mocksymlinkproperties) function described below.
### `mock.symlink(properties)`
Create a factory for new symlinks. Supported properties:
* **path** - `string` Path to the source (required).
* **mode** - `number` Symlink mode (permission and sticky bits). Defaults to `0666`.
* **uid** - `number` The user id. Defaults to `process.getuid()`.
* **gid** - `number` The group id. Defaults to `process.getgid()`.
* **atime** - `Date` The last symlink access time. Defaults to `new Date()`.
* **ctime** - `Date` The last symlink change time. Defaults to `new Date()`.
* **mtime** - `Date` The last symlink modification time. Defaults to `new Date()`.
* **birthtime** - `Date` The time of symlink creation. Defaults to `new Date()`.
To create a mock filesystem with a file and a symlink, you could do something like this:
```js
mock({
'some/dir': {
'regular-file': 'file contents',
'a-symlink': mock.symlink({
path: 'regular-file'
})
}
});
```
### Restoring the file system
### `mock.restore()`
Restore the `fs` binding to the real file system. This undoes the effect of calling `mock()`. Typically, you would set up a mock file system before running a test and restore the original after. Using a test runner with `beforeEach` and `afterEach` hooks, this might look like the following:
```js
beforeEach(function() {
mock({
'fake-file': 'file contents'
});
});
afterEach(mock.restore);
```
### Bypassing the mock file system
#### `mock.bypass(fn)`
Execute calls to the real filesystem with mock.bypass()
```js
// This file exists only on the real FS, not on the mocked FS
const realFilePath = '/path/to/real/file.txt';
const myData = mock.bypass(() => fs.readFileSync(realFilePath, 'utf-8'));
```
If you pass an asynchronous function or a promise-returning function to `bypass()`, a promise will be returned.
#### Async Warning
Asynchronous calls are supported, however, they are not recommended as they could produce unintended consequences if
anything else tries to access the mocked filesystem before they've completed.
```js
async function getFileInfo(fileName) {
return await mock.bypass(async () => {
const stats = await fs.promises.stat(fileName);
const data = await fs.promises.readFile(fileName);
return {stats, data};
});
}
```
## Install
Using `npm`:
```
npm install mock-fs --save-dev
```
## Caveats
When you require `mock-fs`, Node's own `fs` module is patched to allow the binding to the underlying file system to be swapped out. If you require `mock-fs` *before* any other modules that modify `fs` (e.g. `graceful-fs`), the mock should behave as expected.
**Note** `mock-fs` is not compatible with `graceful-fs@3.x` but works with `graceful-fs@4.x`.
Mock file access is controlled based on file mode where `process.getuid()` and `process.getgid()` are available (POSIX systems). On other systems (e.g. Windows) the file mode has no effect.
Tested on Linux, OSX, and Windows using Node 18 through 22. Check the tickets for a list of [known issues](https://github.com/tschaub/mock-fs/issues).
### Using with Jest Snapshot Testing
`.toMatchSnapshot` in [Jest](https://jestjs.io/docs/en/snapshot-testing) uses `fs` to load existing snapshots.
If `mockFs` is active, Jest isn't able to load existing snapshots. In such case it accepts all snapshots
without diffing the old ones, which breaks the concept of snapshot testing.
Calling `mock.restore()` in `afterEach` is too late and it's necessary to call it before snapshot matching:
```js
const actual = testedFunction()
mock.restore()
expect(actual).toMatchSnapshot()
```
Note: it's safe to call `mock.restore` multiple times, so it can still be called in `afterEach` and then manually
in test cases which use snapshot testing. mock-fs-5.5.0/tasks/ 0000775 0000000 0000000 00000000000 14751162414 0014212 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/tasks/next-dev-version.js 0000664 0000000 0000000 00000000572 14751162414 0017771 0 ustar 00root root 0000000 0000000 const semver = require('semver');
const pkg = require('../package.json');
function nextVersion() {
const version = pkg.version;
const s = semver.parse(version);
if (!s) {
throw new Error(`Invalid version ${version}`);
}
return `${s.major}.${s.minor}.${s.patch}-dev.${Date.now()}`;
}
if (require.main === module) {
process.stdout.write(`${nextVersion()}\n`);
}
mock-fs-5.5.0/test/ 0000775 0000000 0000000 00000000000 14751162414 0014044 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/test/.eslintrc 0000664 0000000 0000000 00000000045 14751162414 0015667 0 ustar 00root root 0000000 0000000 {
"env": {
"mocha": true
}
}
mock-fs-5.5.0/test/assets/ 0000775 0000000 0000000 00000000000 14751162414 0015346 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/test/assets/dir/ 0000775 0000000 0000000 00000000000 14751162414 0016124 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/test/assets/dir/file2.txt 0000775 0000000 0000000 00000000005 14751162414 0017664 0 ustar 00root root 0000000 0000000 data2 mock-fs-5.5.0/test/assets/dir/subdir/ 0000775 0000000 0000000 00000000000 14751162414 0017414 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/test/assets/dir/subdir/file3.txt 0000775 0000000 0000000 00000000005 14751162414 0021155 0 ustar 00root root 0000000 0000000 data3 mock-fs-5.5.0/test/assets/file1.txt 0000775 0000000 0000000 00000000005 14751162414 0017105 0 ustar 00root root 0000000 0000000 data1 mock-fs-5.5.0/test/helper.js 0000664 0000000 0000000 00000004700 14751162414 0015662 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const chai = require('chai');
const {describe, it, xdescribe, xit} = require('mocha');
const semver = require('semver');
/** @type {boolean} */
chai.config.includeStack = true;
/**
* Chai's assert function configured to include stacks on failure.
* @type {Function}
*/
exports.assert = chai.assert;
function run(func) {
func();
}
function noRun() {}
const TEST = {
it: it,
xit: xit,
describe: describe,
xdescribe: xdescribe,
run: run,
};
const NO_TEST = {
it: xit,
xit: xit,
describe: xdescribe,
xdescribe: xdescribe,
run: noRun,
};
exports.assertEqualPaths = function (actual, expected) {
if (process.platform === 'win32') {
chai.assert.equal(actual.toLowerCase(), expected.toLowerCase());
} else {
chai.assert(actual, expected);
}
};
exports.flags = function (str) {
switch (str) {
case 'r':
return constants.O_RDONLY;
case 'rs':
return constants.O_RDONLY | constants.O_SYNC;
case 'r+':
return constants.O_RDWR;
case 'rs+':
return constants.O_RDWR | constants.O_SYNC;
case 'w':
return constants.O_TRUNC | constants.O_CREAT | constants.O_WRONLY;
case 'wx': // fall through
case 'xw':
return (
constants.O_TRUNC |
constants.O_CREAT |
constants.O_WRONLY |
constants.O_EXCL
);
case 'w+':
return constants.O_TRUNC | constants.O_CREAT | constants.O_RDWR;
case 'wx+': // fall through
case 'xw+':
return (
constants.O_TRUNC |
constants.O_CREAT |
constants.O_RDWR |
constants.O_EXCL
);
case 'a':
return constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY;
case 'ax': // fall through
case 'xa':
return (
constants.O_APPEND |
constants.O_CREAT |
constants.O_WRONLY |
constants.O_EXCL
);
case 'a+':
return constants.O_APPEND | constants.O_CREAT | constants.O_RDWR;
case 'ax+': // fall through
case 'xa+':
return (
constants.O_APPEND |
constants.O_CREAT |
constants.O_RDWR |
constants.O_EXCL
);
default:
throw new Error('Unsupported flag: ' + str);
}
};
exports.inVersion = function (range) {
if (semver.satisfies(process.version, range)) {
return TEST;
} else {
return NO_TEST;
}
};
/**
* Convert a string to flags for fs.open.
* @param {string} str String.
* @return {number} Flags.
*/
mock-fs-5.5.0/test/integration/ 0000775 0000000 0000000 00000000000 14751162414 0016367 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/test/integration/filecount.js 0000664 0000000 0000000 00000001544 14751162414 0020721 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
function numFiles(dir, items, callback) {
const total = items.length;
let files = 0;
let completed = 0;
if (total === 0) {
callback(null, 0);
}
items.forEach(function (item) {
fs.stat(path.join(dir, item), function (err, stats) {
if (err) {
return callback(err);
}
if (stats && stats.isFile()) {
++files;
}
++completed;
if (completed === total) {
callback(null, files);
}
});
});
}
/**
* Count the number of files in a directory.
* @param {string} dir Path to directory.
* @param {function(Error, number):void} callback Callback.
*/
module.exports = function (dir, callback) {
fs.readdir(dir, function (err, items) {
if (err) {
return callback(err);
}
numFiles(dir, items, callback);
});
};
mock-fs-5.5.0/test/integration/filecount.spec.js 0000664 0000000 0000000 00000002551 14751162414 0021651 0 ustar 00root root 0000000 0000000 const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const assert = require('../helper.js').assert;
const count = require('./filecount.js');
describe('count(dir, callback)', function () {
beforeEach(function () {
mock({
'path/to/dir': {
'one.txt': 'first file',
'two.txt': 'second file',
'empty-dir': {},
'another-dir': {
'another.txt': 'more files',
},
},
});
});
afterEach(mock.restore);
it('counts files in a directory', function (done) {
count('path/to/dir', function (err, num) {
if (err) {
return done(err);
}
assert.equal(num, 2);
done();
});
});
it('counts files in another directory', function (done) {
count('path/to/dir/another-dir', function (err, num) {
if (err) {
return done(err);
}
assert.equal(num, 1);
done();
});
});
it('counts files in an empty directory', function (done) {
count('path/to/dir/empty-dir', function (err, num) {
if (err) {
return done(err);
}
assert.equal(num, 0);
done();
});
});
it('fails for bogus path', function (done) {
count('path/to/dir/bogus', function (err, num) {
assert.instanceOf(err, Error);
assert.isUndefined(num);
done();
});
});
});
mock-fs-5.5.0/test/lib/ 0000775 0000000 0000000 00000000000 14751162414 0014612 5 ustar 00root root 0000000 0000000 mock-fs-5.5.0/test/lib/binding.spec.js 0000664 0000000 0000000 00000154676 14751162414 0017536 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const path = require('path');
const {beforeEach, describe, it} = require('mocha');
const Binding = require('../../lib/binding.js');
const Directory = require('../../lib/directory.js');
const File = require('../../lib/file.js');
const FileSystem = require('../../lib/filesystem.js');
const SymbolicLink = require('../../lib/symlink.js');
const helper = require('../helper.js');
const assert = helper.assert;
const assertEqualPaths = helper.assertEqualPaths;
const flags = helper.flags;
describe('Binding', function () {
let system;
beforeEach(function () {
system = FileSystem.create({
'mock-dir': {
'one.txt': 'one content',
'two.txt': FileSystem.file({
content: 'two content',
mode: parseInt('0644', 8),
atime: new Date(1),
ctime: new Date(2),
mtime: new Date(3),
birthtime: new Date(4),
}),
'one-link.txt': FileSystem.symlink({path: './one.txt'}),
'one-link2.txt': FileSystem.symlink({path: './one-link.txt'}),
'three.bin': Buffer.from([1, 2, 3]),
empty: {},
'non-empty': {
'a.txt': FileSystem.file({
content: 'a content',
mode: parseInt('0644', 8),
atime: new Date(1),
ctime: new Date(2),
mtime: new Date(3),
birthtime: new Date(4),
}),
'b.txt': 'b content',
},
'dir-link': FileSystem.symlink({path: './non-empty'}),
'dir-link2': FileSystem.symlink({path: './dir-link'}),
'dead-link': FileSystem.symlink({path: './non-a-real-file'}),
},
});
});
describe('constructor', function () {
it('creates a new instance', function () {
const binding = new Binding(system);
assert.instanceOf(binding, Binding);
});
});
describe('#getSystem()', function () {
const binding = new Binding(system);
assert.equal(binding.getSystem(), system);
});
describe('#setSystem()', function () {
const firstSystem = new FileSystem();
const binding = new Binding(firstSystem);
assert.equal(binding.getSystem(), firstSystem);
binding.setSystem(system);
assert.equal(binding.getSystem(), system);
});
describe('#stat()', function () {
it('calls callback with a Stats instance', function (done) {
const binding = new Binding(system);
binding.stat(
path.join('mock-dir', 'one.txt'),
false,
function (err, stats) {
if (err) {
return done(err);
}
assert.instanceOf(stats, Float64Array);
done();
},
);
});
it('returns a Stats instance when called synchronously', function () {
const binding = new Binding(system);
const stats = binding.stat(path.join('mock-dir', 'one.txt'), false);
assert.instanceOf(stats, Float64Array);
});
it('identifies files (async)', function (done) {
const binding = new Binding(system);
binding.stat(
path.join('mock-dir', 'one.txt'),
false,
function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFREG);
done();
},
);
});
it('identifies files (sync)', function () {
const binding = new Binding(system);
const stats = binding.stat(path.join('mock-dir', 'one.txt'), false);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFREG);
});
it('identifies directories (async)', function (done) {
const binding = new Binding(system);
binding.stat('mock-dir', false, function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFDIR);
done();
});
});
it('identifies directories (sync)', function () {
const binding = new Binding(system);
const stats = binding.stat('mock-dir', false);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFDIR);
});
it('includes atime, ctime, mtime and birthtime', function (done) {
const binding = new Binding(system);
binding.stat(
path.join('mock-dir', 'two.txt'),
false,
function (err, stats) {
if (err) {
return done(err);
}
assert.equal(
stats[10] * 1000 + stats[11] / 1000000,
new Date(1).getTime(),
);
assert.equal(
stats[12] * 1000 + stats[13] / 1000000,
new Date(3).getTime(),
);
assert.equal(
stats[14] * 1000 + stats[15] / 1000000,
new Date(2).getTime(),
);
assert.equal(
stats[16] * 1000 + stats[17] / 1000000,
new Date(4).getTime(),
);
done();
},
);
});
it('includes mode with file permissions (default)', function (done) {
const binding = new Binding(system);
binding.stat(
path.join('mock-dir', 'one.txt'),
false,
function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[1] & parseInt('0777', 8), parseInt('0666', 8));
done();
},
);
});
it('includes mode with file permissions (custom)', function (done) {
const binding = new Binding(system);
binding.stat(
path.join('mock-dir', 'two.txt'),
false,
function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[1] & parseInt('0777', 8), parseInt('0644', 8));
done();
},
);
});
it('includes size in bytes (async)', function (done) {
const binding = new Binding(system);
binding.stat(
path.join('mock-dir', 'two.txt'),
false,
function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[8], 11);
done();
},
);
});
it('includes size in bytes (sync)', function () {
const binding = new Binding(system);
const stats = binding.stat(path.join('mock-dir', 'three.bin'), false);
assert.equal(stats[8], 3);
});
it('includes non-zero size for directories', function () {
const binding = new Binding(system);
const stats = binding.stat('mock-dir', false);
assert.isNumber(stats[8]);
assert.isTrue(stats[8] > 0);
});
it('includes uid for files', function () {
const binding = new Binding(system);
const stats = binding.stat(path.join('mock-dir', 'two.txt'), false);
if (process.getuid) {
assert.equal(stats[3], process.getuid());
}
});
it('includes uid for directories', function () {
const binding = new Binding(system);
const stats = binding.stat(path.join('mock-dir', 'empty'), false);
if (process.getuid) {
assert.equal(stats[3], process.getuid());
}
});
it('includes gid for files', function () {
const binding = new Binding(system);
const stats = binding.stat(path.join('mock-dir', 'two.txt'), false);
if (process.getgid) {
assert.equal(stats[4], process.getgid());
}
});
it('includes gid for directories', function () {
const binding = new Binding(system);
const stats = binding.stat(path.join('mock-dir', 'empty'), false);
if (process.getgid) {
assert.equal(stats[4], process.getgid());
}
});
it('retrieves stats of files relative to symbolic linked directories', function () {
const binding = new Binding(system);
const stats = binding.stat(
path.join('mock-dir', 'dir-link', 'a.txt'),
false,
);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats[1] & 0x1ff, parseInt('0644', 8));
if (process.getuid) {
assert.equal(stats[3], process.getuid());
}
if (process.getgid) {
assert.equal(stats[4], process.getgid());
}
});
});
describe('#realpath()', function () {
it('returns the real path for a regular file', function (done) {
const binding = new Binding(system);
binding.realpath('mock-dir/one.txt', 'utf-8', function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
});
});
it('returns the real path for a directory', function (done) {
const binding = new Binding(system);
binding.realpath('mock-dir/empty', 'utf-8', function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/empty'));
done();
});
});
it('returns the real path for a symlinked file', function (done) {
const binding = new Binding(system);
binding.realpath(
'mock-dir/one-link.txt',
'utf-8',
function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
},
);
});
it('returns the real path for a deeply symlinked file', function (done) {
const binding = new Binding(system);
binding.realpath(
'mock-dir/one-link2.txt',
'utf-8',
function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
},
);
});
it('returns the real path for a symlinked directory', function (done) {
const binding = new Binding(system);
binding.realpath('mock-dir/dir-link', 'utf-8', function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/non-empty'));
done();
});
});
it('returns the real path for a deeply symlinked directory', function (done) {
const binding = new Binding(system);
binding.realpath('mock-dir/dir-link2', 'utf-8', function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/non-empty'));
done();
});
});
it('returns the real path for a file in a symlinked directory', function (done) {
const binding = new Binding(system);
binding.realpath(
'mock-dir/dir-link/b.txt',
'utf-8',
function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/non-empty/b.txt'));
done();
},
);
});
it('accepts a buffer', function (done) {
const binding = new Binding(system);
binding.realpath(
Buffer.from('mock-dir/one.txt'),
'utf-8',
function (err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
},
);
});
it('can return a buffer', function (done) {
const binding = new Binding(system);
binding.realpath('mock-dir/one.txt', 'buffer', function (err, realPath) {
if (err) {
return done(err);
}
assert.equal(Buffer.isBuffer(realPath), true);
assertEqualPaths(realPath.toString(), path.resolve('mock-dir/one.txt'));
done();
});
});
it('throws ENOENT for a non-existent file', function (done) {
const binding = new Binding(system);
binding.realpath(
'mock-dir/bogus-path',
'utf-8',
function (err, realPath) {
if (!err || realPath) {
return done(new Error('Expected ENOENT'));
}
assert.equal(err.code, 'ENOENT');
done();
},
);
});
it('throws ENOTDIR for a file treated like a directory', function (done) {
const binding = new Binding(system);
binding.realpath(
'mock-dir/one.txt/foo',
'utf-8',
function (err, realPath) {
if (!err || realPath) {
return done(new Error('Expected ENOTDIR'));
}
assert.equal(err.code, 'ENOTDIR');
done();
},
);
});
});
describe('#fstat()', function () {
it('calls callback with a Stats instance', function (done) {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
binding.fstat(fd, false, function (err, stats) {
if (err) {
return done(err);
}
assert.instanceOf(stats, Float64Array);
done();
});
});
it('returns a Stats instance when called synchronously', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
const stats = binding.fstat(fd, false);
assert.instanceOf(stats, Float64Array);
});
it('identifies files (async)', function (done) {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
binding.fstat(fd, false, function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFREG);
done();
});
});
it('identifies directories (async)', function (done) {
const binding = new Binding(system);
const fd = binding.open('mock-dir', flags('r'));
binding.fstat(fd, false, function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFDIR);
done();
});
});
it('includes size in bytes (async)', function (done) {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'two.txt'), flags('r'));
binding.fstat(fd, false, function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats[8], 11);
done();
});
});
it('includes size in bytes (sync)', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'three.bin'), flags('r'));
const stats = binding.fstat(fd, false);
assert.equal(stats[8], 3);
});
it('includes non-zero size for directories', function () {
const binding = new Binding(system);
const fd = binding.open('mock-dir', flags('r'));
const stats = binding.fstat(fd, false);
assert.isNumber(stats[8]);
assert.isTrue(stats[8] > 0);
});
});
describe('#readdir()', function () {
it('calls callback with file list', function (done) {
const binding = new Binding(system);
binding.readdir('mock-dir', 'utf8', false, function (err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items.sort(), [
'dead-link',
'dir-link',
'dir-link2',
'empty',
'non-empty',
'one-link.txt',
'one-link2.txt',
'one.txt',
'three.bin',
'two.txt',
]);
done();
});
});
it('accepts "buffer" encoding', function (done) {
const binding = new Binding(system);
binding.readdir('mock-dir', 'buffer', false, function (err, items) {
assert.isNull(err);
assert.isArray(items);
items.forEach(function (item) {
assert.equal(Buffer.isBuffer(item), true);
});
const strings = items.map(function (item) {
return item.toString();
});
assert.deepEqual(strings.sort(), [
'dead-link',
'dir-link',
'dir-link2',
'empty',
'non-empty',
'one-link.txt',
'one-link2.txt',
'one.txt',
'three.bin',
'two.txt',
]);
done();
});
});
it('returns a file list (sync)', function () {
const binding = new Binding(system);
const items = binding.readdir('mock-dir', 'utf8', false);
assert.isArray(items);
assert.deepEqual(items.sort(), [
'dead-link',
'dir-link',
'dir-link2',
'empty',
'non-empty',
'one-link.txt',
'one-link2.txt',
'one.txt',
'three.bin',
'two.txt',
]);
});
it('calls callback with file list for symbolic linked dir', function (done) {
const binding = new Binding(system);
binding.readdir(
path.join('mock-dir', 'dir-link'),
'utf8',
false,
function (err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items.sort(), ['a.txt', 'b.txt']);
done();
},
);
});
it('calls callback with file list for link to symbolic linked dir', function (done) {
const binding = new Binding(system);
binding.readdir(
path.join('mock-dir', 'dir-link2'),
'utf8',
false,
function (err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items.sort(), ['a.txt', 'b.txt']);
done();
},
);
});
it('calls callback with file list for symbolic linked dir (sync)', function () {
const binding = new Binding(system);
const items = binding.readdir(
path.join('mock-dir', 'dir-link'),
'utf8',
false,
);
assert.isArray(items);
assert.deepEqual(items.sort(), ['a.txt', 'b.txt']);
});
it('calls callback with error for bogus dir', function (done) {
const binding = new Binding(system);
binding.readdir('bogus', 'utf8', false, function (err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
});
});
it('calls callback with error for file path', function (done) {
const binding = new Binding(system);
binding.readdir(
path.join('mock-dir', 'one.txt'),
'utf8',
false,
function (err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
},
);
});
it('calls callback with error for dead symbolic link', function (done) {
const binding = new Binding(system);
binding.readdir(
path.join('mock-dir', 'dead-link'),
'utf8',
false,
function (err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
},
);
});
it('calls callback with error for symbolic link to file', function (done) {
const binding = new Binding(system);
binding.readdir(
path.join('mock-dir', 'one-link.txt'),
'utf8',
false,
function (err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
},
);
});
it('calls callback with error for link to symbolic link to file', function (done) {
const binding = new Binding(system);
binding.readdir(
path.join('mock-dir', 'one-link2.txt'),
'utf8',
false,
function (err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
},
);
});
});
describe('#open()', function () {
it('creates a file descriptor for reading (r)', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
assert.isNumber(fd);
});
it('generates error if file does not exist (r)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open('bogus', flags('r'));
});
});
it('creates a file descriptor for reading and writing (r+)', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r+'));
assert.isNumber(fd);
});
it('does not truncate (r+)', function () {
const binding = new Binding(system);
binding.open(path.join('mock-dir', 'two.txt'), flags('r+'));
const file = system.getItem(path.join('mock-dir', 'two.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'two content');
});
it('generates error if file does not exist (r+)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open('bogus', flags('r+'));
});
});
it('creates a file descriptor for reading (rs)', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'two.txt'), flags('rs'));
assert.isNumber(fd);
});
it('generates error if file does not exist (rs)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open('bogus', flags('rs'));
});
});
it('creates a file descriptor for reading and writing (rs+)', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'two.txt'), flags('rs+'));
assert.isNumber(fd);
});
it('generates error if file does not exist (rs+)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open('bogus', flags('rs+'));
});
});
it('opens a new file for writing (w)', function () {
const binding = new Binding(system);
binding.open('new.txt', flags('w'), parseInt('0644', 8));
const file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0644', 8));
});
it('truncates an existing file for writing (w)', function () {
const binding = new Binding(system);
binding.open(
path.join('mock-dir', 'two.txt'),
flags('w'),
parseInt('0666', 8),
);
const file = system.getItem(path.join('mock-dir', 'two.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), '');
});
it('generates error if file is directory (w)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open('mock-dir', flags('w'));
});
});
it('generates error if file exists (wx)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open(path.join('mock-dir', 'two.txt'), flags('wx'));
});
});
it('opens a new file for reading and writing (w+)', function () {
const binding = new Binding(system);
binding.open('new.txt', flags('w+'), parseInt('0644', 8));
const file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0644', 8));
assert.equal(String(file.getContent()), '');
});
it('truncates an existing file for writing (w+)', function () {
const binding = new Binding(system);
binding.open(
path.join('mock-dir', 'one.txt'),
flags('w+'),
parseInt('0666', 8),
);
const file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), '');
});
it('opens a new file for reading and writing (wx+)', function () {
const binding = new Binding(system);
binding.open('new.txt', flags('wx+'), parseInt('0644', 8));
const file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0644', 8));
assert.equal(String(file.getContent()), '');
});
it('generates error if file exists (wx+)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open(
path.join('mock-dir', 'one.txt'),
flags('wx+'),
parseInt('0666', 8),
);
});
});
it('opens a new file for appending (a)', function () {
const binding = new Binding(system);
binding.open('new.txt', flags('a'), parseInt('0666', 8));
const file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0666', 8));
assert.equal(String(file.getContent()), '');
});
it('opens an existing file for appending (a)', function () {
const binding = new Binding(system);
binding.open(
path.join('mock-dir', 'one.txt'),
flags('a'),
parseInt('0666', 8),
);
const file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'one content');
});
it('generates error if file is directory (a)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open('mock-dir', flags('a'));
});
});
it('opens a new file for appending (ax)', function () {
const binding = new Binding(system);
binding.open('new.txt', flags('ax'), parseInt('0664', 8));
const file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0664', 8));
assert.equal(String(file.getContent()), '');
});
it('generates error if file exists (ax)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open(
path.join('mock-dir', 'one.txt'),
flags('ax'),
parseInt('0666', 8),
);
});
});
it('opens a new file for appending and reading (a+)', function () {
const binding = new Binding(system);
binding.open('new.txt', flags('a+'), parseInt('0666', 8));
const file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0666', 8));
assert.equal(String(file.getContent()), '');
});
it('opens an existing file for appending and reading (a+)', function () {
const binding = new Binding(system);
binding.open(
path.join('mock-dir', 'one.txt'),
flags('a+'),
parseInt('0666', 8),
);
const file = system.getItem(path.join('mock-dir', 'two.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'two content');
});
it('opens a new file for appending and reading (ax+)', function () {
const binding = new Binding(system);
binding.open('new.txt', flags('ax+'), parseInt('0666', 8));
const file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0666', 8));
assert.equal(String(file.getContent()), '');
});
it('opens an existing file for appending and reading (ax+)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open(
path.join('mock-dir', 'two.txt'),
flags('ax+'),
parseInt('0666', 8),
);
});
});
});
describe('#close()', function () {
it('closes an existing file descriptor', function () {
const binding = new Binding(system);
const fd = binding.open('new.txt', flags('w'), parseInt('0644', 8));
binding.close(fd);
});
it('fails for closed file descriptor', function () {
const binding = new Binding(system);
const fd = binding.open('new.txt', flags('w'), parseInt('0644', 8));
binding.close(fd);
assert.throws(function () {
binding.close(fd);
});
});
});
describe('#read()', function () {
it('reads from a file', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'two.txt'), flags('r'));
const buffer = Buffer.alloc(11);
const read = binding.read(fd, buffer, 0, 11, 0);
assert.equal(read, 11);
assert.equal(String(buffer), 'two content');
});
it('reads into a Uint8Array', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'three.bin'), flags('r'));
const buffer = new Uint8Array(3);
const read = binding.read(fd, buffer, 0, 3, 0);
assert.equal(read, 3);
assert.deepEqual(Array.from(buffer), [1, 2, 3]);
});
it('interprets null position as current position', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
const buffer = Buffer.alloc(4);
// chunk 1
assert.equal(binding.read(fd, buffer, 0, 11, null), 4);
assert.equal(String(buffer), 'one ');
// chunk 2
assert.equal(binding.read(fd, buffer, 0, 11, null), 4);
assert.equal(String(buffer), 'cont');
// chunk 3
assert.equal(binding.read(fd, buffer, 0, 11, null), 3);
assert.equal(String(buffer.slice(0, 3)), 'ent');
});
it('reads from a symbolic link', function () {
const binding = new Binding(system);
const fd = binding.open(
path.join('mock-dir', 'one-link.txt'),
flags('r'),
);
const buffer = Buffer.alloc(11);
const read = binding.read(fd, buffer, 0, 11, 0);
assert.equal(read, 11);
assert.equal(String(buffer), 'one content');
});
it('reads from a deeply linked symlink', function () {
const binding = new Binding(system);
const fd = binding.open(
path.join('mock-dir', 'one-link2.txt'),
flags('r'),
);
const buffer = Buffer.alloc(11);
const read = binding.read(fd, buffer, 0, 11, 0);
assert.equal(read, 11);
assert.equal(String(buffer), 'one content');
});
it('throws if not open for reading', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'two.txt'), flags('w'));
const buffer = Buffer.alloc(11);
assert.throws(function () {
binding.read(fd, buffer, 0, 11, 0);
});
});
it('throws ENOTDIR when trying to open an incorrect path (nested under existing file)', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.open(
path.join('mock-dir', 'two.txt', 'bogus-path'),
flags('r'),
);
}, 'ENOTDIR');
});
});
describe('#writeBuffers()', function () {
it('writes to a file', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'new.txt'), flags('w'));
const buffers = [Buffer.from('new '), Buffer.from('content')];
const written = binding.writeBuffers(fd, buffers);
assert.equal(written, 11);
const file = system.getItem(path.join('mock-dir', 'new.txt'));
assert.instanceOf(file, File);
const content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'new content');
});
it('can append to a file', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('a'));
const buffers = [Buffer.from(' more'), Buffer.from(' content')];
const written = binding.writeBuffers(fd, buffers);
assert.equal(written, 13);
const file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
const content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'one content more content');
});
it('can overwrite part of a file', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'one.txt'), flags('a'));
const buffers = [Buffer.from('n'), Buffer.from('e'), Buffer.from('w')];
const written = binding.writeBuffers(fd, buffers, 0);
assert.equal(written, 3);
const file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
const content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'new content');
});
it('throws if not open for writing', function () {
const binding = new Binding(system);
const fd = binding.open(path.join('mock-dir', 'two.txt'), flags('r'));
const buffers = [Buffer.from('some content')];
assert.throws(function () {
binding.writeBuffers(fd, buffers);
});
});
});
describe('#rename()', function () {
it('allows files to be renamed', function (done) {
const binding = new Binding(system);
const oldPath = path.join('mock-dir', 'one.txt');
const newPath = path.join('mock-dir', 'empty', 'new.txt');
binding.rename(oldPath, newPath, function (_) {
const stats = binding.stat(newPath);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats[8], 11);
done();
});
});
it('allows files to be renamed (sync)', function () {
const binding = new Binding(system);
const oldPath = path.join('mock-dir', 'one.txt');
const newPath = path.join('mock-dir', 'new.txt');
binding.rename(oldPath, newPath);
const stats = binding.stat(newPath);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats[8], 11);
});
it('replaces existing files (sync)', function () {
const binding = new Binding(system);
const oldPath = path.join('mock-dir', 'one.txt');
const newPath = path.join('mock-dir', 'two.txt');
binding.rename(oldPath, newPath);
const stats = binding.stat(newPath);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats[8], 11);
});
it('allows directories to be renamed', function (done) {
const binding = new Binding(system);
const oldPath = path.join('mock-dir', 'empty');
const newPath = path.join('mock-dir', 'new');
binding.rename(oldPath, newPath, function (_) {
const stats = binding.stat(newPath);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFDIR);
done();
});
});
it('allows directories to be renamed (sync)', function () {
const binding = new Binding(system);
const oldPath = path.join('mock-dir');
const newPath = path.join('new-dir');
binding.rename(oldPath, newPath);
const stats = binding.stat(newPath);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFDIR);
const items = binding.readdir(newPath);
assert.isArray(items);
assert.deepEqual(items.sort(), [
'dead-link',
'dir-link',
'dir-link2',
'empty',
'non-empty',
'one-link.txt',
'one-link2.txt',
'one.txt',
'three.bin',
'two.txt',
]);
});
it('calls callback with error for bogus old path', function (done) {
const binding = new Binding(system);
const oldPath = path.join('mock-dir', 'bogus');
const newPath = path.join('mock-dir', 'new');
binding.rename(oldPath, newPath, function (err) {
assert.instanceOf(err, Error);
done();
});
});
it('calls callback with error for file->dir rename', function (done) {
const binding = new Binding(system);
const oldPath = path.join('mock-dir', 'one.txt');
const newPath = path.join('mock-dir', 'empty');
binding.rename(oldPath, newPath, function (err) {
assert.instanceOf(err, Error);
done();
});
});
it('calls callback with error for dir->file rename', function (done) {
const binding = new Binding(system);
const oldPath = path.join('mock-dir', 'one.txt');
const newPath = path.join('mock-dir', 'empty');
binding.rename(oldPath, newPath, function (err) {
assert.instanceOf(err, Error);
done();
});
});
});
describe('#mkdir()', function () {
it('creates a new directory', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'foo');
binding.mkdir(dirPath, parseInt('0755', 8), false);
const dir = system.getItem(dirPath);
assert.instanceOf(dir, Directory);
assert.equal(dir.getMode(), parseInt('0755', 8));
});
it('fails if parent does not exist', function () {
const binding = new Binding(system);
const dirPath = path.join('bogus', 'path');
assert.throws(function () {
binding.mkdir(dirPath, parseInt('0755', 8), false);
});
});
it('fails if directory exists', function () {
const binding = new Binding(system);
const dirPath = 'mock-dir';
assert.throws(function () {
binding.mkdir(dirPath, parseInt('0755', 8), false);
});
});
it('fails if file exists', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'one.txt');
assert.throws(function () {
binding.mkdir(dirPath, parseInt('0755', 8), false);
});
});
});
describe('#mkdir() recursive', function () {
it('creates a new directory', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'foo');
binding.mkdir(dirPath, parseInt('0755', 8), true);
const dir = system.getItem(dirPath);
assert.instanceOf(dir, Directory);
assert.equal(dir.getMode(), parseInt('0755', 8));
});
it('creates a new deep directory', function () {
const binding = new Binding(system);
const dirPath1 = path.join('mock-dir', 'foo');
const dirPath2 = path.join(dirPath1, 'bar');
const dirPath3 = path.join(dirPath2, 'loo');
binding.mkdir(dirPath3, parseInt('0755', 8), true);
let dir = system.getItem(dirPath3);
assert.instanceOf(dir, Directory);
assert.equal(dir.getMode(), parseInt('0755', 8));
dir = system.getItem(dirPath2);
assert.instanceOf(dir, Directory);
assert.equal(dir.getMode(), parseInt('0755', 8));
dir = system.getItem(dirPath1);
assert.instanceOf(dir, Directory);
assert.equal(dir.getMode(), parseInt('0755', 8));
});
it('fails if permission does not allow recursive creation', function () {
const binding = new Binding(system);
const dirPath1 = path.join('mock-dir', 'foo');
const dirPath2 = path.join(dirPath1, 'bar');
const dirPath3 = path.join(dirPath2, 'loo');
assert.throws(function () {
binding.mkdir(dirPath3, parseInt('0400', 8), true);
});
});
it('fails if one parent is not a folder', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'one.txt', 'foo', 'bar');
assert.throws(function () {
binding.mkdir(dirPath, parseInt('0755', 8), true);
});
});
it('fails if file exists', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'non-empty', 'a.txt');
assert.throws(function () {
binding.mkdir(dirPath, parseInt('0755', 8), true);
});
});
it('passes silently if directory exists', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'non-empty');
assert.doesNotThrow(function () {
binding.mkdir(dirPath, parseInt('0755', 8), true);
});
});
});
describe('#mkdtemp()', function () {
it('creates a new directory', function () {
const binding = new Binding(system);
const template = path.join('mock-dir', 'fooXXXXXX');
const dirPath = binding.mkdtemp(template);
assert.notEqual(template, dirPath);
const dir = system.getItem(dirPath);
assert.instanceOf(dir, Directory);
});
it('fails if parent does not exist', function () {
const binding = new Binding(system);
const dirPath = path.join('bogus', 'pathXXXXXX');
assert.throws(function () {
binding.mkdtemp(dirPath);
});
});
it('fails if file exists', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'one.txt', 'XXXXXX');
assert.throws(function () {
binding.mkdtemp(dirPath);
});
});
});
describe('#rmdir()', function () {
it('removes an empty directory', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'empty');
binding.rmdir(dirPath);
assert.isNull(system.getItem(dirPath));
});
it('fails if directory is not empty', function () {
const binding = new Binding(system);
const dirPath = 'mock-dir';
assert.throws(function () {
binding.rmdir(dirPath);
});
});
it('fails if directory does not exist', function () {
const binding = new Binding(system);
const dirPath = path.join('bogus', 'path');
assert.throws(function () {
binding.rmdir(dirPath);
});
});
it('fails if a file exists', function () {
const binding = new Binding(system);
const dirPath = path.join('mock-dir', 'one.txt');
assert.throws(function () {
binding.rmdir(dirPath);
});
});
});
describe('#ftruncate()', function () {
it('truncates a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r+'));
binding.ftruncate(fd, 3);
const file = system.getItem(pathname);
assert.equal(String(file.getContent()), 'one');
});
it('fails if directory', function () {
const binding = new Binding(system);
const fd = binding.open('mock-dir', flags('r'));
assert.throws(function () {
binding.ftruncate(fd, 3);
});
});
it('fails if not open for writing', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
assert.throws(function () {
binding.ftruncate(fd, 4);
});
});
});
describe('#chown()', function () {
it('sets the uid and gid for a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
binding.chown(pathname, 3, 4);
const file = system.getItem(pathname);
assert.equal(file.getUid(), 3);
assert.equal(file.getGid(), 4);
});
it('sets the uid and gid for a directory', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'empty');
binding.chown(pathname, 5, 6);
const dir = system.getItem(pathname);
assert.equal(dir.getUid(), 5);
assert.equal(dir.getGid(), 6);
});
});
describe('#fchown()', function () {
it('sets the uid and gid for a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
binding.fchown(fd, 3, 4);
const file = system.getItem(pathname);
assert.equal(file.getUid(), 3);
assert.equal(file.getGid(), 4);
});
it('sets the uid and gid for a directory', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'empty');
const fd = binding.open(pathname, flags('r'));
binding.fchown(fd, 5, 6);
const dir = system.getItem(pathname);
assert.equal(dir.getUid(), 5);
assert.equal(dir.getGid(), 6);
});
});
describe('#chmod()', function () {
it('sets the mode for a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'two.txt');
binding.chmod(pathname, parseInt('0644', 8));
const file = system.getItem(pathname);
assert.equal(file.getMode(), parseInt('0644', 8));
});
it('sets the mode for a directory', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'empty');
binding.chmod(pathname, parseInt('0755', 8));
const dir = system.getItem(pathname);
assert.equal(dir.getMode(), parseInt('0755', 8));
});
});
describe('#fchmod()', function () {
it('sets the mode for a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
binding.fchmod(fd, parseInt('0664', 8));
const file = system.getItem(pathname);
assert.equal(file.getMode(), parseInt('0664', 8));
});
it('sets the mode for a directory', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'empty');
const fd = binding.open(pathname, flags('r'));
binding.fchmod(fd, parseInt('0775', 8));
const dir = system.getItem(pathname);
assert.equal(dir.getMode(), parseInt('0775', 8));
});
});
describe('#unlink()', function () {
it('deletes a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
binding.unlink(pathname);
assert.isNull(system.getItem(pathname));
});
it('fails for directory', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'empty');
assert.throws(function () {
binding.unlink(pathname);
});
});
it('fails for bogus path', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'bogus.txt');
assert.throws(function () {
binding.unlink(pathname);
});
});
});
describe('#utimes()', function () {
it('updates atime and mtime for a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
binding.utimes(pathname, 100, 200);
const item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 100 * 1000);
assert.equal(item.getMTime().getTime(), 200 * 1000);
});
it('updates atime and mtime for a directory', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'empty');
binding.utimes(pathname, 300, 400);
const item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 300 * 1000);
assert.equal(item.getMTime().getTime(), 400 * 1000);
});
it('fails for a bogus path', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'bogus.txt');
assert.throws(function () {
binding.utimes(pathname, 300, 400);
});
});
});
describe('#futimes()', function () {
it('updates atime and mtime for a file', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
binding.futimes(fd, 100, 200);
const item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 100 * 1000);
assert.equal(item.getMTime().getTime(), 200 * 1000);
});
it('updates atime and mtime for a directory', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'empty');
const fd = binding.open(pathname, flags('r'));
binding.futimes(fd, 300, 400);
const item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 300 * 1000);
assert.equal(item.getMTime().getTime(), 400 * 1000);
});
});
describe('#fsync()', function () {
it('synchronize file state (noop)', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
binding.fsync(fd);
});
it('fails for closed file descriptor', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
binding.close(fd);
assert.throws(function () {
binding.fsync(fd);
});
});
});
describe('#fdatasync()', function () {
it('synchronize file state (noop)', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
binding.fdatasync(fd);
});
it('fails for closed file descriptor', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one.txt');
const fd = binding.open(pathname, flags('r'));
binding.close(fd);
assert.throws(function () {
binding.fdatasync(fd);
});
});
});
describe('#link()', function () {
it('creates a link to a file', function () {
const binding = new Binding(system);
const source = path.join('mock-dir', 'one.txt');
const dest = path.join('mock-dir', 'link.txt');
binding.link(source, dest);
const link = system.getItem(dest);
assert.instanceOf(link, File);
assert.equal(String(link.getContent()), 'one content');
});
it('fails if dest exists', function () {
const binding = new Binding(system);
const source = path.join('mock-dir', 'one.txt');
const dest = path.join('mock-dir', 'two.txt');
assert.throws(function () {
binding.link(source, dest);
});
});
it('fails if source is directory', function () {
const binding = new Binding(system);
const source = path.join('mock-dir', 'empty');
const dest = path.join('mock-dir', 'link');
assert.throws(function () {
binding.link(source, dest);
});
});
});
describe('#symlink()', function () {
it('creates a symbolic link to a file', function () {
const binding = new Binding(system);
const source = path.join('.', 'one.txt');
const dest = path.join('mock-dir', 'link.txt');
binding.symlink(source, dest);
const link = system.getItem(dest);
assert.instanceOf(link, SymbolicLink);
assert.equal(link.getPath(), source);
});
it('fails if dest exists', function () {
const binding = new Binding(system);
const source = path.join('.', 'one.txt');
const dest = path.join('mock-dir', 'two.txt');
assert.throws(function () {
binding.symlink(source, dest);
});
});
it('works if source is directory', function () {
const binding = new Binding(system);
const source = path.join('mock-dir', 'empty');
const dest = path.join('mock-dir', 'link');
binding.symlink(source, dest);
const link = system.getItem(dest);
assert.instanceOf(link, SymbolicLink);
assert.equal(link.getPath(), source);
});
});
describe('#readlink()', function () {
it('reads the symbolic link', function () {
const binding = new Binding(system);
const srcPath = binding.readlink(path.join('mock-dir', 'one-link.txt'));
assert.equal(srcPath, './one.txt');
});
it('can return "buffer" encoding', function () {
const binding = new Binding(system);
const srcPath = binding.readlink(
path.join('mock-dir', 'one-link.txt'),
'buffer',
);
assert.equal(Buffer.isBuffer(srcPath), true);
assert.equal(srcPath.toString(), './one.txt');
});
it('fails for regular files', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.readlink(path.join('mock-dir', 'one.txt'));
}, /EINVAL/);
});
it('fails for directories', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.readlink(path.join('mock-dir', 'empty'));
}, /EINVAL/);
});
it('fails for bogus paths', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.readlink(path.join('mock-dir', 'bogus'));
}, /ENOENT/);
});
});
describe('#lstat()', function () {
it('stats symbolic links', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one-link.txt');
const stats = binding.lstat(pathname, false);
assert.equal(stats[1] & constants.S_IFMT, constants.S_IFLNK);
assert.equal(stats[8], binding.readlink(pathname).length);
});
});
describe('#access()', function () {
const originalGetuid = process.getuid;
const originalGetgid = process.getgid;
beforeEach(function () {
process.getuid = originalGetuid;
process.getgid = originalGetgid;
});
it('works if file exists', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'one-link.txt');
binding.access(pathname);
});
it('throws for dead link', function () {
const binding = new Binding(system);
const pathname = path.join('mock-dir', 'dead-link.txt');
assert.throws(function () {
binding.access(pathname);
}, /ENOENT/);
});
if (originalGetuid && originalGetgid) {
it('fails in case of insufficient user permissions', function () {
const binding = new Binding(system);
const item = system.getItem(path.join('mock-dir', 'one.txt'));
item.setMode(parseInt('0077', 8));
assert.throws(function () {
binding.access(path.join('mock-dir', 'one.txt'), 1);
}, /EACCES/);
});
it('fails in case of insufficient group permissions', function () {
const binding = new Binding(system);
const item = system.getItem(path.join('mock-dir', 'one.txt'));
item.setUid(process.getuid() + 1);
item.setMode(parseInt('0707', 8));
assert.throws(function () {
binding.access(path.join('mock-dir', 'one.txt'), 2);
}, /EACCES/);
});
it('fails in case of insufficient permissions', function () {
const binding = new Binding(system);
const item = system.getItem(path.join('mock-dir', 'one.txt'));
item.setUid(process.getuid() + 1);
item.setGid(process.getgid() + 1);
item.setMode(parseInt('0771', 8));
assert.throws(function () {
binding.access(path.join('mock-dir', 'one.txt'), 5);
}, /EACCES/);
});
it('sould not throw if process runs as root', function () {
const binding = new Binding(system);
const item = system.getItem(path.join('mock-dir', 'one.txt'));
item.setUid(42);
item.setGid(42);
item.setMode(parseInt('0000', 8));
process.getuid = () => 0;
binding.access(path.join('mock-dir', 'one.txt'), 5);
});
}
it('fails for bogus paths', function () {
const binding = new Binding(system);
assert.throws(function () {
binding.access(path.join('mock-dir', 'bogus'));
}, /ENOENT/);
});
});
});
mock-fs-5.5.0/test/lib/bypass.spec.js 0000664 0000000 0000000 00000005171 14751162414 0017406 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const {afterEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('mock.bypass()', () => {
afterEach(mock.restore);
it('runs a synchronous function using the real filesystem', () => {
mock({'/path/to/file': 'content'});
assert.equal(fs.readFileSync('/path/to/file', 'utf-8'), 'content');
assert.isNotOk(fs.existsSync(__filename));
assert.isOk(mock.bypass(() => fs.existsSync(__filename)));
assert.isNotOk(fs.existsSync(__filename));
});
it('handles functions that throw', () => {
mock({'/path/to/file': 'content'});
const error = new Error('oops');
assert.throws(() => {
mock.bypass(() => {
assert.isFalse(fs.existsSync('/path/to/file'));
throw error;
});
}, error);
assert.equal(fs.readFileSync('/path/to/file', 'utf8'), 'content');
});
it('bypasses patched process.cwd() and process.chdir()', () => {
const originalCwd = process.cwd();
mock({
dir: {},
});
process.chdir('dir');
assert.equal(process.cwd(), path.join(originalCwd, 'dir'));
mock.bypass(() => {
assert.equal(process.cwd(), originalCwd);
process.chdir('lib');
assert.equal(process.cwd(), path.join(originalCwd, 'lib'));
process.chdir('..');
assert.equal(process.cwd(), originalCwd);
});
assert.equal(process.cwd(), path.join(originalCwd, 'dir'));
mock.restore();
assert.equal(process.cwd(), originalCwd);
});
it('runs an async function using the real filesystem', (done) => {
mock({'/path/to/file': 'content'});
assert.equal(fs.readFileSync('/path/to/file', 'utf8'), 'content');
assert.isFalse(fs.existsSync(__filename));
mock
.bypass(() => fs.promises.stat(__filename))
.then((stat) => {
assert.isTrue(stat.isFile());
assert.isFalse(fs.existsSync(__filename));
done();
})
.catch(done);
});
it('handles promise rejection', (done) => {
mock({'/path/to/file': 'content'});
assert.equal(fs.readFileSync('/path/to/file', 'utf8'), 'content');
assert.isFalse(fs.existsSync(__filename));
const error = new Error('oops');
mock
.bypass(() => {
assert.isTrue(fs.existsSync(__filename));
return Promise.reject(error);
})
.then(() => {
done(new Error('should not succeed'));
})
.catch((err) => {
assert.equal(err, error);
assert.equal(fs.readFileSync('/path/to/file', 'utf8'), 'content');
done();
});
});
});
mock-fs-5.5.0/test/lib/descriptor.spec.js 0000664 0000000 0000000 00000031074 14751162414 0020264 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const {describe, it} = require('mocha');
const FileDescriptor = require('../../lib/descriptor.js');
const helper = require('../helper.js');
const assert = helper.assert;
const flags = helper.flags;
describe('FileDescriptor', function () {
describe('constructor', function () {
it('creates a new descriptor', function () {
const fd = new FileDescriptor(flags('r'));
assert.instanceOf(fd, FileDescriptor);
});
});
describe('#getPosition()', function () {
it('returns zero by default', function () {
const fd = new FileDescriptor(flags('r'));
assert.equal(fd.getPosition(), 0);
});
});
describe('#setPosition()', function () {
it('updates the position', function () {
const fd = new FileDescriptor(flags('r'));
fd.setPosition(10);
assert.equal(fd.getPosition(), 10);
});
});
describe('#isAppend()', function () {
it('not opened for appending (r)', function () {
const fd = new FileDescriptor(flags('r'));
assert.isFalse(fd.isAppend());
});
it('not opened for appending (r+)', function () {
const fd = new FileDescriptor(flags('r+'));
assert.isFalse(fd.isAppend());
});
it('not opened for appending (rs)', function () {
const fd = new FileDescriptor(flags('rs'));
assert.isFalse(fd.isAppend());
});
it('not opened for appending (rs+)', function () {
const fd = new FileDescriptor(flags('rs+'));
assert.isFalse(fd.isAppend());
});
it('not opened for appending (w)', function () {
const fd = new FileDescriptor(flags('w'));
assert.isFalse(fd.isAppend());
});
it('not opened for appending (wx)', function () {
const fd = new FileDescriptor(flags('wx'));
assert.isFalse(fd.isAppend());
});
it('not opened for appending (w+)', function () {
const fd = new FileDescriptor(flags('w+'));
assert.isFalse(fd.isAppend());
});
it('not opened for appending (wx+)', function () {
const fd = new FileDescriptor(flags('wx+'));
assert.isFalse(fd.isAppend());
});
it('opened for appending (a)', function () {
const fd = new FileDescriptor(flags('a'));
assert.isTrue(fd.isAppend());
});
it('opened for appending (ax)', function () {
const fd = new FileDescriptor(flags('ax'));
assert.isTrue(fd.isAppend());
});
it('opened for appending (a+)', function () {
const fd = new FileDescriptor(flags('a+'));
assert.isTrue(fd.isAppend());
});
it('opened for appending (ax+)', function () {
const fd = new FileDescriptor(flags('ax+'));
assert.isTrue(fd.isAppend());
});
it('not opened for appending (O_CREAT | O_RDONLY)', function () {
const fd = new FileDescriptor(constants.O_CREAT | constants.O_RDONLY);
assert.isFalse(fd.isAppend());
});
});
describe('#isTruncate()', function () {
it('not opened for truncating (r)', function () {
const fd = new FileDescriptor(flags('r'));
assert.isFalse(fd.isTruncate());
});
it('not opened for truncating (r+)', function () {
const fd = new FileDescriptor(flags('r+'));
assert.isFalse(fd.isTruncate());
});
it('not opened for truncating (rs)', function () {
const fd = new FileDescriptor(flags('rs'));
assert.isFalse(fd.isTruncate());
});
it('not opened for truncating (rs+)', function () {
const fd = new FileDescriptor(flags('rs+'));
assert.isFalse(fd.isTruncate());
});
it('opened for truncating (w)', function () {
const fd = new FileDescriptor(flags('w'));
assert.isTrue(fd.isTruncate());
});
it('opened for truncating (wx)', function () {
const fd = new FileDescriptor(flags('wx'));
assert.isTrue(fd.isTruncate());
});
it('opened for truncating (w+)', function () {
const fd = new FileDescriptor(flags('w+'));
assert.isTrue(fd.isTruncate());
});
it('opened for truncating (wx+)', function () {
const fd = new FileDescriptor(flags('wx+'));
assert.isTrue(fd.isTruncate());
});
it('not opened for truncating (a)', function () {
const fd = new FileDescriptor(flags('a'));
assert.isFalse(fd.isTruncate());
});
it('not opened for truncating (ax)', function () {
const fd = new FileDescriptor(flags('ax'));
assert.isFalse(fd.isTruncate());
});
it('not opened for truncating (a+)', function () {
const fd = new FileDescriptor(flags('a+'));
assert.isFalse(fd.isTruncate());
});
it('not opened for truncating (ax+)', function () {
const fd = new FileDescriptor(flags('ax+'));
assert.isFalse(fd.isTruncate());
});
it('not opened for truncating (O_CREAT | O_RDONLY)', function () {
const fd = new FileDescriptor(constants.O_CREAT | constants.O_RDONLY);
assert.isFalse(fd.isTruncate());
});
});
describe('#isCreate()', function () {
it('not opened for creation (r)', function () {
const fd = new FileDescriptor(flags('r'));
assert.isFalse(fd.isCreate());
});
it('not opened for creation (r+)', function () {
const fd = new FileDescriptor(flags('r+'));
assert.isFalse(fd.isCreate());
});
it('not opened for creation (rs)', function () {
const fd = new FileDescriptor(flags('rs'));
assert.isFalse(fd.isCreate());
});
it('not opened for creation (rs+)', function () {
const fd = new FileDescriptor(flags('rs+'));
assert.isFalse(fd.isCreate());
});
it('opened for creation (w)', function () {
const fd = new FileDescriptor(flags('w'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (wx)', function () {
const fd = new FileDescriptor(flags('wx'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (w+)', function () {
const fd = new FileDescriptor(flags('w+'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (wx+)', function () {
const fd = new FileDescriptor(flags('wx+'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (a)', function () {
const fd = new FileDescriptor(flags('a'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (ax)', function () {
const fd = new FileDescriptor(flags('ax'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (a+)', function () {
const fd = new FileDescriptor(flags('a+'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (ax+)', function () {
const fd = new FileDescriptor(flags('ax+'));
assert.isTrue(fd.isCreate());
});
it('opened for creation (O_CREAT | O_RDONLY)', function () {
const fd = new FileDescriptor(constants.O_CREAT | constants.O_RDONLY);
assert.isTrue(fd.isCreate());
});
});
describe('#isRead()', function () {
it('opened for reading (r)', function () {
const fd = new FileDescriptor(flags('r'));
assert.isTrue(fd.isRead());
});
it('opened for reading (r+)', function () {
const fd = new FileDescriptor(flags('r+'));
assert.isTrue(fd.isRead());
});
it('opened for reading (rs)', function () {
const fd = new FileDescriptor(flags('rs'));
assert.isTrue(fd.isRead());
});
it('opened for reading (rs+)', function () {
const fd = new FileDescriptor(flags('rs+'));
assert.isTrue(fd.isRead());
});
it('not opened for reading (w)', function () {
const fd = new FileDescriptor(flags('w'));
assert.isFalse(fd.isRead());
});
it('not opened for reading (wx)', function () {
const fd = new FileDescriptor(flags('wx'));
assert.isFalse(fd.isRead());
});
it('opened for reading (w+)', function () {
const fd = new FileDescriptor(flags('w+'));
assert.isTrue(fd.isRead());
});
it('opened for reading (wx+)', function () {
const fd = new FileDescriptor(flags('wx+'));
assert.isTrue(fd.isRead());
});
it('not opened for reading (a)', function () {
const fd = new FileDescriptor(flags('a'));
assert.isFalse(fd.isRead());
});
it('not opened for reading (ax)', function () {
const fd = new FileDescriptor(flags('ax'));
assert.isFalse(fd.isRead());
});
it('opened for reading (a+)', function () {
const fd = new FileDescriptor(flags('a+'));
assert.isTrue(fd.isRead());
});
it('opened for reading (ax+)', function () {
const fd = new FileDescriptor(flags('ax+'));
assert.isTrue(fd.isRead());
});
it('opened for reading (O_CREAT | O_RDONLY)', function () {
const fd = new FileDescriptor(constants.O_CREAT | constants.O_RDONLY);
assert.isTrue(fd.isRead());
});
});
describe('#isWrite()', function () {
it('not opened for writing (r)', function () {
const fd = new FileDescriptor(flags('r'));
assert.isFalse(fd.isWrite());
});
it('opened for writing (r+)', function () {
const fd = new FileDescriptor(flags('r+'));
assert.isTrue(fd.isWrite());
});
it('not opened for writing (rs)', function () {
const fd = new FileDescriptor(flags('rs'));
assert.isFalse(fd.isWrite());
});
it('opened for writing (rs+)', function () {
const fd = new FileDescriptor(flags('rs+'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (w)', function () {
const fd = new FileDescriptor(flags('w'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (wx)', function () {
const fd = new FileDescriptor(flags('wx'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (w+)', function () {
const fd = new FileDescriptor(flags('w+'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (wx+)', function () {
const fd = new FileDescriptor(flags('wx+'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (a)', function () {
const fd = new FileDescriptor(flags('a'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (ax)', function () {
const fd = new FileDescriptor(flags('ax'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (a+)', function () {
const fd = new FileDescriptor(flags('a+'));
assert.isTrue(fd.isWrite());
});
it('opened for writing (ax+)', function () {
const fd = new FileDescriptor(flags('ax+'));
assert.isTrue(fd.isWrite());
});
it('not opened for writing (O_CREAT | O_RDONLY)', function () {
const fd = new FileDescriptor(constants.O_CREAT | constants.O_RDONLY);
assert.isFalse(fd.isWrite());
});
});
describe('#isExclusive()', function () {
it('not opened exclusive (r)', function () {
const fd = new FileDescriptor(flags('r'));
assert.isFalse(fd.isExclusive());
});
it('not opened exclusive (r+)', function () {
const fd = new FileDescriptor(flags('r+'));
assert.isFalse(fd.isExclusive());
});
it('not opened exclusive (rs)', function () {
const fd = new FileDescriptor(flags('rs'));
assert.isFalse(fd.isExclusive());
});
it('not opened exclusive (rs+)', function () {
const fd = new FileDescriptor(flags('rs+'));
assert.isFalse(fd.isExclusive());
});
it('not opened exclusive (w)', function () {
const fd = new FileDescriptor(flags('w'));
assert.isFalse(fd.isExclusive());
});
it('opened exclusive (wx)', function () {
const fd = new FileDescriptor(flags('wx'));
assert.isTrue(fd.isExclusive());
});
it('not opened exclusive (w+)', function () {
const fd = new FileDescriptor(flags('w+'));
assert.isFalse(fd.isExclusive());
});
it('opened exclusive (wx+)', function () {
const fd = new FileDescriptor(flags('wx+'));
assert.isTrue(fd.isExclusive());
});
it('not opened exclusive (a)', function () {
const fd = new FileDescriptor(flags('a'));
assert.isFalse(fd.isExclusive());
});
it('opened exclusive (ax)', function () {
const fd = new FileDescriptor(flags('ax'));
assert.isTrue(fd.isExclusive());
});
it('not opened exclusive (a+)', function () {
const fd = new FileDescriptor(flags('a+'));
assert.isFalse(fd.isExclusive());
});
it('opened exclusive (ax+)', function () {
const fd = new FileDescriptor(flags('ax+'));
assert.isTrue(fd.isExclusive());
});
it('not opened for exclusive (O_CREAT | O_RDONLY)', function () {
const fd = new FileDescriptor(constants.O_CREAT | constants.O_RDONLY);
assert.isFalse(fd.isExclusive());
});
});
});
mock-fs-5.5.0/test/lib/directory.spec.js 0000664 0000000 0000000 00000007200 14751162414 0020104 0 ustar 00root root 0000000 0000000 const {describe, it} = require('mocha');
const Directory = require('../../lib/directory.js');
const File = require('../../lib/file.js');
const Item = require('../../lib/item.js');
const assert = require('../helper.js').assert;
describe('Directory', function () {
describe('constructor', function () {
it('creates a named directory', function () {
const dir = new Directory();
assert.instanceOf(dir, Directory);
assert.instanceOf(dir, Item);
});
});
describe('#addItem()', function () {
it('allows a directory to be added', function () {
const parent = new Directory();
const child = new Directory();
parent.addItem('child', child);
assert.equal(parent.getItem('child'), child);
});
it('allows a file to be added', function () {
const parent = new Directory();
const child = new File();
parent.addItem('child', child);
assert.equal(parent.getItem('child'), child);
});
it('returns the added item', function () {
const parent = new Directory();
const child = new File();
const got = parent.addItem('child', child);
assert.equal(got, child);
});
});
describe('#getItem()', function () {
it('retrieves a named directory', function () {
const parent = new Directory();
const child = new Directory();
parent.addItem('child', child);
assert.equal(parent.getItem('child'), child);
});
it('retrieves a named file', function () {
const parent = new Directory();
const child = new File();
parent.addItem('child', child);
assert.equal(parent.getItem('child'), child);
});
it('returns null for missing item', function () {
const parent = new Directory();
const child = new File();
parent.addItem('child', child);
assert.isNull(parent.getItem('kid'));
});
});
describe('#removeItem()', function () {
it('allows a directory to be removed', function () {
const parent = new Directory();
const child = new Directory();
parent.addItem('child', child);
const removed = parent.removeItem('child');
assert.equal(removed, child);
assert.isNull(parent.getItem('child'));
});
it('allows a file to be removed', function () {
const parent = new Directory();
const child = new File();
parent.addItem('child', child);
const removed = parent.removeItem('child');
assert.equal(removed, child);
assert.isNull(parent.getItem('child'));
});
it('throws if item is not a child', function () {
const parent = new Directory();
parent.addItem('one', new Directory());
parent.addItem('two', new File());
assert.throws(function () {
parent.removeItem('three');
});
});
});
describe('#list()', function () {
it('lists all items in a directory', function () {
const dir = new Directory();
dir.addItem('one file', new File());
dir.addItem('another file', new File());
dir.addItem('a directory', new Directory());
dir.addItem('another directory', new Directory());
const list = dir.list();
assert.deepEqual(list.sort(), [
'a directory',
'another directory',
'another file',
'one file',
]);
});
it('works for empty dir', function () {
const dir = new Directory();
assert.deepEqual(dir.list(), []);
});
it('lists one level deep', function () {
const d0 = new Directory();
const d1 = new Directory();
const d2 = new Directory();
d1.addItem('d2', d2);
d0.addItem('d1', d1);
assert.deepEqual(d0.list(), ['d1']);
});
});
});
mock-fs-5.5.0/test/lib/encoding.spec.js 0000664 0000000 0000000 00000002036 14751162414 0017670 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
const CHARS = [
// // 1 utf-16, 1 utf-8 byte
'A',
// 1 utf-16 code unit, 3 utf-8 bytes
'’',
// // 2 utf-16 code units, 4 utf-8 bytes
'😄',
];
const ENCODINGS = ['utf8', 'utf16le', 'latin1'];
for (const encoding of ENCODINGS) {
for (const char of CHARS) {
describe(`Encoding (${encoding} ${char})`, () => {
const buffer = Buffer.from(char, encoding);
beforeEach(() => mock());
afterEach(() => mock.restore());
beforeEach(() => fs.writeFileSync('file', char, {encoding}));
it(`writes ${buffer.length} bytes`, () => {
assert.strictEqual(fs.statSync('file').size, buffer.length);
});
it('reads the written value (buffer)', () => {
const out = fs.readFileSync('file');
assert.sameOrderedMembers(Array.from(out), Array.from(buffer));
});
});
}
}
mock-fs-5.5.0/test/lib/file.spec.js 0000664 0000000 0000000 00000003775 14751162414 0017034 0 ustar 00root root 0000000 0000000 const {describe, it} = require('mocha');
const File = require('../../lib/file.js');
const Item = require('../../lib/item.js');
const assert = require('../helper.js').assert;
describe('File', function () {
describe('constructor', function () {
it('creates a named file', function () {
const file = new File();
assert.instanceOf(file, File);
assert.instanceOf(file, Item);
});
});
describe('#getContent()', function () {
it('gets the file content', function () {
const file = new File();
const content = Buffer.from('bar');
file.setContent(content);
assert.equal(file.getContent(), content);
});
it('is initially empty', function () {
const file = new File();
assert.equal(String(file.getContent()), '');
});
it('updates the atime', function () {
const file = new File();
file.setContent('bar');
const old = new Date(1);
file.setATime(old);
file.getContent();
assert.isTrue(file.getATime() > old);
});
});
describe('#setContent()', function () {
it('accepts a string', function () {
const file = new File();
file.setContent('bar');
const content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'bar');
});
it('accepts a buffer', function () {
const file = new File();
file.setContent(Buffer.from('baz'));
const content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'baz');
});
it('throws for other types', function () {
assert.throws(function () {
const file = new File();
file.setContent(123);
});
});
it('updates the ctime and mtime', function () {
const file = new File();
const old = new Date(1);
file.setCTime(old);
file.setMTime(old);
file.setContent('bar');
assert.isTrue(file.getCTime() > old);
assert.isTrue(file.getMTime() > old);
});
});
});
mock-fs-5.5.0/test/lib/filesystem.spec.js 0000664 0000000 0000000 00000024015 14751162414 0020267 0 ustar 00root root 0000000 0000000 const os = require('os');
const path = require('path');
const {describe, it} = require('mocha');
const Directory = require('../../lib/directory.js');
const File = require('../../lib/file.js');
const FileSystem = require('../../lib/filesystem.js');
const assert = require('../helper.js').assert;
describe('FileSystem', function () {
describe('constructor', function () {
it('creates a new instance', function () {
const system = new FileSystem();
assert.instanceOf(system, FileSystem);
});
it('accepts a createCwd option', function () {
const cwd = process.cwd();
const withCwd = new FileSystem({createCwd: true});
const withoutCwd = new FileSystem({createCwd: false});
assert.instanceOf(withCwd.getItem(cwd), Directory);
assert.isNull(withoutCwd.getItem(cwd));
});
it('accepts a createTmp option', function () {
const tmp = os.tmpdir ? os.tmpdir() : os.tmpDir();
const withTmp = new FileSystem({createTmp: true});
const withoutTmp = new FileSystem({createTmp: false});
assert.instanceOf(withTmp.getItem(tmp), Directory);
assert.isNull(withoutTmp.getItem(tmp));
});
});
describe('#getRoot()', function () {
it('gets the root directory', function () {
const system = new FileSystem();
assert.instanceOf(system.getRoot(), Directory);
});
});
describe('#getItem() #getFilepath()', function () {
it('gets an item', function () {
const system = FileSystem.create({
'one/two/three.js': 'contents',
});
const filepath = path.join('one', 'two', 'three.js');
const item = system.getItem(filepath);
assert.instanceOf(item, File);
assert.equal(system.getFilepath(item), path.resolve(filepath));
});
it('returns null if not found', function () {
const system = FileSystem.create({
'one/two/three.js': 'contents',
});
assert.isNull(system.getItem(path.join('one', 'two', 'four.js')));
assert.isNull(system.getItem(path.join('one', '2', 'three.js')));
assert.isNull(system.getItem(path.join('um', 'two', 'three.js')));
});
it('gets an item traversing links to symbolic links', function () {
const system = FileSystem.create({
'dir-link': FileSystem.symlink({path: './b/dir-link2'}),
b: {
'dir-link2': FileSystem.symlink({path: './c/dir'}),
c: {
dir: {
a: 'file a',
b: {
c: 'file c',
d: 'file d',
},
},
},
},
});
const file = system.getItem(path.join('dir-link', 'a'));
assert.instanceOf(file, File);
assert.equal(
system.getFilepath(file),
path.resolve(path.join('b', 'c', 'dir', 'a')),
);
const dir = system.getItem(path.join('dir-link', 'b'));
assert.instanceOf(dir, Directory);
assert.deepEqual(dir.list().sort(), ['c', 'd']);
assert.equal(
system.getFilepath(dir),
path.resolve(path.join('b', 'c', 'dir', 'b')),
);
});
});
});
describe('FileSystem.file', function () {
it('creates a factory for files', function () {
const factory = FileSystem.file();
assert.isFunction(factory);
const file = factory();
assert.instanceOf(file, File);
});
it('accepts a content member', function () {
const factory = FileSystem.file({content: 'foo'});
assert.isFunction(factory);
const file = factory();
assert.instanceOf(file, File);
const content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'foo');
});
});
describe('FileSystem.directory', function () {
it('creates a factory for directories', function () {
const factory = FileSystem.directory();
assert.isFunction(factory);
const dir = factory();
assert.instanceOf(dir, Directory);
});
});
describe('FileSystem.create', function () {
it('provides a convenient way to populate a file system', function () {
const system = FileSystem.create({
'path/to/one': {
'file.js': 'file.js content',
dir: {},
},
'path/to/two.js': 'two.js content',
'path/to/three': {},
});
assert.instanceOf(system, FileSystem);
let filepath, item;
// confirm 'path/to/one' directory was created
filepath = path.join('path', 'to', 'one');
item = system.getItem(filepath);
assert.instanceOf(item, Directory);
assert.deepEqual(item.list().sort(), ['dir', 'file.js']);
// confirm 'path/to/one/file.js' file was created
filepath = path.join('path', 'to', 'one', 'file.js');
item = system.getItem(filepath);
assert.instanceOf(item, File);
assert.equal(String(item.getContent()), 'file.js content');
// confirm 'path/to/one/dir' directory was created
filepath = path.join('path', 'to', 'one', 'dir');
item = system.getItem(filepath);
assert.instanceOf(item, Directory);
assert.deepEqual(item.list(), []);
// confirm 'path/to/two.js' file was created
filepath = path.join('path', 'to', 'two.js');
item = system.getItem(filepath);
assert.instanceOf(item, File);
assert.equal(String(item.getContent()), 'two.js content');
// confirm 'path/to/three' directory was created
filepath = path.join('path', 'to', 'three');
item = system.getItem(filepath);
assert.instanceOf(item, Directory);
assert.deepEqual(item.list(), []);
});
it('passes options to the FileSystem constructor', function () {
const cwd = process.cwd();
const tmp = os.tmpdir ? os.tmpdir() : os.tmpDir();
const withoutCwd = FileSystem.create({}, {createCwd: false});
const withoutTmp = FileSystem.create({}, {createTmp: false});
assert.isNull(withoutCwd.getItem(cwd));
assert.instanceOf(withoutCwd.getItem(tmp), Directory);
assert.isNull(withoutTmp.getItem(tmp));
assert.instanceOf(withoutTmp.getItem(cwd), Directory);
});
it('accepts file factory', function () {
const system = FileSystem.create({
'path/to/file.js': FileSystem.file({content: 'foo'}),
});
assert.instanceOf(system, FileSystem);
const file = system.getItem(path.join('path', 'to', 'file.js'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'foo');
});
it('accepts file factory with uid & gid', function () {
const system = FileSystem.create({
'path/to/file.js': FileSystem.file({
content: 'foo',
uid: 42,
gid: 43,
}),
});
assert.instanceOf(system, FileSystem);
const file = system.getItem(path.join('path', 'to', 'file.js'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'foo');
assert.equal(file.getUid(), 42);
assert.equal(file.getGid(), 43);
});
it('accepts directory factory', function () {
const system = FileSystem.create({
'path/to/dir': FileSystem.directory(),
});
assert.instanceOf(system, FileSystem);
const dir = system.getItem(path.join('path', 'to', 'dir'));
assert.instanceOf(dir, Directory);
});
it('accepts directory factory with uid & gid', function () {
const system = FileSystem.create({
'path/to/dir': FileSystem.directory({
uid: 42,
gid: 43,
}),
});
assert.instanceOf(system, FileSystem);
const dir = system.getItem(path.join('path', 'to', 'dir'));
assert.instanceOf(dir, Directory);
assert.equal(dir.getUid(), 42);
assert.equal(dir.getGid(), 43);
});
it('accepts directory factory with additional items', function () {
const system = FileSystem.create({
'path/to/dir': FileSystem.directory({
mode: parseInt('0755', 8),
items: {
'file.txt': 'file content',
'empty-dir': {},
},
}),
});
assert.instanceOf(system, FileSystem);
const dir = system.getItem(path.join('path', 'to', 'dir'));
assert.instanceOf(dir, Directory);
assert.equal(dir.getMode(), parseInt('0755', 8));
const file = system.getItem(path.join('path', 'to', 'dir', 'file.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'file content');
const empty = system.getItem(path.join('path', 'to', 'dir', 'empty-dir'));
assert.instanceOf(empty, Directory);
assert.deepEqual(empty.list(), []);
});
it('correctly generates link counts', function () {
const system = FileSystem.create({
'/dir-a.0': {
'dir-b.0': {
'dir-c.0': {},
'dir-c.1': {},
'file-c.0': 'content',
'file-c.1': 'content',
'symlink-c.0': FileSystem.symlink({path: 'file-c.0'}),
},
},
});
/**
* 3 links: /dir-a.0, /dir-a.0/., and /dir-a.0/dir-b.0/..
*/
assert.equal(system.getItem('/dir-a.0').links, 3);
/**
* 4 links: /dir-a.0/dir-b.0, /dir-a.0/dir-b.0/.,
* /dir-a.0/dir-b.0/dir-c.0/.., and /dir-a.0/dir-b.0/dir-c.1/..
*/
assert.equal(system.getItem('/dir-a.0/dir-b.0').links, 4);
/**
* 2 links: /dir-a.0/dir-b.0/dir-c.0 and /dir-a.0/dir-b.0/dir-c.0/.
*/
assert.equal(system.getItem('/dir-a.0/dir-b.0/dir-c.0').links, 2);
/**
* 2 links: /dir-a.0/dir-b.0/dir-c.0 and /dir-a.0/dir-b.0/dir-c.0/.
*/
assert.equal(system.getItem('/dir-a.0/dir-b.0/dir-c.0').links, 2);
/**
* 1 link: /dir-a.0/dir-b.0/file-c.0
*/
assert.equal(system.getItem('/dir-a.0/dir-b.0/file-c.0').links, 1);
/**
* 1 link: /dir-a.0/dir-b.0/file-c.1
*/
assert.equal(system.getItem('/dir-a.0/dir-b.0/file-c.1').links, 1);
/**
* 1 link: /dir-a.0/dir-b.0/symlink-c.0
*/
assert.equal(system.getItem('/dir-a.0/dir-b.0/symlink-c.0').links, 1);
});
it('throws if item content is not valid type', function () {
assert.throws(function () {
FileSystem.create({
'/dir-a.0': {
'dir-b.0': {
'file-c.0': undefined,
},
},
});
});
assert.throws(function () {
FileSystem.create({
'/dir-a.0': {
'dir-b.0': {
'file-c.0': 123,
},
},
});
});
});
});
mock-fs-5.5.0/test/lib/fs.access.spec.js 0000664 0000000 0000000 00000050453 14751162414 0017760 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
if (process.getuid && process.getgid) {
// TODO: figure out how fs.access() works on Windows (without gid/uid)
describe('fs.access(path[, mode], callback)', function () {
beforeEach(function () {
mock({
'path/to/accessible/file': 'can access',
'path/to/000': mock.file({
mode: parseInt('0000', 8),
content: 'no permissions',
}),
'path/to/111': mock.file({
mode: parseInt('0111', 8),
content: 'execute only',
}),
'path/to/write/only': mock.file({
mode: parseInt('0222', 8),
content: 'write only',
}),
'path/to/333': mock.file({
mode: parseInt('0333', 8),
content: 'write and execute',
}),
'path/to/444': mock.file({
mode: parseInt('0444', 8),
content: 'read only',
}),
'path/to/555': mock.file({
mode: parseInt('0555', 8),
content: 'read and execute',
}),
'path/to/666': mock.file({
mode: parseInt('0666', 8),
content: 'read and write',
}),
'path/to/777': mock.file({
mode: parseInt('0777', 8),
content: 'read, write, and execute',
}),
unreadable: mock.directory({
mode: parseInt('0000', 8),
items: {
'readable-child': mock.file({
mode: parseInt('0777', 8),
content: 'read, write, and execute',
}),
},
}),
});
});
afterEach(mock.restore);
it('works for an accessible file', function (done) {
fs.access('path/to/accessible/file', done);
});
it('supports Buffer input', function (done) {
fs.access(Buffer.from('path/to/accessible/file'), done);
});
it('promise works for an accessible file', function (done) {
fs.promises.access('path/to/accessible/file').then(done, done);
});
it('works 000 (and no mode arg)', function (done) {
fs.access('path/to/000', done);
});
it('promise works 000 (and no mode arg)', function (done) {
fs.promises.access('path/to/000').then(done, done);
});
it('works F_OK and 000', function (done) {
fs.access('path/to/000', fs.F_OK, done);
});
it('promise works F_OK and 000', function (done) {
fs.promises.access('path/to/000', fs.F_OK).then(done, done);
});
it('generates EACCES for R_OK and 000', function (done) {
fs.access('path/to/000', fs.R_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for R_OK and 000', function (done) {
fs.promises.access('path/to/000', fs.R_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('generates EACCES for W_OK and 000', function (done) {
fs.access('path/to/000', fs.W_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for W_OK and 000', function (done) {
fs.promises.access('path/to/000', fs.W_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('generates EACCES for X_OK and 000', function (done) {
fs.access('path/to/000', fs.X_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for X_OK and 000', function (done) {
fs.promises.access('path/to/000', fs.X_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('works 111 (and no mode arg)', function (done) {
fs.access('path/to/111', done);
});
it('promise works 111 (and no mode arg)', function (done) {
fs.promises.access('path/to/111').then(done, done);
});
it('works F_OK and 111', function (done) {
fs.access('path/to/111', fs.F_OK, done);
});
it('promise works F_OK and 111', function (done) {
fs.promises.access('path/to/111', fs.F_OK).then(done, done);
});
it('works X_OK and 111', function (done) {
fs.access('path/to/111', fs.X_OK, done);
});
it('promise works X_OK and 111', function (done) {
fs.promises.access('path/to/111', fs.X_OK).then(done, done);
});
it('generates EACCES for R_OK and 111', function (done) {
fs.access('path/to/111', fs.R_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for R_OK and 111', function (done) {
fs.promises.access('path/to/111', fs.R_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('generates EACCES for W_OK and 111', function (done) {
fs.access('path/to/111', fs.W_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for W_OK and 111', function (done) {
fs.promises.access('path/to/111', fs.W_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('works for 222 (and no mode arg)', function (done) {
fs.access('path/to/write/only', done);
});
it('promise works for 222 (and no mode arg)', function (done) {
fs.promises.access('path/to/write/only').then(done, done);
});
it('works F_OK and 222', function (done) {
fs.access('path/to/write/only', fs.F_OK, done);
});
it('promise works F_OK and 222', function (done) {
fs.promises.access('path/to/write/only', fs.F_OK).then(done, done);
});
it('works W_OK and 222', function (done) {
fs.access('path/to/write/only', fs.W_OK, done);
});
it('promise works W_OK and 222', function (done) {
fs.promises.access('path/to/write/only', fs.W_OK).then(done, done);
});
it('generates EACCES for R_OK and 222', function (done) {
fs.access('path/to/write/only', fs.R_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for R_OK and 222', function (done) {
fs.promises.access('path/to/write/only', fs.R_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('generates EACCES for X_OK and 222', function (done) {
fs.access('path/to/write/only', fs.X_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for X_OK and 222', function (done) {
fs.promises.access('path/to/write/only', fs.X_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('works for 333 (and no mode arg)', function (done) {
fs.access('path/to/333', done);
});
it('promise works for 333 (and no mode arg)', function (done) {
fs.promises.access('path/to/333').then(done, done);
});
it('works F_OK and 333', function (done) {
fs.access('path/to/333', fs.F_OK, done);
});
it('promise works F_OK and 333', function (done) {
fs.promises.access('path/to/333', fs.F_OK).then(done, done);
});
it('works W_OK and 333', function (done) {
fs.access('path/to/333', fs.W_OK, done);
});
it('promise works W_OK and 333', function (done) {
fs.promises.access('path/to/333', fs.W_OK).then(done, done);
});
it('works X_OK and 333', function (done) {
fs.access('path/to/333', fs.X_OK, done);
});
it('promise works X_OK and 333', function (done) {
fs.promises.access('path/to/333', fs.X_OK).then(done, done);
});
it('works X_OK | W_OK and 333', function (done) {
fs.access('path/to/333', fs.X_OK | fs.W_OK, done);
});
it('promise works X_OK | W_OK and 333', function (done) {
fs.promises.access('path/to/333', fs.X_OK | fs.W_OK).then(done, done);
});
it('generates EACCES for R_OK and 333', function (done) {
fs.access('path/to/333', fs.R_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for R_OK and 333', function (done) {
fs.promises.access('path/to/333', fs.R_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('works for 444 (and no mode arg)', function (done) {
fs.access('path/to/444', done);
});
it('promise works for 444 (and no mode arg)', function (done) {
fs.promises.access('path/to/444').then(done, done);
});
it('works F_OK and 444', function (done) {
fs.access('path/to/444', fs.F_OK, done);
});
it('promise works F_OK and 444', function (done) {
fs.promises.access('path/to/444', fs.F_OK).then(done, done);
});
it('works R_OK and 444', function (done) {
fs.access('path/to/444', fs.R_OK, done);
});
it('promise works R_OK and 444', function (done) {
fs.promises.access('path/to/444', fs.R_OK).then(done, done);
});
it('generates EACCES for W_OK and 444', function (done) {
fs.access('path/to/444', fs.W_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for W_OK and 444', function (done) {
fs.promises.access('path/to/444', fs.W_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('generates EACCES for X_OK and 444', function (done) {
fs.access('path/to/444', fs.X_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for X_OK and 444', function (done) {
fs.promises.access('path/to/444', fs.X_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('works for 555 (and no mode arg)', function (done) {
fs.access('path/to/555', done);
});
it('promise works for 555 (and no mode arg)', function (done) {
fs.promises.access('path/to/555').then(done, done);
});
it('works F_OK and 555', function (done) {
fs.access('path/to/555', fs.F_OK, done);
});
it('promise works F_OK and 555', function (done) {
fs.promises.access('path/to/555', fs.F_OK).then(done, done);
});
it('works R_OK and 555', function (done) {
fs.access('path/to/555', fs.R_OK, done);
});
it('promise works R_OK and 555', function (done) {
fs.promises.access('path/to/555', fs.R_OK).then(done, done);
});
it('works X_OK and 555', function (done) {
fs.access('path/to/555', fs.X_OK, done);
});
it('promise works X_OK and 555', function (done) {
fs.promises.access('path/to/555', fs.X_OK).then(done, done);
});
it('works R_OK | X_OK and 555', function (done) {
fs.access('path/to/555', fs.R_OK | fs.X_OK, done);
});
it('promise works R_OK | X_OK and 555', function (done) {
fs.promises.access('path/to/555', fs.R_OK | fs.X_OK).then(done, done);
});
it('generates EACCES for W_OK and 555', function (done) {
fs.access('path/to/555', fs.W_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for W_OK and 555', function (done) {
fs.promises.access('path/to/555', fs.W_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('works for 666 (and no mode arg)', function (done) {
fs.access('path/to/666', done);
});
it('promise works for 666 (and no mode arg)', function (done) {
fs.promises.access('path/to/666').then(done, done);
});
it('works F_OK and 666', function (done) {
fs.access('path/to/666', fs.F_OK, done);
});
it('promise works F_OK and 666', function (done) {
fs.promises.access('path/to/666', fs.F_OK).then(done, done);
});
it('works R_OK and 666', function (done) {
fs.access('path/to/666', fs.R_OK, done);
});
it('promise works R_OK and 666', function (done) {
fs.promises.access('path/to/666', fs.R_OK).then(done, done);
});
it('works W_OK and 666', function (done) {
fs.access('path/to/666', fs.W_OK, done);
});
it('promise works W_OK and 666', function (done) {
fs.promises.access('path/to/666', fs.W_OK).then(done, done);
});
it('works R_OK | W_OK and 666', function (done) {
fs.access('path/to/666', fs.R_OK | fs.W_OK, done);
});
it('promise works R_OK | W_OK and 666', function (done) {
fs.promises.access('path/to/666', fs.R_OK | fs.W_OK).then(done, done);
});
it('generates EACCES for X_OK and 666', function (done) {
fs.access('path/to/666', fs.X_OK, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCES for X_OK and 666', function (done) {
fs.promises.access('path/to/666', fs.X_OK).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('works for 777 (and no mode arg)', function (done) {
fs.access('path/to/777', done);
});
it('promise works for 777 (and no mode arg)', function (done) {
fs.promises.access('path/to/777').then(done, done);
});
it('works F_OK and 777', function (done) {
fs.access('path/to/777', fs.F_OK, done);
});
it('promise works F_OK and 777', function (done) {
fs.promises.access('path/to/777', fs.F_OK).then(done, done);
});
it('works R_OK and 777', function (done) {
fs.access('path/to/777', fs.R_OK, done);
});
it('promise works R_OK and 777', function (done) {
fs.promises.access('path/to/777', fs.R_OK).then(done, done);
});
it('works W_OK and 777', function (done) {
fs.access('path/to/777', fs.W_OK, done);
});
it('promise works W_OK and 777', function (done) {
fs.promises.access('path/to/777', fs.W_OK).then(done, done);
});
it('works X_OK and 777', function (done) {
fs.access('path/to/777', fs.X_OK, done);
});
it('promise works X_OK and 777', function (done) {
fs.promises.access('path/to/777', fs.X_OK).then(done, done);
});
it('works X_OK | W_OK and 777', function (done) {
fs.access('path/to/777', fs.X_OK | fs.W_OK, done);
});
it('promise works X_OK | W_OK and 777', function (done) {
fs.promises.access('path/to/777', fs.X_OK | fs.W_OK).then(done, done);
});
it('works X_OK | R_OK and 777', function (done) {
fs.access('path/to/777', fs.X_OK | fs.R_OK, done);
});
it('promise works X_OK | R_OK and 777', function (done) {
fs.promises.access('path/to/777', fs.X_OK | fs.R_OK).then(done, done);
});
it('works R_OK | W_OK and 777', function (done) {
fs.access('path/to/777', fs.R_OK | fs.W_OK, done);
});
it('promise works R_OK | W_OK and 777', function (done) {
fs.promises.access('path/to/777', fs.R_OK | fs.W_OK).then(done, done);
});
it('works R_OK | W_OK | X_OK and 777', function (done) {
fs.access('path/to/777', fs.R_OK | fs.W_OK | fs.X_OK, done);
});
it('promise works R_OK | W_OK | X_OK and 777', function (done) {
fs.promises
.access('path/to/777', fs.R_OK | fs.W_OK | fs.X_OK)
.then(done, done);
});
it('generates EACCESS for F_OK and an unreadable parent', function (done) {
fs.access('unreadable/readable-child', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise generates EACCESS for F_OK and an unreadable parent', function (done) {
fs.promises.access('unreadable/readable-child').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
});
describe('fs.accessSync(path[, mode])', function () {
beforeEach(function () {
mock({
'path/to/777': mock.file({
mode: parseInt('0777', 8),
content: 'all access',
}),
'path/to/000': mock.file({
mode: parseInt('0000', 8),
content: 'no permissions',
}),
'broken-link': mock.symlink({path: './path/to/nothing'}),
'circular-link': mock.symlink({path: './loop-link'}),
'loop-link': mock.symlink({path: './circular-link'}),
});
});
afterEach(mock.restore);
it('works for an accessible file', function () {
fs.accessSync('path/to/777');
fs.accessSync('path/to/777', fs.F_OK);
fs.accessSync('path/to/777', fs.X_OK);
fs.accessSync('path/to/777', fs.W_OK);
fs.accessSync('path/to/777', fs.X_OK | fs.W_OK);
fs.accessSync('path/to/777', fs.R_OK);
fs.accessSync('path/to/777', fs.X_OK | fs.R_OK);
fs.accessSync('path/to/777', fs.W_OK | fs.R_OK);
fs.accessSync('path/to/777', fs.X_OK | fs.W_OK | fs.R_OK);
});
it('throws EACCESS for broken link', function () {
assert.throws(function () {
fs.accessSync('broken-link');
});
});
it('throws ELOOP for circular link', function () {
assert.throws(function () {
fs.accessSync('circular-link');
});
});
it('throws EACCESS for all but F_OK for 000', function () {
fs.accessSync('path/to/000');
assert.throws(function () {
fs.accessSync('path/to/000', fs.X_OK);
});
assert.throws(function () {
fs.accessSync('path/to/000', fs.W_OK);
});
assert.throws(function () {
fs.accessSync('path/to/000', fs.X_OK | fs.W_OK);
});
assert.throws(function () {
fs.accessSync('path/to/000', fs.R_OK);
});
assert.throws(function () {
fs.accessSync('path/to/000', fs.X_OK | fs.R_OK);
});
assert.throws(function () {
fs.accessSync('path/to/000', fs.W_OK | fs.R_OK);
});
assert.throws(function () {
fs.accessSync('path/to/000', fs.X_OK | fs.W_OK | fs.R_OK);
});
});
});
}
mock-fs-5.5.0/test/lib/fs.appendFile.spec.js 0000664 0000000 0000000 00000007554 14751162414 0020572 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.appendFile(filename, data, [options], callback)', function () {
beforeEach(function () {
mock({
'dir/file.txt': 'file content',
'link.txt': mock.symlink({path: 'dir/file.txt'}),
});
});
afterEach(mock.restore);
it('writes a string to a new file', function (done) {
fs.appendFile('foo', 'bar', function (err) {
if (err) {
return done(err);
}
assert.equal(String(fs.readFileSync('foo')), 'bar');
done();
});
});
it('promise writes a string to a new file', function (done) {
fs.promises
.appendFile('foo', 'bar')
.then(function () {
assert.equal(String(fs.readFileSync('foo')), 'bar');
done();
})
.catch(done);
});
it('appends a string to an existing file', function (done) {
fs.appendFile('dir/file.txt', ' bar', function (err) {
if (err) {
return done(err);
}
assert.equal(String(fs.readFileSync('dir/file.txt')), 'file content bar');
done();
});
});
it('promise appends a string to an existing file', function (done) {
fs.promises
.appendFile('dir/file.txt', ' bar')
.then(function () {
assert.equal(
String(fs.readFileSync('dir/file.txt')),
'file content bar',
);
done();
})
.catch(done);
});
it('appends a buffer to a file', function (done) {
fs.appendFile('dir/file.txt', Buffer.from(' bar'), function (err) {
if (err) {
return done(err);
}
assert.equal(String(fs.readFileSync('dir/file.txt')), 'file content bar');
done();
});
});
it('promise appends a buffer to a file', function (done) {
fs.promises
.appendFile('dir/file.txt', Buffer.from(' bar'))
.then(function () {
assert.equal(
String(fs.readFileSync('dir/file.txt')),
'file content bar',
);
done();
})
.catch(done);
});
it('appends via a symbolic link file', function (done) {
fs.appendFile('link.txt', ' bar', function (err) {
if (err) {
return done(err);
}
assert.equal(String(fs.readFileSync('dir/file.txt')), 'file content bar');
done();
});
});
it('promise appends via a symbolic link file', function (done) {
fs.promises
.appendFile('link.txt', ' bar')
.then(function () {
assert.equal(
String(fs.readFileSync('dir/file.txt')),
'file content bar',
);
done();
})
.catch(done);
});
it('fails if directory does not exist', function (done) {
fs.appendFile('foo/bar', 'baz', function (err) {
assert.instanceOf(err, Error);
done();
});
});
it('promise fails if directory does not exist', function (done) {
fs.promises.appendFile('foo/bar', 'baz').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.appendFileSync(filename, data, [options]', function () {
beforeEach(function () {
mock({
'path/to/file': 'content',
});
});
afterEach(mock.restore);
it('writes a string to a new file', function () {
fs.appendFileSync('foo', 'bar');
assert.equal(String(fs.readFileSync('foo')), 'bar');
});
it('appends a string to an existing file', function () {
fs.appendFileSync('path/to/file', ' bar');
assert.equal(String(fs.readFileSync('path/to/file')), 'content bar');
});
it('fails if directory does not exist', function () {
assert.throws(function () {
fs.appendFileSync('foo/bar', 'baz');
});
});
});
mock-fs-5.5.0/test/lib/fs.chmod-fchmod.spec.js 0000664 0000000 0000000 00000007501 14751162414 0021043 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.chmod(path, mode, callback)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({mode: parseInt('0644', 8)}),
});
});
afterEach(mock.restore);
it('changes permissions of a file', function (done) {
fs.chmod('file.txt', parseInt('0664', 8), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('file.txt');
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0664', 8));
done();
});
});
it('supports Buffer input', function (done) {
fs.chmod(Buffer.from('file.txt'), parseInt('0664', 8), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync(Buffer.from('file.txt'));
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0664', 8));
done();
});
});
it('promise changes permissions of a file', function (done) {
fs.promises
.chmod('file.txt', parseInt('0664', 8))
.then(function () {
const stats = fs.statSync('file.txt');
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0664', 8));
done();
})
.catch(done);
});
it('fails if file does not exist', function (done) {
fs.chmod('bogus.txt', parseInt('0664', 8), function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails if file does not exist', function (done) {
fs.promises.chmod('bogus.txt', parseInt('0664', 8)).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.chmodSync(path, mode)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({mode: parseInt('0666', 8)}),
});
});
afterEach(mock.restore);
it('changes permissions of a file', function () {
fs.chmodSync('file.txt', parseInt('0644', 8));
const stats = fs.statSync('file.txt');
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0644', 8));
});
it('fails if file does not exist', function () {
assert.throws(function () {
fs.chmodSync('bogus.txt', parseInt('0644', 8));
});
});
});
describe('fs.fchmod(fd, mode, callback)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({mode: parseInt('0666', 8)}),
});
});
afterEach(mock.restore);
it('changes permissions of a file', function (done) {
const fd = fs.openSync('file.txt', 'r');
fs.fchmod(fd, parseInt('0644', 8), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('file.txt');
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0644', 8));
done();
});
});
it('promise changes permissions of a file', function (done) {
fs.promises
.open('file.txt', 'r')
.then(function (fd) {
return fd.chmod(parseInt('0644', 8));
})
.then(function () {
const stats = fs.statSync('file.txt');
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0644', 8));
done();
})
.catch(done);
});
});
describe('fs.fchmodSync(fd, mode)', function () {
beforeEach(function () {
mock({
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('changes permissions of a file', function () {
const fd = fs.openSync('file.txt', 'r');
fs.fchmodSync(fd, parseInt('0444', 8));
const stats = fs.statSync('file.txt');
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0444', 8));
});
});
mock-fs-5.5.0/test/lib/fs.chown-fchown.spec.js 0000664 0000000 0000000 00000004754 14751162414 0021122 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.chown(path, uid, gid, callback)', function () {
beforeEach(function () {
mock({
'path/empty': {},
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('changes ownership of a file', function (done) {
fs.chown('file.txt', 42, 43, done);
});
it('supports Buffer input', function (done) {
fs.chown(Buffer.from('file.txt'), 42, 43, done);
});
it('promise changes ownership of a file', function (done) {
fs.promises.chown('file.txt', 42, 43).then(done, done);
});
it('fails if file does not exist', function (done) {
fs.chown('bogus.txt', 42, 43, function (err) {
assert.instanceOf(err, Error);
done();
});
});
it('promise fails if file does not exist', function (done) {
fs.promises.chown('bogus.txt', 42, 43).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.chownSync(path, uid, gid)', function () {
beforeEach(function () {
mock({
'path/empty': {},
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('changes ownership of a file', function () {
fs.chownSync('file.txt', 42, 43);
});
it('fails if file does not exist', function () {
assert.throws(function () {
fs.chownSync('bogus.txt', 42, 43);
});
});
});
describe('fs.fchown(fd, uid, gid, callback)', function () {
beforeEach(function () {
mock({
'path/empty': {},
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('changes ownership of a file', function (done) {
const fd = fs.openSync('file.txt', 'r');
fs.fchown(fd, 42, 43, done);
});
it('promise changes ownership of a file', function (done) {
fs.promises
.open('file.txt', 'r')
.then(function (fd) {
return fd.chown(42, 43);
})
.then(done, done);
});
});
describe('fs.fchownSync(fd, uid, gid)', function () {
beforeEach(function () {
mock({
'path/empty': {},
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('changes ownership of a file', function () {
const fd = fs.openSync('file.txt', 'r');
fs.fchownSync(fd, 42, 43);
});
});
mock-fs-5.5.0/test/lib/fs.copyFile.spec.js 0000664 0000000 0000000 00000011700 14751162414 0020261 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
if (fs.copyFile && fs.copyFileSync) {
describe('fs.copyFile(src, dest[, flags], callback)', function () {
beforeEach(function () {
mock({
'path/to/src.txt': 'file content',
'path/to/other.txt': 'other file content',
empty: {},
});
});
afterEach(mock.restore);
it('copies a file to an empty directory', function (done) {
fs.copyFile('path/to/src.txt', 'empty/dest.txt', function (err) {
assert.isTrue(!err);
assert.isTrue(fs.existsSync('empty/dest.txt'));
assert.equal(String(fs.readFileSync('empty/dest.txt')), 'file content');
done();
});
});
it('supports Buffer input', function (done) {
fs.copyFile(
Buffer.from('path/to/src.txt'),
Buffer.from('empty/dest.txt'),
function (err) {
assert.isTrue(!err);
assert.isTrue(fs.existsSync('empty/dest.txt'));
assert.equal(
String(fs.readFileSync('empty/dest.txt')),
'file content',
);
done();
},
);
});
it('promise copies a file to an empty directory', function (done) {
fs.promises
.copyFile('path/to/src.txt', 'empty/dest.txt')
.then(function () {
assert.isTrue(fs.existsSync('empty/dest.txt'));
assert.equal(
String(fs.readFileSync('empty/dest.txt')),
'file content',
);
done();
})
.catch(done);
});
it('truncates dest file if it exists', function (done) {
fs.copyFile('path/to/src.txt', 'path/to/other.txt', function (err) {
assert.isTrue(!err);
assert.equal(
String(fs.readFileSync('path/to/other.txt')),
'file content',
);
done();
});
});
it('promise truncates dest file if it exists', function (done) {
fs.promises
.copyFile('path/to/src.txt', 'path/to/other.txt')
.then(function () {
assert.equal(
String(fs.readFileSync('path/to/other.txt')),
'file content',
);
done();
})
.catch(done);
});
it('throws if dest exists and exclusive', function (done) {
fs.copyFile(
'path/to/src.txt',
'path/to/other.txt',
fs.constants.COPYFILE_EXCL,
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
},
);
});
it('promise throws if dest exists and exclusive', function (done) {
fs.promises
.copyFile(
'path/to/src.txt',
'path/to/other.txt',
fs.constants.COPYFILE_EXCL,
)
.then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
},
);
});
it('fails if src does not exist', function (done) {
fs.copyFile('path/to/bogus.txt', 'empty/dest.txt', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails if src does not exist', function (done) {
fs.promises.copyFile('path/to/bogus.txt', 'empty/dest.txt').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
it('fails if dest path does not exist', function (done) {
fs.copyFile('path/to/src.txt', 'path/nope/dest.txt', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails if dest path does not exist', function (done) {
fs.promises.copyFile('path/to/src.txt', 'path/nope/dest.txt').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
it('fails if dest is a directory', function (done) {
fs.copyFile('path/to/src.txt', 'empty', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EISDIR');
done();
});
});
it('promise fails if dest is a directory', function (done) {
fs.promises.copyFile('path/to/src.txt', 'empty').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EISDIR');
done();
},
);
});
});
}
mock-fs-5.5.0/test/lib/fs.createReadStream.spec.js 0000664 0000000 0000000 00000001747 14751162414 0021734 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.createReadStream(path, [options])', function () {
beforeEach(function () {
mock({
'dir/source': 'source content',
});
});
afterEach(mock.restore);
it('creates a readable stream', function () {
const stream = fs.createReadStream('dir/source');
assert.isTrue(stream.readable);
});
it('allows piping to a writable stream', function (done) {
const input = fs.createReadStream('dir/source');
const output = fs.createWriteStream('dir/dest');
output.on('close', function () {
fs.readFile('dir/dest', function (err, data) {
if (err) {
return done(err);
}
assert.equal(String(data), 'source content');
done();
});
});
output.on('error', done);
input.pipe(output);
});
});
mock-fs-5.5.0/test/lib/fs.createWriteStream.spec.js 0000664 0000000 0000000 00000005704 14751162414 0022150 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const Writable = require('stream').Writable;
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.createWriteStream(path[, options])', function () {
beforeEach(function () {
mock({
existing: 'content',
});
});
afterEach(mock.restore);
it('provides a write stream for a file in buffered mode', function (done) {
const output = fs.createWriteStream('test.txt');
output.on('close', function () {
fs.readFile('test.txt', function (err, data) {
if (err) {
return done(err);
}
assert.equal(String(data), 'lots of source content');
done();
});
});
output.on('error', done);
// if output._writev is available, buffered multiple writes will hit _writev.
// otherwise, hit multiple _write.
output.write(Buffer.from('lots '));
output.write(Buffer.from('of '));
output.write(Buffer.from('source '));
output.end(Buffer.from('content'));
});
it('can be used with the append flag', function (done) {
const filename = 'existing';
const output = fs.createWriteStream(filename, {flags: 'a'});
output.on('close', function () {
fs.readFile(filename, function (err, data) {
if (err) {
return done(err);
}
assert.equal(String(data), 'contentmorecontent');
done();
});
});
output.on('error', done);
output.write(Buffer.from('more'));
output.end(Buffer.from('content'));
});
it('provides a write stream for a file', function (done) {
const output = fs.createWriteStream('test.txt');
output.on('close', function () {
fs.readFile('test.txt', function (err, data) {
if (err) {
return done(err);
}
assert.equal(String(data), 'lots of source content');
done();
});
});
output.on('error', done);
output.write(Buffer.from('lots '));
setTimeout(function () {
output.write(Buffer.from('of '));
setTimeout(function () {
output.write(Buffer.from('source '));
setTimeout(function () {
output.end(Buffer.from('content'));
}, 50);
}, 50);
}, 50);
});
if (Writable && Writable.prototype.cork) {
it('works when write stream is corked', function (done) {
const output = fs.createWriteStream('test.txt');
output.on('close', function () {
fs.readFile('test.txt', function (err, data) {
if (err) {
return done(err);
}
assert.equal(String(data), 'lots of source content');
done();
});
});
output.on('error', done);
output.cork();
output.write(Buffer.from('lots '));
output.write(Buffer.from('of '));
output.write(Buffer.from('source '));
output.end(Buffer.from('content'));
output.uncork();
});
}
});
mock-fs-5.5.0/test/lib/fs.exists.spec.js 0000664 0000000 0000000 00000006755 14751162414 0020044 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.exists(path, callback)', function () {
beforeEach(function () {
mock({
'path/to/a.bin': Buffer.from([1, 2, 3]),
empty: {},
nested: {
dir: {
'file.txt': '',
},
},
});
});
afterEach(mock.restore);
it('calls with true if file exists', function (done) {
fs.exists(path.join('path', 'to', 'a.bin'), function (exists) {
assert.isTrue(exists);
done();
});
});
it('calls with true if directory exists', function (done) {
fs.exists('path', function (exists) {
assert.isTrue(exists);
done();
});
});
it('calls with true if empty directory exists', function (done) {
fs.exists('empty', function (exists) {
assert.isTrue(exists);
done();
});
});
it('calls with true if nested directory exists', function (done) {
fs.exists(path.join('nested', 'dir'), function (exists) {
assert.isTrue(exists);
done();
});
});
it('calls with true if file exists', function (done) {
fs.exists(path.join('path', 'to', 'a.bin'), function (exists) {
assert.isTrue(exists);
done();
});
});
it('calls with true if empty file exists', function (done) {
fs.exists(path.join('nested', 'dir', 'file.txt'), function (exists) {
assert.isTrue(exists);
done();
});
});
it('calls with false for bogus path', function (done) {
fs.exists(path.join('bogus', 'path'), function (exists) {
assert.isFalse(exists);
done();
});
});
it('calls with false for bogus path (II)', function (done) {
fs.exists(path.join('nested', 'dir', 'none'), function (exists) {
assert.isFalse(exists);
done();
});
});
it('calls with false for bogus path (III)', function (done) {
fs.exists(path.join('path', 'to', 'a.bin', 'foo'), function (exists) {
assert.isFalse(exists);
done();
});
});
});
describe('fs.existsSync(path)', function () {
beforeEach(function () {
mock({
'path/to/a.bin': Buffer.from([1, 2, 3]),
empty: {},
nested: {
dir: {
'file.txt': '',
},
},
});
});
afterEach(mock.restore);
it('returns true if file exists', function () {
assert.isTrue(fs.existsSync(path.join('path', 'to', 'a.bin')));
});
it('returns true if directory exists', function () {
assert.isTrue(fs.existsSync('path'));
});
it('returns true if empty directory exists', function () {
assert.isTrue(fs.existsSync('empty'));
});
it('returns true if nested directory exists', function () {
assert.isTrue(fs.existsSync(path.join('nested', 'dir')));
});
it('returns true if file exists', function () {
assert.isTrue(fs.existsSync(path.join('path', 'to', 'a.bin')));
});
it('returns true if empty file exists', function () {
assert.isTrue(fs.existsSync(path.join('nested', 'dir', 'file.txt')));
});
it('returns false for bogus path', function () {
assert.isFalse(fs.existsSync(path.join('bogus', 'path')));
});
it('returns false for bogus path (II)', function () {
assert.isFalse(fs.existsSync(path.join('nested', 'dir', 'none')));
});
it('returns false for a path beyond a file', function () {
assert.isFalse(fs.existsSync(path.join('path', 'to', 'a.bin', 'foo')));
});
});
mock-fs-5.5.0/test/lib/fs.link-symlink.spec.js 0000664 0000000 0000000 00000022113 14751162414 0021130 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.link(srcpath, dstpath, callback)', function () {
beforeEach(function () {
mock({
dir: {},
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('creates a link to a file', function (done) {
assert.equal(fs.statSync('file.txt').nlink, 1);
fs.link('file.txt', 'link.txt', function (err) {
if (err) {
return done(err);
}
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(fs.statSync('link.txt').nlink, 2);
assert.equal(fs.statSync('file.txt').nlink, 2);
assert.equal(String(fs.readFileSync('link.txt')), 'content');
done();
});
});
it('supports Buffer input', function (done) {
assert.equal(fs.statSync('file.txt').nlink, 1);
fs.link(Buffer.from('file.txt'), Buffer.from('link.txt'), function (err) {
if (err) {
return done(err);
}
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(fs.statSync('link.txt').nlink, 2);
assert.equal(fs.statSync('file.txt').nlink, 2);
assert.equal(String(fs.readFileSync('link.txt')), 'content');
done();
});
});
it('promise creates a link to a file', function (done) {
assert.equal(fs.statSync('file.txt').nlink, 1);
fs.promises
.link('file.txt', 'link.txt')
.then(function () {
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(fs.statSync('link.txt').nlink, 2);
assert.equal(fs.statSync('file.txt').nlink, 2);
assert.equal(String(fs.readFileSync('link.txt')), 'content');
done();
})
.catch(done);
});
it('works if original is renamed', function (done) {
fs.link('file.txt', 'link.txt', function (err) {
if (err) {
return done(err);
}
fs.renameSync('file.txt', 'renamed.txt');
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(String(fs.readFileSync('link.txt')), 'content');
done();
});
});
it('promise works if original is renamed', function (done) {
fs.promises
.link('file.txt', 'link.txt')
.then(function () {
fs.renameSync('file.txt', 'renamed.txt');
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(String(fs.readFileSync('link.txt')), 'content');
done();
})
.catch(done);
});
it('works if original is removed', function (done) {
assert.equal(fs.statSync('file.txt').nlink, 1);
fs.link('file.txt', 'link.txt', function (err) {
if (err) {
return done(err);
}
assert.equal(fs.statSync('link.txt').nlink, 2);
assert.equal(fs.statSync('file.txt').nlink, 2);
fs.unlinkSync('file.txt');
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(fs.statSync('link.txt').nlink, 1);
assert.equal(String(fs.readFileSync('link.txt')), 'content');
done();
});
});
it('promise works if original is removed', function (done) {
assert.equal(fs.statSync('file.txt').nlink, 1);
fs.promises
.link('file.txt', 'link.txt')
.then(function () {
assert.equal(fs.statSync('link.txt').nlink, 2);
assert.equal(fs.statSync('file.txt').nlink, 2);
fs.unlinkSync('file.txt');
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(fs.statSync('link.txt').nlink, 1);
assert.equal(String(fs.readFileSync('link.txt')), 'content');
done();
})
.catch(done);
});
it('fails if original is a directory', function (done) {
fs.link('dir', 'link', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EPERM');
done();
});
});
it('promise fails if original is a directory', function (done) {
fs.promises.link('dir', 'link').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EPERM');
done();
},
);
});
});
describe('fs.linkSync(srcpath, dstpath)', function () {
beforeEach(function () {
mock({
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('creates a link to a file', function () {
fs.linkSync('file.txt', 'link.txt');
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(String(fs.readFileSync('link.txt')), 'content');
});
it('works if original is renamed', function () {
fs.linkSync('file.txt', 'link.txt');
fs.renameSync('file.txt', 'renamed.txt');
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(String(fs.readFileSync('link.txt')), 'content');
});
it('works if original is removed', function () {
fs.linkSync('file.txt', 'link.txt');
fs.unlinkSync('file.txt');
assert.isTrue(fs.statSync('link.txt').isFile());
assert.equal(String(fs.readFileSync('link.txt')), 'content');
});
it('fails if original is a directory', function () {
assert.throws(function () {
fs.linkSync('dir', 'link');
});
});
});
describe('fs.symlink(srcpath, dstpath, [type], callback)', function () {
beforeEach(function () {
mock({
dir: {},
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('creates a symbolic link to a file', function (done) {
fs.symlink('../file.txt', 'dir/link.txt', function (err) {
if (err) {
return done(err);
}
assert.isTrue(fs.statSync('dir/link.txt').isFile());
assert.equal(String(fs.readFileSync('dir/link.txt')), 'content');
done();
});
});
// https://github.com/nodejs/node/issues/34514
if (process.platform === 'win32') {
it('supports Buffer input', function (done) {
fs.symlink(
Buffer.from('../file.txt'),
Buffer.from('dir/link.txt'),
function (err) {
if (err) {
return done(err);
}
assert.isTrue(fs.statSync('dir/link.txt').isFile());
assert.equal(String(fs.readFileSync('dir/link.txt')), 'content');
done();
},
);
});
} else {
it('supports Buffer input', function (done) {
fs.symlink(
Buffer.from('../file.txt'),
Buffer.from('dir/link.txt'),
function (err) {
if (err) {
return done(err);
}
assert.isTrue(fs.statSync('dir/link.txt').isFile());
assert.equal(String(fs.readFileSync('dir/link.txt')), 'content');
done();
},
);
});
}
it('promise creates a symbolic link to a file', function (done) {
fs.promises
.symlink('../file.txt', 'dir/link.txt')
.then(function () {
assert.isTrue(fs.statSync('dir/link.txt').isFile());
assert.equal(String(fs.readFileSync('dir/link.txt')), 'content');
done();
})
.catch(done);
});
it('breaks if original is renamed', function (done) {
fs.symlink('file.txt', 'link.txt', function (err) {
if (err) {
return done(err);
}
assert.isTrue(fs.existsSync('link.txt'));
fs.renameSync('file.txt', 'renamed.txt');
assert.isFalse(fs.existsSync('link.txt'));
done();
});
});
it('promise breaks if original is renamed', function (done) {
fs.promises
.symlink('file.txt', 'link.txt')
.then(function () {
assert.isTrue(fs.existsSync('link.txt'));
fs.renameSync('file.txt', 'renamed.txt');
assert.isFalse(fs.existsSync('link.txt'));
done();
})
.catch(done);
});
it('works if original is a directory', function (done) {
fs.symlink('dir', 'link', function (err) {
if (err) {
return done(err);
}
assert.isTrue(fs.statSync('link').isDirectory());
done();
});
});
it('promise works if original is a directory', function (done) {
fs.promises
.symlink('dir', 'link')
.then(function () {
assert.isTrue(fs.statSync('link').isDirectory());
done();
})
.catch(done);
});
});
describe('fs.symlinkSync(srcpath, dstpath, [type])', function () {
beforeEach(function () {
mock({
dir: {},
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('creates a symbolic link to a file', function () {
fs.symlinkSync('../file.txt', 'dir/link.txt');
assert.isTrue(fs.statSync('dir/link.txt').isFile());
assert.equal(String(fs.readFileSync('dir/link.txt')), 'content');
});
it('breaks if original is renamed', function () {
fs.symlinkSync('file.txt', 'link.txt');
assert.isTrue(fs.existsSync('link.txt'));
fs.renameSync('file.txt', 'renamed.txt');
assert.isFalse(fs.existsSync('link.txt'));
});
it('works if original is a directory', function () {
fs.symlinkSync('dir', 'link');
assert.isTrue(fs.statSync('link').isDirectory());
});
it('exists works if symlink is relative', function () {
fs.renameSync('file.txt', 'dir/file.txt');
fs.symlinkSync('file.txt', 'dir/link.txt');
assert.isTrue(fs.existsSync('dir/link.txt'));
});
});
mock-fs-5.5.0/test/lib/fs.lstat.spec.js 0000664 0000000 0000000 00000013100 14751162414 0017632 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.lstat(path, options, callback)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({
content: 'content',
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('stats a symbolic link', function (done) {
fs.lstat('link', function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(stats.mtime.getTime(), 2);
done();
});
});
it('stats a symbolic link with bigint', function (done) {
fs.lstat('link', {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(typeof stats.mtimeMs, 'bigint');
done();
});
});
it('suports Buffer input', function (done) {
fs.lstat(Buffer.from('link'), function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(stats.mtime.getTime(), 2);
done();
});
});
it('suports Buffer input with bigint', function (done) {
fs.lstat(Buffer.from('link'), {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(typeof stats.mtimeMs, 'bigint');
done();
});
});
it('promise stats a symbolic link', function (done) {
fs.promises
.lstat('link')
.then(function (stats) {
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(stats.mtime.getTime(), 2);
done();
})
.catch(done);
});
it('promise stats a symbolic link with bigint', function (done) {
fs.promises
.lstat('link', {bigint: true})
.then(function (stats) {
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(typeof stats.mtimeMs, 'bigint');
done();
})
.catch(done);
});
it('stats a regular file', function (done) {
fs.lstat('file.txt', function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.isFalse(stats.isSymbolicLink());
assert.equal(stats.mtime.getTime(), 1);
done();
});
});
it('stats a regular file with bigint', function (done) {
fs.lstat('file.txt', {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.isFalse(stats.isSymbolicLink());
assert.equal(typeof stats.mtimeMs, 'bigint');
done();
});
});
it('promise stats a regular file', function (done) {
fs.promises
.lstat('file.txt')
.then(function (stats) {
assert.isTrue(stats.isFile());
assert.isFalse(stats.isSymbolicLink());
assert.equal(stats.mtime.getTime(), 1);
done();
})
.catch(done);
});
it('promise stats a regular file with bigint', function (done) {
fs.promises
.lstat('file.txt', {bigint: true})
.then(function (stats) {
assert.isTrue(stats.isFile());
assert.isFalse(stats.isSymbolicLink());
assert.equal(typeof stats.mtimeMs, 'bigint');
done();
})
.catch(done);
});
it('fails on file not exist', function (done) {
fs.lstat('bogus', function (err, stats) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails on file not exist', function (done) {
fs.promises.lstat('bogus').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.lstatSync(path, options)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({
content: 'content',
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('stats a symbolic link', function () {
const stats = fs.lstatSync('link');
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(stats.mtime.getTime(), 2);
});
it('stats a symbolic link with bigint', function () {
const stats = fs.lstatSync('link', {bigint: true});
assert.isTrue(stats.isSymbolicLink());
assert.isFalse(stats.isFile());
assert.equal(typeof stats.mtimeMs, 'bigint');
});
it('stats a regular file', function () {
const stats = fs.lstatSync('file.txt');
assert.isTrue(stats.isFile());
assert.isFalse(stats.isSymbolicLink());
assert.equal(stats.mtime.getTime(), 1);
});
it('stats a regular file with bigint', function () {
const stats = fs.lstatSync('file.txt', {bigint: true});
assert.isTrue(stats.isFile());
assert.isFalse(stats.isSymbolicLink());
assert.equal(typeof stats.mtimeMs, 'bigint');
});
it('fails on file not exist', function () {
assert.throws(function () {
fs.lstatSync('bogus');
});
});
});
mock-fs-5.5.0/test/lib/fs.mkdir.spec.js 0000664 0000000 0000000 00000030347 14751162414 0017625 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
const testParentPerms = process.getuid && process.getgid;
describe('fs.mkdir(path, [mode], callback)', function () {
beforeEach(function () {
mock({
parent: {
'file.md': '',
child: {},
},
'file.txt': '',
unwriteable: mock.directory({mode: parseInt('0555', 8)}),
});
});
afterEach(mock.restore);
it('creates a new directory', function (done) {
fs.mkdir('parent/dir', function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('parent/dir');
assert.isTrue(stats.isDirectory());
done();
});
});
it('supports Buffer input', function (done) {
fs.mkdir(Buffer.from('parent/dir'), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('parent/dir');
assert.isTrue(stats.isDirectory());
done();
});
});
it('promise creates a new directory', function (done) {
fs.promises
.mkdir('parent/dir')
.then(function () {
const stats = fs.statSync('parent/dir');
assert.isTrue(stats.isDirectory());
done();
})
.catch(done);
});
it('creates a new directory recursively', function (done) {
fs.mkdir('parent/foo/bar/dir', {recursive: true}, function (err) {
if (err) {
return done(err);
}
let stats = fs.statSync('parent/foo/bar/dir');
assert.isTrue(stats.isDirectory());
stats = fs.statSync('parent/foo/bar');
assert.isTrue(stats.isDirectory());
stats = fs.statSync('parent/foo');
assert.isTrue(stats.isDirectory());
done();
});
});
it('promise creates a new directory recursively', function (done) {
fs.promises
.mkdir('parent/foo/bar/dir', {recursive: true})
.then(function () {
let stats = fs.statSync('parent/foo/bar/dir');
assert.isTrue(stats.isDirectory());
stats = fs.statSync('parent/foo/bar');
assert.isTrue(stats.isDirectory());
stats = fs.statSync('parent/foo');
assert.isTrue(stats.isDirectory());
done();
})
.catch(done);
});
it('accepts dir mode', function (done) {
fs.mkdir('parent/dir', parseInt('0755', 8), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('parent/dir');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
done();
});
});
it('promise accepts dir mode', function (done) {
fs.promises
.mkdir('parent/dir', parseInt('0755', 8))
.then(function () {
const stats = fs.statSync('parent/dir');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
done();
})
.catch(done);
});
it('accepts dir mode recursively', function (done) {
fs.mkdir(
'parent/foo/bar/dir',
{recursive: true, mode: parseInt('0755', 8)},
function (err) {
if (err) {
return done(err);
}
let stats = fs.statSync('parent/foo/bar/dir');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
stats = fs.statSync('parent/foo/bar');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
stats = fs.statSync('parent/foo');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
done();
},
);
});
it('promise accepts dir mode recursively', function (done) {
fs.promises
.mkdir('parent/foo/bar/dir', {recursive: true, mode: parseInt('0755', 8)})
.then(function () {
let stats = fs.statSync('parent/foo/bar/dir');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
stats = fs.statSync('parent/foo/bar');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
stats = fs.statSync('parent/foo');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
done();
})
.catch(done);
});
it('fails if parent does not exist', function (done) {
fs.mkdir('parent/bogus/dir', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails if parent does not exist', function (done) {
fs.promises.mkdir('parent/bogus/dir').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
it('fails if one parent is not a folder in recursive creation', function (done) {
fs.mkdir('file.txt/bogus/dir', {recursive: true}, function (err) {
assert.instanceOf(err, Error);
done();
});
});
it('promise fails if one parent is not a folder in recursive creation', function (done) {
fs.promises.mkdir('file.txt/bogus/dir', {recursive: true}).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
done();
},
);
});
it('fails if permission does not allow recursive creation', function (done) {
fs.mkdir(
'parent/foo/bar/dir',
{recursive: true, mode: parseInt('0400', 8)},
function (err) {
assert.instanceOf(err, Error);
done();
},
);
});
it('promise fails if permission does not allow recursive creation', function (done) {
fs.promises
.mkdir('parent/foo/bar/dir', {
recursive: true,
mode: parseInt('0400', 8),
})
.then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
done();
},
);
});
it('fails if directory already exists', function (done) {
fs.mkdir('parent', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
});
});
it('promise fails if directory already exists', function (done) {
fs.promises.mkdir('parent').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
},
);
});
it('fails if file already exists', function (done) {
fs.mkdir('file.txt', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
});
});
it('promise fails if file already exists', function (done) {
fs.promises.mkdir('file.txt').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
},
);
});
it('fails in recursive mode if file already exists', function (done) {
fs.mkdir('parent/file.md', {recursive: true}, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
});
});
it('promise fails in recursive mode if file already exists', function (done) {
fs.promises.mkdir('parent/file.md', {recursive: true}).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
},
);
});
it('passes in recursive mode if directory already exists', function (done) {
fs.mkdir('parent/child', {recursive: true}, function (err) {
assert.isNotOk(err, Error);
done();
});
});
it('promise passes in recursive mode if directory already exists', function (done) {
fs.promises.mkdir('parent/child', {recursive: true}).then(done, done);
});
if (testParentPerms) {
it('fails if parent is not writeable', function (done) {
fs.mkdir('unwriteable/child', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise fails if parent is not writeable', function (done) {
fs.promises.mkdir('unwriteable/child').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
}
it('calls callback with a single argument on success', function (done) {
fs.mkdir('parent/arity', function (_) {
assert.equal(arguments.length, 1);
done();
});
});
it('calls callback with a single argument on failure', function (done) {
fs.mkdir('parent', function (err) {
assert.instanceOf(err, Error);
done();
});
});
});
describe('fs.mkdirSync(path, [mode])', function () {
beforeEach(function () {
mock({
parent: {
'file.md': '',
child: {},
},
'file.txt': 'content',
unwriteable: mock.directory({mode: parseInt('0555', 8)}),
});
});
afterEach(mock.restore);
it('creates a new directory', function () {
fs.mkdirSync('parent/dir');
const stats = fs.statSync('parent/dir');
assert.isTrue(stats.isDirectory());
});
it('creates a new directory recursively', function () {
fs.mkdirSync('parent/foo/bar/dir', {recursive: true});
let stats = fs.statSync('parent/foo/bar/dir');
assert.isTrue(stats.isDirectory());
stats = fs.statSync('parent/foo/bar');
assert.isTrue(stats.isDirectory());
stats = fs.statSync('parent/foo');
assert.isTrue(stats.isDirectory());
});
it('accepts dir mode', function () {
fs.mkdirSync('parent/dir', parseInt('0755', 8));
const stats = fs.statSync('parent/dir');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
});
it('accepts dir mode recursively', function () {
fs.mkdirSync('parent/foo/bar/dir', {
recursive: true,
mode: parseInt('0755', 8),
});
let stats = fs.statSync('parent/foo/bar/dir');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
stats = fs.statSync('parent/foo/bar');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
stats = fs.statSync('parent/foo');
assert.isTrue(stats.isDirectory());
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0755', 8));
});
it('fails if parent does not exist', function () {
assert.throws(function () {
fs.mkdirSync('parent/bogus/dir');
});
});
it('fails if one parent is not a folder in recursive creation', function () {
assert.throws(function () {
fs.mkdirSync('file.txt/bogus/dir', {recursive: true});
});
});
it('fails if permission does not allow recursive creation', function () {
assert.throws(function () {
fs.mkdirSync('parent/foo/bar/dir', {
recursive: true,
mode: parseInt('0400', 8),
});
});
});
it('fails if directory already exists', function () {
assert.throws(function () {
fs.mkdirSync('parent');
});
});
it('fails if file already exists', function () {
assert.throws(function () {
fs.mkdirSync('file.txt');
});
});
it('fails in recursive mode if file already exists', function () {
assert.throws(function () {
fs.mkdirSync('parent/file.md', {recursive: true});
});
});
it('passes in recursive mode if directory already exists', function () {
assert.doesNotThrow(function () {
fs.mkdirSync('parent/child', {recursive: true});
});
});
if (testParentPerms) {
it('fails if parent is not writeable', function () {
assert.throws(function () {
fs.mkdirSync('unwriteable/child');
});
});
}
});
mock-fs-5.5.0/test/lib/fs.mkdtemp.spec.js 0000664 0000000 0000000 00000023544 14751162414 0020161 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
const testParentPerms = process.getuid && process.getgid;
if (fs.mkdtemp) {
describe('fs.mkdtemp(prefix[, options], callback)', function () {
beforeEach(function () {
mock({
parent: {},
file: 'contents',
unwriteable: mock.directory({mode: parseInt('0555', 8)}),
});
});
afterEach(mock.restore);
it('creates a new directory', function (done) {
fs.mkdtemp('parent/dir', function (err, dirPath) {
if (err) {
return done(err);
}
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
});
});
it('promise creates a new directory', function (done) {
fs.promises
.mkdtemp('parent/dir')
.then(function (dirPath) {
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
})
.catch(done);
});
it('accepts a "utf8" encoding argument', function (done) {
fs.mkdtemp('parent/dir', 'utf8', function (err, dirPath) {
if (err) {
return done(err);
}
assert.isString(dirPath);
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
});
});
it('promise accepts a "utf8" encoding argument', function (done) {
fs.promises
.mkdtemp('parent/dir', 'utf8')
.then(function (dirPath) {
assert.isString(dirPath);
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
})
.catch(done);
});
it('accepts a "buffer" encoding argument', function (done) {
fs.mkdtemp('parent/dir', 'buffer', function (err, buffer) {
if (err) {
return done(err);
}
assert.instanceOf(buffer, Buffer);
const dirPath = buffer.toString();
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
});
});
it('promise accepts a "buffer" encoding argument', function (done) {
fs.promises
.mkdtemp('parent/dir', 'buffer')
.then(function (buffer) {
assert.instanceOf(buffer, Buffer);
const dirPath = buffer.toString();
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
})
.catch(done);
});
it('accepts an options argument with "utf8" encoding', function (done) {
fs.mkdtemp('parent/dir', {encoding: 'utf8'}, function (err, dirPath) {
if (err) {
return done(err);
}
assert.isString(dirPath);
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
});
});
it('promise accepts an options argument with "utf8" encoding', function (done) {
fs.promises
.mkdtemp('parent/dir', {encoding: 'utf8'})
.then(function (dirPath) {
assert.isString(dirPath);
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
})
.catch(done);
});
it('accepts an options argument with "buffer" encoding', function (done) {
fs.mkdtemp('parent/dir', {encoding: 'buffer'}, function (err, buffer) {
if (err) {
return done(err);
}
assert.instanceOf(buffer, Buffer);
const dirPath = buffer.toString();
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
});
});
it('promise accepts an options argument with "buffer" encoding', function (done) {
fs.promises
.mkdtemp('parent/dir', {encoding: 'buffer'})
.then(function (buffer) {
assert.instanceOf(buffer, Buffer);
const dirPath = buffer.toString();
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
done();
})
.catch(done);
});
it('fails if parent does not exist', function (done) {
fs.mkdtemp('unknown/child', function (err, dirPath) {
if (!err || dirPath) {
done(new Error('Expected failure'));
} else {
assert.isTrue(!dirPath);
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
}
});
});
it('promise fails if parent does not exist', function (done) {
fs.promises.mkdtemp('unknown/child').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
it('fails if parent is a file', function (done) {
fs.mkdtemp('file/child', function (err, dirPath) {
if (!err || dirPath) {
done(new Error('Expected failure'));
} else {
assert.isTrue(!dirPath);
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOTDIR');
done();
}
});
});
it('promise fails if parent is a file', function (done) {
fs.promises.mkdtemp('file/child').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOTDIR');
done();
},
);
});
if (testParentPerms) {
it('fails if parent is not writeable', function (done) {
fs.mkdtemp('unwriteable/child', function (err, dirPath) {
if (!err || dirPath) {
done(new Error('Expected failure'));
} else {
assert.isTrue(!dirPath);
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
}
});
});
it('promise fails if parent is not writeable', function (done) {
fs.promises.mkdtemp('unwriteable/child').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
}
});
}
if (fs.mkdtempSync) {
describe('fs.mkdtempSync(prefix[, options])', function () {
beforeEach(function () {
mock({
parent: {},
file: 'contents',
unwriteable: mock.directory({mode: parseInt('0555', 8)}),
});
});
afterEach(mock.restore);
it('creates a new directory', function () {
const dirPath = fs.mkdtempSync('parent/dir');
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
});
it('accepts a "utf8" encoding argument', function () {
const dirPath = fs.mkdtempSync('parent/dir', 'utf8');
assert.isString(dirPath);
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
});
it('accepts a "buffer" encoding argument', function () {
const buffer = fs.mkdtempSync('parent/dir', 'buffer');
assert.instanceOf(buffer, Buffer);
const dirPath = buffer.toString();
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
});
it('accepts an options argument with "utf8" encoding', function () {
const dirPath = fs.mkdtempSync('parent/dir', {encoding: 'utf8'});
assert.isString(dirPath);
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
});
it('accepts an options argument with "buffer" encoding', function () {
const buffer = fs.mkdtempSync('parent/dir', {encoding: 'buffer'});
assert.instanceOf(buffer, Buffer);
const dirPath = buffer.toString();
const parentPath = path.dirname(dirPath);
assert.equal(parentPath, 'parent');
const stats = fs.statSync(dirPath);
assert.isTrue(stats.isDirectory());
});
it('fails if parent does not exist', function () {
assert.throws(function () {
fs.mkdtempSync('unknown/child');
});
});
it('fails if parent is a file', function () {
assert.throws(function () {
fs.mkdtempSync('file/child');
});
});
if (testParentPerms) {
it('fails if parent is not writeable', function () {
assert.throws(function () {
fs.mkdtempSync('unwriteable/child');
});
});
}
});
}
mock-fs-5.5.0/test/lib/fs.open-close.spec.js 0000664 0000000 0000000 00000013650 14751162414 0020561 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.open(path, flags, [mode], callback)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
nested: {
sub: {
dir: {
'one.txt': 'one content',
'two.txt': 'two content',
empty: {},
},
},
},
});
});
afterEach(mock.restore);
it('opens an existing file for reading (r)', function (done) {
fs.open('nested/sub/dir/one.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
assert.isNumber(fd);
done();
});
});
it('supports Buffer input', function (done) {
fs.open(Buffer.from('nested/sub/dir/one.txt'), 'r', function (err, fd) {
if (err) {
return done(err);
}
assert.isNumber(fd);
done();
});
});
it('promise opens an existing file for reading (r)', function (done) {
fs.promises
.open('nested/sub/dir/one.txt', 'r')
.then(function (fd) {
assert.isNumber(fd.fd);
done();
})
.catch(done);
});
it('fails if file does not exist (r)', function (done) {
fs.open('bogus.txt', 'r', function (err, fd) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails if file does not exist (r)', function (done) {
fs.promises.open('bogus.txt', 'r').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
it('creates a new file for writing (w)', function (done) {
fs.open('path/to/new.txt', 'w', parseInt('0666', 8), function (err, fd) {
if (err) {
return done(err);
}
assert.isNumber(fd);
assert.isTrue(fs.existsSync('path/to/new.txt'));
done();
});
});
it('promise creates a new file for writing (w)', function (done) {
fs.promises
.open('path/to/new.txt', 'w', parseInt('0666', 8))
.then(function (fd) {
assert.isNumber(fd.fd);
assert.isTrue(fs.existsSync('path/to/new.txt'));
done();
})
.catch(done);
});
it('opens an existing file for writing (w)', function (done) {
fs.open('path/to/file.txt', 'w', parseInt('0666', 8), function (err, fd) {
if (err) {
return done(err);
}
assert.isNumber(fd);
done();
});
});
it('promise opens an existing file for writing (w)', function (done) {
fs.promises
.open('path/to/file.txt', 'w', parseInt('0666', 8))
.then(function (fd) {
assert.isNumber(fd.fd);
done();
})
.catch(done);
});
it('fails if file exists (wx)', function (done) {
fs.open('path/to/file.txt', 'wx', parseInt('0666', 8), function (err, fd) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
});
});
it('promise fails if file exists (wx)', function (done) {
fs.promises.open('path/to/file.txt', 'wx', parseInt('0666', 8)).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EEXIST');
done();
},
);
});
});
describe('fs.openSync(path, flags, [mode])', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
nested: {
sub: {
dir: {
'one.txt': 'one content',
'two.txt': 'two content',
empty: {},
},
},
},
});
});
afterEach(mock.restore);
it('opens an existing file for reading (r)', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
assert.isNumber(fd);
});
it('fails if file does not exist (r)', function () {
assert.throws(function () {
fs.openSync('bogus.txt', 'r');
});
});
it('creates a new file for writing (w)', function () {
const fd = fs.openSync('nested/sub/new.txt', 'w', parseInt('0666', 8));
assert.isNumber(fd);
assert.isTrue(fs.existsSync('nested/sub/new.txt'));
});
it('opens an existing file for writing (w)', function () {
const fd = fs.openSync('path/to/one.txt', 'w', parseInt('0666', 8));
assert.isNumber(fd);
});
it('fails if file exists (wx)', function () {
assert.throws(function () {
fs.openSync('path/to/file.txt', 'wx', parseInt('0666', 8));
});
});
});
describe('fs.close(fd, callback)', function () {
beforeEach(function () {
mock({dir: {}});
});
afterEach(mock.restore);
it('closes a file descriptor', function (done) {
const fd = fs.openSync('dir/file.txt', 'w');
fs.close(fd, function (err) {
done(err);
});
});
it('promise closes a file descriptor', function (done) {
fs.promises
.open('dir/file.txt', 'w')
.then(function (fd) {
return fd.close();
})
.then(done, done);
});
it('fails for closed file descriptors', function (done) {
const fd = fs.openSync('dir/file.txt', 'w');
fs.close(fd, function (err) {
if (err) {
return done(err);
}
fs.close(fd, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
done();
});
});
});
});
describe('fs.closeSync(fd)', function () {
beforeEach(function () {
mock({dir: {}});
});
afterEach(mock.restore);
it('closes a file descriptor', function () {
const fd = fs.openSync('dir/file.txt', 'w');
fs.closeSync(fd);
});
it('fails for closed file descriptors', function () {
const fd = fs.openSync('dir/file.txt', 'w');
fs.closeSync(fd);
assert.throws(function () {
fs.closeSync(fd);
});
});
});
mock-fs-5.5.0/test/lib/fs.read.spec.js 0000664 0000000 0000000 00000022021 14751162414 0017420 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.read(fd, buffer, offset, length, position, callback)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('allows file contents to be read', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.alloc(12);
fs.read(fd, buffer, 0, 12, 0, function (err2, bytesRead, buf) {
if (err2) {
return done(err2);
}
assert.equal(bytesRead, 12);
assert.equal(buf, buffer);
assert.equal(String(buffer), 'file content');
done();
});
});
});
it('promise allows file contents to be read', function (done) {
const buffer = Buffer.alloc(12);
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.read(buffer, 0, 12, 0);
})
.then(function (result) {
assert.equal(result.bytesRead, 12);
assert.equal(result.buffer, buffer);
assert.equal(String(buffer), 'file content');
done();
})
.catch(done);
});
it('allows file contents to be read w/ offset', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.alloc(12);
fs.read(fd, buffer, 5, 7, 0, function (err2, bytesRead, buf) {
if (err2) {
return done(err2);
}
assert.equal(bytesRead, 7);
assert.equal(buf, buffer);
assert.equal(String(buffer.slice(5)), 'file co');
done();
});
});
});
it('promise allows file contents to be read w/ offset', function (done) {
const buffer = Buffer.alloc(12);
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.read(buffer, 5, 7, 0);
})
.then(function (result) {
assert.equal(result.bytesRead, 7);
assert.equal(result.buffer, buffer);
assert.equal(String(buffer.slice(5)), 'file co');
done();
})
.catch(done);
});
it('allows file contents to be read w/ length', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.alloc(12);
fs.read(fd, buffer, 0, 4, 0, function (err2, bytesRead, buf) {
if (err2) {
return done(err2);
}
assert.equal(bytesRead, 4);
assert.equal(buf, buffer);
assert.equal(String(buffer.slice(0, 4)), 'file');
done();
});
});
});
it('promise allows file contents to be read w/ length', function (done) {
const buffer = Buffer.alloc(12);
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.read(buffer, 0, 4, 0);
})
.then(function (result) {
assert.equal(result.bytesRead, 4);
assert.equal(result.buffer, buffer);
assert.equal(String(buffer.slice(0, 4)), 'file');
done();
})
.catch(done);
});
it('allows file contents to be read w/ offset & length', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.alloc(12);
fs.read(fd, buffer, 2, 4, 0, function (err2, bytesRead, buf) {
if (err2) {
return done(err2);
}
assert.equal(bytesRead, 4);
assert.equal(buf, buffer);
assert.equal(String(buffer.slice(2, 6)), 'file');
done();
});
});
});
it('promise allows file contents to be read w/ offset & length', function (done) {
const buffer = Buffer.alloc(12);
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.read(buffer, 2, 4, 0);
})
.then(function (result) {
assert.equal(result.bytesRead, 4);
assert.equal(result.buffer, buffer);
assert.equal(String(buffer.slice(2, 6)), 'file');
done();
})
.catch(done);
});
it('allows file contents to be read w/ position', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.alloc(7);
fs.read(fd, buffer, 0, 7, 5, function (err2, bytesRead, buf) {
if (err2) {
return done(err2);
}
assert.equal(bytesRead, 7);
assert.equal(buf, buffer);
assert.equal(String(buffer), 'content');
done();
});
});
});
it('promise allows file contents to be read w/ position', function (done) {
const buffer = Buffer.alloc(7);
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.read(buffer, 0, 7, 5);
})
.then(function (result) {
assert.equal(result.bytesRead, 7);
assert.equal(result.buffer, buffer);
assert.equal(String(buffer), 'content');
done();
})
.catch(done);
});
it('allows read w/ offset, length, & position', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.alloc(12);
fs.read(fd, buffer, 2, 7, 5, function (err2, bytesRead, buf) {
if (err2) {
return done(err2);
}
assert.equal(bytesRead, 7);
assert.equal(buf, buffer);
assert.equal(String(buffer.slice(2, 9)), 'content');
done();
});
});
});
it('promise allows read w/ offset, length, & position', function (done) {
const buffer = Buffer.alloc(12);
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.read(buffer, 2, 7, 5);
})
.then(function (result) {
assert.equal(result.bytesRead, 7);
assert.equal(result.buffer, buffer);
assert.equal(String(buffer.slice(2, 9)), 'content');
done();
})
.catch(done);
});
it('fails for closed file descriptor', function (done) {
const fd = fs.openSync('path/to/file.txt', 'r');
fs.closeSync(fd);
fs.read(fd, Buffer.alloc(12), 0, 12, 0, function (err, bytesRead, buf) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
assert.equal(0, bytesRead);
done();
});
});
it('promise fails for closed file descriptor', function (done) {
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.close().then(function () {
return fd.read(Buffer.alloc(12), 0, 12, 0);
});
})
.then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
done();
},
);
});
it('fails if not open for reading', function (done) {
const fd = fs.openSync('path/to/file.txt', 'w');
fs.read(fd, Buffer.alloc(12), 0, 12, 0, function (err, bytesRead, buf) {
assert.instanceOf(err, Error);
assert.equal(0, bytesRead);
done();
});
});
it('promise fails if not open for reading', function (done) {
fs.promises
.open('path/to/file.txt', 'w')
.then(function (fd) {
return fd.read(Buffer.alloc(12), 0, 12, 0);
})
.then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
done();
},
);
});
});
describe('fs.readSync(fd, buffer, offset, length, position)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('allows a file to be read synchronously', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
const buffer = Buffer.alloc(12);
const read = fs.readSync(fd, buffer, 0, 12, 0);
assert.equal(read, 12);
assert.equal(String(buffer), 'file content');
});
it('allows a file to be read in two parts', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
const first = Buffer.alloc(4);
fs.readSync(fd, first, 0, 4, 0);
assert.equal(String(first), 'file');
const second = Buffer.alloc(7);
fs.readSync(fd, second, 0, 7, 5);
assert.equal(String(second), 'content');
});
it('treats null position as current position', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
const first = Buffer.alloc(4);
fs.readSync(fd, first, 0, 4, null);
assert.equal(String(first), 'file');
// consume the space
assert.equal(fs.readSync(fd, Buffer.alloc(1), 0, 1, null), 1);
const second = Buffer.alloc(7);
fs.readSync(fd, second, 0, 7, null);
assert.equal(String(second), 'content');
});
});
mock-fs-5.5.0/test/lib/fs.readFile.spec.js 0000664 0000000 0000000 00000006324 14751162414 0020230 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.readFile(filename, [options], callback)', function () {
// this is provided by fs.open, fs.fstat, and fs.read
// so more heavily tested elsewhere
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('allows a file to be read asynchronously', function (done) {
fs.readFile('path/to/file.txt', function (err, data) {
if (err) {
return done(err);
}
assert.isTrue(Buffer.isBuffer(data));
assert.equal(String(data), 'file content');
done();
});
});
it('promise allows a file to be read asynchronously', function (done) {
fs.promises
.readFile('path/to/file.txt')
.then(function (data) {
assert.isTrue(Buffer.isBuffer(data));
assert.equal(String(data), 'file content');
done();
})
.catch(done);
});
it('fails for directory', function (done) {
fs.readFile('path/to', function (err, data) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EISDIR');
done();
});
});
it('promise fails for directory', function (done) {
fs.promises.readFile('path/to').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EISDIR');
done();
},
);
});
it('fails for bad path', function (done) {
fs.readFile('path/to/bogus', function (err, data) {
assert.instanceOf(err, Error);
// windows has different errno for ENOENT
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails for bad path', function (done) {
fs.promises.readFile('path/to/bogus').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
// windows has different errno for ENOENT
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.readFileSync(filename, [options])', function () {
// this is provided by fs.openSync, fs.fstatSync, and fs.readSync
// so more heavily tested elsewhere
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('works with utf-8', function () {
const content = fs.readFileSync('path/to/file.txt', 'utf-8').toString();
assert.equal(content, 'file content');
});
it('allows a file to be read synchronously', function () {
const data = fs.readFileSync('path/to/file.txt');
assert.isTrue(Buffer.isBuffer(data));
assert.equal(String(data), 'file content');
});
it('fails for directory', function () {
try {
fs.readFileSync('path/to');
assert.fail('should not succeed.');
} catch (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EISDIR');
}
});
it('fails for bad path', function () {
assert.throws(function () {
fs.readFileSync('path/to/bogus');
});
});
});
mock-fs-5.5.0/test/lib/fs.readdir.spec.js 0000664 0000000 0000000 00000014760 14751162414 0020132 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.readdir(path, callback)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
nested: {
sub: {
dir: {
'one.txt': 'one content',
'two.txt': 'two content',
empty: {},
},
},
},
denied: mock.directory({
mode: 0o000,
items: [
{
'one.txt': 'content',
},
],
}),
});
});
afterEach(mock.restore);
it('lists directory contents', function (done) {
fs.readdir(path.join('path', 'to'), function (err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items, ['file.txt']);
done();
});
});
it('supports Buffer input', function (done) {
fs.readdir(Buffer.from(path.join('path', 'to')), function (err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items, ['file.txt']);
done();
});
});
it('promise lists directory contents', function (done) {
fs.promises
.readdir(path.join('path', 'to'))
.then(function (items) {
assert.isArray(items);
assert.deepEqual(items, ['file.txt']);
done();
})
.catch(done);
});
it('lists nested directory contents', function (done) {
fs.readdir(path.join('nested', 'sub', 'dir'), function (err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items, ['empty', 'one.txt', 'two.txt']);
done();
});
});
it('promise lists nested directory contents', function (done) {
fs.promises
.readdir(path.join('nested', 'sub', 'dir'))
.then(function (items) {
assert.isArray(items);
assert.deepEqual(items, ['empty', 'one.txt', 'two.txt']);
done();
})
.catch(done);
});
it('calls with an error for bogus path', function (done) {
fs.readdir('bogus', function (err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
});
});
it('promise calls with an error for bogus path', function (done) {
fs.promises.readdir('bogus').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
done();
},
);
});
it('calls with an error for restricted path', function (done) {
fs.readdir('denied', function (err, items) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
assert.isUndefined(items);
done();
});
});
it('promise calls with an error for restricted path', function (done) {
fs.promises.readdir('denied').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
it('should support "withFileTypes" option', function (done) {
fs.readdir(
path.join('nested', 'sub', 'dir'),
{withFileTypes: true},
function (err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(
items.map((i) => i.name),
['empty', 'one.txt', 'two.txt'],
);
assert.ok(items[0].isDirectory());
assert.ok(items[1].isFile());
assert.ok(items[2].isFile());
done();
},
);
});
it('should support "withFileTypes" option', function (done) {
fs.promises
.readdir(path.join('nested', 'sub', 'dir'), {withFileTypes: true})
.then(function (items) {
assert.isArray(items);
assert.deepEqual(
items.map((i) => i.name),
['empty', 'one.txt', 'two.txt'],
);
assert.ok(items[0].isDirectory());
assert.ok(items[1].isFile());
assert.ok(items[2].isFile());
done();
})
.catch(done);
});
it('should support "withFileTypes" option with "encoding" option', function (done) {
fs.readdir(
path.join('nested', 'sub', 'dir'),
{withFileTypes: true, encoding: 'buffer'},
function (err, items) {
assert.isNull(err);
assert.isArray(items);
items.forEach(function (item) {
assert.equal(Buffer.isBuffer(item.name), true);
});
const names = items.map(function (item) {
return item.name.toString();
});
assert.deepEqual(names, ['empty', 'one.txt', 'two.txt']);
assert.ok(items[0].isDirectory());
assert.ok(items[1].isFile());
assert.ok(items[2].isFile());
done();
},
);
});
it('should support "withFileTypes" option with "encoding" option', function (done) {
fs.promises
.readdir(path.join('nested', 'sub', 'dir'), {
withFileTypes: true,
encoding: 'buffer',
})
.then(function (items) {
assert.isArray(items);
items.forEach(function (item) {
assert.equal(Buffer.isBuffer(item.name), true);
});
const names = items.map(function (item) {
return item.name.toString();
});
assert.deepEqual(names, ['empty', 'one.txt', 'two.txt']);
assert.ok(items[0].isDirectory());
assert.ok(items[1].isFile());
assert.ok(items[2].isFile());
done();
});
});
});
describe('fs.readdirSync(path)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
nested: {
sub: {
dir: {
'one.txt': 'one content',
'two.txt': 'two content',
empty: {},
},
},
},
});
});
afterEach(mock.restore);
it('lists directory contents', function () {
const items = fs.readdirSync(path.join('path', 'to'));
assert.isArray(items);
assert.deepEqual(items, ['file.txt']);
});
it('lists nested directory contents', function () {
const items = fs.readdirSync(path.join('nested', 'sub', 'dir'));
assert.isArray(items);
assert.deepEqual(items, ['empty', 'one.txt', 'two.txt']);
});
it('throws for bogus path', function () {
assert.throws(function () {
fs.readdirSync('bogus');
});
});
it('throws when access refused', function () {
assert.throws(function () {
fs.readdirSync('denied');
});
});
});
mock-fs-5.5.0/test/lib/fs.readlink.spec.js 0000664 0000000 0000000 00000003713 14751162414 0020305 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.readlink(path, callback)', function () {
beforeEach(function () {
mock({
'file.txt': 'content',
link: mock.symlink({path: './file.txt'}),
});
});
afterEach(mock.restore);
it('reads a symbolic link', function (done) {
fs.readlink('link', function (err, srcPath) {
if (err) {
return done(err);
}
assert.equal(srcPath, './file.txt');
done();
});
});
it('supports Buffer input', function (done) {
fs.readlink(Buffer.from('link'), function (err, srcPath) {
if (err) {
return done(err);
}
assert.equal(srcPath, './file.txt');
done();
});
});
it('promise reads a symbolic link', function (done) {
fs.promises
.readlink('link')
.then(function (srcPath) {
assert.equal(srcPath, './file.txt');
done();
})
.catch(done);
});
it('fails for regular files', function (done) {
fs.readlink('file.txt', function (err, srcPath) {
assert.instanceOf(err, Error);
done();
});
});
it('promise fails for regular files', function (done) {
fs.promises.readlink('file.txt').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
done();
},
);
});
});
describe('fs.readlinkSync(path)', function () {
beforeEach(function () {
mock({
'file.txt': 'content',
link: mock.symlink({path: './file.txt'}),
});
});
afterEach(mock.restore);
it('reads a symbolic link', function () {
assert.equal(fs.readlinkSync('link'), './file.txt');
});
it('fails for regular files', function () {
assert.throws(function () {
fs.readlinkSync('file.txt');
});
});
});
mock-fs-5.5.0/test/lib/fs.realpath.spec.js 0000664 0000000 0000000 00000011174 14751162414 0020314 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const path = require('path');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
const assertEqualPaths = helper.assertEqualPaths;
describe('fs.realpath(path, [cache], callback)', function () {
beforeEach(function () {
mock({
'dir/file.txt': 'content',
link: mock.symlink({path: './dir/file.txt'}),
});
});
afterEach(mock.restore);
it('resolves the real path for a symbolic link', function (done) {
fs.realpath('link', function (err, resolved) {
if (err) {
return done(err);
}
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
done();
});
});
it('promise resolves the real path for a symbolic link', function (done) {
fs.promises
.realpath('link')
.then(function (resolved) {
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
done();
})
.catch(done);
});
it('resolves the real path regular file', function (done) {
fs.realpath('dir/file.txt', function (err, resolved) {
if (err) {
return done(err);
}
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
done();
});
});
it('promise resolves the real path regular file', function (done) {
fs.promises
.realpath('dir/file.txt')
.then(function (resolved) {
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
done();
})
.catch(done);
});
it('fails on file not exist', function (done) {
fs.realpath('bogus', function (err, resolved) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails on file not exist', function (done) {
fs.promises.realpath('bogus').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
if (fs.realpath.native) {
describe('fs.realpath.native(path, [cache], callback)', function () {
beforeEach(function () {
mock({
'dir/file.txt': 'content',
link: mock.symlink({path: './dir/file.txt'}),
});
});
afterEach(mock.restore);
it('resolves the real path for a symbolic link', function (done) {
fs.realpath.native('link', function (err, resolved) {
if (err) {
return done(err);
}
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
done();
});
});
it('resolves the real path regular file', function (done) {
fs.realpath.native('dir/file.txt', function (err, resolved) {
if (err) {
return done(err);
}
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
done();
});
});
it('fails on file not exist', function (done) {
fs.realpath.native('bogus', function (err, resolved) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
});
}
describe('fs.realpathSync(path, [cache])', function () {
beforeEach(function () {
mock({
'dir/file.txt': 'content',
link: mock.symlink({path: './dir/file.txt'}),
});
});
afterEach(mock.restore);
it('resolves the real path for a symbolic link', function () {
const resolved = fs.realpathSync('link');
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
});
it('resolves the real path regular file', function () {
const resolved = fs.realpathSync('dir/file.txt');
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
});
it('fails on file not exist', function () {
assert.throws(function () {
fs.realpathSync('bogus');
});
});
});
if (fs.realpathSync.native) {
describe('fs.realpathSync.native(path, [cache])', function () {
beforeEach(function () {
mock({
'dir/file.txt': 'content',
link: mock.symlink({path: './dir/file.txt'}),
});
});
afterEach(mock.restore);
it('resolves the real path for a symbolic link', function () {
const resolved = fs.realpathSync.native('link');
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
});
it('resolves the real path regular file', function () {
const resolved = fs.realpathSync.native('dir/file.txt');
assertEqualPaths(resolved, path.resolve('dir/file.txt'));
});
it('fails on file not exist', function () {
assert.throws(function () {
fs.realpathSync.native('bogus');
});
});
});
}
mock-fs-5.5.0/test/lib/fs.rename.spec.js 0000664 0000000 0000000 00000015122 14751162414 0017760 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.rename(oldPath, newPath, callback)', function () {
beforeEach(function () {
mock({
'path/to/a.bin': Buffer.from([1, 2, 3]),
empty: {},
nested: {
dir: mock.directory({
mtime: new Date(1),
items: {'file.txt': ''},
}),
},
});
});
afterEach(mock.restore);
it('allows files to be renamed', function (done) {
fs.rename('path/to/a.bin', 'path/to/b.bin', function (err) {
assert.isTrue(!err);
assert.isFalse(fs.existsSync('path/to/a.bin'));
assert.isTrue(fs.existsSync('path/to/b.bin'));
done();
});
});
it('supports Buffer input', function (done) {
fs.rename(
Buffer.from('path/to/a.bin'),
Buffer.from('path/to/b.bin'),
function (err) {
assert.isTrue(!err);
assert.isFalse(fs.existsSync('path/to/a.bin'));
assert.isTrue(fs.existsSync('path/to/b.bin'));
done();
},
);
});
it('promise allows files to be renamed', function (done) {
fs.promises
.rename('path/to/a.bin', 'path/to/b.bin')
.then(function () {
assert.isFalse(fs.existsSync('path/to/a.bin'));
assert.isTrue(fs.existsSync('path/to/b.bin'));
done();
})
.catch(done);
});
it('updates mtime of parent directory', function (done) {
const oldTime = fs.statSync('nested/dir').mtime;
fs.rename('nested/dir/file.txt', 'nested/dir/renamed.txt', function (err) {
assert.isTrue(!err);
assert.isFalse(fs.existsSync('nested/dir/file.txt'));
assert.isTrue(fs.existsSync('nested/dir/renamed.txt'));
const newTime = fs.statSync('nested/dir').mtime;
assert.isTrue(newTime > oldTime);
done();
});
});
it('promise updates mtime of parent directory', function (done) {
const oldTime = fs.statSync('nested/dir').mtime;
fs.promises
.rename('nested/dir/file.txt', 'nested/dir/renamed.txt')
.then(function () {
assert.isFalse(fs.existsSync('nested/dir/file.txt'));
assert.isTrue(fs.existsSync('nested/dir/renamed.txt'));
const newTime = fs.statSync('nested/dir').mtime;
assert.isTrue(newTime > oldTime);
done();
})
.catch(done);
});
it('calls callback with error if old path does not exist', function (done) {
fs.rename('bogus', 'empty', function (err) {
assert.instanceOf(err, Error);
done();
});
});
it('promise calls callback with error if old path does not exist', function (done) {
fs.promises.rename('bogus', 'empty').then(
function () {
done(new Error('Should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
done();
},
);
});
it('overwrites existing files', function (done) {
fs.rename('path/to/a.bin', 'nested/dir/file.txt', function (err) {
assert.isTrue(!err);
assert.isFalse(fs.existsSync('path/to/a.bin'));
assert.isTrue(fs.existsSync('nested/dir/file.txt'));
done();
});
});
it('promise overwrites existing files', function (done) {
fs.promises
.rename('path/to/a.bin', 'nested/dir/file.txt')
.then(function () {
assert.isFalse(fs.existsSync('path/to/a.bin'));
assert.isTrue(fs.existsSync('nested/dir/file.txt'));
done();
})
.catch(done);
});
it('allows directories to be renamed', function (done) {
fs.rename('path/to', 'path/foo', function (err) {
assert.isTrue(!err);
assert.isFalse(fs.existsSync('path/to'));
assert.isTrue(fs.existsSync('path/foo'));
assert.deepEqual(fs.readdirSync('path/foo'), ['a.bin']);
done();
});
});
it('promise allows directories to be renamed', function (done) {
fs.promises
.rename('path/to', 'path/foo')
.then(function () {
assert.isFalse(fs.existsSync('path/to'));
assert.isTrue(fs.existsSync('path/foo'));
assert.deepEqual(fs.readdirSync('path/foo'), ['a.bin']);
done();
})
.catch(done);
});
it('calls callback with error if new directory not empty', function (done) {
fs.rename('path', 'nested', function (err) {
assert.instanceOf(err, Error);
done();
});
});
it('promise calls callback with error if new directory not empty', function (done) {
fs.promises.rename('path', 'nested').then(
function () {
done(new Error('Should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
done();
},
);
});
});
describe('fs.renameSync(oldPath, newPath)', function () {
beforeEach(function () {
mock({
'path/to/a.bin': Buffer.from([1, 2, 3]),
empty: {},
nested: {
dir: {
'file.txt': '',
},
},
link: mock.symlink({path: './path/to/a.bin'}),
});
});
afterEach(mock.restore);
it('allows files to be renamed', function () {
fs.renameSync('path/to/a.bin', 'path/to/b.bin');
assert.isFalse(fs.existsSync('path/to/a.bin'));
assert.isTrue(fs.existsSync('path/to/b.bin'));
});
it('overwrites existing files', function () {
fs.renameSync('path/to/a.bin', 'nested/dir/file.txt');
assert.isFalse(fs.existsSync('path/to/a.bin'));
assert.isTrue(fs.existsSync('nested/dir/file.txt'));
});
it('allows directories to be renamed', function () {
fs.renameSync('path/to', 'path/foo');
assert.isFalse(fs.existsSync('path/to'));
assert.isTrue(fs.existsSync('path/foo'));
assert.deepEqual(fs.readdirSync('path/foo'), ['a.bin']);
});
it('replaces existing directories (if empty)', function () {
fs.renameSync('path/to', 'empty');
assert.isFalse(fs.existsSync('path/to'));
assert.isTrue(fs.existsSync('empty'));
assert.deepEqual(fs.readdirSync('empty'), ['a.bin']);
});
it('renames symbolic links', function () {
fs.renameSync('link', 'renamed');
assert.isTrue(fs.existsSync('renamed'));
assert.isFalse(fs.existsSync('link'));
assert.isTrue(fs.existsSync('path/to/a.bin'));
});
it('throws if old path does not exist', function () {
assert.throws(function () {
fs.renameSync('bogus', 'empty');
});
});
it('throws if new path basename is not directory', function () {
assert.throws(function () {
fs.renameSync('path/to/a.bin', 'bogus/a.bin');
});
});
it('throws if new dir is not empty dir', function () {
assert.throws(function () {
fs.renameSync('path/to', 'nested');
});
});
});
mock-fs-5.5.0/test/lib/fs.rmdir.spec.js 0000664 0000000 0000000 00000014174 14751162414 0017634 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
const testParentPerms = process.getuid && process.getgid;
function setup() {
mock({
'path/to/empty': {},
'path2/to': {
empty: {
deep: {},
},
'non-empty': {
deep: {
'b.file': 'lorem',
},
'a.file': '',
},
},
'file.txt': 'content',
unwriteable: mock.directory({
mode: parseInt('0555', 8),
items: {child: {}},
}),
});
}
describe('fs.rmdir(path, callback)', function () {
beforeEach(setup);
afterEach(mock.restore);
it('removes an empty directory', function (done) {
assert.equal(fs.statSync('path/to').nlink, 3);
fs.rmdir('path/to/empty', function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('path/to/empty'));
assert.equal(fs.statSync('path/to').nlink, 2);
done();
});
});
it('supports Buffer input', function (done) {
assert.equal(fs.statSync('path/to').nlink, 3);
fs.rmdir(Buffer.from('path/to/empty'), function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('path/to/empty'));
assert.equal(fs.statSync('path/to').nlink, 2);
done();
});
});
it('promise removes an empty directory', function (done) {
assert.equal(fs.statSync('path/to').nlink, 3);
fs.promises
.rmdir('path/to/empty')
.then(function () {
assert.isFalse(fs.existsSync('path/to/empty'));
assert.equal(fs.statSync('path/to').nlink, 2);
done();
})
.catch(done);
});
it('fails if not empty', function (done) {
fs.rmdir('path/to', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOTEMPTY');
done();
});
});
it('promise fails if not empty', function (done) {
fs.promises.rmdir('path/to').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOTEMPTY');
done();
},
);
});
it('fails if file', function (done) {
fs.rmdir('file.txt', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOTDIR');
done();
});
});
it('promise fails if file', function (done) {
fs.promises.rmdir('file.txt').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOTDIR');
done();
},
);
});
it('recursively remove empty directory', function (done) {
assert.equal(fs.statSync('path2/to').nlink, 4);
fs.rmdir('path2/to/empty', {recursive: true}, function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('path2/to/empty'));
assert.equal(fs.statSync('path2/to').nlink, 3);
done();
});
});
it('promise recursively remove empty directory', function (done) {
assert.equal(fs.statSync('path2/to').nlink, 4);
fs.promises
.rmdir('path2/to/empty', {recursive: true})
.then(function () {
assert.isFalse(fs.existsSync('path2/to/empty'));
assert.equal(fs.statSync('path2/to').nlink, 3);
done();
})
.catch(done);
});
it('recursively remove non-empty directory', function (done) {
assert.equal(fs.statSync('path2/to').nlink, 4);
fs.rmdir('path2/to/non-empty', {recursive: true}, function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('path2/to/non-empty'));
assert.equal(fs.statSync('path2/to').nlink, 3);
done();
});
});
it('promise recursively remove non-empty directory', function (done) {
assert.equal(fs.statSync('path2/to').nlink, 4);
fs.promises
.rmdir('path2/to/non-empty', {recursive: true})
.then(function () {
assert.isFalse(fs.existsSync('path2/to/non-empty'));
assert.equal(fs.statSync('path2/to').nlink, 3);
done();
})
.catch(done);
});
if (testParentPerms) {
it('fails if parent is not writeable', function (done) {
fs.rmdir('unwriteable/child', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
});
});
it('promise fails if parent is not writeable', function (done) {
fs.promises.rmdir('unwriteable/child').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
done();
},
);
});
}
});
describe('fs.rmdirSync(path)', function () {
beforeEach(setup);
afterEach(mock.restore);
it('removes an empty directory', function () {
fs.rmdirSync('path/to/empty');
assert.isFalse(fs.existsSync('path/empty'));
});
it('fails if directory does not exist', function () {
assert.throws(function () {
fs.rmdirSync('path/bogus');
});
});
it('fails if not empty', function () {
assert.throws(function () {
fs.rmdirSync('path');
});
});
it('fails if file', function () {
assert.throws(function () {
fs.rmdirSync('file.txt');
});
});
it('recursively remove empty directory', function () {
assert.equal(fs.statSync('path2/to').nlink, 4);
fs.rmdirSync('path2/to/empty', {recursive: true});
assert.isFalse(fs.existsSync('path2/to/empty'));
assert.equal(fs.statSync('path2/to').nlink, 3);
});
it('recursively remove non-empty directory', function () {
assert.equal(fs.statSync('path2/to').nlink, 4);
fs.rmdirSync('path2/to/non-empty', {recursive: true});
assert.isFalse(fs.existsSync('path2/to/non-empty'));
assert.equal(fs.statSync('path2/to').nlink, 3);
});
if (testParentPerms) {
it('fails if parent is not writeable', function () {
assert.throws(function () {
fs.rmdirSync('unwriteable/child');
});
});
}
});
mock-fs-5.5.0/test/lib/fs.stat-fstat.spec.js 0000664 0000000 0000000 00000037407 14751162414 0020615 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it, xit} = require('mocha');
const semver = require('semver');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.stat(path, options, callback)', function () {
beforeEach(function () {
mock({
'/path/to/file.txt': mock.file({
ctime: new Date(1),
mtime: new Date(2),
atime: new Date(3),
uid: 42,
gid: 43,
}),
'/dir/symlink': mock.symlink({
path: '/path/to/file.txt',
mtime: new Date(2),
}),
'/empty': {},
});
});
afterEach(mock.restore);
xit('creates an instance of fs.Stats', function (done) {
fs.stat('/path/to/file.txt', function (err, stats) {
if (err) {
return done(err);
}
assert.instanceOf(stats, fs.Stats);
done();
});
});
xit('promise creates an instance of fs.Stats', function (done) {
fs.promises
.stat('/path/to/file.txt')
.then(function (stats) {
assert.instanceOf(stats, fs.Stats);
done();
})
.catch(done);
});
it('identifies files', function (done) {
fs.stat('/path/to/file.txt', function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.isFalse(stats.isDirectory());
assert.equal(stats.mtime.getTime(), 2);
done();
});
});
it('identifies files with bigint', function (done) {
fs.stat('/path/to/file.txt', {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.isFalse(stats.isDirectory());
assert.equal(typeof stats.mtimeMs, 'bigint');
done();
});
});
it('supports Buffer input', function (done) {
fs.stat(Buffer.from('/path/to/file.txt'), function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.isFalse(stats.isDirectory());
assert.equal(stats.mtime.getTime(), 2);
done();
});
});
it('supports Buffer input with bigint', function (done) {
fs.stat(
Buffer.from('/path/to/file.txt'),
{bigint: true},
function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.isFalse(stats.isDirectory());
assert.equal(typeof stats.mtimeMs, 'bigint');
done();
},
);
});
it('promise identifies files', function (done) {
fs.promises
.stat('/path/to/file.txt')
.then(function (stats) {
assert.isTrue(stats.isFile());
assert.isFalse(stats.isDirectory());
done();
assert.equal(stats.mtime.getTime(), 2);
})
.catch(done);
});
it('promise identifies files', function (done) {
fs.promises
.stat('/path/to/file.txt', {bigint: true})
.then(function (stats) {
assert.isTrue(stats.isFile());
assert.isFalse(stats.isDirectory());
done();
assert.equal(typeof stats.mtimeMs, 'bigint');
})
.catch(done);
});
it('identifies directories', function (done) {
fs.stat('/empty', function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isDirectory());
assert.isFalse(stats.isFile());
assert.equal(stats.size, 1);
done();
});
});
it('identifies directories with bigint', function (done) {
fs.stat('/empty', {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isDirectory());
assert.isFalse(stats.isFile());
assert.equal(typeof stats.size, 'bigint');
done();
});
});
it('promise identifies directories', function (done) {
fs.promises
.stat('/empty')
.then(function (stats) {
assert.isTrue(stats.isDirectory());
assert.isFalse(stats.isFile());
assert.equal(stats.size, 1);
done();
})
.catch(done);
});
it('promise identifies directories with bigint', function (done) {
fs.promises
.stat('/empty', {bigint: true})
.then(function (stats) {
assert.isTrue(stats.isDirectory());
assert.isFalse(stats.isFile());
assert.equal(typeof stats.size, 'bigint');
done();
})
.catch(done);
});
it('provides file stats', function (done) {
fs.stat('/path/to/file.txt', function (err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.ctime.getTime(), 1);
assert.equal(stats.mtime.getTime(), 2);
assert.equal(stats.atime.getTime(), 3);
assert.equal(stats.uid, 42);
assert.equal(stats.gid, 43);
assert.equal(stats.nlink, 1);
assert.isNumber(stats.rdev);
done();
});
});
it('provides file stats with bigint', function (done) {
fs.stat('/path/to/file.txt', {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.equal(typeof stats.ctimeMs, 'bigint');
assert.equal(typeof stats.mtimeMs, 'bigint');
assert.equal(typeof stats.atimeMs, 'bigint');
assert.equal(typeof stats.uid, 'bigint');
assert.equal(typeof stats.gid, 'bigint');
assert.equal(typeof stats.nlink, 'bigint');
assert.equal(typeof stats.rdev, 'bigint');
done();
});
});
it('promise provides file stats', function (done) {
fs.promises
.stat('/path/to/file.txt')
.then(function (stats) {
assert.equal(stats.ctime.getTime(), 1);
assert.equal(stats.mtime.getTime(), 2);
assert.equal(stats.atime.getTime(), 3);
assert.equal(stats.uid, 42);
assert.equal(stats.gid, 43);
assert.equal(stats.nlink, 1);
assert.isNumber(stats.rdev);
done();
})
.catch(done);
});
it('promise provides file stats with bigint', function (done) {
fs.promises
.stat('/path/to/file.txt', {bigint: true})
.then(function (stats) {
assert.equal(typeof stats.ctimeMs, 'bigint');
assert.equal(typeof stats.mtimeMs, 'bigint');
assert.equal(typeof stats.atimeMs, 'bigint');
assert.equal(typeof stats.uid, 'bigint');
assert.equal(typeof stats.gid, 'bigint');
assert.equal(typeof stats.nlink, 'bigint');
assert.equal(typeof stats.rdev, 'bigint');
done();
})
.catch(done);
});
if (
process.platform !== 'win32' ||
semver.coerce(process.version).major !== 10
) {
// The fix for https://github.com/nodejs/node/issues/25913
// is not shipped in v10. But it's shipped in v12.
it('includes blocks and blksize in stats', function (done) {
fs.stat('/path/to/file.txt', function (err, stats) {
if (err) {
return done(err);
}
assert.isNumber(stats.blocks);
assert.isNumber(stats.blksize);
done();
});
});
it('promise includes blocks and blksize in stats', function (done) {
fs.promises
.stat('/path/to/file.txt')
.then(function (stats) {
assert.isNumber(stats.blocks);
assert.isNumber(stats.blksize);
done();
})
.catch(done);
});
}
it('provides directory stats', function (done) {
fs.stat('/path', function (err, stats) {
if (err) {
return done(err);
}
assert.instanceOf(stats.ctime, Date);
assert.instanceOf(stats.mtime, Date);
assert.instanceOf(stats.atime, Date);
if (process.getuid) {
assert.isNumber(stats.uid);
} else {
assert.strictEqual(stats.uid, 0);
}
if (process.getgid) {
assert.isNumber(stats.gid);
} else {
assert.strictEqual(stats.gid, 0);
}
assert.equal(stats.nlink, 3);
assert.isNumber(stats.rdev);
done();
});
});
it('provides directory stats with bigint', function (done) {
fs.stat('/path', {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.instanceOf(stats.ctime, Date);
assert.instanceOf(stats.mtime, Date);
assert.instanceOf(stats.atime, Date);
if (process.getuid) {
assert.equal(typeof stats.uid, 'bigint');
} else {
assert.strictEqual(stats.uid, 0n);
}
if (process.getgid) {
assert.equal(typeof stats.gid, 'bigint');
} else {
assert.strictEqual(stats.gid, 0n);
}
assert.equal(typeof stats.nlink, 'bigint');
assert.equal(typeof stats.rdev, 'bigint');
done();
});
});
it('promise provides directory stats', function (done) {
fs.promises
.stat('/path')
.then(function (stats) {
assert.instanceOf(stats.ctime, Date);
assert.instanceOf(stats.mtime, Date);
assert.instanceOf(stats.atime, Date);
if (process.getuid) {
assert.isNumber(stats.uid);
} else {
assert.strictEqual(stats.uid, 0);
}
if (process.getgid) {
assert.isNumber(stats.gid);
} else {
assert.strictEqual(stats.gid, 0);
}
assert.equal(stats.nlink, 3);
assert.isNumber(stats.rdev);
done();
})
.catch(done);
});
it('promise provides directory stats with bigint', function (done) {
fs.promises
.stat('/path', {bigint: true})
.then(function (stats) {
assert.instanceOf(stats.ctime, Date);
assert.instanceOf(stats.mtime, Date);
assert.instanceOf(stats.atime, Date);
if (process.getuid) {
assert.equal(typeof stats.uid, 'bigint');
} else {
assert.strictEqual(stats.uid, 0n);
}
if (process.getgid) {
assert.equal(typeof stats.gid, 'bigint');
} else {
assert.strictEqual(stats.gid, 0n);
}
assert.equal(typeof stats.nlink, 'bigint');
assert.equal(typeof stats.rdev, 'bigint');
done();
})
.catch(done);
});
if (
process.platform !== 'win32' ||
semver.coerce(process.version).major !== 10
) {
// The fix for https://github.com/nodejs/node/issues/25913
// is not shipped in v10. But it's shipped in v12.
it('includes blocks and blksize in directory stats', function (done) {
fs.stat('/path', function (err, stats) {
if (err) {
return done(err);
}
assert.isNumber(stats.blocks);
assert.isNumber(stats.blksize);
done();
});
});
it('promise includes blocks and blksize in directory stats', function (done) {
fs.promises
.stat('/path')
.then(function (stats) {
assert.isNumber(stats.blocks);
assert.isNumber(stats.blksize);
done();
})
.catch(done);
});
}
});
describe('fs.fstat(fd, options, callback)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
empty: {},
});
});
afterEach(mock.restore);
it('accepts a file descriptor for a file (r)', function (done) {
const fd = fs.openSync('path/to/file.txt', 'r');
fs.fstat(fd, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.equal(stats.size, 12);
done();
});
});
it('accepts a file descriptor for a file (r) with bigint', function (done) {
const fd = fs.openSync('path/to/file.txt', 'r');
fs.fstat(fd, {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.equal(typeof stats.size, 'bigint');
done();
});
});
it('promise accepts a file descriptor for a file (r)', function (done) {
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.stat();
})
.then(function (stats) {
assert.isTrue(stats.isFile());
assert.equal(stats.size, 12);
done();
})
.catch(done);
});
it('promise accepts a file descriptor for a file (r) with bigint', function (done) {
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.stat({bigint: true});
})
.then(function (stats) {
assert.isTrue(stats.isFile());
assert.equal(typeof stats.size, 'bigint');
done();
})
.catch(done);
});
it('accepts a file descriptor for a directory (r)', function (done) {
const fd = fs.openSync('path/to', 'r');
fs.fstat(fd, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isDirectory());
assert.equal(stats.size, 1);
done();
});
});
it('accepts a file descriptor for a directory (r) with bigint', function (done) {
const fd = fs.openSync('path/to', 'r');
fs.fstat(fd, {bigint: true}, function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isDirectory());
assert.equal(typeof stats.size, 'bigint');
done();
});
});
it('promise accepts a file descriptor for a directory (r)', function (done) {
fs.promises
.open('path/to', 'r')
.then(function (fd) {
return fd.stat();
})
.then(function (stats) {
assert.isTrue(stats.isDirectory());
assert.equal(stats.size, 1);
done();
})
.catch(done);
});
it('promise accepts a file descriptor for a directory (r) with bigint', function (done) {
fs.promises
.open('path/to', 'r')
.then(function (fd) {
return fd.stat({bigint: true});
})
.then(function (stats) {
assert.isTrue(stats.isDirectory());
assert.equal(typeof stats.size, 'bigint');
done();
})
.catch(done);
});
it('fails for bad file descriptor', function (done) {
const fd = fs.openSync('path/to/file.txt', 'r');
fs.closeSync(fd);
fs.fstat(fd, function (err, stats) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
done();
});
});
it('promise fails for bad file descriptor', function (done) {
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.close().then(function () {
return fd.stat({bigint: true});
});
})
.then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
done();
},
);
});
});
describe('fs.fstatSync(fd, options)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
empty: {},
});
});
afterEach(mock.restore);
it('accepts a file descriptor for a file (r)', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
const stats = fs.fstatSync(fd);
assert.isTrue(stats.isFile());
assert.equal(stats.size, 12);
});
it('accepts a file descriptor for a file (r) with bigint', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
const stats = fs.fstatSync(fd, {bigint: true});
assert.isTrue(stats.isFile());
assert.equal(typeof stats.size, 'bigint');
});
it('accepts a file descriptor for a directory (r)', function () {
const fd = fs.openSync('path/to', 'r');
const stats = fs.fstatSync(fd);
assert.isTrue(stats.isDirectory());
assert.equal(stats.size, 1);
});
it('accepts a file descriptor for a directory (r) with bigint', function () {
const fd = fs.openSync('path/to', 'r');
const stats = fs.fstatSync(fd, {bigint: true});
assert.isTrue(stats.isDirectory());
assert.equal(typeof stats.size, 'bigint');
});
it('fails for bad file descriptor', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
fs.closeSync(fd);
assert.throws(function () {
fs.fstatSync(fd);
});
});
});
mock-fs-5.5.0/test/lib/fs.unlink.spec.js 0000664 0000000 0000000 00000010057 14751162414 0020013 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.unlink(path, callback)', function () {
beforeEach(function () {
mock({
dir: {},
dir2: mock.directory({
mtime: new Date(1),
items: {file: 'content here'},
}),
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('deletes a file', function (done) {
fs.unlink('file.txt', function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('file.txt'));
done();
});
});
it('supports Buffer input', function (done) {
fs.unlink(Buffer.from('file.txt'), function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('file.txt'));
done();
});
});
it('promise deletes a file', function (done) {
fs.promises
.unlink('file.txt')
.then(function () {
assert.isFalse(fs.existsSync('file.txt'));
done();
})
.catch(done);
});
it('updates mtime of parent', function (done) {
const oldTime = fs.statSync('dir2').mtime;
fs.unlink('dir2/file', function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('dir2/file'));
const newTime = fs.statSync('dir2').mtime;
assert.isTrue(newTime > oldTime);
done();
});
});
it('updates mtime of parent', function (done) {
const oldTime = fs.statSync('dir2').mtime;
fs.promises
.unlink('dir2/file')
.then(function () {
assert.isFalse(fs.existsSync('dir2/file'));
const newTime = fs.statSync('dir2').mtime;
assert.isTrue(newTime > oldTime);
done();
})
.catch(done);
});
it('fails for a directory', function (done) {
fs.unlink('dir', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EPERM');
assert.isTrue(fs.existsSync('dir'));
done();
});
});
it('promise fails for a directory', function (done) {
fs.promises.unlink('dir').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EPERM');
assert.isTrue(fs.existsSync('dir'));
done();
},
);
});
it('respects previously opened file descriptors', function (done) {
const fd = fs.openSync('file.txt', 'r');
fs.unlink('file.txt', function (err) {
if (err) {
return done(err);
}
assert.isFalse(fs.existsSync('file.txt'));
// but we can still use fd to read
const buffer = Buffer.alloc(7);
const read = fs.readSync(fd, buffer, 0, 7);
assert.equal(read, 7);
assert.equal(String(buffer), 'content');
done();
});
});
it('promise respects previously opened file descriptors', function (done) {
const fd = fs.openSync('file.txt', 'r');
fs.promises
.unlink('file.txt')
.then(function () {
assert.isFalse(fs.existsSync('file.txt'));
// but we can still use fd to read
const buffer = Buffer.alloc(7);
const read = fs.readSync(fd, buffer, 0, 7);
assert.equal(read, 7);
assert.equal(String(buffer), 'content');
done();
})
.catch(done);
});
});
describe('fs.unlinkSync(path)', function () {
beforeEach(function () {
mock({
'file.txt': 'content',
});
});
afterEach(mock.restore);
it('deletes a file', function () {
fs.unlinkSync('file.txt');
assert.isFalse(fs.existsSync('file.txt'));
});
it('respects previously opened file descriptors', function () {
const fd = fs.openSync('file.txt', 'r');
fs.unlinkSync('file.txt');
assert.isFalse(fs.existsSync('file.txt'));
// but we can still use fd to read
const buffer = Buffer.alloc(7);
const read = fs.readSync(fd, buffer, 0, 7);
assert.equal(read, 7);
assert.equal(String(buffer), 'content');
});
});
mock-fs-5.5.0/test/lib/fs.utimes-lutimes-futimes.spec.js 0000664 0000000 0000000 00000030516 14751162414 0023155 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.utimes(path, atime, mtime, callback)', function () {
beforeEach(function () {
mock({
dir: {},
'file.txt': mock.file({
content: 'content',
atime: new Date(1),
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
atime: new Date(2),
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('updates timestamps for a file', function (done) {
fs.utimes('file.txt', new Date(100), new Date(200), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
});
});
it('updates timestamps for a file following symlink', function (done) {
fs.utimes('link', new Date(100), new Date(200), function (err) {
if (err) {
return done(err);
}
const stats = fs.lstatSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
const stats2 = fs.lstatSync('link');
assert.equal(stats2.atime.getTime(), 2);
assert.equal(stats2.mtime.getTime(), 2);
done();
});
});
it('supports Buffer input', function (done) {
fs.utimes(
Buffer.from('file.txt'),
new Date(100),
new Date(200),
function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
},
);
});
it('promise updates timestamps for a file', function (done) {
fs.promises
.utimes('file.txt', new Date(100), new Date(200))
.then(function () {
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
})
.catch(done);
});
it('updates timestamps for a directory', function (done) {
fs.utimes('dir', new Date(300), new Date(400), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('dir');
assert.equal(stats.atime.getTime(), 300);
assert.equal(stats.mtime.getTime(), 400);
done();
});
});
it('promise updates timestamps for a directory', function (done) {
fs.promises
.utimes('dir', new Date(300), new Date(400))
.then(function () {
const stats = fs.statSync('dir');
assert.equal(stats.atime.getTime(), 300);
assert.equal(stats.mtime.getTime(), 400);
done();
})
.catch(done);
});
it('fails for a bogus path', function (done) {
fs.utimes('bogus.txt', new Date(100), new Date(200), function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails for a bogus path', function (done) {
fs.promises.utimes('bogus.txt', new Date(100), new Date(200)).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.lutimes(path, atime, mtime, callback)', function () {
beforeEach(function () {
mock({
dir: {},
'file.txt': mock.file({
content: 'content',
atime: new Date(1),
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
atime: new Date(2),
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('updates timestamps for a file', function (done) {
fs.lutimes('file.txt', new Date(100), new Date(200), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
});
});
it('updates timestamps for a file but not following symlink', function (done) {
fs.lutimes('link', new Date(100), new Date(200), function (err) {
if (err) {
return done(err);
}
const stats = fs.lstatSync('file.txt');
assert.equal(stats.atime.getTime(), 1);
assert.equal(stats.mtime.getTime(), 1);
const stats2 = fs.lstatSync('link');
assert.equal(stats2.atime.getTime(), 100);
assert.equal(stats2.mtime.getTime(), 200);
done();
});
});
it('supports Buffer input', function (done) {
fs.lutimes(
Buffer.from('file.txt'),
new Date(100),
new Date(200),
function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
},
);
});
it('promise updates timestamps for a file', function (done) {
fs.promises
.lutimes('file.txt', new Date(100), new Date(200))
.then(function () {
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
})
.catch(done);
});
it('updates timestamps for a directory', function (done) {
fs.lutimes('dir', new Date(300), new Date(400), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('dir');
assert.equal(stats.atime.getTime(), 300);
assert.equal(stats.mtime.getTime(), 400);
done();
});
});
it('promise updates timestamps for a directory', function (done) {
fs.promises
.lutimes('dir', new Date(300), new Date(400))
.then(function () {
const stats = fs.statSync('dir');
assert.equal(stats.atime.getTime(), 300);
assert.equal(stats.mtime.getTime(), 400);
done();
})
.catch(done);
});
it('fails for a bogus path', function (done) {
fs.lutimes('bogus.txt', new Date(100), new Date(200), function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails for a bogus path', function (done) {
fs.promises.lutimes('bogus.txt', new Date(100), new Date(200)).then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.utimesSync(path, atime, mtime)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({
content: 'content',
atime: new Date(1),
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
atime: new Date(2),
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('updates timestamps for a file', function () {
fs.utimesSync('file.txt', new Date(100), new Date(200));
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
});
it('updates timestamps for a file following symlink', function () {
fs.utimesSync('link', new Date(100), new Date(200));
const stats = fs.lstatSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
const stats2 = fs.lstatSync('link');
assert.equal(stats2.atime.getTime(), 2);
assert.equal(stats2.mtime.getTime(), 2);
});
});
describe('fs.lutimesSync(path, atime, mtime)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({
content: 'content',
atime: new Date(1),
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
atime: new Date(2),
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('updates timestamps for a file', function () {
fs.lutimesSync('file.txt', new Date(100), new Date(200));
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
});
it('updates timestamps for a file but not following symlink', function () {
fs.lutimesSync('link', new Date(100), new Date(200));
const stats = fs.lstatSync('file.txt');
assert.equal(stats.atime.getTime(), 1);
assert.equal(stats.mtime.getTime(), 1);
const stats2 = fs.lstatSync('link');
assert.equal(stats2.atime.getTime(), 100);
assert.equal(stats2.mtime.getTime(), 200);
});
});
describe('fs.futimes(fd, atime, mtime, callback)', function () {
beforeEach(function () {
mock({
dir: {},
'file.txt': mock.file({
content: 'content',
atime: new Date(1),
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
atime: new Date(2),
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('updates timestamps for a file', function (done) {
const fd = fs.openSync('file.txt', 'r');
fs.futimes(fd, new Date(100), new Date(200), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
});
});
it('updates timestamps for a file following symlink', function (done) {
const fd = fs.openSync('link', 'r');
fs.futimes(fd, new Date(100), new Date(200), function (err) {
if (err) {
return done(err);
}
const stats = fs.lstatSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
const stats2 = fs.lstatSync('link');
assert.equal(stats2.atime.getTime(), 2);
assert.equal(stats2.mtime.getTime(), 2);
done();
});
});
it('promise updates timestamps for a file', function (done) {
fs.promises
.open('file.txt', 'r')
.then(function (fd) {
return fd.utimes(new Date(100), new Date(200));
})
.then(function () {
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
done();
})
.catch(done);
});
it('updates timestamps for a directory', function (done) {
const fd = fs.openSync('dir', 'r');
fs.futimes(fd, new Date(300), new Date(400), function (err) {
if (err) {
return done(err);
}
const stats = fs.statSync('dir');
assert.equal(stats.atime.getTime(), 300);
assert.equal(stats.mtime.getTime(), 400);
done();
});
});
it('promise updates timestamps for a directory', function (done) {
fs.promises
.open('dir', 'r')
.then(function (fd) {
return fd.utimes(new Date(300), new Date(400));
})
.then(function () {
const stats = fs.statSync('dir');
assert.equal(stats.atime.getTime(), 300);
assert.equal(stats.mtime.getTime(), 400);
done();
})
.catch(done);
});
});
describe('fs.futimesSync(path, atime, mtime)', function () {
beforeEach(function () {
mock({
'file.txt': mock.file({
content: 'content',
atime: new Date(1),
mtime: new Date(1),
}),
link: mock.symlink({
path: './file.txt',
atime: new Date(2),
mtime: new Date(2),
}),
});
});
afterEach(mock.restore);
it('updates timestamps for a file', function () {
const fd = fs.openSync('file.txt', 'r');
fs.futimesSync(fd, new Date(100), new Date(200));
const stats = fs.statSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
});
it('updates timestamps for a file following symlink', function () {
const fd = fs.openSync('link', 'r');
fs.futimesSync(fd, new Date(100), new Date(200));
const stats = fs.lstatSync('file.txt');
assert.equal(stats.atime.getTime(), 100);
assert.equal(stats.mtime.getTime(), 200);
const stats2 = fs.lstatSync('link');
assert.equal(stats2.atime.getTime(), 2);
assert.equal(stats2.mtime.getTime(), 2);
});
});
mock-fs-5.5.0/test/lib/fs.write.spec.js 0000664 0000000 0000000 00000037340 14751162414 0017651 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.write(fd, buffer, offset, length, position, callback)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('writes a buffer to a file', function (done) {
const fd = fs.openSync('path/new-file.txt', 'w');
const buffer = Buffer.from('new file');
fs.write(fd, buffer, 0, buffer.length, null, function (err, written, buf) {
if (err) {
return done(err);
}
assert.equal(written, 8);
assert.equal(buf, buffer);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'new file');
done();
});
});
it('promise writes a buffer to a file', function (done) {
const buffer = Buffer.from('new file');
fs.promises
.open('path/new-file.txt', 'w')
.then(function (fd) {
return fd.write(buffer, 0, buffer.length);
})
.then(function (result) {
assert.equal(result.bytesWritten, 8);
assert.equal(result.buffer, buffer);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'new file');
done();
})
.catch(done);
});
it('writes a buffer to a file with implicit offset, length, position', function (done) {
const fd = fs.openSync('path/new-file.txt', 'w');
const buffer = Buffer.from('new file');
fs.write(fd, buffer, function (err, written, buf) {
if (err) {
return done(err);
}
assert.equal(written, 8);
assert.equal(buf, buffer);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'new file');
done();
});
});
it('promise writes a buffer to a file with implicit offset, length, position', function (done) {
const buffer = Buffer.from('new file');
fs.promises
.open('path/new-file.txt', 'w')
.then(function (fd) {
return fd.write(buffer);
})
.then(function (result) {
assert.equal(result.bytesWritten, 8);
assert.equal(result.buffer, buffer);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'new file');
done();
})
.catch(done);
});
it('can write a portion of a buffer to a file', function (done) {
fs.open('path/new-file.txt', 'w', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.from('new file');
fs.write(fd, buffer, 1, 5, null, function (err2, written, buf) {
if (err2) {
return done(err2);
}
assert.equal(written, 5);
assert.equal(buf, buffer);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'ew fi');
done();
});
});
});
it('promise can write a portion of a buffer to a file', function (done) {
const buffer = Buffer.from('new file');
fs.promises
.open('path/new-file.txt', 'w')
.then(function (fd) {
return fd.write(buffer, 1, 5);
})
.then(function (result) {
assert.equal(result.bytesWritten, 5);
assert.equal(result.buffer, buffer);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'ew fi');
done();
})
.catch(done);
});
it('can write a portion of a buffer to a file position', function (done) {
fs.open('path/to/file.txt', 'a', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.from('new file');
fs.write(fd, buffer, 1, 5, 2, function (err2, written, buf) {
if (err2) {
return done(err2);
}
assert.equal(written, 5);
assert.equal(buf, buffer);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'fiew fintent',
);
done();
});
});
});
it('promise can write a portion of a buffer to a file position', function (done) {
const buffer = Buffer.from('new file');
fs.promises
.open('path/to/file.txt', 'a')
.then(function (fd) {
return fd.write(buffer, 1, 5, 2);
})
.then(function (result) {
assert.equal(result.bytesWritten, 5);
assert.equal(result.buffer, buffer);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'fiew fintent',
);
done();
})
.catch(done);
});
it('can write a portion of a buffer to a file position and enlarge the file', function (done) {
fs.open('path/to/file.txt', 'a', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.from('new file');
fs.write(fd, buffer, 1, 5, 8, function (err2, written, buf) {
if (err2) {
return done(err2);
}
assert.equal(written, 5);
assert.equal(buf, buffer);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'file conew fi',
);
done();
});
});
});
it('promise can write a portion of a buffer to a file position and enlarge the file', function (done) {
const buffer = Buffer.from('new file');
fs.promises
.open('path/to/file.txt', 'a')
.then(function (fd) {
return fd.write(buffer, 1, 5, 8);
})
.then(function (result) {
assert.equal(result.bytesWritten, 5);
assert.equal(result.buffer, buffer);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'file conew fi',
);
done();
})
.catch(done);
});
it('can append to a file', function (done) {
fs.open('path/to/file.txt', 'a', function (err, fd) {
if (err) {
return done(err);
}
const buffer = Buffer.from(' more');
fs.write(fd, buffer, 0, 5, null, function (err2, written, buf) {
if (err2) {
return done(err2);
}
assert.equal(written, 5);
assert.equal(buf, buffer);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'file content more',
);
done();
});
});
});
it('promise can append to a file', function (done) {
const buffer = Buffer.from(' more');
fs.promises
.open('path/to/file.txt', 'a')
.then(function (fd) {
return fd.write(buffer, 0, 5);
})
.then(function (result) {
assert.equal(result.bytesWritten, 5);
assert.equal(result.buffer, buffer);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'file content more',
);
done();
})
.catch(done);
});
it('fails if file not open for writing', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
fs.write(fd, Buffer.from('oops'), 0, 4, null, function (err2) {
assert.instanceOf(err2, Error);
assert.equal(err2.code, 'EBADF');
done();
});
});
});
it('fails if file not open for writing', function (done) {
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.write(Buffer.from('oops'), 0, 4);
})
.then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
done();
},
);
});
});
describe('fs.writeSync(fd, buffer, offset, length, position)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('writes a buffer to a file', function () {
const buffer = Buffer.from('new file');
const fd = fs.openSync('path/new-file.txt', 'w');
const written = fs.writeSync(fd, buffer, 0, buffer.length);
assert.equal(written, 8);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'new file');
});
it('can write a portion of a buffer to a file', function () {
const buffer = Buffer.from('new file');
const fd = fs.openSync('path/new-file.txt', 'w');
const written = fs.writeSync(fd, buffer, 1, 5);
assert.equal(written, 5);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'ew fi');
});
it('can append to a file', function () {
const buffer = Buffer.from(' more');
const fd = fs.openSync('path/to/file.txt', 'a');
const written = fs.writeSync(fd, buffer, 0, 5);
assert.equal(written, 5);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'file content more',
);
});
it('fails if file not open for writing', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
assert.throws(function () {
fs.writeSync(fd, Buffer.from('oops'), 0, 4);
});
});
});
describe('fs.write(fd, data[, position[, encoding]], callback)', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('writes a string to a file', function (done) {
fs.open('path/new-file.txt', 'w', function (err, fd) {
if (err) {
return done(err);
}
const string = 'new file';
fs.write(fd, string, null, 'utf-8', function (err2, written, str) {
if (err2) {
return done(err2);
}
assert.equal(written, 8);
assert.equal(str, string);
assert.equal(fs.readFileSync('path/new-file.txt'), 'new file');
done();
});
});
});
it('promise writes a string to a file', function (done) {
const string = 'new file';
fs.promises
.open('path/new-file.txt', 'w')
.then(function (fd) {
return fd.write(string, null, 'utf-8');
})
.then(function (result) {
assert.equal(result.bytesWritten, 8);
assert.equal(String(result.buffer), string);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'new file');
done();
})
.catch(done);
});
it('writes a string to a file with implicit position and encoding', function (done) {
fs.open('path/new-file.txt', 'w', function (err, fd) {
if (err) {
return done(err);
}
const string = 'new file';
fs.write(fd, string, function (err2, written, str) {
if (err2) {
return done(err2);
}
assert.equal(written, 8);
assert.equal(str, string);
assert.equal(fs.readFileSync('path/new-file.txt'), 'new file');
done();
});
});
});
it('promise writes a string to a file with implicit position and encoding', function (done) {
const string = 'new file';
fs.promises
.open('path/new-file.txt', 'w')
.then(function (fd) {
return fd.write(string);
})
.then(function (result) {
assert.equal(result.bytesWritten, 8);
assert.equal(String(result.buffer), string);
assert.equal(String(fs.readFileSync('path/new-file.txt')), 'new file');
done();
})
.catch(done);
});
it('can append to a file', function (done) {
fs.open('path/to/file.txt', 'a', function (err, fd) {
if (err) {
return done(err);
}
const string = ' more';
fs.write(fd, string, null, 'utf-8', function (err2, written, str) {
if (err2) {
return done(err2);
}
assert.equal(written, 5);
assert.equal(str, string);
assert.equal(fs.readFileSync('path/to/file.txt'), 'file content more');
done();
});
});
});
it('promise can append to a file', function (done) {
const string = ' more';
fs.promises
.open('path/to/file.txt', 'a')
.then(function (fd) {
return fd.write(string);
})
.then(function (result) {
assert.equal(result.bytesWritten, 5);
assert.equal(String(result.buffer), string);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'file content more',
);
done();
})
.catch(done);
});
it('can write to a position of a file', function (done) {
fs.open('path/to/file.txt', 'a', function (err, fd) {
if (err) {
return done(err);
}
const string = ' more';
fs.write(fd, string, 3, function (err2, written, str) {
if (err2) {
return done(err2);
}
assert.equal(written, 5);
assert.equal(str, string);
assert.equal(fs.readFileSync('path/to/file.txt'), 'fil moretent');
done();
});
});
});
it('promise can write to a position of a file', function (done) {
const string = ' more';
fs.promises
.open('path/to/file.txt', 'a')
.then(function (fd) {
return fd.write(string, 3);
})
.then(function (result) {
assert.equal(result.bytesWritten, 5);
assert.equal(String(result.buffer), string);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'fil moretent',
);
done();
})
.catch(done);
});
it('can write to a position of a file and enlarge it', function (done) {
fs.open('path/to/file.txt', 'a', function (err, fd) {
if (err) {
return done(err);
}
const string = ' more';
fs.write(fd, string, 9, function (err2, written, str) {
if (err2) {
return done(err2);
}
assert.equal(written, 5);
assert.equal(str, string);
assert.equal(fs.readFileSync('path/to/file.txt'), 'file cont more');
done();
});
});
});
it('promise can write to a position of a file and enlarge it', function (done) {
const string = ' more';
fs.promises
.open('path/to/file.txt', 'a')
.then(function (fd) {
return fd.write(string, 9);
})
.then(function (result) {
assert.equal(result.bytesWritten, 5);
assert.equal(String(result.buffer), string);
assert.equal(
String(fs.readFileSync('path/to/file.txt')),
'file cont more',
);
done();
})
.catch(done);
});
it('fails if file not open for writing', function (done) {
fs.open('path/to/file.txt', 'r', function (err, fd) {
if (err) {
return done(err);
}
fs.write(fd, 'oops', null, 'utf-8', function (err2) {
assert.instanceOf(err2, Error);
done();
});
});
});
it('promise fails if file not open for writing', function (done) {
fs.promises
.open('path/to/file.txt', 'r')
.then(function (fd) {
return fd.write('oops');
})
.then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'EBADF');
done();
},
);
});
});
describe('fs.writeSync(fd, data[, position[, encoding]])', function () {
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
});
});
afterEach(mock.restore);
it('writes a string to a file', function () {
const fd = fs.openSync('path/new-file.txt', 'w');
const string = 'new file';
const written = fs.writeSync(fd, string, null, 'utf-8');
assert.equal(written, 8);
assert.equal(fs.readFileSync('path/new-file.txt'), 'new file');
});
it('can append to a file', function () {
const fd = fs.openSync('path/to/file.txt', 'a');
const string = ' more';
const written = fs.writeSync(fd, string, null, 'utf-8');
assert.equal(written, 5);
assert.equal(fs.readFileSync('path/to/file.txt'), 'file content more');
});
it('fails if file not open for writing', function () {
const fd = fs.openSync('path/to/file.txt', 'r');
assert.throws(function () {
fs.writeSync(fd, 'oops', null, 'utf-8');
});
});
});
mock-fs-5.5.0/test/lib/fs.writeFile.spec.js 0000664 0000000 0000000 00000006342 14751162414 0020447 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('fs.writeFile(filename, data, [options], callback)', function () {
beforeEach(function () {
mock({
dir: mock.directory({
mtime: new Date(1),
}),
});
});
afterEach(mock.restore);
it('writes a string to a file', function (done) {
fs.writeFile('dir/foo', 'bar', function (err) {
if (err) {
return done(err);
}
assert.equal(String(fs.readFileSync('dir/foo')), 'bar');
done();
});
});
it('promise writes a string to a file', function (done) {
fs.promises
.writeFile('dir/foo', 'bar')
.then(function () {
assert.equal(String(fs.readFileSync('dir/foo')), 'bar');
done();
})
.catch(done);
});
it('updates mtime of parent directory', function (done) {
const oldTime = fs.statSync('dir').mtime;
fs.writeFile('dir/foo', 'bar', function (err) {
if (err) {
return done(err);
}
const newTime = fs.statSync('dir').mtime;
assert.isTrue(newTime > oldTime);
done();
});
});
it('promise updates mtime of parent directory', function (done) {
const oldTime = fs.statSync('dir').mtime;
fs.promises
.writeFile('dir/foo', 'bar')
.then(function () {
const newTime = fs.statSync('dir').mtime;
assert.isTrue(newTime > oldTime);
done();
})
.catch(done);
});
it('writes a buffer to a file', function (done) {
fs.writeFile('dir/foo', Buffer.from('bar'), function (err) {
if (err) {
return done(err);
}
assert.equal(String(fs.readFileSync('dir/foo')), 'bar');
done();
});
});
it('promise writes a buffer to a file', function (done) {
fs.promises
.writeFile('dir/foo', Buffer.from('bar'))
.then(function () {
assert.equal(String(fs.readFileSync('dir/foo')), 'bar');
done();
})
.catch(done);
});
it('fails if directory does not exist', function (done) {
fs.writeFile('foo/bar', 'baz', function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
});
});
it('promise fails if directory does not exist', function (done) {
fs.promises.writeFile('foo/bar', 'baz').then(
function () {
done(new Error('should not succeed.'));
},
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
done();
},
);
});
});
describe('fs.writeFileSync(filename, data, [options]', function () {
beforeEach(function () {
mock({
'.': {},
});
});
afterEach(mock.restore);
it('writes a string to a file', function () {
fs.writeFileSync('foo', 'bar');
assert.equal(String(fs.readFileSync('foo')), 'bar');
});
it('writes a buffer to a file', function () {
fs.writeFileSync('foo', Buffer.from('bar'));
assert.equal(String(fs.readFileSync('foo')), 'bar');
});
it('fails if directory does not exist', function () {
assert.throws(function () {
fs.writeFileSync('foo/bar', 'baz');
});
});
});
mock-fs-5.5.0/test/lib/index.spec.js 0000664 0000000 0000000 00000032707 14751162414 0017221 0 ustar 00root root 0000000 0000000 const fs = require('fs');
const os = require('os');
const path = require('path');
const {afterEach, beforeEach, describe, it, xit} = require('mocha');
const Directory = require('../../lib/directory.js');
const File = require('../../lib/file.js');
const mock = require('../../lib/index.js');
const {fixWin32Permissions} = require('../../lib/item.js');
const helper = require('../helper.js');
const assert = helper.assert;
const assetsPath = path.resolve(__dirname, '../assets');
describe('The API', function () {
describe('mock()', function () {
it('configures the real fs module with a mock file system', function () {
mock({
'fake-file-for-testing-only': 'file content',
});
assert.isTrue(fs.existsSync('fake-file-for-testing-only'));
mock.restore();
});
it('provides direct access to the internal filesystem object', function () {
mock();
const root = mock.getMockRoot();
assert.notDeepEqual(root, {});
mock.restore();
assert.deepEqual(mock.getMockRoot(), {});
});
it('creates process.cwd() and os.tmpdir() by default', function () {
mock();
assert.isTrue(fs.statSync(process.cwd()).isDirectory());
let tmp;
if (os.tmpdir) {
tmp = os.tmpdir();
} else if (os.tmpDir) {
tmp = os.tmpDir();
}
if (tmp) {
assert.isTrue(fs.statSync(tmp).isDirectory());
}
mock.restore();
});
it('passes the createCwd option to the FileSystem constructor', function () {
mock({}, {createCwd: false});
assert.isFalse(fs.existsSync(process.cwd()));
mock.restore();
});
it('passes the createTmp option to the FileSystem constructor', function () {
mock({}, {createTmp: false});
let tmp;
if (os.tmpdir) {
tmp = os.tmpdir();
} else if (os.tmpDir) {
tmp = os.tmpDir();
}
if (tmp) {
assert.isFalse(fs.existsSync(tmp));
}
mock.restore();
});
xit('uses the real fs module in require() calls', function () {
mock({foo: 'bar'});
const pkg = require('../../package.json');
assert.equal(pkg.name, 'mock-fs');
mock.restore();
});
});
describe('mock.restore()', function () {
it('restores bindings for the real file system', function () {
mock({
'fake-file-for-testing-only': 'file content',
});
assert.isTrue(fs.existsSync('fake-file-for-testing-only'));
mock.restore();
assert.isFalse(fs.existsSync('fake-file-for-testing-only'));
});
});
describe('mock.file()', function () {
afterEach(mock.restore);
it('lets you create files with additional properties', function (done) {
mock({
'path/to/file.txt': mock.file({
content: 'file content',
mtime: new Date(8675309),
mode: parseInt('0644', 8),
}),
});
fs.stat('path/to/file.txt', function (err, stats) {
if (err) {
return done(err);
}
assert.isTrue(stats.isFile());
assert.isFalse(stats.isDirectory());
assert.equal(stats.mtime.getTime(), 8675309);
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0644', 8));
done();
});
});
});
describe('mock.directory()', function () {
afterEach(mock.restore);
it('lets you create directories with more properties', function (done) {
mock({
'path/to/dir': mock.directory({
mtime: new Date(8675309),
mode: parseInt('0644', 8),
}),
});
fs.stat('path/to/dir', function (err, stats) {
if (err) {
return done(err);
}
assert.isFalse(stats.isFile());
assert.isTrue(stats.isDirectory());
assert.equal(stats.mtime.getTime(), 8675309);
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0644', 8));
done();
});
});
it('works with a trailing slash', function () {
mock({
'path/to/dir/': mock.directory({
mtime: new Date(8675309),
mode: parseInt('0644', 8),
}),
});
assert.isTrue(fs.statSync('path/to/dir').isDirectory());
assert.isTrue(fs.statSync('path/to/dir/').isDirectory());
});
it('works without a trailing slash', function () {
mock({
'path/to/dir': mock.directory({
mtime: new Date(8675309),
mode: parseInt('0644', 8),
}),
});
assert.isTrue(fs.statSync('path/to/dir').isDirectory());
assert.isTrue(fs.statSync('path/to/dir/').isDirectory());
});
});
describe('mock.symlink()', function () {
afterEach(mock.restore);
it('lets you create symbolic links', function () {
mock({
'path/to/file': 'content',
'path/to/link': mock.symlink({path: './file'}),
});
const stats = fs.statSync('path/to/link');
assert.isTrue(stats.isFile());
assert.equal(String(fs.readFileSync('path/to/link')), 'content');
});
});
describe(`mock.load()`, () => {
const statsCompareKeys = [
'birthtime',
'ctime',
'mtime',
'gid',
'uid',
'mode',
];
const filterStats = (stats) => {
const res = {};
for (const key of statsCompareKeys) {
const k =
(stats.hasOwnProperty(key) && key) ||
(stats.hasOwnProperty(`_${key}`) && `_${key}`) ||
(stats.hasOwnProperty(`${key}Ms`) && `${key}Ms`);
if (k) {
res[key] =
k === 'mode' && stats.isDirectory()
? fixWin32Permissions(stats[k])
: k.endsWith('Ms')
? new Date(stats[k])
: stats[k];
}
}
return res;
};
describe(`File`, () => {
const filePath = path.join(assetsPath, 'file1.txt');
it('creates a File factory with correct attributes', () => {
const file = mock.load(filePath)();
const stats = fs.statSync(filePath);
assert.instanceOf(file, File);
assert.deepEqual(filterStats(file), filterStats(stats));
});
describe('lazy=true', () => {
let file;
beforeEach(() => (file = mock.load(filePath)()));
it('creates accessors', () => {
assert.typeOf(
Object.getOwnPropertyDescriptor(file, '_content').get,
'function',
);
assert.typeOf(
Object.getOwnPropertyDescriptor(file, '_content').set,
'function',
);
});
it('read file loads data and replaces accessors', () => {
assert.equal(file._content.toString(), 'data1');
assert.instanceOf(
Object.getOwnPropertyDescriptor(file, '_content').value,
Buffer,
);
assert.isNotOk(
Object.getOwnPropertyDescriptor(file, '_content').get,
'function',
);
assert.isNotOk(
Object.getOwnPropertyDescriptor(file, '_content').set,
'function',
);
});
it('write file updates content and replaces accessors', () => {
file._content = Buffer.from('new data');
assert.equal(file._content.toString(), 'new data');
assert.instanceOf(
Object.getOwnPropertyDescriptor(file, '_content').value,
Buffer,
);
assert.isNotOk(
Object.getOwnPropertyDescriptor(file, '_content').get,
'function',
);
assert.isNotOk(
Object.getOwnPropertyDescriptor(file, '_content').set,
'function',
);
});
});
it('lazy=false loads file content', () => {
const file = mock.load(path.join(assetsPath, 'file1.txt'), {
lazy: false,
})();
assert.equal(
Object.getOwnPropertyDescriptor(file, '_content').value.toString(),
'data1',
);
});
it('can read file from mocked FS', () => {
mock({'/file': mock.load(filePath)});
assert.equal(fs.readFileSync('/file'), 'data1');
mock.restore();
});
});
describe(`Dir`, () => {
it('creates a Directory factory with correct attributes', () => {
const dir = mock.load(assetsPath)();
const stats = fs.statSync(assetsPath);
assert.instanceOf(dir, Directory);
assert.deepEqual(filterStats(dir), filterStats(stats));
});
describe('recursive=true', () => {
it('creates all files & dirs', () => {
const base = mock.load(assetsPath, {recursive: true})();
const baseDir = base._items.dir;
const baseDirSubdir = baseDir._items.subdir;
assert.instanceOf(base, Directory);
assert.instanceOf(base._items['file1.txt'], File);
assert.instanceOf(baseDir, Directory);
assert.instanceOf(baseDir._items['file2.txt'], File);
assert.instanceOf(baseDirSubdir, Directory);
assert.instanceOf(baseDirSubdir._items['file3.txt'], File);
});
it('respects lazy setting', () => {
let dir;
const getFile = () =>
dir._items.dir._items.subdir._items['file3.txt'];
dir = mock.load(assetsPath, {recursive: true, lazy: true})();
assert.typeOf(
Object.getOwnPropertyDescriptor(getFile(), '_content').get,
'function',
);
dir = mock.load(assetsPath, {recursive: true, lazy: false})();
assert.instanceOf(
Object.getOwnPropertyDescriptor(getFile(), '_content').value,
Buffer,
);
});
});
it('recursive=false creates files & does not recurse', () => {
const base = mock.load(assetsPath, {recursive: false})();
assert.instanceOf(base, Directory);
assert.instanceOf(base._items['file1.txt'], File);
assert.isNotOk(base._items.dir);
});
it('can read file from mocked FS', () => {
mock({'/dir': mock.load(assetsPath, {recursive: true})});
assert.equal(fs.readFileSync('/dir/file1.txt'), 'data1');
mock.restore();
});
});
});
});
describe('process.cwd()', function () {
afterEach(mock.restore);
it('maintains current working directory', function () {
const originalCwd = process.cwd();
mock();
const cwd = process.cwd();
assert.equal(cwd, originalCwd);
});
it('allows changing directory', function () {
const originalCwd = process.cwd();
mock({
dir: {},
});
process.chdir('dir');
const cwd = process.cwd();
assert.equal(cwd, path.join(originalCwd, 'dir'));
});
it('prevents changing directory to non-existent path', function () {
mock();
let err;
try {
process.chdir('dir');
} catch (e) {
err = e;
}
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOENT');
});
it('prevents changing directory to non-directory path', function () {
mock({
file: '',
});
let err;
try {
process.chdir('file');
} catch (e) {
err = e;
}
assert.instanceOf(err, Error);
assert.equal(err.code, 'ENOTDIR');
});
it('restores original methods on restore', function () {
const originalCwd = process.cwd;
const originalChdir = process.chdir;
mock();
mock.restore();
assert.equal(process.cwd, originalCwd);
assert.equal(process.chdir, originalChdir);
});
it('restores original working directory on restore', function () {
const originalCwd = process.cwd();
mock({
dir: {},
});
process.chdir('dir');
mock.restore();
const cwd = process.cwd();
assert.equal(cwd, originalCwd);
});
});
if (process.getuid && process.getgid) {
describe('security', function () {
afterEach(mock.restore);
it('denies dir listing without execute on parent', function () {
mock({
secure: mock.directory({
mode: parseInt('0666', 8),
items: {
insecure: {
file: 'file content',
},
},
}),
});
let err;
try {
fs.readdirSync('secure/insecure');
} catch (e) {
err = e;
}
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
});
it('denies file read without execute on parent', function () {
mock({
secure: mock.directory({
mode: parseInt('0666', 8),
items: {
insecure: {
file: 'file content',
},
},
}),
});
let err;
try {
fs.readFileSync('secure/insecure/file');
} catch (e) {
err = e;
}
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
});
it('denies file read without read on file', function () {
mock({
insecure: {
'write-only': mock.file({
mode: parseInt('0222', 8),
content: 'write only',
}),
},
});
let err;
try {
fs.readFileSync('insecure/write-only');
} catch (e) {
err = e;
}
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
});
it('denies file write without write on file', function () {
mock({
insecure: {
'read-only': mock.file({
mode: parseInt('0444', 8),
content: 'read only',
}),
},
});
let err;
try {
fs.writeFileSync('insecure/read-only', 'denied');
} catch (e) {
err = e;
}
assert.instanceOf(err, Error);
assert.equal(err.code, 'EACCES');
});
});
}
mock-fs-5.5.0/test/lib/item.spec.js 0000664 0000000 0000000 00000026761 14751162414 0017053 0 ustar 00root root 0000000 0000000 const {beforeEach, describe, it} = require('mocha');
const Item = require('../../lib/item.js');
const assert = require('../helper.js').assert;
describe('Item', function () {
describe('constructor', function () {
it('creates a new instance', function () {
const item = new Item();
assert.instanceOf(item, Item);
});
});
describe('#getATime()', function () {
it('returns a date', function () {
const item = new Item();
const date = item.getATime();
assert.instanceOf(date, Date);
assert.isTrue(date <= new Date());
});
});
describe('#setATime()', function () {
it('sets the atime', function () {
const item = new Item();
const date = new Date();
item.setATime(date);
assert.equal(item.getATime(), date);
});
});
describe('#getCTime()', function () {
it('returns a date', function () {
const item = new Item();
const date = item.getCTime();
assert.instanceOf(date, Date);
assert.isTrue(date <= new Date());
});
});
describe('#setCTime()', function () {
it('sets the ctime', function () {
const item = new Item();
const date = new Date();
item.setCTime(date);
assert.equal(item.getCTime(), date);
});
});
describe('#getBirthtime()', function () {
it('returns a date', function () {
const item = new Item();
const date = item.getBirthtime();
assert.instanceOf(date, Date);
assert.isTrue(date <= new Date());
});
});
describe('#setBirthtime()', function () {
it('sets the birthtime', function () {
const item = new Item();
const date = new Date();
item.setBirthtime(date);
assert.equal(item.getBirthtime(), date);
});
});
describe('#getMTime()', function () {
it('returns a date', function () {
const item = new Item();
const date = item.getMTime();
assert.instanceOf(date, Date);
assert.isTrue(date <= new Date());
});
});
describe('#setMTime()', function () {
it('sets the mtime', function () {
const item = new Item();
const date = new Date();
item.setMTime(date);
assert.equal(item.getMTime(), date);
});
});
describe('#getMode()', function () {
it('returns a number', function () {
const item = new Item();
assert.isNumber(item.getMode());
});
});
describe('#setMode()', function () {
it('sets the mode', function () {
const item = new Item();
item.setMode(parseInt('0644', 8));
assert.equal(item.getMode(), parseInt('0644', 8));
});
it('updates the ctime', function () {
const item = new Item();
const original = new Date(1);
item.setCTime(original);
item.setMode(parseInt('0644', 8));
assert.isTrue(item.getCTime() > original);
});
});
describe('#setUid()', function () {
it('sets the uid', function () {
const item = new Item();
item.setUid(42);
assert.equal(item.getUid(), 42);
});
it('updates the ctime', function () {
const item = new Item();
const original = new Date(1);
item.setCTime(original);
item.setUid(42);
assert.isTrue(item.getCTime() > original);
});
});
describe('#setGid()', function () {
it('sets the gid', function () {
const item = new Item();
item.setGid(42);
assert.equal(item.getGid(), 42);
});
it('updates the ctime', function () {
const item = new Item();
const original = new Date(1);
item.setCTime(original);
item.setGid(42);
assert.isTrue(item.getCTime() > original);
});
});
if (process.getgid && process.getuid) {
const originalGetuid = process.getuid;
const originalGetgid = process.getgid;
const uid = originalGetuid();
const gid = originalGetgid();
let item;
beforeEach(function () {
process.getuid = originalGetuid;
process.getgid = originalGetgid;
item = new Item();
});
describe('#canRead()', function () {
it('returns true if owner and 0700', function () {
item.setMode(parseInt('0700', 8));
assert.isTrue(item.canRead());
});
it('returns true if owner and 0600', function () {
item.setMode(parseInt('0600', 8));
assert.isTrue(item.canRead());
});
it('returns true if owner and 0500', function () {
item.setMode(parseInt('0500', 8));
assert.isTrue(item.canRead());
});
it('returns true if owner and 0400', function () {
item.setMode(parseInt('0400', 8));
assert.isTrue(item.canRead());
});
it('returns false if owner and 0300', function () {
item.setMode(parseInt('0300', 8));
assert.isFalse(item.canRead());
});
it('returns false if owner and 0200', function () {
item.setMode(parseInt('0200', 8));
assert.isFalse(item.canRead());
});
it('returns false if owner and 0100', function () {
item.setMode(parseInt('0100', 8));
assert.isFalse(item.canRead());
});
it('returns false if not owner and 0700 (different user)', function () {
item.setUid(uid + 1);
item.setMode(parseInt('0700', 8));
assert.isFalse(item.canRead());
});
it('returns false if not owner and 0700 (different group)', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0700', 8));
assert.isFalse(item.canRead());
});
it('returns false if owner and 0170', function () {
item.setMode(parseInt('0170', 8));
assert.isFalse(item.canRead());
});
it('returns true if in group and 0170', function () {
item.setUid(uid + 1);
item.setMode(parseInt('0170', 8));
assert.isTrue(item.canRead());
});
it('returns false if not in group and 0770', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0770', 8));
assert.isFalse(item.canRead());
});
it('returns true if not in group and 0777', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0777', 8));
assert.isTrue(item.canRead());
});
it('always returns true if process runs as root', function () {
process.getuid = () => 0;
item.setUid(42);
item.setGid(42);
item.setMode(parseInt('0000', 8));
assert.isTrue(item.canRead());
});
});
describe('#canWrite()', function () {
it('returns true if owner and 0700', function () {
item.setMode(parseInt('0700', 8));
assert.isTrue(item.canWrite());
});
it('returns true if owner and 0600', function () {
item.setMode(parseInt('0600', 8));
assert.isTrue(item.canWrite());
});
it('returns false if owner and 0500', function () {
item.setMode(parseInt('0500', 8));
assert.isFalse(item.canWrite());
});
it('returns false if owner and 0400', function () {
item.setMode(parseInt('0400', 8));
assert.isFalse(item.canWrite());
});
it('returns true if owner and 0300', function () {
item.setMode(parseInt('0300', 8));
assert.isTrue(item.canWrite());
});
it('returns true if owner and 0200', function () {
item.setMode(parseInt('0200', 8));
assert.isTrue(item.canWrite());
});
it('returns false if owner and 0100', function () {
item.setMode(parseInt('0100', 8));
assert.isFalse(item.canWrite());
});
it('returns false if not owner and 0700 (different user)', function () {
item.setUid(uid + 1);
item.setMode(parseInt('0700', 8));
assert.isFalse(item.canWrite());
});
it('returns false if not owner and 0700 (different group)', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0700', 8));
assert.isFalse(item.canWrite());
});
it('returns false if owner and 0170', function () {
item.setMode(parseInt('0170', 8));
assert.isFalse(item.canWrite());
});
it('returns true if in group and 0170', function () {
item.setUid(uid + 1);
item.setMode(parseInt('0170', 8));
assert.isTrue(item.canWrite());
});
it('returns false if not in group and 0770', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0770', 8));
assert.isFalse(item.canWrite());
});
it('returns true if not in group and 0777', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0777', 8));
assert.isTrue(item.canWrite());
});
it('always returns true if process runs as root', function () {
process.getuid = () => 0;
item.setUid(42);
item.setGid(42);
item.setMode(parseInt('0000', 8));
assert.isTrue(item.canWrite());
});
});
describe('#canExecute()', function () {
it('returns true if owner and 0700', function () {
item.setMode(parseInt('0700', 8));
assert.isTrue(item.canExecute());
});
it('returns false if owner and 0600', function () {
item.setMode(parseInt('0600', 8));
assert.isFalse(item.canExecute());
});
it('returns true if owner and 0500', function () {
item.setMode(parseInt('0500', 8));
assert.isTrue(item.canExecute());
});
it('returns false if owner and 0400', function () {
item.setMode(parseInt('0400', 8));
assert.isFalse(item.canExecute());
});
it('returns true if owner and 0300', function () {
item.setMode(parseInt('0300', 8));
assert.isTrue(item.canExecute());
});
it('returns false if owner and 0200', function () {
item.setMode(parseInt('0200', 8));
assert.isFalse(item.canExecute());
});
it('returns true if owner and 0100', function () {
item.setMode(parseInt('0100', 8));
assert.isTrue(item.canExecute());
});
it('returns false if not owner and 0700 (different user)', function () {
item.setUid(uid + 1);
item.setMode(parseInt('0700', 8));
assert.isFalse(item.canExecute());
});
it('returns false if not owner and 0700 (different group)', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0700', 8));
assert.isFalse(item.canExecute());
});
it('returns false if owner and 0270', function () {
item.setMode(parseInt('0270', 8));
assert.isFalse(item.canExecute());
});
it('returns true if in group and 0270', function () {
item.setUid(uid + 1);
item.setMode(parseInt('0270', 8));
assert.isTrue(item.canExecute());
});
it('returns false if not in group and 0770', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0770', 8));
assert.isFalse(item.canExecute());
});
it('returns true if not in group and 0777', function () {
item.setUid(uid + 1);
item.setGid(gid + 1);
item.setMode(parseInt('0777', 8));
assert.isTrue(item.canExecute());
});
it('always returns true if process runs as root', function () {
process.getuid = () => 0;
item.setUid(42);
item.setGid(42);
item.setMode(parseInt('0000', 8));
assert.isTrue(item.canExecute());
});
});
}
});
mock-fs-5.5.0/test/lib/readfilecontext.spec.js 0000664 0000000 0000000 00000010267 14751162414 0021267 0 ustar 00root root 0000000 0000000 const constants = require('constants');
const fs = require('fs');
const {afterEach, beforeEach, describe, it} = require('mocha');
const mock = require('../../lib/index.js');
const {
getReadFileContextPrototype,
patchReadFileContext,
} = require('../../lib/readfilecontext.js');
const helper = require('../helper.js');
const assert = helper.assert;
describe('getReadFileContextPrototype', function () {
it('provides access to the internal ReadFileContext', function () {
const proto = getReadFileContextPrototype();
assert.equal(proto.constructor.name, 'ReadFileContext');
assert.equal(typeof proto.read, 'function');
assert.equal(typeof proto.close, 'function');
});
});
describe('patchReadFileContext', function () {
it('patch forwards calls to mocked binding when available', function () {
const calls = {
read: 0,
close: 0,
mockedRead: 0,
mockedClose: 0,
};
const proto = {
read: function () {
calls.read++;
},
close: function () {
calls.close++;
},
};
const mockedBinding = {
read: function () {
assert.strictEqual(this, mockedBinding);
calls.mockedRead++;
},
close: function () {
assert.strictEqual(this, mockedBinding);
calls.mockedClose++;
},
};
patchReadFileContext(proto);
const target = Object.create(proto);
assert.deepEqual(calls, {
read: 0,
close: 0,
mockedRead: 0,
mockedClose: 0,
});
target.read();
assert.deepEqual(calls, {
read: 1,
close: 0,
mockedRead: 0,
mockedClose: 0,
});
target.close();
assert.deepEqual(calls, {
read: 1,
close: 1,
mockedRead: 0,
mockedClose: 0,
});
proto._mockedBinding = mockedBinding;
target.read();
assert.deepEqual(calls, {
read: 1,
close: 1,
mockedRead: 1,
mockedClose: 0,
});
target.close();
assert.deepEqual(calls, {
read: 1,
close: 1,
mockedRead: 1,
mockedClose: 1,
});
delete proto._mockedBinding;
target.read();
assert.deepEqual(calls, {
read: 2,
close: 1,
mockedRead: 1,
mockedClose: 1,
});
target.close();
assert.deepEqual(calls, {
read: 2,
close: 2,
mockedRead: 1,
mockedClose: 1,
});
});
});
describe('fs.readFile() with ReadFileContext', function () {
// fs.readFile() is already tested elsewhere, here we just make sure we have
// coverage of the mocked ReadFileContext implementation.
beforeEach(function () {
mock({
'path/to/file.txt': 'file content',
1: 'fd content',
});
});
afterEach(mock.restore);
it('allows file reads to be aborted', function (done) {
const controller = new AbortController();
const {signal} = controller;
fs.readFile('path/to/file.txt', {signal}, function (err) {
assert.instanceOf(err, Error);
assert.equal(err.name, 'AbortError');
assert.equal(err.code, 'ABORT_ERR');
done();
});
// By aborting after the call it will be handled by the context rather than readFile()
controller.abort();
});
it('allows file reads with a numeric descriptor', function (done) {
// This isn't actually supported by mock-fs, but let's make sure the call goes through
// It also covers the case of reading an empty file and reading with encoding
fs.readFile(1, 'utf-8', function (err, data) {
assert.isNull(err);
assert.equal(data, '');
done();
});
});
it('allows file reads with unknown size', function (done) {
mock({
'unknown-size.txt': function () {
const file = mock.file({
content: Buffer.from('unknown size'),
})();
// Override getStats to drop the S_IFREG flag
const origGetStats = file.getStats;
file.getStats = function () {
const stats = origGetStats.apply(this, arguments);
stats[1] ^= constants.S_IFREG;
return stats;
};
return file;
},
});
fs.readFile('unknown-size.txt', 'utf-8', function (err, data) {
assert.isNull(err);
assert.equal(data, 'unknown size');
done();
});
});
});