@zenfs/core 0.9.7 → 0.10.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.
Files changed (71) hide show
  1. package/dist/backends/AsyncStore.js +29 -29
  2. package/dist/backends/Fetch.d.ts +84 -0
  3. package/dist/backends/Fetch.js +171 -0
  4. package/dist/backends/Index.js +19 -19
  5. package/dist/backends/Locked.d.ts +11 -11
  6. package/dist/backends/Locked.js +50 -49
  7. package/dist/backends/Overlay.js +21 -21
  8. package/dist/backends/SyncStore.js +27 -27
  9. package/dist/backends/backend.js +4 -4
  10. package/dist/backends/port/fs.d.ts +124 -0
  11. package/dist/backends/port/fs.js +241 -0
  12. package/dist/backends/port/rpc.d.ts +60 -0
  13. package/dist/backends/port/rpc.js +71 -0
  14. package/dist/backends/port/store.d.ts +30 -0
  15. package/dist/backends/port/store.js +142 -0
  16. package/dist/browser.min.js +4 -4
  17. package/dist/browser.min.js.map +4 -4
  18. package/dist/config.d.ts +8 -10
  19. package/dist/config.js +11 -11
  20. package/dist/emulation/async.js +6 -6
  21. package/dist/emulation/dir.js +2 -2
  22. package/dist/emulation/index.d.ts +1 -1
  23. package/dist/emulation/index.js +1 -1
  24. package/dist/emulation/path.d.ts +3 -2
  25. package/dist/emulation/path.js +19 -45
  26. package/dist/emulation/promises.d.ts +7 -12
  27. package/dist/emulation/promises.js +144 -146
  28. package/dist/emulation/shared.d.ts +5 -10
  29. package/dist/emulation/shared.js +8 -8
  30. package/dist/emulation/streams.js +3 -3
  31. package/dist/emulation/sync.js +25 -25
  32. package/dist/{ApiError.d.ts → error.d.ts} +13 -14
  33. package/dist/error.js +292 -0
  34. package/dist/file.d.ts +2 -0
  35. package/dist/file.js +10 -4
  36. package/dist/filesystem.js +15 -15
  37. package/dist/index.d.ts +4 -1
  38. package/dist/index.js +4 -1
  39. package/dist/mutex.js +2 -1
  40. package/dist/utils.d.ts +8 -7
  41. package/dist/utils.js +11 -12
  42. package/package.json +3 -3
  43. package/readme.md +17 -9
  44. package/src/backends/AsyncStore.ts +29 -29
  45. package/src/backends/Fetch.ts +230 -0
  46. package/src/backends/Index.ts +19 -19
  47. package/src/backends/Locked.ts +50 -49
  48. package/src/backends/Overlay.ts +23 -23
  49. package/src/backends/SyncStore.ts +27 -27
  50. package/src/backends/backend.ts +6 -6
  51. package/src/backends/port/fs.ts +308 -0
  52. package/src/backends/port/readme.md +59 -0
  53. package/src/backends/port/rpc.ts +144 -0
  54. package/src/backends/port/store.ts +187 -0
  55. package/src/config.ts +20 -24
  56. package/src/emulation/async.ts +6 -6
  57. package/src/emulation/dir.ts +2 -2
  58. package/src/emulation/index.ts +1 -1
  59. package/src/emulation/path.ts +25 -49
  60. package/src/emulation/promises.ts +150 -159
  61. package/src/emulation/shared.ts +12 -14
  62. package/src/emulation/streams.ts +3 -3
  63. package/src/emulation/sync.ts +28 -28
  64. package/src/{ApiError.ts → error.ts} +89 -89
  65. package/src/file.ts +12 -4
  66. package/src/filesystem.ts +15 -15
  67. package/src/index.ts +4 -1
  68. package/src/mutex.ts +3 -1
  69. package/src/utils.ts +16 -18
  70. package/tsconfig.json +2 -2
  71. package/dist/ApiError.js +0 -292
@@ -1,3 +1,4 @@
1
+ import { ErrnoError } from '../error.js';
1
2
  import { Mutex } from '../mutex.js';
