@zenfs/core 2.0.0 → 2.1.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/backend.js +6 -5
- package/dist/backends/cow.d.ts +2 -2
- package/dist/backends/cow.js +39 -58
- package/dist/backends/fetch.js +27 -29
- package/dist/backends/passthrough.d.ts +2 -3
- package/dist/backends/passthrough.js +84 -199
- package/dist/backends/port.d.ts +16 -3
- package/dist/backends/port.js +61 -30
- package/dist/backends/single_buffer.d.ts +52 -46
- package/dist/backends/single_buffer.js +462 -219
- package/dist/backends/store/fs.d.ts +16 -10
- package/dist/backends/store/fs.js +227 -242
- package/dist/backends/store/store.d.ts +3 -3
- package/dist/backends/store/store.js +11 -10
- package/dist/config.d.ts +2 -2
- package/dist/config.js +10 -11
- package/dist/internal/devices.d.ts +2 -2
- package/dist/internal/devices.js +39 -49
- package/dist/internal/error.d.ts +9 -204
- package/dist/internal/error.js +19 -288
- package/dist/internal/file_index.d.ts +1 -1
- package/dist/internal/file_index.js +9 -9
- package/dist/internal/filesystem.d.ts +23 -8
- package/dist/internal/index.d.ts +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index_fs.d.ts +2 -2
- package/dist/internal/index_fs.js +19 -19
- package/dist/internal/inode.d.ts +81 -103
- package/dist/internal/inode.js +336 -195
- package/dist/mixins/async.js +32 -28
- package/dist/mixins/mutexed.d.ts +4 -4
- package/dist/mixins/mutexed.js +39 -39
- package/dist/mixins/readonly.d.ts +2 -2
- package/dist/mixins/readonly.js +20 -20
- package/dist/mixins/sync.js +2 -2
- package/dist/polyfills.js +1 -1
- package/dist/readline.js +1 -1
- package/dist/utils.d.ts +8 -5
- package/dist/utils.js +14 -17
- package/dist/vfs/acl.d.ts +8 -8
- package/dist/vfs/acl.js +66 -47
- package/dist/vfs/async.d.ts +2 -2
- package/dist/vfs/async.js +6 -8
- package/dist/vfs/dir.d.ts +1 -1
- package/dist/vfs/dir.js +3 -4
- package/dist/vfs/file.js +33 -24
- package/dist/vfs/flags.js +3 -3
- package/dist/vfs/ioctl.d.ts +8 -7
- package/dist/vfs/ioctl.js +132 -27
- package/dist/vfs/promises.d.ts +3 -3
- package/dist/vfs/promises.js +200 -235
- package/dist/vfs/shared.d.ts +1 -12
- package/dist/vfs/shared.js +7 -35
- package/dist/vfs/streams.js +9 -9
- package/dist/vfs/sync.d.ts +1 -2
- package/dist/vfs/sync.js +158 -170
- package/dist/vfs/watchers.js +8 -8
- package/dist/vfs/xattr.js +89 -106
- package/package.json +4 -2
- package/scripts/test.js +2 -2
- package/tests/assignment.ts +1 -1
- package/tests/backend/port.test.ts +4 -4
- package/tests/backend/single-buffer.test.ts +39 -10
- package/tests/backend/single-buffer.worker.js +30 -0
- package/tests/common/context.test.ts +2 -2
- package/tests/common/mutex.test.ts +9 -9
- package/tests/fetch/fetch.ts +1 -1
- package/tests/fs/append.test.ts +4 -4
- package/tests/fs/directory.test.ts +25 -25
- package/tests/fs/errors.test.ts +15 -19
- package/tests/fs/links.test.ts +3 -2
- package/tests/fs/open.test.ts +4 -21
- package/tests/fs/permissions.test.ts +8 -13
- package/tests/fs/read.test.ts +10 -9
- package/tests/fs/readFile.test.ts +8 -24
- package/tests/fs/rename.test.ts +4 -9
- package/tests/fs/stat.test.ts +2 -2
- package/tests/fs/times.test.ts +6 -6
- package/tests/fs/truncate.test.ts +8 -36
- package/tests/fs/watch.test.ts +10 -10
- package/tests/fs/write.test.ts +77 -13
- package/tests/fs/xattr.test.ts +7 -7
- package/tests/logs.js +2 -2
- package/tests/setup/port.ts +6 -0
- package/dist/internal/log.d.ts +0 -139
- package/dist/internal/log.js +0 -219
- package/tests/fs/writeFile.test.ts +0 -70
package/dist/utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { withErrno } from 'kerium';
|
|
1
2
|
import { decodeUTF8, encodeUTF8 } from 'utilium';
|
|
2
|
-
import { Errno, ErrnoError } from './internal/error.js';
|
|
3
3
|
import { resolve } from './path.js';
|
|
4
4
|
/**
|
|
5
5
|
* Decodes a directory listing
|
|
@@ -31,7 +31,7 @@ export function normalizeMode(mode, def) {
|
|
|
31
31
|
}
|
|
32
32
|
if (typeof def == 'number')
|
|
33
33
|
return def;
|
|
34
|
-
throw
|
|
34
|
+
throw withErrno('EINVAL', 'Invalid mode: ' + (mode === null || mode === void 0 ? void 0 : mode.toString()));
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Normalizes a time
|
|
@@ -44,9 +44,15 @@ export function normalizeTime(time) {
|
|
|
44
44
|
return Number(time);
|
|
45
45
|
}
|
|
46
46
|
catch {
|
|
47
|
-
throw
|
|
47
|
+
throw withErrno('EINVAL', 'Invalid time.');
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* TypeScript is dumb, so we need to assert the type of a value sometimes.
|
|
52
|
+
* For example, after calling `normalizePath`, TS still thinks the type is `PathLike` and not `string`.
|
|
53
|
+
* @internal @hidden
|
|
54
|
+
*/
|
|
55
|
+
export function __assertType(value) { }
|
|
50
56
|
/**
|
|
51
57
|
* Normalizes a path
|
|
52
58
|
* @internal
|
|
@@ -54,18 +60,16 @@ export function normalizeTime(time) {
|
|
|
54
60
|
export function normalizePath(p, noResolve = false) {
|
|
55
61
|
if (p instanceof URL) {
|
|
56
62
|
if (p.protocol != 'file:')
|
|
57
|
-
throw
|
|
63
|
+
throw withErrno('EINVAL', 'URLs must use the file: protocol');
|
|
58
64
|
p = p.pathname;
|
|
59
65
|
}
|
|
60
66
|
p = p.toString();
|
|
61
67
|
if (p.startsWith('file://'))
|
|
62
68
|
p = p.slice('file://'.length);
|
|
63
|
-
if (p.includes('\x00'))
|
|
64
|
-
throw
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
throw new ErrnoError(Errno.EINVAL, 'Path can not be empty');
|
|
68
|
-
}
|
|
69
|
+
if (p.includes('\x00'))
|
|
70
|
+
throw withErrno('EINVAL', 'Path can not contain null character');
|
|
71
|
+
if (p.length == 0)
|
|
72
|
+
throw withErrno('EINVAL', 'Path can not be empty');
|
|
69
73
|
p = p.replaceAll(/[/\\]+/g, '/');
|
|
70
74
|
// Note: PWD is not resolved here, it is resolved later.
|
|
71
75
|
return noResolve ? p : resolve(p);
|
|
@@ -92,10 +96,3 @@ export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
|
|
|
92
96
|
mode: normalizeMode('mode' in options ? options === null || options === void 0 ? void 0 : options.mode : null, mode),
|
|
93
97
|
};
|
|
94
98
|
}
|
|
95
|
-
export function stringifyUUID(uuid) {
|
|
96
|
-
const hex = uuid.toString(16).padStart(32, '0');
|
|
97
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
98
|
-
}
|
|
99
|
-
export function parseUUID(uuid) {
|
|
100
|
-
return BigInt(`0x${uuid.replace(/-/g, '')}`);
|
|
101
|
-
}
|
package/dist/vfs/acl.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BufferView } from 'utilium/buffer.js';
|
|
1
2
|
import { type V_Context } from '../internal/contexts.js';
|
|
2
3
|
import { type InodeLike } from '../internal/inode.js';
|
|
3
4
|
export declare const enum Type {
|
|
@@ -16,16 +17,15 @@ export declare const enum Tag {
|
|
|
16
17
|
*/
|
|
17
18
|
_None = 0
|
|
18
19
|
}
|
|
19
|
-
export declare class Entry {
|
|
20
|
-
tag: Tag;
|
|
21
|
-
perm: number;
|
|
22
|
-
id: number;
|
|
23
|
-
constructor(data?: Partial<Entry> | Uint8Array);
|
|
20
|
+
export declare class Entry extends BufferView {
|
|
21
|
+
accessor tag: Tag;
|
|
22
|
+
accessor perm: number;
|
|
23
|
+
accessor id: number;
|
|
24
24
|
}
|
|
25
|
-
export declare class ACL {
|
|
26
|
-
version: number;
|
|
25
|
+
export declare class ACL extends BufferView {
|
|
26
|
+
accessor version: number;
|
|
27
27
|
entries: Entry[];
|
|
28
|
-
constructor(
|
|
28
|
+
constructor(...args: ConstructorParameters<typeof BufferView>);
|
|
29
29
|
}
|
|
30
30
|
export declare function fromMode(mode: number): ACL;
|
|
31
31
|
export declare function toMode(acl: ACL): number;
|
package/dist/vfs/acl.js
CHANGED
|
@@ -36,18 +36,30 @@ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, p
|
|
|
36
36
|
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
37
37
|
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
38
38
|
};
|
|
39
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
40
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
41
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
42
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
43
|
+
};
|
|
44
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
45
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
46
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
47
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
48
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
49
|
+
};
|
|
39
50
|
/*
|
|
40
51
|
Access Control Lists.
|
|
41
52
|
At the moment, they are only intended for internal use.
|
|
42
53
|
They also are not checked for permissions yet.
|
|
43
54
|
Please use a namespace import for the best experience.
|
|
44
55
|
*/
|
|
45
|
-
import {
|
|
56
|
+
import { withErrno } from 'kerium';
|
|
57
|
+
import { err } from 'kerium/log';
|
|
58
|
+
import { packed, sizeof, struct, types as t } from 'memium';
|
|
59
|
+
import { BufferView } from 'utilium/buffer.js';
|
|
46
60
|
import { defaultContext } from '../internal/contexts.js';
|
|
47
|
-
import { Errno, ErrnoError } from '../internal/error.js';
|
|
48
61
|
import { Attributes } from '../internal/inode.js';
|
|
49
|
-
import {
|
|
50
|
-
import { S_IRWXG, S_IRWXO, S_IRWXU, W_OK, X_OK, R_OK } from './constants.js';
|
|
62
|
+
import { R_OK, S_IRWXG, S_IRWXO, S_IRWXU, W_OK, X_OK } from './constants.js';
|
|
51
63
|
import * as xattr from './xattr.js';
|
|
52
64
|
const version = 2;
|
|
53
65
|
export var Type;
|
|
@@ -69,11 +81,13 @@ export var Tag;
|
|
|
69
81
|
Tag[Tag["_None"] = 0] = "_None";
|
|
70
82
|
})(Tag || (Tag = {}));
|
|
71
83
|
let Entry = (() => {
|
|
84
|
+
var _Entry_tag_accessor_storage, _Entry_perm_accessor_storage, _Entry_id_accessor_storage;
|
|
72
85
|
var _a, _b, _c;
|
|
73
|
-
let _classDecorators = [struct()];
|
|
86
|
+
let _classDecorators = [struct(packed)];
|
|
74
87
|
let _classDescriptor;
|
|
75
88
|
let _classExtraInitializers = [];
|
|
76
89
|
let _classThis;
|
|
90
|
+
let _classSuper = BufferView;
|
|
77
91
|
let _tag_decorators;
|
|
78
92
|
let _tag_initializers = [];
|
|
79
93
|
let _tag_extraInitializers = [];
|
|
@@ -83,27 +97,34 @@ let Entry = (() => {
|
|
|
83
97
|
let _id_decorators;
|
|
84
98
|
let _id_initializers = [];
|
|
85
99
|
let _id_extraInitializers = [];
|
|
86
|
-
var Entry = _classThis = class {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
100
|
+
var Entry = _classThis = class extends _classSuper {
|
|
101
|
+
get tag() { return __classPrivateFieldGet(this, _Entry_tag_accessor_storage, "f"); }
|
|
102
|
+
set tag(value) { __classPrivateFieldSet(this, _Entry_tag_accessor_storage, value, "f"); }
|
|
103
|
+
get perm() { return __classPrivateFieldGet(this, _Entry_perm_accessor_storage, "f"); }
|
|
104
|
+
set perm(value) { __classPrivateFieldSet(this, _Entry_perm_accessor_storage, value, "f"); }
|
|
105
|
+
get id() { return __classPrivateFieldGet(this, _Entry_id_accessor_storage, "f"); }
|
|
106
|
+
set id(value) { __classPrivateFieldSet(this, _Entry_id_accessor_storage, value, "f"); }
|
|
107
|
+
constructor() {
|
|
108
|
+
super(...arguments);
|
|
109
|
+
_Entry_tag_accessor_storage.set(this, __runInitializers(this, _tag_initializers, void 0));
|
|
110
|
+
_Entry_perm_accessor_storage.set(this, (__runInitializers(this, _tag_extraInitializers), __runInitializers(this, _perm_initializers, void 0)));
|
|
111
|
+
_Entry_id_accessor_storage.set(this, (__runInitializers(this, _perm_extraInitializers), __runInitializers(this, _id_initializers, void 0)));
|
|
91
112
|
__runInitializers(this, _id_extraInitializers);
|
|
92
|
-
if (data instanceof Uint8Array)
|
|
93
|
-
deserialize(this, data);
|
|
94
|
-
else if (typeof data == 'object')
|
|
95
|
-
assignWithDefaults(this, data);
|
|
96
113
|
}
|
|
97
114
|
};
|
|
115
|
+
_Entry_tag_accessor_storage = new WeakMap();
|
|
116
|
+
_Entry_perm_accessor_storage = new WeakMap();
|
|
117
|
+
_Entry_id_accessor_storage = new WeakMap();
|
|
98
118
|
__setFunctionName(_classThis, "Entry");
|
|
99
119
|
(() => {
|
|
100
|
-
|
|
120
|
+
var _a;
|
|
121
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
|
|
101
122
|
_tag_decorators = [(_a = t).uint16.bind(_a)];
|
|
102
123
|
_perm_decorators = [(_b = t).uint16.bind(_b)];
|
|
103
124
|
_id_decorators = [(_c = t).uint32.bind(_c)];
|
|
104
|
-
__esDecorate(
|
|
105
|
-
__esDecorate(
|
|
106
|
-
__esDecorate(
|
|
125
|
+
__esDecorate(_classThis, null, _tag_decorators, { kind: "accessor", name: "tag", static: false, private: false, access: { has: obj => "tag" in obj, get: obj => obj.tag, set: (obj, value) => { obj.tag = value; } }, metadata: _metadata }, _tag_initializers, _tag_extraInitializers);
|
|
126
|
+
__esDecorate(_classThis, null, _perm_decorators, { kind: "accessor", name: "perm", static: false, private: false, access: { has: obj => "perm" in obj, get: obj => obj.perm, set: (obj, value) => { obj.perm = value; } }, metadata: _metadata }, _perm_initializers, _perm_extraInitializers);
|
|
127
|
+
__esDecorate(_classThis, null, _id_decorators, { kind: "accessor", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
|
|
107
128
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
108
129
|
Entry = _classThis = _classDescriptor.value;
|
|
109
130
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -113,40 +134,40 @@ let Entry = (() => {
|
|
|
113
134
|
})();
|
|
114
135
|
export { Entry };
|
|
115
136
|
let ACL = (() => {
|
|
137
|
+
var _ACL_version_accessor_storage;
|
|
116
138
|
var _a;
|
|
117
|
-
let _classDecorators = [struct()];
|
|
139
|
+
let _classDecorators = [struct(packed)];
|
|
118
140
|
let _classDescriptor;
|
|
119
141
|
let _classExtraInitializers = [];
|
|
120
142
|
let _classThis;
|
|
143
|
+
let _classSuper = BufferView;
|
|
121
144
|
let _version_decorators;
|
|
122
145
|
let _version_initializers = [];
|
|
123
146
|
let _version_extraInitializers = [];
|
|
124
|
-
var ACL = _classThis = class {
|
|
125
|
-
|
|
126
|
-
|
|
147
|
+
var ACL = _classThis = class extends _classSuper {
|
|
148
|
+
get version() { return __classPrivateFieldGet(this, _ACL_version_accessor_storage, "f"); }
|
|
149
|
+
set version(value) { __classPrivateFieldSet(this, _ACL_version_accessor_storage, value, "f"); }
|
|
150
|
+
constructor(...args) {
|
|
151
|
+
super(...args);
|
|
152
|
+
_ACL_version_accessor_storage.set(this, __runInitializers(this, _version_initializers, void 0));
|
|
127
153
|
this.entries = (__runInitializers(this, _version_extraInitializers), []);
|
|
128
|
-
|
|
129
|
-
return;
|
|
130
|
-
if (!(data instanceof Uint8Array)) {
|
|
131
|
-
this.entries.push(...data);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
deserialize(this, data);
|
|
154
|
+
this.version || (this.version = version);
|
|
135
155
|
if (this.version != version)
|
|
136
|
-
throw err(
|
|
137
|
-
for (let offset = sizeof(ACL); offset <
|
|
138
|
-
if (offset + sizeof(Entry) >
|
|
139
|
-
throw err(
|
|
140
|
-
|
|
141
|
-
this.entries.push(new Entry(slice));
|
|
156
|
+
throw err(withErrno('EINVAL', 'Invalid ACL version'));
|
|
157
|
+
for (let offset = sizeof(ACL); offset < this.byteLength; offset += sizeof(Entry)) {
|
|
158
|
+
if (offset + sizeof(Entry) > this.byteLength)
|
|
159
|
+
throw err(withErrno('EIO', 'Invalid ACL data'));
|
|
160
|
+
this.entries.push(new Entry(this.buffer, offset));
|
|
142
161
|
}
|
|
143
162
|
}
|
|
144
163
|
};
|
|
164
|
+
_ACL_version_accessor_storage = new WeakMap();
|
|
145
165
|
__setFunctionName(_classThis, "ACL");
|
|
146
166
|
(() => {
|
|
147
|
-
|
|
167
|
+
var _a;
|
|
168
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
|
|
148
169
|
_version_decorators = [(_a = t).uint32.bind(_a)];
|
|
149
|
-
__esDecorate(
|
|
170
|
+
__esDecorate(_classThis, null, _version_decorators, { kind: "accessor", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers);
|
|
150
171
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
151
172
|
ACL = _classThis = _classDescriptor.value;
|
|
152
173
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -156,11 +177,9 @@ let ACL = (() => {
|
|
|
156
177
|
})();
|
|
157
178
|
export { ACL };
|
|
158
179
|
export function fromMode(mode) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
new Entry({ tag: Tag.Other, perm: mode & S_IRWXO }),
|
|
163
|
-
]);
|
|
180
|
+
const acl = new ACL();
|
|
181
|
+
acl.entries.push(Object.assign(new Entry(), { tag: Tag.UserObj, perm: (mode & S_IRWXU) >> 6 }), Object.assign(new Entry(), { tag: Tag.GroupObj, perm: (mode & S_IRWXG) >> 3 }), Object.assign(new Entry(), { tag: Tag.Other, perm: mode & S_IRWXO }));
|
|
182
|
+
return acl;
|
|
164
183
|
}
|
|
165
184
|
export function toMode(acl) {
|
|
166
185
|
let mode = 0;
|
|
@@ -191,10 +210,10 @@ export function getSync($, path) {
|
|
|
191
210
|
return new ACL(xattr.getSync.call($, path, 'system.posix_acl_access'));
|
|
192
211
|
}
|
|
193
212
|
export async function set($, path, acl) {
|
|
194
|
-
await xattr.set.call($, path, 'system.posix_acl_access',
|
|
213
|
+
await xattr.set.call($, path, 'system.posix_acl_access', new Uint8Array(acl.buffer, acl.byteOffset, acl.byteLength));
|
|
195
214
|
}
|
|
196
215
|
export function setSync($, path, acl) {
|
|
197
|
-
xattr.setSync.call($, path, 'system.posix_acl_access',
|
|
216
|
+
xattr.setSync.call($, path, 'system.posix_acl_access', new Uint8Array(acl.buffer, acl.byteOffset, acl.byteLength));
|
|
198
217
|
}
|
|
199
218
|
export let shouldCheck = true;
|
|
200
219
|
export function setChecks(enabled) {
|
|
@@ -210,10 +229,10 @@ export function check($, inode, access) {
|
|
|
210
229
|
return true;
|
|
211
230
|
(_a = inode.attributes) !== null && _a !== void 0 ? _a : (inode.attributes = new Attributes());
|
|
212
231
|
const { euid, egid } = (_b = $ === null || $ === void 0 ? void 0 : $.credentials) !== null && _b !== void 0 ? _b : defaultContext.credentials;
|
|
213
|
-
const
|
|
214
|
-
if (!
|
|
232
|
+
const data = inode.attributes.get('system.posix_acl_access');
|
|
233
|
+
if (!data)
|
|
215
234
|
return true;
|
|
216
|
-
const acl = new ACL(
|
|
235
|
+
const acl = new ACL(data);
|
|
217
236
|
let mask = R_OK | W_OK | X_OK;
|
|
218
237
|
let result = false;
|
|
219
238
|
for (const entry of acl.entries) {
|
package/dist/vfs/async.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { Dir, Dirent } from './dir.js';
|
|
|
5
5
|
import type { Stats } from './stats.js';
|
|
6
6
|
import type { FileContents } from './types.js';
|
|
7
7
|
import { Buffer } from 'buffer';
|
|
8
|
-
import {
|
|
8
|
+
import { type Exception } from 'kerium';
|
|
9
9
|
import { BigIntStats } from './stats.js';
|
|
10
10
|
import { ReadStream, WriteStream, type ReadStreamOptions, type WriteStreamOptions } from './streams.js';
|
|
11
11
|
import { FSWatcher } from './watchers.js';
|
|
@@ -267,7 +267,7 @@ export declare function statfs(this: V_Context, path: fs.PathLike, options: fs.S
|
|
|
267
267
|
bigint: true;
|
|
268
268
|
}, callback: Callback<[fs.BigIntStatsFs]>): void;
|
|
269
269
|
export declare function openAsBlob(this: V_Context, path: fs.PathLike, options?: fs.OpenAsBlobOptions): Promise<Blob>;
|
|
270
|
-
type GlobCallback<Args extends unknown[]> = (e:
|
|
270
|
+
type GlobCallback<Args extends unknown[]> = (e: Exception | null, ...args: Args) => unknown;
|
|
271
271
|
/**
|
|
272
272
|
* Retrieves the files matching the specified pattern.
|
|
273
273
|
*/
|
package/dist/vfs/async.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
|
-
import {
|
|
2
|
+
import { UV, withErrno } from 'kerium';
|
|
3
3
|
import { normalizeMode, normalizePath } from '../utils.js';
|
|
4
4
|
import { R_OK } from './constants.js';
|
|
5
5
|
import * as promises from './promises.js';
|
|
@@ -124,9 +124,8 @@ export function ftruncate(fd, lenOrCB, cb = nop) {
|
|
|
124
124
|
const length = typeof lenOrCB === 'number' ? lenOrCB : 0;
|
|
125
125
|
cb = typeof lenOrCB === 'function' ? lenOrCB : cb;
|
|
126
126
|
const file = new promises.FileHandle(this, fd);
|
|
127
|
-
if (length < 0)
|
|
128
|
-
throw
|
|
129
|
-
}
|
|
127
|
+
if (length < 0)
|
|
128
|
+
throw withErrno('EINVAL');
|
|
130
129
|
file.truncate(length)
|
|
131
130
|
.then(() => cb())
|
|
132
131
|
.catch(cb);
|
|
@@ -166,7 +165,7 @@ export function write(fd, data, cbPosOff, cbLenEnc, cbPosEnc, cb = nop) {
|
|
|
166
165
|
default:
|
|
167
166
|
// ...try to find the callback and get out of here!
|
|
168
167
|
cb = (typeof cbLenEnc === 'function' ? cbLenEnc : typeof cbPosEnc === 'function' ? cbPosEnc : cb);
|
|
169
|
-
cb(
|
|
168
|
+
cb(withErrno('EINVAL'));
|
|
170
169
|
return;
|
|
171
170
|
}
|
|
172
171
|
buffer = Buffer.from(data);
|
|
@@ -355,9 +354,8 @@ export function watchFile(path, options, listener) {
|
|
|
355
354
|
if (typeof options == 'function') {
|
|
356
355
|
listener = options;
|
|
357
356
|
}
|
|
358
|
-
if (!listener)
|
|
359
|
-
throw
|
|
360
|
-
}
|
|
357
|
+
if (!listener)
|
|
358
|
+
throw UV('EINVAL', 'watch', path.toString());
|
|
361
359
|
if (statWatchers.has(normalizedPath)) {
|
|
362
360
|
const entry = statWatchers.get(normalizedPath);
|
|
363
361
|
if (entry) {
|
package/dist/vfs/dir.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Dir as _Dir, Dirent as _Dirent } from 'node:fs';
|
|
2
2
|
import type { V_Context } from '../context.js';
|
|
3
|
-
import {
|
|
3
|
+
import type { InodeLike } from '../internal/inode.js';
|
|
4
4
|
import type { Callback } from '../utils.js';
|
|
5
5
|
export declare class Dirent implements _Dirent {
|
|
6
6
|
path: string;
|
package/dist/vfs/dir.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { withErrno } from 'kerium';
|
|
1
2
|
import { isBlockDevice, isCharacterDevice, isDirectory, isFIFO, isFile, isSocket, isSymbolicLink } from '../internal/inode.js';
|
|
2
|
-
import { Errno, ErrnoError } from '../internal/error.js';
|
|
3
3
|
import { basename } from '../path.js';
|
|
4
4
|
import { readdir } from './promises.js';
|
|
5
5
|
import { readdirSync } from './sync.js';
|
|
@@ -41,9 +41,8 @@ export class Dirent {
|
|
|
41
41
|
*/
|
|
42
42
|
export class Dir {
|
|
43
43
|
checkClosed() {
|
|
44
|
-
if (this.closed)
|
|
45
|
-
throw
|
|
46
|
-
}
|
|
44
|
+
if (this.closed)
|
|
45
|
+
throw withErrno('EBADF', 'Can not use closed Dir');
|
|
47
46
|
}
|
|
48
47
|
constructor(path, context) {
|
|
49
48
|
this.path = path;
|
package/dist/vfs/file.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { UV, withErrno } from 'kerium';
|
|
1
2
|
import { defaultContext } from '../internal/contexts.js';
|
|
2
|
-
import { Errno, ErrnoError } from '../internal/error.js';
|
|
3
3
|
import { InodeFlags, isBlockDevice, isCharacterDevice } from '../internal/inode.js';
|
|
4
4
|
import '../polyfills.js';
|
|
5
5
|
import * as c from './constants.js';
|
|
@@ -51,11 +51,11 @@ export class SyncHandle {
|
|
|
51
51
|
this.close();
|
|
52
52
|
}
|
|
53
53
|
get _isSync() {
|
|
54
|
-
return !!(this.flag & c.O_SYNC || this.inode.flags & InodeFlags.Sync);
|
|
54
|
+
return !!(this.flag & c.O_SYNC || this.inode.flags & InodeFlags.Sync || this.fs.attributes.has('sync'));
|
|
55
55
|
}
|
|
56
56
|
sync() {
|
|
57
57
|
if (this.closed)
|
|
58
|
-
throw
|
|
58
|
+
throw UV('EBADF', 'sync', this.path);
|
|
59
59
|
if (!this.dirty)
|
|
60
60
|
return;
|
|
61
61
|
if (!this.fs.attributes.has('no_write'))
|
|
@@ -70,7 +70,7 @@ export class SyncHandle {
|
|
|
70
70
|
}
|
|
71
71
|
close() {
|
|
72
72
|
if (this.closed)
|
|
73
|
-
throw
|
|
73
|
+
throw UV('EBADF', 'close', this.path);
|
|
74
74
|
this.sync();
|
|
75
75
|
this.dispose();
|
|
76
76
|
}
|
|
@@ -79,23 +79,28 @@ export class SyncHandle {
|
|
|
79
79
|
*/
|
|
80
80
|
dispose(force) {
|
|
81
81
|
if (this.closed)
|
|
82
|
-
throw
|
|
82
|
+
throw UV('EBADF', 'close', this.path);
|
|
83
83
|
if (this.dirty && !force)
|
|
84
|
-
throw
|
|
84
|
+
throw UV('EBUSY', 'close', this.path);
|
|
85
85
|
this.closed = true;
|
|
86
86
|
}
|
|
87
87
|
stat() {
|
|
88
88
|
if (this.closed)
|
|
89
|
-
throw
|
|
89
|
+
throw UV('EBADF', 'stat', this.path);
|
|
90
90
|
return this.inode;
|
|
91
91
|
}
|
|
92
92
|
truncate(length) {
|
|
93
|
+
if (length < 0)
|
|
94
|
+
throw UV('EINVAL', 'truncate', this.path);
|
|
93
95
|
if (this.closed)
|
|
94
|
-
throw
|
|
96
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
97
|
+
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
|
|
98
|
+
throw UV('EBADF', 'truncate', this.path);
|
|
99
|
+
if (this.fs.attributes.has('readonly'))
|
|
100
|
+
throw UV('EROFS', 'truncate', this.path);
|
|
101
|
+
if (this.inode.flags & InodeFlags.Immutable)
|
|
102
|
+
throw UV('EPERM', 'truncate', this.path);
|
|
95
103
|
this.dirty = true;
|
|
96
|
-
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR)) {
|
|
97
|
-
throw new ErrnoError(Errno.EPERM, 'File not opened with a writeable mode', this.path, 'truncate');
|
|
98
|
-
}
|
|
99
104
|
this.inode.mtimeMs = Date.now();
|
|
100
105
|
this.inode.size = length;
|
|
101
106
|
this.inode.ctimeMs = Date.now();
|
|
@@ -113,11 +118,13 @@ export class SyncHandle {
|
|
|
113
118
|
*/
|
|
114
119
|
write(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
115
120
|
if (this.closed)
|
|
116
|
-
throw
|
|
121
|
+
throw UV('EBADF', 'write', this.path);
|
|
117
122
|
if (!(this.flag & c.O_WRONLY || this.flag & c.O_RDWR))
|
|
118
|
-
throw
|
|
123
|
+
throw UV('EBADF', 'write', this.path);
|
|
124
|
+
if (this.fs.attributes.has('readonly'))
|
|
125
|
+
throw UV('EROFS', 'write', this.path);
|
|
119
126
|
if (this.inode.flags & InodeFlags.Immutable)
|
|
120
|
-
throw
|
|
127
|
+
throw UV('EPERM', 'write', this.path);
|
|
121
128
|
this.dirty = true;
|
|
122
129
|
const end = position + length;
|
|
123
130
|
const slice = buffer.subarray(offset, offset + length);
|
|
@@ -142,10 +149,10 @@ export class SyncHandle {
|
|
|
142
149
|
*/
|
|
143
150
|
read(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
|
|
144
151
|
if (this.closed)
|
|
145
|
-
throw
|
|
152
|
+
throw UV('EBADF', 'read', this.path);
|
|
146
153
|
if (this.flag & c.O_WRONLY)
|
|
147
|
-
throw
|
|
148
|
-
if (!(this.inode.flags & InodeFlags.NoAtime)) {
|
|
154
|
+
throw UV('EBADF', 'read', this.path);
|
|
155
|
+
if (!(this.inode.flags & InodeFlags.NoAtime) && !this.fs.attributes.has('no_atime')) {
|
|
149
156
|
this.dirty = true;
|
|
150
157
|
this.inode.atimeMs = Date.now();
|
|
151
158
|
}
|
|
@@ -162,7 +169,7 @@ export class SyncHandle {
|
|
|
162
169
|
}
|
|
163
170
|
chmod(mode) {
|
|
164
171
|
if (this.closed)
|
|
165
|
-
throw
|
|
172
|
+
throw UV('EBADF', 'chmod', this.path);
|
|
166
173
|
this.dirty = true;
|
|
167
174
|
this.inode.mode = (this.inode.mode & (mode > c.S_IFMT ? ~c.S_IFMT : c.S_IFMT)) | mode;
|
|
168
175
|
if (this._isSync || mode > c.S_IFMT)
|
|
@@ -170,7 +177,7 @@ export class SyncHandle {
|
|
|
170
177
|
}
|
|
171
178
|
chown(uid, gid) {
|
|
172
179
|
if (this.closed)
|
|
173
|
-
throw
|
|
180
|
+
throw UV('EBADF', 'chmod', this.path);
|
|
174
181
|
this.dirty = true;
|
|
175
182
|
_chown(this.inode, uid, gid);
|
|
176
183
|
if (this._isSync)
|
|
@@ -181,7 +188,7 @@ export class SyncHandle {
|
|
|
181
188
|
*/
|
|
182
189
|
utimes(atime, mtime) {
|
|
183
190
|
if (this.closed)
|
|
184
|
-
throw
|
|
191
|
+
throw UV('EBADF', 'utimes', this.path);
|
|
185
192
|
this.dirty = true;
|
|
186
193
|
this.inode.atimeMs = atime;
|
|
187
194
|
this.inode.mtimeMs = mtime;
|
|
@@ -193,7 +200,7 @@ export class SyncHandle {
|
|
|
193
200
|
*/
|
|
194
201
|
streamRead(options) {
|
|
195
202
|
if (this.closed)
|
|
196
|
-
throw
|
|
203
|
+
throw UV('EBADF', 'streamRead', this.path);
|
|
197
204
|
return this.fs.streamRead(this.internalPath, options);
|
|
198
205
|
}
|
|
199
206
|
/**
|
|
@@ -201,9 +208,11 @@ export class SyncHandle {
|
|
|
201
208
|
*/
|
|
202
209
|
streamWrite(options) {
|
|
203
210
|
if (this.closed)
|
|
204
|
-
throw
|
|
211
|
+
throw UV('EBADF', 'write', this.path);
|
|
205
212
|
if (this.inode.flags & InodeFlags.Immutable)
|
|
206
|
-
throw
|
|
213
|
+
throw UV('EPERM', 'write', this.path);
|
|
214
|
+
if (this.fs.attributes.has('readonly'))
|
|
215
|
+
throw UV('EROFS', 'write', this.path);
|
|
207
216
|
return this.fs.streamWrite(this.internalPath, options);
|
|
208
217
|
}
|
|
209
218
|
}
|
|
@@ -226,7 +235,7 @@ export function fromFD($, fd) {
|
|
|
226
235
|
const map = (_a = $ === null || $ === void 0 ? void 0 : $.descriptors) !== null && _a !== void 0 ? _a : defaultContext.descriptors;
|
|
227
236
|
const value = map.get(fd);
|
|
228
237
|
if (!value)
|
|
229
|
-
throw
|
|
238
|
+
throw withErrno('EBADF');
|
|
230
239
|
return value;
|
|
231
240
|
}
|
|
232
241
|
export function deleteFD($, fd) {
|
package/dist/vfs/flags.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { withErrno } from 'kerium';
|
|
2
2
|
import * as c from './constants.js';
|
|
3
3
|
export const pattern = /[rwasx]{1,2}\+?/;
|
|
4
4
|
/**
|
|
@@ -8,7 +8,7 @@ export function parse(flag) {
|
|
|
8
8
|
if (typeof flag == 'number')
|
|
9
9
|
return flag;
|
|
10
10
|
if (!pattern.test(flag)) {
|
|
11
|
-
throw
|
|
11
|
+
throw withErrno('EINVAL', 'Invalid flag string: ' + flag);
|
|
12
12
|
}
|
|
13
13
|
return toNumber(flag);
|
|
14
14
|
}
|
|
@@ -30,7 +30,7 @@ export function toString(flag) {
|
|
|
30
30
|
*/
|
|
31
31
|
export function toNumber(flag) {
|
|
32
32
|
if (!flag.includes('r') && !flag.includes('w') && !flag.includes('a')) {
|
|
33
|
-
throw
|
|
33
|
+
throw withErrno('EINVAL', 'Invalid flag string: ' + flag);
|
|
34
34
|
}
|
|
35
35
|
let n = flag.includes('r') ? c.O_RDONLY : c.O_CREAT;
|
|
36
36
|
if (flag.includes('w'))
|
package/dist/vfs/ioctl.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import { BufferView } from 'utilium/buffer.js';
|
|
1
2
|
import type { V_Context } from '../context.js';
|
|
2
3
|
import { Inode } from '../internal/inode.js';
|
|
3
|
-
declare class fsxattr {
|
|
4
|
+
declare class fsxattr extends BufferView {
|
|
4
5
|
/** xflags field value */
|
|
5
|
-
xflags: number;
|
|
6
|
+
accessor xflags: number;
|
|
6
7
|
/** extsize field value */
|
|
7
|
-
extsize: number;
|
|
8
|
+
accessor extsize: number;
|
|
8
9
|
/** nextents field value */
|
|
9
|
-
nextents: number;
|
|
10
|
+
accessor nextents: number;
|
|
10
11
|
/** project identifier */
|
|
11
|
-
projid: number;
|
|
12
|
+
accessor projid: number;
|
|
12
13
|
/** CoW extsize field value */
|
|
13
|
-
cowextsize: number;
|
|
14
|
-
protected pad:
|
|
14
|
+
accessor cowextsize: number;
|
|
15
|
+
protected accessor pad: number[];
|
|
15
16
|
constructor(inode?: Inode);
|
|
16
17
|
}
|
|
17
18
|
/**
|