@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/stats.js
CHANGED
|
@@ -14,72 +14,109 @@ export class StatsCommon {
|
|
|
14
14
|
return this._convert(Math.ceil(Number(this.size) / 512));
|
|
15
15
|
}
|
|
16
16
|
set blocks(value) { }
|
|
17
|
+
/**
|
|
18
|
+
* Unix-style file mode (e.g. 0o644) that includes the type of the item.
|
|
19
|
+
*/
|
|
20
|
+
mode;
|
|
21
|
+
/**
|
|
22
|
+
* ID of device containing file
|
|
23
|
+
*/
|
|
24
|
+
dev = this._convert(0);
|
|
25
|
+
/**
|
|
26
|
+
* Inode number
|
|
27
|
+
*/
|
|
28
|
+
ino = this._convert(0);
|
|
29
|
+
/**
|
|
30
|
+
* Device ID (if special file)
|
|
31
|
+
*/
|
|
32
|
+
rdev = this._convert(0);
|
|
33
|
+
/**
|
|
34
|
+
* Number of hard links
|
|
35
|
+
*/
|
|
36
|
+
nlink = this._convert(1);
|
|
37
|
+
/**
|
|
38
|
+
* Block size for file system I/O
|
|
39
|
+
*/
|
|
40
|
+
blksize = this._convert(4096);
|
|
41
|
+
/**
|
|
42
|
+
* User ID of owner
|
|
43
|
+
*/
|
|
44
|
+
uid = this._convert(0);
|
|
45
|
+
/**
|
|
46
|
+
* Group ID of owner
|
|
47
|
+
*/
|
|
48
|
+
gid = this._convert(0);
|
|
49
|
+
/**
|
|
50
|
+
* Time of last access, since epoch
|
|
51
|
+
*/
|
|
52
|
+
atimeMs;
|
|
17
53
|
get atime() {
|
|
18
54
|
return new Date(Number(this.atimeMs));
|
|
19
55
|
}
|
|
20
56
|
set atime(value) {
|
|
21
57
|
this.atimeMs = this._convert(value.getTime());
|
|
22
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Time of last modification, since epoch
|
|
61
|
+
*/
|
|
62
|
+
mtimeMs;
|
|
23
63
|
get mtime() {
|
|
24
64
|
return new Date(Number(this.mtimeMs));
|
|
25
65
|
}
|
|
26
66
|
set mtime(value) {
|
|
27
67
|
this.mtimeMs = this._convert(value.getTime());
|
|
28
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Time of last time file status was changed, since epoch
|
|
71
|
+
*/
|
|
72
|
+
ctimeMs;
|
|
29
73
|
get ctime() {
|
|
30
74
|
return new Date(Number(this.ctimeMs));
|
|
31
75
|
}
|
|
32
76
|
set ctime(value) {
|
|
33
77
|
this.ctimeMs = this._convert(value.getTime());
|
|
34
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Time of file creation, since epoch
|
|
81
|
+
*/
|
|
82
|
+
birthtimeMs;
|
|
35
83
|
get birthtime() {
|
|
36
84
|
return new Date(Number(this.birthtimeMs));
|
|
37
85
|
}
|
|
38
86
|
set birthtime(value) {
|
|
39
87
|
this.birthtimeMs = this._convert(value.getTime());
|
|
40
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Size of the item in bytes.
|
|
91
|
+
* For directories/symlinks, this is normally the size of the struct that represents the item.
|
|
92
|
+
*/
|
|
93
|
+
size;
|
|
94
|
+
/**
|
|
95
|
+
* @internal Used by inodes
|
|
96
|
+
*/
|
|
97
|
+
data;
|
|
98
|
+
/**
|
|
99
|
+
* @internal Used by inodes
|
|
100
|
+
*/
|
|
101
|
+
flags;
|
|
102
|
+
/**
|
|
103
|
+
* @internal Used by inodes
|
|
104
|
+
*/
|
|
105
|
+
version;
|
|
41
106
|
/**
|
|
42
107
|
* Creates a new stats instance from a stats-like object. Can be used to copy stats (note)
|
|
43
108
|
*/
|
|
44
109
|
constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode, ino, ...rest } = {}) {
|
|
45
|
-
/**
|
|
46
|
-
* ID of device containing file
|
|
47
|
-
*/
|
|
48
|
-
this.dev = this._convert(0);
|
|
49
|
-
/**
|
|
50
|
-
* Inode number
|
|
51
|
-
*/
|
|
52
|
-
this.ino = this._convert(0);
|
|
53
|
-
/**
|
|
54
|
-
* Device ID (if special file)
|
|
55
|
-
*/
|
|
56
|
-
this.rdev = this._convert(0);
|
|
57
|
-
/**
|
|
58
|
-
* Number of hard links
|
|
59
|
-
*/
|
|
60
|
-
this.nlink = this._convert(1);
|
|
61
|
-
/**
|
|
62
|
-
* Block size for file system I/O
|
|
63
|
-
*/
|
|
64
|
-
this.blksize = this._convert(4096);
|
|
65
|
-
/**
|
|
66
|
-
* User ID of owner
|
|
67
|
-
*/
|
|
68
|
-
this.uid = this._convert(0);
|
|
69
|
-
/**
|
|
70
|
-
* Group ID of owner
|
|
71
|
-
*/
|
|
72
|
-
this.gid = this._convert(0);
|
|
73
110
|
const now = Date.now();
|
|
74
|
-
this.atimeMs = this._convert(atimeMs
|
|
75
|
-
this.mtimeMs = this._convert(mtimeMs
|
|
76
|
-
this.ctimeMs = this._convert(ctimeMs
|
|
77
|
-
this.birthtimeMs = this._convert(birthtimeMs
|
|
78
|
-
this.uid = this._convert(uid
|
|
79
|
-
this.gid = this._convert(gid
|
|
80
|
-
this.size = this._convert(size
|
|
81
|
-
this.ino = this._convert(ino
|
|
82
|
-
this.mode = this._convert(mode
|
|
111
|
+
this.atimeMs = this._convert(atimeMs ?? now);
|
|
112
|
+
this.mtimeMs = this._convert(mtimeMs ?? now);
|
|
113
|
+
this.ctimeMs = this._convert(ctimeMs ?? now);
|
|
114
|
+
this.birthtimeMs = this._convert(birthtimeMs ?? now);
|
|
115
|
+
this.uid = this._convert(uid ?? 0);
|
|
116
|
+
this.gid = this._convert(gid ?? 0);
|
|
117
|
+
this.size = this._convert(size ?? 0);
|
|
118
|
+
this.ino = this._convert(ino ?? 0);
|
|
119
|
+
this.mode = this._convert(mode ?? 0o644 & c.S_IFREG);
|
|
83
120
|
if ((this.mode & c.S_IFMT) == 0) {
|
|
84
121
|
this.mode = (this.mode | this._convert(c.S_IFREG));
|
|
85
122
|
}
|
|
@@ -154,20 +191,14 @@ export function _chown(stats, uid, gid) {
|
|
|
154
191
|
* @see http://man7.org/linux/man-pages/man2/stat.2.html
|
|
155
192
|
*/
|
|
156
193
|
export class Stats extends StatsCommon {
|
|
157
|
-
|
|
158
|
-
super(...arguments);
|
|
159
|
-
this._isBigint = false;
|
|
160
|
-
}
|
|
194
|
+
_isBigint = false;
|
|
161
195
|
}
|
|
162
196
|
Stats;
|
|
163
197
|
/**
|
|
164
198
|
* Stats with bigint
|
|
165
199
|
*/
|
|
166
200
|
export class BigIntStats extends StatsCommon {
|
|
167
|
-
|
|
168
|
-
super(...arguments);
|
|
169
|
-
this._isBigint = true;
|
|
170
|
-
}
|
|
201
|
+
_isBigint = true;
|
|
171
202
|
}
|
|
172
203
|
/**
|
|
173
204
|
* Determines if the file stats have changed by comparing relevant properties.
|
|
@@ -190,41 +221,37 @@ export const ZenFsType = 0x7a656e6673; // 'z' 'e' 'n' 'f' 's'
|
|
|
190
221
|
* @hidden
|
|
191
222
|
*/
|
|
192
223
|
export class StatsFs {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
this.ffree = c.size_max;
|
|
208
|
-
}
|
|
224
|
+
/** Type of file system. */
|
|
225
|
+
type = 0x7a656e6673;
|
|
226
|
+
/** Optimal transfer block size. */
|
|
227
|
+
bsize = 4096;
|
|
228
|
+
/** Total data blocks in file system. */
|
|
229
|
+
blocks = 0;
|
|
230
|
+
/** Free blocks in file system. */
|
|
231
|
+
bfree = 0;
|
|
232
|
+
/** Available blocks for unprivileged users */
|
|
233
|
+
bavail = 0;
|
|
234
|
+
/** Total file nodes in file system. */
|
|
235
|
+
files = c.size_max;
|
|
236
|
+
/** Free file nodes in file system. */
|
|
237
|
+
ffree = c.size_max;
|
|
209
238
|
}
|
|
210
239
|
/**
|
|
211
240
|
* @hidden
|
|
212
241
|
*/
|
|
213
242
|
export class BigIntStatsFs {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
this.ffree = BigInt(c.size_max);
|
|
229
|
-
}
|
|
243
|
+
/** Type of file system. */
|
|
244
|
+
type = BigInt('0x7a656e6673');
|
|
245
|
+
/** Optimal transfer block size. */
|
|
246
|
+
bsize = BigInt(4096);
|
|
247
|
+
/** Total data blocks in file system. */
|
|
248
|
+
blocks = BigInt(0);
|
|
249
|
+
/** Free blocks in file system. */
|
|
250
|
+
bfree = BigInt(0);
|
|
251
|
+
/** Available blocks for unprivileged users */
|
|
252
|
+
bavail = BigInt(0);
|
|
253
|
+
/** Total file nodes in file system. */
|
|
254
|
+
files = BigInt(c.size_max);
|
|
255
|
+
/** Free file nodes in file system. */
|
|
256
|
+
ffree = BigInt(c.size_max);
|
|
230
257
|
}
|
package/dist/vfs/streams.js
CHANGED
|
@@ -5,12 +5,13 @@ import { Readable, Writable } from 'readable-stream';
|
|
|
5
5
|
* A ReadStream implementation that wraps an underlying global ReadableStream.
|
|
6
6
|
*/
|
|
7
7
|
export class ReadStream extends Readable {
|
|
8
|
+
pending = true;
|
|
9
|
+
_path = '<unknown>';
|
|
10
|
+
_bytesRead = 0;
|
|
11
|
+
reader;
|
|
12
|
+
ready;
|
|
8
13
|
constructor(opts = {}, handleOrPromise) {
|
|
9
|
-
|
|
10
|
-
super({ ...opts, encoding: (_a = opts.encoding) !== null && _a !== void 0 ? _a : undefined });
|
|
11
|
-
this.pending = true;
|
|
12
|
-
this._path = '<unknown>';
|
|
13
|
-
this._bytesRead = 0;
|
|
14
|
+
super({ ...opts, encoding: opts.encoding ?? undefined });
|
|
14
15
|
this.ready = Promise.resolve(handleOrPromise)
|
|
15
16
|
.then(handle => {
|
|
16
17
|
this._path = handle.path;
|
|
@@ -64,11 +65,13 @@ export class ReadStream extends Readable {
|
|
|
64
65
|
* A WriteStream implementation that wraps an underlying global WritableStream.
|
|
65
66
|
*/
|
|
66
67
|
export class WriteStream extends Writable {
|
|
68
|
+
pending = true;
|
|
69
|
+
_path = '<unknown>';
|
|
70
|
+
_bytesWritten = 0;
|
|
71
|
+
writer;
|
|
72
|
+
ready;
|
|
67
73
|
constructor(opts = {}, handleOrPromise) {
|
|
68
74
|
super(opts);
|
|
69
|
-
this.pending = true;
|
|
70
|
-
this._path = '<unknown>';
|
|
71
|
-
this._bytesWritten = 0;
|
|
72
75
|
this.ready = Promise.resolve(handleOrPromise)
|
|
73
76
|
.then(handle => {
|
|
74
77
|
this._path = handle.path;
|
package/dist/vfs/sync.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as fs from 'node:fs';
|
|
2
2
|
import type { V_Context } from '../context.js';
|
|
3
|
-
import type { FileContents,
|
|
3
|
+
import type { FileContents, ReaddirOptions } from './types.js';
|
|
4
4
|
import { Buffer } from 'buffer';
|
|
5
5
|
import { Dir, Dirent } from './dir.js';
|
|
6
6
|
import { BigIntStats, Stats } from './stats.js';
|
|
@@ -47,7 +47,7 @@ export declare function lopenSync(this: V_Context, path: fs.PathLike, flag: stri
|
|
|
47
47
|
*/
|
|
48
48
|
export declare function readFileSync(this: V_Context, path: fs.PathOrFileDescriptor, options?: {
|
|
49
49
|
flag?: string;
|
|
50
|
-
} | null):
|
|
50
|
+
} | null): NonSharedBuffer;
|
|
51
51
|
export declare function readFileSync(this: V_Context, path: fs.PathOrFileDescriptor, options?: (fs.EncodingOption & {
|
|
52
52
|
flag?: string;
|
|
53
53
|
}) | BufferEncoding | null): string;
|
|
@@ -112,19 +112,30 @@ export declare function mkdirSync(this: V_Context, path: fs.PathLike, options?:
|
|
|
112
112
|
recursive?: false;
|
|
113
113
|
}) | null): void;
|
|
114
114
|
export declare function mkdirSync(this: V_Context, path: fs.PathLike, options?: fs.Mode | fs.MakeDirectoryOptions | null): string | undefined;
|
|
115
|
-
export declare function readdirSync(this: V_Context, path: fs.PathLike, options?:
|
|
115
|
+
export declare function readdirSync(this: V_Context, path: fs.PathLike, options?: {
|
|
116
|
+
encoding: BufferEncoding | null;
|
|
116
117
|
withFileTypes?: false;
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
recursive?: boolean;
|
|
119
|
+
} | BufferEncoding | null): string[];
|
|
120
|
+
export declare function readdirSync(this: V_Context, path: fs.PathLike, options: {
|
|
121
|
+
encoding: 'buffer';
|
|
119
122
|
withFileTypes?: false;
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
recursive?: boolean;
|
|
124
|
+
} | 'buffer'): Buffer[];
|
|
125
|
+
export declare function readdirSync(this: V_Context, path: fs.PathLike, options?: (fs.ObjectEncodingOptions & {
|
|
122
126
|
withFileTypes?: false;
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
recursive?: boolean;
|
|
128
|
+
}) | BufferEncoding | null): string[] | Buffer[];
|
|
129
|
+
export declare function readdirSync(this: V_Context, path: fs.PathLike, options: fs.ObjectEncodingOptions & {
|
|
125
130
|
withFileTypes: true;
|
|
126
|
-
|
|
127
|
-
|
|
131
|
+
recursive?: boolean;
|
|
132
|
+
}): Dirent[];
|
|
133
|
+
export declare function readdirSync(this: V_Context, path: fs.PathLike, options: {
|
|
134
|
+
encoding: 'buffer';
|
|
135
|
+
withFileTypes: true;
|
|
136
|
+
recursive?: boolean;
|
|
137
|
+
}): Dirent<Buffer>[];
|
|
138
|
+
export declare function readdirSync(this: V_Context, path: fs.PathLike, options?: ReaddirOptions): string[] | Dirent<any>[] | Buffer[];
|
|
128
139
|
export declare function linkSync(this: V_Context, targetPath: fs.PathLike, linkPath: fs.PathLike): void;
|
|
129
140
|
/**
|
|
130
141
|
* Synchronous `symlink`.
|
package/dist/vfs/sync.js
CHANGED
|
@@ -134,7 +134,7 @@ export function statSync(path, options) {
|
|
|
134
134
|
}
|
|
135
135
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
136
136
|
throw UV('EACCES', { syscall: 'stat', path });
|
|
137
|
-
return
|
|
137
|
+
return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
|
|
138
138
|
}
|
|
139
139
|
statSync;
|
|
140
140
|
export function lstatSync(path, options) {
|
|
@@ -143,14 +143,14 @@ export function lstatSync(path, options) {
|
|
|
143
143
|
const stats = wrap(fs, 'statSync', path)(resolved);
|
|
144
144
|
if (checkAccess && !hasAccess(this, stats, constants.R_OK))
|
|
145
145
|
throw UV('EACCES', { syscall: 'lstat', path });
|
|
146
|
-
return
|
|
146
|
+
return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
|
|
147
147
|
}
|
|
148
148
|
lstatSync;
|
|
149
149
|
export function truncateSync(path, len = 0) {
|
|
150
150
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
151
151
|
try {
|
|
152
152
|
const file = __addDisposableResource(env_1, _openSync.call(this, path, { flag: 'r+' }), false);
|
|
153
|
-
len
|
|
153
|
+
len ||= 0;
|
|
154
154
|
if (len < 0)
|
|
155
155
|
throw UV('EINVAL', 'truncate', path.toString());
|
|
156
156
|
file.truncate(len);
|
|
@@ -180,7 +180,6 @@ export function unlinkSync(path) {
|
|
|
180
180
|
}
|
|
181
181
|
unlinkSync;
|
|
182
182
|
function _openSync(path, opt) {
|
|
183
|
-
var _a;
|
|
184
183
|
path = normalizePath(path);
|
|
185
184
|
const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
|
|
186
185
|
path = opt.preserveSymlinks ? path : realpathSync.call(this, path);
|
|
@@ -209,7 +208,7 @@ function _openSync(path, opt) {
|
|
|
209
208
|
if (checkAccess && !hasAccess(this, parentStats, constants.W_OK)) {
|
|
210
209
|
throw UV('EACCES', 'open', path);
|
|
211
210
|
}
|
|
212
|
-
const { euid: uid, egid: gid } =
|
|
211
|
+
const { euid: uid, egid: gid } = this?.credentials ?? defaultContext.credentials;
|
|
213
212
|
const inode = fs.createFileSync(resolved, {
|
|
214
213
|
mode,
|
|
215
214
|
uid: parentStats.mode & constants.S_ISUID ? parentStats.uid : uid,
|
|
@@ -339,7 +338,7 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
339
338
|
appendFileSync;
|
|
340
339
|
export function fstatSync(fd, options) {
|
|
341
340
|
const stats = fromFD(this, fd).stat();
|
|
342
|
-
return
|
|
341
|
+
return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
|
|
343
342
|
}
|
|
344
343
|
fstatSync;
|
|
345
344
|
export function closeSync(fd) {
|
|
@@ -348,7 +347,7 @@ export function closeSync(fd) {
|
|
|
348
347
|
}
|
|
349
348
|
closeSync;
|
|
350
349
|
export function ftruncateSync(fd, len = 0) {
|
|
351
|
-
len
|
|
350
|
+
len ||= 0;
|
|
352
351
|
if (len < 0) {
|
|
353
352
|
throw new Exception(Errno.EINVAL);
|
|
354
353
|
}
|
|
@@ -381,7 +380,7 @@ export function writeSync(fd, data, posOrOff, lenOrEnc, pos) {
|
|
|
381
380
|
position = typeof pos === 'number' ? pos : null;
|
|
382
381
|
}
|
|
383
382
|
const file = fromFD(this, fd);
|
|
384
|
-
position
|
|
383
|
+
position ??= file.position;
|
|
385
384
|
const bytesWritten = file.write(buffer, offset, length, position);
|
|
386
385
|
emitChange(this, 'change', file.path);
|
|
387
386
|
return bytesWritten;
|
|
@@ -441,10 +440,9 @@ export function rmdirSync(path) {
|
|
|
441
440
|
}
|
|
442
441
|
rmdirSync;
|
|
443
442
|
export function mkdirSync(path, options) {
|
|
444
|
-
|
|
445
|
-
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
|
|
443
|
+
const { euid: uid, egid: gid } = this?.credentials ?? defaultContext.credentials;
|
|
446
444
|
options = typeof options === 'object' ? options : { mode: options };
|
|
447
|
-
const mode = normalizeMode(options
|
|
445
|
+
const mode = normalizeMode(options?.mode, 0o777);
|
|
448
446
|
path = realpathSync.call(this, path);
|
|
449
447
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
450
448
|
const __create = (path, resolved, parent) => {
|
|
@@ -458,7 +456,7 @@ export function mkdirSync(path, options) {
|
|
|
458
456
|
emitChange(this, 'rename', path);
|
|
459
457
|
return inode;
|
|
460
458
|
};
|
|
461
|
-
if (!
|
|
459
|
+
if (!options?.recursive) {
|
|
462
460
|
__create(path, resolved, wrap(fs, 'statSync', dirname(path))(dirname(resolved)));
|
|
463
461
|
return;
|
|
464
462
|
}
|
|
@@ -495,16 +493,16 @@ export function readdirSync(path, options) {
|
|
|
495
493
|
catch {
|
|
496
494
|
continue;
|
|
497
495
|
}
|
|
498
|
-
if (options
|
|
499
|
-
values.push(new Dirent(entry, entryStat));
|
|
496
|
+
if (options?.withFileTypes) {
|
|
497
|
+
values.push(new Dirent(entry, entryStat, options.encoding));
|
|
500
498
|
}
|
|
501
|
-
else if (
|
|
499
|
+
else if (options?.encoding == 'buffer') {
|
|
502
500
|
values.push(Buffer.from(entry));
|
|
503
501
|
}
|
|
504
502
|
else {
|
|
505
503
|
values.push(entry);
|
|
506
504
|
}
|
|
507
|
-
if (!isDirectory(entryStat) || !
|
|
505
|
+
if (!isDirectory(entryStat) || !options?.recursive)
|
|
508
506
|
continue;
|
|
509
507
|
for (const subEntry of readdirSync.call(this, join(path, entry), options)) {
|
|
510
508
|
if (subEntry instanceof Dirent) {
|
|
@@ -576,12 +574,12 @@ export function readlinkSync(path, options) {
|
|
|
576
574
|
const size = handle.inode.size;
|
|
577
575
|
const data = Buffer.alloc(size);
|
|
578
576
|
handle.read(data, 0, size, 0);
|
|
579
|
-
const encoding = typeof options == 'object' ? options
|
|
577
|
+
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
580
578
|
if (encoding == 'buffer') {
|
|
581
579
|
return data;
|
|
582
580
|
}
|
|
583
581
|
// always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
|
|
584
|
-
return data.toString(encoding
|
|
582
|
+
return data.toString(encoding ?? 'utf-8');
|
|
585
583
|
}
|
|
586
584
|
catch (e_6) {
|
|
587
585
|
env_6.error = e_6;
|
|
@@ -680,8 +678,7 @@ function _resolveSync($, path, preserveSymlinks) {
|
|
|
680
678
|
return _resolveSync($, target);
|
|
681
679
|
}
|
|
682
680
|
export function realpathSync(path, options) {
|
|
683
|
-
|
|
684
|
-
const encoding = typeof options == 'string' ? options : ((_a = options === null || options === void 0 ? void 0 : options.encoding) !== null && _a !== void 0 ? _a : 'utf8');
|
|
681
|
+
const encoding = typeof options == 'string' ? options : (options?.encoding ?? 'utf8');
|
|
685
682
|
path = normalizePath(path);
|
|
686
683
|
const { fullPath } = _resolveSync(this, path);
|
|
687
684
|
if (encoding == 'utf8' || encoding == 'utf-8')
|
|
@@ -711,14 +708,14 @@ export function rmSync(path, options) {
|
|
|
711
708
|
stats = lstatSync.bind(this)(path);
|
|
712
709
|
}
|
|
713
710
|
catch (error) {
|
|
714
|
-
if (error.code != 'ENOENT' || !
|
|
711
|
+
if (error.code != 'ENOENT' || !options?.force)
|
|
715
712
|
throw error;
|
|
716
713
|
}
|
|
717
714
|
if (!stats)
|
|
718
715
|
return;
|
|
719
716
|
switch (stats.mode & constants.S_IFMT) {
|
|
720
717
|
case constants.S_IFDIR:
|
|
721
|
-
if (options
|
|
718
|
+
if (options?.recursive) {
|
|
722
719
|
for (const entry of readdirSync.call(this, path)) {
|
|
723
720
|
rmSync.call(this, join(path, entry), options);
|
|
724
721
|
}
|
|
@@ -739,7 +736,7 @@ export function rmSync(path, options) {
|
|
|
739
736
|
}
|
|
740
737
|
rmSync;
|
|
741
738
|
export function mkdtempSync(prefix, options) {
|
|
742
|
-
const encoding = typeof options === 'object' ? options
|
|
739
|
+
const encoding = typeof options === 'object' ? options?.encoding : options || 'utf8';
|
|
743
740
|
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
744
741
|
const resolvedPath = '/tmp/' + fsName;
|
|
745
742
|
mkdirSync.call(this, resolvedPath);
|
|
@@ -820,11 +817,11 @@ export function cpSync(source, destination, opts) {
|
|
|
820
817
|
source = normalizePath(source);
|
|
821
818
|
destination = normalizePath(destination);
|
|
822
819
|
const srcStats = lstatSync.call(this, source); // Use lstat to follow symlinks if not dereferencing
|
|
823
|
-
if (
|
|
820
|
+
if (opts?.errorOnExist && existsSync.call(this, destination))
|
|
824
821
|
throw UV('EEXIST', 'cp', destination);
|
|
825
822
|
switch (srcStats.mode & constants.S_IFMT) {
|
|
826
823
|
case constants.S_IFDIR:
|
|
827
|
-
if (!
|
|
824
|
+
if (!opts?.recursive)
|
|
828
825
|
throw UV('EISDIR', 'cp', source);
|
|
829
826
|
mkdirSync.call(this, destination, { recursive: true }); // Ensure the destination directory exists
|
|
830
827
|
for (const dirent of readdirSync.call(this, source, { withFileTypes: true })) {
|
|
@@ -846,7 +843,7 @@ export function cpSync(source, destination, opts) {
|
|
|
846
843
|
throw UV('ENOSYS', 'cp', source);
|
|
847
844
|
}
|
|
848
845
|
// Optionally preserve timestamps
|
|
849
|
-
if (opts
|
|
846
|
+
if (opts?.preserveTimestamps) {
|
|
850
847
|
utimesSync.call(this, destination, srcStats.atime, srcStats.mtime);
|
|
851
848
|
}
|
|
852
849
|
}
|
|
@@ -854,7 +851,7 @@ cpSync;
|
|
|
854
851
|
export function statfsSync(path, options) {
|
|
855
852
|
path = normalizePath(path);
|
|
856
853
|
const { fs } = resolveMount(path, this);
|
|
857
|
-
return _statfs(fs, options
|
|
854
|
+
return _statfs(fs, options?.bigint);
|
|
858
855
|
}
|
|
859
856
|
export function globSync(pattern, options = {}) {
|
|
860
857
|
pattern = Array.isArray(pattern) ? pattern : [pattern];
|
package/dist/vfs/types.d.ts
CHANGED
|
@@ -15,15 +15,10 @@ export interface OpenOptions {
|
|
|
15
15
|
*/
|
|
16
16
|
allowDirectory?: boolean;
|
|
17
17
|
}
|
|
18
|
-
export
|
|
18
|
+
export type ReaddirOptions = {
|
|
19
19
|
withFileTypes?: boolean;
|
|
20
20
|
recursive?: boolean;
|
|
21
|
-
|
|
21
|
+
encoding?: BufferEncoding | 'buffer' | null;
|
|
22
|
+
} | BufferEncoding | 'buffer' | null;
|
|
22
23
|
/** Helper union @hidden */
|
|
23
24
|
export type GlobOptionsU = fs.GlobOptionsWithFileTypes | fs.GlobOptionsWithoutFileTypes | fs.GlobOptions;
|
|
24
|
-
/** Helper with union @hidden */
|
|
25
|
-
export type ReaddirOptsU<T> = (ReaddirOptions & (fs.ObjectEncodingOptions | T)) | NullEnc;
|
|
26
|
-
/** Helper with intersection @hidden */
|
|
27
|
-
export type ReaddirOptsI<T> = ReaddirOptions & fs.ObjectEncodingOptions & T;
|
|
28
|
-
/** @hidden */
|
|
29
|
-
export type NullEnc = BufferEncoding | null;
|
package/dist/vfs/watchers.js
CHANGED
|
@@ -11,6 +11,8 @@ import { statSync } from './sync.js';
|
|
|
11
11
|
* @template TEvents The type of events emitted by the watcher.
|
|
12
12
|
*/
|
|
13
13
|
class Watcher extends EventEmitter {
|
|
14
|
+
_context;
|
|
15
|
+
path;
|
|
14
16
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
15
17
|
off(event, fn, context, once) {
|
|
16
18
|
return super.off(event, fn, context, once);
|
|
@@ -56,10 +58,12 @@ class Watcher extends EventEmitter {
|
|
|
56
58
|
* @template T The type of the filename, either `string` or `Buffer`.
|
|
57
59
|
*/
|
|
58
60
|
export class FSWatcher extends Watcher {
|
|
61
|
+
options;
|
|
62
|
+
realpath;
|
|
59
63
|
constructor(context, path, options) {
|
|
60
64
|
super(context, path);
|
|
61
65
|
this.options = options;
|
|
62
|
-
this.realpath =
|
|
66
|
+
this.realpath = context?.root ? join(context.root, path) : path;
|
|
63
67
|
addWatcher(this.realpath, this);
|
|
64
68
|
}
|
|
65
69
|
close() {
|
|
@@ -76,6 +80,9 @@ export class FSWatcher extends Watcher {
|
|
|
76
80
|
* Instances of `StatWatcher` are used by `fs.watchFile()` to monitor changes to a file's statistics.
|
|
77
81
|
*/
|
|
78
82
|
export class StatWatcher extends Watcher {
|
|
83
|
+
options;
|
|
84
|
+
intervalId;
|
|
85
|
+
previous;
|
|
79
86
|
constructor(context, path, options) {
|
|
80
87
|
super(context, path);
|
|
81
88
|
this.options = options;
|
|
@@ -139,9 +146,8 @@ export function removeWatcher(path, watcher) {
|
|
|
139
146
|
* @internal @hidden
|
|
140
147
|
*/
|
|
141
148
|
export function emitChange($, eventType, filename) {
|
|
142
|
-
var _a;
|
|
143
149
|
if ($)
|
|
144
|
-
filename = join(
|
|
150
|
+
filename = join($.root ?? '/', filename);
|
|
145
151
|
filename = normalizePath(filename);
|
|
146
152
|
// Notify watchers, including ones on parent directories if they are watching recursively
|
|
147
153
|
for (let path = filename; path != '/'; path = dirname(path)) {
|