@zenfs/core 0.1.0 → 0.2.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/ApiError.d.ts +51 -14
- package/dist/ApiError.js +60 -34
- package/dist/FileIndex.d.ts +32 -35
- package/dist/FileIndex.js +93 -109
- package/dist/backends/AsyncMirror.d.ts +42 -43
- package/dist/backends/AsyncMirror.js +146 -133
- package/dist/backends/AsyncStore.d.ts +29 -28
- package/dist/backends/AsyncStore.js +139 -189
- package/dist/backends/InMemory.d.ts +16 -13
- package/dist/backends/InMemory.js +29 -14
- package/dist/backends/Locked.d.ts +8 -28
- package/dist/backends/Locked.js +44 -148
- package/dist/backends/OverlayFS.d.ts +26 -34
- package/dist/backends/OverlayFS.js +208 -371
- package/dist/backends/SyncStore.d.ts +54 -72
- package/dist/backends/SyncStore.js +159 -161
- package/dist/backends/backend.d.ts +45 -29
- package/dist/backends/backend.js +83 -13
- package/dist/backends/index.d.ts +6 -7
- package/dist/backends/index.js +5 -6
- package/dist/browser.min.js +5 -7
- package/dist/browser.min.js.map +4 -4
- package/dist/emulation/callbacks.d.ts +36 -67
- package/dist/emulation/callbacks.js +90 -46
- package/dist/emulation/constants.js +1 -1
- package/dist/emulation/promises.d.ts +228 -129
- package/dist/emulation/promises.js +414 -172
- package/dist/emulation/shared.d.ts +10 -10
- package/dist/emulation/shared.js +18 -20
- package/dist/emulation/sync.d.ts +25 -25
- package/dist/emulation/sync.js +187 -73
- package/dist/file.d.ts +166 -170
- package/dist/file.js +199 -218
- package/dist/filesystem.d.ts +68 -241
- package/dist/filesystem.js +59 -383
- package/dist/index.d.ts +7 -44
- package/dist/index.js +13 -52
- package/dist/inode.d.ts +37 -28
- package/dist/inode.js +123 -65
- package/dist/stats.d.ts +21 -19
- package/dist/stats.js +35 -56
- package/dist/utils.d.ts +26 -9
- package/dist/utils.js +73 -102
- package/package.json +4 -3
package/dist/filesystem.js
CHANGED
|
@@ -1,36 +1,19 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
2
|
// disable no-unused-vars since BaseFileSystem uses them a lot
|
|
3
|
-
var _a;
|
|
4
3
|
import { ApiError, ErrorCode } from './ApiError.js';
|
|
5
|
-
import { FileFlag, ActionType } from './file.js';
|
|
6
|
-
import * as path from './emulation/path.js';
|
|
7
|
-
import { encode } from './utils.js';
|
|
8
4
|
/**
|
|
9
|
-
* Structure for a filesystem.
|
|
10
|
-
* this.
|
|
5
|
+
* Structure for a filesystem. All ZenFS FileSystems must implement this.
|
|
11
6
|
*
|
|
12
|
-
*
|
|
7
|
+
* This class includes some default implementations
|
|
13
8
|
*
|
|
14
|
-
*
|
|
9
|
+
* Assume the following about arguments passed to each API method:
|
|
15
10
|
*
|
|
16
|
-
* - Every path is an absolute path. `.`, `..`, and other items
|
|
17
|
-
*
|
|
18
|
-
* - All arguments are present. Any optional arguments at the Node API level
|
|
19
|
-
* have been passed in with their default values.
|
|
11
|
+
* - Every path is an absolute path. `.`, `..`, and other items are resolved into an absolute form.
|
|
12
|
+
* - All arguments are present. Any optional arguments at the Node API level have been passed in with their default values.
|
|
20
13
|
*/
|
|
21
14
|
export class FileSystem {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Basic filesystem class. Most filesystems should extend this class, as it
|
|
28
|
-
* provides default implementations for a handful of methods.
|
|
29
|
-
*/
|
|
30
|
-
export class BaseFileSystem extends FileSystem {
|
|
31
|
-
constructor(options) {
|
|
32
|
-
super();
|
|
33
|
-
this._ready = Promise.resolve(this);
|
|
15
|
+
static get Name() {
|
|
16
|
+
return this.name;
|
|
34
17
|
}
|
|
35
18
|
get metadata() {
|
|
36
19
|
return {
|
|
@@ -38,418 +21,111 @@ export class BaseFileSystem extends FileSystem {
|
|
|
38
21
|
readonly: false,
|
|
39
22
|
synchronous: false,
|
|
40
23
|
supportsProperties: false,
|
|
41
|
-
supportsLinks: false,
|
|
42
24
|
totalSpace: 0,
|
|
43
25
|
freeSpace: 0,
|
|
44
26
|
};
|
|
45
27
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Opens the file at path p with the given flag. The file must exist.
|
|
51
|
-
* @param p The path to open.
|
|
52
|
-
* @param flag The flag to use when opening the file.
|
|
53
|
-
*/
|
|
54
|
-
async openFile(p, flag, cred) {
|
|
55
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
28
|
+
constructor(options) {
|
|
29
|
+
// unused
|
|
56
30
|
}
|
|
57
31
|
/**
|
|
58
|
-
*
|
|
59
|
-
* flag.
|
|
32
|
+
* Test whether or not the given path exists by checking with the file system.
|
|
60
33
|
*/
|
|
61
|
-
async
|
|
62
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
63
|
-
}
|
|
64
|
-
async open(p, flag, mode, cred) {
|
|
34
|
+
async exists(path, cred) {
|
|
65
35
|
try {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
case ActionType.THROW_EXCEPTION:
|
|
69
|
-
throw ApiError.EEXIST(p);
|
|
70
|
-
case ActionType.TRUNCATE_FILE:
|
|
71
|
-
// NOTE: In a previous implementation, we deleted the file and
|
|
72
|
-
// re-created it. However, this created a race condition if another
|
|
73
|
-
// asynchronous request was trying to read the file, as the file
|
|
74
|
-
// would not exist for a small period of time.
|
|
75
|
-
const fd = await this.openFile(p, flag, cred);
|
|
76
|
-
if (!fd)
|
|
77
|
-
throw new Error('BFS has reached an impossible code path; please file a bug.');
|
|
78
|
-
await fd.truncate(0);
|
|
79
|
-
await fd.sync();
|
|
80
|
-
return fd;
|
|
81
|
-
case ActionType.NOP:
|
|
82
|
-
return this.openFile(p, flag, cred);
|
|
83
|
-
default:
|
|
84
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
|
|
85
|
-
}
|
|
86
|
-
// File exists.
|
|
36
|
+
await this.stat(path, cred);
|
|
37
|
+
return true;
|
|
87
38
|
}
|
|
88
39
|
catch (e) {
|
|
89
|
-
|
|
90
|
-
switch (flag.pathNotExistsAction()) {
|
|
91
|
-
case ActionType.CREATE_FILE:
|
|
92
|
-
// Ensure parent exists.
|
|
93
|
-
const parentStats = await this.stat(path.dirname(p), cred);
|
|
94
|
-
if (parentStats && !parentStats.isDirectory()) {
|
|
95
|
-
throw ApiError.ENOTDIR(path.dirname(p));
|
|
96
|
-
}
|
|
97
|
-
return this.createFile(p, flag, mode, cred);
|
|
98
|
-
case ActionType.THROW_EXCEPTION:
|
|
99
|
-
throw ApiError.ENOENT(p);
|
|
100
|
-
default:
|
|
101
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
|
|
102
|
-
}
|
|
40
|
+
return false;
|
|
103
41
|
}
|
|
104
42
|
}
|
|
105
|
-
async access(p, mode, cred) {
|
|
106
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
107
|
-
}
|
|
108
|
-
accessSync(p, mode, cred) {
|
|
109
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
110
|
-
}
|
|
111
|
-
async rename(oldPath, newPath, cred) {
|
|
112
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
113
|
-
}
|
|
114
|
-
renameSync(oldPath, newPath, cred) {
|
|
115
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
116
|
-
}
|
|
117
|
-
async stat(p, cred) {
|
|
118
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
119
|
-
}
|
|
120
|
-
statSync(p, cred) {
|
|
121
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Opens the file at path p with the given flag. The file must exist.
|
|
125
|
-
* @param p The path to open.
|
|
126
|
-
* @param flag The flag to use when opening the file.
|
|
127
|
-
* @return A File object corresponding to the opened file.
|
|
128
|
-
*/
|
|
129
|
-
openFileSync(p, flag, cred) {
|
|
130
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
131
|
-
}
|
|
132
43
|
/**
|
|
133
|
-
*
|
|
134
|
-
* flag.
|
|
44
|
+
* Test whether or not the given path exists by checking with the file system.
|
|
135
45
|
*/
|
|
136
|
-
|
|
137
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
138
|
-
}
|
|
139
|
-
openSync(p, flag, mode, cred) {
|
|
140
|
-
// Check if the path exists, and is a file.
|
|
141
|
-
let stats;
|
|
142
|
-
try {
|
|
143
|
-
stats = this.statSync(p, cred);
|
|
144
|
-
}
|
|
145
|
-
catch (e) {
|
|
146
|
-
// File does not exist.
|
|
147
|
-
switch (flag.pathNotExistsAction()) {
|
|
148
|
-
case ActionType.CREATE_FILE:
|
|
149
|
-
// Ensure parent exists.
|
|
150
|
-
const parentStats = this.statSync(path.dirname(p), cred);
|
|
151
|
-
if (!parentStats.isDirectory()) {
|
|
152
|
-
throw ApiError.ENOTDIR(path.dirname(p));
|
|
153
|
-
}
|
|
154
|
-
return this.createFileSync(p, flag, mode, cred);
|
|
155
|
-
case ActionType.THROW_EXCEPTION:
|
|
156
|
-
throw ApiError.ENOENT(p);
|
|
157
|
-
default:
|
|
158
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (!stats.hasAccess(mode, cred)) {
|
|
162
|
-
throw ApiError.EACCES(p);
|
|
163
|
-
}
|
|
164
|
-
// File exists.
|
|
165
|
-
switch (flag.pathExistsAction()) {
|
|
166
|
-
case ActionType.THROW_EXCEPTION:
|
|
167
|
-
throw ApiError.EEXIST(p);
|
|
168
|
-
case ActionType.TRUNCATE_FILE:
|
|
169
|
-
// Delete file.
|
|
170
|
-
this.unlinkSync(p, cred);
|
|
171
|
-
// Create file. Use the same mode as the old file.
|
|
172
|
-
// Node itself modifies the ctime when this occurs, so this action
|
|
173
|
-
// will preserve that behavior if the underlying file system
|
|
174
|
-
// supports those properties.
|
|
175
|
-
return this.createFileSync(p, flag, stats.mode, cred);
|
|
176
|
-
case ActionType.NOP:
|
|
177
|
-
return this.openFileSync(p, flag, cred);
|
|
178
|
-
default:
|
|
179
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid FileFlag object.');
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
async unlink(p, cred) {
|
|
183
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
184
|
-
}
|
|
185
|
-
unlinkSync(p, cred) {
|
|
186
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
187
|
-
}
|
|
188
|
-
async rmdir(p, cred) {
|
|
189
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
190
|
-
}
|
|
191
|
-
rmdirSync(p, cred) {
|
|
192
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
193
|
-
}
|
|
194
|
-
async mkdir(p, mode, cred) {
|
|
195
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
196
|
-
}
|
|
197
|
-
mkdirSync(p, mode, cred) {
|
|
198
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
199
|
-
}
|
|
200
|
-
async readdir(p, cred) {
|
|
201
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
202
|
-
}
|
|
203
|
-
readdirSync(p, cred) {
|
|
204
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
205
|
-
}
|
|
206
|
-
async exists(p, cred) {
|
|
46
|
+
existsSync(path, cred) {
|
|
207
47
|
try {
|
|
208
|
-
|
|
48
|
+
this.statSync(path, cred);
|
|
209
49
|
return true;
|
|
210
50
|
}
|
|
211
51
|
catch (e) {
|
|
212
52
|
return false;
|
|
213
53
|
}
|
|
214
54
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Implements the asynchronous API in terms of the synchronous API.
|
|
58
|
+
*/
|
|
59
|
+
export class SyncFileSystem extends FileSystem {
|
|
60
|
+
get metadata() {
|
|
61
|
+
return { ...super.metadata, synchronous: true };
|
|
223
62
|
}
|
|
224
|
-
async
|
|
225
|
-
|
|
226
|
-
// The path could contain symlinks. Split up the path,
|
|
227
|
-
// resolve any symlinks, return the resolved string.
|
|
228
|
-
const splitPath = p.split(path.sep);
|
|
229
|
-
// TODO: Simpler to just pass through file, find sep and such.
|
|
230
|
-
for (let i = 0; i < splitPath.length; i++) {
|
|
231
|
-
const addPaths = splitPath.slice(0, i + 1);
|
|
232
|
-
splitPath[i] = path.join(...addPaths);
|
|
233
|
-
}
|
|
234
|
-
return splitPath.join(path.sep);
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
// No symlinks. We just need to verify that it exists.
|
|
238
|
-
if (!(await this.exists(p, cred))) {
|
|
239
|
-
throw ApiError.ENOENT(p);
|
|
240
|
-
}
|
|
241
|
-
return p;
|
|
242
|
-
}
|
|
63
|
+
async ready() {
|
|
64
|
+
return this;
|
|
243
65
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
// The path could contain symlinks. Split up the path,
|
|
247
|
-
// resolve any symlinks, return the resolved string.
|
|
248
|
-
const splitPath = p.split(path.sep);
|
|
249
|
-
// TODO: Simpler to just pass through file, find sep and such.
|
|
250
|
-
for (let i = 0; i < splitPath.length; i++) {
|
|
251
|
-
const addPaths = splitPath.slice(0, i + 1);
|
|
252
|
-
splitPath[i] = path.join(...addPaths);
|
|
253
|
-
}
|
|
254
|
-
return splitPath.join(path.sep);
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
// No symlinks. We just need to verify that it exists.
|
|
258
|
-
if (this.existsSync(p, cred)) {
|
|
259
|
-
return p;
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
throw ApiError.ENOENT(p);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
66
|
+
async rename(oldPath, newPath, cred) {
|
|
67
|
+
return this.renameSync(oldPath, newPath, cred);
|
|
265
68
|
}
|
|
266
|
-
async
|
|
267
|
-
|
|
268
|
-
try {
|
|
269
|
-
await fd.truncate(len);
|
|
270
|
-
}
|
|
271
|
-
finally {
|
|
272
|
-
await fd.close();
|
|
273
|
-
}
|
|
69
|
+
async stat(path, cred) {
|
|
70
|
+
return this.statSync(path, cred);
|
|
274
71
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
// Need to safely close FD, regardless of whether or not truncate succeeds.
|
|
278
|
-
try {
|
|
279
|
-
fd.truncateSync(len);
|
|
280
|
-
}
|
|
281
|
-
finally {
|
|
282
|
-
fd.closeSync();
|
|
283
|
-
}
|
|
72
|
+
async createFile(path, flag, mode, cred) {
|
|
73
|
+
return this.createFileSync(path, flag, mode, cred);
|
|
284
74
|
}
|
|
285
|
-
async
|
|
286
|
-
|
|
287
|
-
const fd = await this.open(fname, flag, 0o644, cred);
|
|
288
|
-
try {
|
|
289
|
-
const stat = await fd.stat();
|
|
290
|
-
// Allocate buffer.
|
|
291
|
-
const buf = new Uint8Array(stat.size);
|
|
292
|
-
await fd.read(buf, 0, stat.size, 0);
|
|
293
|
-
await fd.close();
|
|
294
|
-
return buf;
|
|
295
|
-
}
|
|
296
|
-
finally {
|
|
297
|
-
await fd.close();
|
|
298
|
-
}
|
|
75
|
+
async openFile(path, flag, cred) {
|
|
76
|
+
return this.openFileSync(path, flag, cred);
|
|
299
77
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const fd = this.openSync(fname, flag, 0o644, cred);
|
|
303
|
-
try {
|
|
304
|
-
const stat = fd.statSync();
|
|
305
|
-
// Allocate buffer.
|
|
306
|
-
const buf = new Uint8Array(stat.size);
|
|
307
|
-
fd.readSync(buf, 0, stat.size, 0);
|
|
308
|
-
fd.closeSync();
|
|
309
|
-
return buf;
|
|
310
|
-
}
|
|
311
|
-
finally {
|
|
312
|
-
fd.closeSync();
|
|
313
|
-
}
|
|
78
|
+
async unlink(path, cred) {
|
|
79
|
+
return this.unlinkSync(path, cred);
|
|
314
80
|
}
|
|
315
|
-
async
|
|
316
|
-
|
|
317
|
-
const fd = await this.open(fname, flag, mode, cred);
|
|
318
|
-
try {
|
|
319
|
-
if (typeof data === 'string') {
|
|
320
|
-
data = encode(data);
|
|
321
|
-
}
|
|
322
|
-
// Write into file.
|
|
323
|
-
await fd.write(data, 0, data.length, 0);
|
|
324
|
-
}
|
|
325
|
-
finally {
|
|
326
|
-
await fd.close();
|
|
327
|
-
}
|
|
81
|
+
async rmdir(path, cred) {
|
|
82
|
+
return this.rmdirSync(path, cred);
|
|
328
83
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const fd = this.openSync(fname, flag, mode, cred);
|
|
332
|
-
try {
|
|
333
|
-
if (typeof data === 'string') {
|
|
334
|
-
data = encode(data);
|
|
335
|
-
}
|
|
336
|
-
// Write into file.
|
|
337
|
-
fd.writeSync(data, 0, data.length, 0);
|
|
338
|
-
}
|
|
339
|
-
finally {
|
|
340
|
-
fd.closeSync();
|
|
341
|
-
}
|
|
84
|
+
async mkdir(path, mode, cred) {
|
|
85
|
+
return this.mkdirSync(path, mode, cred);
|
|
342
86
|
}
|
|
343
|
-
async
|
|
344
|
-
|
|
345
|
-
try {
|
|
346
|
-
if (typeof data === 'string') {
|
|
347
|
-
data = encode(data);
|
|
348
|
-
}
|
|
349
|
-
await fd.write(data, 0, data.length, null);
|
|
350
|
-
}
|
|
351
|
-
finally {
|
|
352
|
-
await fd.close();
|
|
353
|
-
}
|
|
87
|
+
async readdir(path, cred) {
|
|
88
|
+
return this.readdirSync(path, cred);
|
|
354
89
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
try {
|
|
358
|
-
if (typeof data === 'string') {
|
|
359
|
-
data = encode(data);
|
|
360
|
-
}
|
|
361
|
-
fd.writeSync(data, 0, data.length, null);
|
|
362
|
-
}
|
|
363
|
-
finally {
|
|
364
|
-
fd.closeSync();
|
|
365
|
-
}
|
|
90
|
+
async link(srcpath, dstpath, cred) {
|
|
91
|
+
return this.linkSync(srcpath, dstpath, cred);
|
|
366
92
|
}
|
|
367
|
-
async
|
|
368
|
-
|
|
93
|
+
async sync(path, data, stats) {
|
|
94
|
+
return this.syncSync(path, data, stats);
|
|
369
95
|
}
|
|
370
|
-
|
|
96
|
+
}
|
|
97
|
+
export class AsyncFileSystem extends FileSystem {
|
|
98
|
+
renameSync(oldPath, newPath, cred) {
|
|
371
99
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
372
100
|
}
|
|
373
|
-
|
|
101
|
+
statSync(path, cred) {
|
|
374
102
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
375
103
|
}
|
|
376
|
-
|
|
104
|
+
createFileSync(path, flag, mode, cred) {
|
|
377
105
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
378
106
|
}
|
|
379
|
-
|
|
107
|
+
openSync(path, flags, mode, cred) {
|
|
380
108
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
381
109
|
}
|
|
382
|
-
|
|
110
|
+
openFileSync(path, flag, cred) {
|
|
383
111
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
384
112
|
}
|
|
385
|
-
|
|
113
|
+
unlinkSync(path, cred) {
|
|
386
114
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
387
115
|
}
|
|
388
|
-
|
|
116
|
+
rmdirSync(path, cred) {
|
|
389
117
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
390
118
|
}
|
|
391
|
-
|
|
119
|
+
mkdirSync(path, mode, cred) {
|
|
392
120
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
393
121
|
}
|
|
394
|
-
|
|
122
|
+
readdirSync(path, cred) {
|
|
395
123
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
396
124
|
}
|
|
397
|
-
|
|
125
|
+
linkSync(srcpath, dstpath, cred) {
|
|
398
126
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
399
127
|
}
|
|
400
|
-
|
|
128
|
+
syncSync(path, data, stats) {
|
|
401
129
|
throw new ApiError(ErrorCode.ENOTSUP);
|
|
402
130
|
}
|
|
403
131
|
}
|
|
404
|
-
_a = BaseFileSystem;
|
|
405
|
-
BaseFileSystem.Name = _a.name;
|
|
406
|
-
/**
|
|
407
|
-
* Implements the asynchronous API in terms of the synchronous API.
|
|
408
|
-
*/
|
|
409
|
-
export class SynchronousFileSystem extends BaseFileSystem {
|
|
410
|
-
get metadata() {
|
|
411
|
-
return { ...super.metadata, synchronous: true };
|
|
412
|
-
}
|
|
413
|
-
async access(p, mode, cred) {
|
|
414
|
-
return this.accessSync(p, mode, cred);
|
|
415
|
-
}
|
|
416
|
-
async rename(oldPath, newPath, cred) {
|
|
417
|
-
return this.renameSync(oldPath, newPath, cred);
|
|
418
|
-
}
|
|
419
|
-
async stat(p, cred) {
|
|
420
|
-
return this.statSync(p, cred);
|
|
421
|
-
}
|
|
422
|
-
async open(p, flags, mode, cred) {
|
|
423
|
-
return this.openSync(p, flags, mode, cred);
|
|
424
|
-
}
|
|
425
|
-
async unlink(p, cred) {
|
|
426
|
-
return this.unlinkSync(p, cred);
|
|
427
|
-
}
|
|
428
|
-
async rmdir(p, cred) {
|
|
429
|
-
return this.rmdirSync(p, cred);
|
|
430
|
-
}
|
|
431
|
-
async mkdir(p, mode, cred) {
|
|
432
|
-
return this.mkdirSync(p, mode, cred);
|
|
433
|
-
}
|
|
434
|
-
async readdir(p, cred) {
|
|
435
|
-
return this.readdirSync(p, cred);
|
|
436
|
-
}
|
|
437
|
-
async chmod(p, mode, cred) {
|
|
438
|
-
return this.chmodSync(p, mode, cred);
|
|
439
|
-
}
|
|
440
|
-
async chown(p, new_uid, new_gid, cred) {
|
|
441
|
-
return this.chownSync(p, new_uid, new_gid, cred);
|
|
442
|
-
}
|
|
443
|
-
async utimes(p, atime, mtime, cred) {
|
|
444
|
-
return this.utimesSync(p, atime, mtime, cred);
|
|
445
|
-
}
|
|
446
|
-
async link(srcpath, dstpath, cred) {
|
|
447
|
-
return this.linkSync(srcpath, dstpath, cred);
|
|
448
|
-
}
|
|
449
|
-
async symlink(srcpath, dstpath, type, cred) {
|
|
450
|
-
return this.symlinkSync(srcpath, dstpath, type, cred);
|
|
451
|
-
}
|
|
452
|
-
async readlink(p, cred) {
|
|
453
|
-
return this.readlinkSync(p, cred);
|
|
454
|
-
}
|
|
455
|
-
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ZenFS's main module. This is exposed in the browser via the ZenFS global.
|
|
3
3
|
*/
|
|
4
|
-
import fs from './emulation/
|
|
5
|
-
import { FileSystem
|
|
4
|
+
import * as fs from './emulation/index.js';
|
|
5
|
+
import { FileSystem } from './filesystem.js';
|
|
6
6
|
import { backends } from './backends/index.js';
|
|
7
|
+
import { type Backend, type BackendConfig } from './backends/backend.js';
|
|
7
8
|
/**
|
|
8
9
|
* Initializes ZenFS with the given file systems.
|
|
9
10
|
*/
|
|
@@ -14,55 +15,17 @@ export declare function initialize(mounts: {
|
|
|
14
15
|
* Defines a mapping of mount points to their configurations
|
|
15
16
|
*/
|
|
16
17
|
export interface ConfigMapping {
|
|
17
|
-
[mountPoint: string]: FileSystem |
|
|
18
|
+
[mountPoint: string]: FileSystem | BackendConfig | keyof typeof backends | Backend;
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
21
|
* A configuration for ZenFS
|
|
21
22
|
*/
|
|
22
|
-
export type Configuration = FileSystem |
|
|
23
|
+
export type Configuration = FileSystem | BackendConfig | ConfigMapping;
|
|
23
24
|
/**
|
|
24
|
-
* Creates
|
|
25
|
-
* See the
|
|
25
|
+
* Creates filesystems with the given configuration, and initializes ZenFS with it.
|
|
26
|
+
* See the Configuration type for more info on the configuration object.
|
|
26
27
|
*/
|
|
27
28
|
export declare function configure(config: Configuration): Promise<void>;
|
|
28
|
-
export declare function configure(config: Configuration, cb: NoArgCallback): void;
|
|
29
|
-
/**
|
|
30
|
-
* Asynchronously creates a file system with the given configuration, and initializes ZenFS with it.
|
|
31
|
-
* See the FileSystemConfiguration type for more info on the configuration object.
|
|
32
|
-
* Note: unlike configure, the .then is provided with the file system
|
|
33
|
-
*/
|
|
34
|
-
/**
|
|
35
|
-
* Specifies a file system backend type and its options.
|
|
36
|
-
*
|
|
37
|
-
* Individual options can recursively contain FileSystemConfiguration objects for
|
|
38
|
-
* option values that require file systems.
|
|
39
|
-
*
|
|
40
|
-
* For example, to mirror Dropbox to Storage with AsyncMirror, use the following
|
|
41
|
-
* object:
|
|
42
|
-
*
|
|
43
|
-
* ```javascript
|
|
44
|
-
* var config = {
|
|
45
|
-
* fs: "AsyncMirror",
|
|
46
|
-
* options: {
|
|
47
|
-
* sync: {fs: "Storage"},
|
|
48
|
-
* async: {fs: "Dropbox", options: {client: anAuthenticatedDropboxSDKClient }}
|
|
49
|
-
* }
|
|
50
|
-
* };
|
|
51
|
-
* ```
|
|
52
|
-
*
|
|
53
|
-
* The option object for each file system corresponds to that file system's option object passed to its `Create()` method.
|
|
54
|
-
*/
|
|
55
|
-
export interface FileSystemConfiguration {
|
|
56
|
-
fs: string;
|
|
57
|
-
options?: object;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Retrieve a file system with the given configuration. Will return a promise if invoked without a callback
|
|
61
|
-
* @param config A FileSystemConfiguration object. See FileSystemConfiguration for details.
|
|
62
|
-
* @param cb Called when the file system is constructed, or when an error occurs.
|
|
63
|
-
*/
|
|
64
|
-
export declare function getFileSystem(config: FileSystemConfiguration): Promise<FileSystem>;
|
|
65
|
-
export declare function getFileSystem(config: FileSystemConfiguration, cb: TwoArgCallback<FileSystem>): void;
|
|
66
29
|
export * from './backends/index.js';
|
|
67
30
|
export * from './backends/AsyncStore.js';
|
|
68
31
|
export * from './backends/SyncStore.js';
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ZenFS's main module. This is exposed in the browser via the ZenFS global.
|
|
3
3
|
*/
|
|
4
|
-
import fs from './emulation/
|
|
4
|
+
import * as fs from './emulation/index.js';
|
|
5
5
|
import { FileSystem } from './filesystem.js';
|
|
6
6
|
import { backends } from './backends/index.js';
|
|
7
|
-
import { ErrorCode, ApiError } from './ApiError.js';
|
|
8
7
|
import { Cred } from './cred.js';
|
|
8
|
+
import { isBackend, resolveBackendConfig } from './backends/backend.js';
|
|
9
9
|
import { setCred } from './emulation/shared.js';
|
|
10
10
|
/**
|
|
11
11
|
* Initializes ZenFS with the given file systems.
|
|
@@ -14,8 +14,12 @@ export function initialize(mounts, uid = 0, gid = 0) {
|
|
|
14
14
|
setCred(new Cred(uid, gid, uid, gid, uid, gid));
|
|
15
15
|
return fs.initialize(mounts);
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Creates filesystems with the given configuration, and initializes ZenFS with it.
|
|
19
|
+
* See the Configuration type for more info on the configuration object.
|
|
20
|
+
*/
|
|
21
|
+
export async function configure(config) {
|
|
22
|
+
if ('backend' in config || config instanceof FileSystem) {
|
|
19
23
|
// single FS
|
|
20
24
|
config = { '/': config };
|
|
21
25
|
}
|
|
@@ -28,57 +32,14 @@ async function _configure(config) {
|
|
|
28
32
|
continue;
|
|
29
33
|
}
|
|
30
34
|
if (typeof value == 'string') {
|
|
31
|
-
value = {
|
|
35
|
+
value = { backend: backends[value] };
|
|
32
36
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return initialize(config);
|
|
36
|
-
}
|
|
37
|
-
export function configure(config, cb) {
|
|
38
|
-
// Promise version
|
|
39
|
-
if (typeof cb != 'function') {
|
|
40
|
-
return _configure(config);
|
|
41
|
-
}
|
|
42
|
-
// Callback version
|
|
43
|
-
_configure(config)
|
|
44
|
-
.then(() => cb())
|
|
45
|
-
.catch(err => cb(err));
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
async function _getFileSystem({ fs: fsName, options = {} }) {
|
|
49
|
-
if (!fsName) {
|
|
50
|
-
throw new ApiError(ErrorCode.EPERM, 'Missing "fs" property on configuration object.');
|
|
51
|
-
}
|
|
52
|
-
if (typeof options !== 'object' || options === null) {
|
|
53
|
-
throw new ApiError(ErrorCode.EINVAL, 'Invalid "options" property on configuration object.');
|
|
54
|
-
}
|
|
55
|
-
const props = Object.keys(options).filter(k => k != 'fs');
|
|
56
|
-
for (const prop of props) {
|
|
57
|
-
const opt = options[prop];
|
|
58
|
-
if (opt === null || typeof opt !== 'object' || !('fs' in opt)) {
|
|
59
|
-
continue;
|
|
37
|
+
if (isBackend(value)) {
|
|
38
|
+
value = { backend: value };
|
|
60
39
|
}
|
|
61
|
-
|
|
62
|
-
options[prop] = fs;
|
|
63
|
-
}
|
|
64
|
-
const fsc = backends[fsName];
|
|
65
|
-
if (!fsc) {
|
|
66
|
-
throw new ApiError(ErrorCode.EPERM, `File system ${fsName} is not available in ZenFS.`);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
return fsc.Create(options);
|
|
40
|
+
config[point] = await resolveBackendConfig(value);
|
|
70
41
|
}
|
|
71
|
-
|
|
72
|
-
export function getFileSystem(config, cb) {
|
|
73
|
-
// Promise version
|
|
74
|
-
if (typeof cb != 'function') {
|
|
75
|
-
return _getFileSystem(config);
|
|
76
|
-
}
|
|
77
|
-
// Callback version
|
|
78
|
-
_getFileSystem(config)
|
|
79
|
-
.then(fs => cb(null, fs))
|
|
80
|
-
.catch(err => cb(err));
|
|
81
|
-
return;
|
|
42
|
+
return initialize(config);
|
|
82
43
|
}
|
|
83
44
|
export * from './backends/index.js';
|
|
84
45
|
export * from './backends/AsyncStore.js';
|