@zenfs/core 2.0.0 → 2.1.0
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 +6 -5
- package/dist/backends/cow.d.ts +2 -2
- package/dist/backends/cow.js +39 -58
- package/dist/backends/fetch.js +27 -29
- package/dist/backends/passthrough.d.ts +2 -3
- package/dist/backends/passthrough.js +84 -199
- package/dist/backends/port.d.ts +16 -3
- package/dist/backends/port.js +61 -30
- package/dist/backends/single_buffer.d.ts +52 -46
- package/dist/backends/single_buffer.js +462 -219
- package/dist/backends/store/fs.d.ts +16 -10
- package/dist/backends/store/fs.js +227 -242
- package/dist/backends/store/store.d.ts +3 -3
- package/dist/backends/store/store.js +11 -10
- package/dist/config.d.ts +2 -2
- package/dist/config.js +10 -11
- package/dist/internal/devices.d.ts +2 -2
- package/dist/internal/devices.js +39 -49
- package/dist/internal/error.d.ts +9 -204
- package/dist/internal/error.js +19 -288
- package/dist/internal/file_index.d.ts +1 -1
- package/dist/internal/file_index.js +9 -9
- package/dist/internal/filesystem.d.ts +23 -8
- package/dist/internal/index.d.ts +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index_fs.d.ts +2 -2
- package/dist/internal/index_fs.js +19 -19
- package/dist/internal/inode.d.ts +81 -103
- package/dist/internal/inode.js +336 -195
- package/dist/mixins/async.js +32 -28
- package/dist/mixins/mutexed.d.ts +4 -4
- package/dist/mixins/mutexed.js +39 -39
- package/dist/mixins/readonly.d.ts +2 -2
- package/dist/mixins/readonly.js +20 -20
- package/dist/mixins/sync.js +2 -2
- package/dist/polyfills.js +1 -1
- package/dist/readline.js +1 -1
- package/dist/utils.d.ts +8 -5
- package/dist/utils.js +14 -17
- package/dist/vfs/acl.d.ts +8 -8
- package/dist/vfs/acl.js +66 -47
- package/dist/vfs/async.d.ts +2 -2
- package/dist/vfs/async.js +6 -8
- package/dist/vfs/dir.d.ts +1 -1
- package/dist/vfs/dir.js +3 -4
- package/dist/vfs/file.js +33 -24
- package/dist/vfs/flags.js +3 -3
- package/dist/vfs/ioctl.d.ts +8 -7
- package/dist/vfs/ioctl.js +132 -27
- package/dist/vfs/promises.d.ts +3 -3
- package/dist/vfs/promises.js +200 -235
- package/dist/vfs/shared.d.ts +1 -12
- package/dist/vfs/shared.js +7 -35
- package/dist/vfs/streams.js +9 -9
- package/dist/vfs/sync.d.ts +1 -2
- package/dist/vfs/sync.js +158 -170
- package/dist/vfs/watchers.js +8 -8
- package/dist/vfs/xattr.js +89 -106
- package/package.json +4 -2
- package/scripts/test.js +2 -2
- package/tests/assignment.ts +1 -1
- package/tests/backend/port.test.ts +4 -4
- package/tests/backend/single-buffer.test.ts +39 -10
- package/tests/backend/single-buffer.worker.js +30 -0
- package/tests/common/context.test.ts +2 -2
- package/tests/common/mutex.test.ts +9 -9
- package/tests/fetch/fetch.ts +1 -1
- package/tests/fs/append.test.ts +4 -4
- package/tests/fs/directory.test.ts +25 -25
- package/tests/fs/errors.test.ts +15 -19
- package/tests/fs/links.test.ts +3 -2
- package/tests/fs/open.test.ts +4 -21
- package/tests/fs/permissions.test.ts +8 -13
- package/tests/fs/read.test.ts +10 -9
- package/tests/fs/readFile.test.ts +8 -24
- package/tests/fs/rename.test.ts +4 -9
- package/tests/fs/stat.test.ts +2 -2
- package/tests/fs/times.test.ts +6 -6
- package/tests/fs/truncate.test.ts +8 -36
- package/tests/fs/watch.test.ts +10 -10
- package/tests/fs/write.test.ts +77 -13
- package/tests/fs/xattr.test.ts +7 -7
- package/tests/logs.js +2 -2
- package/tests/setup/port.ts +6 -0
- package/dist/internal/log.d.ts +0 -139
- package/dist/internal/log.js +0 -219
- package/tests/fs/writeFile.test.ts +0 -70
package/dist/vfs/promises.js
CHANGED
|
@@ -51,20 +51,20 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
53
|
import { Buffer } from 'buffer';
|
|
54
|
-
import {
|
|
54
|
+
import { Exception, rethrow, setUVMessage, UV } from 'kerium';
|
|
55
|
+
import { decodeUTF8, pick } from 'utilium';
|
|
55
56
|
import { defaultContext } from '../internal/contexts.js';
|
|
56
|
-
import { Errno, ErrnoError } from '../internal/error.js';
|
|
57
57
|
import { hasAccess, InodeFlags, isBlockDevice, isCharacterDevice, isDirectory, isSymbolicLink } from '../internal/inode.js';
|
|
58
58
|
import { dirname, join, parse, resolve } from '../path.js';
|
|
59
59
|
import '../polyfills.js';
|
|
60
60
|
import { createInterface } from '../readline.js';
|
|
61
|
-
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
61
|
+
import { __assertType, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
62
62
|
import { checkAccess } from './config.js';
|
|
63
63
|
import * as constants from './constants.js';
|
|
64
64
|
import { Dir, Dirent } from './dir.js';
|
|
65
65
|
import { deleteFD, fromFD, SyncHandle, toFD } from './file.js';
|
|
66
66
|
import * as flags from './flags.js';
|
|
67
|
-
import { _statfs,
|
|
67
|
+
import { _statfs, resolveMount } from './shared.js';
|
|
68
68
|
import { _chown, BigIntStats, Stats } from './stats.js';
|
|
69
69
|
import { ReadStream, WriteStream } from './streams.js';
|
|
70
70
|
import { emitChange, FSWatcher } from './watchers.js';
|
|
@@ -114,7 +114,7 @@ export class FileHandle {
|
|
|
114
114
|
*/
|
|
115
115
|
async chown(uid, gid) {
|
|
116
116
|
if (this.closed)
|
|
117
|
-
throw
|
|
117
|
+
throw UV('EBADF', 'chown', this.path);
|
|
118
118
|
this.dirty = true;
|
|
119
119
|
_chown(this.inode, uid, gid);
|
|
120
120
|
if (this._isSync)
|
|
@@ -128,9 +128,9 @@ export class FileHandle {
|
|
|
128
128
|
async chmod(mode) {
|
|
129
129
|
const numMode = normalizeMode(mode, -1);
|
|
130
130
|
if (numMode < 0)
|
|
131
|
-
throw
|
|
131
|
+
throw UV('EINVAL', 'chmod', this.path);
|
|
132
132
|
if (this.closed)
|
|
133
|
-
throw
|
|
133
|
+
throw UV('EBADF', 'chmod', this.path);
|
|
134
134
|
this.dirty = true;
|
|
135
135
|
this.inode.mode = (this.inode.mode & (numMode > constants.S_IFMT ? ~constants.S_IFMT : constants.S_IFMT)) | numMode;
|
|
136
136
|
if (this._isSync || numMode > constants.S_IFMT)
|
|
@@ -148,7 +148,7 @@ export class FileHandle {
|
|
|
148
148
|
*/
|
|
149
149
|
async sync() {
|
|
150
150
|
if (this.closed)
|
|
151
|
-
throw
|
|
151
|
+
throw UV('EBADF', 'sync', this.path);
|
|
152
152
|
if (!this.dirty)
|
|
153
153
|
return;
|
|
154
154
|
if (!this.fs.attributes.has('no_write'))
|
|
@@ -161,13 +161,18 @@ export class FileHandle {
|
|
|
161
161
|
*/
|
|
162
162
|
async truncate(length = 0) {
|
|
163
163
|
if (this.closed)
|
|
164
|
-
throw
|
|
164
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
165
165
|
if (length < 0)
|
|
166
|
-
throw
|
|
166
|
+
throw UV('EINVAL', 'truncate', this.path);
|
|
167
|
+
if (!(this.flag & constants.O_WRONLY || this.flag & constants.O_RDWR))
|
|
168
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
169
|
+
if (this.fs.attributes.has('readonly'))
|
|
170
|
+
throw UV('EROFS', 'truncate', this.path);
|
|
171
|
+
if (this.inode.flags & InodeFlags.Immutable)
|
|
172
|
+
throw UV('EPERM', 'truncate', this.path);
|
|
167
173
|
this.dirty = true;
|
|
168
|
-
if (!(this.flag & constants.O_WRONLY || this.flag & constants.O_RDWR))
|
|
169
|
-
throw
|
|
170
|
-
}
|
|
174
|
+
if (!(this.flag & constants.O_WRONLY || this.flag & constants.O_RDWR))
|
|
175
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
171
176
|
this.inode.mtimeMs = Date.now();
|
|
172
177
|
this.inode.size = length;
|
|
173
178
|
if (this._isSync)
|
|
@@ -181,7 +186,7 @@ export class FileHandle {
|
|
|
181
186
|
*/
|
|
182
187
|
async utimes(atime, mtime) {
|
|
183
188
|
if (this.closed)
|
|
184
|
-
throw
|
|
189
|
+
throw UV('EBADF', 'utimes', this.path);
|
|
185
190
|
this.dirty = true;
|
|
186
191
|
this.inode.atimeMs = normalizeTime(atime);
|
|
187
192
|
this.inode.mtimeMs = normalizeTime(mtime);
|
|
@@ -201,12 +206,8 @@ export class FileHandle {
|
|
|
201
206
|
async appendFile(data, _options = {}) {
|
|
202
207
|
const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
|
|
203
208
|
const flag = flags.parse(options.flag);
|
|
204
|
-
if (!(flag & constants.O_APPEND))
|
|
205
|
-
throw
|
|
206
|
-
}
|
|
207
|
-
if (typeof data != 'string' && !options.encoding) {
|
|
208
|
-
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
209
|
-
}
|
|
209
|
+
if (!(flag & constants.O_APPEND))
|
|
210
|
+
throw UV('EBADF', 'write', this.path);
|
|
210
211
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
211
212
|
await this._write(encodedData, 0, encodedData.length);
|
|
212
213
|
this._emitChange();
|
|
@@ -221,10 +222,10 @@ export class FileHandle {
|
|
|
221
222
|
*/
|
|
222
223
|
async _read(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
223
224
|
if (this.closed)
|
|
224
|
-
throw
|
|
225
|
+
throw UV('EBADF', 'read', this.path);
|
|
225
226
|
if (this.flag & constants.O_WRONLY)
|
|
226
|
-
throw
|
|
227
|
-
if (!(this.inode.flags & InodeFlags.NoAtime)) {
|
|
227
|
+
throw UV('EBADF', 'read', this.path);
|
|
228
|
+
if (!(this.inode.flags & InodeFlags.NoAtime) && !this.fs.attributes.has('no_atime')) {
|
|
228
229
|
this.dirty = true;
|
|
229
230
|
this.inode.atimeMs = Date.now();
|
|
230
231
|
}
|
|
@@ -259,11 +260,11 @@ export class FileHandle {
|
|
|
259
260
|
async readFile(_options) {
|
|
260
261
|
const options = normalizeOptions(_options, null, 'r', 0o444);
|
|
261
262
|
const flag = flags.parse(options.flag);
|
|
262
|
-
if (flag & constants.O_WRONLY)
|
|
263
|
-
throw
|
|
264
|
-
}
|
|
263
|
+
if (flag & constants.O_WRONLY)
|
|
264
|
+
throw UV('EBADF', 'read', this.path);
|
|
265
265
|
const { size } = await this.stat();
|
|
266
|
-
const
|
|
266
|
+
const data = new Uint8Array(size);
|
|
267
|
+
await this._read(data, 0, size, 0);
|
|
267
268
|
const buffer = Buffer.from(data);
|
|
268
269
|
return options.encoding ? buffer.toString(options.encoding) : buffer;
|
|
269
270
|
}
|
|
@@ -273,7 +274,7 @@ export class FileHandle {
|
|
|
273
274
|
*/
|
|
274
275
|
readableWebStream(options = {}) {
|
|
275
276
|
if (this.closed)
|
|
276
|
-
throw
|
|
277
|
+
throw UV('EBADF', 'readableWebStream', this.path);
|
|
277
278
|
return this.fs.streamRead(this.internalPath, options);
|
|
278
279
|
}
|
|
279
280
|
/**
|
|
@@ -285,9 +286,9 @@ export class FileHandle {
|
|
|
285
286
|
*/
|
|
286
287
|
writableWebStream(options = {}) {
|
|
287
288
|
if (this.closed)
|
|
288
|
-
throw
|
|
289
|
+
throw UV('EBADF', 'writableWebStream', this.path);
|
|
289
290
|
if (this.inode.flags & InodeFlags.Immutable)
|
|
290
|
-
throw
|
|
291
|
+
throw UV('EPERM', 'writableWebStream', this.path);
|
|
291
292
|
return this.fs.streamWrite(this.internalPath, options);
|
|
292
293
|
}
|
|
293
294
|
/**
|
|
@@ -297,7 +298,7 @@ export class FileHandle {
|
|
|
297
298
|
*/
|
|
298
299
|
readLines(options) {
|
|
299
300
|
if (this.closed || this.flag & constants.O_WRONLY)
|
|
300
|
-
throw
|
|
301
|
+
throw UV('EBADF', 'read', this.path);
|
|
301
302
|
return createInterface({ input: this.createReadStream(options), crlfDelay: Infinity });
|
|
302
303
|
}
|
|
303
304
|
[Symbol.asyncDispose]() {
|
|
@@ -305,10 +306,9 @@ export class FileHandle {
|
|
|
305
306
|
}
|
|
306
307
|
async stat(opts) {
|
|
307
308
|
if (this.closed)
|
|
308
|
-
throw
|
|
309
|
-
if (checkAccess && !hasAccess(this.context, this.inode, constants.R_OK))
|
|
310
|
-
throw
|
|
311
|
-
}
|
|
309
|
+
throw UV('EBADF', 'stat', this.path);
|
|
310
|
+
if (checkAccess && !hasAccess(this.context, this.inode, constants.R_OK))
|
|
311
|
+
throw UV('EACCES', 'stat', this.path);
|
|
312
312
|
return (opts === null || opts === void 0 ? void 0 : opts.bigint) ? new BigIntStats(this.inode) : new Stats(this.inode);
|
|
313
313
|
}
|
|
314
314
|
/**
|
|
@@ -321,11 +321,13 @@ export class FileHandle {
|
|
|
321
321
|
*/
|
|
322
322
|
async _write(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
323
323
|
if (this.closed)
|
|
324
|
-
throw
|
|
324
|
+
throw UV('EBADF', 'write', this.path);
|
|
325
325
|
if (this.inode.flags & InodeFlags.Immutable)
|
|
326
|
-
throw
|
|
326
|
+
throw UV('EPERM', 'write', this.path);
|
|
327
327
|
if (!(this.flag & constants.O_WRONLY || this.flag & constants.O_RDWR))
|
|
328
|
-
throw
|
|
328
|
+
throw UV('EBADF', 'write', this.path);
|
|
329
|
+
if (this.fs.attributes.has('readonly'))
|
|
330
|
+
throw UV('EROFS', 'write', this.path);
|
|
329
331
|
this.dirty = true;
|
|
330
332
|
const end = position + length;
|
|
331
333
|
const slice = buffer.subarray(offset, offset + length);
|
|
@@ -382,12 +384,8 @@ export class FileHandle {
|
|
|
382
384
|
async writeFile(data, _options = {}) {
|
|
383
385
|
const options = normalizeOptions(_options, 'utf8', 'w', 0o644);
|
|
384
386
|
const flag = flags.parse(options.flag);
|
|
385
|
-
if (!(flag & constants.O_WRONLY || flag & constants.O_RDWR))
|
|
386
|
-
throw
|
|
387
|
-
}
|
|
388
|
-
if (typeof data != 'string' && !options.encoding) {
|
|
389
|
-
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
390
|
-
}
|
|
387
|
+
if (!(flag & constants.O_WRONLY || flag & constants.O_RDWR))
|
|
388
|
+
throw UV('EBADF', 'writeFile', this.path);
|
|
391
389
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
392
390
|
await this._write(encodedData, 0, encodedData.length, 0);
|
|
393
391
|
this._emitChange();
|
|
@@ -397,7 +395,7 @@ export class FileHandle {
|
|
|
397
395
|
*/
|
|
398
396
|
async close() {
|
|
399
397
|
if (this.closed)
|
|
400
|
-
throw
|
|
398
|
+
throw UV('EBADF', 'close', this.path);
|
|
401
399
|
await this.sync();
|
|
402
400
|
this.dispose();
|
|
403
401
|
deleteFD(this.context, this.fd);
|
|
@@ -407,9 +405,9 @@ export class FileHandle {
|
|
|
407
405
|
*/
|
|
408
406
|
dispose(force) {
|
|
409
407
|
if (this.closed)
|
|
410
|
-
throw
|
|
408
|
+
throw UV('EBADF', 'close', this.path);
|
|
411
409
|
if (this.dirty && !force)
|
|
412
|
-
throw
|
|
410
|
+
throw UV('EBUSY', 'close', this.path);
|
|
413
411
|
this.closed = true;
|
|
414
412
|
}
|
|
415
413
|
/**
|
|
@@ -448,7 +446,7 @@ export class FileHandle {
|
|
|
448
446
|
*/
|
|
449
447
|
createReadStream(options = {}) {
|
|
450
448
|
if (this.closed || this.flag & constants.O_WRONLY)
|
|
451
|
-
throw
|
|
449
|
+
throw UV('EBADF', 'createReadStream', this.path);
|
|
452
450
|
return new ReadStream(options, this);
|
|
453
451
|
}
|
|
454
452
|
/**
|
|
@@ -457,34 +455,43 @@ export class FileHandle {
|
|
|
457
455
|
*/
|
|
458
456
|
createWriteStream(options = {}) {
|
|
459
457
|
if (this.closed)
|
|
460
|
-
throw
|
|
458
|
+
throw UV('EBADF', 'createWriteStream', this.path);
|
|
461
459
|
if (this.inode.flags & InodeFlags.Immutable)
|
|
462
|
-
throw
|
|
460
|
+
throw UV('EPERM', 'createWriteStream', this.path);
|
|
461
|
+
if (this.fs.attributes.has('readonly'))
|
|
462
|
+
throw UV('EROFS', 'createWriteStream', this.path);
|
|
463
463
|
return new WriteStream(options, this);
|
|
464
464
|
}
|
|
465
465
|
}
|
|
466
466
|
export async function rename(oldPath, newPath) {
|
|
467
467
|
oldPath = normalizePath(oldPath);
|
|
468
|
+
__assertType(oldPath);
|
|
468
469
|
newPath = normalizePath(newPath);
|
|
470
|
+
__assertType(newPath);
|
|
471
|
+
const $ex = { syscall: 'rename', path: oldPath, dest: newPath };
|
|
469
472
|
const src = resolveMount(oldPath, this);
|
|
470
473
|
const dst = resolveMount(newPath, this);
|
|
471
|
-
if (
|
|
472
|
-
throw
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
throw
|
|
487
|
-
|
|
474
|
+
if (src.fs !== dst.fs)
|
|
475
|
+
throw UV('EXDEV', $ex);
|
|
476
|
+
if (dst.path.startsWith(src.path + '/'))
|
|
477
|
+
throw UV('EBUSY', $ex);
|
|
478
|
+
const parent = (await stat.call(this, dirname(oldPath)).catch(rethrow($ex)));
|
|
479
|
+
const stats = (await stat.call(this, oldPath).catch(rethrow($ex)));
|
|
480
|
+
const newParent = (await stat.call(this, dirname(newPath)).catch(rethrow($ex)));
|
|
481
|
+
const newStats = (await stat.call(this, newPath).catch((e) => {
|
|
482
|
+
if (e.code == 'ENOENT')
|
|
483
|
+
return null;
|
|
484
|
+
throw setUVMessage(Object.assign(e, $ex));
|
|
485
|
+
}));
|
|
486
|
+
if (checkAccess && (!parent.hasAccess(constants.R_OK, this) || !newParent.hasAccess(constants.W_OK, this)))
|
|
487
|
+
throw UV('EACCES', $ex);
|
|
488
|
+
if (newStats && !isDirectory(stats) && isDirectory(newStats))
|
|
489
|
+
throw UV('EISDIR', $ex);
|
|
490
|
+
if (newStats && isDirectory(stats) && !isDirectory(newStats))
|
|
491
|
+
throw UV('ENOTDIR', $ex);
|
|
492
|
+
await src.fs.rename(src.path, dst.path).catch(rethrow($ex));
|
|
493
|
+
emitChange(this, 'rename', oldPath);
|
|
494
|
+
emitChange(this, 'change', newPath);
|
|
488
495
|
}
|
|
489
496
|
rename;
|
|
490
497
|
/**
|
|
@@ -496,7 +503,7 @@ export async function exists(path) {
|
|
|
496
503
|
return await fs.exists(resolved);
|
|
497
504
|
}
|
|
498
505
|
catch (e) {
|
|
499
|
-
if (e instanceof
|
|
506
|
+
if (e instanceof Exception && e.code == 'ENOENT') {
|
|
500
507
|
return false;
|
|
501
508
|
}
|
|
502
509
|
throw e;
|
|
@@ -505,34 +512,23 @@ export async function exists(path) {
|
|
|
505
512
|
export async function stat(path, options) {
|
|
506
513
|
path = normalizePath(path);
|
|
507
514
|
const { fs, path: resolved } = resolveMount(await realpath.call(this, path), this);
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
|
|
514
|
-
}
|
|
515
|
-
catch (e) {
|
|
516
|
-
throw fixError(e, { [resolved]: path });
|
|
517
|
-
}
|
|
515
|
+
const $ex = { syscall: 'stat', path };
|
|
516
|
+
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
517
|
+
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
518
|
+
throw UV('EACCES', $ex);
|
|
519
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
|
|
518
520
|
}
|
|
519
521
|
stat;
|
|
520
522
|
export async function lstat(path, options) {
|
|
521
523
|
path = normalizePath(path);
|
|
522
524
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
|
|
529
|
-
}
|
|
530
|
-
catch (e) {
|
|
531
|
-
throw fixError(e, { [resolved]: path });
|
|
532
|
-
}
|
|
525
|
+
const $ex = { syscall: 'lstat', path };
|
|
526
|
+
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
527
|
+
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
528
|
+
throw UV('EACCES', $ex);
|
|
529
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
|
|
533
530
|
}
|
|
534
531
|
lstat;
|
|
535
|
-
// FILE-ONLY METHODS
|
|
536
532
|
export async function truncate(path, len = 0) {
|
|
537
533
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
538
534
|
try {
|
|
@@ -553,16 +549,12 @@ truncate;
|
|
|
553
549
|
export async function unlink(path) {
|
|
554
550
|
path = normalizePath(path);
|
|
555
551
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
}
|
|
563
|
-
catch (e) {
|
|
564
|
-
throw fixError(e, { [resolved]: path });
|
|
565
|
-
}
|
|
552
|
+
const $ex = { syscall: 'unlink', path };
|
|
553
|
+
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
554
|
+
if (checkAccess && !hasAccess(this, stats, constants.W_OK))
|
|
555
|
+
throw UV('EACCES', $ex);
|
|
556
|
+
await fs.unlink(resolved).catch(rethrow($ex));
|
|
557
|
+
emitChange(this, 'rename', path.toString());
|
|
566
558
|
}
|
|
567
559
|
unlink;
|
|
568
560
|
/**
|
|
@@ -573,19 +565,19 @@ async function _open($, path, opt) {
|
|
|
573
565
|
var _a;
|
|
574
566
|
path = normalizePath(path);
|
|
575
567
|
const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
|
|
576
|
-
const
|
|
568
|
+
const $ex = { syscall: 'open', path };
|
|
569
|
+
const { fs, path: resolved, stats } = await _resolve($, path.toString(), opt.preserveSymlinks);
|
|
577
570
|
if (!stats) {
|
|
578
|
-
if (!(flag & constants.O_CREAT))
|
|
579
|
-
throw
|
|
580
|
-
}
|
|
571
|
+
if (!(flag & constants.O_CREAT))
|
|
572
|
+
throw UV('ENOENT', $ex);
|
|
581
573
|
// Create the file
|
|
582
574
|
const parentStats = await fs.stat(dirname(resolved));
|
|
583
|
-
if (checkAccess && !hasAccess($, parentStats, constants.W_OK))
|
|
584
|
-
throw
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
575
|
+
if (checkAccess && !hasAccess($, parentStats, constants.W_OK))
|
|
576
|
+
throw UV('EACCES', 'open', dirname(path));
|
|
577
|
+
if (!isDirectory(parentStats))
|
|
578
|
+
throw UV('ENOTDIR', 'open', dirname(path));
|
|
579
|
+
if (!opt.allowDirectory && mode & constants.S_IFDIR)
|
|
580
|
+
throw UV('EISDIR', 'open', path);
|
|
589
581
|
const { euid: uid, egid: gid } = (_a = $ === null || $ === void 0 ? void 0 : $.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
|
|
590
582
|
const inode = await fs.createFile(resolved, {
|
|
591
583
|
mode,
|
|
@@ -594,18 +586,13 @@ async function _open($, path, opt) {
|
|
|
594
586
|
});
|
|
595
587
|
return new FileHandle($, toFD(new SyncHandle($, path, fs, resolved, flag, inode)));
|
|
596
588
|
}
|
|
597
|
-
if (checkAccess && !hasAccess($, stats, flags.toMode(flag)))
|
|
598
|
-
throw
|
|
599
|
-
}
|
|
589
|
+
if (checkAccess && !hasAccess($, stats, flags.toMode(flag)))
|
|
590
|
+
throw UV('EACCES', $ex);
|
|
600
591
|
if (flag & constants.O_EXCL)
|
|
601
|
-
throw
|
|
592
|
+
throw UV('EEXIST', $ex);
|
|
602
593
|
const handle = new FileHandle($, toFD(new SyncHandle($, path, fs, resolved, flag, stats)));
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
re-created it. However, this created a race condition if another
|
|
606
|
-
asynchronous request was trying to read the file, as the file
|
|
607
|
-
would not exist for a small period of time.
|
|
608
|
-
*/
|
|
594
|
+
if (!opt.allowDirectory && mode & constants.S_IFDIR)
|
|
595
|
+
throw UV('EISDIR', 'open', path);
|
|
609
596
|
if (flag & constants.O_TRUNC)
|
|
610
597
|
await handle.truncate(0);
|
|
611
598
|
return handle;
|
|
@@ -652,9 +639,8 @@ export async function writeFile(path, data, _options) {
|
|
|
652
639
|
const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
|
|
653
640
|
const handle = __addDisposableResource(env_3, path instanceof FileHandle ? path : await open.call(this, path.toString(), options.flag, options.mode), true);
|
|
654
641
|
const _data = typeof data == 'string' ? data : data instanceof DataView ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : data;
|
|
655
|
-
if (typeof _data != 'string' && !(_data instanceof Uint8Array))
|
|
656
|
-
throw new
|
|
657
|
-
}
|
|
642
|
+
if (typeof _data != 'string' && !(_data instanceof Uint8Array))
|
|
643
|
+
throw new TypeError('The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received ' + typeof data);
|
|
658
644
|
await handle.writeFile(_data, options);
|
|
659
645
|
}
|
|
660
646
|
catch (e_3) {
|
|
@@ -679,12 +665,9 @@ export async function appendFile(path, data, _options) {
|
|
|
679
665
|
try {
|
|
680
666
|
const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
|
|
681
667
|
const flag = flags.parse(options.flag);
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (typeof data != 'string' && !options.encoding) {
|
|
686
|
-
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
687
|
-
}
|
|
668
|
+
const $ex = { syscall: 'write', path: path instanceof FileHandle ? path.path : path.toString() };
|
|
669
|
+
if (!(flag & constants.O_APPEND))
|
|
670
|
+
throw UV('EBADF', $ex);
|
|
688
671
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
689
672
|
const handle = __addDisposableResource(env_4, typeof path == 'object' && 'fd' in path ? path : await open.call(this, path, options.flag, options.mode), true);
|
|
690
673
|
await handle.appendFile(encodedData, options);
|
|
@@ -703,77 +686,69 @@ appendFile;
|
|
|
703
686
|
export async function rmdir(path) {
|
|
704
687
|
path = await realpath.call(this, path);
|
|
705
688
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
}
|
|
717
|
-
catch (e) {
|
|
718
|
-
throw fixError(e, { [resolved]: path });
|
|
719
|
-
}
|
|
689
|
+
const $ex = { syscall: 'rmdir', path };
|
|
690
|
+
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
691
|
+
if (!stats)
|
|
692
|
+
throw UV('ENOENT', $ex);
|
|
693
|
+
if (!isDirectory(stats))
|
|
694
|
+
throw UV('ENOTDIR', $ex);
|
|
695
|
+
if (checkAccess && !hasAccess(this, stats, constants.W_OK))
|
|
696
|
+
throw UV('EACCES', $ex);
|
|
697
|
+
await fs.rmdir(resolved).catch(rethrow($ex));
|
|
698
|
+
emitChange(this, 'rename', path.toString());
|
|
720
699
|
}
|
|
721
700
|
rmdir;
|
|
722
701
|
export async function mkdir(path, options) {
|
|
723
|
-
var _a
|
|
702
|
+
var _a;
|
|
724
703
|
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
|
|
725
704
|
options = typeof options === 'object' ? options : { mode: options };
|
|
726
705
|
const mode = normalizeMode(options === null || options === void 0 ? void 0 : options.mode, 0o777);
|
|
727
706
|
path = await realpath.call(this, path);
|
|
728
|
-
const { fs, path: resolved
|
|
729
|
-
const
|
|
730
|
-
const __create = async (path, parent) => {
|
|
707
|
+
const { fs, path: resolved } = resolveMount(path, this);
|
|
708
|
+
const __create = async (path, resolved, parent) => {
|
|
731
709
|
if (checkAccess && !hasAccess(this, parent, constants.W_OK))
|
|
732
|
-
throw
|
|
733
|
-
const inode = await fs
|
|
710
|
+
throw UV('EACCES', 'mkdir', dirname(path));
|
|
711
|
+
const inode = await fs
|
|
712
|
+
.mkdir(resolved, {
|
|
734
713
|
mode,
|
|
735
714
|
uid: parent.mode & constants.S_ISUID ? parent.uid : uid,
|
|
736
715
|
gid: parent.mode & constants.S_ISGID ? parent.gid : gid,
|
|
737
|
-
})
|
|
716
|
+
})
|
|
717
|
+
.catch(rethrow({ syscall: 'mkdir', path }));
|
|
738
718
|
emitChange(this, 'rename', path);
|
|
739
719
|
return inode;
|
|
740
720
|
};
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
return;
|
|
745
|
-
}
|
|
746
|
-
const dirs = [];
|
|
747
|
-
for (let dir = resolved, origDir = path; !(await fs.exists(dir)); dir = dirname(dir), origDir = dirname(origDir)) {
|
|
748
|
-
dirs.unshift(dir);
|
|
749
|
-
errorPaths[dir] = origDir;
|
|
750
|
-
}
|
|
751
|
-
if (!dirs.length)
|
|
752
|
-
return;
|
|
753
|
-
const stats = [await fs.stat(dirname(dirs[0]))];
|
|
754
|
-
for (const [i, dir] of dirs.entries()) {
|
|
755
|
-
stats.push(await __create(dir, stats[i]));
|
|
756
|
-
}
|
|
757
|
-
return root.length == 1 ? dirs[0] : (_b = dirs[0]) === null || _b === void 0 ? void 0 : _b.slice(root.length);
|
|
721
|
+
if (!(options === null || options === void 0 ? void 0 : options.recursive)) {
|
|
722
|
+
await __create(path, resolved, await fs.stat(dirname(resolved)).catch(rethrow({ path: dirname(path) })));
|
|
723
|
+
return;
|
|
758
724
|
}
|
|
759
|
-
|
|
760
|
-
|
|
725
|
+
const dirs = [];
|
|
726
|
+
let origDir = path;
|
|
727
|
+
for (let dir = resolved; !(await fs.exists(dir).catch(rethrow({ syscall: 'exists', path: origDir }))); dir = dirname(dir), origDir = dirname(origDir)) {
|
|
728
|
+
dirs.unshift([origDir, dir]);
|
|
761
729
|
}
|
|
730
|
+
if (!dirs.length)
|
|
731
|
+
return;
|
|
732
|
+
const stats = [await fs.stat(dirname(dirs[0][1])).catch(rethrow({ syscall: 'stat', path: dirname(dirs[0][0]) }))];
|
|
733
|
+
for (const [i, [path, resolved]] of dirs.entries()) {
|
|
734
|
+
stats.push(await __create(path, resolved, stats[i]));
|
|
735
|
+
}
|
|
736
|
+
return dirs[0][0];
|
|
762
737
|
}
|
|
763
738
|
mkdir;
|
|
764
739
|
export async function readdir(path, options) {
|
|
765
740
|
options = typeof options === 'object' ? options : { encoding: options };
|
|
766
741
|
path = await realpath.call(this, path);
|
|
767
742
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
743
|
+
const $ex = { syscall: 'readdir', path };
|
|
744
|
+
const stats = await fs.stat(resolved).catch(rethrow({ syscall: 'stat', path }));
|
|
745
|
+
if (!stats)
|
|
746
|
+
throw UV('ENOENT', $ex);
|
|
772
747
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
773
|
-
throw
|
|
748
|
+
throw UV('EACCES', $ex);
|
|
774
749
|
if (!isDirectory(stats))
|
|
775
|
-
throw
|
|
776
|
-
const entries = await fs.readdir(resolved).catch((
|
|
750
|
+
throw UV('ENOTDIR', $ex);
|
|
751
|
+
const entries = await fs.readdir(resolved).catch(rethrow($ex));
|
|
777
752
|
const values = [];
|
|
778
753
|
const addEntry = async (entry) => {
|
|
779
754
|
let entryStats;
|
|
@@ -781,7 +756,7 @@ export async function readdir(path, options) {
|
|
|
781
756
|
entryStats = await fs.stat(join(resolved, entry)).catch((e) => {
|
|
782
757
|
if (e.code == 'ENOENT')
|
|
783
758
|
return;
|
|
784
|
-
throw
|
|
759
|
+
throw setUVMessage(Object.assign(e, { syscall: 'stat', path: join(path, entry) }));
|
|
785
760
|
});
|
|
786
761
|
if (!entryStats)
|
|
787
762
|
return;
|
|
@@ -815,49 +790,41 @@ export async function readdir(path, options) {
|
|
|
815
790
|
return values;
|
|
816
791
|
}
|
|
817
792
|
readdir;
|
|
818
|
-
export async function link(
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
const { fs, path } = resolveMount(
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
throw ErrnoError.With('EACCES', path, 'link');
|
|
836
|
-
}
|
|
837
|
-
return await fs.link(path, link.path);
|
|
838
|
-
}
|
|
839
|
-
catch (e) {
|
|
840
|
-
throw fixError(e, { [link.path]: linkPath, [path]: targetPath });
|
|
841
|
-
}
|
|
793
|
+
export async function link(path, dest) {
|
|
794
|
+
path = normalizePath(path);
|
|
795
|
+
dest = normalizePath(dest);
|
|
796
|
+
const { fs, path: resolved } = resolveMount(path, this);
|
|
797
|
+
const dst = resolveMount(dest, this);
|
|
798
|
+
const $ex = { syscall: 'link', path };
|
|
799
|
+
if (fs != dst.fs)
|
|
800
|
+
throw UV('EXDEV', $ex);
|
|
801
|
+
const stats = await fs.stat(dirname(resolved)).catch(rethrow({ syscall: 'stat', path: dirname(path) }));
|
|
802
|
+
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
803
|
+
throw UV('EACCES', 'link', dirname(path));
|
|
804
|
+
// We need to use the VFS here since the link path may be a mount point
|
|
805
|
+
if (checkAccess && !(await stat.call(this, dirname(dest))).hasAccess(constants.W_OK, this))
|
|
806
|
+
throw UV('EACCES', 'link', dirname(dest));
|
|
807
|
+
if (checkAccess && !hasAccess(this, await fs.stat(resolved).catch(rethrow($ex)), constants.R_OK))
|
|
808
|
+
throw UV('EACCES', $ex);
|
|
809
|
+
return await fs.link(resolved, dst.path).catch(rethrow($ex));
|
|
842
810
|
}
|
|
843
811
|
link;
|
|
844
812
|
/**
|
|
845
813
|
* `symlink`.
|
|
846
|
-
* @param
|
|
814
|
+
* @param dest target path
|
|
847
815
|
* @param path link path
|
|
848
816
|
* @param type can be either `'dir'` or `'file'` (default is `'file'`)
|
|
849
817
|
*/
|
|
850
|
-
export async function symlink(
|
|
818
|
+
export async function symlink(dest, path, type = 'file') {
|
|
851
819
|
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
852
820
|
try {
|
|
853
|
-
if (!['file', 'dir', 'junction'].includes(type))
|
|
854
|
-
throw new
|
|
855
|
-
}
|
|
821
|
+
if (!['file', 'dir', 'junction'].includes(type))
|
|
822
|
+
throw new TypeError('Invalid symlink type: ' + type);
|
|
856
823
|
path = normalizePath(path);
|
|
857
824
|
if (await exists.call(this, path))
|
|
858
|
-
throw
|
|
825
|
+
throw UV('EEXIST', 'symlink', path);
|
|
859
826
|
const handle = __addDisposableResource(env_5, await _open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
|
|
860
|
-
await handle.writeFile(normalizePath(
|
|
827
|
+
await handle.writeFile(normalizePath(dest, true));
|
|
861
828
|
await handle.chmod(constants.S_IFLNK);
|
|
862
829
|
}
|
|
863
830
|
catch (e_5) {
|
|
@@ -874,7 +841,11 @@ symlink;
|
|
|
874
841
|
export async function readlink(path, options) {
|
|
875
842
|
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
876
843
|
try {
|
|
877
|
-
|
|
844
|
+
path = normalizePath(path);
|
|
845
|
+
__assertType(path);
|
|
846
|
+
const handle = __addDisposableResource(env_6, await _open(this, path, { flag: 'r', mode: 0o644, preserveSymlinks: true }), true);
|
|
847
|
+
if (!isSymbolicLink(handle.inode))
|
|
848
|
+
throw UV('EINVAL', 'readlink', path);
|
|
878
849
|
const value = await handle.readFile();
|
|
879
850
|
const encoding = typeof options == 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options;
|
|
880
851
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
@@ -1044,20 +1015,18 @@ async function _resolve($, path, preserveSymlinks) {
|
|
|
1044
1015
|
const realDir = dir == '/' ? '/' : await realpath.call($, dir);
|
|
1045
1016
|
const maybePath = join(realDir, base);
|
|
1046
1017
|
const resolved = resolveMount(maybePath, $);
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
return
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
if (e.code == 'ENOENT') {
|
|
1057
|
-
return { ...resolved, fullPath: path };
|
|
1058
|
-
}
|
|
1059
|
-
throw fixError(e, { [resolved.path]: maybePath });
|
|
1018
|
+
const stats = await resolved.fs.stat(resolved.path).catch((e) => {
|
|
1019
|
+
if (e.code == 'ENOENT')
|
|
1020
|
+
return;
|
|
1021
|
+
throw setUVMessage(Object.assign(e, { syscall: 'stat', path: maybePath }));
|
|
1022
|
+
});
|
|
1023
|
+
if (!stats)
|
|
1024
|
+
return { ...resolved, fullPath: path };
|
|
1025
|
+
if (!isSymbolicLink(stats)) {
|
|
1026
|
+
return { ...resolved, fullPath: maybePath, stats };
|
|
1060
1027
|
}
|
|
1028
|
+
const target = resolve.call($, realDir, (await readlink.call($, maybePath)).toString());
|
|
1029
|
+
return await _resolve($, target);
|
|
1061
1030
|
}
|
|
1062
1031
|
export async function realpath(path, options) {
|
|
1063
1032
|
var _a;
|
|
@@ -1113,9 +1082,8 @@ export async function access(path, mode = constants.F_OK) {
|
|
|
1113
1082
|
if (!checkAccess)
|
|
1114
1083
|
return;
|
|
1115
1084
|
const stats = await stat.call(this, path);
|
|
1116
|
-
if (!stats.hasAccess(mode, this))
|
|
1117
|
-
throw
|
|
1118
|
-
}
|
|
1085
|
+
if (!stats.hasAccess(mode, this))
|
|
1086
|
+
throw UV('EACCES', 'access', path.toString());
|
|
1119
1087
|
}
|
|
1120
1088
|
access;
|
|
1121
1089
|
/**
|
|
@@ -1149,7 +1117,7 @@ export async function rm(path, options) {
|
|
|
1149
1117
|
case constants.S_IFIFO:
|
|
1150
1118
|
case constants.S_IFSOCK:
|
|
1151
1119
|
default:
|
|
1152
|
-
throw
|
|
1120
|
+
throw UV('ENOSYS', 'rm', path);
|
|
1153
1121
|
}
|
|
1154
1122
|
}
|
|
1155
1123
|
rm;
|
|
@@ -1171,9 +1139,8 @@ mkdtemp;
|
|
|
1171
1139
|
export async function copyFile(src, dest, mode) {
|
|
1172
1140
|
src = normalizePath(src);
|
|
1173
1141
|
dest = normalizePath(dest);
|
|
1174
|
-
if (mode && mode & constants.COPYFILE_EXCL && (await exists.call(this, dest)))
|
|
1175
|
-
throw
|
|
1176
|
-
}
|
|
1142
|
+
if (mode && mode & constants.COPYFILE_EXCL && (await exists.call(this, dest)))
|
|
1143
|
+
throw UV('EEXIST', 'copyFile', dest);
|
|
1177
1144
|
await writeFile.call(this, dest, await readFile.call(this, src));
|
|
1178
1145
|
emitChange(this, 'rename', dest.toString());
|
|
1179
1146
|
}
|
|
@@ -1206,14 +1173,12 @@ export async function cp(source, destination, opts) {
|
|
|
1206
1173
|
source = normalizePath(source);
|
|
1207
1174
|
destination = normalizePath(destination);
|
|
1208
1175
|
const srcStats = await lstat.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
1209
|
-
if ((opts === null || opts === void 0 ? void 0 : opts.errorOnExist) && (await exists.call(this, destination)))
|
|
1210
|
-
throw
|
|
1211
|
-
}
|
|
1176
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.errorOnExist) && (await exists.call(this, destination)))
|
|
1177
|
+
throw UV('EEXIST', 'cp', destination);
|
|
1212
1178
|
switch (srcStats.mode & constants.S_IFMT) {
|
|
1213
1179
|
case constants.S_IFDIR: {
|
|
1214
|
-
if (!(opts === null || opts === void 0 ? void 0 : opts.recursive))
|
|
1215
|
-
throw
|
|
1216
|
-
}
|
|
1180
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.recursive))
|
|
1181
|
+
throw UV('EISDIR', 'cp', source);
|
|
1217
1182
|
const [entries] = await Promise.all([
|
|
1218
1183
|
readdir.call(this, source, { withFileTypes: true }),
|
|
1219
1184
|
mkdir.call(this, destination, { recursive: true }),
|
|
@@ -1237,7 +1202,7 @@ export async function cp(source, destination, opts) {
|
|
|
1237
1202
|
case constants.S_IFIFO:
|
|
1238
1203
|
case constants.S_IFSOCK:
|
|
1239
1204
|
default:
|
|
1240
|
-
throw
|
|
1205
|
+
throw UV('ENOSYS', 'cp', source);
|
|
1241
1206
|
}
|
|
1242
1207
|
// Optionally preserve timestamps
|
|
1243
1208
|
if (opts === null || opts === void 0 ? void 0 : opts.preserveTimestamps) {
|