@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.
- package/dist/backends/AsyncStore.js +29 -29
- package/dist/backends/Fetch.d.ts +84 -0
- package/dist/backends/Fetch.js +171 -0
- package/dist/backends/Index.js +19 -19
- package/dist/backends/Locked.d.ts +11 -11
- package/dist/backends/Locked.js +50 -49
- package/dist/backends/Overlay.js +21 -21
- package/dist/backends/SyncStore.js +27 -27
- package/dist/backends/backend.js +4 -4
- package/dist/backends/port/fs.d.ts +124 -0
- package/dist/backends/port/fs.js +241 -0
- package/dist/backends/port/rpc.d.ts +60 -0
- package/dist/backends/port/rpc.js +71 -0
- package/dist/backends/port/store.d.ts +30 -0
- package/dist/backends/port/store.js +142 -0
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +8 -10
- package/dist/config.js +11 -11
- package/dist/emulation/async.js +6 -6
- package/dist/emulation/dir.js +2 -2
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/path.d.ts +3 -2
- package/dist/emulation/path.js +19 -45
- package/dist/emulation/promises.d.ts +7 -12
- package/dist/emulation/promises.js +144 -146
- package/dist/emulation/shared.d.ts +5 -10
- package/dist/emulation/shared.js +8 -8
- package/dist/emulation/streams.js +3 -3
- package/dist/emulation/sync.js +25 -25
- package/dist/{ApiError.d.ts → error.d.ts} +13 -14
- package/dist/error.js +292 -0
- package/dist/file.d.ts +2 -0
- package/dist/file.js +10 -4
- package/dist/filesystem.js +15 -15
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/mutex.js +2 -1
- package/dist/utils.d.ts +8 -7
- package/dist/utils.js +11 -12
- package/package.json +3 -3
- package/readme.md +17 -9
- package/src/backends/AsyncStore.ts +29 -29
- package/src/backends/Fetch.ts +230 -0
- package/src/backends/Index.ts +19 -19
- package/src/backends/Locked.ts +50 -49
- package/src/backends/Overlay.ts +23 -23
- package/src/backends/SyncStore.ts +27 -27
- package/src/backends/backend.ts +6 -6
- package/src/backends/port/fs.ts +308 -0
- package/src/backends/port/readme.md +59 -0
- package/src/backends/port/rpc.ts +144 -0
- package/src/backends/port/store.ts +187 -0
- package/src/config.ts +20 -24
- package/src/emulation/async.ts +6 -6
- package/src/emulation/dir.ts +2 -2
- package/src/emulation/index.ts +1 -1
- package/src/emulation/path.ts +25 -49
- package/src/emulation/promises.ts +150 -159
- package/src/emulation/shared.ts +12 -14
- package/src/emulation/streams.ts +3 -3
- package/src/emulation/sync.ts +28 -28
- package/src/{ApiError.ts → error.ts} +89 -89
- package/src/file.ts +12 -4
- package/src/filesystem.ts +15 -15
- package/src/index.ts +4 -1
- package/src/mutex.ts +3 -1
- package/src/utils.ts +16 -18
- package/tsconfig.json +2 -2
- package/dist/ApiError.js +0 -292
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Readable, Writable } from 'readable-stream';
|
|
2
|
-
import {
|
|
2
|
+
import { ErrnoError, Errno } from '../error.js';
|
|
3
3
|
export class ReadStream extends Readable {
|
|
4
4
|
close(callback = () => null) {
|
|
5
5
|
try {
|
|
@@ -8,7 +8,7 @@ export class ReadStream extends Readable {
|
|
|
8
8
|
callback();
|
|
9
9
|
}
|
|
10
10
|
catch (err) {
|
|
11
|
-
callback(new
|
|
11
|
+
callback(new ErrnoError(Errno.EIO, err.toString()));
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -20,7 +20,7 @@ export class WriteStream extends Writable {
|
|
|
20
20
|
callback();
|
|
21
21
|
}
|
|
22
22
|
catch (err) {
|
|
23
|
-
callback(new
|
|
23
|
+
callback(new ErrnoError(Errno.EIO, err.toString()));
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
}
|
package/dist/emulation/sync.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
|
-
import {
|
|
2
|
+
import { ErrnoError, Errno } from '../error.js';
|
|
3
3
|
import { ActionType, isAppendable, isReadable, isWriteable, parseFlag, pathExistsAction, pathNotExistsAction } from '../file.js';
|
|
4
4
|
import { BigIntStats, FileType } from '../stats.js';
|
|
5
5
|
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
@@ -52,7 +52,7 @@ export function existsSync(path) {
|
|
|
52
52
|
return fs.existsSync(resolvedPath, cred);
|
|
53
53
|
}
|
|
54
54
|
catch (e) {
|
|
55
|
-
if (e.errno ==
|
|
55
|
+
if (e.errno == Errno.ENOENT) {
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
58
|
throw e;
|
|
@@ -106,22 +106,22 @@ function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
|
|
|
106
106
|
// Ensure parent exists.
|
|
107
107
|
const parentStats = doOp('statSync', resolveSymlinks, dirname(path), cred);
|
|
108
108
|
if (!parentStats.isDirectory()) {
|
|
109
|
-
throw
|
|
109
|
+
throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
|
|
110
110
|
}
|
|
111
111
|
return doOp('createFileSync', resolveSymlinks, path, flag, mode, cred);
|
|
112
112
|
case ActionType.THROW:
|
|
113
|
-
throw
|
|
113
|
+
throw ErrnoError.With('ENOENT', path, '_open');
|
|
114
114
|
default:
|
|
115
|
-
throw new
|
|
115
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid FileFlag object.');
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
if (!stats.hasAccess(mode, cred)) {
|
|
119
|
-
throw
|
|
119
|
+
throw ErrnoError.With('EACCES', path, '_open');
|
|
120
120
|
}
|
|
121
121
|
// File exists.
|
|
122
122
|
switch (pathExistsAction(flag)) {
|
|
123
123
|
case ActionType.THROW:
|
|
124
|
-
throw
|
|
124
|
+
throw ErrnoError.With('EEXIST', path, '_open');
|
|
125
125
|
case ActionType.TRUNCATE:
|
|
126
126
|
// Delete file.
|
|
127
127
|
doOp('unlinkSync', resolveSymlinks, path, cred);
|
|
@@ -135,7 +135,7 @@ function _openSync(_path, _flag, _mode, resolveSymlinks = true) {
|
|
|
135
135
|
case ActionType.NOP:
|
|
136
136
|
return doOp('openFileSync', resolveSymlinks, path, flag, cred);
|
|
137
137
|
default:
|
|
138
|
-
throw new
|
|
138
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid FileFlag object.');
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
@@ -179,7 +179,7 @@ export function readFileSync(path, _options = {}) {
|
|
|
179
179
|
const options = normalizeOptions(_options, null, 'r', 0o644);
|
|
180
180
|
const flag = parseFlag(options.flag);
|
|
181
181
|
if (!isReadable(flag)) {
|
|
182
|
-
throw new
|
|
182
|
+
throw new ErrnoError(Errno.EINVAL, 'Flag passed to readFile must allow for reading.');
|
|
183
183
|
}
|
|
184
184
|
const data = Buffer.from(_readFileSync(typeof path == 'number' ? fd2file(path).path : path.toString(), options.flag, true));
|
|
185
185
|
return options.encoding ? data.toString(options.encoding) : data;
|
|
@@ -204,14 +204,14 @@ export function writeFileSync(path, data, _options = {}) {
|
|
|
204
204
|
const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
|
|
205
205
|
const flag = parseFlag(options.flag);
|
|
206
206
|
if (!isWriteable(flag)) {
|
|
207
|
-
throw new
|
|
207
|
+
throw new ErrnoError(Errno.EINVAL, 'Flag passed to writeFile must allow for writing.');
|
|
208
208
|
}
|
|
209
209
|
if (typeof data != 'string' && !options.encoding) {
|
|
210
|
-
throw new
|
|
210
|
+
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
211
211
|
}
|
|
212
212
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
213
213
|
if (!encodedData) {
|
|
214
|
-
throw new
|
|
214
|
+
throw new ErrnoError(Errno.EINVAL, 'Data not specified');
|
|
215
215
|
}
|
|
216
216
|
_writeFileSync(typeof path == 'number' ? fd2file(path).path : path.toString(), encodedData, options.flag, options.mode, true);
|
|
217
217
|
}
|
|
@@ -244,10 +244,10 @@ export function appendFileSync(filename, data, _options = {}) {
|
|
|
244
244
|
const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
|
|
245
245
|
const flag = parseFlag(options.flag);
|
|
246
246
|
if (!isAppendable(flag)) {
|
|
247
|
-
throw new
|
|
247
|
+
throw new ErrnoError(Errno.EINVAL, 'Flag passed to appendFile must allow for appending.');
|
|
248
248
|
}
|
|
249
249
|
if (typeof data != 'string' && !options.encoding) {
|
|
250
|
-
throw new
|
|
250
|
+
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
251
251
|
}
|
|
252
252
|
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
253
253
|
_appendFileSync(typeof filename == 'number' ? fd2file(filename).path : filename.toString(), encodedData, options.flag, options.mode, true);
|
|
@@ -275,7 +275,7 @@ closeSync;
|
|
|
275
275
|
export function ftruncateSync(fd, len = 0) {
|
|
276
276
|
len || (len = 0);
|
|
277
277
|
if (len < 0) {
|
|
278
|
-
throw new
|
|
278
|
+
throw new ErrnoError(Errno.EINVAL);
|
|
279
279
|
}
|
|
280
280
|
fd2file(fd).truncateSync(len);
|
|
281
281
|
}
|
|
@@ -350,7 +350,7 @@ fchownSync;
|
|
|
350
350
|
export function fchmodSync(fd, mode) {
|
|
351
351
|
const numMode = normalizeMode(mode, -1);
|
|
352
352
|
if (numMode < 0) {
|
|
353
|
-
throw new
|
|
353
|
+
throw new ErrnoError(Errno.EINVAL, `Invalid mode.`);
|
|
354
354
|
}
|
|
355
355
|
fd2file(fd).chmodSync(numMode);
|
|
356
356
|
}
|
|
@@ -424,10 +424,10 @@ linkSync;
|
|
|
424
424
|
*/
|
|
425
425
|
export function symlinkSync(target, path, type = 'file') {
|
|
426
426
|
if (!['file', 'dir', 'junction'].includes(type)) {
|
|
427
|
-
throw new
|
|
427
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid type: ' + type);
|
|
428
428
|
}
|
|
429
429
|
if (existsSync(path)) {
|
|
430
|
-
throw
|
|
430
|
+
throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
|
|
431
431
|
}
|
|
432
432
|
writeFileSync(path, target.toString());
|
|
433
433
|
const file = _openSync(path, 'r+', 0o644, false);
|
|
@@ -539,7 +539,7 @@ realpathSync;
|
|
|
539
539
|
export function accessSync(path, mode = 0o600) {
|
|
540
540
|
const stats = statSync(path);
|
|
541
541
|
if (!stats.hasAccess(mode, cred)) {
|
|
542
|
-
throw new
|
|
542
|
+
throw new ErrnoError(Errno.EACCES);
|
|
543
543
|
}
|
|
544
544
|
}
|
|
545
545
|
accessSync;
|
|
@@ -568,7 +568,7 @@ export function rmSync(path, options) {
|
|
|
568
568
|
case S_IFIFO:
|
|
569
569
|
case S_IFSOCK:
|
|
570
570
|
default:
|
|
571
|
-
throw new
|
|
571
|
+
throw new ErrnoError(Errno.EPERM, 'File type not supported', path, 'rm');
|
|
572
572
|
}
|
|
573
573
|
}
|
|
574
574
|
rmSync;
|
|
@@ -591,7 +591,7 @@ export function copyFileSync(src, dest, flags) {
|
|
|
591
591
|
src = normalizePath(src);
|
|
592
592
|
dest = normalizePath(dest);
|
|
593
593
|
if (flags && flags & COPYFILE_EXCL && existsSync(dest)) {
|
|
594
|
-
throw new
|
|
594
|
+
throw new ErrnoError(Errno.EEXIST, 'Destination file already exists.', dest, 'copyFile');
|
|
595
595
|
}
|
|
596
596
|
writeFileSync(dest, readFileSync(src));
|
|
597
597
|
}
|
|
@@ -656,12 +656,12 @@ export function cpSync(source, destination, opts) {
|
|
|
656
656
|
destination = normalizePath(destination);
|
|
657
657
|
const srcStats = lstatSync(source); // Use lstat to follow symlinks if not dereferencing
|
|
658
658
|
if (opts?.errorOnExist && existsSync(destination)) {
|
|
659
|
-
throw new
|
|
659
|
+
throw new ErrnoError(Errno.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
|
|
660
660
|
}
|
|
661
661
|
switch (srcStats.mode & S_IFMT) {
|
|
662
662
|
case S_IFDIR:
|
|
663
663
|
if (!opts?.recursive) {
|
|
664
|
-
throw new
|
|
664
|
+
throw new ErrnoError(Errno.EISDIR, source + ' is a directory (not copied)', source, 'cp');
|
|
665
665
|
}
|
|
666
666
|
mkdirSync(destination, { recursive: true }); // Ensure the destination directory exists
|
|
667
667
|
for (const dirent of readdirSync(source, { withFileTypes: true })) {
|
|
@@ -680,7 +680,7 @@ export function cpSync(source, destination, opts) {
|
|
|
680
680
|
case S_IFIFO:
|
|
681
681
|
case S_IFSOCK:
|
|
682
682
|
default:
|
|
683
|
-
throw new
|
|
683
|
+
throw new ErrnoError(Errno.EPERM, 'File type not supported', source, 'rm');
|
|
684
684
|
}
|
|
685
685
|
// Optionally preserve timestamps
|
|
686
686
|
if (opts?.preserveTimestamps) {
|
|
@@ -689,5 +689,5 @@ export function cpSync(source, destination, opts) {
|
|
|
689
689
|
}
|
|
690
690
|
cpSync;
|
|
691
691
|
export function statfsSync(path, options) {
|
|
692
|
-
throw
|
|
692
|
+
throw ErrnoError.With('ENOSYS', path.toString(), 'statfs');
|
|
693
693
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
/**
|
|
3
|
-
* Standard libc error codes. More will be added to this enum and
|
|
3
|
+
* Standard libc error codes. More will be added to this enum and error strings as they are
|
|
4
4
|
* needed.
|
|
5
5
|
* @url https://en.wikipedia.org/wiki/Errno.h
|
|
6
6
|
*/
|
|
7
|
-
export declare enum
|
|
7
|
+
export declare enum Errno {
|
|
8
8
|
/** Operation not permitted */
|
|
9
9
|
EPERM = 1,
|
|
10
10
|
/** No such file or directory */
|
|
@@ -159,13 +159,13 @@ export declare enum ErrorCode {
|
|
|
159
159
|
* @internal
|
|
160
160
|
*/
|
|
161
161
|
export declare const errorMessages: {
|
|
162
|
-
[K in
|
|
162
|
+
[K in Errno]: string;
|
|
163
163
|
};
|
|
164
|
-
interface
|
|
165
|
-
errno:
|
|
164
|
+
export interface ErrnoErrorJSON {
|
|
165
|
+
errno: Errno;
|
|
166
166
|
message: string;
|
|
167
167
|
path?: string;
|
|
168
|
-
code: keyof typeof
|
|
168
|
+
code: keyof typeof Errno;
|
|
169
169
|
stack: string;
|
|
170
170
|
syscall: string;
|
|
171
171
|
}
|
|
@@ -173,13 +173,13 @@ interface ApiErrorJSON {
|
|
|
173
173
|
* Represents a ZenFS error. Passed back to applications after a failed
|
|
174
174
|
* call to the ZenFS API.
|
|
175
175
|
*/
|
|
176
|
-
export declare class
|
|
177
|
-
errno:
|
|
176
|
+
export declare class ErrnoError extends Error implements NodeJS.ErrnoException {
|
|
177
|
+
errno: Errno;
|
|
178
178
|
path?: string | undefined;
|
|
179
179
|
syscall: string;
|
|
180
|
-
static fromJSON(json:
|
|
181
|
-
static With(code: keyof typeof
|
|
182
|
-
code: keyof typeof
|
|
180
|
+
static fromJSON(json: ErrnoErrorJSON): ErrnoError;
|
|
181
|
+
static With(code: keyof typeof Errno, path?: string, syscall?: string): ErrnoError;
|
|
182
|
+
code: keyof typeof Errno;
|
|
183
183
|
stack: string;
|
|
184
184
|
/**
|
|
185
185
|
* Represents a ZenFS error. Passed back to applications after a failed
|
|
@@ -191,15 +191,14 @@ export declare class ApiError extends Error implements NodeJS.ErrnoException {
|
|
|
191
191
|
* @param type The type of the error.
|
|
192
192
|
* @param message A descriptive error message.
|
|
193
193
|
*/
|
|
194
|
-
constructor(errno:
|
|
194
|
+
constructor(errno: Errno, message?: string, path?: string | undefined, syscall?: string);
|
|
195
195
|
/**
|
|
196
196
|
* @return A friendly error message.
|
|
197
197
|
*/
|
|
198
198
|
toString(): string;
|
|
199
|
-
toJSON():
|
|
199
|
+
toJSON(): ErrnoErrorJSON;
|
|
200
200
|
/**
|
|
201
201
|
* The size of the API error in buffer-form in bytes.
|
|
202
202
|
*/
|
|
203
203
|
bufferSize(): number;
|
|
204
204
|
}
|
|
205
|
-
export {};
|
package/dist/error.js
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard libc error codes. More will be added to this enum and error strings as they are
|
|
3
|
+
* needed.
|
|
4
|
+
* @url https://en.wikipedia.org/wiki/Errno.h
|
|
5
|
+
*/
|
|
6
|
+
export var Errno;
|
|
7
|
+
(function (Errno) {
|
|
8
|
+
/** Operation not permitted */
|
|
9
|
+
Errno[Errno["EPERM"] = 1] = "EPERM";
|
|
10
|
+
/** No such file or directory */
|
|
11
|
+
Errno[Errno["ENOENT"] = 2] = "ENOENT";
|
|
12
|
+
/** Interrupted system call */
|
|
13
|
+
Errno[Errno["EINTR"] = 4] = "EINTR";
|
|
14
|
+
/** Input/output error */
|
|
15
|
+
Errno[Errno["EIO"] = 5] = "EIO";
|
|
16
|
+
/** No such device or address */
|
|
17
|
+
Errno[Errno["ENXIO"] = 6] = "ENXIO";
|
|
18
|
+
/** Bad file descriptor */
|
|
19
|
+
Errno[Errno["EBADF"] = 9] = "EBADF";
|
|
20
|
+
/** Resource temporarily unavailable */
|
|
21
|
+
Errno[Errno["EAGAIN"] = 11] = "EAGAIN";
|
|
22
|
+
/** Cannot allocate memory */
|
|
23
|
+
Errno[Errno["ENOMEM"] = 12] = "ENOMEM";
|
|
24
|
+
/** Permission denied */
|
|
25
|
+
Errno[Errno["EACCES"] = 13] = "EACCES";
|
|
26
|
+
/** Bad address */
|
|
27
|
+
Errno[Errno["EFAULT"] = 14] = "EFAULT";
|
|
28
|
+
/** Block device required */
|
|
29
|
+
Errno[Errno["ENOTBLK"] = 15] = "ENOTBLK";
|
|
30
|
+
/** Resource busy or locked */
|
|
31
|
+
Errno[Errno["EBUSY"] = 16] = "EBUSY";
|
|
32
|
+
/** File exists */
|
|
33
|
+
Errno[Errno["EEXIST"] = 17] = "EEXIST";
|
|
34
|
+
/** Invalid cross-device link */
|
|
35
|
+
Errno[Errno["EXDEV"] = 18] = "EXDEV";
|
|
36
|
+
/** No such device */
|
|
37
|
+
Errno[Errno["ENODEV"] = 19] = "ENODEV";
|
|
38
|
+
/** File is not a directory */
|
|
39
|
+
Errno[Errno["ENOTDIR"] = 20] = "ENOTDIR";
|
|
40
|
+
/** File is a directory */
|
|
41
|
+
Errno[Errno["EISDIR"] = 21] = "EISDIR";
|
|
42
|
+
/** Invalid argument */
|
|
43
|
+
Errno[Errno["EINVAL"] = 22] = "EINVAL";
|
|
44
|
+
/** Too many open files in system */
|
|
45
|
+
Errno[Errno["ENFILE"] = 23] = "ENFILE";
|
|
46
|
+
/** Too many open files */
|
|
47
|
+
Errno[Errno["EMFILE"] = 24] = "EMFILE";
|
|
48
|
+
/** Text file busy */
|
|
49
|
+
Errno[Errno["ETXTBSY"] = 26] = "ETXTBSY";
|
|
50
|
+
/** File is too big */
|
|
51
|
+
Errno[Errno["EFBIG"] = 27] = "EFBIG";
|
|
52
|
+
/** No space left on disk */
|
|
53
|
+
Errno[Errno["ENOSPC"] = 28] = "ENOSPC";
|
|
54
|
+
/** Illegal seek */
|
|
55
|
+
Errno[Errno["ESPIPE"] = 29] = "ESPIPE";
|
|
56
|
+
/** Cannot modify a read-only file system */
|
|
57
|
+
Errno[Errno["EROFS"] = 30] = "EROFS";
|
|
58
|
+
/** Too many links */
|
|
59
|
+
Errno[Errno["EMLINK"] = 31] = "EMLINK";
|
|
60
|
+
/** Broken pipe */
|
|
61
|
+
Errno[Errno["EPIPE"] = 32] = "EPIPE";
|
|
62
|
+
/** Numerical argument out of domain */
|
|
63
|
+
Errno[Errno["EDOM"] = 33] = "EDOM";
|
|
64
|
+
/** Numerical result out of range */
|
|
65
|
+
Errno[Errno["ERANGE"] = 34] = "ERANGE";
|
|
66
|
+
/** Resource deadlock would occur */
|
|
67
|
+
Errno[Errno["EDEADLK"] = 35] = "EDEADLK";
|
|
68
|
+
/** File name too long */
|
|
69
|
+
Errno[Errno["ENAMETOOLONG"] = 36] = "ENAMETOOLONG";
|
|
70
|
+
/** No locks available */
|
|
71
|
+
Errno[Errno["ENOLCK"] = 37] = "ENOLCK";
|
|
72
|
+
/** Function not implemented */
|
|
73
|
+
Errno[Errno["ENOSYS"] = 38] = "ENOSYS";
|
|
74
|
+
/** Directory is not empty */
|
|
75
|
+
Errno[Errno["ENOTEMPTY"] = 39] = "ENOTEMPTY";
|
|
76
|
+
/** Too many levels of symbolic links */
|
|
77
|
+
Errno[Errno["ELOOP"] = 40] = "ELOOP";
|
|
78
|
+
/** No message of desired type */
|
|
79
|
+
Errno[Errno["ENOMSG"] = 42] = "ENOMSG";
|
|
80
|
+
/** Invalid exchange */
|
|
81
|
+
Errno[Errno["EBADE"] = 52] = "EBADE";
|
|
82
|
+
/** Invalid request descriptor */
|
|
83
|
+
Errno[Errno["EBADR"] = 53] = "EBADR";
|
|
84
|
+
/** Exchange full */
|
|
85
|
+
Errno[Errno["EXFULL"] = 54] = "EXFULL";
|
|
86
|
+
/** No anode */
|
|
87
|
+
Errno[Errno["ENOANO"] = 55] = "ENOANO";
|
|
88
|
+
/** Invalid request code */
|
|
89
|
+
Errno[Errno["EBADRQC"] = 56] = "EBADRQC";
|
|
90
|
+
/** Device not a stream */
|
|
91
|
+
Errno[Errno["ENOSTR"] = 60] = "ENOSTR";
|
|
92
|
+
/** No data available */
|
|
93
|
+
Errno[Errno["ENODATA"] = 61] = "ENODATA";
|
|
94
|
+
/** Timer expired */
|
|
95
|
+
Errno[Errno["ETIME"] = 62] = "ETIME";
|
|
96
|
+
/** Out of streams resources */
|
|
97
|
+
Errno[Errno["ENOSR"] = 63] = "ENOSR";
|
|
98
|
+
/** Machine is not on the network */
|
|
99
|
+
Errno[Errno["ENONET"] = 64] = "ENONET";
|
|
100
|
+
/** Object is remote */
|
|
101
|
+
Errno[Errno["EREMOTE"] = 66] = "EREMOTE";
|
|
102
|
+
/** Link has been severed */
|
|
103
|
+
Errno[Errno["ENOLINK"] = 67] = "ENOLINK";
|
|
104
|
+
/** Communication error on send */
|
|
105
|
+
Errno[Errno["ECOMM"] = 70] = "ECOMM";
|
|
106
|
+
/** Protocol error */
|
|
107
|
+
Errno[Errno["EPROTO"] = 71] = "EPROTO";
|
|
108
|
+
/** Bad message */
|
|
109
|
+
Errno[Errno["EBADMSG"] = 74] = "EBADMSG";
|
|
110
|
+
/** Value too large for defined data type */
|
|
111
|
+
Errno[Errno["EOVERFLOW"] = 75] = "EOVERFLOW";
|
|
112
|
+
/** File descriptor in bad state */
|
|
113
|
+
Errno[Errno["EBADFD"] = 77] = "EBADFD";
|
|
114
|
+
/** Streams pipe error */
|
|
115
|
+
Errno[Errno["ESTRPIPE"] = 86] = "ESTRPIPE";
|
|
116
|
+
/** Socket operation on non-socket */
|
|
117
|
+
Errno[Errno["ENOTSOCK"] = 88] = "ENOTSOCK";
|
|
118
|
+
/** Destination address required */
|
|
119
|
+
Errno[Errno["EDESTADDRREQ"] = 89] = "EDESTADDRREQ";
|
|
120
|
+
/** Message too long */
|
|
121
|
+
Errno[Errno["EMSGSIZE"] = 90] = "EMSGSIZE";
|
|
122
|
+
/** Protocol wrong type for socket */
|
|
123
|
+
Errno[Errno["EPROTOTYPE"] = 91] = "EPROTOTYPE";
|
|
124
|
+
/** Protocol not available */
|
|
125
|
+
Errno[Errno["ENOPROTOOPT"] = 92] = "ENOPROTOOPT";
|
|
126
|
+
/** Protocol not supported */
|
|
127
|
+
Errno[Errno["EPROTONOSUPPORT"] = 93] = "EPROTONOSUPPORT";
|
|
128
|
+
/** Socket type not supported */
|
|
129
|
+
Errno[Errno["ESOCKTNOSUPPORT"] = 94] = "ESOCKTNOSUPPORT";
|
|
130
|
+
/** Operation is not supported */
|
|
131
|
+
Errno[Errno["ENOTSUP"] = 95] = "ENOTSUP";
|
|
132
|
+
/** Network is down */
|
|
133
|
+
Errno[Errno["ENETDOWN"] = 100] = "ENETDOWN";
|
|
134
|
+
/** Network is unreachable */
|
|
135
|
+
Errno[Errno["ENETUNREACH"] = 101] = "ENETUNREACH";
|
|
136
|
+
/** Network dropped connection on reset */
|
|
137
|
+
Errno[Errno["ENETRESET"] = 102] = "ENETRESET";
|
|
138
|
+
/** Connection timed out */
|
|
139
|
+
Errno[Errno["ETIMEDOUT"] = 110] = "ETIMEDOUT";
|
|
140
|
+
/** Connection refused */
|
|
141
|
+
Errno[Errno["ECONNREFUSED"] = 111] = "ECONNREFUSED";
|
|
142
|
+
/** Host is down */
|
|
143
|
+
Errno[Errno["EHOSTDOWN"] = 112] = "EHOSTDOWN";
|
|
144
|
+
/** No route to host */
|
|
145
|
+
Errno[Errno["EHOSTUNREACH"] = 113] = "EHOSTUNREACH";
|
|
146
|
+
/** Operation already in progress */
|
|
147
|
+
Errno[Errno["EALREADY"] = 114] = "EALREADY";
|
|
148
|
+
/** Operation now in progress */
|
|
149
|
+
Errno[Errno["EINPROGRESS"] = 115] = "EINPROGRESS";
|
|
150
|
+
/** Stale file handle */
|
|
151
|
+
Errno[Errno["ESTALE"] = 116] = "ESTALE";
|
|
152
|
+
/** Remote I/O error */
|
|
153
|
+
Errno[Errno["EREMOTEIO"] = 121] = "EREMOTEIO";
|
|
154
|
+
/** Disk quota exceeded */
|
|
155
|
+
Errno[Errno["EDQUOT"] = 122] = "EDQUOT";
|
|
156
|
+
})(Errno || (Errno = {}));
|
|
157
|
+
/**
|
|
158
|
+
* Strings associated with each error code.
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
export const errorMessages = {
|
|
162
|
+
[Errno.EPERM]: 'Operation not permitted',
|
|
163
|
+
[Errno.ENOENT]: 'No such file or directory',
|
|
164
|
+
[Errno.EINTR]: 'Interrupted system call',
|
|
165
|
+
[Errno.EIO]: 'Input/output error',
|
|
166
|
+
[Errno.ENXIO]: 'No such device or address',
|
|
167
|
+
[Errno.EBADF]: 'Bad file descriptor',
|
|
168
|
+
[Errno.EAGAIN]: 'Resource temporarily unavailable',
|
|
169
|
+
[Errno.ENOMEM]: 'Cannot allocate memory',
|
|
170
|
+
[Errno.EACCES]: 'Permission denied',
|
|
171
|
+
[Errno.EFAULT]: 'Bad address',
|
|
172
|
+
[Errno.ENOTBLK]: 'Block device required',
|
|
173
|
+
[Errno.EBUSY]: 'Resource busy or locked',
|
|
174
|
+
[Errno.EEXIST]: 'File exists',
|
|
175
|
+
[Errno.EXDEV]: 'Invalid cross-device link',
|
|
176
|
+
[Errno.ENODEV]: 'No such device',
|
|
177
|
+
[Errno.ENOTDIR]: 'File is not a directory',
|
|
178
|
+
[Errno.EISDIR]: 'File is a directory',
|
|
179
|
+
[Errno.EINVAL]: 'Invalid argument',
|
|
180
|
+
[Errno.ENFILE]: 'Too many open files in system',
|
|
181
|
+
[Errno.EMFILE]: 'Too many open files',
|
|
182
|
+
[Errno.ETXTBSY]: 'Text file busy',
|
|
183
|
+
[Errno.EFBIG]: 'File is too big',
|
|
184
|
+
[Errno.ENOSPC]: 'No space left on disk',
|
|
185
|
+
[Errno.ESPIPE]: 'Illegal seek',
|
|
186
|
+
[Errno.EROFS]: 'Cannot modify a read-only file system',
|
|
187
|
+
[Errno.EMLINK]: 'Too many links',
|
|
188
|
+
[Errno.EPIPE]: 'Broken pipe',
|
|
189
|
+
[Errno.EDOM]: 'Numerical argument out of domain',
|
|
190
|
+
[Errno.ERANGE]: 'Numerical result out of range',
|
|
191
|
+
[Errno.EDEADLK]: 'Resource deadlock would occur',
|
|
192
|
+
[Errno.ENAMETOOLONG]: 'File name too long',
|
|
193
|
+
[Errno.ENOLCK]: 'No locks available',
|
|
194
|
+
[Errno.ENOSYS]: 'Function not implemented',
|
|
195
|
+
[Errno.ENOTEMPTY]: 'Directory is not empty',
|
|
196
|
+
[Errno.ELOOP]: 'Too many levels of symbolic links',
|
|
197
|
+
[Errno.ENOMSG]: 'No message of desired type',
|
|
198
|
+
[Errno.EBADE]: 'Invalid exchange',
|
|
199
|
+
[Errno.EBADR]: 'Invalid request descriptor',
|
|
200
|
+
[Errno.EXFULL]: 'Exchange full',
|
|
201
|
+
[Errno.ENOANO]: 'No anode',
|
|
202
|
+
[Errno.EBADRQC]: 'Invalid request code',
|
|
203
|
+
[Errno.ENOSTR]: 'Device not a stream',
|
|
204
|
+
[Errno.ENODATA]: 'No data available',
|
|
205
|
+
[Errno.ETIME]: 'Timer expired',
|
|
206
|
+
[Errno.ENOSR]: 'Out of streams resources',
|
|
207
|
+
[Errno.ENONET]: 'Machine is not on the network',
|
|
208
|
+
[Errno.EREMOTE]: 'Object is remote',
|
|
209
|
+
[Errno.ENOLINK]: 'Link has been severed',
|
|
210
|
+
[Errno.ECOMM]: 'Communication error on send',
|
|
211
|
+
[Errno.EPROTO]: 'Protocol error',
|
|
212
|
+
[Errno.EBADMSG]: 'Bad message',
|
|
213
|
+
[Errno.EOVERFLOW]: 'Value too large for defined data type',
|
|
214
|
+
[Errno.EBADFD]: 'File descriptor in bad state',
|
|
215
|
+
[Errno.ESTRPIPE]: 'Streams pipe error',
|
|
216
|
+
[Errno.ENOTSOCK]: 'Socket operation on non-socket',
|
|
217
|
+
[Errno.EDESTADDRREQ]: 'Destination address required',
|
|
218
|
+
[Errno.EMSGSIZE]: 'Message too long',
|
|
219
|
+
[Errno.EPROTOTYPE]: 'Protocol wrong type for socket',
|
|
220
|
+
[Errno.ENOPROTOOPT]: 'Protocol not available',
|
|
221
|
+
[Errno.EPROTONOSUPPORT]: 'Protocol not supported',
|
|
222
|
+
[Errno.ESOCKTNOSUPPORT]: 'Socket type not supported',
|
|
223
|
+
[Errno.ENOTSUP]: 'Operation is not supported',
|
|
224
|
+
[Errno.ENETDOWN]: 'Network is down',
|
|
225
|
+
[Errno.ENETUNREACH]: 'Network is unreachable',
|
|
226
|
+
[Errno.ENETRESET]: 'Network dropped connection on reset',
|
|
227
|
+
[Errno.ETIMEDOUT]: 'Connection timed out',
|
|
228
|
+
[Errno.ECONNREFUSED]: 'Connection refused',
|
|
229
|
+
[Errno.EHOSTDOWN]: 'Host is down',
|
|
230
|
+
[Errno.EHOSTUNREACH]: 'No route to host',
|
|
231
|
+
[Errno.EALREADY]: 'Operation already in progress',
|
|
232
|
+
[Errno.EINPROGRESS]: 'Operation now in progress',
|
|
233
|
+
[Errno.ESTALE]: 'Stale file handle',
|
|
234
|
+
[Errno.EREMOTEIO]: 'Remote I/O error',
|
|
235
|
+
[Errno.EDQUOT]: 'Disk quota exceeded',
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* Represents a ZenFS error. Passed back to applications after a failed
|
|
239
|
+
* call to the ZenFS API.
|
|
240
|
+
*/
|
|
241
|
+
export class ErrnoError extends Error {
|
|
242
|
+
static fromJSON(json) {
|
|
243
|
+
const err = new ErrnoError(json.errno, json.message, json.path, json.syscall);
|
|
244
|
+
err.code = json.code;
|
|
245
|
+
err.stack = json.stack;
|
|
246
|
+
return err;
|
|
247
|
+
}
|
|
248
|
+
static With(code, path, syscall) {
|
|
249
|
+
return new ErrnoError(Errno[code], errorMessages[Errno[code]], path, syscall);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Represents a ZenFS error. Passed back to applications after a failed
|
|
253
|
+
* call to the ZenFS API.
|
|
254
|
+
*
|
|
255
|
+
* Error codes mirror those returned by regular Unix file operations, which is
|
|
256
|
+
* what Node returns.
|
|
257
|
+
* @constructor ApiError
|
|
258
|
+
* @param type The type of the error.
|
|
259
|
+
* @param message A descriptive error message.
|
|
260
|
+
*/
|
|
261
|
+
constructor(errno, message = errorMessages[errno], path, syscall = '') {
|
|
262
|
+
super(message);
|
|
263
|
+
this.errno = errno;
|
|
264
|
+
this.path = path;
|
|
265
|
+
this.syscall = syscall;
|
|
266
|
+
this.code = Errno[errno];
|
|
267
|
+
this.message = `${this.code}: ${message}${this.path ? `, '${this.path}'` : ''}`;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* @return A friendly error message.
|
|
271
|
+
*/
|
|
272
|
+
toString() {
|
|
273
|
+
return this.message;
|
|
274
|
+
}
|
|
275
|
+
toJSON() {
|
|
276
|
+
return {
|
|
277
|
+
errno: this.errno,
|
|
278
|
+
code: this.code,
|
|
279
|
+
path: this.path,
|
|
280
|
+
stack: this.stack,
|
|
281
|
+
message: this.message,
|
|
282
|
+
syscall: this.syscall,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The size of the API error in buffer-form in bytes.
|
|
287
|
+
*/
|
|
288
|
+
bufferSize() {
|
|
289
|
+
// 4 bytes for string length.
|
|
290
|
+
return 4 + JSON.stringify(this.toJSON()).length;
|
|
291
|
+
}
|
|
292
|
+
}
|
package/dist/file.d.ts
CHANGED
package/dist/file.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ErrnoError, Errno } from './error.js';
|
|
2
2
|
import { O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_SYNC, O_TRUNC, O_WRONLY, S_IFMT } from './emulation/constants.js';
|
|
3
3
|
import { size_max } from './inode.js';
|
|
4
4
|
import { Stats } from './stats.js';
|
|
@@ -133,6 +133,12 @@ export function pathNotExistsAction(flag) {
|
|
|
133
133
|
return ActionType.THROW;
|
|
134
134
|
}
|
|
135
135
|
export class File {
|
|
136
|
+
[Symbol.asyncDispose]() {
|
|
137
|
+
return this.close();
|
|
138
|
+
}
|
|
139
|
+
[Symbol.dispose]() {
|
|
140
|
+
return this.closeSync();
|
|
141
|
+
}
|
|
136
142
|
/**
|
|
137
143
|
* Asynchronous `datasync`.
|
|
138
144
|
*
|
|
@@ -276,7 +282,7 @@ export class PreloadFile extends File {
|
|
|
276
282
|
truncateSync(len) {
|
|
277
283
|
this._dirty = true;
|
|
278
284
|
if (!isWriteable(this.flag)) {
|
|
279
|
-
throw new
|
|
285
|
+
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
|
|
280
286
|
}
|
|
281
287
|
this.stats.mtimeMs = Date.now();
|
|
282
288
|
if (len > this._buffer.length) {
|
|
@@ -329,7 +335,7 @@ export class PreloadFile extends File {
|
|
|
329
335
|
this._dirty = true;
|
|
330
336
|
position ?? (position = this.position);
|
|
331
337
|
if (!isWriteable(this.flag)) {
|
|
332
|
-
throw new
|
|
338
|
+
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode.');
|
|
333
339
|
}
|
|
334
340
|
const endFp = position + length;
|
|
335
341
|
if (endFp > this.stats.size) {
|
|
@@ -384,7 +390,7 @@ export class PreloadFile extends File {
|
|
|
384
390
|
*/
|
|
385
391
|
readSync(buffer, offset = 0, length = this.stats.size, position) {
|
|
386
392
|
if (!isReadable(this.flag)) {
|
|
387
|
-
throw new
|
|
393
|
+
throw new ErrnoError(Errno.EPERM, 'File not opened with a readable mode.');
|
|
388
394
|
}
|
|
389
395
|
position ?? (position = this.position);
|
|
390
396
|
let end = position + length;
|