@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
package/dist/ApiError.d.ts
CHANGED
|
@@ -80,9 +80,10 @@ export declare const ErrorStrings: {
|
|
|
80
80
|
interface ApiErrorJSON {
|
|
81
81
|
errno: ErrorCode;
|
|
82
82
|
message: string;
|
|
83
|
-
path
|
|
83
|
+
path?: string;
|
|
84
84
|
code: string;
|
|
85
85
|
stack: string;
|
|
86
|
+
syscall: string;
|
|
86
87
|
}
|
|
87
88
|
/**
|
|
88
89
|
* Represents a ZenFS error. Passed back to applications after a failed
|
|
@@ -91,18 +92,10 @@ interface ApiErrorJSON {
|
|
|
91
92
|
export declare class ApiError extends Error implements NodeJS.ErrnoException {
|
|
92
93
|
errno: ErrorCode;
|
|
93
94
|
path?: string;
|
|
95
|
+
syscall: string;
|
|
94
96
|
static fromJSON(json: ApiErrorJSON): ApiError;
|
|
95
|
-
static
|
|
96
|
-
static EACCES(path: string): ApiError;
|
|
97
|
-
static ENOENT(path: string): ApiError;
|
|
98
|
-
static EEXIST(path: string): ApiError;
|
|
99
|
-
static EISDIR(path: string): ApiError;
|
|
100
|
-
static ENOTDIR(path: string): ApiError;
|
|
101
|
-
static EPERM(path: string): ApiError;
|
|
102
|
-
static ENOTEMPTY(path: string): ApiError;
|
|
97
|
+
static With(code: string, path: string, syscall?: string): ApiError;
|
|
103
98
|
code: string;
|
|
104
|
-
syscall: string;
|
|
105
|
-
stack?: string;
|
|
106
99
|
/**
|
|
107
100
|
* Represents a ZenFS error. Passed back to applications after a failed
|
|
108
101
|
* call to the ZenFS API.
|
|
@@ -113,7 +106,7 @@ export declare class ApiError extends Error implements NodeJS.ErrnoException {
|
|
|
113
106
|
* @param type The type of the error.
|
|
114
107
|
* @param message A descriptive error message.
|
|
115
108
|
*/
|
|
116
|
-
constructor(errno: ErrorCode, message?: string, path?: string);
|
|
109
|
+
constructor(errno: ErrorCode, message?: string, path?: string, syscall?: string);
|
|
117
110
|
/**
|
|
118
111
|
* @return A friendly error message.
|
|
119
112
|
*/
|
package/dist/ApiError.js
CHANGED
|
@@ -98,34 +98,13 @@ export const ErrorStrings = {
|
|
|
98
98
|
*/
|
|
99
99
|
export class ApiError extends Error {
|
|
100
100
|
static fromJSON(json) {
|
|
101
|
-
const err = new ApiError(json.errno, json.message, json.path);
|
|
101
|
+
const err = new ApiError(json.errno, json.message, json.path, json.syscall);
|
|
102
102
|
err.code = json.code;
|
|
103
103
|
err.stack = json.stack;
|
|
104
104
|
return err;
|
|
105
105
|
}
|
|
106
|
-
static
|
|
107
|
-
return new ApiError(code, ErrorStrings[code], path);
|
|
108
|
-
}
|
|
109
|
-
static EACCES(path) {
|
|
110
|
-
return this.OnPath(ErrorCode.EACCES, path);
|
|
111
|
-
}
|
|
112
|
-
static ENOENT(path) {
|
|
113
|
-
return this.OnPath(ErrorCode.ENOENT, path);
|
|
114
|
-
}
|
|
115
|
-
static EEXIST(path) {
|
|
116
|
-
return this.OnPath(ErrorCode.EEXIST, path);
|
|
117
|
-
}
|
|
118
|
-
static EISDIR(path) {
|
|
119
|
-
return this.OnPath(ErrorCode.EISDIR, path);
|
|
120
|
-
}
|
|
121
|
-
static ENOTDIR(path) {
|
|
122
|
-
return this.OnPath(ErrorCode.ENOTDIR, path);
|
|
123
|
-
}
|
|
124
|
-
static EPERM(path) {
|
|
125
|
-
return this.OnPath(ErrorCode.EPERM, path);
|
|
126
|
-
}
|
|
127
|
-
static ENOTEMPTY(path) {
|
|
128
|
-
return this.OnPath(ErrorCode.ENOTEMPTY, path);
|
|
106
|
+
static With(code, path, syscall) {
|
|
107
|
+
return new ApiError(ErrorCode[code], ErrorStrings[ErrorCode[code]], path, syscall);
|
|
129
108
|
}
|
|
130
109
|
/**
|
|
131
110
|
* Represents a ZenFS error. Passed back to applications after a failed
|
|
@@ -137,12 +116,11 @@ export class ApiError extends Error {
|
|
|
137
116
|
* @param type The type of the error.
|
|
138
117
|
* @param message A descriptive error message.
|
|
139
118
|
*/
|
|
140
|
-
constructor(errno, message = ErrorStrings[errno], path) {
|
|
119
|
+
constructor(errno, message = ErrorStrings[errno], path, syscall = '') {
|
|
141
120
|
super(message);
|
|
142
121
|
this.errno = errno;
|
|
143
122
|
this.path = path;
|
|
144
|
-
|
|
145
|
-
this.syscall = '';
|
|
123
|
+
this.syscall = syscall;
|
|
146
124
|
this.code = ErrorCode[errno];
|
|
147
125
|
this.message = `${this.code}: ${message}${this.path ? `, '${this.path}'` : ''}`;
|
|
148
126
|
}
|
|
@@ -159,6 +137,7 @@ export class ApiError extends Error {
|
|
|
159
137
|
path: this.path,
|
|
160
138
|
stack: this.stack,
|
|
161
139
|
message: this.message,
|
|
140
|
+
syscall: this.syscall,
|
|
162
141
|
};
|
|
163
142
|
}
|
|
164
143
|
/**
|
package/dist/FileIndex.js
CHANGED
|
@@ -306,7 +306,7 @@ export class FileIndexFS extends Readonly(FileSystem) {
|
|
|
306
306
|
async stat(path) {
|
|
307
307
|
const inode = this._index.get(path);
|
|
308
308
|
if (!inode) {
|
|
309
|
-
throw ApiError.ENOENT
|
|
309
|
+
throw ApiError.With('ENOENT', path, 'stat');
|
|
310
310
|
}
|
|
311
311
|
if (inode.isDirectory()) {
|
|
312
312
|
return inode.stats;
|
|
@@ -319,7 +319,7 @@ export class FileIndexFS extends Readonly(FileSystem) {
|
|
|
319
319
|
statSync(path) {
|
|
320
320
|
const inode = this._index.get(path);
|
|
321
321
|
if (!inode) {
|
|
322
|
-
throw ApiError.ENOENT
|
|
322
|
+
throw ApiError.With('ENOENT', path, 'statSync');
|
|
323
323
|
}
|
|
324
324
|
if (inode.isDirectory()) {
|
|
325
325
|
return inode.stats;
|
|
@@ -337,10 +337,10 @@ export class FileIndexFS extends Readonly(FileSystem) {
|
|
|
337
337
|
// Check if the path exists, and is a file.
|
|
338
338
|
const inode = this._index.get(path);
|
|
339
339
|
if (!inode) {
|
|
340
|
-
throw ApiError.ENOENT
|
|
340
|
+
throw ApiError.With('ENOENT', path, 'openFile');
|
|
341
341
|
}
|
|
342
342
|
if (!inode.toStats().hasAccess(flagToMode(flag), cred)) {
|
|
343
|
-
throw ApiError.
|
|
343
|
+
throw ApiError.With('EACCESS', path, 'openFile');
|
|
344
344
|
}
|
|
345
345
|
if (inode.isDirectory()) {
|
|
346
346
|
const stats = inode.stats;
|
|
@@ -356,10 +356,10 @@ export class FileIndexFS extends Readonly(FileSystem) {
|
|
|
356
356
|
// Check if the path exists, and is a file.
|
|
357
357
|
const inode = this._index.get(path);
|
|
358
358
|
if (!inode) {
|
|
359
|
-
throw ApiError.ENOENT
|
|
359
|
+
throw ApiError.With('ENOENT', path, 'openFileSync');
|
|
360
360
|
}
|
|
361
361
|
if (!inode.toStats().hasAccess(flagToMode(flag), cred)) {
|
|
362
|
-
throw ApiError.EACCES
|
|
362
|
+
throw ApiError.With('EACCES', path, 'openFileSync');
|
|
363
363
|
}
|
|
364
364
|
if (inode.isDirectory()) {
|
|
365
365
|
const stats = inode.stats;
|
|
@@ -371,23 +371,23 @@ export class FileIndexFS extends Readonly(FileSystem) {
|
|
|
371
371
|
// Check if it exists.
|
|
372
372
|
const inode = this._index.get(path);
|
|
373
373
|
if (!inode) {
|
|
374
|
-
throw ApiError.ENOENT
|
|
374
|
+
throw ApiError.With('ENOENT', path, 'readdir');
|
|
375
375
|
}
|
|
376
376
|
if (inode.isDirectory()) {
|
|
377
377
|
return inode.listing;
|
|
378
378
|
}
|
|
379
|
-
throw ApiError.ENOTDIR
|
|
379
|
+
throw ApiError.With('ENOTDIR', path, 'readdir');
|
|
380
380
|
}
|
|
381
381
|
readdirSync(path) {
|
|
382
382
|
// Check if it exists.
|
|
383
383
|
const inode = this._index.get(path);
|
|
384
384
|
if (!inode) {
|
|
385
|
-
throw ApiError.ENOENT
|
|
385
|
+
throw ApiError.With('ENOENT', path, 'readdirSync');
|
|
386
386
|
}
|
|
387
387
|
if (inode.isDirectory()) {
|
|
388
388
|
return inode.listing;
|
|
389
389
|
}
|
|
390
|
-
throw ApiError.ENOTDIR
|
|
390
|
+
throw ApiError.With('ENOTDIR', path, 'readdirSync');
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
export class SyncFileIndexFS extends Sync((FileIndexFS)) {
|
|
@@ -127,10 +127,10 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
127
127
|
// Remove oldPath from parent's directory listing.
|
|
128
128
|
oldDirNode = await this.findINode(tx, oldParent), oldDirList = await this.getDirListing(tx, oldDirNode, oldParent);
|
|
129
129
|
if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
130
|
-
throw ApiError.EACCES
|
|
130
|
+
throw ApiError.With('EACCES', oldPath, 'rename');
|
|
131
131
|
}
|
|
132
132
|
if (!oldDirList[oldName]) {
|
|
133
|
-
throw ApiError.ENOENT
|
|
133
|
+
throw ApiError.With('ENOENT', oldPath, 'rename');
|
|
134
134
|
}
|
|
135
135
|
const nodeId = oldDirList[oldName];
|
|
136
136
|
delete oldDirList[oldName];
|
|
@@ -168,7 +168,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
168
168
|
}
|
|
169
169
|
else {
|
|
170
170
|
// If it's a directory, throw a permissions error.
|
|
171
|
-
throw ApiError.EPERM
|
|
171
|
+
throw ApiError.With('EPERM', newPath, 'rename');
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
newDirList[newName] = nodeId;
|
|
@@ -193,11 +193,11 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
193
193
|
const tx = this.store.beginTransaction();
|
|
194
194
|
const inode = await this.findINode(tx, p);
|
|
195
195
|
if (!inode) {
|
|
196
|
-
throw ApiError.ENOENT
|
|
196
|
+
throw ApiError.With('ENOENT', p, 'stat');
|
|
197
197
|
}
|
|
198
198
|
const stats = inode.toStats();
|
|
199
199
|
if (!stats.hasAccess(R_OK, cred)) {
|
|
200
|
-
throw ApiError.EACCES
|
|
200
|
+
throw ApiError.With('EACCES', p, 'stat');
|
|
201
201
|
}
|
|
202
202
|
return stats;
|
|
203
203
|
}
|
|
@@ -209,10 +209,10 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
209
209
|
async openFile(p, flag, cred) {
|
|
210
210
|
const tx = this.store.beginTransaction(), node = await this.findINode(tx, p), data = await tx.get(node.ino);
|
|
211
211
|
if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
|
|
212
|
-
throw ApiError.EACCES
|
|
212
|
+
throw ApiError.With('EACCES', p, 'openFile');
|
|
213
213
|
}
|
|
214
214
|
if (!data) {
|
|
215
|
-
throw ApiError.ENOENT
|
|
215
|
+
throw ApiError.With('ENOENT', p, 'openFile');
|
|
216
216
|
}
|
|
217
217
|
return new AsyncFile(this, p, flag, node.toStats(), data);
|
|
218
218
|
}
|
|
@@ -223,7 +223,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
223
223
|
// Check first if directory is empty.
|
|
224
224
|
const list = await this.readdir(p, cred);
|
|
225
225
|
if (list.length > 0) {
|
|
226
|
-
throw ApiError.ENOTEMPTY
|
|
226
|
+
throw ApiError.With('ENOTEMPTY', p, 'rmdir');
|
|
227
227
|
}
|
|
228
228
|
await this.removeEntry(p, true, cred);
|
|
229
229
|
}
|
|
@@ -235,7 +235,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
235
235
|
const tx = this.store.beginTransaction();
|
|
236
236
|
const node = await this.findINode(tx, p);
|
|
237
237
|
if (!node.toStats().hasAccess(R_OK, cred)) {
|
|
238
|
-
throw ApiError.EACCES
|
|
238
|
+
throw ApiError.With('EACCES', p, 'readdur');
|
|
239
239
|
}
|
|
240
240
|
return Object.keys(await this.getDirListing(tx, node, p));
|
|
241
241
|
}
|
|
@@ -264,16 +264,16 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
264
264
|
async link(existing, newpath, cred) {
|
|
265
265
|
const tx = this.store.beginTransaction(), existingDir = dirname(existing), existingDirNode = await this.findINode(tx, existingDir);
|
|
266
266
|
if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
|
|
267
|
-
throw ApiError.EACCES
|
|
267
|
+
throw ApiError.With('EACCES', existingDir, 'link');
|
|
268
268
|
}
|
|
269
269
|
const newDir = dirname(newpath), newDirNode = await this.findINode(tx, newDir), newListing = await this.getDirListing(tx, newDirNode, newDir);
|
|
270
270
|
if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
|
|
271
|
-
throw ApiError.EACCES
|
|
271
|
+
throw ApiError.With('EACCES', newDir, 'link');
|
|
272
272
|
}
|
|
273
273
|
const ino = await this._findINode(tx, existingDir, basename(existing));
|
|
274
274
|
const node = await this.getINode(tx, ino, existing);
|
|
275
275
|
if (!node.toStats().hasAccess(W_OK, cred)) {
|
|
276
|
-
throw ApiError.EACCES
|
|
276
|
+
throw ApiError.With('EACCES', newpath, 'link');
|
|
277
277
|
}
|
|
278
278
|
node.nlink++;
|
|
279
279
|
newListing[basename(newpath)] = ino;
|
|
@@ -341,7 +341,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
341
341
|
return id;
|
|
342
342
|
}
|
|
343
343
|
else {
|
|
344
|
-
throw ApiError.ENOENT
|
|
344
|
+
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
347
|
}
|
|
@@ -358,7 +358,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
358
358
|
return id;
|
|
359
359
|
}
|
|
360
360
|
else {
|
|
361
|
-
throw ApiError.ENOENT
|
|
361
|
+
throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
|
|
362
362
|
}
|
|
363
363
|
}
|
|
364
364
|
}
|
|
@@ -380,7 +380,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
380
380
|
async getINode(tx, id, p) {
|
|
381
381
|
const data = await tx.get(id);
|
|
382
382
|
if (!data) {
|
|
383
|
-
throw ApiError.ENOENT
|
|
383
|
+
throw ApiError.With('ENOENT', p, 'getINode');
|
|
384
384
|
}
|
|
385
385
|
return new Inode(data.buffer);
|
|
386
386
|
}
|
|
@@ -390,7 +390,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
390
390
|
*/
|
|
391
391
|
async getDirListing(tx, inode, p) {
|
|
392
392
|
if (!inode.toStats().isDirectory()) {
|
|
393
|
-
throw ApiError.ENOTDIR
|
|
393
|
+
throw ApiError.With('ENOTDIR', p, 'getDirListing');
|
|
394
394
|
}
|
|
395
395
|
const data = await tx.get(inode.ino);
|
|
396
396
|
if (!data) {
|
|
@@ -399,7 +399,7 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
399
399
|
than a directory listing. The latter should never occur unless
|
|
400
400
|
the file system is corrupted.
|
|
401
401
|
*/
|
|
402
|
-
throw ApiError.ENOENT
|
|
402
|
+
throw ApiError.With('ENOENT', p, 'getDirListing');
|
|
403
403
|
}
|
|
404
404
|
return decodeDirListing(data);
|
|
405
405
|
}
|
|
@@ -407,26 +407,18 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
407
407
|
* Adds a new node under a random ID. Retries 5 times before giving up in
|
|
408
408
|
* the exceedingly unlikely chance that we try to reuse a random ino.
|
|
409
409
|
*/
|
|
410
|
-
async addNewNode(tx, data) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return reroll();
|
|
423
|
-
}
|
|
424
|
-
else {
|
|
425
|
-
return ino;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
return reroll();
|
|
410
|
+
async addNewNode(tx, data, _maxAttempts = 5) {
|
|
411
|
+
if (_maxAttempts <= 0) {
|
|
412
|
+
// Max retries hit. Return with an error.
|
|
413
|
+
throw new ApiError(ErrorCode.EIO, 'Unable to commit data to key-value store.');
|
|
414
|
+
}
|
|
415
|
+
// Make an attempt
|
|
416
|
+
const ino = randomIno();
|
|
417
|
+
const isCommited = await tx.put(ino, data, false);
|
|
418
|
+
if (!isCommited) {
|
|
419
|
+
return await this.addNewNode(tx, data, --_maxAttempts);
|
|
420
|
+
}
|
|
421
|
+
return ino;
|
|
430
422
|
}
|
|
431
423
|
/**
|
|
432
424
|
* Commits a new file (well, a FILE or a DIRECTORY) to the file system with
|
|
@@ -442,18 +434,18 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
442
434
|
const parentDir = dirname(p), fname = basename(p), parentNode = await this.findINode(tx, parentDir), dirListing = await this.getDirListing(tx, parentNode, parentDir);
|
|
443
435
|
//Check that the creater has correct access
|
|
444
436
|
if (!parentNode.toStats().hasAccess(W_OK, cred)) {
|
|
445
|
-
throw ApiError.EACCES
|
|
437
|
+
throw ApiError.With('EACCES', p, 'commitNewFile');
|
|
446
438
|
}
|
|
447
439
|
// Invariant: The root always exists.
|
|
448
440
|
// If we don't check this prior to taking steps below, we will create a
|
|
449
441
|
// file with name '' in root should p == '/'.
|
|
450
442
|
if (p === '/') {
|
|
451
|
-
throw ApiError.EEXIST
|
|
443
|
+
throw ApiError.With('EEXIST', p, 'commitNewFile');
|
|
452
444
|
}
|
|
453
445
|
// Check if file already exists.
|
|
454
446
|
if (dirListing[fname]) {
|
|
455
447
|
await tx.abort();
|
|
456
|
-
throw ApiError.EEXIST
|
|
448
|
+
throw ApiError.With('EEXIST', p, 'commitNewFile');
|
|
457
449
|
}
|
|
458
450
|
try {
|
|
459
451
|
// Commit data.
|
|
@@ -492,21 +484,21 @@ export class AsyncStoreFS extends Async(FileSystem) {
|
|
|
492
484
|
}
|
|
493
485
|
const tx = this.store.beginTransaction(), parent = dirname(p), parentNode = await this.findINode(tx, parent), parentListing = await this.getDirListing(tx, parentNode, parent), fileName = basename(p);
|
|
494
486
|
if (!parentListing[fileName]) {
|
|
495
|
-
throw ApiError.ENOENT
|
|
487
|
+
throw ApiError.With('ENOENT', p, 'removeEntry');
|
|
496
488
|
}
|
|
497
489
|
const fileIno = parentListing[fileName];
|
|
498
490
|
// Get file inode.
|
|
499
491
|
const fileNode = await this.getINode(tx, fileIno, p);
|
|
500
492
|
if (!fileNode.toStats().hasAccess(W_OK, cred)) {
|
|
501
|
-
throw ApiError.EACCES
|
|
493
|
+
throw ApiError.With('EACCES', p, 'removeEntry');
|
|
502
494
|
}
|
|
503
495
|
// Remove from directory listing of parent.
|
|
504
496
|
delete parentListing[fileName];
|
|
505
497
|
if (!isDir && fileNode.toStats().isDirectory()) {
|
|
506
|
-
throw ApiError.EISDIR
|
|
498
|
+
throw ApiError.With('EISDIR', p, 'removeEntry');
|
|
507
499
|
}
|
|
508
500
|
if (isDir && !fileNode.toStats().isDirectory()) {
|
|
509
|
-
throw ApiError.ENOTDIR
|
|
501
|
+
throw ApiError.With('ENOTDIR', p, 'removeEntry');
|
|
510
502
|
}
|
|
511
503
|
try {
|
|
512
504
|
await tx.put(parentNode.ino, encodeDirListing(parentListing), true);
|
package/dist/backends/Overlay.js
CHANGED
|
@@ -134,7 +134,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
134
134
|
}
|
|
135
135
|
catch (e) {
|
|
136
136
|
if (this._deletedFiles.has(oldPath)) {
|
|
137
|
-
throw ApiError.ENOENT
|
|
137
|
+
throw ApiError.With('ENOENT', oldPath, 'rename');
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
}
|
|
@@ -147,7 +147,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
147
147
|
}
|
|
148
148
|
catch (e) {
|
|
149
149
|
if (this._deletedFiles.has(oldPath)) {
|
|
150
|
-
throw ApiError.ENOENT
|
|
150
|
+
throw ApiError.With('ENOENT', oldPath, 'renameSync');
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
}
|
|
@@ -158,7 +158,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
158
158
|
}
|
|
159
159
|
catch (e) {
|
|
160
160
|
if (this._deletedFiles.has(p)) {
|
|
161
|
-
throw ApiError.ENOENT
|
|
161
|
+
throw ApiError.With('ENOENT', p, 'stat');
|
|
162
162
|
}
|
|
163
163
|
const oldStat = new Stats(await this._readable.stat(p, cred));
|
|
164
164
|
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type
|
|
@@ -173,7 +173,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
173
173
|
}
|
|
174
174
|
catch (e) {
|
|
175
175
|
if (this._deletedFiles.has(p)) {
|
|
176
|
-
throw ApiError.ENOENT
|
|
176
|
+
throw ApiError.With('ENOENT', p, 'statSync');
|
|
177
177
|
}
|
|
178
178
|
const oldStat = new Stats(this._readable.statSync(p, cred));
|
|
179
179
|
// Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type.
|
|
@@ -224,7 +224,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
224
224
|
this.checkInitialized();
|
|
225
225
|
this.checkPath(p);
|
|
226
226
|
if (!(await this.exists(p, cred))) {
|
|
227
|
-
throw ApiError.ENOENT
|
|
227
|
+
throw ApiError.With('ENOENT', p, 'unlink');
|
|
228
228
|
}
|
|
229
229
|
if (await this._writable.exists(p, cred)) {
|
|
230
230
|
await this._writable.unlink(p, cred);
|
|
@@ -238,7 +238,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
238
238
|
this.checkInitialized();
|
|
239
239
|
this.checkPath(p);
|
|
240
240
|
if (!this.existsSync(p, cred)) {
|
|
241
|
-
throw ApiError.ENOENT
|
|
241
|
+
throw ApiError.With('ENOENT', p, 'unlinkSync');
|
|
242
242
|
}
|
|
243
243
|
if (this._writable.existsSync(p, cred)) {
|
|
244
244
|
this._writable.unlinkSync(p, cred);
|
|
@@ -251,7 +251,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
251
251
|
async rmdir(p, cred) {
|
|
252
252
|
this.checkInitialized();
|
|
253
253
|
if (!(await this.exists(p, cred))) {
|
|
254
|
-
throw ApiError.ENOENT
|
|
254
|
+
throw ApiError.With('ENOENT', p, 'rmdir');
|
|
255
255
|
}
|
|
256
256
|
if (await this._writable.exists(p, cred)) {
|
|
257
257
|
await this._writable.rmdir(p, cred);
|
|
@@ -259,7 +259,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
259
259
|
if (await this.exists(p, cred)) {
|
|
260
260
|
// Check if directory is empty.
|
|
261
261
|
if ((await this.readdir(p, cred)).length > 0) {
|
|
262
|
-
throw ApiError.ENOTEMPTY
|
|
262
|
+
throw ApiError.With('ENOTEMPTY', p, 'rmdir');
|
|
263
263
|
}
|
|
264
264
|
else {
|
|
265
265
|
this.deletePath(p, cred);
|
|
@@ -269,7 +269,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
269
269
|
rmdirSync(p, cred) {
|
|
270
270
|
this.checkInitialized();
|
|
271
271
|
if (!this.existsSync(p, cred)) {
|
|
272
|
-
throw ApiError.ENOENT
|
|
272
|
+
throw ApiError.With('ENOENT', p, 'rmdirSync');
|
|
273
273
|
}
|
|
274
274
|
if (this._writable.existsSync(p, cred)) {
|
|
275
275
|
this._writable.rmdirSync(p, cred);
|
|
@@ -277,7 +277,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
277
277
|
if (this.existsSync(p, cred)) {
|
|
278
278
|
// Check if directory is empty.
|
|
279
279
|
if (this.readdirSync(p, cred).length > 0) {
|
|
280
|
-
throw ApiError.ENOTEMPTY
|
|
280
|
+
throw ApiError.With('ENOTEMPTY', p, 'rmdirSync');
|
|
281
281
|
}
|
|
282
282
|
else {
|
|
283
283
|
this.deletePath(p, cred);
|
|
@@ -287,7 +287,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
287
287
|
async mkdir(p, mode, cred) {
|
|
288
288
|
this.checkInitialized();
|
|
289
289
|
if (await this.exists(p, cred)) {
|
|
290
|
-
throw ApiError.EEXIST
|
|
290
|
+
throw ApiError.With('EEXIST', p, 'mkdir');
|
|
291
291
|
}
|
|
292
292
|
// The below will throw should any of the parent directories fail to exist on _writable.
|
|
293
293
|
await this.createParentDirectories(p, cred);
|
|
@@ -296,7 +296,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
296
296
|
mkdirSync(p, mode, cred) {
|
|
297
297
|
this.checkInitialized();
|
|
298
298
|
if (this.existsSync(p, cred)) {
|
|
299
|
-
throw ApiError.EEXIST
|
|
299
|
+
throw ApiError.With('EEXIST', p, 'mkdirSync');
|
|
300
300
|
}
|
|
301
301
|
// The below will throw should any of the parent directories fail to exist on _writable.
|
|
302
302
|
this.createParentDirectoriesSync(p, cred);
|
|
@@ -306,7 +306,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
306
306
|
this.checkInitialized();
|
|
307
307
|
const dirStats = await this.stat(p, cred);
|
|
308
308
|
if (!dirStats.isDirectory()) {
|
|
309
|
-
throw ApiError.ENOTDIR
|
|
309
|
+
throw ApiError.With('ENOTDIR', p, 'readdir');
|
|
310
310
|
}
|
|
311
311
|
// Readdir in both, check delete log on RO file system's listing, merge, return.
|
|
312
312
|
const contents = [];
|
|
@@ -333,7 +333,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
333
333
|
this.checkInitialized();
|
|
334
334
|
const dirStats = this.statSync(p, cred);
|
|
335
335
|
if (!dirStats.isDirectory()) {
|
|
336
|
-
throw ApiError.ENOTDIR
|
|
336
|
+
throw ApiError.With('ENOTDIR', p, 'readdirSync');
|
|
337
337
|
}
|
|
338
338
|
// Readdir in both, check delete log on RO file system's listing, merge, return.
|
|
339
339
|
let contents = [];
|
|
@@ -405,7 +405,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
405
405
|
}
|
|
406
406
|
checkPath(path) {
|
|
407
407
|
if (path == deletionLogPath) {
|
|
408
|
-
throw ApiError.EPERM
|
|
408
|
+
throw ApiError.With('EPERM', path, 'checkPath');
|
|
409
409
|
}
|
|
410
410
|
}
|
|
411
411
|
/**
|
|
@@ -442,7 +442,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
442
442
|
*/
|
|
443
443
|
operateOnWritable(p, cred) {
|
|
444
444
|
if (!this.existsSync(p, cred)) {
|
|
445
|
-
throw ApiError.ENOENT
|
|
445
|
+
throw ApiError.With('ENOENT', p, 'operateOnWriteable');
|
|
446
446
|
}
|
|
447
447
|
if (!this._writable.existsSync(p, cred)) {
|
|
448
448
|
// File is on readable storage. Copy to writable storage before
|
|
@@ -452,7 +452,7 @@ export class UnlockedOverlayFS extends FileSystem {
|
|
|
452
452
|
}
|
|
453
453
|
async operateOnWritableAsync(p, cred) {
|
|
454
454
|
if (!(await this.exists(p, cred))) {
|
|
455
|
-
throw ApiError.ENOENT
|
|
455
|
+
throw ApiError.With('ENOENT', p, 'operateOnWritableAsync');
|
|
456
456
|
}
|
|
457
457
|
if (!(await this._writable.exists(p, cred))) {
|
|
458
458
|
return this.copyToWritable(p, cred);
|
|
@@ -202,7 +202,7 @@ export declare class SyncStoreFS extends SyncStoreFS_base {
|
|
|
202
202
|
* the exceedingly unlikely chance that we try to reuse a random GUID.
|
|
203
203
|
* @return The GUID that the data was stored under.
|
|
204
204
|
*/
|
|
205
|
-
protected addNewNode(tx: SyncTransaction, data: Uint8Array): Ino;
|
|
205
|
+
protected addNewNode(tx: SyncTransaction, data: Uint8Array, _maxAttempts?: number): Ino;
|
|
206
206
|
/**
|
|
207
207
|
* Commits a new file (well, a FILE or a DIRECTORY) to the file system with the given mode.
|
|
208
208
|
* Note: This will commit the transaction.
|