@zenfs/core 1.11.3 → 2.0.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.d.ts +19 -15
- package/dist/backends/backend.js +31 -15
- package/dist/backends/cow.d.ts +20 -30
- package/dist/backends/cow.js +52 -142
- package/dist/backends/fetch.d.ts +1 -0
- package/dist/backends/fetch.js +3 -1
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.js +1 -1
- package/dist/backends/memory.d.ts +5 -7
- package/dist/backends/memory.js +2 -3
- package/dist/backends/passthrough.d.ts +19 -22
- package/dist/backends/passthrough.js +85 -160
- package/dist/backends/port.d.ts +207 -0
- package/dist/backends/port.js +297 -0
- package/dist/backends/single_buffer.d.ts +11 -5
- package/dist/backends/single_buffer.js +18 -12
- package/dist/backends/store/fs.d.ts +11 -27
- package/dist/backends/store/fs.js +67 -91
- package/dist/backends/store/store.d.ts +7 -12
- package/dist/config.d.ts +1 -10
- package/dist/config.js +7 -8
- package/dist/context.d.ts +8 -21
- package/dist/context.js +33 -10
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/contexts.d.ts +63 -0
- package/dist/internal/contexts.js +15 -0
- package/dist/internal/credentials.d.ts +2 -11
- package/dist/internal/credentials.js +0 -19
- package/dist/internal/devices.d.ts +18 -80
- package/dist/internal/devices.js +76 -279
- package/dist/internal/file_index.js +3 -3
- package/dist/internal/filesystem.d.ts +31 -89
- package/dist/internal/filesystem.js +21 -20
- package/dist/internal/index.d.ts +0 -1
- package/dist/internal/index.js +0 -1
- package/dist/internal/index_fs.d.ts +12 -30
- package/dist/internal/index_fs.js +23 -55
- package/dist/internal/inode.d.ts +147 -9
- package/dist/internal/inode.js +333 -25
- package/dist/internal/log.d.ts +19 -13
- package/dist/internal/log.js +81 -80
- package/dist/mixins/async.js +26 -90
- package/dist/mixins/mutexed.d.ts +17 -16
- package/dist/mixins/mutexed.js +29 -31
- package/dist/mixins/readonly.d.ts +7 -6
- package/dist/mixins/readonly.js +6 -0
- package/dist/mixins/sync.js +8 -8
- package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
- package/dist/{vfs/path.js → path.js} +6 -9
- package/dist/readline.d.ts +134 -0
- package/dist/readline.js +623 -0
- package/dist/utils.d.ts +4 -35
- package/dist/utils.js +8 -73
- package/dist/vfs/acl.d.ts +42 -0
- package/dist/vfs/acl.js +249 -0
- package/dist/vfs/async.d.ts +7 -21
- package/dist/vfs/async.js +19 -19
- package/dist/vfs/config.d.ts +6 -18
- package/dist/vfs/config.js +8 -18
- package/dist/vfs/dir.d.ts +3 -3
- package/dist/vfs/dir.js +9 -8
- package/dist/vfs/file.d.ts +106 -0
- package/dist/vfs/file.js +235 -0
- package/dist/vfs/flags.d.ts +19 -0
- package/dist/vfs/flags.js +62 -0
- package/dist/vfs/index.d.ts +4 -10
- package/dist/vfs/index.js +4 -13
- package/dist/vfs/ioctl.d.ts +87 -0
- package/dist/vfs/ioctl.js +304 -0
- package/dist/vfs/promises.d.ts +78 -16
- package/dist/vfs/promises.js +273 -122
- package/dist/vfs/shared.d.ts +7 -26
- package/dist/vfs/shared.js +25 -53
- package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
- package/dist/{stats.js → vfs/stats.js} +11 -66
- package/dist/vfs/streams.d.ts +1 -0
- package/dist/vfs/streams.js +24 -19
- package/dist/vfs/sync.d.ts +4 -3
- package/dist/vfs/sync.js +143 -128
- package/dist/vfs/watchers.d.ts +2 -2
- package/dist/vfs/watchers.js +6 -6
- package/dist/vfs/xattr.d.ts +116 -0
- package/dist/vfs/xattr.js +218 -0
- package/package.json +3 -3
- package/readme.md +1 -1
- package/tests/backend/config.worker.js +4 -1
- package/tests/backend/fetch.test.ts +3 -0
- package/tests/backend/port.test.ts +21 -35
- package/tests/backend/remote.worker.js +4 -1
- package/tests/backend/single-buffer.test.ts +24 -0
- package/tests/common/context.test.ts +1 -1
- package/tests/common/handle.test.ts +17 -12
- package/tests/common/path.test.ts +1 -1
- package/tests/common/readline.test.ts +104 -0
- package/tests/common.ts +4 -19
- package/tests/fetch/fetch.ts +1 -1
- package/tests/fs/links.test.ts +1 -1
- package/tests/fs/permissions.test.ts +7 -6
- package/tests/fs/readFile.test.ts +3 -3
- package/tests/fs/stat.test.ts +6 -6
- package/tests/fs/streams.test.ts +2 -11
- package/tests/fs/times.test.ts +1 -1
- package/tests/fs/xattr.test.ts +85 -0
- package/tests/logs.js +22 -0
- package/tests/setup/context.ts +1 -1
- package/tests/setup/index.ts +3 -3
- package/tests/setup/port.ts +1 -1
- package/dist/backends/port/fs.d.ts +0 -84
- package/dist/backends/port/fs.js +0 -151
- package/dist/backends/port/rpc.d.ts +0 -77
- package/dist/backends/port/rpc.js +0 -100
- package/dist/backends/store/simple.d.ts +0 -20
- package/dist/backends/store/simple.js +0 -13
- package/dist/internal/file.d.ts +0 -351
- package/dist/internal/file.js +0 -739
package/dist/vfs/sync.js
CHANGED
|
@@ -50,24 +50,28 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
+
import { deleteFD, fromFD, SyncHandle, toFD } from './file.js';
|
|
54
|
+
import { Stats } from './stats.js';
|
|
53
55
|
import { Buffer } from 'buffer';
|
|
54
|
-
import {
|
|
56
|
+
import { decodeUTF8, encodeUTF8 } from 'utilium';
|
|
57
|
+
import { defaultContext } from '../internal/contexts.js';
|
|
55
58
|
import { Errno, ErrnoError } from '../internal/error.js';
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
59
|
+
import { hasAccess, isDirectory, isSymbolicLink } from '../internal/inode.js';
|
|
60
|
+
import { dirname, join, parse, resolve } from '../path.js';
|
|
61
|
+
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
62
|
+
import { checkAccess } from './config.js';
|
|
60
63
|
import * as constants from './constants.js';
|
|
61
64
|
import { Dir, Dirent } from './dir.js';
|
|
62
|
-
import
|
|
63
|
-
import { _statfs,
|
|
65
|
+
import * as flags from './flags.js';
|
|
66
|
+
import { _statfs, fixError, resolveMount } from './shared.js';
|
|
67
|
+
import { BigIntStats } from './stats.js';
|
|
64
68
|
import { emitChange } from './watchers.js';
|
|
65
69
|
export function renameSync(oldPath, newPath) {
|
|
66
70
|
oldPath = normalizePath(oldPath);
|
|
67
71
|
newPath = normalizePath(newPath);
|
|
68
72
|
const oldMount = resolveMount(oldPath, this);
|
|
69
73
|
const newMount = resolveMount(newPath, this);
|
|
70
|
-
if (
|
|
74
|
+
if (checkAccess && !statSync.call(this, dirname(oldPath)).hasAccess(constants.W_OK, this)) {
|
|
71
75
|
throw ErrnoError.With('EACCES', oldPath, 'rename');
|
|
72
76
|
}
|
|
73
77
|
try {
|
|
@@ -108,10 +112,10 @@ export function statSync(path, options) {
|
|
|
108
112
|
const { fs, path: resolved } = resolveMount(realpathSync.call(this, path), this);
|
|
109
113
|
try {
|
|
110
114
|
const stats = fs.statSync(resolved);
|
|
111
|
-
if (
|
|
115
|
+
if (checkAccess && !hasAccess(this, stats, constants.R_OK)) {
|
|
112
116
|
throw ErrnoError.With('EACCES', resolved, 'stat');
|
|
113
117
|
}
|
|
114
|
-
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
|
|
118
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
|
|
115
119
|
}
|
|
116
120
|
catch (e) {
|
|
117
121
|
throw fixError(e, { [resolved]: path });
|
|
@@ -123,7 +127,10 @@ export function lstatSync(path, options) {
|
|
|
123
127
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
124
128
|
try {
|
|
125
129
|
const stats = fs.statSync(resolved);
|
|
126
|
-
|
|
130
|
+
if (checkAccess && !hasAccess(this, stats, constants.R_OK)) {
|
|
131
|
+
throw ErrnoError.With('EACCES', resolved, 'lstat');
|
|
132
|
+
}
|
|
133
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
|
|
127
134
|
}
|
|
128
135
|
catch (e) {
|
|
129
136
|
throw fixError(e, { [resolved]: path });
|
|
@@ -138,7 +145,7 @@ export function truncateSync(path, len = 0) {
|
|
|
138
145
|
if (len < 0) {
|
|
139
146
|
throw new ErrnoError(Errno.EINVAL);
|
|
140
147
|
}
|
|
141
|
-
file.
|
|
148
|
+
file.truncate(len);
|
|
142
149
|
}
|
|
143
150
|
catch (e_1) {
|
|
144
151
|
env_1.error = e_1;
|
|
@@ -153,7 +160,7 @@ export function unlinkSync(path) {
|
|
|
153
160
|
path = normalizePath(path);
|
|
154
161
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
155
162
|
try {
|
|
156
|
-
if (
|
|
163
|
+
if (checkAccess && !hasAccess(this, fs.statSync(resolved), constants.W_OK)) {
|
|
157
164
|
throw ErrnoError.With('EACCES', resolved, 'unlink');
|
|
158
165
|
}
|
|
159
166
|
fs.unlinkSync(resolved);
|
|
@@ -164,20 +171,10 @@ export function unlinkSync(path) {
|
|
|
164
171
|
}
|
|
165
172
|
}
|
|
166
173
|
unlinkSync;
|
|
167
|
-
/**
|
|
168
|
-
* Manually apply setuid/setgid.
|
|
169
|
-
*/
|
|
170
|
-
function applySetId(file, uid, gid) {
|
|
171
|
-
if (file.fs.attributes.has('setid'))
|
|
172
|
-
return;
|
|
173
|
-
const parent = file.fs.statSync(dirname(file.path));
|
|
174
|
-
file.chownSync(parent.mode & constants.S_ISUID ? parent.uid : uid, // manually apply setuid/setgid
|
|
175
|
-
parent.mode & constants.S_ISGID ? parent.gid : gid);
|
|
176
|
-
}
|
|
177
174
|
function _openSync(path, opt) {
|
|
178
175
|
var _a;
|
|
179
176
|
path = normalizePath(path);
|
|
180
|
-
const mode = normalizeMode(opt.mode, 0o644), flag =
|
|
177
|
+
const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
|
|
181
178
|
path = opt.preserveSymlinks ? path : realpathSync.call(this, path);
|
|
182
179
|
const { fs, path: resolved } = resolveMount(path, this);
|
|
183
180
|
let stats;
|
|
@@ -188,44 +185,49 @@ function _openSync(path, opt) {
|
|
|
188
185
|
// nothing
|
|
189
186
|
}
|
|
190
187
|
if (!stats) {
|
|
191
|
-
if (
|
|
188
|
+
if (!(flag & constants.O_CREAT)) {
|
|
192
189
|
throw ErrnoError.With('ENOENT', path, '_open');
|
|
193
190
|
}
|
|
194
191
|
// Create the file
|
|
195
192
|
const parentStats = fs.statSync(dirname(resolved));
|
|
196
|
-
if (
|
|
193
|
+
if (checkAccess && !hasAccess(this, parentStats, constants.W_OK)) {
|
|
197
194
|
throw ErrnoError.With('EACCES', dirname(path), '_open');
|
|
198
195
|
}
|
|
199
|
-
if (!
|
|
196
|
+
if (!isDirectory(parentStats)) {
|
|
200
197
|
throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
|
|
201
198
|
}
|
|
202
|
-
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : credentials;
|
|
203
|
-
const file = fs.createFileSync(resolved, flag, mode, { uid, gid });
|
|
204
199
|
if (!opt.allowDirectory && mode & constants.S_IFDIR)
|
|
205
200
|
throw ErrnoError.With('EISDIR', path, '_open');
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
201
|
+
if (checkAccess && !hasAccess(this, parentStats, constants.W_OK)) {
|
|
202
|
+
throw ErrnoError.With('EACCES', dirname(resolved), '_open');
|
|
203
|
+
}
|
|
204
|
+
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
|
|
205
|
+
const inode = fs.createFileSync(resolved, {
|
|
206
|
+
mode,
|
|
207
|
+
uid: parentStats.mode & constants.S_ISUID ? parentStats.uid : uid,
|
|
208
|
+
gid: parentStats.mode & constants.S_ISGID ? parentStats.gid : gid,
|
|
209
|
+
});
|
|
210
|
+
return new SyncHandle(this, path, fs, resolved, flag, inode);
|
|
211
|
+
}
|
|
212
|
+
if (checkAccess && (!hasAccess(this, stats, mode) || !hasAccess(this, stats, flags.toMode(flag)))) {
|
|
210
213
|
throw ErrnoError.With('EACCES', path, '_open');
|
|
211
214
|
}
|
|
212
|
-
if (
|
|
215
|
+
if (flag & constants.O_EXCL)
|
|
213
216
|
throw ErrnoError.With('EEXIST', path, '_open');
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
file.truncateSync(0);
|
|
218
|
-
}
|
|
217
|
+
const file = new SyncHandle(this, path, fs, resolved, flag, stats);
|
|
218
|
+
if (flag & constants.O_TRUNC)
|
|
219
|
+
file.truncate(0);
|
|
219
220
|
if (!opt.allowDirectory && stats.mode & constants.S_IFDIR)
|
|
220
221
|
throw ErrnoError.With('EISDIR', path, '_open');
|
|
221
222
|
return file;
|
|
222
223
|
}
|
|
223
224
|
/**
|
|
224
225
|
* Synchronous file open.
|
|
225
|
-
* @see
|
|
226
|
+
* @see https://nodejs.org/api/fs.html#fsopensyncpath-flags-mode
|
|
227
|
+
* @param flag {@link https://nodejs.org/api/fs.html#file-system-flags}
|
|
226
228
|
*/
|
|
227
229
|
export function openSync(path, flag, mode = constants.F_OK) {
|
|
228
|
-
return
|
|
230
|
+
return toFD(_openSync.call(this, path, { flag, mode }));
|
|
229
231
|
}
|
|
230
232
|
openSync;
|
|
231
233
|
/**
|
|
@@ -233,18 +235,15 @@ openSync;
|
|
|
233
235
|
* @internal
|
|
234
236
|
*/
|
|
235
237
|
export function lopenSync(path, flag, mode) {
|
|
236
|
-
return
|
|
238
|
+
return toFD(_openSync.call(this, path, { flag, mode, preserveSymlinks: true }));
|
|
237
239
|
}
|
|
238
240
|
function _readFileSync(path, flag, preserveSymlinks) {
|
|
239
241
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
240
242
|
try {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
// Allocate buffer.
|
|
246
|
-
const data = new Uint8Array(stat.size);
|
|
247
|
-
file.readSync(data, 0, stat.size, 0);
|
|
243
|
+
const file = __addDisposableResource(env_2, typeof path == 'number' ? fromFD(this, path) : _openSync.call(this, path.toString(), { flag, mode: 0o644, preserveSymlinks }), false);
|
|
244
|
+
const { size } = file.stat();
|
|
245
|
+
const data = new Uint8Array(size);
|
|
246
|
+
file.read(data, 0, size, 0);
|
|
248
247
|
return data;
|
|
249
248
|
}
|
|
250
249
|
catch (e_2) {
|
|
@@ -257,11 +256,11 @@ function _readFileSync(path, flag, preserveSymlinks) {
|
|
|
257
256
|
}
|
|
258
257
|
export function readFileSync(path, _options = {}) {
|
|
259
258
|
const options = normalizeOptions(_options, null, 'r', 0o644);
|
|
260
|
-
const flag =
|
|
261
|
-
if (
|
|
259
|
+
const flag = flags.parse(options.flag);
|
|
260
|
+
if (flag & constants.O_WRONLY) {
|
|
262
261
|
throw new ErrnoError(Errno.EINVAL, 'Flag passed to readFile must allow for reading');
|
|
263
262
|
}
|
|
264
|
-
const data = Buffer.from(_readFileSync.call(this,
|
|
263
|
+
const data = Buffer.from(_readFileSync.call(this, path, options.flag, false));
|
|
265
264
|
return options.encoding ? data.toString(options.encoding) : data;
|
|
266
265
|
}
|
|
267
266
|
readFileSync;
|
|
@@ -269,8 +268,8 @@ export function writeFileSync(path, data, _options = {}) {
|
|
|
269
268
|
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
270
269
|
try {
|
|
271
270
|
const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
|
|
272
|
-
const flag =
|
|
273
|
-
if (!
|
|
271
|
+
const flag = flags.parse(options.flag);
|
|
272
|
+
if (!(flag & constants.O_WRONLY || flag & constants.O_RDWR)) {
|
|
274
273
|
throw new ErrnoError(Errno.EINVAL, 'Flag passed to writeFile must allow for writing');
|
|
275
274
|
}
|
|
276
275
|
if (typeof data != 'string' && !options.encoding) {
|
|
@@ -280,12 +279,14 @@ export function writeFileSync(path, data, _options = {}) {
|
|
|
280
279
|
if (!encodedData) {
|
|
281
280
|
throw new ErrnoError(Errno.EINVAL, 'Data not specified');
|
|
282
281
|
}
|
|
283
|
-
const file = __addDisposableResource(env_3,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
282
|
+
const file = __addDisposableResource(env_3, typeof path == 'number'
|
|
283
|
+
? fromFD(this, path)
|
|
284
|
+
: _openSync.call(this, path.toString(), {
|
|
285
|
+
flag,
|
|
286
|
+
mode: options.mode,
|
|
287
|
+
preserveSymlinks: true,
|
|
288
|
+
}), false);
|
|
289
|
+
file.write(encodedData, 0, encodedData.byteLength, 0);
|
|
289
290
|
emitChange(this, 'change', path.toString());
|
|
290
291
|
}
|
|
291
292
|
catch (e_3) {
|
|
@@ -307,20 +308,20 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
307
308
|
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
308
309
|
try {
|
|
309
310
|
const options = normalizeOptions(_options, 'utf8', 'a+', 0o644);
|
|
310
|
-
const flag =
|
|
311
|
-
if (!
|
|
311
|
+
const flag = flags.parse(options.flag);
|
|
312
|
+
if (!(flag & constants.O_APPEND)) {
|
|
312
313
|
throw new ErrnoError(Errno.EINVAL, 'Flag passed to appendFile must allow for appending');
|
|
313
314
|
}
|
|
314
315
|
if (typeof data != 'string' && !options.encoding) {
|
|
315
316
|
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
316
317
|
}
|
|
317
318
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
318
|
-
const file = __addDisposableResource(env_4, _openSync.call(this, typeof filename == 'number' ?
|
|
319
|
+
const file = __addDisposableResource(env_4, _openSync.call(this, typeof filename == 'number' ? fromFD(this, filename).path : filename.toString(), {
|
|
319
320
|
flag,
|
|
320
321
|
mode: options.mode,
|
|
321
322
|
preserveSymlinks: true,
|
|
322
323
|
}), false);
|
|
323
|
-
file.
|
|
324
|
+
file.write(encodedData, 0, encodedData.byteLength);
|
|
324
325
|
}
|
|
325
326
|
catch (e_4) {
|
|
326
327
|
env_4.error = e_4;
|
|
@@ -332,13 +333,13 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
332
333
|
}
|
|
333
334
|
appendFileSync;
|
|
334
335
|
export function fstatSync(fd, options) {
|
|
335
|
-
const stats =
|
|
336
|
-
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
|
|
336
|
+
const stats = fromFD(this, fd).stat();
|
|
337
|
+
return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
|
|
337
338
|
}
|
|
338
339
|
fstatSync;
|
|
339
340
|
export function closeSync(fd) {
|
|
340
|
-
|
|
341
|
-
|
|
341
|
+
fromFD(this, fd).close();
|
|
342
|
+
deleteFD(this, fd);
|
|
342
343
|
}
|
|
343
344
|
closeSync;
|
|
344
345
|
export function ftruncateSync(fd, len = 0) {
|
|
@@ -346,15 +347,15 @@ export function ftruncateSync(fd, len = 0) {
|
|
|
346
347
|
if (len < 0) {
|
|
347
348
|
throw new ErrnoError(Errno.EINVAL);
|
|
348
349
|
}
|
|
349
|
-
|
|
350
|
+
fromFD(this, fd).truncate(len);
|
|
350
351
|
}
|
|
351
352
|
ftruncateSync;
|
|
352
353
|
export function fsyncSync(fd) {
|
|
353
|
-
|
|
354
|
+
fromFD(this, fd).sync();
|
|
354
355
|
}
|
|
355
356
|
fsyncSync;
|
|
356
357
|
export function fdatasyncSync(fd) {
|
|
357
|
-
|
|
358
|
+
fromFD(this, fd).datasync();
|
|
358
359
|
}
|
|
359
360
|
fdatasyncSync;
|
|
360
361
|
export function writeSync(fd, data, posOrOff, lenOrEnc, pos) {
|
|
@@ -374,9 +375,9 @@ export function writeSync(fd, data, posOrOff, lenOrEnc, pos) {
|
|
|
374
375
|
length = lenOrEnc;
|
|
375
376
|
position = typeof pos === 'number' ? pos : null;
|
|
376
377
|
}
|
|
377
|
-
const file =
|
|
378
|
+
const file = fromFD(this, fd);
|
|
378
379
|
position !== null && position !== void 0 ? position : (position = file.position);
|
|
379
|
-
const bytesWritten = file.
|
|
380
|
+
const bytesWritten = file.write(buffer, offset, length, position);
|
|
380
381
|
emitChange(this, 'change', file.path);
|
|
381
382
|
return bytesWritten;
|
|
382
383
|
}
|
|
@@ -390,7 +391,7 @@ writeSync;
|
|
|
390
391
|
* If position is null, data will be read from the current file position.
|
|
391
392
|
*/
|
|
392
393
|
export function readSync(fd, buffer, options, length, position) {
|
|
393
|
-
const file =
|
|
394
|
+
const file = fromFD(this, fd);
|
|
394
395
|
const offset = typeof options == 'object' ? options.offset : options;
|
|
395
396
|
if (typeof options == 'object') {
|
|
396
397
|
length = options.length;
|
|
@@ -400,11 +401,11 @@ export function readSync(fd, buffer, options, length, position) {
|
|
|
400
401
|
if (isNaN(position)) {
|
|
401
402
|
position = file.position;
|
|
402
403
|
}
|
|
403
|
-
return file.
|
|
404
|
+
return file.read(buffer, offset, length, position);
|
|
404
405
|
}
|
|
405
406
|
readSync;
|
|
406
407
|
export function fchownSync(fd, uid, gid) {
|
|
407
|
-
|
|
408
|
+
fromFD(this, fd).chown(uid, gid);
|
|
408
409
|
}
|
|
409
410
|
fchownSync;
|
|
410
411
|
export function fchmodSync(fd, mode) {
|
|
@@ -412,14 +413,14 @@ export function fchmodSync(fd, mode) {
|
|
|
412
413
|
if (numMode < 0) {
|
|
413
414
|
throw new ErrnoError(Errno.EINVAL, `Invalid mode.`);
|
|
414
415
|
}
|
|
415
|
-
|
|
416
|
+
fromFD(this, fd).chmod(numMode);
|
|
416
417
|
}
|
|
417
418
|
fchmodSync;
|
|
418
419
|
/**
|
|
419
420
|
* Change the file timestamps of a file referenced by the supplied file descriptor.
|
|
420
421
|
*/
|
|
421
422
|
export function futimesSync(fd, atime, mtime) {
|
|
422
|
-
|
|
423
|
+
fromFD(this, fd).utimes(normalizeTime(atime), normalizeTime(mtime));
|
|
423
424
|
}
|
|
424
425
|
futimesSync;
|
|
425
426
|
export function rmdirSync(path) {
|
|
@@ -427,10 +428,10 @@ export function rmdirSync(path) {
|
|
|
427
428
|
const { fs, path: resolved } = resolveMount(realpathSync.call(this, path), this);
|
|
428
429
|
try {
|
|
429
430
|
const stats = fs.statSync(resolved);
|
|
430
|
-
if (!
|
|
431
|
+
if (!isDirectory(stats)) {
|
|
431
432
|
throw ErrnoError.With('ENOTDIR', resolved, 'rmdir');
|
|
432
433
|
}
|
|
433
|
-
if (
|
|
434
|
+
if (checkAccess && !hasAccess(this, stats, constants.W_OK)) {
|
|
434
435
|
throw ErrnoError.With('EACCES', resolved, 'rmdir');
|
|
435
436
|
}
|
|
436
437
|
fs.rmdirSync(resolved);
|
|
@@ -443,19 +444,27 @@ export function rmdirSync(path) {
|
|
|
443
444
|
rmdirSync;
|
|
444
445
|
export function mkdirSync(path, options) {
|
|
445
446
|
var _a, _b;
|
|
446
|
-
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : credentials;
|
|
447
|
+
const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
|
|
447
448
|
options = typeof options === 'object' ? options : { mode: options };
|
|
448
449
|
const mode = normalizeMode(options === null || options === void 0 ? void 0 : options.mode, 0o777);
|
|
449
450
|
path = realpathSync.call(this, path);
|
|
450
451
|
const { fs, path: resolved, root } = resolveMount(path, this);
|
|
451
452
|
const errorPaths = { [resolved]: path };
|
|
453
|
+
const __create = (path, parent) => {
|
|
454
|
+
if (checkAccess && !hasAccess(this, parent, constants.W_OK)) {
|
|
455
|
+
throw ErrnoError.With('EACCES', dirname(path), 'mkdir');
|
|
456
|
+
}
|
|
457
|
+
const inode = fs.mkdirSync(path, {
|
|
458
|
+
mode,
|
|
459
|
+
uid: parent.mode & constants.S_ISUID ? parent.uid : uid,
|
|
460
|
+
gid: parent.mode & constants.S_ISGID ? parent.gid : gid,
|
|
461
|
+
});
|
|
462
|
+
emitChange(this, 'rename', path);
|
|
463
|
+
return inode;
|
|
464
|
+
};
|
|
452
465
|
try {
|
|
453
466
|
if (!(options === null || options === void 0 ? void 0 : options.recursive)) {
|
|
454
|
-
|
|
455
|
-
throw ErrnoError.With('EACCES', dirname(resolved), 'mkdir');
|
|
456
|
-
}
|
|
457
|
-
fs.mkdirSync(resolved, mode, { uid, gid });
|
|
458
|
-
applySetId(fs.openFileSync(resolved, 'r+'), uid, gid);
|
|
467
|
+
__create(resolved, fs.statSync(dirname(resolved)));
|
|
459
468
|
return;
|
|
460
469
|
}
|
|
461
470
|
const dirs = [];
|
|
@@ -463,13 +472,11 @@ export function mkdirSync(path, options) {
|
|
|
463
472
|
dirs.unshift(dir);
|
|
464
473
|
errorPaths[dir] = original;
|
|
465
474
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
applySetId(fs.openFileSync(dir, 'r+'), uid, gid);
|
|
472
|
-
emitChange(this, 'rename', dir);
|
|
475
|
+
if (!dirs.length)
|
|
476
|
+
return;
|
|
477
|
+
const stats = [fs.statSync(dirname(dirs[0]))];
|
|
478
|
+
for (const [i, dir] of dirs.entries()) {
|
|
479
|
+
stats.push(__create(dir, stats[i]));
|
|
473
480
|
}
|
|
474
481
|
return root.length == 1 ? dirs[0] : (_b = dirs[0]) === null || _b === void 0 ? void 0 : _b.slice(root.length);
|
|
475
482
|
}
|
|
@@ -485,10 +492,10 @@ export function readdirSync(path, options) {
|
|
|
485
492
|
let entries;
|
|
486
493
|
try {
|
|
487
494
|
const stats = fs.statSync(resolved);
|
|
488
|
-
if (
|
|
495
|
+
if (checkAccess && !hasAccess(this, stats, constants.R_OK)) {
|
|
489
496
|
throw ErrnoError.With('EACCES', resolved, 'readdir');
|
|
490
497
|
}
|
|
491
|
-
if (!
|
|
498
|
+
if (!isDirectory(stats)) {
|
|
492
499
|
throw ErrnoError.With('ENOTDIR', resolved, 'readdir');
|
|
493
500
|
}
|
|
494
501
|
entries = fs.readdirSync(resolved);
|
|
@@ -515,7 +522,7 @@ export function readdirSync(path, options) {
|
|
|
515
522
|
else {
|
|
516
523
|
values.push(entry);
|
|
517
524
|
}
|
|
518
|
-
if (!
|
|
525
|
+
if (!isDirectory(entryStat) || !(options === null || options === void 0 ? void 0 : options.recursive))
|
|
519
526
|
continue;
|
|
520
527
|
for (const subEntry of readdirSync.call(this, join(path, entry), options)) {
|
|
521
528
|
if (subEntry instanceof Dirent) {
|
|
@@ -535,11 +542,11 @@ export function readdirSync(path, options) {
|
|
|
535
542
|
readdirSync;
|
|
536
543
|
export function linkSync(targetPath, linkPath) {
|
|
537
544
|
targetPath = normalizePath(targetPath);
|
|
538
|
-
if (
|
|
545
|
+
if (checkAccess && !statSync(dirname(targetPath)).hasAccess(constants.R_OK, this)) {
|
|
539
546
|
throw ErrnoError.With('EACCES', dirname(targetPath), 'link');
|
|
540
547
|
}
|
|
541
548
|
linkPath = normalizePath(linkPath);
|
|
542
|
-
if (
|
|
549
|
+
if (checkAccess && !statSync(dirname(linkPath)).hasAccess(constants.W_OK, this)) {
|
|
543
550
|
throw ErrnoError.With('EACCES', dirname(linkPath), 'link');
|
|
544
551
|
}
|
|
545
552
|
const { fs, path } = resolveMount(targetPath, this);
|
|
@@ -548,7 +555,7 @@ export function linkSync(targetPath, linkPath) {
|
|
|
548
555
|
throw ErrnoError.With('EXDEV', linkPath, 'link');
|
|
549
556
|
}
|
|
550
557
|
try {
|
|
551
|
-
if (
|
|
558
|
+
if (checkAccess && !hasAccess(this, fs.statSync(path), constants.R_OK)) {
|
|
552
559
|
throw ErrnoError.With('EACCES', path, 'link');
|
|
553
560
|
}
|
|
554
561
|
return fs.linkSync(path, link.path);
|
|
@@ -565,15 +572,23 @@ linkSync;
|
|
|
565
572
|
* @param type can be either `'dir'` or `'file'` (default is `'file'`)
|
|
566
573
|
*/
|
|
567
574
|
export function symlinkSync(target, path, type = 'file') {
|
|
568
|
-
|
|
569
|
-
|
|
575
|
+
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
576
|
+
try {
|
|
577
|
+
if (!['file', 'dir', 'junction'].includes(type)) {
|
|
578
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid type: ' + type);
|
|
579
|
+
}
|
|
580
|
+
path = normalizePath(path);
|
|
581
|
+
const file = __addDisposableResource(env_5, _openSync.call(this, path, { flag: 'wx', mode: 0o644 }), false);
|
|
582
|
+
file.write(encodeUTF8(normalizePath(target, true)));
|
|
583
|
+
file.chmod(constants.S_IFLNK);
|
|
570
584
|
}
|
|
571
|
-
|
|
572
|
-
|
|
585
|
+
catch (e_5) {
|
|
586
|
+
env_5.error = e_5;
|
|
587
|
+
env_5.hasError = true;
|
|
588
|
+
}
|
|
589
|
+
finally {
|
|
590
|
+
__disposeResources(env_5);
|
|
573
591
|
}
|
|
574
|
-
writeFileSync.call(this, path, normalizePath(target, true));
|
|
575
|
-
const file = _openSync.call(this, path, { flag: 'r+', mode: 0o644, preserveSymlinks: true });
|
|
576
|
-
file.chmodSync(constants.S_IFLNK);
|
|
577
592
|
}
|
|
578
593
|
symlinkSync;
|
|
579
594
|
export function readlinkSync(path, options) {
|
|
@@ -588,26 +603,26 @@ export function readlinkSync(path, options) {
|
|
|
588
603
|
readlinkSync;
|
|
589
604
|
export function chownSync(path, uid, gid) {
|
|
590
605
|
const fd = openSync.call(this, path, 'r+');
|
|
591
|
-
fchownSync(fd, uid, gid);
|
|
592
|
-
closeSync(fd);
|
|
606
|
+
fchownSync.call(this, fd, uid, gid);
|
|
607
|
+
closeSync.call(this, fd);
|
|
593
608
|
}
|
|
594
609
|
chownSync;
|
|
595
610
|
export function lchownSync(path, uid, gid) {
|
|
596
611
|
const fd = lopenSync.call(this, path, 'r+');
|
|
597
|
-
fchownSync(fd, uid, gid);
|
|
598
|
-
closeSync(fd);
|
|
612
|
+
fchownSync.call(this, fd, uid, gid);
|
|
613
|
+
closeSync.call(this, fd);
|
|
599
614
|
}
|
|
600
615
|
lchownSync;
|
|
601
616
|
export function chmodSync(path, mode) {
|
|
602
617
|
const fd = openSync.call(this, path, 'r+');
|
|
603
|
-
fchmodSync(fd, mode);
|
|
604
|
-
closeSync(fd);
|
|
618
|
+
fchmodSync.call(this, fd, mode);
|
|
619
|
+
closeSync.call(this, fd);
|
|
605
620
|
}
|
|
606
621
|
chmodSync;
|
|
607
622
|
export function lchmodSync(path, mode) {
|
|
608
623
|
const fd = lopenSync.call(this, path, 'r+');
|
|
609
|
-
fchmodSync(fd, mode);
|
|
610
|
-
closeSync(fd);
|
|
624
|
+
fchmodSync.call(this, fd, mode);
|
|
625
|
+
closeSync.call(this, fd);
|
|
611
626
|
}
|
|
612
627
|
lchmodSync;
|
|
613
628
|
/**
|
|
@@ -615,8 +630,8 @@ lchmodSync;
|
|
|
615
630
|
*/
|
|
616
631
|
export function utimesSync(path, atime, mtime) {
|
|
617
632
|
const fd = openSync.call(this, path, 'r+');
|
|
618
|
-
futimesSync(fd, atime, mtime);
|
|
619
|
-
closeSync(fd);
|
|
633
|
+
futimesSync.call(this, fd, atime, mtime);
|
|
634
|
+
closeSync.call(this, fd);
|
|
620
635
|
}
|
|
621
636
|
utimesSync;
|
|
622
637
|
/**
|
|
@@ -624,8 +639,8 @@ utimesSync;
|
|
|
624
639
|
*/
|
|
625
640
|
export function lutimesSync(path, atime, mtime) {
|
|
626
641
|
const fd = lopenSync.call(this, path, 'r+');
|
|
627
|
-
futimesSync(fd, atime, mtime);
|
|
628
|
-
closeSync(fd);
|
|
642
|
+
futimesSync.call(this, fd, atime, mtime);
|
|
643
|
+
closeSync.call(this, fd);
|
|
629
644
|
}
|
|
630
645
|
lutimesSync;
|
|
631
646
|
/**
|
|
@@ -645,10 +660,10 @@ function _resolveSync($, path, preserveSymlinks) {
|
|
|
645
660
|
const resolved = resolveMount(path, $);
|
|
646
661
|
// Stat it to make sure it exists
|
|
647
662
|
const stats = resolved.fs.statSync(resolved.path);
|
|
648
|
-
if (!
|
|
663
|
+
if (!isSymbolicLink(stats)) {
|
|
649
664
|
return { ...resolved, fullPath: path, stats };
|
|
650
665
|
}
|
|
651
|
-
const target = resolve(dirname(path), readlinkSync.call($, path).toString());
|
|
666
|
+
const target = resolve.call($, dirname(path), readlinkSync.call($, path).toString());
|
|
652
667
|
return _resolveSync($, target);
|
|
653
668
|
}
|
|
654
669
|
catch {
|
|
@@ -660,10 +675,10 @@ function _resolveSync($, path, preserveSymlinks) {
|
|
|
660
675
|
const resolved = resolveMount(maybePath, $);
|
|
661
676
|
try {
|
|
662
677
|
const stats = resolved.fs.statSync(resolved.path);
|
|
663
|
-
if (!
|
|
678
|
+
if (!isSymbolicLink(stats)) {
|
|
664
679
|
return { ...resolved, fullPath: maybePath, stats };
|
|
665
680
|
}
|
|
666
|
-
const target = resolve(realDir, readlinkSync.call($, maybePath).toString());
|
|
681
|
+
const target = resolve.call($, realDir, readlinkSync.call($, maybePath).toString());
|
|
667
682
|
return _resolveSync($, target);
|
|
668
683
|
}
|
|
669
684
|
catch (e) {
|
|
@@ -687,9 +702,9 @@ export function realpathSync(path, options) {
|
|
|
687
702
|
}
|
|
688
703
|
realpathSync;
|
|
689
704
|
export function accessSync(path, mode = 0o600) {
|
|
690
|
-
if (!
|
|
705
|
+
if (!checkAccess)
|
|
691
706
|
return;
|
|
692
|
-
if (!statSync.call(this, path)
|
|
707
|
+
if (!hasAccess(this, statSync.call(this, path), mode)) {
|
|
693
708
|
throw new ErrnoError(Errno.EACCES);
|
|
694
709
|
}
|
|
695
710
|
}
|
|
@@ -763,10 +778,10 @@ copyFileSync;
|
|
|
763
778
|
* @returns The number of bytes read.
|
|
764
779
|
*/
|
|
765
780
|
export function readvSync(fd, buffers, position) {
|
|
766
|
-
const file =
|
|
781
|
+
const file = fromFD(this, fd);
|
|
767
782
|
let bytesRead = 0;
|
|
768
783
|
for (const buffer of buffers) {
|
|
769
|
-
bytesRead += file.
|
|
784
|
+
bytesRead += file.read(buffer, 0, buffer.byteLength, position + bytesRead);
|
|
770
785
|
}
|
|
771
786
|
return bytesRead;
|
|
772
787
|
}
|
|
@@ -779,10 +794,10 @@ readvSync;
|
|
|
779
794
|
* @returns The number of bytes written.
|
|
780
795
|
*/
|
|
781
796
|
export function writevSync(fd, buffers, position) {
|
|
782
|
-
const file =
|
|
797
|
+
const file = fromFD(this, fd);
|
|
783
798
|
let bytesWritten = 0;
|
|
784
799
|
for (const buffer of buffers) {
|
|
785
|
-
bytesWritten += file.
|
|
800
|
+
bytesWritten += file.write(new Uint8Array(buffer.buffer), 0, buffer.byteLength, position + bytesWritten);
|
|
786
801
|
}
|
|
787
802
|
return bytesWritten;
|
|
788
803
|
}
|
package/dist/vfs/watchers.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { EventEmitter as NodeEventEmitter } from 'node:events';
|
|
|
2
2
|
import type * as fs from 'node:fs';
|
|
3
3
|
import type { V_Context } from '../context.js';
|
|
4
4
|
import { EventEmitter } from 'eventemitter3';
|
|
5
|
-
import { type Stats } from '
|
|
5
|
+
import { type Stats } from './stats.js';
|
|
6
6
|
/**
|
|
7
7
|
* Base class for file system watchers.
|
|
8
8
|
* Provides event handling capabilities for watching file system changes.
|
|
@@ -75,5 +75,5 @@ export declare function removeWatcher(path: string, watcher: FSWatcher): void;
|
|
|
75
75
|
/**
|
|
76
76
|
* @internal @hidden
|
|
77
77
|
*/
|
|
78
|
-
export declare function emitChange(
|
|
78
|
+
export declare function emitChange($: V_Context, eventType: fs.WatchEventType, filename: string): void;
|
|
79
79
|
export {};
|
package/dist/vfs/watchers.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { EventEmitter } from 'eventemitter3';
|
|
2
2
|
import { ErrnoError } from '../internal/error.js';
|
|
3
|
-
import { isStatsEqual } from '
|
|
3
|
+
import { isStatsEqual } from './stats.js';
|
|
4
4
|
import { normalizePath } from '../utils.js';
|
|
5
|
-
import { basename, dirname, join, relative } from '
|
|
5
|
+
import { basename, dirname, join, relative } from '../path.js';
|
|
6
6
|
import { statSync } from './sync.js';
|
|
7
7
|
/**
|
|
8
8
|
* Base class for file system watchers.
|
|
@@ -138,10 +138,10 @@ export function removeWatcher(path, watcher) {
|
|
|
138
138
|
/**
|
|
139
139
|
* @internal @hidden
|
|
140
140
|
*/
|
|
141
|
-
export function emitChange(
|
|
141
|
+
export function emitChange($, eventType, filename) {
|
|
142
142
|
var _a;
|
|
143
|
-
if (
|
|
144
|
-
filename = join((_a =
|
|
143
|
+
if ($)
|
|
144
|
+
filename = join((_a = $.root) !== null && _a !== void 0 ? _a : '/', filename);
|
|
145
145
|
filename = normalizePath(filename);
|
|
146
146
|
// Notify watchers, including ones on parent directories if they are watching recursively
|
|
147
147
|
for (let path = filename; path != '/'; path = dirname(path)) {
|
|
@@ -149,7 +149,7 @@ export function emitChange(context, eventType, filename) {
|
|
|
149
149
|
if (!watchersForPath)
|
|
150
150
|
continue;
|
|
151
151
|
for (const watcher of watchersForPath) {
|
|
152
|
-
watcher.emit('change', eventType, relative(path, filename) || basename(filename));
|
|
152
|
+
watcher.emit('change', eventType, relative.call(watcher._context, path, filename) || basename(filename));
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
}
|