@zenfs/core 0.5.3 → 0.5.5
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 +5 -12
- package/dist/ApiError.js +6 -27
- package/dist/FileIndex.js +10 -10
- package/dist/backends/AsyncStore.js +36 -44
- package/dist/backends/Overlay.js +17 -17
- package/dist/backends/SyncStore.d.ts +1 -1
- package/dist/backends/SyncStore.js +29 -34
- package/dist/backends/backend.d.ts +3 -3
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +3 -3
- package/dist/emulation/promises.d.ts +2 -3
- package/dist/emulation/promises.js +15 -11
- package/dist/emulation/shared.d.ts +9 -1
- package/dist/emulation/shared.js +28 -40
- package/dist/emulation/sync.d.ts +3 -6
- package/dist/emulation/sync.js +17 -7
- package/dist/file.d.ts +4 -0
- package/dist/file.js +10 -14
- package/dist/stats.d.ts +2 -3
- package/dist/stats.js +6 -22
- package/dist/utils.js +6 -2
- package/package.json +1 -1
- package/readme.md +2 -2
|
@@ -134,10 +134,10 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
134
134
|
// Remove oldPath from parent's directory listing.
|
|
135
135
|
oldDirNode = this.findINode(tx, oldParent), oldDirList = this.getDirListing(tx, oldDirNode, oldParent);
|
|
136
136
|
if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
137
|
-
throw ApiError.EACCES
|
|
137
|
+
throw ApiError.With('EACCES', oldPath, 'renameSync');
|
|
138
138
|
}
|
|
139
139
|
if (!oldDirList[oldName]) {
|
|
140
|
-
throw ApiError.ENOENT
|
|
140
|
+
throw ApiError.With('ENOENT', oldPath, 'renameSync');
|
|
141
141
|
}
|
|
142
142
|
const ino = oldDirList[oldName];
|
|
143
143
|
delete oldDirList[oldName];
|
|
@@ -175,7 +175,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
175
175
|
}
|
|
176
176
|
else {
|
|
177
177
|
// If it's a directory, throw a permissions error.
|
|
178
|
-
throw ApiError.EPERM
|
|
178
|
+
throw ApiError.With('EPERM', newPath, 'renameSync');
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
newDirList[newName] = ino;
|
|
@@ -194,7 +194,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
194
194
|
// Get the inode to the item, convert it into a Stats object.
|
|
195
195
|
const stats = this.findINode(this.store.beginTransaction(), p).toStats();
|
|
196
196
|
if (!stats.hasAccess(R_OK, cred)) {
|
|
197
|
-
throw ApiError.EACCES
|
|
197
|
+
throw ApiError.With('EACCES', p, 'statSync');
|
|
198
198
|
}
|
|
199
199
|
return stats;
|
|
200
200
|
}
|
|
@@ -205,10 +205,10 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
205
205
|
openFileSync(p, flag, cred) {
|
|
206
206
|
const tx = this.store.beginTransaction(), node = this.findINode(tx, p), data = tx.get(node.ino);
|
|
207
207
|
if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
|
|
208
|
-
throw ApiError.EACCES
|
|
208
|
+
throw ApiError.With('EACCES', p, 'openFileSync');
|
|
209
209
|
}
|
|
210
210
|
if (data === null) {
|
|
211
|
-
throw ApiError.ENOENT
|
|
211
|
+
throw ApiError.With('ENOENT', p, 'openFileSync');
|
|
212
212
|
}
|
|
213
213
|
return new SyncStoreFile(this, p, flag, node.toStats(), data);
|
|
214
214
|
}
|
|
@@ -218,7 +218,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
218
218
|
rmdirSync(p, cred) {
|
|
219
219
|
// Check first if directory is empty.
|
|
220
220
|
if (this.readdirSync(p, cred).length > 0) {
|
|
221
|
-
throw ApiError.ENOTEMPTY
|
|
221
|
+
throw ApiError.With('ENOTEMPTY', p, 'rmdirSync');
|
|
222
222
|
}
|
|
223
223
|
else {
|
|
224
224
|
this.removeEntry(p, true, cred);
|
|
@@ -231,7 +231,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
231
231
|
const tx = this.store.beginTransaction();
|
|
232
232
|
const node = this.findINode(tx, p);
|
|
233
233
|
if (!node.toStats().hasAccess(R_OK, cred)) {
|
|
234
|
-
throw ApiError.EACCES
|
|
234
|
+
throw ApiError.With('EACCES', p, 'readdirSync');
|
|
235
235
|
}
|
|
236
236
|
return Object.keys(this.getDirListing(tx, node, p));
|
|
237
237
|
}
|
|
@@ -258,16 +258,16 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
258
258
|
linkSync(existing, newpath, cred) {
|
|
259
259
|
const tx = this.store.beginTransaction(), existingDir = dirname(existing), existingDirNode = this.findINode(tx, existingDir);
|
|
260
260
|
if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
|
|
261
|
-
throw ApiError.EACCES
|
|
261
|
+
throw ApiError.With('EACCES', existingDir, 'linkSync');
|
|
262
262
|
}
|
|
263
263
|
const newDir = dirname(newpath), newDirNode = this.findINode(tx, newDir), newListing = this.getDirListing(tx, newDirNode, newDir);
|
|
264
264
|
if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
265
|
-
throw ApiError.EACCES
|
|
265
|
+
throw ApiError.With('EACCES', newDir, 'linkSync');
|
|
266
266
|
}
|
|
267
267
|
const ino = this._findINode(tx, existingDir, basename(existing));
|
|
268
268
|
const node = this.getINode(tx, ino, existing);
|
|
269
269
|
if (!node.toStats().hasAccess(W_OK, cred)) {
|
|
270
|
-
throw ApiError.EACCES
|
|
270
|
+
throw ApiError.With('EACCES', newpath, 'linkSync');
|
|
271
271
|
}
|
|
272
272
|
node.nlink++;
|
|
273
273
|
newListing[basename(newpath)] = ino;
|
|
@@ -314,7 +314,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
314
314
|
const ino = this._findINode(tx, dirname(parent), basename(parent), visited);
|
|
315
315
|
const dir = this.getDirListing(tx, this.getINode(tx, ino, parent + sep + filename), parent);
|
|
316
316
|
if (!(filename in dir)) {
|
|
317
|
-
throw ApiError.ENOENT
|
|
317
|
+
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
|
|
318
318
|
}
|
|
319
319
|
return dir[filename];
|
|
320
320
|
}
|
|
@@ -322,7 +322,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
322
322
|
// Find the item in the root node.
|
|
323
323
|
const dir = this.getDirListing(tx, this.getINode(tx, rootIno, parent), parent);
|
|
324
324
|
if (!(filename in dir)) {
|
|
325
|
-
throw ApiError.ENOENT
|
|
325
|
+
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
|
|
326
326
|
}
|
|
327
327
|
return dir[filename];
|
|
328
328
|
}
|
|
@@ -348,7 +348,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
348
348
|
getINode(tx, id, p) {
|
|
349
349
|
const data = tx.get(id);
|
|
350
350
|
if (!data) {
|
|
351
|
-
throw ApiError.ENOENT
|
|
351
|
+
throw ApiError.With('ENOENT', p, 'getINode');
|
|
352
352
|
}
|
|
353
353
|
const inode = new Inode(data.buffer);
|
|
354
354
|
return inode;
|
|
@@ -358,11 +358,11 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
358
358
|
*/
|
|
359
359
|
getDirListing(tx, inode, p) {
|
|
360
360
|
if (!inode.toStats().isDirectory()) {
|
|
361
|
-
throw ApiError.ENOTDIR
|
|
361
|
+
throw ApiError.With('ENOTDIR', p, 'getDirListing');
|
|
362
362
|
}
|
|
363
363
|
const data = tx.get(inode.ino);
|
|
364
364
|
if (!data) {
|
|
365
|
-
throw ApiError.ENOENT
|
|
365
|
+
throw ApiError.With('ENOENT', p, 'getDirListing');
|
|
366
366
|
}
|
|
367
367
|
return decodeDirListing(data);
|
|
368
368
|
}
|
|
@@ -371,18 +371,13 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
371
371
|
* the exceedingly unlikely chance that we try to reuse a random GUID.
|
|
372
372
|
* @return The GUID that the data was stored under.
|
|
373
373
|
*/
|
|
374
|
-
addNewNode(tx, data) {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
ino = randomIno();
|
|
380
|
-
tx.put(ino, data, false);
|
|
381
|
-
return ino;
|
|
382
|
-
}
|
|
383
|
-
catch (e) {
|
|
384
|
-
// Ignore and reroll.
|
|
374
|
+
addNewNode(tx, data, _maxAttempts = 5) {
|
|
375
|
+
for (let i = 0; i < _maxAttempts; i++) {
|
|
376
|
+
const ino = randomIno();
|
|
377
|
+
if (!tx.put(ino, data, false)) {
|
|
378
|
+
continue;
|
|
385
379
|
}
|
|
380
|
+
return ino;
|
|
386
381
|
}
|
|
387
382
|
throw new ApiError(ErrorCode.EIO, 'Unable to commit data to key-value store.');
|
|
388
383
|
}
|
|
@@ -399,18 +394,18 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
399
394
|
const tx = this.store.beginTransaction(), parentDir = dirname(p), fname = basename(p), parentNode = this.findINode(tx, parentDir), dirListing = this.getDirListing(tx, parentNode, parentDir);
|
|
400
395
|
//Check that the creater has correct access
|
|
401
396
|
if (!parentNode.toStats().hasAccess(W_OK, cred)) {
|
|
402
|
-
throw ApiError.EACCES
|
|
397
|
+
throw ApiError.With('EACCES', p, 'commitNewFile');
|
|
403
398
|
}
|
|
404
399
|
/* Invariant: The root always exists.
|
|
405
400
|
If we don't check this prior to taking steps below,
|
|
406
401
|
we will create a file with name '' in root should p == '/'.
|
|
407
402
|
*/
|
|
408
403
|
if (p === '/') {
|
|
409
|
-
throw ApiError.EEXIST
|
|
404
|
+
throw ApiError.With('EEXIST', p, 'commitNewFile');
|
|
410
405
|
}
|
|
411
406
|
// Check if file already exists.
|
|
412
407
|
if (dirListing[fname]) {
|
|
413
|
-
throw ApiError.EEXIST
|
|
408
|
+
throw ApiError.With('EEXIST', p, 'commitNewFile');
|
|
414
409
|
}
|
|
415
410
|
const fileNode = new Inode();
|
|
416
411
|
try {
|
|
@@ -440,20 +435,20 @@ export class SyncStoreFS extends Sync(FileSystem) {
|
|
|
440
435
|
removeEntry(p, isDir, cred) {
|
|
441
436
|
const tx = this.store.beginTransaction(), parent = dirname(p), parentNode = this.findINode(tx, parent), parentListing = this.getDirListing(tx, parentNode, parent), fileName = basename(p), fileIno = parentListing[fileName];
|
|
442
437
|
if (!fileIno) {
|
|
443
|
-
throw ApiError.ENOENT
|
|
438
|
+
throw ApiError.With('ENOENT', p, 'removeEntry');
|
|
444
439
|
}
|
|
445
440
|
// Get file inode.
|
|
446
441
|
const fileNode = this.getINode(tx, fileIno, p);
|
|
447
442
|
if (!fileNode.toStats().hasAccess(W_OK, cred)) {
|
|
448
|
-
throw ApiError.EACCES
|
|
443
|
+
throw ApiError.With('EACCES', p, 'removeEntry');
|
|
449
444
|
}
|
|
450
445
|
// Remove from directory listing of parent.
|
|
451
446
|
delete parentListing[fileName];
|
|
452
447
|
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
453
|
-
throw ApiError.EISDIR
|
|
448
|
+
throw ApiError.With('EISDIR', p, 'removeEntry');
|
|
454
449
|
}
|
|
455
450
|
if (isDir && !fileNode.toStats().isDirectory()) {
|
|
456
|
-
throw ApiError.ENOTDIR
|
|
451
|
+
throw ApiError.With('ENOTDIR', p, 'removeEntry');
|
|
457
452
|
}
|
|
458
453
|
try {
|
|
459
454
|
// Update directory listing.
|
|
@@ -73,8 +73,8 @@ export declare function createBackend<B extends Backend>(backend: B, options?: o
|
|
|
73
73
|
*
|
|
74
74
|
* The option object for each file system corresponds to that file system's option object passed to its `Create()` method.
|
|
75
75
|
*/
|
|
76
|
-
export interface BackendConfig {
|
|
77
|
-
backend: Backend
|
|
76
|
+
export interface BackendConfig<FS extends FileSystem = FileSystem, OC extends BackendOptionsConfig = BackendOptionsConfig> {
|
|
77
|
+
backend: Backend<FS, OC>;
|
|
78
78
|
[key: string]: unknown;
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
@@ -85,5 +85,5 @@ export declare function isBackendConfig(arg: unknown): arg is BackendConfig;
|
|
|
85
85
|
* Retrieve a file system with the given configuration.
|
|
86
86
|
* @param config A BackendConfig object.
|
|
87
87
|
*/
|
|
88
|
-
export declare function resolveBackend(options: BackendConfig
|
|
88
|
+
export declare function resolveBackend<FS extends FileSystem>(options: BackendConfig<FS>, _depth?: number): Promise<FS>;
|
|
89
89
|
export {};
|