@zenfs/core 0.0.1
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/README.md +293 -0
- package/dist/ApiError.d.ts +86 -0
- package/dist/ApiError.js +135 -0
- package/dist/backends/AsyncMirror.d.ts +102 -0
- package/dist/backends/AsyncMirror.js +252 -0
- package/dist/backends/AsyncStore.d.ts +166 -0
- package/dist/backends/AsyncStore.js +620 -0
- package/dist/backends/FolderAdapter.d.ts +52 -0
- package/dist/backends/FolderAdapter.js +184 -0
- package/dist/backends/InMemory.d.ts +25 -0
- package/dist/backends/InMemory.js +46 -0
- package/dist/backends/Locked.d.ts +64 -0
- package/dist/backends/Locked.js +302 -0
- package/dist/backends/OverlayFS.d.ts +120 -0
- package/dist/backends/OverlayFS.js +749 -0
- package/dist/backends/SyncStore.d.ts +223 -0
- package/dist/backends/SyncStore.js +479 -0
- package/dist/backends/backend.d.ts +73 -0
- package/dist/backends/backend.js +14 -0
- package/dist/backends/index.d.ts +11 -0
- package/dist/backends/index.js +15 -0
- package/dist/browser.min.js +12 -0
- package/dist/browser.min.js.map +7 -0
- package/dist/cred.d.ts +14 -0
- package/dist/cred.js +15 -0
- package/dist/emulation/callbacks.d.ts +382 -0
- package/dist/emulation/callbacks.js +422 -0
- package/dist/emulation/constants.d.ts +101 -0
- package/dist/emulation/constants.js +110 -0
- package/dist/emulation/fs.d.ts +7 -0
- package/dist/emulation/fs.js +5 -0
- package/dist/emulation/index.d.ts +5 -0
- package/dist/emulation/index.js +7 -0
- package/dist/emulation/promises.d.ts +309 -0
- package/dist/emulation/promises.js +521 -0
- package/dist/emulation/shared.d.ts +62 -0
- package/dist/emulation/shared.js +192 -0
- package/dist/emulation/sync.d.ts +278 -0
- package/dist/emulation/sync.js +392 -0
- package/dist/file.d.ts +449 -0
- package/dist/file.js +576 -0
- package/dist/filesystem.d.ts +367 -0
- package/dist/filesystem.js +542 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +113 -0
- package/dist/inode.d.ts +51 -0
- package/dist/inode.js +112 -0
- package/dist/mutex.d.ts +12 -0
- package/dist/mutex.js +48 -0
- package/dist/stats.d.ts +98 -0
- package/dist/stats.js +226 -0
- package/dist/utils.d.ts +52 -0
- package/dist/utils.js +261 -0
- package/license.md +122 -0
- package/package.json +61 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { ApiError, ErrorCode } from '../ApiError';
|
|
2
|
+
import { FileFlag } from '../file';
|
|
3
|
+
import { normalizePath, cred, getFdForFile, normalizeMode, normalizeOptions, fdMap, fd2file, normalizeTime, resolveFS, fixError, mounts } from './shared';
|
|
4
|
+
function doOp(...[name, resolveSymlinks, path, ...args]) {
|
|
5
|
+
path = normalizePath(path);
|
|
6
|
+
const { fs, path: resolvedPath } = resolveFS(resolveSymlinks && existsSync(path) ? realpathSync(path) : path);
|
|
7
|
+
try {
|
|
8
|
+
// @ts-expect-error 2556 (since ...args is not correctly picked up as being a tuple)
|
|
9
|
+
return fs[name](resolvedPath, ...args);
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
throw fixError(e, { [resolvedPath]: path });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Synchronous rename.
|
|
17
|
+
* @param oldPath
|
|
18
|
+
* @param newPath
|
|
19
|
+
*/
|
|
20
|
+
export function renameSync(oldPath, newPath) {
|
|
21
|
+
oldPath = normalizePath(oldPath);
|
|
22
|
+
newPath = normalizePath(newPath);
|
|
23
|
+
const _old = resolveFS(oldPath);
|
|
24
|
+
const _new = resolveFS(newPath);
|
|
25
|
+
const paths = { [_old.path]: oldPath, [_new.path]: newPath };
|
|
26
|
+
try {
|
|
27
|
+
if (_old === _new) {
|
|
28
|
+
return _old.fs.renameSync(_old.path, _new.path, cred);
|
|
29
|
+
}
|
|
30
|
+
const data = readFileSync(oldPath);
|
|
31
|
+
writeFileSync(newPath, data);
|
|
32
|
+
unlinkSync(oldPath);
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
throw fixError(e, paths);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Test whether or not the given path exists by checking with the file system.
|
|
40
|
+
* @param path
|
|
41
|
+
*/
|
|
42
|
+
export function existsSync(path) {
|
|
43
|
+
path = normalizePath(path);
|
|
44
|
+
try {
|
|
45
|
+
const { fs, path: resolvedPath } = resolveFS(path);
|
|
46
|
+
return fs.existsSync(resolvedPath, cred);
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
if (e.errno == ErrorCode.ENOENT) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
throw e;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Synchronous `stat`.
|
|
57
|
+
* @param path
|
|
58
|
+
* @returns Stats
|
|
59
|
+
*/
|
|
60
|
+
export function statSync(path) {
|
|
61
|
+
return doOp('statSync', true, path, cred);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Synchronous `lstat`.
|
|
65
|
+
* `lstat()` is identical to `stat()`, except that if path is a symbolic link,
|
|
66
|
+
* then the link itself is stat-ed, not the file that it refers to.
|
|
67
|
+
* @param path
|
|
68
|
+
* @return [ZenFS.node.fs.Stats]
|
|
69
|
+
*/
|
|
70
|
+
export function lstatSync(path) {
|
|
71
|
+
return doOp('statSync', false, path, cred);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Synchronous `truncate`.
|
|
75
|
+
* @param path
|
|
76
|
+
* @param len
|
|
77
|
+
*/
|
|
78
|
+
export function truncateSync(path, len = 0) {
|
|
79
|
+
if (len < 0) {
|
|
80
|
+
throw new ApiError(ErrorCode.EINVAL);
|
|
81
|
+
}
|
|
82
|
+
return doOp('truncateSync', true, path, len, cred);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Synchronous `unlink`.
|
|
86
|
+
* @param path
|
|
87
|
+
*/
|
|
88
|
+
export function unlinkSync(path) {
|
|
89
|
+
return doOp('unlinkSync', false, path, cred);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Synchronous file open.
|
|
93
|
+
* @see http://www.manpagez.com/man/2/open/
|
|
94
|
+
* @param path
|
|
95
|
+
* @param flags
|
|
96
|
+
* @param mode defaults to `0644`
|
|
97
|
+
* @return [ZenFS.File]
|
|
98
|
+
*/
|
|
99
|
+
export function openSync(path, flag, mode = 0o644) {
|
|
100
|
+
const file = doOp('openSync', true, path, FileFlag.getFileFlag(flag), normalizeMode(mode, 0o644), cred);
|
|
101
|
+
return getFdForFile(file);
|
|
102
|
+
}
|
|
103
|
+
export function readFileSync(filename, arg2 = {}) {
|
|
104
|
+
const options = normalizeOptions(arg2, null, 'r', null);
|
|
105
|
+
const flag = FileFlag.getFileFlag(options.flag);
|
|
106
|
+
if (!flag.isReadable()) {
|
|
107
|
+
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to readFile must allow for reading.');
|
|
108
|
+
}
|
|
109
|
+
return doOp('readFileSync', true, filename, options.encoding, flag, cred);
|
|
110
|
+
}
|
|
111
|
+
export function writeFileSync(filename, data, arg3) {
|
|
112
|
+
const options = normalizeOptions(arg3, 'utf8', 'w', 0o644);
|
|
113
|
+
const flag = FileFlag.getFileFlag(options.flag);
|
|
114
|
+
if (!flag.isWriteable()) {
|
|
115
|
+
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to writeFile must allow for writing.');
|
|
116
|
+
}
|
|
117
|
+
return doOp('writeFileSync', true, filename, data, options.encoding, flag, options.mode, cred);
|
|
118
|
+
}
|
|
119
|
+
export function appendFileSync(filename, data, arg3) {
|
|
120
|
+
const options = normalizeOptions(arg3, 'utf8', 'a', 0o644);
|
|
121
|
+
const flag = FileFlag.getFileFlag(options.flag);
|
|
122
|
+
if (!flag.isAppendable()) {
|
|
123
|
+
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to appendFile must allow for appending.');
|
|
124
|
+
}
|
|
125
|
+
return doOp('appendFileSync', true, filename, data, options.encoding, flag, options.mode, cred);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Synchronous `fstat`.
|
|
129
|
+
* `fstat()` is identical to `stat()`, except that the file to be stat-ed is
|
|
130
|
+
* specified by the file descriptor `fd`.
|
|
131
|
+
* @param fd
|
|
132
|
+
* @return [ZenFS.node.fs.Stats]
|
|
133
|
+
*/
|
|
134
|
+
export function fstatSync(fd) {
|
|
135
|
+
return fd2file(fd).statSync();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Synchronous close.
|
|
139
|
+
* @param fd
|
|
140
|
+
*/
|
|
141
|
+
export function closeSync(fd) {
|
|
142
|
+
fd2file(fd).closeSync();
|
|
143
|
+
fdMap.delete(fd);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Synchronous ftruncate.
|
|
147
|
+
* @param fd
|
|
148
|
+
* @param len
|
|
149
|
+
*/
|
|
150
|
+
export function ftruncateSync(fd, len = 0) {
|
|
151
|
+
const file = fd2file(fd);
|
|
152
|
+
if (len < 0) {
|
|
153
|
+
throw new ApiError(ErrorCode.EINVAL);
|
|
154
|
+
}
|
|
155
|
+
file.truncateSync(len);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Synchronous fsync.
|
|
159
|
+
* @param fd
|
|
160
|
+
*/
|
|
161
|
+
export function fsyncSync(fd) {
|
|
162
|
+
fd2file(fd).syncSync();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Synchronous fdatasync.
|
|
166
|
+
* @param fd
|
|
167
|
+
*/
|
|
168
|
+
export function fdatasyncSync(fd) {
|
|
169
|
+
fd2file(fd).datasyncSync();
|
|
170
|
+
}
|
|
171
|
+
export function writeSync(fd, arg2, arg3, arg4, arg5) {
|
|
172
|
+
let buffer, offset = 0, length, position;
|
|
173
|
+
if (typeof arg2 === 'string') {
|
|
174
|
+
// Signature 1: (fd, string, [position?, [encoding?]])
|
|
175
|
+
position = typeof arg3 === 'number' ? arg3 : null;
|
|
176
|
+
const encoding = (typeof arg4 === 'string' ? arg4 : 'utf8');
|
|
177
|
+
offset = 0;
|
|
178
|
+
buffer = Buffer.from(arg2, encoding);
|
|
179
|
+
length = buffer.length;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Signature 2: (fd, buffer, offset, length, position?)
|
|
183
|
+
buffer = arg2;
|
|
184
|
+
offset = arg3;
|
|
185
|
+
length = arg4;
|
|
186
|
+
position = typeof arg5 === 'number' ? arg5 : null;
|
|
187
|
+
}
|
|
188
|
+
const file = fd2file(fd);
|
|
189
|
+
if (position === undefined || position === null) {
|
|
190
|
+
position = file.getPos();
|
|
191
|
+
}
|
|
192
|
+
return file.writeSync(buffer, offset, length, position);
|
|
193
|
+
}
|
|
194
|
+
export function readSync(fd, buffer, opts, length, position) {
|
|
195
|
+
const file = fd2file(fd);
|
|
196
|
+
let offset = opts;
|
|
197
|
+
if (typeof opts == 'object') {
|
|
198
|
+
({ offset, length, position } = opts);
|
|
199
|
+
}
|
|
200
|
+
if (isNaN(+position)) {
|
|
201
|
+
position = file.getPos();
|
|
202
|
+
}
|
|
203
|
+
return file.readSync(buffer, offset, length, position);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Synchronous `fchown`.
|
|
207
|
+
* @param fd
|
|
208
|
+
* @param uid
|
|
209
|
+
* @param gid
|
|
210
|
+
*/
|
|
211
|
+
export function fchownSync(fd, uid, gid) {
|
|
212
|
+
fd2file(fd).chownSync(uid, gid);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Synchronous `fchmod`.
|
|
216
|
+
* @param fd
|
|
217
|
+
* @param mode
|
|
218
|
+
*/
|
|
219
|
+
export function fchmodSync(fd, mode) {
|
|
220
|
+
const numMode = typeof mode === 'string' ? parseInt(mode, 8) : mode;
|
|
221
|
+
fd2file(fd).chmodSync(numMode);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Change the file timestamps of a file referenced by the supplied file
|
|
225
|
+
* descriptor.
|
|
226
|
+
* @param fd
|
|
227
|
+
* @param atime
|
|
228
|
+
* @param mtime
|
|
229
|
+
*/
|
|
230
|
+
export function futimesSync(fd, atime, mtime) {
|
|
231
|
+
fd2file(fd).utimesSync(normalizeTime(atime), normalizeTime(mtime));
|
|
232
|
+
}
|
|
233
|
+
// DIRECTORY-ONLY METHODS
|
|
234
|
+
/**
|
|
235
|
+
* Synchronous `rmdir`.
|
|
236
|
+
* @param path
|
|
237
|
+
*/
|
|
238
|
+
export function rmdirSync(path) {
|
|
239
|
+
return doOp('rmdirSync', true, path, cred);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Synchronous `mkdir`.
|
|
243
|
+
* @param path
|
|
244
|
+
* @param mode defaults to `0777`
|
|
245
|
+
*/
|
|
246
|
+
export function mkdirSync(path, mode) {
|
|
247
|
+
doOp('mkdirSync', true, path, normalizeMode(mode, 0o777), cred);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Synchronous `readdir`. Reads the contents of a directory.
|
|
251
|
+
* @param path
|
|
252
|
+
* @return [String[]]
|
|
253
|
+
*/
|
|
254
|
+
export function readdirSync(path) {
|
|
255
|
+
path = normalizePath(path);
|
|
256
|
+
const entries = doOp('readdirSync', true, path, cred);
|
|
257
|
+
const points = [...mounts.keys()];
|
|
258
|
+
for (const point of points) {
|
|
259
|
+
if (point.startsWith(path)) {
|
|
260
|
+
const entry = point.slice(path.length);
|
|
261
|
+
if (entry.includes('/') || entry.length == 0) {
|
|
262
|
+
// ignore FSs mounted in subdirectories and any FS mounted to `path`.
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
entries.push(entry);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return entries;
|
|
269
|
+
}
|
|
270
|
+
// SYMLINK METHODS
|
|
271
|
+
/**
|
|
272
|
+
* Synchronous `link`.
|
|
273
|
+
* @param srcpath
|
|
274
|
+
* @param dstpath
|
|
275
|
+
*/
|
|
276
|
+
export function linkSync(srcpath, dstpath) {
|
|
277
|
+
dstpath = normalizePath(dstpath);
|
|
278
|
+
return doOp('linkSync', false, srcpath, dstpath, cred);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Synchronous `symlink`.
|
|
282
|
+
* @param srcpath
|
|
283
|
+
* @param dstpath
|
|
284
|
+
* @param type can be either `'dir'` or `'file'` (default is `'file'`)
|
|
285
|
+
*/
|
|
286
|
+
export function symlinkSync(srcpath, dstpath, type) {
|
|
287
|
+
if (!['file', 'dir', 'junction'].includes(type)) {
|
|
288
|
+
throw new ApiError(ErrorCode.EINVAL, 'Invalid type: ' + type);
|
|
289
|
+
}
|
|
290
|
+
dstpath = normalizePath(dstpath);
|
|
291
|
+
return doOp('symlinkSync', false, srcpath, dstpath, type, cred);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Synchronous readlink.
|
|
295
|
+
* @param path
|
|
296
|
+
* @return [String]
|
|
297
|
+
*/
|
|
298
|
+
export function readlinkSync(path) {
|
|
299
|
+
return doOp('readlinkSync', false, path, cred);
|
|
300
|
+
}
|
|
301
|
+
// PROPERTY OPERATIONS
|
|
302
|
+
/**
|
|
303
|
+
* Synchronous `chown`.
|
|
304
|
+
* @param path
|
|
305
|
+
* @param uid
|
|
306
|
+
* @param gid
|
|
307
|
+
*/
|
|
308
|
+
export function chownSync(path, uid, gid) {
|
|
309
|
+
doOp('chownSync', true, path, uid, gid, cred);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Synchronous `lchown`.
|
|
313
|
+
* @param path
|
|
314
|
+
* @param uid
|
|
315
|
+
* @param gid
|
|
316
|
+
*/
|
|
317
|
+
export function lchownSync(path, uid, gid) {
|
|
318
|
+
doOp('chownSync', false, path, uid, gid, cred);
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Synchronous `chmod`.
|
|
322
|
+
* @param path
|
|
323
|
+
* @param mode
|
|
324
|
+
*/
|
|
325
|
+
export function chmodSync(path, mode) {
|
|
326
|
+
const numMode = normalizeMode(mode, -1);
|
|
327
|
+
if (numMode < 0) {
|
|
328
|
+
throw new ApiError(ErrorCode.EINVAL, `Invalid mode.`);
|
|
329
|
+
}
|
|
330
|
+
doOp('chmodSync', true, path, numMode, cred);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Synchronous `lchmod`.
|
|
334
|
+
* @param path
|
|
335
|
+
* @param mode
|
|
336
|
+
*/
|
|
337
|
+
export function lchmodSync(path, mode) {
|
|
338
|
+
const numMode = normalizeMode(mode, -1);
|
|
339
|
+
if (numMode < 1) {
|
|
340
|
+
throw new ApiError(ErrorCode.EINVAL, `Invalid mode.`);
|
|
341
|
+
}
|
|
342
|
+
doOp('chmodSync', false, path, numMode, cred);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Change file timestamps of the file referenced by the supplied path.
|
|
346
|
+
* @param path
|
|
347
|
+
* @param atime
|
|
348
|
+
* @param mtime
|
|
349
|
+
*/
|
|
350
|
+
export function utimesSync(path, atime, mtime) {
|
|
351
|
+
doOp('utimesSync', true, path, normalizeTime(atime), normalizeTime(mtime), cred);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Change file timestamps of the file referenced by the supplied path.
|
|
355
|
+
* @param path
|
|
356
|
+
* @param atime
|
|
357
|
+
* @param mtime
|
|
358
|
+
*/
|
|
359
|
+
export function lutimesSync(path, atime, mtime) {
|
|
360
|
+
doOp('utimesSync', false, path, normalizeTime(atime), normalizeTime(mtime), cred);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Synchronous `realpath`.
|
|
364
|
+
* @param path
|
|
365
|
+
* @param cache An object literal of mapped paths that can be used to
|
|
366
|
+
* force a specific path resolution or avoid additional `fs.stat` calls for
|
|
367
|
+
* known real paths.
|
|
368
|
+
* @return [String]
|
|
369
|
+
*/
|
|
370
|
+
export function realpathSync(path, cache = {}) {
|
|
371
|
+
path = normalizePath(path);
|
|
372
|
+
const { fs, path: resolvedPath, mountPoint } = resolveFS(path);
|
|
373
|
+
try {
|
|
374
|
+
const stats = fs.statSync(resolvedPath, cred);
|
|
375
|
+
if (!stats.isSymbolicLink()) {
|
|
376
|
+
return path;
|
|
377
|
+
}
|
|
378
|
+
const dst = normalizePath(mountPoint + fs.readlinkSync(resolvedPath, cred));
|
|
379
|
+
return realpathSync(dst);
|
|
380
|
+
}
|
|
381
|
+
catch (e) {
|
|
382
|
+
throw fixError(e, { [resolvedPath]: path });
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Synchronous `access`.
|
|
387
|
+
* @param path
|
|
388
|
+
* @param mode
|
|
389
|
+
*/
|
|
390
|
+
export function accessSync(path, mode = 0o600) {
|
|
391
|
+
return doOp('accessSync', true, path, mode, cred);
|
|
392
|
+
}
|