@zenfs/core 0.16.0 → 0.16.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/fetch.js +5 -4
- package/dist/backends/index/fs.js +12 -5
- package/dist/backends/overlay.d.ts +1 -1
- package/dist/backends/overlay.js +9 -9
- package/dist/backends/port/fs.d.ts +22 -0
- package/dist/backends/port/fs.js +12 -1
- package/dist/backends/port/rpc.d.ts +2 -0
- package/dist/backends/port/rpc.js +13 -1
- package/dist/backends/store/fs.js +1 -1
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +1 -2
- package/dist/config.js +2 -2
- package/dist/emulation/async.d.ts +4 -5
- package/dist/emulation/async.js +9 -9
- package/dist/emulation/dir.js +1 -1
- package/dist/emulation/promises.js +10 -5
- package/dist/emulation/sync.d.ts +1 -0
- package/dist/emulation/sync.js +1 -1
- package/dist/file.js +6 -6
- package/dist/filesystem.js +1 -1
- package/dist/inode.d.ts +1 -1
- package/dist/inode.js +54 -37
- package/dist/polyfills.js +1 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/eslint.shared.js +53 -0
- package/package.json +16 -6
- package/src/backends/fetch.ts +6 -5
- package/src/backends/index/fs.ts +12 -5
- package/src/backends/index/index.ts +1 -1
- package/src/backends/overlay.ts +9 -9
- package/src/backends/port/fs.ts +18 -3
- package/src/backends/port/readme.md +7 -12
- package/src/backends/port/rpc.ts +16 -1
- package/src/backends/store/fs.ts +2 -2
- package/src/config.ts +3 -3
- package/src/emulation/async.ts +31 -18
- package/src/emulation/dir.ts +1 -1
- package/src/emulation/promises.ts +11 -6
- package/src/emulation/sync.ts +5 -4
- package/src/file.ts +6 -6
- package/src/filesystem.ts +2 -1
- package/src/inode.ts +56 -37
- package/src/polyfills.ts +1 -0
- package/src/utils.ts +5 -2
package/dist/config.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type MountConfiguration<T extends Backend> = FilesystemOf<T> | BackendCon
|
|
|
9
9
|
* @see MountConfiguration
|
|
10
10
|
*/
|
|
11
11
|
export declare function resolveMountConfig<T extends Backend>(config: MountConfiguration<T>, _depth?: number): Promise<FilesystemOf<T>>;
|
|
12
|
-
type ConfigMounts = {
|
|
12
|
+
export type ConfigMounts = {
|
|
13
13
|
[K in AbsolutePath]: Backend;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
@@ -40,4 +40,3 @@ export declare function configureSingle<T extends Backend>(config: MountConfigur
|
|
|
40
40
|
* @see Configuration
|
|
41
41
|
*/
|
|
42
42
|
export declare function configure<T extends ConfigMounts>(config: Partial<Configuration<T>>): Promise<void>;
|
|
43
|
-
export {};
|
package/dist/config.js
CHANGED
|
@@ -37,9 +37,9 @@ export async function resolveMountConfig(config, _depth = 0) {
|
|
|
37
37
|
}
|
|
38
38
|
const { backend } = config;
|
|
39
39
|
if (!(await backend.isAvailable())) {
|
|
40
|
-
throw new ErrnoError(Errno.EPERM, 'Backend not available: ' + backend);
|
|
40
|
+
throw new ErrnoError(Errno.EPERM, 'Backend not available: ' + backend.name);
|
|
41
41
|
}
|
|
42
|
-
checkOptions(backend, config);
|
|
42
|
+
await checkOptions(backend, config);
|
|
43
43
|
const mount = (await backend.create(config));
|
|
44
44
|
if ('_disableSync' in mount) {
|
|
45
45
|
mount._disableSync = config.disableAsyncCache || false;
|
|
@@ -141,12 +141,11 @@ export declare function writeFile(filename: fs.PathLike, data: FileContents, opt
|
|
|
141
141
|
* @param callback
|
|
142
142
|
*/
|
|
143
143
|
export declare function appendFile(filename: fs.PathLike, data: FileContents, cb?: Callback): void;
|
|
144
|
-
export declare function appendFile(filename: fs.PathLike, data: FileContents, options?: {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
flag?: string;
|
|
144
|
+
export declare function appendFile(filename: fs.PathLike, data: FileContents, options?: fs.EncodingOption & {
|
|
145
|
+
mode?: fs.Mode;
|
|
146
|
+
flag?: fs.OpenMode;
|
|
148
147
|
}, cb?: Callback): void;
|
|
149
|
-
export declare function appendFile(filename: fs.PathLike, data: FileContents, encoding?:
|
|
148
|
+
export declare function appendFile(filename: fs.PathLike, data: FileContents, encoding?: BufferEncoding, cb?: Callback): void;
|
|
150
149
|
/**
|
|
151
150
|
* Asynchronous `fstat`.
|
|
152
151
|
* `fstat()` is identical to `stat()`, except that the file to be stat-ed is
|
package/dist/emulation/async.js
CHANGED
|
@@ -97,9 +97,10 @@ export function writeFile(filename, data, cbEncOpts, cb = nop) {
|
|
|
97
97
|
}
|
|
98
98
|
writeFile;
|
|
99
99
|
export function appendFile(filename, data, cbEncOpts, cb = nop) {
|
|
100
|
+
const optionsOrEncoding = typeof cbEncOpts != 'function' ? cbEncOpts : undefined;
|
|
100
101
|
cb = typeof cbEncOpts === 'function' ? cbEncOpts : cb;
|
|
101
102
|
promises
|
|
102
|
-
.appendFile(filename, data,
|
|
103
|
+
.appendFile(filename, data, optionsOrEncoding)
|
|
103
104
|
.then(() => cb())
|
|
104
105
|
.catch(cb);
|
|
105
106
|
}
|
|
@@ -160,7 +161,7 @@ export function fdatasync(fd, cb = nop) {
|
|
|
160
161
|
.catch(cb);
|
|
161
162
|
}
|
|
162
163
|
fdatasync;
|
|
163
|
-
export function write(fd, data, cbPosOff, cbLenEnc,
|
|
164
|
+
export function write(fd, data, cbPosOff, cbLenEnc, cbPosEnc, cb = nop) {
|
|
164
165
|
let buffer, offset, length, position, encoding;
|
|
165
166
|
const handle = new promises.FileHandle(fd);
|
|
166
167
|
if (typeof data === 'string') {
|
|
@@ -175,11 +176,11 @@ export function write(fd, data, cbPosOff, cbLenEnc, cbPos, cb = nop) {
|
|
|
175
176
|
// (fd, string, position, encoding?, cb?)
|
|
176
177
|
position = cbPosOff;
|
|
177
178
|
encoding = typeof cbLenEnc === 'string' ? cbLenEnc : 'utf8';
|
|
178
|
-
cb = typeof
|
|
179
|
+
cb = typeof cbPosEnc === 'function' ? cbPosEnc : cb;
|
|
179
180
|
break;
|
|
180
181
|
default:
|
|
181
182
|
// ...try to find the callback and get out of here!
|
|
182
|
-
cb = typeof cbLenEnc === 'function' ? cbLenEnc : typeof
|
|
183
|
+
cb = (typeof cbLenEnc === 'function' ? cbLenEnc : typeof cbPosEnc === 'function' ? cbPosEnc : cb);
|
|
183
184
|
cb(new ErrnoError(Errno.EINVAL, 'Invalid arguments.'));
|
|
184
185
|
return;
|
|
185
186
|
}
|
|
@@ -197,9 +198,9 @@ export function write(fd, data, cbPosOff, cbLenEnc, cbPos, cb = nop) {
|
|
|
197
198
|
buffer = Buffer.from(data.buffer);
|
|
198
199
|
offset = cbPosOff;
|
|
199
200
|
length = cbLenEnc;
|
|
200
|
-
position = typeof
|
|
201
|
-
const _cb = typeof
|
|
202
|
-
handle
|
|
201
|
+
position = typeof cbPosEnc === 'number' ? cbPosEnc : null;
|
|
202
|
+
const _cb = (typeof cbPosEnc === 'function' ? cbPosEnc : cb);
|
|
203
|
+
void handle
|
|
203
204
|
.write(buffer, offset, length, position)
|
|
204
205
|
.then(({ bytesWritten }) => _cb(undefined, bytesWritten, buffer))
|
|
205
206
|
.catch(_cb);
|
|
@@ -297,7 +298,6 @@ export function readdir(path, _options, cb = nop) {
|
|
|
297
298
|
const options = typeof _options != 'function' ? _options : {};
|
|
298
299
|
promises
|
|
299
300
|
.readdir(path, options)
|
|
300
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
301
301
|
.then(entries => cb(undefined, entries))
|
|
302
302
|
.catch(cb);
|
|
303
303
|
}
|
|
@@ -426,7 +426,7 @@ export function access(path, cbMode, cb = nop) {
|
|
|
426
426
|
const mode = typeof cbMode === 'number' ? cbMode : R_OK;
|
|
427
427
|
cb = typeof cbMode === 'function' ? cbMode : cb;
|
|
428
428
|
promises
|
|
429
|
-
.access(path,
|
|
429
|
+
.access(path, mode)
|
|
430
430
|
.then(() => cb())
|
|
431
431
|
.catch(cb);
|
|
432
432
|
}
|
package/dist/emulation/dir.js
CHANGED
|
@@ -76,7 +76,7 @@ export class Dir {
|
|
|
76
76
|
if (!cb) {
|
|
77
77
|
return this._read();
|
|
78
78
|
}
|
|
79
|
-
this._read().then(value => cb(undefined, value));
|
|
79
|
+
void this._read().then(value => cb(undefined, value));
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
82
82
|
* Synchronously read the next directory entry via `readdir(3)` as a `Dirent`.
|
|
@@ -169,17 +169,17 @@ export class FileHandle {
|
|
|
169
169
|
*/
|
|
170
170
|
readableWebStream(options = {}) {
|
|
171
171
|
// Note: using an arrow function to preserve `this`
|
|
172
|
-
const start = async (
|
|
172
|
+
const start = async (controller) => {
|
|
173
173
|
try {
|
|
174
174
|
const chunkSize = 64 * 1024, maxChunks = 1e7;
|
|
175
175
|
let i = 0, position = 0, bytesRead = NaN;
|
|
176
176
|
while (bytesRead > 0) {
|
|
177
177
|
const result = await this.read(new Uint8Array(chunkSize), 0, chunkSize, position);
|
|
178
178
|
if (!result.bytesRead) {
|
|
179
|
-
close();
|
|
179
|
+
controller.close();
|
|
180
180
|
return;
|
|
181
181
|
}
|
|
182
|
-
enqueue(result.buffer.slice(0, result.bytesRead));
|
|
182
|
+
controller.enqueue(result.buffer.slice(0, result.bytesRead));
|
|
183
183
|
position += result.bytesRead;
|
|
184
184
|
if (++i >= maxChunks) {
|
|
185
185
|
throw new ErrnoError(Errno.EFBIG, 'Too many iterations on readable stream', this.file.path, 'FileHandle.readableWebStream');
|
|
@@ -188,10 +188,14 @@ export class FileHandle {
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
catch (e) {
|
|
191
|
-
error(e);
|
|
191
|
+
controller.error(e);
|
|
192
192
|
}
|
|
193
193
|
};
|
|
194
|
-
|
|
194
|
+
const _gt = globalThis;
|
|
195
|
+
if (!('ReadableStream' in _gt)) {
|
|
196
|
+
throw new ErrnoError(Errno.ENOSYS, 'ReadableStream is missing on globalThis');
|
|
197
|
+
}
|
|
198
|
+
return new _gt.ReadableStream({ start, type: options.type });
|
|
195
199
|
}
|
|
196
200
|
readLines(options) {
|
|
197
201
|
throw ErrnoError.With('ENOSYS', this.file.path, 'FileHandle.readLines');
|
|
@@ -290,6 +294,7 @@ export class FileHandle {
|
|
|
290
294
|
const stream = new ReadStream({
|
|
291
295
|
highWaterMark: options?.highWaterMark || 64 * 1024,
|
|
292
296
|
encoding: options.encoding,
|
|
297
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
293
298
|
read: async (size) => {
|
|
294
299
|
try {
|
|
295
300
|
const result = await this.read(new Uint8Array(size), 0, size, this.file.position);
|
package/dist/emulation/sync.d.ts
CHANGED
|
@@ -247,6 +247,7 @@ export declare function symlinkSync(target: fs.PathLike, path: fs.PathLike, type
|
|
|
247
247
|
*/
|
|
248
248
|
export declare function readlinkSync(path: fs.PathLike, options?: fs.BufferEncodingOption): Buffer;
|
|
249
249
|
export declare function readlinkSync(path: fs.PathLike, options: fs.EncodingOption | BufferEncoding): string;
|
|
250
|
+
export declare function readlinkSync(path: fs.PathLike, options?: fs.EncodingOption | BufferEncoding | fs.BufferEncodingOption): Buffer | string;
|
|
250
251
|
/**
|
|
251
252
|
* Synchronous `chown`.
|
|
252
253
|
* @param path
|
package/dist/emulation/sync.js
CHANGED
|
@@ -618,7 +618,7 @@ export function realpathSync(path, options) {
|
|
|
618
618
|
if (!stats.isSymbolicLink()) {
|
|
619
619
|
return lpath;
|
|
620
620
|
}
|
|
621
|
-
return realpathSync(mountPoint + readlinkSync(lpath));
|
|
621
|
+
return realpathSync(mountPoint + readlinkSync(lpath, options).toString());
|
|
622
622
|
}
|
|
623
623
|
catch (e) {
|
|
624
624
|
throw fixError(e, { [resolvedPath]: lpath });
|
package/dist/file.js
CHANGED
|
@@ -228,8 +228,8 @@ export class PreloadFile extends File {
|
|
|
228
228
|
/**
|
|
229
229
|
* Asynchronous `stat`.
|
|
230
230
|
*/
|
|
231
|
-
|
|
232
|
-
return new Stats(this.stats);
|
|
231
|
+
stat() {
|
|
232
|
+
return Promise.resolve(new Stats(this.stats));
|
|
233
233
|
}
|
|
234
234
|
/**
|
|
235
235
|
* Synchronous `stat`.
|
|
@@ -453,8 +453,8 @@ export class NoSyncFile extends PreloadFile {
|
|
|
453
453
|
/**
|
|
454
454
|
* Asynchronous sync. Doesn't do anything, simply calls the cb.
|
|
455
455
|
*/
|
|
456
|
-
|
|
457
|
-
return;
|
|
456
|
+
sync() {
|
|
457
|
+
return Promise.resolve();
|
|
458
458
|
}
|
|
459
459
|
/**
|
|
460
460
|
* Synchronous sync. Doesn't do anything.
|
|
@@ -465,8 +465,8 @@ export class NoSyncFile extends PreloadFile {
|
|
|
465
465
|
/**
|
|
466
466
|
* Asynchronous close. Doesn't do anything, simply calls the cb.
|
|
467
467
|
*/
|
|
468
|
-
|
|
469
|
-
return;
|
|
468
|
+
close() {
|
|
469
|
+
return Promise.resolve();
|
|
470
470
|
}
|
|
471
471
|
/**
|
|
472
472
|
* Synchronous close. Doesn't do anything.
|
package/dist/filesystem.js
CHANGED
package/dist/inode.d.ts
CHANGED
package/dist/inode.js
CHANGED
|
@@ -25,20 +25,37 @@ export function randomIno() {
|
|
|
25
25
|
/**
|
|
26
26
|
* Offsets for inode members
|
|
27
27
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
const offsets = {
|
|
29
|
+
ino: 0,
|
|
30
|
+
size: 8,
|
|
31
|
+
mode: 12,
|
|
32
|
+
nlink: 14,
|
|
33
|
+
uid: 18,
|
|
34
|
+
gid: 22,
|
|
35
|
+
atime: 26,
|
|
36
|
+
birthtime: 34,
|
|
37
|
+
mtime: 42,
|
|
38
|
+
ctime: 50,
|
|
39
|
+
end: 58,
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Offsets for a 64-bit inode's members
|
|
43
|
+
* Currently unused
|
|
44
|
+
*/
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
46
|
+
const offsets_64 = {
|
|
47
|
+
ino: 0,
|
|
48
|
+
size: 8,
|
|
49
|
+
mode: 16,
|
|
50
|
+
nlink: 18,
|
|
51
|
+
uid: 22,
|
|
52
|
+
gid: 26,
|
|
53
|
+
atime: 30,
|
|
54
|
+
birthtime: 38,
|
|
55
|
+
mtime: 46,
|
|
56
|
+
ctime: 54,
|
|
57
|
+
end: 62,
|
|
58
|
+
};
|
|
42
59
|
/**
|
|
43
60
|
* Generic inode definition that can easily be serialized.
|
|
44
61
|
*/
|
|
@@ -48,9 +65,9 @@ export class Inode {
|
|
|
48
65
|
}
|
|
49
66
|
constructor(buffer) {
|
|
50
67
|
const setDefaults = !buffer;
|
|
51
|
-
buffer ?? (buffer = new ArrayBuffer(
|
|
52
|
-
if (buffer?.byteLength <
|
|
53
|
-
throw new RangeError(`Can not create an inode from a buffer less than ${
|
|
68
|
+
buffer ?? (buffer = new ArrayBuffer(offsets.end));
|
|
69
|
+
if (buffer?.byteLength < offsets.end) {
|
|
70
|
+
throw new RangeError(`Can not create an inode from a buffer less than ${offsets.end} bytes`);
|
|
54
71
|
}
|
|
55
72
|
this.view = new DataView(buffer);
|
|
56
73
|
this.buffer = buffer;
|
|
@@ -68,64 +85,64 @@ export class Inode {
|
|
|
68
85
|
this.birthtimeMs = now;
|
|
69
86
|
}
|
|
70
87
|
get ino() {
|
|
71
|
-
return this.view.getBigUint64(
|
|
88
|
+
return this.view.getBigUint64(offsets.ino, true);
|
|
72
89
|
}
|
|
73
90
|
set ino(value) {
|
|
74
|
-
this.view.setBigUint64(
|
|
91
|
+
this.view.setBigUint64(offsets.ino, value, true);
|
|
75
92
|
}
|
|
76
93
|
get size() {
|
|
77
|
-
return this.view.getUint32(
|
|
94
|
+
return this.view.getUint32(offsets.size, true);
|
|
78
95
|
}
|
|
79
96
|
set size(value) {
|
|
80
|
-
this.view.setUint32(
|
|
97
|
+
this.view.setUint32(offsets.size, value, true);
|
|
81
98
|
}
|
|
82
99
|
get mode() {
|
|
83
|
-
return this.view.getUint16(
|
|
100
|
+
return this.view.getUint16(offsets.mode, true);
|
|
84
101
|
}
|
|
85
102
|
set mode(value) {
|
|
86
|
-
this.view.setUint16(
|
|
103
|
+
this.view.setUint16(offsets.mode, value, true);
|
|
87
104
|
}
|
|
88
105
|
get nlink() {
|
|
89
|
-
return this.view.getUint32(
|
|
106
|
+
return this.view.getUint32(offsets.nlink, true);
|
|
90
107
|
}
|
|
91
108
|
set nlink(value) {
|
|
92
|
-
this.view.setUint32(
|
|
109
|
+
this.view.setUint32(offsets.nlink, value, true);
|
|
93
110
|
}
|
|
94
111
|
get uid() {
|
|
95
|
-
return this.view.getUint32(
|
|
112
|
+
return this.view.getUint32(offsets.uid, true);
|
|
96
113
|
}
|
|
97
114
|
set uid(value) {
|
|
98
|
-
this.view.setUint32(
|
|
115
|
+
this.view.setUint32(offsets.uid, value, true);
|
|
99
116
|
}
|
|
100
117
|
get gid() {
|
|
101
|
-
return this.view.getUint32(
|
|
118
|
+
return this.view.getUint32(offsets.gid, true);
|
|
102
119
|
}
|
|
103
120
|
set gid(value) {
|
|
104
|
-
this.view.setUint32(
|
|
121
|
+
this.view.setUint32(offsets.gid, value, true);
|
|
105
122
|
}
|
|
106
123
|
get atimeMs() {
|
|
107
|
-
return this.view.getFloat64(
|
|
124
|
+
return this.view.getFloat64(offsets.atime, true);
|
|
108
125
|
}
|
|
109
126
|
set atimeMs(value) {
|
|
110
|
-
this.view.setFloat64(
|
|
127
|
+
this.view.setFloat64(offsets.atime, value, true);
|
|
111
128
|
}
|
|
112
129
|
get birthtimeMs() {
|
|
113
|
-
return this.view.getFloat64(
|
|
130
|
+
return this.view.getFloat64(offsets.birthtime, true);
|
|
114
131
|
}
|
|
115
132
|
set birthtimeMs(value) {
|
|
116
|
-
this.view.setFloat64(
|
|
133
|
+
this.view.setFloat64(offsets.birthtime, value, true);
|
|
117
134
|
}
|
|
118
135
|
get mtimeMs() {
|
|
119
|
-
return this.view.getFloat64(
|
|
136
|
+
return this.view.getFloat64(offsets.mtime, true);
|
|
120
137
|
}
|
|
121
138
|
set mtimeMs(value) {
|
|
122
|
-
this.view.setFloat64(
|
|
139
|
+
this.view.setFloat64(offsets.mtime, value, true);
|
|
123
140
|
}
|
|
124
141
|
get ctimeMs() {
|
|
125
|
-
return this.view.getFloat64(
|
|
142
|
+
return this.view.getFloat64(offsets.ctime, true);
|
|
126
143
|
}
|
|
127
144
|
set ctimeMs(value) {
|
|
128
|
-
this.view.setFloat64(
|
|
145
|
+
this.view.setFloat64(offsets.ctime, value, true);
|
|
129
146
|
}
|
|
130
147
|
/**
|
|
131
148
|
* Handy function that converts the Inode to a Node Stats object.
|
package/dist/polyfills.js
CHANGED
package/dist/utils.d.ts
CHANGED
|
@@ -56,7 +56,7 @@ export declare function _toUnixTimestamp(time: Date | number): number;
|
|
|
56
56
|
* Normalizes a mode
|
|
57
57
|
* @internal
|
|
58
58
|
*/
|
|
59
|
-
export declare function normalizeMode(mode:
|
|
59
|
+
export declare function normalizeMode(mode: unknown, def?: number): number;
|
|
60
60
|
/**
|
|
61
61
|
* Normalizes a time
|
|
62
62
|
* @internal
|
package/dist/utils.js
CHANGED
|
@@ -146,7 +146,7 @@ export function _toUnixTimestamp(time) {
|
|
|
146
146
|
if (time instanceof Date) {
|
|
147
147
|
return Math.floor(time.getTime() / 1000);
|
|
148
148
|
}
|
|
149
|
-
throw new Error('Cannot parse time
|
|
149
|
+
throw new Error('Cannot parse time');
|
|
150
150
|
}
|
|
151
151
|
/**
|
|
152
152
|
* Normalizes a mode
|
package/eslint.shared.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Shared eslint rules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import eslint from '@eslint/js';
|
|
6
|
+
import stylistic from '@stylistic/eslint-plugin';
|
|
7
|
+
import globals from 'globals';
|
|
8
|
+
import tseslint from 'typescript-eslint';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
name: 'ZenFS',
|
|
12
|
+
extends: [eslint.configs.recommended, ...tseslint.configs.recommendedTypeChecked],
|
|
13
|
+
files: ['src/**/*.ts', 'tests/**/*.ts'],
|
|
14
|
+
languageOptions: {
|
|
15
|
+
globals: { ...globals.browser, ...globals.node },
|
|
16
|
+
ecmaVersion: 'latest',
|
|
17
|
+
sourceType: 'module',
|
|
18
|
+
},
|
|
19
|
+
plugins: { stylistic },
|
|
20
|
+
rules: {
|
|
21
|
+
'no-useless-escape': 'warn',
|
|
22
|
+
'stylistic/no-mixed-spaces-and-tabs': 'warn',
|
|
23
|
+
'no-unreachable': 'warn',
|
|
24
|
+
'stylistic/no-extra-semi': 'warn',
|
|
25
|
+
'no-fallthrough': 'warn',
|
|
26
|
+
'no-empty': 'warn',
|
|
27
|
+
'no-case-declarations': 'warn',
|
|
28
|
+
'prefer-const': 'warn',
|
|
29
|
+
'prefer-rest-params': 'warn',
|
|
30
|
+
'prefer-spread': 'warn',
|
|
31
|
+
'no-unused-vars': 'off',
|
|
32
|
+
'@typescript-eslint/no-unused-vars': 'warn',
|
|
33
|
+
'@typescript-eslint/no-inferrable-types': 'off',
|
|
34
|
+
'@typescript-eslint/no-this-alias': 'off',
|
|
35
|
+
'@typescript-eslint/no-unsafe-function-type': 'warn',
|
|
36
|
+
'@typescript-eslint/no-wrapper-object-types': 'warn',
|
|
37
|
+
'@typescript-eslint/triple-slash-reference': 'warn',
|
|
38
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
39
|
+
'@typescript-eslint/no-namespace': 'warn',
|
|
40
|
+
'@typescript-eslint/prefer-as-const': 'warn',
|
|
41
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
42
|
+
'@typescript-eslint/consistent-type-assertions': 'warn',
|
|
43
|
+
'@typescript-eslint/consistent-type-imports': 'warn',
|
|
44
|
+
'@typescript-eslint/no-unnecessary-type-assertion': 'warn',
|
|
45
|
+
'@typescript-eslint/require-await': 'warn',
|
|
46
|
+
'@typescript-eslint/no-unsafe-return': 'warn',
|
|
47
|
+
'@typescript-eslint/no-unsafe-assignment': 'warn',
|
|
48
|
+
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
|
49
|
+
'@typescript-eslint/no-unsafe-argument': 'warn',
|
|
50
|
+
'@typescript-eslint/no-redundant-type-constituents': 'warn',
|
|
51
|
+
'@typescript-eslint/no-unsafe-call': 'warn',
|
|
52
|
+
},
|
|
53
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenfs/core",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "A filesystem, anywhere",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"dist",
|
|
18
18
|
"src",
|
|
19
19
|
"license.md",
|
|
20
|
-
"tsconfig.json"
|
|
20
|
+
"tsconfig.json",
|
|
21
|
+
"eslint.shared.js"
|
|
21
22
|
],
|
|
22
23
|
"type": "module",
|
|
23
24
|
"homepage": "https://github.com/zen-fs/core",
|
|
@@ -51,6 +52,11 @@
|
|
|
51
52
|
"dev": "npm run build -- --watch",
|
|
52
53
|
"prepublishOnly": "npm run build"
|
|
53
54
|
},
|
|
55
|
+
"lint-staged": {
|
|
56
|
+
"*": [
|
|
57
|
+
"prettier --write"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
54
60
|
"dependencies": {
|
|
55
61
|
"@types/node": "^20.12.12",
|
|
56
62
|
"@types/readable-stream": "^4.0.10",
|
|
@@ -61,19 +67,23 @@
|
|
|
61
67
|
"utilium": "^0.4.0"
|
|
62
68
|
},
|
|
63
69
|
"devDependencies": {
|
|
70
|
+
"@eslint/js": "^9.8.0",
|
|
64
71
|
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
|
65
72
|
"@jest/globals": "^29.5.0",
|
|
73
|
+
"@stylistic/eslint-plugin": "^2.6.1",
|
|
74
|
+
"@types/eslint__js": "^8.42.3",
|
|
66
75
|
"@types/jest": "^29.5.1",
|
|
67
|
-
"@typescript-eslint/eslint-plugin": "^7.7.0",
|
|
68
|
-
"@typescript-eslint/parser": "^7.7.0",
|
|
69
76
|
"cross-env": "^7.0.3",
|
|
70
77
|
"esbuild": "^0.21.0",
|
|
71
|
-
"eslint": "^8.
|
|
78
|
+
"eslint": "^9.8.0",
|
|
79
|
+
"globals": "^15.9.0",
|
|
72
80
|
"jest": "^29.7.0",
|
|
81
|
+
"lint-staged": "^15.2.7",
|
|
73
82
|
"prettier": "^3.2.5",
|
|
74
83
|
"ts-jest": "^29.1.5",
|
|
75
84
|
"typedoc": "^0.25.13",
|
|
76
85
|
"typedoc-plugin-remove-references": "^0.0.6",
|
|
77
|
-
"typescript": "^5.4.0"
|
|
86
|
+
"typescript": "^5.4.0",
|
|
87
|
+
"typescript-eslint": "^8.0.0"
|
|
78
88
|
}
|
|
79
89
|
}
|
package/src/backends/fetch.ts
CHANGED
|
@@ -15,21 +15,22 @@ import type { IndexData } from './index/index.js';
|
|
|
15
15
|
async function fetchFile(path: string, type: 'buffer'): Promise<Uint8Array>;
|
|
16
16
|
async function fetchFile<T extends object>(path: string, type: 'json'): Promise<T>;
|
|
17
17
|
async function fetchFile<T extends object>(path: string, type: 'buffer' | 'json'): Promise<T | Uint8Array>;
|
|
18
|
-
async function fetchFile<T extends object>(path: string, type:
|
|
19
|
-
const response = await fetch(path).catch(e => {
|
|
18
|
+
async function fetchFile<T extends object>(path: string, type: string): Promise<T | Uint8Array> {
|
|
19
|
+
const response = await fetch(path).catch((e: Error) => {
|
|
20
20
|
throw new ErrnoError(Errno.EIO, e.message);
|
|
21
21
|
});
|
|
22
22
|
if (!response.ok) {
|
|
23
23
|
throw new ErrnoError(Errno.EIO, 'fetch failed: response returned code ' + response.status);
|
|
24
24
|
}
|
|
25
25
|
switch (type) {
|
|
26
|
-
case 'buffer':
|
|
27
|
-
const arrayBuffer = await response.arrayBuffer().catch(e => {
|
|
26
|
+
case 'buffer': {
|
|
27
|
+
const arrayBuffer = await response.arrayBuffer().catch((e: Error) => {
|
|
28
28
|
throw new ErrnoError(Errno.EIO, e.message);
|
|
29
29
|
});
|
|
30
30
|
return new Uint8Array(arrayBuffer);
|
|
31
|
+
}
|
|
31
32
|
case 'json':
|
|
32
|
-
return response.json().catch(e => {
|
|
33
|
+
return response.json().catch((e: Error) => {
|
|
33
34
|
throw new ErrnoError(Errno.EIO, e.message);
|
|
34
35
|
}) as Promise<T>;
|
|
35
36
|
default:
|
package/src/backends/index/fs.ts
CHANGED
|
@@ -39,8 +39,8 @@ export abstract class IndexFS extends Readonly(FileSystem) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
public
|
|
43
|
-
return this.statSync(path);
|
|
42
|
+
public stat(path: string): Promise<Stats> {
|
|
43
|
+
return Promise.resolve(this.statSync(path));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
public statSync(path: string): Stats {
|
|
@@ -91,8 +91,8 @@ export abstract class IndexFS extends Readonly(FileSystem) {
|
|
|
91
91
|
return new NoSyncFile(this, path, flag, stats, stats.isDirectory() ? stats.fileData : this.getDataSync(path, stats));
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
public
|
|
95
|
-
return this.readdirSync(path);
|
|
94
|
+
public readdir(path: string): Promise<string[]> {
|
|
95
|
+
return Promise.resolve(this.readdirSync(path));
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
public readdirSync(path: string): string[] {
|
|
@@ -106,7 +106,14 @@ export abstract class IndexFS extends Readonly(FileSystem) {
|
|
|
106
106
|
throw ErrnoError.With('ENOTDIR', path, 'readdir');
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
const content: unknown = JSON.parse(decode(stats.fileData));
|
|
110
|
+
if (!Array.isArray(content)) {
|
|
111
|
+
throw ErrnoError.With('ENODATA', path, 'readdir');
|
|
112
|
+
}
|
|
113
|
+
if (!content.every(item => typeof item == 'string')) {
|
|
114
|
+
throw ErrnoError.With('ENODATA', path, 'readdir');
|
|
115
|
+
}
|
|
116
|
+
return content as string[];
|
|
110
117
|
}
|
|
111
118
|
|
|
112
119
|
protected abstract getData(path: string, stats: Stats): Promise<Uint8Array>;
|
|
@@ -96,7 +96,7 @@ export class Index extends Map<string, Stats> {
|
|
|
96
96
|
throw new ErrnoError(Errno.EINVAL, 'Invalid JSON');
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
const json = JSON.parse(data);
|
|
99
|
+
const json = JSON.parse(data) as IndexData;
|
|
100
100
|
const index = new Index();
|
|
101
101
|
index.fromJSON(json);
|
|
102
102
|
return index;
|