@zenfs/core 0.11.0 → 0.11.2
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 +1 -2
- package/dist/backends/backend.js +0 -6
- package/dist/backends/fetch.d.ts +1 -1
- package/dist/backends/fetch.js +13 -11
- package/dist/backends/locked.d.ts +1 -1
- package/dist/backends/locked.js +34 -34
- package/dist/backends/memory.d.ts +1 -1
- package/dist/backends/port/fs.d.ts +1 -1
- package/dist/backends/port/fs.js +2 -1
- package/dist/backends/port/rpc.js +3 -1
- package/dist/backends/store/fs.d.ts +5 -5
- package/dist/backends/store/fs.js +1 -1
- package/dist/browser.min.js +3 -3
- package/dist/browser.min.js.map +3 -3
- package/dist/config.js +1 -1
- package/dist/emulation/promises.js +1 -2
- package/dist/emulation/sync.js +24 -40
- package/dist/filesystem.d.ts +6 -6
- package/dist/filesystem.js +11 -10
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mutex.d.ts +1 -1
- package/dist/mutex.js +11 -11
- package/package.json +1 -1
- package/scripts/make-index.js +15 -12
- package/src/backends/backend.ts +3 -8
- package/src/backends/fetch.ts +13 -12
- package/src/backends/locked.ts +34 -34
- package/src/backends/memory.ts +1 -1
- package/src/backends/port/fs.ts +2 -1
- package/src/backends/port/rpc.ts +2 -1
- package/src/backends/store/fs.ts +5 -5
- package/src/config.ts +1 -1
- package/src/emulation/promises.ts +1 -2
- package/src/emulation/sync.ts +23 -41
- package/src/filesystem.ts +18 -17
- package/src/index.ts +2 -0
- package/src/mutex.ts +11 -11
package/dist/config.js
CHANGED
|
@@ -40,7 +40,7 @@ export async function resolveMountConfig(config, _depth = 0) {
|
|
|
40
40
|
throw new ErrnoError(Errno.EPERM, 'Backend not available: ' + backend);
|
|
41
41
|
}
|
|
42
42
|
checkOptions(backend, config);
|
|
43
|
-
const mount = backend.create(config);
|
|
43
|
+
const mount = await backend.create(config);
|
|
44
44
|
await mount.ready();
|
|
45
45
|
return mount;
|
|
46
46
|
}
|
|
@@ -106,8 +106,7 @@ export class FileHandle {
|
|
|
106
106
|
throw new ErrnoError(Errno.EINVAL, 'Flag passed must allow for reading.');
|
|
107
107
|
}
|
|
108
108
|
const { size } = await this.stat();
|
|
109
|
-
const data = new Uint8Array(size);
|
|
110
|
-
await this.file.read(data, 0, size, 0);
|
|
109
|
+
const { buffer: data } = await this.file.read(new Uint8Array(size), 0, size, 0);
|
|
111
110
|
const buffer = Buffer.from(data);
|
|
112
111
|
return options.encoding ? buffer.toString(options.encoding) : buffer;
|
|
113
112
|
}
|
package/dist/emulation/sync.js
CHANGED
|
@@ -7,7 +7,7 @@ import { COPYFILE_EXCL, F_OK, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFM
|
|
|
7
7
|
import { Dir, Dirent } from './dir.js';
|
|
8
8
|
import { dirname, join, parse } from './path.js';
|
|
9
9
|
import { cred, fd2file, fdMap, fixError, file2fd, mounts, resolveMount } from './shared.js';
|
|
10
|
-
function
|
|
10
|
+
function wrap(...[name, resolveSymlinks, path, ...args]) {
|
|
11
11
|
path = normalizePath(path);
|
|
12
12
|
const { fs, path: resolvedPath } = resolveMount(resolveSymlinks && existsSync(path) ? realpathSync(path) : path);
|
|
13
13
|
try {
|
|
@@ -60,12 +60,12 @@ export function existsSync(path) {
|
|
|
60
60
|
}
|
|
61
61
|
existsSync;
|
|
62
62
|
export function statSync(path, options) {
|
|
63
|
-
const stats =
|
|
63
|
+
const stats = wrap('statSync', true, path.toString(), cred);
|
|
64
64
|
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
65
65
|
}
|
|
66
66
|
statSync;
|
|
67
67
|
export function lstatSync(path, options) {
|
|
68
|
-
const stats =
|
|
68
|
+
const stats = wrap('statSync', false, path.toString(), cred);
|
|
69
69
|
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
70
70
|
}
|
|
71
71
|
lstatSync;
|
|
@@ -89,7 +89,7 @@ truncateSync;
|
|
|
89
89
|
* @param path
|
|
90
90
|
*/
|
|
91
91
|
export function unlinkSync(path) {
|
|
92
|
-
return
|
|
92
|
+
return wrap('unlinkSync', false, path.toString(), cred);
|
|
93
93
|
}
|
|
94
94
|
unlinkSync;
|
|
95
95
|
function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
|
|
@@ -97,18 +97,18 @@ function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
|
|
|
97
97
|
// Check if the path exists, and is a file.
|
|
98
98
|
let stats;
|
|
99
99
|
try {
|
|
100
|
-
stats =
|
|
100
|
+
stats = wrap('statSync', resolveSymlinks, path, cred);
|
|
101
101
|
}
|
|
102
102
|
catch (e) {
|
|
103
103
|
// File does not exist.
|
|
104
104
|
switch (pathNotExistsAction(flag)) {
|
|
105
105
|
case ActionType.CREATE:
|
|
106
106
|
// Ensure parent exists.
|
|
107
|
-
const parentStats =
|
|
107
|
+
const parentStats = wrap('statSync', resolveSymlinks, dirname(path), cred);
|
|
108
108
|
if (!parentStats.isDirectory()) {
|
|
109
109
|
throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
|
|
110
110
|
}
|
|
111
|
-
return
|
|
111
|
+
return wrap('createFileSync', resolveSymlinks, path, flag, mode, cred);
|
|
112
112
|
case ActionType.THROW:
|
|
113
113
|
throw ErrnoError.With('ENOENT', path, '_open');
|
|
114
114
|
default:
|
|
@@ -124,16 +124,16 @@ function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
|
|
|
124
124
|
throw ErrnoError.With('EEXIST', path, '_open');
|
|
125
125
|
case ActionType.TRUNCATE:
|
|
126
126
|
// Delete file.
|
|
127
|
-
|
|
127
|
+
wrap('unlinkSync', resolveSymlinks, path, cred);
|
|
128
128
|
/*
|
|
129
129
|
Create file. Use the same mode as the old file.
|
|
130
130
|
Node itself modifies the ctime when this occurs, so this action
|
|
131
131
|
will preserve that behavior if the underlying file system
|
|
132
132
|
supports those properties.
|
|
133
133
|
*/
|
|
134
|
-
return
|
|
134
|
+
return wrap('createFileSync', resolveSymlinks, path, flag, stats.mode, cred);
|
|
135
135
|
case ActionType.NOP:
|
|
136
|
-
return
|
|
136
|
+
return wrap('openFileSync', resolveSymlinks, path, flag, cred);
|
|
137
137
|
default:
|
|
138
138
|
throw new ErrnoError(Errno.EINVAL, 'Invalid FileFlag object.');
|
|
139
139
|
}
|
|
@@ -185,21 +185,6 @@ export function readFileSync(path, _options = {}) {
|
|
|
185
185
|
return options.encoding ? data.toString(options.encoding) : data;
|
|
186
186
|
}
|
|
187
187
|
readFileSync;
|
|
188
|
-
/**
|
|
189
|
-
* Synchronously writes data to a file, replacing the file
|
|
190
|
-
* if it already exists.
|
|
191
|
-
*
|
|
192
|
-
* The encoding option is ignored if data is a buffer.
|
|
193
|
-
*/
|
|
194
|
-
function _writeFileSync(fname, data, flag, mode, resolveSymlinks) {
|
|
195
|
-
const file = _openSync(fname, flag, mode, resolveSymlinks);
|
|
196
|
-
try {
|
|
197
|
-
file.writeSync(data, 0, data.byteLength, 0);
|
|
198
|
-
}
|
|
199
|
-
finally {
|
|
200
|
-
file.closeSync();
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
188
|
export function writeFileSync(path, data, _options = {}) {
|
|
204
189
|
const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
|
|
205
190
|
const flag = parseFlag(options.flag);
|
|
@@ -213,22 +198,15 @@ export function writeFileSync(path, data, _options = {}) {
|
|
|
213
198
|
if (!encodedData) {
|
|
214
199
|
throw new ErrnoError(Errno.EINVAL, 'Data not specified');
|
|
215
200
|
}
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
writeFileSync;
|
|
219
|
-
/**
|
|
220
|
-
* Synchronously append data to a file, creating the file if
|
|
221
|
-
* it not yet exists.
|
|
222
|
-
*/
|
|
223
|
-
function _appendFileSync(fname, data, flag, mode, resolveSymlinks) {
|
|
224
|
-
const file = _openSync(fname, flag, mode, resolveSymlinks);
|
|
201
|
+
const file = _openSync(typeof path == 'number' ? fd2file(path).path : path.toString(), flag, options.mode, true);
|
|
225
202
|
try {
|
|
226
|
-
file.writeSync(
|
|
203
|
+
file.writeSync(encodedData, 0, encodedData.byteLength, 0);
|
|
227
204
|
}
|
|
228
205
|
finally {
|
|
229
206
|
file.closeSync();
|
|
230
207
|
}
|
|
231
208
|
}
|
|
209
|
+
writeFileSync;
|
|
232
210
|
/**
|
|
233
211
|
* Asynchronously append data to a file, creating the file if it not yet
|
|
234
212
|
* exists.
|
|
@@ -250,7 +228,13 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
250
228
|
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
251
229
|
}
|
|
252
230
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
253
|
-
|
|
231
|
+
const file = _openSync(typeof filename == 'number' ? fd2file(filename).path : filename.toString(), flag, options.mode, true);
|
|
232
|
+
try {
|
|
233
|
+
file.writeSync(encodedData, 0, encodedData.byteLength, null);
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
file.closeSync();
|
|
237
|
+
}
|
|
254
238
|
}
|
|
255
239
|
appendFileSync;
|
|
256
240
|
export function fstatSync(fd, options) {
|
|
@@ -371,18 +355,18 @@ futimesSync;
|
|
|
371
355
|
* @param path
|
|
372
356
|
*/
|
|
373
357
|
export function rmdirSync(path) {
|
|
374
|
-
return
|
|
358
|
+
return wrap('rmdirSync', true, path.toString(), cred);
|
|
375
359
|
}
|
|
376
360
|
rmdirSync;
|
|
377
361
|
export function mkdirSync(path, options) {
|
|
378
362
|
const mode = typeof options == 'number' || typeof options == 'string' ? options : options?.mode;
|
|
379
363
|
const recursive = typeof options == 'object' && options?.recursive;
|
|
380
|
-
|
|
364
|
+
wrap('mkdirSync', true, path.toString(), normalizeMode(mode, 0o777), cred);
|
|
381
365
|
}
|
|
382
366
|
mkdirSync;
|
|
383
367
|
export function readdirSync(path, options) {
|
|
384
368
|
path = normalizePath(path);
|
|
385
|
-
const entries =
|
|
369
|
+
const entries = wrap('readdirSync', true, path, cred);
|
|
386
370
|
for (const mount of mounts.keys()) {
|
|
387
371
|
if (!mount.startsWith(path)) {
|
|
388
372
|
continue;
|
|
@@ -413,7 +397,7 @@ readdirSync;
|
|
|
413
397
|
*/
|
|
414
398
|
export function linkSync(existing, newpath) {
|
|
415
399
|
newpath = normalizePath(newpath);
|
|
416
|
-
return
|
|
400
|
+
return wrap('linkSync', false, existing.toString(), newpath.toString(), cred);
|
|
417
401
|
}
|
|
418
402
|
linkSync;
|
|
419
403
|
/**
|
package/dist/filesystem.d.ts
CHANGED
|
@@ -147,7 +147,7 @@ export declare abstract class FileSystem {
|
|
|
147
147
|
/**
|
|
148
148
|
* @internal
|
|
149
149
|
*/
|
|
150
|
-
declare abstract class
|
|
150
|
+
declare abstract class SyncFS extends FileSystem {
|
|
151
151
|
metadata(): FileSystemMetadata;
|
|
152
152
|
ready(): Promise<void>;
|
|
153
153
|
exists(path: string, cred: Cred): Promise<boolean>;
|
|
@@ -165,11 +165,11 @@ declare abstract class SyncFileSystem extends FileSystem {
|
|
|
165
165
|
/**
|
|
166
166
|
* Implements the asynchronous API in terms of the synchronous API.
|
|
167
167
|
*/
|
|
168
|
-
export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) =>
|
|
168
|
+
export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => SyncFS) & T;
|
|
169
169
|
/**
|
|
170
170
|
* @internal
|
|
171
171
|
*/
|
|
172
|
-
declare abstract class
|
|
172
|
+
declare abstract class AsyncFS extends FileSystem {
|
|
173
173
|
/**
|
|
174
174
|
* @hidden
|
|
175
175
|
*/
|
|
@@ -200,11 +200,11 @@ declare abstract class AsyncFileSystem extends FileSystem {
|
|
|
200
200
|
* the synchronous store, if desired.
|
|
201
201
|
*
|
|
202
202
|
*/
|
|
203
|
-
export declare function Async<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) =>
|
|
203
|
+
export declare function Async<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => AsyncFS) & T;
|
|
204
204
|
/**
|
|
205
205
|
* @internal
|
|
206
206
|
*/
|
|
207
|
-
declare abstract class
|
|
207
|
+
declare abstract class ReadonlyFS extends FileSystem {
|
|
208
208
|
metadata(): FileSystemMetadata;
|
|
209
209
|
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
|
|
210
210
|
renameSync(oldPath: string, newPath: string, cred: Cred): void;
|
|
@@ -224,5 +224,5 @@ declare abstract class ReadonlyFileSystem extends FileSystem {
|
|
|
224
224
|
/**
|
|
225
225
|
* Implements the non-readonly methods to throw `EROFS`
|
|
226
226
|
*/
|
|
227
|
-
export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) =>
|
|
227
|
+
export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => ReadonlyFS) & T;
|
|
228
228
|
export {};
|
package/dist/filesystem.js
CHANGED
|
@@ -58,7 +58,7 @@ export class FileSystem {
|
|
|
58
58
|
*/
|
|
59
59
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
60
|
export function Sync(FS) {
|
|
61
|
-
class
|
|
61
|
+
class _SyncFS extends FS {
|
|
62
62
|
async exists(path, cred) {
|
|
63
63
|
return this.existsSync(path, cred);
|
|
64
64
|
}
|
|
@@ -93,7 +93,7 @@ export function Sync(FS) {
|
|
|
93
93
|
return this.syncSync(path, data, stats);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
return
|
|
96
|
+
return _SyncFS;
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* Async() implements synchronous methods on an asynchronous file system
|
|
@@ -109,7 +109,7 @@ export function Sync(FS) {
|
|
|
109
109
|
*/
|
|
110
110
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
111
|
export function Async(FS) {
|
|
112
|
-
class
|
|
112
|
+
class _AsyncFS extends FS {
|
|
113
113
|
constructor() {
|
|
114
114
|
super(...arguments);
|
|
115
115
|
/**
|
|
@@ -150,16 +150,17 @@ export function Async(FS) {
|
|
|
150
150
|
return this._sync.statSync(path, cred);
|
|
151
151
|
}
|
|
152
152
|
createFileSync(path, flag, mode, cred) {
|
|
153
|
-
|
|
153
|
+
this._sync.createFileSync(path, flag, mode, cred);
|
|
154
154
|
this.queue('createFile', path, flag, mode, cred);
|
|
155
|
+
return this.openFileSync(path, flag, cred);
|
|
156
|
+
}
|
|
157
|
+
openFileSync(path, flag, cred) {
|
|
158
|
+
const file = this._sync.openFileSync(path, flag, cred);
|
|
155
159
|
const stats = file.statSync();
|
|
156
160
|
const buffer = new Uint8Array(stats.size);
|
|
157
161
|
file.readSync(buffer);
|
|
158
162
|
return new PreloadFile(this, path, flag, stats, buffer);
|
|
159
163
|
}
|
|
160
|
-
openFileSync(path, flag, cred) {
|
|
161
|
-
return this._sync.openFileSync(path, flag, cred);
|
|
162
|
-
}
|
|
163
164
|
unlinkSync(path, cred) {
|
|
164
165
|
this._sync.unlinkSync(path, cred);
|
|
165
166
|
this.queue('unlink', path, cred);
|
|
@@ -235,14 +236,14 @@ export function Async(FS) {
|
|
|
235
236
|
this._next();
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
|
-
return
|
|
239
|
+
return _AsyncFS;
|
|
239
240
|
}
|
|
240
241
|
/**
|
|
241
242
|
* Implements the non-readonly methods to throw `EROFS`
|
|
242
243
|
*/
|
|
243
244
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
244
245
|
export function Readonly(FS) {
|
|
245
|
-
class
|
|
246
|
+
class _ReadonlyFS extends FS {
|
|
246
247
|
metadata() {
|
|
247
248
|
return { ...super.metadata(), readonly: true };
|
|
248
249
|
}
|
|
@@ -290,5 +291,5 @@ export function Readonly(FS) {
|
|
|
290
291
|
throw new ErrnoError(Errno.EROFS);
|
|
291
292
|
}
|
|
292
293
|
}
|
|
293
|
-
return
|
|
294
|
+
return _ReadonlyFS;
|
|
294
295
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from './backends/Index.js';
|
|
|
6
6
|
export * from './backends/locked.js';
|
|
7
7
|
export * from './backends/overlay.js';
|
|
8
8
|
export * from './backends/store/fs.js';
|
|
9
|
+
export * from './backends/store/simple.js';
|
|
10
|
+
export * from './backends/store/store.js';
|
|
9
11
|
export * from './backends/backend.js';
|
|
10
12
|
export * from './config.js';
|
|
11
13
|
export * from './cred.js';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ export * from './backends/Index.js';
|
|
|
6
6
|
export * from './backends/locked.js';
|
|
7
7
|
export * from './backends/overlay.js';
|
|
8
8
|
export * from './backends/store/fs.js';
|
|
9
|
+
export * from './backends/store/simple.js';
|
|
10
|
+
export * from './backends/store/store.js';
|
|
9
11
|
export * from './backends/backend.js';
|
|
10
12
|
export * from './config.js';
|
|
11
13
|
export * from './cred.js';
|
package/dist/mutex.d.ts
CHANGED
package/dist/mutex.js
CHANGED
|
@@ -5,23 +5,23 @@ import { ErrnoError, Errno } from './error.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export class Mutex {
|
|
7
7
|
constructor() {
|
|
8
|
-
this.
|
|
8
|
+
this.locks = new Map();
|
|
9
9
|
}
|
|
10
10
|
lock(path) {
|
|
11
11
|
return new Promise(resolve => {
|
|
12
|
-
if (this.
|
|
13
|
-
this.
|
|
12
|
+
if (this.locks.has(path)) {
|
|
13
|
+
this.locks.get(path).push(resolve);
|
|
14
14
|
}
|
|
15
15
|
else {
|
|
16
|
-
this.
|
|
16
|
+
this.locks.set(path, [resolve]);
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
unlock(path) {
|
|
21
|
-
if (!this.
|
|
21
|
+
if (!this.locks.has(path)) {
|
|
22
22
|
throw new ErrnoError(Errno.EPERM, 'Can not unlock an already unlocked path', path);
|
|
23
23
|
}
|
|
24
|
-
const next = this.
|
|
24
|
+
const next = this.locks.get(path)?.shift();
|
|
25
25
|
/*
|
|
26
26
|
don't unlock - we want to queue up next for the
|
|
27
27
|
end of the current task execution, but we don't
|
|
@@ -31,19 +31,19 @@ export class Mutex {
|
|
|
31
31
|
lock won't cause starvation.
|
|
32
32
|
*/
|
|
33
33
|
if (next) {
|
|
34
|
-
setTimeout(next
|
|
34
|
+
setTimeout(next);
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
this.
|
|
37
|
+
this.locks.delete(path);
|
|
38
38
|
}
|
|
39
39
|
tryLock(path) {
|
|
40
|
-
if (this.
|
|
40
|
+
if (this.locks.has(path)) {
|
|
41
41
|
return false;
|
|
42
42
|
}
|
|
43
|
-
this.
|
|
43
|
+
this.locks.set(path, []);
|
|
44
44
|
return true;
|
|
45
45
|
}
|
|
46
46
|
isLocked(path) {
|
|
47
|
-
return this.
|
|
47
|
+
return this.locks.has(path);
|
|
48
48
|
}
|
|
49
49
|
}
|
package/package.json
CHANGED
package/scripts/make-index.js
CHANGED
|
@@ -16,19 +16,19 @@ const { values: options, positionals } = parseArgs({
|
|
|
16
16
|
allowPositionals: true,
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
const root = positionals.at(-1)
|
|
19
|
+
const root = positionals.at(-1) || '.';
|
|
20
20
|
|
|
21
21
|
if (options.help) {
|
|
22
22
|
console.log(`make-index <path> [...options]
|
|
23
|
-
path: The path to create a listing for
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
--help, -h Outputs this help message
|
|
27
|
-
--quiet, -q Do not output messages about individual files
|
|
28
|
-
--verbose Output verbose messages
|
|
24
|
+
path: The path to create a listing for
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
options:
|
|
27
|
+
--help, -h Outputs this help message
|
|
28
|
+
--quiet, -q The command will not generate any output, including error messages.
|
|
29
|
+
--verbose Output verbose messages
|
|
30
|
+
--output, -o <path> Path to the output file. Defaults to listing.
|
|
31
|
+
--ignore, -i <pattern> Ignores files which match the glob <pattern>. Can be passed multiple times.
|
|
32
32
|
`);
|
|
33
33
|
process.exit();
|
|
34
34
|
}
|
|
@@ -66,11 +66,13 @@ function color(color, text) {
|
|
|
66
66
|
return `\x1b[${colors[color]}m${text}\x1b[0m`;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function
|
|
69
|
+
function listing(path, seen = new Set()) {
|
|
70
70
|
try {
|
|
71
|
+
if (options.verbose) console.log(`${color('blue', 'list')} ${path}`);
|
|
71
72
|
const stats = statSync(path);
|
|
72
73
|
|
|
73
74
|
if (stats.isFile()) {
|
|
75
|
+
if (options.verbose) console.log(`${color('green', 'file')} ${path}`);
|
|
74
76
|
return null;
|
|
75
77
|
}
|
|
76
78
|
|
|
@@ -82,8 +84,9 @@ function makeListing(path, seen = new Set()) {
|
|
|
82
84
|
continue;
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
entries[file] =
|
|
87
|
+
entries[file] = listing(full, seen);
|
|
86
88
|
}
|
|
89
|
+
if (options.verbose) console.log(`${color('bright_green', ' dir')} ${path}`);
|
|
87
90
|
return entries;
|
|
88
91
|
} catch (e) {
|
|
89
92
|
if (!options.quiet) {
|
|
@@ -92,7 +95,7 @@ function makeListing(path, seen = new Set()) {
|
|
|
92
95
|
}
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
const
|
|
98
|
+
const rootListing = listing(pathToPosix(root));
|
|
96
99
|
if (!options.quiet) console.log('Generated listing for ' + pathToPosix(resolve(root)));
|
|
97
100
|
|
|
98
|
-
writeFileSync(options.output, JSON.stringify(
|
|
101
|
+
writeFileSync(options.output, JSON.stringify(rootListing));
|
package/src/backends/backend.ts
CHANGED
|
@@ -41,7 +41,7 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
|
|
|
41
41
|
/**
|
|
42
42
|
* Create a new instance of the backend
|
|
43
43
|
*/
|
|
44
|
-
create(options: TOptions): FS
|
|
44
|
+
create(options: TOptions): FS | Promise<FS>;
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* A name to identify the backend.
|
|
@@ -68,6 +68,8 @@ export interface Backend<FS extends FileSystem = FileSystem, TOptions extends ob
|
|
|
68
68
|
|
|
69
69
|
type OptionsOf<T extends Backend> = T extends Backend<FileSystem, infer TOptions> ? TOptions : never;
|
|
70
70
|
|
|
71
|
+
type FilesystemOf<T extends Backend> = T extends Backend<infer FS> ? FS : never;
|
|
72
|
+
|
|
71
73
|
/**
|
|
72
74
|
* @internal
|
|
73
75
|
*/
|
|
@@ -128,13 +130,6 @@ export async function checkOptions<T extends Backend>(backend: T, opts: Partial<
|
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
export async function createBackend<B extends Backend>(backend: B, options: Partial<OptionsOf<B>> = {}): Promise<ReturnType<B['create']>> {
|
|
132
|
-
await checkOptions(backend, options);
|
|
133
|
-
const fs = <ReturnType<B['create']>>backend.create(options);
|
|
134
|
-
await fs.ready();
|
|
135
|
-
return fs;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
133
|
/**
|
|
139
134
|
* Specifies a file system backend type and its options.
|
|
140
135
|
*
|
package/src/backends/fetch.ts
CHANGED
|
@@ -5,13 +5,6 @@ import { Stats } from '../stats.js';
|
|
|
5
5
|
import { type ListingTree, FileIndex, type IndexFileInode, AsyncIndexFS } from './Index.js';
|
|
6
6
|
import type { Backend } from './backend.js';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* @hidden
|
|
10
|
-
*/
|
|
11
|
-
function convertError(e: Error): never {
|
|
12
|
-
throw new ErrnoError(Errno.EIO, e.message);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
8
|
/**
|
|
16
9
|
* Asynchronously download a file as a buffer or a JSON object.
|
|
17
10
|
* Note that the third function signature with a non-specialized type is
|
|
@@ -23,16 +16,22 @@ async function fetchFile(path: string, type: 'buffer'): Promise<Uint8Array>;
|
|
|
23
16
|
async function fetchFile<T extends object>(path: string, type: 'json'): Promise<T>;
|
|
24
17
|
async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'): Promise<T | Uint8Array>;
|
|
25
18
|
async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'): Promise<T | Uint8Array> {
|
|
26
|
-
const response = await fetch(path).catch(
|
|
19
|
+
const response = await fetch(path).catch(e => {
|
|
20
|
+
throw new ErrnoError(Errno.EIO, e.message);
|
|
21
|
+
});
|
|
27
22
|
if (!response.ok) {
|
|
28
23
|
throw new ErrnoError(Errno.EIO, 'fetch failed: response returned code ' + response.status);
|
|
29
24
|
}
|
|
30
25
|
switch (type) {
|
|
31
26
|
case 'buffer':
|
|
32
|
-
const arrayBuffer = await response.arrayBuffer().catch(
|
|
27
|
+
const arrayBuffer = await response.arrayBuffer().catch(e => {
|
|
28
|
+
throw new ErrnoError(Errno.EIO, e.message);
|
|
29
|
+
});
|
|
33
30
|
return new Uint8Array(arrayBuffer);
|
|
34
31
|
case 'json':
|
|
35
|
-
return response.json().catch(
|
|
32
|
+
return response.json().catch(e => {
|
|
33
|
+
throw new ErrnoError(Errno.EIO, e.message);
|
|
34
|
+
}) as Promise<T>;
|
|
36
35
|
default:
|
|
37
36
|
throw new ErrnoError(Errno.EINVAL, 'Invalid download type: ' + type);
|
|
38
37
|
}
|
|
@@ -43,7 +42,9 @@ async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'
|
|
|
43
42
|
* @hidden
|
|
44
43
|
*/
|
|
45
44
|
async function fetchSize(path: string): Promise<number> {
|
|
46
|
-
const response = await fetch(path, { method: 'HEAD' }).catch(
|
|
45
|
+
const response = await fetch(path, { method: 'HEAD' }).catch(e => {
|
|
46
|
+
throw new ErrnoError(Errno.EIO, e.message);
|
|
47
|
+
});
|
|
47
48
|
if (!response.ok) {
|
|
48
49
|
throw new ErrnoError(Errno.EIO, 'fetch failed: HEAD response returned code ' + response.status);
|
|
49
50
|
}
|
|
@@ -210,7 +211,7 @@ export const Fetch = {
|
|
|
210
211
|
index: {
|
|
211
212
|
type: ['string', 'object'],
|
|
212
213
|
required: false,
|
|
213
|
-
description: 'URL to a file index as a JSON file or the file index object itself, generated with the
|
|
214
|
+
description: 'URL to a file index as a JSON file or the file index object itself, generated with the make-index script. Defaults to `index.json`.',
|
|
214
215
|
},
|
|
215
216
|
baseUrl: {
|
|
216
217
|
type: 'string',
|