@zenfs/core 2.2.2 → 2.3.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 -9
- package/dist/backends/cow.js +4 -4
- package/dist/backends/fetch.js +8 -6
- package/dist/backends/memory.js +4 -2
- package/dist/backends/passthrough.js +2 -0
- package/dist/backends/port.d.ts +16 -89
- package/dist/backends/port.js +35 -171
- package/dist/backends/single_buffer.d.ts +4 -2
- package/dist/backends/single_buffer.js +169 -195
- package/dist/backends/store/fs.js +50 -73
- package/dist/backends/store/map.js +1 -2
- package/dist/backends/store/store.js +23 -27
- package/dist/config.js +2 -3
- package/dist/context.js +2 -2
- package/dist/internal/credentials.d.ts +6 -0
- package/dist/internal/credentials.js +10 -0
- package/dist/internal/devices.js +7 -10
- package/dist/internal/file_index.js +3 -8
- package/dist/internal/filesystem.js +19 -12
- package/dist/internal/index_fs.js +3 -4
- package/dist/internal/inode.d.ts +2 -0
- package/dist/internal/inode.js +148 -185
- package/dist/internal/rpc.d.ts +143 -0
- package/dist/internal/rpc.js +251 -0
- package/dist/mixins/async.js +5 -6
- package/dist/mixins/mutexed.js +16 -10
- package/dist/path.js +3 -4
- package/dist/polyfills.js +51 -22
- package/dist/readline.js +32 -30
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +11 -5
- package/dist/vfs/acl.d.ts +2 -0
- package/dist/vfs/acl.js +48 -66
- package/dist/vfs/async.js +4 -4
- package/dist/vfs/dir.d.ts +4 -3
- package/dist/vfs/dir.js +16 -10
- package/dist/vfs/file.js +22 -18
- package/dist/vfs/ioctl.js +39 -62
- package/dist/vfs/promises.d.ts +33 -25
- package/dist/vfs/promises.js +56 -47
- package/dist/vfs/shared.js +7 -7
- package/dist/vfs/stats.js +104 -77
- package/dist/vfs/streams.js +11 -8
- package/dist/vfs/sync.d.ts +22 -11
- package/dist/vfs/sync.js +24 -27
- package/dist/vfs/types.d.ts +3 -8
- package/dist/vfs/watchers.js +9 -3
- package/dist/vfs/xattr.js +6 -12
- package/package.json +2 -2
- package/scripts/test.js +14 -7
- package/tests/backend/fetch.test.ts +14 -14
- package/tests/backend/port.test.ts +25 -17
- package/tests/common/context.test.ts +14 -0
- package/tests/common/handle.test.ts +5 -3
- package/tests/fetch/run.sh +2 -1
- package/tests/fs/scaling.test.ts +32 -0
- package/tests/fs/watch.test.ts +2 -5
- package/tests/setup/single-buffer.ts +1 -1
- package/tests/tsconfig.json +3 -2
- package/types/uint8array.d.ts +64 -0
package/dist/vfs/ioctl.js
CHANGED
|
@@ -38,21 +38,6 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
38
38
|
}
|
|
39
39
|
return useValue ? value : void 0;
|
|
40
40
|
};
|
|
41
|
-
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
42
|
-
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
43
|
-
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
44
|
-
};
|
|
45
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
46
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
47
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
48
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
49
|
-
};
|
|
50
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
51
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
52
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
53
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
54
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
55
|
-
};
|
|
56
41
|
import { Errno, Exception, setUVMessage, UV } from 'kerium';
|
|
57
42
|
import { sizeof, struct, types as t } from 'memium';
|
|
58
43
|
import { _throw } from 'utilium';
|
|
@@ -101,7 +86,6 @@ var XFlag;
|
|
|
101
86
|
XFlag[XFlag["HasAttr"] = 2147483648] = "HasAttr";
|
|
102
87
|
})(XFlag || (XFlag = {}));
|
|
103
88
|
let fsxattr = (() => {
|
|
104
|
-
var _fsxattr_xflags_accessor_storage, _fsxattr_extsize_accessor_storage, _fsxattr_nextents_accessor_storage, _fsxattr_projid_accessor_storage, _fsxattr_cowextsize_accessor_storage, _fsxattr_pad_accessor_storage;
|
|
105
89
|
var _a, _b, _c, _d, _e;
|
|
106
90
|
let _classDecorators = [struct()];
|
|
107
91
|
let _classDescriptor;
|
|
@@ -126,32 +110,52 @@ let fsxattr = (() => {
|
|
|
126
110
|
let _pad_decorators;
|
|
127
111
|
let _pad_initializers = [];
|
|
128
112
|
let _pad_extraInitializers = [];
|
|
129
|
-
var fsxattr =
|
|
113
|
+
var fsxattr = class extends _classSuper {
|
|
114
|
+
static { _classThis = this; }
|
|
115
|
+
static {
|
|
116
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
117
|
+
_xflags_decorators = [(_a = t).uint32.bind(_a)];
|
|
118
|
+
_extsize_decorators = [(_b = t).uint32.bind(_b)];
|
|
119
|
+
_nextents_decorators = [(_c = t).uint32.bind(_c)];
|
|
120
|
+
_projid_decorators = [(_d = t).uint32.bind(_d)];
|
|
121
|
+
_cowextsize_decorators = [(_e = t).uint32.bind(_e)];
|
|
122
|
+
_pad_decorators = [t.char(8)];
|
|
123
|
+
__esDecorate(this, null, _xflags_decorators, { kind: "accessor", name: "xflags", static: false, private: false, access: { has: obj => "xflags" in obj, get: obj => obj.xflags, set: (obj, value) => { obj.xflags = value; } }, metadata: _metadata }, _xflags_initializers, _xflags_extraInitializers);
|
|
124
|
+
__esDecorate(this, null, _extsize_decorators, { kind: "accessor", name: "extsize", static: false, private: false, access: { has: obj => "extsize" in obj, get: obj => obj.extsize, set: (obj, value) => { obj.extsize = value; } }, metadata: _metadata }, _extsize_initializers, _extsize_extraInitializers);
|
|
125
|
+
__esDecorate(this, null, _nextents_decorators, { kind: "accessor", name: "nextents", static: false, private: false, access: { has: obj => "nextents" in obj, get: obj => obj.nextents, set: (obj, value) => { obj.nextents = value; } }, metadata: _metadata }, _nextents_initializers, _nextents_extraInitializers);
|
|
126
|
+
__esDecorate(this, null, _projid_decorators, { kind: "accessor", name: "projid", static: false, private: false, access: { has: obj => "projid" in obj, get: obj => obj.projid, set: (obj, value) => { obj.projid = value; } }, metadata: _metadata }, _projid_initializers, _projid_extraInitializers);
|
|
127
|
+
__esDecorate(this, null, _cowextsize_decorators, { kind: "accessor", name: "cowextsize", static: false, private: false, access: { has: obj => "cowextsize" in obj, get: obj => obj.cowextsize, set: (obj, value) => { obj.cowextsize = value; } }, metadata: _metadata }, _cowextsize_initializers, _cowextsize_extraInitializers);
|
|
128
|
+
__esDecorate(this, null, _pad_decorators, { kind: "accessor", name: "pad", static: false, private: false, access: { has: obj => "pad" in obj, get: obj => obj.pad, set: (obj, value) => { obj.pad = value; } }, metadata: _metadata }, _pad_initializers, _pad_extraInitializers);
|
|
129
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
130
|
+
fsxattr = _classThis = _classDescriptor.value;
|
|
131
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
132
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
133
|
+
}
|
|
134
|
+
#xflags_accessor_storage = __runInitializers(this, _xflags_initializers, void 0);
|
|
130
135
|
/** xflags field value */
|
|
131
|
-
get xflags() { return
|
|
132
|
-
set xflags(value) {
|
|
136
|
+
get xflags() { return this.#xflags_accessor_storage; }
|
|
137
|
+
set xflags(value) { this.#xflags_accessor_storage = value; }
|
|
138
|
+
#extsize_accessor_storage = (__runInitializers(this, _xflags_extraInitializers), __runInitializers(this, _extsize_initializers, void 0));
|
|
133
139
|
/** extsize field value */
|
|
134
|
-
get extsize() { return
|
|
135
|
-
set extsize(value) {
|
|
140
|
+
get extsize() { return this.#extsize_accessor_storage; }
|
|
141
|
+
set extsize(value) { this.#extsize_accessor_storage = value; }
|
|
142
|
+
#nextents_accessor_storage = (__runInitializers(this, _extsize_extraInitializers), __runInitializers(this, _nextents_initializers, void 0));
|
|
136
143
|
/** nextents field value */
|
|
137
|
-
get nextents() { return
|
|
138
|
-
set nextents(value) {
|
|
144
|
+
get nextents() { return this.#nextents_accessor_storage; }
|
|
145
|
+
set nextents(value) { this.#nextents_accessor_storage = value; }
|
|
146
|
+
#projid_accessor_storage = (__runInitializers(this, _nextents_extraInitializers), __runInitializers(this, _projid_initializers, void 0));
|
|
139
147
|
/** project identifier */
|
|
140
|
-
get projid() { return
|
|
141
|
-
set projid(value) {
|
|
148
|
+
get projid() { return this.#projid_accessor_storage; }
|
|
149
|
+
set projid(value) { this.#projid_accessor_storage = value; }
|
|
150
|
+
#cowextsize_accessor_storage = (__runInitializers(this, _projid_extraInitializers), __runInitializers(this, _cowextsize_initializers, void 0));
|
|
142
151
|
/** CoW extsize field value */
|
|
143
|
-
get cowextsize() { return
|
|
144
|
-
set cowextsize(value) {
|
|
145
|
-
|
|
146
|
-
|
|
152
|
+
get cowextsize() { return this.#cowextsize_accessor_storage; }
|
|
153
|
+
set cowextsize(value) { this.#cowextsize_accessor_storage = value; }
|
|
154
|
+
#pad_accessor_storage = (__runInitializers(this, _cowextsize_extraInitializers), __runInitializers(this, _pad_initializers, []));
|
|
155
|
+
get pad() { return this.#pad_accessor_storage; }
|
|
156
|
+
set pad(value) { this.#pad_accessor_storage = value; }
|
|
147
157
|
constructor(inode = _throw(new Exception(Errno.EINVAL, 'fsxattr must be initialized with an inode'))) {
|
|
148
158
|
super(new ArrayBuffer(sizeof(fsxattr)));
|
|
149
|
-
_fsxattr_xflags_accessor_storage.set(this, __runInitializers(this, _xflags_initializers, void 0));
|
|
150
|
-
_fsxattr_extsize_accessor_storage.set(this, (__runInitializers(this, _xflags_extraInitializers), __runInitializers(this, _extsize_initializers, void 0)));
|
|
151
|
-
_fsxattr_nextents_accessor_storage.set(this, (__runInitializers(this, _extsize_extraInitializers), __runInitializers(this, _nextents_initializers, void 0)));
|
|
152
|
-
_fsxattr_projid_accessor_storage.set(this, (__runInitializers(this, _nextents_extraInitializers), __runInitializers(this, _projid_initializers, void 0)));
|
|
153
|
-
_fsxattr_cowextsize_accessor_storage.set(this, (__runInitializers(this, _projid_extraInitializers), __runInitializers(this, _cowextsize_initializers, void 0)));
|
|
154
|
-
_fsxattr_pad_accessor_storage.set(this, (__runInitializers(this, _cowextsize_extraInitializers), __runInitializers(this, _pad_initializers, [])));
|
|
155
159
|
__runInitializers(this, _pad_extraInitializers);
|
|
156
160
|
this.extsize = inode.size;
|
|
157
161
|
this.nextents = 1;
|
|
@@ -165,33 +169,6 @@ let fsxattr = (() => {
|
|
|
165
169
|
}
|
|
166
170
|
}
|
|
167
171
|
};
|
|
168
|
-
_fsxattr_xflags_accessor_storage = new WeakMap();
|
|
169
|
-
_fsxattr_extsize_accessor_storage = new WeakMap();
|
|
170
|
-
_fsxattr_nextents_accessor_storage = new WeakMap();
|
|
171
|
-
_fsxattr_projid_accessor_storage = new WeakMap();
|
|
172
|
-
_fsxattr_cowextsize_accessor_storage = new WeakMap();
|
|
173
|
-
_fsxattr_pad_accessor_storage = new WeakMap();
|
|
174
|
-
__setFunctionName(_classThis, "fsxattr");
|
|
175
|
-
(() => {
|
|
176
|
-
var _a;
|
|
177
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
|
|
178
|
-
_xflags_decorators = [(_a = t).uint32.bind(_a)];
|
|
179
|
-
_extsize_decorators = [(_b = t).uint32.bind(_b)];
|
|
180
|
-
_nextents_decorators = [(_c = t).uint32.bind(_c)];
|
|
181
|
-
_projid_decorators = [(_d = t).uint32.bind(_d)];
|
|
182
|
-
_cowextsize_decorators = [(_e = t).uint32.bind(_e)];
|
|
183
|
-
_pad_decorators = [t.char(8)];
|
|
184
|
-
__esDecorate(_classThis, null, _xflags_decorators, { kind: "accessor", name: "xflags", static: false, private: false, access: { has: obj => "xflags" in obj, get: obj => obj.xflags, set: (obj, value) => { obj.xflags = value; } }, metadata: _metadata }, _xflags_initializers, _xflags_extraInitializers);
|
|
185
|
-
__esDecorate(_classThis, null, _extsize_decorators, { kind: "accessor", name: "extsize", static: false, private: false, access: { has: obj => "extsize" in obj, get: obj => obj.extsize, set: (obj, value) => { obj.extsize = value; } }, metadata: _metadata }, _extsize_initializers, _extsize_extraInitializers);
|
|
186
|
-
__esDecorate(_classThis, null, _nextents_decorators, { kind: "accessor", name: "nextents", static: false, private: false, access: { has: obj => "nextents" in obj, get: obj => obj.nextents, set: (obj, value) => { obj.nextents = value; } }, metadata: _metadata }, _nextents_initializers, _nextents_extraInitializers);
|
|
187
|
-
__esDecorate(_classThis, null, _projid_decorators, { kind: "accessor", name: "projid", static: false, private: false, access: { has: obj => "projid" in obj, get: obj => obj.projid, set: (obj, value) => { obj.projid = value; } }, metadata: _metadata }, _projid_initializers, _projid_extraInitializers);
|
|
188
|
-
__esDecorate(_classThis, null, _cowextsize_decorators, { kind: "accessor", name: "cowextsize", static: false, private: false, access: { has: obj => "cowextsize" in obj, get: obj => obj.cowextsize, set: (obj, value) => { obj.cowextsize = value; } }, metadata: _metadata }, _cowextsize_initializers, _cowextsize_extraInitializers);
|
|
189
|
-
__esDecorate(_classThis, null, _pad_decorators, { kind: "accessor", name: "pad", static: false, private: false, access: { has: obj => "pad" in obj, get: obj => obj.pad, set: (obj, value) => { obj.pad = value; } }, metadata: _metadata }, _pad_initializers, _pad_extraInitializers);
|
|
190
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
191
|
-
fsxattr = _classThis = _classDescriptor.value;
|
|
192
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
193
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
194
|
-
})();
|
|
195
172
|
return fsxattr = _classThis;
|
|
196
173
|
})();
|
|
197
174
|
/**
|
package/dist/vfs/promises.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Abortable } from 'node:events';
|
|
1
2
|
import type * as fs from 'node:fs';
|
|
2
3
|
import type * as promises from 'node:fs/promises';
|
|
3
4
|
import type { Stream } from 'node:stream';
|
|
@@ -6,7 +7,7 @@ import type { V_Context } from '../context.js';
|
|
|
6
7
|
import type { FileSystem, StreamOptions } from '../internal/filesystem.js';
|
|
7
8
|
import type { InodeLike } from '../internal/inode.js';
|
|
8
9
|
import type { Interface as ReadlineInterface } from '../readline.js';
|
|
9
|
-
import type { FileContents,
|
|
10
|
+
import type { FileContents, ReaddirOptions } from './types.js';
|
|
10
11
|
import { Buffer } from 'buffer';
|
|
11
12
|
import '../polyfills.js';
|
|
12
13
|
import { Dir, Dirent } from './dir.js';
|
|
@@ -114,16 +115,13 @@ export declare class FileHandle implements promises.FileHandle {
|
|
|
114
115
|
read<T extends NodeJS.ArrayBufferView>(buffer: T, offset?: number, length?: number, position?: number | null): Promise<promises.FileReadResult<T>>;
|
|
115
116
|
read<T extends NodeJS.ArrayBufferView = Buffer>(buffer: T, options?: promises.FileReadOptions<T>): Promise<promises.FileReadResult<T>>;
|
|
116
117
|
read<T extends NodeJS.ArrayBufferView = Buffer>(options?: promises.FileReadOptions<T>): Promise<promises.FileReadResult<T>>;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
readFile(_options?:
|
|
124
|
-
flag?: fs.OpenMode;
|
|
125
|
-
}): Promise<Buffer>;
|
|
126
|
-
readFile(_options: (fs.ObjectEncodingOptions & promises.FlagAndOpenMode) | BufferEncoding): Promise<string>;
|
|
118
|
+
readFile(options?: ({
|
|
119
|
+
encoding?: null;
|
|
120
|
+
} & Abortable) | null): Promise<Buffer>;
|
|
121
|
+
readFile(options: ({
|
|
122
|
+
encoding: BufferEncoding;
|
|
123
|
+
} & Abortable) | BufferEncoding): Promise<string>;
|
|
124
|
+
readFile(_options?: (fs.ObjectEncodingOptions & Abortable) | BufferEncoding | null): Promise<string | Buffer>;
|
|
127
125
|
/**
|
|
128
126
|
* Read file data using a `ReadableStream`.
|
|
129
127
|
* The handle will not be closed automatically.
|
|
@@ -254,15 +252,15 @@ export declare function open(this: V_Context, path: fs.PathLike, flag?: fs.OpenM
|
|
|
254
252
|
* @option flag Defaults to `'r'`.
|
|
255
253
|
* @returns the file data
|
|
256
254
|
*/
|
|
257
|
-
export declare function readFile(this: V_Context, path: fs.PathLike | promises.FileHandle, options?: {
|
|
255
|
+
export declare function readFile(this: V_Context, path: fs.PathLike | promises.FileHandle, options?: ({
|
|
258
256
|
encoding?: null;
|
|
259
257
|
flag?: fs.OpenMode;
|
|
260
|
-
} | null): Promise<Buffer>;
|
|
261
|
-
export declare function readFile(this: V_Context, path: fs.PathLike | promises.FileHandle, options: {
|
|
258
|
+
} & Abortable) | null): Promise<Buffer>;
|
|
259
|
+
export declare function readFile(this: V_Context, path: fs.PathLike | promises.FileHandle, options: ({
|
|
262
260
|
encoding: BufferEncoding;
|
|
263
261
|
flag?: fs.OpenMode;
|
|
264
|
-
} | BufferEncoding): Promise<string>;
|
|
265
|
-
export declare function readFile(this: V_Context, path: fs.PathLike | promises.FileHandle,
|
|
262
|
+
} & Abortable) | BufferEncoding): Promise<string>;
|
|
263
|
+
export declare function readFile(this: V_Context, path: fs.PathLike | promises.FileHandle, _options?: (fs.ObjectEncodingOptions & Abortable & {
|
|
266
264
|
flag?: fs.OpenMode;
|
|
267
265
|
}) | BufferEncoding | null): Promise<string | Buffer>;
|
|
268
266
|
/**
|
|
@@ -309,19 +307,29 @@ export declare function mkdir(this: V_Context, path: fs.PathLike, options?: fs.M
|
|
|
309
307
|
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
310
308
|
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'`.
|
|
311
309
|
*/
|
|
312
|
-
export declare function readdir(this: V_Context, path: fs.PathLike, options?:
|
|
310
|
+
export declare function readdir(this: V_Context, path: fs.PathLike, options?: (fs.ObjectEncodingOptions & {
|
|
313
311
|
withFileTypes?: false;
|
|
314
|
-
|
|
315
|
-
|
|
312
|
+
recursive?: boolean;
|
|
313
|
+
}) | BufferEncoding | null): Promise<string[]>;
|
|
314
|
+
export declare function readdir(this: V_Context, path: fs.PathLike, options: {
|
|
315
|
+
encoding: 'buffer';
|
|
316
316
|
withFileTypes?: false;
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
recursive?: boolean;
|
|
318
|
+
} | 'buffer'): Promise<Buffer[]>;
|
|
319
|
+
export declare function readdir(this: V_Context, path: fs.PathLike, options?: (fs.ObjectEncodingOptions & {
|
|
319
320
|
withFileTypes?: false;
|
|
320
|
-
|
|
321
|
-
|
|
321
|
+
recursive?: boolean;
|
|
322
|
+
}) | BufferEncoding | null): Promise<string[] | Buffer[]>;
|
|
323
|
+
export declare function readdir(this: V_Context, path: fs.PathLike, options: fs.ObjectEncodingOptions & {
|
|
324
|
+
withFileTypes: true;
|
|
325
|
+
recursive?: boolean;
|
|
326
|
+
}): Promise<Dirent[]>;
|
|
327
|
+
export declare function readdir(this: V_Context, path: fs.PathLike, options: {
|
|
328
|
+
encoding: 'buffer';
|
|
322
329
|
withFileTypes: true;
|
|
323
|
-
|
|
324
|
-
|
|
330
|
+
recursive?: boolean;
|
|
331
|
+
}): Promise<Dirent<Buffer>[]>;
|
|
332
|
+
export declare function readdir(this: V_Context, path: fs.PathLike, options?: ReaddirOptions): Promise<string[] | Dirent<any>[] | Buffer[]>;
|
|
325
333
|
export declare function link(this: V_Context, path: fs.PathLike, dest: fs.PathLike): Promise<void>;
|
|
326
334
|
/**
|
|
327
335
|
* `symlink`.
|
package/dist/vfs/promises.js
CHANGED
|
@@ -70,6 +70,13 @@ import { ReadStream, WriteStream } from './streams.js';
|
|
|
70
70
|
import { emitChange, FSWatcher } from './watchers.js';
|
|
71
71
|
export * as constants from './constants.js';
|
|
72
72
|
export class FileHandle {
|
|
73
|
+
context;
|
|
74
|
+
fd;
|
|
75
|
+
_buffer;
|
|
76
|
+
/**
|
|
77
|
+
* Current position
|
|
78
|
+
*/
|
|
79
|
+
_position = 0;
|
|
73
80
|
/**
|
|
74
81
|
* Get the current file position.
|
|
75
82
|
*
|
|
@@ -85,21 +92,27 @@ export class FileHandle {
|
|
|
85
92
|
set position(value) {
|
|
86
93
|
this._position = value;
|
|
87
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Whether the file has changes which have not been written to the FS
|
|
97
|
+
*/
|
|
98
|
+
dirty = false;
|
|
99
|
+
/**
|
|
100
|
+
* Whether the file is open or closed
|
|
101
|
+
*/
|
|
102
|
+
closed = false;
|
|
103
|
+
/** The path relative to the context's root */
|
|
104
|
+
path;
|
|
105
|
+
/** The internal FS associated with the handle */
|
|
106
|
+
fs;
|
|
107
|
+
/** The path relative to the `FileSystem`'s root */
|
|
108
|
+
internalPath;
|
|
109
|
+
/** The flag the handle was opened with */
|
|
110
|
+
flag;
|
|
111
|
+
/** Stats for the handle */
|
|
112
|
+
inode;
|
|
88
113
|
constructor(context, fd) {
|
|
89
114
|
this.context = context;
|
|
90
115
|
this.fd = fd;
|
|
91
|
-
/**
|
|
92
|
-
* Current position
|
|
93
|
-
*/
|
|
94
|
-
this._position = 0;
|
|
95
|
-
/**
|
|
96
|
-
* Whether the file has changes which have not been written to the FS
|
|
97
|
-
*/
|
|
98
|
-
this.dirty = false;
|
|
99
|
-
/**
|
|
100
|
-
* Whether the file is open or closed
|
|
101
|
-
*/
|
|
102
|
-
this.closed = false;
|
|
103
116
|
const sync = fromFD(context, fd);
|
|
104
117
|
Object.assign(this, pick(sync, 'path', 'fs', 'internalPath', 'flag', 'inode'));
|
|
105
118
|
}
|
|
@@ -253,9 +266,9 @@ export class FileHandle {
|
|
|
253
266
|
buffer = buffer.buffer;
|
|
254
267
|
}
|
|
255
268
|
const pos = Number.isSafeInteger(position) ? position : this.position;
|
|
256
|
-
buffer
|
|
257
|
-
offset
|
|
258
|
-
return this._read(buffer, offset, length
|
|
269
|
+
buffer ||= new Uint8Array(this.inode.size);
|
|
270
|
+
offset ??= 0;
|
|
271
|
+
return this._read(buffer, offset, length ?? buffer.byteLength - offset, pos);
|
|
259
272
|
}
|
|
260
273
|
async readFile(_options) {
|
|
261
274
|
const options = normalizeOptions(_options, null, 'r', 0o444);
|
|
@@ -309,7 +322,7 @@ export class FileHandle {
|
|
|
309
322
|
throw UV('EBADF', 'stat', this.path);
|
|
310
323
|
if (checkAccess && !hasAccess(this.context, this.inode, constants.R_OK))
|
|
311
324
|
throw UV('EACCES', 'stat', this.path);
|
|
312
|
-
return
|
|
325
|
+
return opts?.bigint ? new BigIntStats(this.inode) : new Stats(this.inode);
|
|
313
326
|
}
|
|
314
327
|
/**
|
|
315
328
|
* Write buffer to the file.
|
|
@@ -362,11 +375,11 @@ export class FileHandle {
|
|
|
362
375
|
}
|
|
363
376
|
else {
|
|
364
377
|
buffer = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
365
|
-
offset = options
|
|
378
|
+
offset = options ?? 0;
|
|
366
379
|
length = typeof lenOrEnc == 'number' ? lenOrEnc : buffer.byteLength;
|
|
367
380
|
position = typeof position === 'number' ? position : null;
|
|
368
381
|
}
|
|
369
|
-
position
|
|
382
|
+
position ??= this.position;
|
|
370
383
|
const bytesWritten = await this._write(buffer, offset, length, position);
|
|
371
384
|
this._emitChange();
|
|
372
385
|
return { buffer: data, bytesWritten };
|
|
@@ -516,7 +529,7 @@ export async function stat(path, options) {
|
|
|
516
529
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
517
530
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
518
531
|
throw UV('EACCES', $ex);
|
|
519
|
-
return
|
|
532
|
+
return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
|
|
520
533
|
}
|
|
521
534
|
stat;
|
|
522
535
|
export async function lstat(path, options) {
|
|
@@ -526,7 +539,7 @@ export async function lstat(path, options) {
|
|
|
526
539
|
const stats = await fs.stat(resolved).catch(rethrow($ex));
|
|
527
540
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
528
541
|
throw UV('EACCES', $ex);
|
|
529
|
-
return
|
|
542
|
+
return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
|
|
530
543
|
}
|
|
531
544
|
lstat;
|
|
532
545
|
export async function truncate(path, len = 0) {
|
|
@@ -562,7 +575,6 @@ unlink;
|
|
|
562
575
|
* @internal
|
|
563
576
|
*/
|
|
564
577
|
async function _open($, path, opt) {
|
|
565
|
-
var _a;
|
|
566
578
|
path = normalizePath(path);
|
|
567
579
|
const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
|
|
568
580
|
const $ex = { syscall: 'open', path };
|
|
@@ -578,7 +590,7 @@ async function _open($, path, opt) {
|
|
|
578
590
|
throw UV('ENOTDIR', 'open', dirname(path));
|
|
579
591
|
if (!opt.allowDirectory && mode & constants.S_IFDIR)
|
|
580
592
|
throw UV('EISDIR', 'open', path);
|
|
581
|
-
const { euid: uid, egid: gid } =
|
|
593
|
+
const { euid: uid, egid: gid } = $?.credentials ?? defaultContext.credentials;
|
|
582
594
|
const inode = await fs.createFile(resolved, {
|
|
583
595
|
mode,
|
|
584
596
|
uid: parentStats.mode & constants.S_ISUID ? parentStats.uid : uid,
|
|
@@ -699,10 +711,9 @@ export async function rmdir(path) {
|
|
|
699
711
|
}
|
|
700
712
|
rmdir;
|
|
701
713
|
export async function mkdir(path, options) {
|
|
702
|
-
|
|
703
|
-
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
|
|
714
|
+
const { euid: uid, egid: gid } = this?.credentials ?? defaultContext.credentials;
|
|
704
715
|
options = typeof options === 'object' ? options : { mode: options };
|
|
705
|
-
const mode = normalizeMode(options
|
|
716
|
+
const mode = normalizeMode(options?.mode, 0o777);
|
|
706
717
|
path = await realpath.call(this, path);
|
|
707
718
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
708
719
|
const __create = async (path, resolved, parent) => {
|
|
@@ -718,7 +729,7 @@ export async function mkdir(path, options) {
|
|
|
718
729
|
emitChange(this, 'rename', path);
|
|
719
730
|
return inode;
|
|
720
731
|
};
|
|
721
|
-
if (!
|
|
732
|
+
if (!options?.recursive) {
|
|
722
733
|
await __create(path, resolved, await fs.stat(dirname(resolved)).catch(rethrow({ path: dirname(path) })));
|
|
723
734
|
return;
|
|
724
735
|
}
|
|
@@ -737,7 +748,7 @@ export async function mkdir(path, options) {
|
|
|
737
748
|
}
|
|
738
749
|
mkdir;
|
|
739
750
|
export async function readdir(path, options) {
|
|
740
|
-
|
|
751
|
+
const opt = typeof options === 'object' && options != null ? options : { encoding: options, withFileTypes: false, recursive: false };
|
|
741
752
|
path = await realpath.call(this, path);
|
|
742
753
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
743
754
|
const $ex = { syscall: 'readdir', path };
|
|
@@ -752,7 +763,7 @@ export async function readdir(path, options) {
|
|
|
752
763
|
const values = [];
|
|
753
764
|
const addEntry = async (entry) => {
|
|
754
765
|
let entryStats;
|
|
755
|
-
if (
|
|
766
|
+
if (opt.recursive || opt.withFileTypes) {
|
|
756
767
|
entryStats = await fs.stat(join(resolved, entry)).catch((e) => {
|
|
757
768
|
if (e.code == 'ENOENT')
|
|
758
769
|
return;
|
|
@@ -761,18 +772,18 @@ export async function readdir(path, options) {
|
|
|
761
772
|
if (!entryStats)
|
|
762
773
|
return;
|
|
763
774
|
}
|
|
764
|
-
if (
|
|
765
|
-
values.push(new Dirent(entry, entryStats));
|
|
775
|
+
if (opt.withFileTypes) {
|
|
776
|
+
values.push(new Dirent(entry, entryStats, opt.encoding));
|
|
766
777
|
}
|
|
767
|
-
else if (
|
|
778
|
+
else if (opt.encoding == 'buffer') {
|
|
768
779
|
values.push(Buffer.from(entry));
|
|
769
780
|
}
|
|
770
781
|
else {
|
|
771
782
|
values.push(entry);
|
|
772
783
|
}
|
|
773
|
-
if (!
|
|
784
|
+
if (!opt.recursive || !isDirectory(entryStats))
|
|
774
785
|
return;
|
|
775
|
-
for (const subEntry of await readdir.call(this, join(path, entry),
|
|
786
|
+
for (const subEntry of await readdir.call(this, join(path, entry), opt)) {
|
|
776
787
|
if (subEntry instanceof Dirent) {
|
|
777
788
|
subEntry.path = join(entry, subEntry.path);
|
|
778
789
|
values.push(subEntry);
|
|
@@ -847,9 +858,9 @@ export async function readlink(path, options) {
|
|
|
847
858
|
if (!isSymbolicLink(handle.inode))
|
|
848
859
|
throw UV('EINVAL', 'readlink', path);
|
|
849
860
|
const value = await handle.readFile();
|
|
850
|
-
const encoding = typeof options == 'object' ? options
|
|
861
|
+
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
851
862
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
852
|
-
return encoding == 'buffer' ? value : value.toString((encoding
|
|
863
|
+
return encoding == 'buffer' ? value : value.toString((encoding ?? 'utf-8'));
|
|
853
864
|
}
|
|
854
865
|
catch (e_6) {
|
|
855
866
|
env_6.error = e_6;
|
|
@@ -1029,8 +1040,7 @@ async function _resolve($, path, preserveSymlinks) {
|
|
|
1029
1040
|
return await _resolve($, target);
|
|
1030
1041
|
}
|
|
1031
1042
|
export async function realpath(path, options) {
|
|
1032
|
-
|
|
1033
|
-
const encoding = typeof options == 'string' ? options : ((_a = options === null || options === void 0 ? void 0 : options.encoding) !== null && _a !== void 0 ? _a : 'utf8');
|
|
1043
|
+
const encoding = typeof options == 'string' ? options : (options?.encoding ?? 'utf8');
|
|
1034
1044
|
path = normalizePath(path);
|
|
1035
1045
|
const { fullPath } = await _resolve(this, path);
|
|
1036
1046
|
if (encoding == 'utf8' || encoding == 'utf-8')
|
|
@@ -1047,8 +1057,7 @@ export function watch(filename, options = {}) {
|
|
|
1047
1057
|
const eventQueue = [];
|
|
1048
1058
|
let done = false;
|
|
1049
1059
|
watcher.on('change', (eventType, filename) => {
|
|
1050
|
-
|
|
1051
|
-
(_a = eventQueue.shift()) === null || _a === void 0 ? void 0 : _a({ value: { eventType, filename }, done: false });
|
|
1060
|
+
eventQueue.shift()?.({ value: { eventType, filename }, done: false });
|
|
1052
1061
|
});
|
|
1053
1062
|
function cleanup() {
|
|
1054
1063
|
done = true;
|
|
@@ -1093,7 +1102,7 @@ access;
|
|
|
1093
1102
|
export async function rm(path, options) {
|
|
1094
1103
|
path = normalizePath(path);
|
|
1095
1104
|
const stats = await lstat.call(this, path).catch((error) => {
|
|
1096
|
-
if (error.code == 'ENOENT' &&
|
|
1105
|
+
if (error.code == 'ENOENT' && options?.force)
|
|
1097
1106
|
return undefined;
|
|
1098
1107
|
throw error;
|
|
1099
1108
|
});
|
|
@@ -1101,8 +1110,8 @@ export async function rm(path, options) {
|
|
|
1101
1110
|
return;
|
|
1102
1111
|
switch (stats.mode & constants.S_IFMT) {
|
|
1103
1112
|
case constants.S_IFDIR:
|
|
1104
|
-
if (options
|
|
1105
|
-
for (const entry of
|
|
1113
|
+
if (options?.recursive) {
|
|
1114
|
+
for (const entry of await readdir.call(this, path)) {
|
|
1106
1115
|
await rm.call(this, join(path, entry), options);
|
|
1107
1116
|
}
|
|
1108
1117
|
}
|
|
@@ -1122,7 +1131,7 @@ export async function rm(path, options) {
|
|
|
1122
1131
|
}
|
|
1123
1132
|
rm;
|
|
1124
1133
|
export async function mkdtemp(prefix, options) {
|
|
1125
|
-
const encoding = typeof options === 'object' ? options
|
|
1134
|
+
const encoding = typeof options === 'object' ? options?.encoding : options || 'utf8';
|
|
1126
1135
|
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
1127
1136
|
const resolvedPath = '/tmp/' + fsName;
|
|
1128
1137
|
await mkdir.call(this, resolvedPath);
|
|
@@ -1173,11 +1182,11 @@ export async function cp(source, destination, opts) {
|
|
|
1173
1182
|
source = normalizePath(source);
|
|
1174
1183
|
destination = normalizePath(destination);
|
|
1175
1184
|
const srcStats = await lstat.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
1176
|
-
if (
|
|
1185
|
+
if (opts?.errorOnExist && (await exists.call(this, destination)))
|
|
1177
1186
|
throw UV('EEXIST', 'cp', destination);
|
|
1178
1187
|
switch (srcStats.mode & constants.S_IFMT) {
|
|
1179
1188
|
case constants.S_IFDIR: {
|
|
1180
|
-
if (!
|
|
1189
|
+
if (!opts?.recursive)
|
|
1181
1190
|
throw UV('EISDIR', 'cp', source);
|
|
1182
1191
|
const [entries] = await Promise.all([
|
|
1183
1192
|
readdir.call(this, source, { withFileTypes: true }),
|
|
@@ -1205,7 +1214,7 @@ export async function cp(source, destination, opts) {
|
|
|
1205
1214
|
throw UV('ENOSYS', 'cp', source);
|
|
1206
1215
|
}
|
|
1207
1216
|
// Optionally preserve timestamps
|
|
1208
|
-
if (opts
|
|
1217
|
+
if (opts?.preserveTimestamps) {
|
|
1209
1218
|
await utimes.call(this, destination, srcStats.atime, srcStats.mtime);
|
|
1210
1219
|
}
|
|
1211
1220
|
}
|
|
@@ -1213,7 +1222,7 @@ cp;
|
|
|
1213
1222
|
export async function statfs(path, opts) {
|
|
1214
1223
|
path = normalizePath(path);
|
|
1215
1224
|
const { fs } = resolveMount(path, this);
|
|
1216
|
-
return Promise.resolve(_statfs(fs, opts
|
|
1225
|
+
return Promise.resolve(_statfs(fs, opts?.bigint));
|
|
1217
1226
|
}
|
|
1218
1227
|
export function glob(pattern, opt) {
|
|
1219
1228
|
pattern = Array.isArray(pattern) ? pattern : [pattern];
|
package/dist/vfs/shared.js
CHANGED
|
@@ -6,6 +6,7 @@ import { defaultContext } from '../internal/contexts.js';
|
|
|
6
6
|
import { join, resolve } from '../path.js';
|
|
7
7
|
import { normalizePath } from '../utils.js';
|
|
8
8
|
import { size_max } from './constants.js';
|
|
9
|
+
import { credentialsAllowRoot } from '../internal/credentials.js';
|
|
9
10
|
/**
|
|
10
11
|
* The map of mount points
|
|
11
12
|
* @category Backends and Configuration
|
|
@@ -50,7 +51,7 @@ export function umount(mountPoint) {
|
|
|
50
51
|
* @internal @hidden
|
|
51
52
|
*/
|
|
52
53
|
export function resolveMount(path, ctx) {
|
|
53
|
-
const root =
|
|
54
|
+
const root = ctx?.root || defaultContext.root;
|
|
54
55
|
path = normalizePath(join(root, path));
|
|
55
56
|
const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // descending order of the string length
|
|
56
57
|
for (const [mountPoint, fs] of sortedMounts) {
|
|
@@ -59,7 +60,7 @@ export function resolveMount(path, ctx) {
|
|
|
59
60
|
continue;
|
|
60
61
|
path = path.slice(mountPoint.length > 1 ? mountPoint.length : 0); // Resolve the path relative to the mount point
|
|
61
62
|
if (path === '')
|
|
62
|
-
path =
|
|
63
|
+
path = '/';
|
|
63
64
|
const case_fold = fs.attributes.get('case_fold');
|
|
64
65
|
if (case_fold === 'lower')
|
|
65
66
|
path = path.toLowerCase();
|
|
@@ -90,13 +91,12 @@ export function _statfs(fs, bigint) {
|
|
|
90
91
|
* @category Backends and Configuration
|
|
91
92
|
*/
|
|
92
93
|
export function chroot(path) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (((_a = $.credentials) === null || _a === void 0 ? void 0 : _a.uid) !== 0 && ((_b = $.credentials) === null || _b === void 0 ? void 0 : _b.gid) !== 0 && ((_c = $.credentials) === null || _c === void 0 ? void 0 : _c.euid) !== 0 && ((_d = $.credentials) === null || _d === void 0 ? void 0 : _d.egid) !== 0)
|
|
94
|
+
const $ = this ?? defaultContext;
|
|
95
|
+
if (!credentialsAllowRoot($.credentials))
|
|
96
96
|
throw withErrno('EPERM', 'Can not chroot() as non-root user');
|
|
97
|
-
|
|
97
|
+
$.root ??= '/';
|
|
98
98
|
const newRoot = join($.root, path);
|
|
99
|
-
for (const handle of
|
|
99
|
+
for (const handle of $.descriptors?.values() ?? []) {
|
|
100
100
|
if (!handle.path.startsWith($.root))
|
|
101
101
|
throw UV('EBUSY', 'chroot', handle.path);
|
|
102
102
|
handle.path = handle.path.slice($.root.length);
|