@zenfs/core 1.6.10 → 1.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backends/backend.js +1 -1
- package/dist/backends/port/fs.js +1 -1
- package/dist/backends/store/inode.d.ts +1 -1
- package/dist/backends/store/inode.js +1 -1
- package/dist/config.js +4 -3
- package/dist/devices.js +10 -6
- package/dist/emulation/async.js +10 -19
- package/dist/emulation/dir.js +6 -4
- package/dist/emulation/path.js +1 -1
- package/dist/emulation/promises.js +35 -33
- package/dist/emulation/shared.js +5 -5
- package/dist/emulation/sync.js +25 -24
- package/dist/file.js +1 -1
- package/dist/filesystem.js +2 -1
- package/dist/mixins/async.d.ts +2 -14
- package/dist/mixins/async.js +35 -8
- package/dist/mixins/mutexed.js +8 -5
- package/dist/mixins/shared.d.ts +14 -2
- package/dist/polyfills.js +4 -3
- package/dist/stats.js +20 -19
- package/dist/utils.js +5 -5
- package/eslint.shared.js +3 -6
- package/package.json +3 -3
- package/tests/common/async.test.ts +31 -0
package/dist/backends/backend.js
CHANGED
|
@@ -13,7 +13,7 @@ export async function checkOptions(backend, options) {
|
|
|
13
13
|
}
|
|
14
14
|
// Check for required options.
|
|
15
15
|
for (const [optName, opt] of Object.entries(backend.options)) {
|
|
16
|
-
const value = options
|
|
16
|
+
const value = options === null || options === void 0 ? void 0 : options[optName];
|
|
17
17
|
if (value === undefined || value === null) {
|
|
18
18
|
if (!opt.required) {
|
|
19
19
|
continue;
|
package/dist/backends/port/fs.js
CHANGED
|
@@ -213,7 +213,7 @@ const _Port = {
|
|
|
213
213
|
required: true,
|
|
214
214
|
validator(port) {
|
|
215
215
|
// Check for a `postMessage` function.
|
|
216
|
-
if (typeof port
|
|
216
|
+
if (typeof (port === null || port === void 0 ? void 0 : port.postMessage) != 'function') {
|
|
217
217
|
throw new ErrnoError(Errno.EINVAL, 'option must be a port.');
|
|
218
218
|
}
|
|
219
219
|
},
|
package/dist/config.js
CHANGED
|
@@ -92,11 +92,12 @@ export function addDevice(driver, options) {
|
|
|
92
92
|
* @see Configuration
|
|
93
93
|
*/
|
|
94
94
|
export async function configure(configuration) {
|
|
95
|
+
var _a, _b, _c;
|
|
95
96
|
const uid = 'uid' in configuration ? configuration.uid || 0 : 0;
|
|
96
97
|
const gid = 'gid' in configuration ? configuration.gid || 0 : 0;
|
|
97
98
|
useCredentials({ uid, gid });
|
|
98
|
-
cache.stats.isEnabled = configuration.cacheStats
|
|
99
|
-
cache.paths.isEnabled = configuration.cachePaths
|
|
99
|
+
cache.stats.isEnabled = (_a = configuration.cacheStats) !== null && _a !== void 0 ? _a : false;
|
|
100
|
+
cache.paths.isEnabled = (_b = configuration.cachePaths) !== null && _b !== void 0 ? _b : false;
|
|
100
101
|
config.checkAccess = !configuration.disableAccessChecks;
|
|
101
102
|
config.updateOnRead = !configuration.disableUpdateOnRead;
|
|
102
103
|
config.syncImmediately = !configuration.onlySyncOnClose;
|
|
@@ -105,7 +106,7 @@ export async function configure(configuration) {
|
|
|
105
106
|
for (const [_point, mountConfig] of Object.entries(configuration.mounts).sort(([a], [b]) => (a.length > b.length ? 1 : -1))) {
|
|
106
107
|
const point = _point.startsWith('/') ? _point : '/' + _point;
|
|
107
108
|
if (isBackendConfig(mountConfig)) {
|
|
108
|
-
mountConfig.disableAsyncCache
|
|
109
|
+
(_c = mountConfig.disableAsyncCache) !== null && _c !== void 0 ? _c : (mountConfig.disableAsyncCache = configuration.disableAsyncCache || false);
|
|
109
110
|
}
|
|
110
111
|
if (point == '/')
|
|
111
112
|
fs.umount('/');
|
package/dist/devices.js
CHANGED
|
@@ -111,14 +111,16 @@ export class DeviceFile extends File {
|
|
|
111
111
|
this.writeSync(buffer, 0, buffer.length, length > size ? size : length);
|
|
112
112
|
}
|
|
113
113
|
closeSync() {
|
|
114
|
-
|
|
114
|
+
var _a, _b;
|
|
115
|
+
(_b = (_a = this.driver).close) === null || _b === void 0 ? void 0 : _b.call(_a, this);
|
|
115
116
|
}
|
|
116
117
|
close() {
|
|
117
118
|
this.closeSync();
|
|
118
119
|
return Promise.resolve();
|
|
119
120
|
}
|
|
120
121
|
syncSync() {
|
|
121
|
-
|
|
122
|
+
var _a, _b;
|
|
123
|
+
(_b = (_a = this.driver).sync) === null || _b === void 0 ? void 0 : _b.call(_a, this);
|
|
122
124
|
}
|
|
123
125
|
sync() {
|
|
124
126
|
this.syncSync();
|
|
@@ -158,10 +160,11 @@ export class DeviceFS extends StoreFS {
|
|
|
158
160
|
* @deprecated
|
|
159
161
|
*/
|
|
160
162
|
createDevice(path, driver, options = {}) {
|
|
163
|
+
var _a;
|
|
161
164
|
if (this.existsSync(path)) {
|
|
162
165
|
throw ErrnoError.With('EEXIST', path, 'mknod');
|
|
163
166
|
}
|
|
164
|
-
let ino =
|
|
167
|
+
let ino = BigInt(1);
|
|
165
168
|
while (this.store.has(ino))
|
|
166
169
|
ino++;
|
|
167
170
|
const dev = {
|
|
@@ -170,7 +173,7 @@ export class DeviceFS extends StoreFS {
|
|
|
170
173
|
data: {},
|
|
171
174
|
minor: 0,
|
|
172
175
|
major: 0,
|
|
173
|
-
...driver.init
|
|
176
|
+
...(_a = driver.init) === null || _a === void 0 ? void 0 : _a.call(driver, ino, options),
|
|
174
177
|
};
|
|
175
178
|
this.devices.set(path, dev);
|
|
176
179
|
return dev;
|
|
@@ -193,7 +196,8 @@ export class DeviceFS extends StoreFS {
|
|
|
193
196
|
* @internal
|
|
194
197
|
*/
|
|
195
198
|
_createDevice(driver, options = {}) {
|
|
196
|
-
|
|
199
|
+
var _a;
|
|
200
|
+
let ino = BigInt(1);
|
|
197
201
|
while (this.store.has(ino))
|
|
198
202
|
ino++;
|
|
199
203
|
const dev = {
|
|
@@ -202,7 +206,7 @@ export class DeviceFS extends StoreFS {
|
|
|
202
206
|
data: {},
|
|
203
207
|
minor: 0,
|
|
204
208
|
major: 0,
|
|
205
|
-
...driver.init
|
|
209
|
+
...(_a = driver.init) === null || _a === void 0 ? void 0 : _a.call(driver, ino, options),
|
|
206
210
|
};
|
|
207
211
|
const path = '/' + (dev.name || driver.name) + (driver.singleton ? '' : this.devicesWithDriver(driver).length);
|
|
208
212
|
if (this.existsSync(path)) {
|
package/dist/emulation/async.js
CHANGED
|
@@ -110,7 +110,7 @@ export function fstat(fd, options, cb = nop) {
|
|
|
110
110
|
cb = typeof options == 'function' ? options : cb;
|
|
111
111
|
fd2file(fd)
|
|
112
112
|
.stat()
|
|
113
|
-
.then(stats => cb(undefined, typeof options == 'object' && options
|
|
113
|
+
.then(stats => cb(undefined, typeof options == 'object' && (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats))
|
|
114
114
|
.catch(cb);
|
|
115
115
|
}
|
|
116
116
|
fstat;
|
|
@@ -429,7 +429,7 @@ export function createReadStream(path, options) {
|
|
|
429
429
|
encoding: options.encoding || 'utf8',
|
|
430
430
|
async read(size) {
|
|
431
431
|
try {
|
|
432
|
-
handle || (handle = await promises.open.call(context, path, 'r', options
|
|
432
|
+
handle || (handle = await promises.open.call(context, path, 'r', options === null || options === void 0 ? void 0 : options.mode));
|
|
433
433
|
const result = await handle.read(new Uint8Array(size), 0, size, handle.file.position);
|
|
434
434
|
stream.push(!result.bytesRead ? null : result.buffer.slice(0, result.bytesRead));
|
|
435
435
|
handle.file.position += result.bytesRead;
|
|
@@ -438,15 +438,12 @@ export function createReadStream(path, options) {
|
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
catch (error) {
|
|
441
|
-
await handle
|
|
441
|
+
await (handle === null || handle === void 0 ? void 0 : handle.close());
|
|
442
442
|
stream.destroy(error);
|
|
443
443
|
}
|
|
444
444
|
},
|
|
445
445
|
destroy(error, callback) {
|
|
446
|
-
handle
|
|
447
|
-
?.close()
|
|
448
|
-
.then(() => callback(error))
|
|
449
|
-
.catch(nop);
|
|
446
|
+
handle === null || handle === void 0 ? void 0 : handle.close().then(() => callback(error)).catch(nop);
|
|
450
447
|
},
|
|
451
448
|
});
|
|
452
449
|
stream.path = path.toString();
|
|
@@ -465,30 +462,24 @@ export function createWriteStream(path, options) {
|
|
|
465
462
|
options = typeof options == 'object' ? options : { encoding: options };
|
|
466
463
|
let handle;
|
|
467
464
|
const stream = new WriteStream({
|
|
468
|
-
highWaterMark: options
|
|
465
|
+
highWaterMark: options === null || options === void 0 ? void 0 : options.highWaterMark,
|
|
469
466
|
async write(chunk, encoding, callback) {
|
|
470
467
|
try {
|
|
471
|
-
handle || (handle = await promises.open.call(context, path, 'w', options
|
|
468
|
+
handle || (handle = await promises.open.call(context, path, 'w', (options === null || options === void 0 ? void 0 : options.mode) || 0o666));
|
|
472
469
|
await handle.write(chunk, 0, encoding);
|
|
473
470
|
callback(undefined);
|
|
474
471
|
}
|
|
475
472
|
catch (error) {
|
|
476
|
-
await handle
|
|
473
|
+
await (handle === null || handle === void 0 ? void 0 : handle.close());
|
|
477
474
|
callback(error);
|
|
478
475
|
}
|
|
479
476
|
},
|
|
480
477
|
destroy(error, callback) {
|
|
481
478
|
callback(error);
|
|
482
|
-
handle
|
|
483
|
-
?.close()
|
|
484
|
-
.then(() => callback(error))
|
|
485
|
-
.catch(callback);
|
|
479
|
+
handle === null || handle === void 0 ? void 0 : handle.close().then(() => callback(error)).catch(callback);
|
|
486
480
|
},
|
|
487
481
|
final(callback) {
|
|
488
|
-
handle
|
|
489
|
-
?.close()
|
|
490
|
-
.then(() => callback())
|
|
491
|
-
.catch(callback);
|
|
482
|
+
handle === null || handle === void 0 ? void 0 : handle.close().then(() => callback()).catch(callback);
|
|
492
483
|
},
|
|
493
484
|
});
|
|
494
485
|
stream.path = path.toString();
|
|
@@ -570,7 +561,7 @@ export function glob(pattern, options, callback = nop) {
|
|
|
570
561
|
callback = typeof options == 'function' ? options : callback;
|
|
571
562
|
const it = promises.glob.call(this, pattern, typeof options === 'function' ? undefined : options);
|
|
572
563
|
collectAsyncIterator(it)
|
|
573
|
-
.then(results => callback(null, results
|
|
564
|
+
.then(results => { var _a; return callback(null, (_a = results) !== null && _a !== void 0 ? _a : []); })
|
|
574
565
|
.catch((e) => callback(e));
|
|
575
566
|
}
|
|
576
567
|
glob;
|
package/dist/emulation/dir.js
CHANGED
|
@@ -64,11 +64,12 @@ export class Dir {
|
|
|
64
64
|
this.closed = true;
|
|
65
65
|
}
|
|
66
66
|
async _read() {
|
|
67
|
+
var _a, _b;
|
|
67
68
|
this.checkClosed();
|
|
68
|
-
this._entries
|
|
69
|
+
(_a = this._entries) !== null && _a !== void 0 ? _a : (this._entries = await readdir.call(this.context, this.path, { withFileTypes: true }));
|
|
69
70
|
if (!this._entries.length)
|
|
70
71
|
return null;
|
|
71
|
-
return this._entries.shift()
|
|
72
|
+
return (_b = this._entries.shift()) !== null && _b !== void 0 ? _b : null;
|
|
72
73
|
}
|
|
73
74
|
read(cb) {
|
|
74
75
|
if (!cb) {
|
|
@@ -82,11 +83,12 @@ export class Dir {
|
|
|
82
83
|
* Directory entries returned by this function are in no particular order as provided by the operating system's underlying directory mechanisms.
|
|
83
84
|
*/
|
|
84
85
|
readSync() {
|
|
86
|
+
var _a, _b;
|
|
85
87
|
this.checkClosed();
|
|
86
|
-
this._entries
|
|
88
|
+
(_a = this._entries) !== null && _a !== void 0 ? _a : (this._entries = readdirSync.call(this.context, this.path, { withFileTypes: true }));
|
|
87
89
|
if (!this._entries.length)
|
|
88
90
|
return null;
|
|
89
|
-
return this._entries.shift()
|
|
91
|
+
return (_b = this._entries.shift()) !== null && _b !== void 0 ? _b : null;
|
|
90
92
|
}
|
|
91
93
|
async next() {
|
|
92
94
|
const value = await this._read();
|
package/dist/emulation/path.js
CHANGED
|
@@ -146,7 +146,7 @@ export function join(...parts) {
|
|
|
146
146
|
if (!parts.length)
|
|
147
147
|
return '.';
|
|
148
148
|
const joined = parts.join('/');
|
|
149
|
-
if (!joined
|
|
149
|
+
if (!(joined === null || joined === void 0 ? void 0 : joined.length))
|
|
150
150
|
return '.';
|
|
151
151
|
return normalize(joined);
|
|
152
152
|
}
|
|
@@ -163,7 +163,7 @@ export class FileHandle {
|
|
|
163
163
|
position = this.file.position;
|
|
164
164
|
}
|
|
165
165
|
buffer || (buffer = new Uint8Array((await this.file.stat()).size));
|
|
166
|
-
return this.file.read(buffer, offset
|
|
166
|
+
return this.file.read(buffer, offset !== null && offset !== void 0 ? offset : undefined, length !== null && length !== void 0 ? length : undefined, position !== null && position !== void 0 ? position : undefined);
|
|
167
167
|
}
|
|
168
168
|
async readFile(_options) {
|
|
169
169
|
const options = normalizeOptions(_options, null, 'r', 0o444);
|
|
@@ -229,7 +229,7 @@ export class FileHandle {
|
|
|
229
229
|
if (config.checkAccess && !stats.hasAccess(constants.R_OK, this.context)) {
|
|
230
230
|
throw ErrnoError.With('EACCES', this.file.path, 'stat');
|
|
231
231
|
}
|
|
232
|
-
return opts
|
|
232
|
+
return (opts === null || opts === void 0 ? void 0 : opts.bigint) ? new BigIntStats(stats) : stats;
|
|
233
233
|
}
|
|
234
234
|
/**
|
|
235
235
|
* Asynchronously writes `string` to the file.
|
|
@@ -240,9 +240,9 @@ export class FileHandle {
|
|
|
240
240
|
async write(data, options, lenOrEnc, position) {
|
|
241
241
|
let buffer, offset, length;
|
|
242
242
|
if (typeof options == 'object') {
|
|
243
|
-
lenOrEnc = options
|
|
244
|
-
position = options
|
|
245
|
-
options = options
|
|
243
|
+
lenOrEnc = options === null || options === void 0 ? void 0 : options.length;
|
|
244
|
+
position = options === null || options === void 0 ? void 0 : options.position;
|
|
245
|
+
options = options === null || options === void 0 ? void 0 : options.offset;
|
|
246
246
|
}
|
|
247
247
|
if (typeof data === 'string') {
|
|
248
248
|
position = typeof options === 'number' ? options : null;
|
|
@@ -257,7 +257,7 @@ export class FileHandle {
|
|
|
257
257
|
length = lenOrEnc;
|
|
258
258
|
position = typeof position === 'number' ? position : null;
|
|
259
259
|
}
|
|
260
|
-
position
|
|
260
|
+
position !== null && position !== void 0 ? position : (position = this.file.position);
|
|
261
261
|
const bytesWritten = await this.file.write(buffer, offset, length, position);
|
|
262
262
|
emitChange('change', this.file.path);
|
|
263
263
|
return { buffer: data, bytesWritten };
|
|
@@ -324,7 +324,7 @@ export class FileHandle {
|
|
|
324
324
|
*/
|
|
325
325
|
createReadStream(options) {
|
|
326
326
|
const stream = new ReadStream({
|
|
327
|
-
highWaterMark: options
|
|
327
|
+
highWaterMark: (options === null || options === void 0 ? void 0 : options.highWaterMark) || 64 * 1024,
|
|
328
328
|
encoding: options.encoding,
|
|
329
329
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
330
330
|
read: async (size) => {
|
|
@@ -347,8 +347,8 @@ export class FileHandle {
|
|
|
347
347
|
*/
|
|
348
348
|
createWriteStream(options) {
|
|
349
349
|
const streamOptions = {
|
|
350
|
-
highWaterMark: options
|
|
351
|
-
encoding: options
|
|
350
|
+
highWaterMark: options === null || options === void 0 ? void 0 : options.highWaterMark,
|
|
351
|
+
encoding: options === null || options === void 0 ? void 0 : options.encoding,
|
|
352
352
|
write: async (chunk, encoding, callback) => {
|
|
353
353
|
try {
|
|
354
354
|
const { bytesWritten } = await this.write(chunk, null, encoding);
|
|
@@ -411,7 +411,7 @@ export async function stat(path, options) {
|
|
|
411
411
|
if (config.checkAccess && !stats.hasAccess(constants.R_OK, this)) {
|
|
412
412
|
throw ErrnoError.With('EACCES', resolved, 'stat');
|
|
413
413
|
}
|
|
414
|
-
return options
|
|
414
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
|
|
415
415
|
}
|
|
416
416
|
catch (e) {
|
|
417
417
|
throw fixError(e, { [resolved]: path });
|
|
@@ -423,7 +423,7 @@ export async function lstat(path, options) {
|
|
|
423
423
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
424
424
|
try {
|
|
425
425
|
const stats = await fs.stat(resolved);
|
|
426
|
-
return options
|
|
426
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
|
|
427
427
|
}
|
|
428
428
|
catch (e) {
|
|
429
429
|
throw fixError(e, { [resolved]: path });
|
|
@@ -619,13 +619,14 @@ export async function rmdir(path) {
|
|
|
619
619
|
}
|
|
620
620
|
rmdir;
|
|
621
621
|
export async function mkdir(path, options) {
|
|
622
|
+
var _a;
|
|
622
623
|
options = typeof options === 'object' ? options : { mode: options };
|
|
623
|
-
const mode = normalizeMode(options
|
|
624
|
+
const mode = normalizeMode(options === null || options === void 0 ? void 0 : options.mode, 0o777);
|
|
624
625
|
path = await realpath.call(this, path);
|
|
625
626
|
const { fs, path: resolved, root } = resolveMount(path, this);
|
|
626
627
|
const errorPaths = { [resolved]: path };
|
|
627
628
|
try {
|
|
628
|
-
if (!options
|
|
629
|
+
if (!(options === null || options === void 0 ? void 0 : options.recursive)) {
|
|
629
630
|
if (config.checkAccess && !(await fs.stat(dirname(resolved))).hasAccess(constants.W_OK, this)) {
|
|
630
631
|
throw ErrnoError.With('EACCES', dirname(resolved), 'mkdir');
|
|
631
632
|
}
|
|
@@ -645,7 +646,7 @@ export async function mkdir(path, options) {
|
|
|
645
646
|
await fs.mkdir(dir, mode);
|
|
646
647
|
emitChange('rename', dir);
|
|
647
648
|
}
|
|
648
|
-
return root.length == 1 ? dirs[0] : dirs[0]
|
|
649
|
+
return root.length == 1 ? dirs[0] : (_a = dirs[0]) === null || _a === void 0 ? void 0 : _a.slice(root.length);
|
|
649
650
|
}
|
|
650
651
|
catch (e) {
|
|
651
652
|
throw fixError(e, errorPaths);
|
|
@@ -675,21 +676,21 @@ export async function readdir(path, options) {
|
|
|
675
676
|
const values = [];
|
|
676
677
|
const addEntry = async (entry) => {
|
|
677
678
|
let entryStats;
|
|
678
|
-
if (options
|
|
679
|
+
if ((options === null || options === void 0 ? void 0 : options.recursive) || (options === null || options === void 0 ? void 0 : options.withFileTypes)) {
|
|
679
680
|
const _entryStats = cache.stats.getAsync(join(path, entry)) || fs.stat(join(resolved, entry)).catch(handleError);
|
|
680
681
|
cache.stats.setAsync(join(path, entry), _entryStats);
|
|
681
682
|
entryStats = await _entryStats;
|
|
682
683
|
}
|
|
683
|
-
if (options
|
|
684
|
+
if (options === null || options === void 0 ? void 0 : options.withFileTypes) {
|
|
684
685
|
values.push(new Dirent(entry, entryStats));
|
|
685
686
|
}
|
|
686
|
-
else if (options
|
|
687
|
+
else if ((options === null || options === void 0 ? void 0 : options.encoding) == 'buffer') {
|
|
687
688
|
values.push(Buffer.from(entry));
|
|
688
689
|
}
|
|
689
690
|
else {
|
|
690
691
|
values.push(entry);
|
|
691
692
|
}
|
|
692
|
-
if (!options
|
|
693
|
+
if (!(options === null || options === void 0 ? void 0 : options.recursive) || !(entryStats === null || entryStats === void 0 ? void 0 : entryStats.isDirectory()))
|
|
693
694
|
return;
|
|
694
695
|
for (const subEntry of await readdir.call(this, join(path, entry), { ...options, _isIndirect: true })) {
|
|
695
696
|
if (subEntry instanceof Dirent) {
|
|
@@ -706,7 +707,7 @@ export async function readdir(path, options) {
|
|
|
706
707
|
}
|
|
707
708
|
};
|
|
708
709
|
await Promise.all(entries.map(addEntry));
|
|
709
|
-
if (!options
|
|
710
|
+
if (!(options === null || options === void 0 ? void 0 : options._isIndirect)) {
|
|
710
711
|
cache.stats.clear();
|
|
711
712
|
}
|
|
712
713
|
return values;
|
|
@@ -772,9 +773,9 @@ export async function readlink(path, options) {
|
|
|
772
773
|
try {
|
|
773
774
|
const handle = __addDisposableResource(env_6, await _open.call(this, normalizePath(path), 'r', 0o644, false), true);
|
|
774
775
|
const value = await handle.readFile();
|
|
775
|
-
const encoding = typeof options == 'object' ? options
|
|
776
|
+
const encoding = typeof options == 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options;
|
|
776
777
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
777
|
-
return encoding == 'buffer' ? value : value.toString((encoding
|
|
778
|
+
return encoding == 'buffer' ? value : value.toString((encoding !== null && encoding !== void 0 ? encoding : 'utf-8'));
|
|
778
779
|
}
|
|
779
780
|
catch (e_6) {
|
|
780
781
|
env_6.error = e_6;
|
|
@@ -897,11 +898,11 @@ export async function lutimes(path, atime, mtime) {
|
|
|
897
898
|
lutimes;
|
|
898
899
|
export async function realpath(path, options) {
|
|
899
900
|
path = normalizePath(path);
|
|
900
|
-
const ctx_path = (this
|
|
901
|
+
const ctx_path = ((this === null || this === void 0 ? void 0 : this.root) || '') + path;
|
|
901
902
|
if (cache.paths.hasAsync(ctx_path))
|
|
902
903
|
return cache.paths.getAsync(ctx_path);
|
|
903
904
|
const { base, dir } = parse(path);
|
|
904
|
-
const realDir = dir == '/' ? '/' : await (cache.paths.getAsync((this
|
|
905
|
+
const realDir = dir == '/' ? '/' : await (cache.paths.getAsync(((this === null || this === void 0 ? void 0 : this.root) || '') + dir) || realpath.call(this, dir));
|
|
905
906
|
const lpath = join(realDir, base);
|
|
906
907
|
const { fs, path: resolvedPath } = resolveMount(lpath, this);
|
|
907
908
|
try {
|
|
@@ -912,7 +913,7 @@ export async function realpath(path, options) {
|
|
|
912
913
|
return lpath;
|
|
913
914
|
}
|
|
914
915
|
const target = resolve(realDir, (await readlink.call(this, lpath)).toString());
|
|
915
|
-
const real = cache.paths.getAsync((this
|
|
916
|
+
const real = cache.paths.getAsync(((this === null || this === void 0 ? void 0 : this.root) || '') + target) || realpath.call(this, target);
|
|
916
917
|
cache.paths.setAsync(ctx_path, real);
|
|
917
918
|
return await real;
|
|
918
919
|
}
|
|
@@ -931,7 +932,8 @@ export function watch(filename, options = {}) {
|
|
|
931
932
|
// A queue to hold change events, since we need to resolve them in the async iterator
|
|
932
933
|
const eventQueue = [];
|
|
933
934
|
watcher.on('change', (eventType, filename) => {
|
|
934
|
-
|
|
935
|
+
var _a;
|
|
936
|
+
(_a = eventQueue.shift()) === null || _a === void 0 ? void 0 : _a({ value: { eventType, filename }, done: false });
|
|
935
937
|
});
|
|
936
938
|
function cleanup() {
|
|
937
939
|
watcher.close();
|
|
@@ -974,7 +976,7 @@ export async function rm(path, options) {
|
|
|
974
976
|
path = normalizePath(path);
|
|
975
977
|
const stats = await (cache.stats.getAsync(path) ||
|
|
976
978
|
lstat.call(this, path).catch((error) => {
|
|
977
|
-
if (error.code == 'ENOENT' && options
|
|
979
|
+
if (error.code == 'ENOENT' && (options === null || options === void 0 ? void 0 : options.force))
|
|
978
980
|
return undefined;
|
|
979
981
|
throw error;
|
|
980
982
|
}));
|
|
@@ -984,7 +986,7 @@ export async function rm(path, options) {
|
|
|
984
986
|
cache.stats.set(path, stats);
|
|
985
987
|
switch (stats.mode & constants.S_IFMT) {
|
|
986
988
|
case constants.S_IFDIR:
|
|
987
|
-
if (options
|
|
989
|
+
if (options === null || options === void 0 ? void 0 : options.recursive) {
|
|
988
990
|
for (const entry of await readdir.call(this, path, { _isIndirect: true })) {
|
|
989
991
|
await rm.call(this, join(path, entry), { ...options, _isIndirect: true });
|
|
990
992
|
}
|
|
@@ -1003,13 +1005,13 @@ export async function rm(path, options) {
|
|
|
1003
1005
|
cache.stats.clear();
|
|
1004
1006
|
throw new ErrnoError(Errno.EPERM, 'File type not supported', path, 'rm');
|
|
1005
1007
|
}
|
|
1006
|
-
if (!options
|
|
1008
|
+
if (!(options === null || options === void 0 ? void 0 : options._isIndirect)) {
|
|
1007
1009
|
cache.stats.clear();
|
|
1008
1010
|
}
|
|
1009
1011
|
}
|
|
1010
1012
|
rm;
|
|
1011
1013
|
export async function mkdtemp(prefix, options) {
|
|
1012
|
-
const encoding = typeof options === 'object' ? options
|
|
1014
|
+
const encoding = typeof options === 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options || 'utf8';
|
|
1013
1015
|
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
1014
1016
|
const resolvedPath = '/tmp/' + fsName;
|
|
1015
1017
|
await mkdir.call(this, resolvedPath);
|
|
@@ -1061,12 +1063,12 @@ export async function cp(source, destination, opts) {
|
|
|
1061
1063
|
source = normalizePath(source);
|
|
1062
1064
|
destination = normalizePath(destination);
|
|
1063
1065
|
const srcStats = await lstat.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
1064
|
-
if (opts
|
|
1066
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.errorOnExist) && (await exists.call(this, destination))) {
|
|
1065
1067
|
throw new ErrnoError(Errno.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
|
|
1066
1068
|
}
|
|
1067
1069
|
switch (srcStats.mode & constants.S_IFMT) {
|
|
1068
1070
|
case constants.S_IFDIR: {
|
|
1069
|
-
if (!opts
|
|
1071
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.recursive)) {
|
|
1070
1072
|
throw new ErrnoError(Errno.EISDIR, source + ' is a directory (not copied)', source, 'cp');
|
|
1071
1073
|
}
|
|
1072
1074
|
const [entries] = await Promise.all([readdir.call(this, source, { withFileTypes: true }), mkdir.call(this, destination, { recursive: true })] // Ensure the destination directory exists
|
|
@@ -1092,7 +1094,7 @@ export async function cp(source, destination, opts) {
|
|
|
1092
1094
|
throw new ErrnoError(Errno.EPERM, 'File type not supported', source, 'rm');
|
|
1093
1095
|
}
|
|
1094
1096
|
// Optionally preserve timestamps
|
|
1095
|
-
if (opts
|
|
1097
|
+
if (opts === null || opts === void 0 ? void 0 : opts.preserveTimestamps) {
|
|
1096
1098
|
await utimes.call(this, destination, srcStats.atime, srcStats.mtime);
|
|
1097
1099
|
}
|
|
1098
1100
|
}
|
|
@@ -1100,7 +1102,7 @@ cp;
|
|
|
1100
1102
|
export async function statfs(path, opts) {
|
|
1101
1103
|
path = normalizePath(path);
|
|
1102
1104
|
const { fs } = resolveMount(path, this);
|
|
1103
|
-
return Promise.resolve(_statfs(fs, opts
|
|
1105
|
+
return Promise.resolve(_statfs(fs, opts === null || opts === void 0 ? void 0 : opts.bigint));
|
|
1104
1106
|
}
|
|
1105
1107
|
export function glob(pattern, opt) {
|
|
1106
1108
|
pattern = Array.isArray(pattern) ? pattern : [pattern];
|
package/dist/emulation/shared.js
CHANGED
|
@@ -70,7 +70,7 @@ export function umount(mountPoint) {
|
|
|
70
70
|
* @internal @hidden
|
|
71
71
|
*/
|
|
72
72
|
export function resolveMount(path, ctx) {
|
|
73
|
-
const root = ctx
|
|
73
|
+
const root = (ctx === null || ctx === void 0 ? void 0 : ctx.root) || '/';
|
|
74
74
|
path = normalizePath(join(root, path));
|
|
75
75
|
const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // descending order of the string length
|
|
76
76
|
for (const [mountPoint, fs] of sortedMounts) {
|
|
@@ -91,7 +91,7 @@ export function resolveMount(path, ctx) {
|
|
|
91
91
|
*/
|
|
92
92
|
export function fixPaths(text, paths) {
|
|
93
93
|
for (const [from, to] of Object.entries(paths)) {
|
|
94
|
-
text = text
|
|
94
|
+
text = text === null || text === void 0 ? void 0 : text.replaceAll(from, to);
|
|
95
95
|
}
|
|
96
96
|
return text;
|
|
97
97
|
}
|
|
@@ -141,15 +141,15 @@ export function _statfs(fs, bigint) {
|
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
export function chroot(path, inPlace) {
|
|
144
|
-
const creds = this
|
|
145
|
-
if (creds
|
|
144
|
+
const creds = this === null || this === void 0 ? void 0 : this.credentials;
|
|
145
|
+
if ((creds === null || creds === void 0 ? void 0 : creds.uid) && (creds === null || creds === void 0 ? void 0 : creds.gid) && (creds === null || creds === void 0 ? void 0 : creds.euid) && (creds === null || creds === void 0 ? void 0 : creds.egid)) {
|
|
146
146
|
throw new ErrnoError(Errno.EPERM, 'Can not chroot() as non-root user');
|
|
147
147
|
}
|
|
148
148
|
if (inPlace && this) {
|
|
149
149
|
this.root += path;
|
|
150
150
|
return this;
|
|
151
151
|
}
|
|
152
|
-
return bindContext(join(this
|
|
152
|
+
return bindContext(join((this === null || this === void 0 ? void 0 : this.root) || '/', path), creds);
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
155
|
* @internal @hidden
|
package/dist/emulation/sync.js
CHANGED
|
@@ -111,7 +111,7 @@ export function statSync(path, options) {
|
|
|
111
111
|
if (config.checkAccess && !stats.hasAccess(constants.R_OK, this)) {
|
|
112
112
|
throw ErrnoError.With('EACCES', resolved, 'stat');
|
|
113
113
|
}
|
|
114
|
-
return options
|
|
114
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
|
|
115
115
|
}
|
|
116
116
|
catch (e) {
|
|
117
117
|
throw fixError(e, { [resolved]: path });
|
|
@@ -123,7 +123,7 @@ export function lstatSync(path, options) {
|
|
|
123
123
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
124
124
|
try {
|
|
125
125
|
const stats = fs.statSync(resolved);
|
|
126
|
-
return options
|
|
126
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
|
|
127
127
|
}
|
|
128
128
|
catch (e) {
|
|
129
129
|
throw fixError(e, { [resolved]: path });
|
|
@@ -306,7 +306,7 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
306
306
|
appendFileSync;
|
|
307
307
|
export function fstatSync(fd, options) {
|
|
308
308
|
const stats = fd2file(fd).statSync();
|
|
309
|
-
return options
|
|
309
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
|
|
310
310
|
}
|
|
311
311
|
fstatSync;
|
|
312
312
|
export function closeSync(fd) {
|
|
@@ -348,7 +348,7 @@ export function writeSync(fd, data, posOrOff, lenOrEnc, pos) {
|
|
|
348
348
|
position = typeof pos === 'number' ? pos : null;
|
|
349
349
|
}
|
|
350
350
|
const file = fd2file(fd);
|
|
351
|
-
position
|
|
351
|
+
position !== null && position !== void 0 ? position : (position = file.position);
|
|
352
352
|
const bytesWritten = file.writeSync(buffer, offset, length, position);
|
|
353
353
|
emitChange('change', file.path);
|
|
354
354
|
return bytesWritten;
|
|
@@ -415,13 +415,14 @@ export function rmdirSync(path) {
|
|
|
415
415
|
}
|
|
416
416
|
rmdirSync;
|
|
417
417
|
export function mkdirSync(path, options) {
|
|
418
|
+
var _a;
|
|
418
419
|
options = typeof options === 'object' ? options : { mode: options };
|
|
419
|
-
const mode = normalizeMode(options
|
|
420
|
+
const mode = normalizeMode(options === null || options === void 0 ? void 0 : options.mode, 0o777);
|
|
420
421
|
path = realpathSync.call(this, path);
|
|
421
422
|
const { fs, path: resolved, root } = resolveMount(path, this);
|
|
422
423
|
const errorPaths = { [resolved]: path };
|
|
423
424
|
try {
|
|
424
|
-
if (!options
|
|
425
|
+
if (!(options === null || options === void 0 ? void 0 : options.recursive)) {
|
|
425
426
|
if (config.checkAccess && !fs.statSync(dirname(resolved)).hasAccess(constants.W_OK, this)) {
|
|
426
427
|
throw ErrnoError.With('EACCES', dirname(resolved), 'mkdir');
|
|
427
428
|
}
|
|
@@ -439,7 +440,7 @@ export function mkdirSync(path, options) {
|
|
|
439
440
|
fs.mkdirSync(dir, mode);
|
|
440
441
|
emitChange('rename', dir);
|
|
441
442
|
}
|
|
442
|
-
return root.length == 1 ? dirs[0] : dirs[0]
|
|
443
|
+
return root.length == 1 ? dirs[0] : (_a = dirs[0]) === null || _a === void 0 ? void 0 : _a.slice(root.length);
|
|
443
444
|
}
|
|
444
445
|
catch (e) {
|
|
445
446
|
throw fixError(e, errorPaths);
|
|
@@ -470,16 +471,16 @@ export function readdirSync(path, options) {
|
|
|
470
471
|
for (const entry of entries) {
|
|
471
472
|
const entryStat = cache.stats.get(join(path, entry)) || fs.statSync(join(resolved, entry));
|
|
472
473
|
cache.stats.set(join(path, entry), entryStat);
|
|
473
|
-
if (options
|
|
474
|
+
if (options === null || options === void 0 ? void 0 : options.withFileTypes) {
|
|
474
475
|
values.push(new Dirent(entry, entryStat));
|
|
475
476
|
}
|
|
476
|
-
else if (options
|
|
477
|
+
else if ((options === null || options === void 0 ? void 0 : options.encoding) == 'buffer') {
|
|
477
478
|
values.push(Buffer.from(entry));
|
|
478
479
|
}
|
|
479
480
|
else {
|
|
480
481
|
values.push(entry);
|
|
481
482
|
}
|
|
482
|
-
if (!entryStat.isDirectory() || !options
|
|
483
|
+
if (!entryStat.isDirectory() || !(options === null || options === void 0 ? void 0 : options.recursive))
|
|
483
484
|
continue;
|
|
484
485
|
for (const subEntry of readdirSync.call(this, join(path, entry), { ...options, _isIndirect: true })) {
|
|
485
486
|
if (subEntry instanceof Dirent) {
|
|
@@ -494,7 +495,7 @@ export function readdirSync(path, options) {
|
|
|
494
495
|
}
|
|
495
496
|
}
|
|
496
497
|
}
|
|
497
|
-
if (!options
|
|
498
|
+
if (!(options === null || options === void 0 ? void 0 : options._isIndirect)) {
|
|
498
499
|
cache.stats.clear();
|
|
499
500
|
}
|
|
500
501
|
return values;
|
|
@@ -545,12 +546,12 @@ export function symlinkSync(target, path, type = 'file') {
|
|
|
545
546
|
symlinkSync;
|
|
546
547
|
export function readlinkSync(path, options) {
|
|
547
548
|
const value = Buffer.from(_readFileSync.call(this, path.toString(), 'r', false));
|
|
548
|
-
const encoding = typeof options == 'object' ? options
|
|
549
|
+
const encoding = typeof options == 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options;
|
|
549
550
|
if (encoding == 'buffer') {
|
|
550
551
|
return value;
|
|
551
552
|
}
|
|
552
553
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
553
|
-
return value.toString(encoding
|
|
554
|
+
return value.toString(encoding !== null && encoding !== void 0 ? encoding : 'utf-8');
|
|
554
555
|
}
|
|
555
556
|
readlinkSync;
|
|
556
557
|
export function chownSync(path, uid, gid) {
|
|
@@ -597,11 +598,11 @@ export function lutimesSync(path, atime, mtime) {
|
|
|
597
598
|
lutimesSync;
|
|
598
599
|
export function realpathSync(path, options) {
|
|
599
600
|
path = normalizePath(path);
|
|
600
|
-
const ctx_path = (this
|
|
601
|
+
const ctx_path = ((this === null || this === void 0 ? void 0 : this.root) || '') + path;
|
|
601
602
|
if (cache.paths.has(ctx_path))
|
|
602
603
|
return cache.paths.get(ctx_path);
|
|
603
604
|
const { base, dir } = parse(path);
|
|
604
|
-
const realDir = dir == '/' ? '/' : cache.paths.get((this
|
|
605
|
+
const realDir = dir == '/' ? '/' : cache.paths.get(((this === null || this === void 0 ? void 0 : this.root) || '') + dir) || realpathSync.call(this, dir);
|
|
605
606
|
const lpath = join(realDir, base);
|
|
606
607
|
const { fs, path: resolvedPath } = resolveMount(lpath, this);
|
|
607
608
|
try {
|
|
@@ -612,7 +613,7 @@ export function realpathSync(path, options) {
|
|
|
612
613
|
return lpath;
|
|
613
614
|
}
|
|
614
615
|
const target = resolve(realDir, readlinkSync.call(this, lpath, options).toString());
|
|
615
|
-
const real = cache.paths.get((this
|
|
616
|
+
const real = cache.paths.get(((this === null || this === void 0 ? void 0 : this.root) || '') + target) || realpathSync.call(this, target);
|
|
616
617
|
cache.paths.set(ctx_path, real);
|
|
617
618
|
return real;
|
|
618
619
|
}
|
|
@@ -643,7 +644,7 @@ export function rmSync(path, options) {
|
|
|
643
644
|
stats = cache.stats.get(path) || lstatSync.bind(this)(path);
|
|
644
645
|
}
|
|
645
646
|
catch (error) {
|
|
646
|
-
if (error.code != 'ENOENT' || !options
|
|
647
|
+
if (error.code != 'ENOENT' || !(options === null || options === void 0 ? void 0 : options.force))
|
|
647
648
|
throw error;
|
|
648
649
|
}
|
|
649
650
|
if (!stats) {
|
|
@@ -652,7 +653,7 @@ export function rmSync(path, options) {
|
|
|
652
653
|
cache.stats.set(path, stats);
|
|
653
654
|
switch (stats.mode & constants.S_IFMT) {
|
|
654
655
|
case constants.S_IFDIR:
|
|
655
|
-
if (options
|
|
656
|
+
if (options === null || options === void 0 ? void 0 : options.recursive) {
|
|
656
657
|
for (const entry of readdirSync.call(this, path, { _isIndirect: true })) {
|
|
657
658
|
rmSync.call(this, join(path, entry), { ...options, _isIndirect: true });
|
|
658
659
|
}
|
|
@@ -671,13 +672,13 @@ export function rmSync(path, options) {
|
|
|
671
672
|
cache.stats.clear();
|
|
672
673
|
throw new ErrnoError(Errno.EPERM, 'File type not supported', path, 'rm');
|
|
673
674
|
}
|
|
674
|
-
if (!options
|
|
675
|
+
if (!(options === null || options === void 0 ? void 0 : options._isIndirect)) {
|
|
675
676
|
cache.stats.clear();
|
|
676
677
|
}
|
|
677
678
|
}
|
|
678
679
|
rmSync;
|
|
679
680
|
export function mkdtempSync(prefix, options) {
|
|
680
|
-
const encoding = typeof options === 'object' ? options
|
|
681
|
+
const encoding = typeof options === 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options || 'utf8';
|
|
681
682
|
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
682
683
|
const resolvedPath = '/tmp/' + fsName;
|
|
683
684
|
mkdirSync.call(this, resolvedPath);
|
|
@@ -759,12 +760,12 @@ export function cpSync(source, destination, opts) {
|
|
|
759
760
|
source = normalizePath(source);
|
|
760
761
|
destination = normalizePath(destination);
|
|
761
762
|
const srcStats = lstatSync.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
762
|
-
if (opts
|
|
763
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.errorOnExist) && existsSync.call(this, destination)) {
|
|
763
764
|
throw new ErrnoError(Errno.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
|
|
764
765
|
}
|
|
765
766
|
switch (srcStats.mode & constants.S_IFMT) {
|
|
766
767
|
case constants.S_IFDIR:
|
|
767
|
-
if (!opts
|
|
768
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.recursive)) {
|
|
768
769
|
throw new ErrnoError(Errno.EISDIR, source + ' is a directory (not copied)', source, 'cp');
|
|
769
770
|
}
|
|
770
771
|
mkdirSync.call(this, destination, { recursive: true }); // Ensure the destination directory exists
|
|
@@ -787,7 +788,7 @@ export function cpSync(source, destination, opts) {
|
|
|
787
788
|
throw new ErrnoError(Errno.EPERM, 'File type not supported', source, 'rm');
|
|
788
789
|
}
|
|
789
790
|
// Optionally preserve timestamps
|
|
790
|
-
if (opts
|
|
791
|
+
if (opts === null || opts === void 0 ? void 0 : opts.preserveTimestamps) {
|
|
791
792
|
utimesSync.call(this, destination, srcStats.atime, srcStats.mtime);
|
|
792
793
|
}
|
|
793
794
|
}
|
|
@@ -795,7 +796,7 @@ cpSync;
|
|
|
795
796
|
export function statfsSync(path, options) {
|
|
796
797
|
path = normalizePath(path);
|
|
797
798
|
const { fs } = resolveMount(path, this);
|
|
798
|
-
return _statfs(fs, options
|
|
799
|
+
return _statfs(fs, options === null || options === void 0 ? void 0 : options.bigint);
|
|
799
800
|
}
|
|
800
801
|
export function globSync(pattern, options = {}) {
|
|
801
802
|
pattern = Array.isArray(pattern) ? pattern : [pattern];
|
package/dist/file.js
CHANGED
|
@@ -367,7 +367,7 @@ export class PreloadFile extends File {
|
|
|
367
367
|
this.dirty = true;
|
|
368
368
|
}
|
|
369
369
|
this.stats.atimeMs = Date.now();
|
|
370
|
-
position
|
|
370
|
+
position !== null && position !== void 0 ? position : (position = this.position);
|
|
371
371
|
let end = position + length;
|
|
372
372
|
if (end > this.stats.size) {
|
|
373
373
|
end = position + Math.max(this.stats.size - position, 0);
|
package/dist/filesystem.js
CHANGED
|
@@ -10,13 +10,14 @@ export class FileSystem {
|
|
|
10
10
|
* Get metadata about the current file system
|
|
11
11
|
*/
|
|
12
12
|
metadata() {
|
|
13
|
+
var _a;
|
|
13
14
|
return {
|
|
14
15
|
name: this.constructor.name.toLowerCase(),
|
|
15
16
|
readonly: false,
|
|
16
17
|
totalSpace: 0,
|
|
17
18
|
freeSpace: 0,
|
|
18
19
|
noResizableBuffers: false,
|
|
19
|
-
noAsyncCache: this._disableSync
|
|
20
|
+
noAsyncCache: (_a = this._disableSync) !== null && _a !== void 0 ? _a : false,
|
|
20
21
|
type: ZenFsType,
|
|
21
22
|
};
|
|
22
23
|
}
|
package/dist/mixins/async.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { type File } from '../file.js';
|
|
2
1
|
import type { FileSystem } from '../filesystem.js';
|
|
3
|
-
import type {
|
|
4
|
-
import type { AsyncFSMethods, Mixin } from './shared.js';
|
|
2
|
+
import type { _SyncFSKeys, AsyncFSMethods, Mixin } from './shared.js';
|
|
5
3
|
/** @internal */
|
|
6
4
|
export type AsyncOperation = {
|
|
7
5
|
[K in keyof AsyncFSMethods]: [K, ...Parameters<FileSystem[K]>];
|
|
@@ -9,23 +7,13 @@ export type AsyncOperation = {
|
|
|
9
7
|
/**
|
|
10
8
|
* @internal
|
|
11
9
|
*/
|
|
12
|
-
export interface AsyncMixin {
|
|
10
|
+
export interface AsyncMixin extends Pick<FileSystem, Exclude<_SyncFSKeys, 'existsSync'>> {
|
|
13
11
|
/**
|
|
14
12
|
* @internal @protected
|
|
15
13
|
*/
|
|
16
14
|
_sync?: FileSystem;
|
|
17
15
|
queueDone(): Promise<void>;
|
|
18
16
|
ready(): Promise<void>;
|
|
19
|
-
renameSync(oldPath: string, newPath: string): void;
|
|
20
|
-
statSync(path: string): Stats;
|
|
21
|
-
createFileSync(path: string, flag: string, mode: number): File;
|
|
22
|
-
openFileSync(path: string, flag: string): File;
|
|
23
|
-
unlinkSync(path: string): void;
|
|
24
|
-
rmdirSync(path: string): void;
|
|
25
|
-
mkdirSync(path: string, mode: number): void;
|
|
26
|
-
readdirSync(path: string): string[];
|
|
27
|
-
linkSync(srcpath: string, dstpath: string): void;
|
|
28
|
-
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
|
|
29
17
|
}
|
|
30
18
|
/**
|
|
31
19
|
* Async() implements synchronous methods on an asynchronous file system
|
package/dist/mixins/async.js
CHANGED
|
@@ -66,14 +66,6 @@ import { parseFlag, PreloadFile } from '../file.js';
|
|
|
66
66
|
*/
|
|
67
67
|
export function Async(FS) {
|
|
68
68
|
class AsyncFS extends FS {
|
|
69
|
-
constructor() {
|
|
70
|
-
super(...arguments);
|
|
71
|
-
/**
|
|
72
|
-
* Queue of pending asynchronous operations.
|
|
73
|
-
*/
|
|
74
|
-
this._queue = [];
|
|
75
|
-
this._isInitialized = false;
|
|
76
|
-
}
|
|
77
69
|
get _queueRunning() {
|
|
78
70
|
return !!this._queue.length;
|
|
79
71
|
}
|
|
@@ -83,6 +75,15 @@ export function Async(FS) {
|
|
|
83
75
|
check();
|
|
84
76
|
});
|
|
85
77
|
}
|
|
78
|
+
constructor(...args) {
|
|
79
|
+
super(...args);
|
|
80
|
+
/**
|
|
81
|
+
* Queue of pending asynchronous operations.
|
|
82
|
+
*/
|
|
83
|
+
this._queue = [];
|
|
84
|
+
this._isInitialized = false;
|
|
85
|
+
this._patchAsync();
|
|
86
|
+
}
|
|
86
87
|
async ready() {
|
|
87
88
|
await super.ready();
|
|
88
89
|
await this.queueDone();
|
|
@@ -231,6 +232,32 @@ export function Async(FS) {
|
|
|
231
232
|
this._queue.push(op);
|
|
232
233
|
void this._next();
|
|
233
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* @internal
|
|
237
|
+
* Patch all async methods to also call their synchronous counterparts unless called from the queue
|
|
238
|
+
*/
|
|
239
|
+
_patchAsync() {
|
|
240
|
+
const asyncFSMethodKeys = ['rename', 'stat', 'createFile', 'openFile', 'unlink', 'rmdir', 'mkdir', 'readdir', 'link', 'sync', 'exists'];
|
|
241
|
+
for (const key of asyncFSMethodKeys) {
|
|
242
|
+
if (typeof this[key] !== 'function')
|
|
243
|
+
continue;
|
|
244
|
+
const originalMethod = this[key];
|
|
245
|
+
this[key] = async (...args) => {
|
|
246
|
+
var _a, _b;
|
|
247
|
+
const result = await originalMethod.apply(this, args);
|
|
248
|
+
if (new Error().stack.includes(`at async ${this.constructor.name}._next`))
|
|
249
|
+
return result;
|
|
250
|
+
try {
|
|
251
|
+
// @ts-expect-error 2556
|
|
252
|
+
(_b = (_a = this._sync) === null || _a === void 0 ? void 0 : _a[`${key}Sync`]) === null || _b === void 0 ? void 0 : _b.call(_a, ...args);
|
|
253
|
+
}
|
|
254
|
+
catch (e) {
|
|
255
|
+
throw new ErrnoError(e.errno, 'Out of sync! (' + e.message + ')', args[0], key);
|
|
256
|
+
}
|
|
257
|
+
return result;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
234
261
|
}
|
|
235
262
|
return AsyncFS;
|
|
236
263
|
}
|
package/dist/mixins/mutexed.js
CHANGED
|
@@ -62,7 +62,8 @@ export class MutexLock {
|
|
|
62
62
|
this._isLocked = true;
|
|
63
63
|
}
|
|
64
64
|
async done() {
|
|
65
|
-
|
|
65
|
+
var _a;
|
|
66
|
+
await ((_a = this.previous) === null || _a === void 0 ? void 0 : _a.done());
|
|
66
67
|
await this.current.promise;
|
|
67
68
|
}
|
|
68
69
|
unlock() {
|
|
@@ -103,11 +104,11 @@ export class _MutexedFS {
|
|
|
103
104
|
setTimeout(() => {
|
|
104
105
|
if (lock.isLocked) {
|
|
105
106
|
const error = ErrnoError.With('EDEADLK', path, syscall);
|
|
106
|
-
error.stack += stack
|
|
107
|
+
error.stack += stack === null || stack === void 0 ? void 0 : stack.slice('Error'.length);
|
|
107
108
|
throw error;
|
|
108
109
|
}
|
|
109
110
|
}, 5000);
|
|
110
|
-
await previous
|
|
111
|
+
await (previous === null || previous === void 0 ? void 0 : previous.done());
|
|
111
112
|
return lock;
|
|
112
113
|
}
|
|
113
114
|
/**
|
|
@@ -116,7 +117,8 @@ export class _MutexedFS {
|
|
|
116
117
|
* @internal
|
|
117
118
|
*/
|
|
118
119
|
lockSync(path, syscall) {
|
|
119
|
-
|
|
120
|
+
var _a;
|
|
121
|
+
if ((_a = this.currentLock) === null || _a === void 0 ? void 0 : _a.isLocked) {
|
|
120
122
|
throw ErrnoError.With('EBUSY', path, syscall);
|
|
121
123
|
}
|
|
122
124
|
return this.addLock();
|
|
@@ -126,7 +128,8 @@ export class _MutexedFS {
|
|
|
126
128
|
* @internal
|
|
127
129
|
*/
|
|
128
130
|
get isLocked() {
|
|
129
|
-
|
|
131
|
+
var _a;
|
|
132
|
+
return !!((_a = this.currentLock) === null || _a === void 0 ? void 0 : _a.isLocked);
|
|
130
133
|
}
|
|
131
134
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
132
135
|
async rename(oldPath, newPath) {
|
package/dist/mixins/shared.d.ts
CHANGED
|
@@ -6,10 +6,22 @@ import type { FileSystem } from '../filesystem.js';
|
|
|
6
6
|
*/
|
|
7
7
|
export type Mixin<TBase extends typeof FileSystem, TMixin> = (abstract new (...args: any[]) => TMixin) & TBase;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* @internal @hidden
|
|
10
|
+
* Note this include `existsSync`, even though it is a concrete method.
|
|
11
|
+
*/
|
|
12
|
+
export type _SyncFSKeys = Exclude<Extract<keyof FileSystem, `${string}Sync`>, '_disableSync'>;
|
|
13
|
+
/**
|
|
14
|
+
* @internal @hidden
|
|
15
|
+
* Note this include `exists`, even though it is a concrete method.
|
|
16
|
+
*/
|
|
17
|
+
export type _AsyncFSKeys = {
|
|
18
|
+
[K in _SyncFSKeys]: K extends `${infer T}Sync` ? T : never;
|
|
19
|
+
}[_SyncFSKeys];
|
|
20
|
+
/**
|
|
21
|
+
* Asynchronous `FileSystem` methods. This is a convenience type for all of the async operations.
|
|
10
22
|
* @internal
|
|
11
23
|
*/
|
|
12
|
-
export type AsyncFSMethods =
|
|
24
|
+
export type AsyncFSMethods = Pick<FileSystem, _AsyncFSKeys>;
|
|
13
25
|
/**
|
|
14
26
|
* Concrete `FileSystem`. This is a convenience type.
|
|
15
27
|
* @internal
|
package/dist/polyfills.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
var _a, _b, _c;
|
|
1
2
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
2
|
-
Promise.withResolvers
|
|
3
|
+
(_a = Promise.withResolvers) !== null && _a !== void 0 ? _a : (Promise.withResolvers = function () {
|
|
3
4
|
let _resolve,
|
|
4
5
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
6
|
_reject;
|
|
@@ -10,7 +11,7 @@ Promise.withResolvers ?? (Promise.withResolvers = function () {
|
|
|
10
11
|
return { promise, resolve: _resolve, reject: _reject };
|
|
11
12
|
});
|
|
12
13
|
// @ts-expect-error 2540
|
|
13
|
-
Symbol['dispose']
|
|
14
|
+
(_b = Symbol['dispose']) !== null && _b !== void 0 ? _b : (Symbol['dispose'] = Symbol('Symbol.dispose'));
|
|
14
15
|
// @ts-expect-error 2540
|
|
15
|
-
Symbol['asyncDispose']
|
|
16
|
+
(_c = Symbol['asyncDispose']) !== null && _c !== void 0 ? _c : (Symbol['asyncDispose'] = Symbol('Symbol.asyncDispose'));
|
|
16
17
|
export {};
|
package/dist/stats.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { credentials } from './credentials.js';
|
|
2
2
|
import { R_OK, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR, size_max, W_OK, X_OK, } from './emulation/constants.js';
|
|
3
|
+
const n1000 = BigInt(1000);
|
|
3
4
|
/**
|
|
4
5
|
* Provides information about a particular entry in the file system.
|
|
5
6
|
* Common code used by both Stats and BigIntStats.
|
|
@@ -68,15 +69,15 @@ export class StatsCommon {
|
|
|
68
69
|
*/
|
|
69
70
|
this.gid = this._convert(0);
|
|
70
71
|
const now = Date.now();
|
|
71
|
-
this.atimeMs = this._convert(atimeMs
|
|
72
|
-
this.mtimeMs = this._convert(mtimeMs
|
|
73
|
-
this.ctimeMs = this._convert(ctimeMs
|
|
74
|
-
this.birthtimeMs = this._convert(birthtimeMs
|
|
75
|
-
this.uid = this._convert(uid
|
|
76
|
-
this.gid = this._convert(gid
|
|
77
|
-
this.size = this._convert(size
|
|
78
|
-
this.ino = this._convert(ino
|
|
79
|
-
this.mode = this._convert(mode
|
|
72
|
+
this.atimeMs = this._convert(atimeMs !== null && atimeMs !== void 0 ? atimeMs : now);
|
|
73
|
+
this.mtimeMs = this._convert(mtimeMs !== null && mtimeMs !== void 0 ? mtimeMs : now);
|
|
74
|
+
this.ctimeMs = this._convert(ctimeMs !== null && ctimeMs !== void 0 ? ctimeMs : now);
|
|
75
|
+
this.birthtimeMs = this._convert(birthtimeMs !== null && birthtimeMs !== void 0 ? birthtimeMs : now);
|
|
76
|
+
this.uid = this._convert(uid !== null && uid !== void 0 ? uid : 0);
|
|
77
|
+
this.gid = this._convert(gid !== null && gid !== void 0 ? gid : 0);
|
|
78
|
+
this.size = this._convert(size !== null && size !== void 0 ? size : 0);
|
|
79
|
+
this.ino = this._convert(ino !== null && ino !== void 0 ? ino : 0);
|
|
80
|
+
this.mode = this._convert(mode !== null && mode !== void 0 ? mode : 0o644 & S_IFREG);
|
|
80
81
|
if ((this.mode & S_IFMT) == 0) {
|
|
81
82
|
this.mode = (this.mode | this._convert(S_IFREG));
|
|
82
83
|
}
|
|
@@ -109,7 +110,7 @@ export class StatsCommon {
|
|
|
109
110
|
* @internal
|
|
110
111
|
*/
|
|
111
112
|
hasAccess(mode, context) {
|
|
112
|
-
const creds = context
|
|
113
|
+
const creds = (context === null || context === void 0 ? void 0 : context.credentials) || credentials;
|
|
113
114
|
if (this.isSymbolicLink() || creds.euid === 0 || creds.egid === 0)
|
|
114
115
|
return true;
|
|
115
116
|
let perm = 0;
|
|
@@ -167,16 +168,16 @@ export class StatsCommon {
|
|
|
167
168
|
}
|
|
168
169
|
}
|
|
169
170
|
get atimeNs() {
|
|
170
|
-
return BigInt(this.atimeMs) *
|
|
171
|
+
return BigInt(this.atimeMs) * n1000;
|
|
171
172
|
}
|
|
172
173
|
get mtimeNs() {
|
|
173
|
-
return BigInt(this.mtimeMs) *
|
|
174
|
+
return BigInt(this.mtimeMs) * n1000;
|
|
174
175
|
}
|
|
175
176
|
get ctimeNs() {
|
|
176
|
-
return BigInt(this.ctimeMs) *
|
|
177
|
+
return BigInt(this.ctimeMs) * n1000;
|
|
177
178
|
}
|
|
178
179
|
get birthtimeNs() {
|
|
179
|
-
return BigInt(this.birthtimeMs) *
|
|
180
|
+
return BigInt(this.birthtimeMs) * n1000;
|
|
180
181
|
}
|
|
181
182
|
}
|
|
182
183
|
/**
|
|
@@ -253,15 +254,15 @@ export class StatsFs {
|
|
|
253
254
|
export class BigIntStatsFs {
|
|
254
255
|
constructor() {
|
|
255
256
|
/** Type of file system. */
|
|
256
|
-
this.type =
|
|
257
|
+
this.type = BigInt('0x7a656e6673');
|
|
257
258
|
/** Optimal transfer block size. */
|
|
258
|
-
this.bsize =
|
|
259
|
+
this.bsize = BigInt(4096);
|
|
259
260
|
/** Total data blocks in file system. */
|
|
260
|
-
this.blocks =
|
|
261
|
+
this.blocks = BigInt(0);
|
|
261
262
|
/** Free blocks in file system. */
|
|
262
|
-
this.bfree =
|
|
263
|
+
this.bfree = BigInt(0);
|
|
263
264
|
/** Available blocks for unprivileged users */
|
|
264
|
-
this.bavail =
|
|
265
|
+
this.bavail = BigInt(0);
|
|
265
266
|
/** Total file nodes in file system. */
|
|
266
267
|
this.files = BigInt(size_max);
|
|
267
268
|
/** Free file nodes in file system. */
|
package/dist/utils.js
CHANGED
|
@@ -78,7 +78,7 @@ export function normalizeMode(mode, def) {
|
|
|
78
78
|
if (typeof def == 'number') {
|
|
79
79
|
return def;
|
|
80
80
|
}
|
|
81
|
-
throw new ErrnoError(Errno.EINVAL, 'Invalid mode: ' + mode
|
|
81
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid mode: ' + (mode === null || mode === void 0 ? void 0 : mode.toString()));
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
84
|
* Normalizes a time
|
|
@@ -120,15 +120,15 @@ export function normalizePath(p) {
|
|
|
120
120
|
export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
|
|
121
121
|
if (typeof options != 'object' || options === null) {
|
|
122
122
|
return {
|
|
123
|
-
encoding: typeof options == 'string' ? options : encoding
|
|
123
|
+
encoding: typeof options == 'string' ? options : encoding !== null && encoding !== void 0 ? encoding : null,
|
|
124
124
|
flag,
|
|
125
125
|
mode,
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
return {
|
|
129
|
-
encoding: typeof options
|
|
130
|
-
flag: typeof options
|
|
131
|
-
mode: normalizeMode('mode' in options ? options
|
|
129
|
+
encoding: typeof (options === null || options === void 0 ? void 0 : options.encoding) == 'string' ? options.encoding : encoding !== null && encoding !== void 0 ? encoding : null,
|
|
130
|
+
flag: typeof (options === null || options === void 0 ? void 0 : options.flag) == 'string' ? options.flag : flag,
|
|
131
|
+
mode: normalizeMode('mode' in options ? options === null || options === void 0 ? void 0 : options.mode : null, mode),
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
/**
|
package/eslint.shared.js
CHANGED
|
@@ -37,10 +37,10 @@ export default [
|
|
|
37
37
|
'@typescript-eslint/consistent-type-imports': 'warn',
|
|
38
38
|
'@typescript-eslint/no-unnecessary-type-assertion': 'warn',
|
|
39
39
|
'@typescript-eslint/require-await': 'warn',
|
|
40
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
41
|
+
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
42
|
+
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
40
43
|
'@typescript-eslint/no-unsafe-return': 'warn',
|
|
41
|
-
'@typescript-eslint/no-unsafe-assignment': 'warn',
|
|
42
|
-
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
|
43
|
-
'@typescript-eslint/no-unsafe-argument': 'warn',
|
|
44
44
|
'@typescript-eslint/no-redundant-type-constituents': 'warn',
|
|
45
45
|
'@typescript-eslint/no-unsafe-call': 'warn',
|
|
46
46
|
'@typescript-eslint/restrict-plus-operands': 'off',
|
|
@@ -51,9 +51,6 @@ export default [
|
|
|
51
51
|
name: 'Tests overrides',
|
|
52
52
|
files: ['tests/**/*.ts'],
|
|
53
53
|
rules: {
|
|
54
|
-
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
55
|
-
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
56
|
-
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
57
54
|
'@typescript-eslint/no-floating-promises': 'off',
|
|
58
55
|
'@typescript-eslint/no-explicit-any': 'off',
|
|
59
56
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenfs/core",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.11",
|
|
4
4
|
"description": "A filesystem, anywhere",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -73,12 +73,12 @@
|
|
|
73
73
|
"utilium": "^1.1.1"
|
|
74
74
|
},
|
|
75
75
|
"optionalDependencies": {
|
|
76
|
-
"minimatch": "^9.0.3"
|
|
76
|
+
"minimatch": "^9.0.3",
|
|
77
|
+
"c8": "^10.1.2"
|
|
77
78
|
},
|
|
78
79
|
"devDependencies": {
|
|
79
80
|
"@eslint/js": "^9.8.0",
|
|
80
81
|
"@types/eslint__js": "^8.42.3",
|
|
81
|
-
"c8": "^10.1.2",
|
|
82
82
|
"eslint": "^9.15.0",
|
|
83
83
|
"globals": "^15.9.0",
|
|
84
84
|
"lint-staged": "^15.2.7",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { suite, test } from 'node:test';
|
|
3
|
+
import { configure } from '../../dist/config.js';
|
|
4
|
+
import * as fs from '../../dist/emulation/index.js';
|
|
5
|
+
import { InMemoryStore, StoreFS } from '../../dist/index.js';
|
|
6
|
+
import { Async } from '../../dist/mixins/async.js';
|
|
7
|
+
|
|
8
|
+
class ExampleAsyncFS extends Async(StoreFS) {
|
|
9
|
+
_sync = new StoreFS(new InMemoryStore('cache'));
|
|
10
|
+
|
|
11
|
+
public constructor() {
|
|
12
|
+
super(new InMemoryStore('test'));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const asyncFS = new ExampleAsyncFS();
|
|
17
|
+
|
|
18
|
+
await configure({ mounts: { '/': asyncFS } });
|
|
19
|
+
|
|
20
|
+
suite('Async Mixin', () => {
|
|
21
|
+
test('async -> cache syncing', async () => {
|
|
22
|
+
await fs.promises.writeFile('test', 'test');
|
|
23
|
+
assert.strictEqual(fs.readFileSync('test', 'utf8'), 'test');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('cache -> async syncing', async () => {
|
|
27
|
+
fs.unlinkSync('test');
|
|
28
|
+
await asyncFS.queueDone();
|
|
29
|
+
assert(!(await fs.promises.exists('test')));
|
|
30
|
+
});
|
|
31
|
+
});
|