2
3
  /**
3
4
  * This class serializes access to an underlying async filesystem.
@@ -31,21 +32,21 @@ export class LockedFS {
31
32
  }
32
33
  renameSync(oldPath, newPath, cred) {
33
34
  if (this._mu.isLocked(oldPath)) {
34
- throw new Error('invalid sync call');
35
+ throw ErrnoError.With('EBUSY', oldPath, 'rename');
35
36
  }
36
37
  return this.fs.renameSync(oldPath, newPath, cred);
37
38
  }
38
- async stat(p, cred) {
39
- await this._mu.lock(p);
40
- const stats = await this.fs.stat(p, cred);
41
- this._mu.unlock(p);
39
+ async stat(path, cred) {
40
+ await this._mu.lock(path);
41
+ const stats = await this.fs.stat(path, cred);
42
+ this._mu.unlock(path);
42
43
  return stats;
43
44
  }
44
- statSync(p, cred) {
45
- if (this._mu.isLocked(p)) {
46
- throw new Error('invalid sync call');
45
+ statSync(path, cred) {
46
+ if (this._mu.isLocked(path)) {
47
+ throw ErrnoError.With('EBUSY', path, 'stat');
47
48
  }
48
- return this.fs.statSync(p, cred);
49
+ return this.fs.statSync(path, cred);
49
50
  }
50
51
  async openFile(path, flag, cred) {
51
52
  await this._mu.lock(path);
@@ -55,7 +56,7 @@ export class LockedFS {
55
56
  }
56
57
  openFileSync(path, flag, cred) {
57
58
  if (this._mu.isLocked(path)) {
58
- throw new Error('invalid sync call');
59
+ throw ErrnoError.With('EBUSY', path, 'openFile');
59
60
  }
60
61
  return this.fs.openFileSync(path, flag, cred);
61
62
  }
@@ -67,7 +68,7 @@ export class LockedFS {
67
68
  }
68
69
  createFileSync(path, flag, mode, cred) {
69
70
  if (this._mu.isLocked(path)) {
70
- throw new Error('invalid sync call');
71
+ throw ErrnoError.With('EBUSY', path, 'createFile');
71
72
  }
72
73
  return this.fs.createFileSync(path, flag, mode, cred);
73
74
  }
@@ -76,57 +77,57 @@ export class LockedFS {
76
77
  await this.fs.unlink(p, cred);
77
78
  this._mu.unlock(p);
78
79
  }
79
- unlinkSync(p, cred) {
80
- if (this._mu.isLocked(p)) {
81
- throw new Error('invalid sync call');
80
+ unlinkSync(path, cred) {
81
+ if (this._mu.isLocked(path)) {
82
+ throw ErrnoError.With('EBUSY', path, 'unlink');
82
83
  }
83
- return this.fs.unlinkSync(p, cred);
84
+ return this.fs.unlinkSync(path, cred);
84
85
  }
85
- async rmdir(p, cred) {
86
- await this._mu.lock(p);
87
- await this.fs.rmdir(p, cred);
88
- this._mu.unlock(p);
86
+ async rmdir(path, cred) {
87
+ await this._mu.lock(path);
88
+ await this.fs.rmdir(path, cred);
89
+ this._mu.unlock(path);
89
90
  }
90
- rmdirSync(p, cred) {
91
- if (this._mu.isLocked(p)) {
92
- throw new Error('invalid sync call');
91
+ rmdirSync(path, cred) {
92
+ if (this._mu.isLocked(path)) {
93
+ throw ErrnoError.With('EBUSY', path, 'rmdir');
93
94
  }
94
- return this.fs.rmdirSync(p, cred);
95
+ return this.fs.rmdirSync(path, cred);
95
96
  }
96
- async mkdir(p, mode, cred) {
97
- await this._mu.lock(p);
98
- await this.fs.mkdir(p, mode, cred);
99
- this._mu.unlock(p);
97
+ async mkdir(path, mode, cred) {
98
+ await this._mu.lock(path);
99
+ await this.fs.mkdir(path, mode, cred);
100
+ this._mu.unlock(path);
100
101
  }
101
- mkdirSync(p, mode, cred) {
102
- if (this._mu.isLocked(p)) {
103
- throw new Error('invalid sync call');
102
+ mkdirSync(path, mode, cred) {
103
+ if (this._mu.isLocked(path)) {
104
+ throw ErrnoError.With('EBUSY', path, 'mkdir');
104
105
  }
105
- return this.fs.mkdirSync(p, mode, cred);
106
+ return this.fs.mkdirSync(path, mode, cred);
106
107
  }
107
- async readdir(p, cred) {
108
- await this._mu.lock(p);
109
- const files = await this.fs.readdir(p, cred);
110
- this._mu.unlock(p);
108
+ async readdir(path, cred) {
109
+ await this._mu.lock(path);
110
+ const files = await this.fs.readdir(path, cred);
111
+ this._mu.unlock(path);
111
112
  return files;
112
113
  }
113
- readdirSync(p, cred) {
114
- if (this._mu.isLocked(p)) {
115
- throw new Error('invalid sync call');
114
+ readdirSync(path, cred) {
115
+ if (this._mu.isLocked(path)) {
116
+ throw ErrnoError.With('EBUSY', path, 'readdir');
116
117
  }
117
- return this.fs.readdirSync(p, cred);
118
+ return this.fs.readdirSync(path, cred);
118
119
  }
119
- async exists(p, cred) {
120
- await this._mu.lock(p);
121
- const exists = await this.fs.exists(p, cred);
122
- this._mu.unlock(p);
120
+ async exists(path, cred) {
121
+ await this._mu.lock(path);
122
+ const exists = await this.fs.exists(path, cred);
123
+ this._mu.unlock(path);
123
124
  return exists;
124
125
  }
125
- existsSync(p, cred) {
126
- if (this._mu.isLocked(p)) {
127
- throw new Error('invalid sync call');
126
+ existsSync(path, cred) {
127
+ if (this._mu.isLocked(path)) {
128
+ throw ErrnoError.With('EBUSY', path, 'exists');
128
129
  }
129
- return this.fs.existsSync(p, cred);
130
+ return this.fs.existsSync(path, cred);
130
131
  }
131
132
  async link(srcpath, dstpath, cred) {
132
133
  await this._mu.lock(srcpath);
@@ -135,7 +136,7 @@ export class LockedFS {
135
136
  }
136
137
  linkSync(srcpath, dstpath, cred) {
137
138
  if (this._mu.isLocked(srcpath)) {
138
- throw new Error('invalid sync call');
139
+ throw ErrnoError.With('EBUSY', srcpath, 'link');
139
140
  }
140
141
  return this.fs.linkSync(srcpath, dstpath, cred);
141
142
  }
@@ -146,7 +147,7 @@ export class LockedFS {
146
147
  }
147
148
  syncSync(path, data, stats) {
148
149
  if (this._mu.isLocked(path)) {
149
- throw new Error('invalid sync call');
150
+ throw ErrnoError.With('EBUSY', path, 'sync');
150
151
  }
151
152
  return this.fs.syncSync(path, data, stats);
152
153
  }
@@ -1,5 +1,5 @@
1
1
  import { FileSystem } from '../filesystem.js';
2
- import { ApiError, ErrorCode } from '../ApiError.js';
2
+ import { ErrnoError, Errno } from '../error.js';
3
3
  import { PreloadFile, parseFlag } from '../file.js';
4
4
  import { Stats } from '../stats.js';
5
5
  import { LockedFS } from './Locked.js';
@@ -38,7 +38,7 @@ export class UnlockedOverlayFS extends FileSystem {
38
38
  this._writable = writable;
39
39
  this._readable = readable;
40
40
  if (this._writable.metadata().readonly) {
41
- throw new ApiError(ErrorCode.EINVAL, 'Writable file system must be writable.');
41
+ throw new ErrnoError(Errno.EINVAL, 'Writable file system must be writable.');
42
42
  }
43
43
  this._ready = this._initialize();
44
44
  }
@@ -80,7 +80,7 @@ export class UnlockedOverlayFS extends FileSystem {
80
80
  this._deleteLog = decode(buffer);
81
81
  }
82
82
  catch (err) {
83
- if (err.errno !== ErrorCode.ENOENT) {
83
+ if (err.errno !== Errno.ENOENT) {
84
84
  throw err;
85
85
  }
86
86
  }
@@ -104,7 +104,7 @@ export class UnlockedOverlayFS extends FileSystem {
104
104
  }
105
105
  catch (e) {
106
106
  if (this._deletedFiles.has(oldPath)) {
107
- throw ApiError.With('ENOENT', oldPath, 'rename');
107
+ throw ErrnoError.With('ENOENT', oldPath, 'rename');
108
108
  }
109
109
  }
110
110
  }
@@ -117,7 +117,7 @@ export class UnlockedOverlayFS extends FileSystem {
117
117
  }
118
118
  catch (e) {
119
119
  if (this._deletedFiles.has(oldPath)) {
120
- throw ApiError.With('ENOENT', oldPath, 'rename');
120
+ throw ErrnoError.With('ENOENT', oldPath, 'rename');
121
121
  }
122
122
  }
123
123
  }
@@ -128,7 +128,7 @@ export class UnlockedOverlayFS extends FileSystem {
128
128
  }
129
129
  catch (e) {
130
130
  if (this._deletedFiles.has(p)) {
131
- throw ApiError.With('ENOENT', p, 'stat');
131
+ throw ErrnoError.With('ENOENT', p, 'stat');
132
132
  }
133
133
  const oldStat = new Stats(await this._readable.stat(p, cred));
134
134
  // Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type
@@ -143,7 +143,7 @@ export class UnlockedOverlayFS extends FileSystem {
143
143
  }
144
144
  catch (e) {
145
145
  if (this._deletedFiles.has(p)) {
146
- throw ApiError.With('ENOENT', p, 'stat');
146
+ throw ErrnoError.With('ENOENT', p, 'stat');
147
147
  }
148
148
  const oldStat = new Stats(this._readable.statSync(p, cred));
149
149
  // Make the oldStat's mode writable. Preserve the topmost part of the mode, which specifies the type.
@@ -194,7 +194,7 @@ export class UnlockedOverlayFS extends FileSystem {
194
194
  this.checkInitialized();
195
195
  this.checkPath(p);
196
196
  if (!(await this.exists(p, cred))) {
197
- throw ApiError.With('ENOENT', p, 'unlink');
197
+ throw ErrnoError.With('ENOENT', p, 'unlink');
198
198
  }
199
199
  if (await this._writable.exists(p, cred)) {
200
200
  await this._writable.unlink(p, cred);
@@ -208,7 +208,7 @@ export class UnlockedOverlayFS extends FileSystem {
208
208
  this.checkInitialized();
209
209
  this.checkPath(p);
210
210
  if (!this.existsSync(p, cred)) {
211
- throw ApiError.With('ENOENT', p, 'unlink');
211
+ throw ErrnoError.With('ENOENT', p, 'unlink');
212
212
  }
213
213
  if (this._writable.existsSync(p, cred)) {
214
214
  this._writable.unlinkSync(p, cred);
@@ -221,7 +221,7 @@ export class UnlockedOverlayFS extends FileSystem {
221
221
  async rmdir(p, cred) {
222
222
  this.checkInitialized();
223
223
  if (!(await this.exists(p, cred))) {
224
- throw ApiError.With('ENOENT', p, 'rmdir');
224
+ throw ErrnoError.With('ENOENT', p, 'rmdir');
225
225
  }
226
226
  if (await this._writable.exists(p, cred)) {
227
227
  await this._writable.rmdir(p, cred);
@@ -229,7 +229,7 @@ export class UnlockedOverlayFS extends FileSystem {
229
229
  if (await this.exists(p, cred)) {
230
230
  // Check if directory is empty.
231
231
  if ((await this.readdir(p, cred)).length > 0) {
232
- throw ApiError.With('ENOTEMPTY', p, 'rmdir');
232
+ throw ErrnoError.With('ENOTEMPTY', p, 'rmdir');
233
233
  }
234
234
  else {
235
235
  this.deletePath(p, cred);
@@ -239,7 +239,7 @@ export class UnlockedOverlayFS extends FileSystem {
239
239
  rmdirSync(p, cred) {
240
240
  this.checkInitialized();
241
241
  if (!this.existsSync(p, cred)) {
242
- throw ApiError.With('ENOENT', p, 'rmdir');
242
+ throw ErrnoError.With('ENOENT', p, 'rmdir');
243
243
  }
244
244
  if (this._writable.existsSync(p, cred)) {
245
245
  this._writable.rmdirSync(p, cred);
@@ -247,7 +247,7 @@ export class UnlockedOverlayFS extends FileSystem {
247
247
  if (this.existsSync(p, cred)) {
248
248
  // Check if directory is empty.
249
249
  if (this.readdirSync(p, cred).length > 0) {
250
- throw ApiError.With('ENOTEMPTY', p, 'rmdir');
250
+ throw ErrnoError.With('ENOTEMPTY', p, 'rmdir');
251
251
  }
252
252
  else {
253
253
  this.deletePath(p, cred);
@@ -257,7 +257,7 @@ export class UnlockedOverlayFS extends FileSystem {
257
257
  async mkdir(p, mode, cred) {
258
258
  this.checkInitialized();
259
259
  if (await this.exists(p, cred)) {
260
- throw ApiError.With('EEXIST', p, 'mkdir');
260
+ throw ErrnoError.With('EEXIST', p, 'mkdir');
261
261
  }
262
262
  // The below will throw should any of the parent directories fail to exist on _writable.
263
263
  await this.createParentDirectories(p, cred);
@@ -266,7 +266,7 @@ export class UnlockedOverlayFS extends FileSystem {
266
266
  mkdirSync(p, mode, cred) {
267
267
  this.checkInitialized();
268
268
  if (this.existsSync(p, cred)) {
269
- throw ApiError.With('EEXIST', p, 'mkdir');
269
+ throw ErrnoError.With('EEXIST', p, 'mkdir');
270
270
  }
271
271
  // The below will throw should any of the parent directories fail to exist on _writable.
272
272
  this.createParentDirectoriesSync(p, cred);
@@ -276,7 +276,7 @@ export class UnlockedOverlayFS extends FileSystem {
276
276
  this.checkInitialized();
277
277
  const dirStats = await this.stat(p, cred);
278
278
  if (!dirStats.isDirectory()) {
279
- throw ApiError.With('ENOTDIR', p, 'readdir');
279
+ throw ErrnoError.With('ENOTDIR', p, 'readdir');
280
280
  }
281
281
  // Readdir in both, check delete log on RO file system's listing, merge, return.
282
282
  const contents = [];
@@ -303,7 +303,7 @@ export class UnlockedOverlayFS extends FileSystem {
303
303
  this.checkInitialized();
304
304
  const dirStats = this.statSync(p, cred);
305
305
  if (!dirStats.isDirectory()) {
306
- throw ApiError.With('ENOTDIR', p, 'readdir');
306
+ throw ErrnoError.With('ENOTDIR', p, 'readdir');
307
307
  }
308
308
  // Readdir in both, check delete log on RO file system's listing, merge, return.
309
309
  let contents = [];
@@ -364,7 +364,7 @@ export class UnlockedOverlayFS extends FileSystem {
364
364
  }
365
365
  checkInitialized() {
366
366
  if (!this._isInitialized) {
367
- throw new ApiError(ErrorCode.EPERM, 'OverlayFS is not initialized. Please initialize OverlayFS using its initialize() method before using it.');
367
+ throw new ErrnoError(Errno.EPERM, 'OverlayFS is not initialized. Please initialize OverlayFS using its initialize() method before using it.');
368
368
  }
369
369
  if (!this._deleteLogError) {
370
370
  return;
@@ -375,7 +375,7 @@ export class UnlockedOverlayFS extends FileSystem {
375
375
  }
376
376
  checkPath(path) {
377
377
  if (path == deletionLogPath) {
378
- throw ApiError.With('EPERM', path, 'checkPath');
378
+ throw ErrnoError.With('EPERM', path, 'checkPath');
379
379
  }
380
380
  }
381
381
  /**
@@ -412,7 +412,7 @@ export class UnlockedOverlayFS extends FileSystem {
412
412
  */
413
413
  operateOnWritable(p, cred) {
414
414
  if (!this.existsSync(p, cred)) {
415
- throw ApiError.With('ENOENT', p, 'operateOnWriteable');
415
+ throw ErrnoError.With('ENOENT', p, 'operateOnWriteable');
416
416
  }
417
417
  if (!this._writable.existsSync(p, cred)) {
418
418
  // File is on readable storage. Copy to writable storage before
@@ -422,7 +422,7 @@ export class UnlockedOverlayFS extends FileSystem {
422
422
  }
423
423
  async operateOnWritableAsync(p, cred) {
424
424
  if (!(await this.exists(p, cred))) {
425
- throw ApiError.With('ENOENT', p, 'operateOnWritable');
425
+ throw ErrnoError.With('ENOENT', p, 'operateOnWritable');
426
426
  }
427
427
  if (!(await this._writable.exists(p, cred))) {
428
428
  return this.copyToWritable(p, cred);
@@ -1,5 +1,5 @@
1
1
  import { dirname, basename, join, resolve, sep } from '../emulation/path.js';
2
- import { ApiError, ErrorCode } from '../ApiError.js';
2
+ import { ErrnoError, Errno } from '../error.js';
3
3
  import { W_OK, R_OK } from '../emulation/constants.js';
4
4
  import { PreloadFile, flagToMode } from '../file.js';
5
5
  import { FileSystem, Sync } from '../filesystem.js';
@@ -110,10 +110,10 @@ export class SyncStoreFS extends Sync(FileSystem) {
110
110
  // Remove oldPath from parent's directory listing.
111
111
  oldDirNode = this.findINode(tx, oldParent), oldDirList = this.getDirListing(tx, oldDirNode, oldParent);
112
112
  if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
113
- throw ApiError.With('EACCES', oldPath, 'rename');
113
+ throw ErrnoError.With('EACCES', oldPath, 'rename');
114
114
  }
115
115
  if (!oldDirList[oldName]) {
116
- throw ApiError.With('ENOENT', oldPath, 'rename');
116
+ throw ErrnoError.With('ENOENT', oldPath, 'rename');
117
117
  }
118
118
  const ino = oldDirList[oldName];
119
119
  delete oldDirList[oldName];
@@ -122,7 +122,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
122
122
  // is a subpath of newParent. We append '/' to avoid matching folders that
123
123
  // are a substring of the bottom-most folder in the path.
124
124
  if ((newParent + '/').indexOf(oldPath + '/') == 0) {
125
- throw new ApiError(ErrorCode.EBUSY, oldParent);
125
+ throw new ErrnoError(Errno.EBUSY, oldParent);
126
126
  }
127
127
  // Add newPath to parent's directory listing.
128
128
  let newDirNode, newDirList;
@@ -151,7 +151,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
151
151
  }
152
152
  else {
153
153
  // If it's a directory, throw a permissions error.
154
- throw ApiError.With('EPERM', newPath, 'rename');
154
+ throw ErrnoError.With('EPERM', newPath, 'rename');
155
155
  }
156
156
  }
157
157
  newDirList[newName] = ino;
@@ -170,7 +170,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
170
170
  // Get the inode to the item, convert it into a Stats object.
171
171
  const stats = this.findINode(this.store.beginTransaction(), p).toStats();
172
172
  if (!stats.hasAccess(R_OK, cred)) {
173
- throw ApiError.With('EACCES', p, 'stat');
173
+ throw ErrnoError.With('EACCES', p, 'stat');
174
174
  }
175
175
  return stats;
176
176
  }
@@ -181,10 +181,10 @@ export class SyncStoreFS extends Sync(FileSystem) {
181
181
  openFileSync(p, flag, cred) {
182
182
  const tx = this.store.beginTransaction(), node = this.findINode(tx, p), data = tx.get(node.ino);
183
183
  if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
184
- throw ApiError.With('EACCES', p, 'openFile');
184
+ throw ErrnoError.With('EACCES', p, 'openFile');
185
185
  }
186
186
  if (!data) {
187
- throw ApiError.With('ENOENT', p, 'openFile');
187
+ throw ErrnoError.With('ENOENT', p, 'openFile');
188
188
  }
189
189
  return new PreloadFile(this, p, flag, node.toStats(), data);
190
190
  }
@@ -194,7 +194,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
194
194
  rmdirSync(p, cred) {
195
195
  // Check first if directory is empty.
196
196
  if (this.readdirSync(p, cred).length > 0) {
197
- throw ApiError.With('ENOTEMPTY', p, 'rmdir');
197
+ throw ErrnoError.With('ENOTEMPTY', p, 'rmdir');
198
198
  }
199
199
  else {
200
200
  this.removeEntry(p, true, cred);
@@ -207,7 +207,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
207
207
  const tx = this.store.beginTransaction();
208
208
  const node = this.findINode(tx, p);
209
209
  if (!node.toStats().hasAccess(R_OK, cred)) {
210
- throw ApiError.With('EACCES', p, 'readdir');
210
+ throw ErrnoError.With('EACCES', p, 'readdir');
211
211
  }
212
212
  return Object.keys(this.getDirListing(tx, node, p));
213
213
  }
@@ -234,16 +234,16 @@ export class SyncStoreFS extends Sync(FileSystem) {
234
234
  linkSync(existing, newpath, cred) {
235
235
  const tx = this.store.beginTransaction(), existingDir = dirname(existing), existingDirNode = this.findINode(tx, existingDir);
236
236
  if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
237
- throw ApiError.With('EACCES', existingDir, 'link');
237
+ throw ErrnoError.With('EACCES', existingDir, 'link');
238
238
  }
239
239
  const newDir = dirname(newpath), newDirNode = this.findINode(tx, newDir), newListing = this.getDirListing(tx, newDirNode, newDir);
240
240
  if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
241
- throw ApiError.With('EACCES', newDir, 'link');
241
+ throw ErrnoError.With('EACCES', newDir, 'link');
242
242
  }
243
243
  const ino = this._findINode(tx, existingDir, basename(existing));
244
244
  const node = this.getINode(tx, ino, existing);
245
245
  if (!node.toStats().hasAccess(W_OK, cred)) {
246
- throw ApiError.With('EACCES', newpath, 'link');
246
+ throw ErrnoError.With('EACCES', newpath, 'link');
247
247
  }
248
248
  node.nlink++;
249
249
  newListing[basename(newpath)] = ino;
@@ -283,14 +283,14 @@ export class SyncStoreFS extends Sync(FileSystem) {
283
283
  _findINode(tx, parent, filename, visited = new Set()) {
284
284
  const currentPath = join(parent, filename);
285
285
  if (visited.has(currentPath)) {
286
- throw new ApiError(ErrorCode.EIO, 'Infinite loop detected while finding inode', currentPath);
286
+ throw new ErrnoError(Errno.EIO, 'Infinite loop detected while finding inode', currentPath);
287
287
  }
288
288
  visited.add(currentPath);
289
289
  if (parent != '/') {
290
290
  const ino = this._findINode(tx, dirname(parent), basename(parent), visited);
291
291
  const dir = this.getDirListing(tx, this.getINode(tx, ino, parent + sep + filename), parent);
292
292
  if (!(filename in dir)) {
293
- throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
293
+ throw ErrnoError.With('ENOENT', resolve(parent, filename), '_findINode');
294
294
  }
295
295
  return dir[filename];
296
296
  }
@@ -298,7 +298,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
298
298
  // Find the item in the root node.
299
299
  const dir = this.getDirListing(tx, this.getINode(tx, rootIno, parent), parent);
300
300
  if (!(filename in dir)) {
301
- throw ApiError.With('ENOENT', resolve(parent, filename), '_findINode');
301
+ throw ErrnoError.With('ENOENT', resolve(parent, filename), '_findINode');
302
302
  }
303
303
  return dir[filename];
304
304
  }
@@ -324,7 +324,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
324
324
  getINode(tx, id, path) {
325
325
  const data = tx.get(id);
326
326
  if (!data) {
327
- throw ApiError.With('ENOENT', path, 'getINode');
327
+ throw ErrnoError.With('ENOENT', path, 'getINode');
328
328
  }
329
329
  const inode = new Inode(data.buffer);
330
330
  return inode;
@@ -334,11 +334,11 @@ export class SyncStoreFS extends Sync(FileSystem) {
334
334
  */
335
335
  getDirListing(tx, inode, p) {
336
336
  if (!inode.toStats().isDirectory()) {
337
- throw ApiError.With('ENOTDIR', p, 'getDirListing');
337
+ throw ErrnoError.With('ENOTDIR', p, 'getDirListing');
338
338
  }
339
339
  const data = tx.get(inode.ino);
340
340
  if (!data) {
341
- throw ApiError.With('ENOENT', p, 'getDirListing');
341
+ throw ErrnoError.With('ENOENT', p, 'getDirListing');
342
342
  }
343
343
  return decodeDirListing(data);
344
344
  }
@@ -355,7 +355,7 @@ export class SyncStoreFS extends Sync(FileSystem) {
355
355
  }
356
356
  return ino;
357
357
  }
358
- throw new ApiError(ErrorCode.EIO, 'Unable to commit data to key-value store.');
358
+ throw new ErrnoError(Errno.EIO, 'Unable to commit data to key-value store.');
359
359
  }
360
360
  /**
361
361
  * Commits a new file (well, a FILE or a DIRECTORY) to the file system with the given mode.
@@ -370,18 +370,18 @@ export class SyncStoreFS extends Sync(FileSystem) {
370
370
  const tx = this.store.beginTransaction(), parentDir = dirname(p), fname = basename(p), parentNode = this.findINode(tx, parentDir), dirListing = this.getDirListing(tx, parentNode, parentDir);
371
371
  //Check that the creater has correct access
372
372
  if (!parentNode.toStats().hasAccess(W_OK, cred)) {
373
- throw ApiError.With('EACCES', p, 'commitNewFile');
373
+ throw ErrnoError.With('EACCES', p, 'commitNewFile');
374
374
  }
375
375
  /* Invariant: The root always exists.
376
376
  If we don't check this prior to taking steps below,
377
377
  we will create a file with name '' in root should p == '/'.
378
378
  */
379
379
  if (p === '/') {
380
- throw ApiError.With('EEXIST', p, 'commitNewFile');
380
+ throw ErrnoError.With('EEXIST', p, 'commitNewFile');
381
381
  }
382
382
  // Check if file already exists.
383
383
  if (dirListing[fname]) {
384
- throw ApiError.With('EEXIST', p, 'commitNewFile');
384
+ throw ErrnoError.With('EEXIST', p, 'commitNewFile');
385
385
  }
386
386
  const fileNode = new Inode();
387
387
  try {
@@ -411,20 +411,20 @@ export class SyncStoreFS extends Sync(FileSystem) {
411
411
  removeEntry(p, isDir, cred) {
412
412
  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];
413
413
  if (!fileIno) {
414
- throw ApiError.With('ENOENT', p, 'removeEntry');
414
+ throw ErrnoError.With('ENOENT', p, 'removeEntry');
415
415
  }
416
416
  // Get file inode.
417
417
  const fileNode = this.getINode(tx, fileIno, p);
418
418
  if (!fileNode.toStats().hasAccess(W_OK, cred)) {
419
- throw ApiError.With('EACCES', p, 'removeEntry');
419
+ throw ErrnoError.With('EACCES', p, 'removeEntry');
420
420
  }
421
421
  // Remove from directory listing of parent.
422
422
  delete parentListing[fileName];
423
423
  if (!isDir && fileNode.toStats().isDirectory()) {
424
- throw ApiError.With('EISDIR', p, 'removeEntry');
424
+ throw ErrnoError.With('EISDIR', p, 'removeEntry');
425
425
  }
426
426
  if (isDir && !fileNode.toStats().isDirectory()) {
427
- throw ApiError.With('ENOTDIR', p, 'removeEntry');
427
+ throw ErrnoError.With('ENOTDIR', p, 'removeEntry');
428
428
  }
429
429
  try {
430
430
  // Update directory listing.
@@ -1,4 +1,4 @@
1
- import { ApiError, ErrorCode } from '../ApiError.js';
1
+ import { ErrnoError, Errno } from '../error.js';
2
2
  import { levenshtein } from '../utils.js';
3
3
  /**
4
4
  * @internal
@@ -12,7 +12,7 @@ export function isBackend(arg) {
12
12
  */
13
13
  export async function checkOptions(backend, opts) {
14
14
  if (typeof opts != 'object' || opts === null) {
15
- throw new ApiError(ErrorCode.EINVAL, 'Invalid options');
15
+ throw new ErrnoError(Errno.EINVAL, 'Invalid options');
16
16
  }
17
17
  // Check for required options.
18
18
  for (const [optName, opt] of Object.entries(backend.options)) {
@@ -31,12 +31,12 @@ export async function checkOptions(backend, opts) {
31
31
  })
32
32
  .filter(o => o.distance < 5)
33
33
  .sort((a, b) => a.distance - b.distance);
34
- throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided '${incorrectOptions[0].str}', did you mean '${optName}'.` : ''}`);
34
+ throw new ErrnoError(Errno.EINVAL, `${backend.name}: Required option '${optName}' not provided.${incorrectOptions.length > 0 ? ` You provided '${incorrectOptions[0].str}', did you mean '${optName}'.` : ''}`);
35
35
  }
36
36
  // Option provided, check type.
37
37
  const typeMatches = Array.isArray(opt.type) ? opt.type.indexOf(typeof providedValue) != -1 : typeof providedValue == opt.type;
38
38
  if (!typeMatches) {
39
- throw new ApiError(ErrorCode.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}`);
39
+ throw new ErrnoError(Errno.EINVAL, `${backend.name}: Value provided for option ${optName} is not the proper type. Expected ${Array.isArray(opt.type) ? `one of {${opt.type.join(', ')}}` : opt.type}, but received ${typeof providedValue}`);
40
40
  }
41
41
  if (opt.validator) {
42
42
  await opt.validator(providedValue);