@zenfs/core 1.11.4 → 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.d.ts +19 -15
- package/dist/backends/backend.js +36 -19
- package/dist/backends/cow.d.ts +20 -30
- package/dist/backends/cow.js +83 -192
- package/dist/backends/fetch.d.ts +1 -0
- package/dist/backends/fetch.js +30 -30
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.js +1 -1
- package/dist/backends/memory.d.ts +5 -7
- package/dist/backends/memory.js +2 -3
- package/dist/backends/passthrough.d.ts +19 -23
- package/dist/backends/passthrough.js +98 -288
- package/dist/backends/port.d.ts +220 -0
- package/dist/backends/port.js +328 -0
- package/dist/backends/single_buffer.d.ts +59 -47
- package/dist/backends/single_buffer.js +468 -219
- package/dist/backends/store/fs.d.ts +25 -35
- package/dist/backends/store/fs.js +276 -315
- package/dist/backends/store/store.d.ts +10 -15
- package/dist/backends/store/store.js +11 -10
- package/dist/config.d.ts +3 -12
- package/dist/config.js +17 -19
- package/dist/context.d.ts +8 -21
- package/dist/context.js +33 -10
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/contexts.d.ts +63 -0
- package/dist/internal/contexts.js +15 -0
- package/dist/internal/credentials.d.ts +2 -11
- package/dist/internal/credentials.js +0 -19
- package/dist/internal/devices.d.ts +18 -80
- package/dist/internal/devices.js +103 -316
- 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 +11 -11
- package/dist/internal/filesystem.d.ts +51 -94
- package/dist/internal/filesystem.js +21 -20
- package/dist/internal/index.d.ts +1 -2
- package/dist/internal/index.js +1 -2
- package/dist/internal/index_fs.d.ts +12 -30
- package/dist/internal/index_fs.js +37 -69
- package/dist/internal/inode.d.ts +140 -24
- package/dist/internal/inode.js +515 -66
- package/dist/mixins/async.js +52 -112
- package/dist/mixins/mutexed.d.ts +19 -18
- package/dist/mixins/mutexed.js +62 -64
- package/dist/mixins/readonly.d.ts +7 -6
- package/dist/mixins/readonly.js +24 -18
- package/dist/mixins/sync.js +8 -8
- package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
- package/dist/{vfs/path.js → path.js} +6 -9
- package/dist/polyfills.js +1 -1
- package/dist/readline.d.ts +134 -0
- package/dist/readline.js +623 -0
- package/dist/utils.d.ts +9 -37
- package/dist/utils.js +17 -85
- package/dist/vfs/acl.d.ts +42 -0
- package/dist/vfs/acl.js +268 -0
- package/dist/vfs/async.d.ts +9 -23
- package/dist/vfs/async.js +25 -27
- package/dist/vfs/config.d.ts +6 -18
- package/dist/vfs/config.js +8 -18
- package/dist/vfs/dir.d.ts +3 -3
- package/dist/vfs/dir.js +12 -12
- package/dist/vfs/file.d.ts +106 -0
- package/dist/vfs/file.js +244 -0
- package/dist/vfs/flags.d.ts +19 -0
- package/dist/vfs/flags.js +62 -0
- package/dist/vfs/index.d.ts +4 -10
- package/dist/vfs/index.js +4 -13
- package/dist/vfs/ioctl.d.ts +88 -0
- package/dist/vfs/ioctl.js +409 -0
- package/dist/vfs/promises.d.ts +81 -19
- package/dist/vfs/promises.js +404 -288
- package/dist/vfs/shared.d.ts +7 -37
- package/dist/vfs/shared.js +29 -85
- package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
- package/dist/{stats.js → vfs/stats.js} +11 -66
- package/dist/vfs/streams.d.ts +1 -0
- package/dist/vfs/streams.js +32 -27
- package/dist/vfs/sync.d.ts +3 -3
- package/dist/vfs/sync.js +263 -260
- package/dist/vfs/watchers.d.ts +2 -2
- package/dist/vfs/watchers.js +12 -12
- package/dist/vfs/xattr.d.ts +116 -0
- package/dist/vfs/xattr.js +201 -0
- package/package.json +5 -3
- package/readme.md +1 -1
- package/scripts/test.js +2 -2
- package/tests/assignment.ts +1 -1
- package/tests/backend/config.worker.js +4 -1
- package/tests/backend/fetch.test.ts +3 -0
- package/tests/backend/port.test.ts +19 -33
- package/tests/backend/remote.worker.js +4 -1
- package/tests/backend/single-buffer.test.ts +53 -0
- package/tests/backend/single-buffer.worker.js +30 -0
- package/tests/common/context.test.ts +3 -3
- package/tests/common/handle.test.ts +17 -12
- package/tests/common/mutex.test.ts +9 -9
- package/tests/common/path.test.ts +1 -1
- package/tests/common/readline.test.ts +104 -0
- package/tests/common.ts +4 -19
- package/tests/fetch/fetch.ts +2 -2
- 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 +4 -3
- package/tests/fs/open.test.ts +4 -21
- package/tests/fs/permissions.test.ts +14 -18
- package/tests/fs/read.test.ts +10 -9
- package/tests/fs/readFile.test.ts +10 -26
- package/tests/fs/rename.test.ts +4 -9
- package/tests/fs/stat.test.ts +8 -8
- package/tests/fs/streams.test.ts +2 -11
- package/tests/fs/times.test.ts +7 -7
- 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 +85 -0
- package/tests/logs.js +22 -0
- package/tests/setup/context.ts +1 -1
- package/tests/setup/index.ts +3 -3
- package/tests/setup/port.ts +7 -1
- package/dist/backends/port/fs.d.ts +0 -84
- package/dist/backends/port/fs.js +0 -151
- package/dist/backends/port/rpc.d.ts +0 -77
- package/dist/backends/port/rpc.js +0 -100
- package/dist/backends/store/simple.d.ts +0 -20
- package/dist/backends/store/simple.js +0 -13
- package/dist/internal/file.d.ts +0 -359
- package/dist/internal/file.js +0 -751
- package/dist/internal/log.d.ts +0 -133
- package/dist/internal/log.js +0 -218
- package/tests/fs/writeFile.test.ts +0 -70
package/dist/vfs/shared.d.ts
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
import type * as fs from 'node:fs';
|
|
2
|
-
import type {
|
|
2
|
+
import type { V_Context } from '../context.js';
|
|
3
3
|
import type { FileSystem } from '../internal/filesystem.js';
|
|
4
|
-
import type {
|
|
5
|
-
import { type
|
|
6
|
-
import { ErrnoError } from '../internal/error.js';
|
|
7
|
-
import { type AbsolutePath } from './path.js';
|
|
8
|
-
/**
|
|
9
|
-
* @internal @hidden
|
|
10
|
-
*/
|
|
11
|
-
export declare const fdMap: Map<number, File>;
|
|
12
|
-
/**
|
|
13
|
-
* @internal @hidden
|
|
14
|
-
*/
|
|
15
|
-
export declare function file2fd(file: File): number;
|
|
16
|
-
/**
|
|
17
|
-
* @internal @hidden
|
|
18
|
-
*/
|
|
19
|
-
export declare function fd2file(fd: number): File;
|
|
4
|
+
import type { InodeLike } from '../internal/inode.js';
|
|
5
|
+
import { type AbsolutePath } from '../path.js';
|
|
20
6
|
/**
|
|
21
7
|
* @internal @hidden
|
|
22
8
|
*/
|
|
@@ -32,12 +18,12 @@ export declare const mounts: Map<string, FileSystem>;
|
|
|
32
18
|
* @category Backends and Configuration
|
|
33
19
|
* @internal
|
|
34
20
|
*/
|
|
35
|
-
export declare function mount(mountPoint: string, fs: FileSystem): void;
|
|
21
|
+
export declare function mount(this: V_Context, mountPoint: string, fs: FileSystem): void;
|
|
36
22
|
/**
|
|
37
23
|
* Unmounts the file system at `mountPoint`.
|
|
38
24
|
* @category Backends and Configuration
|
|
39
25
|
*/
|
|
40
|
-
export declare function umount(mountPoint: string): void;
|
|
26
|
+
export declare function umount(this: V_Context, mountPoint: string): void;
|
|
41
27
|
/**
|
|
42
28
|
* @internal @hidden
|
|
43
29
|
*/
|
|
@@ -54,35 +40,19 @@ export interface ResolvedPath extends ResolvedMount {
|
|
|
54
40
|
/** The real, absolute path */
|
|
55
41
|
fullPath: string;
|
|
56
42
|
/** Stats */
|
|
57
|
-
stats?:
|
|
43
|
+
stats?: InodeLike;
|
|
58
44
|
}
|
|
59
45
|
/**
|
|
60
46
|
* Gets the internal `FileSystem` for the path, then returns it along with the path relative to the FS' root
|
|
61
47
|
* @internal @hidden
|
|
62
48
|
*/
|
|
63
49
|
export declare function resolveMount(path: string, ctx: V_Context): ResolvedMount;
|
|
64
|
-
/**
|
|
65
|
-
* Reverse maps the paths in text from the mounted FileSystem to the global path
|
|
66
|
-
* @internal @hidden
|
|
67
|
-
*/
|
|
68
|
-
export declare function fixPaths(text: string, paths: Record<string, string>): string;
|
|
69
|
-
/**
|
|
70
|
-
* Fix paths in error stacks
|
|
71
|
-
* @internal @hidden
|
|
72
|
-
*/
|
|
73
|
-
export declare function fixError<E extends ErrnoError>(e: E, paths: Record<string, string>): E;
|
|
74
|
-
/**
|
|
75
|
-
* @internal @deprecated
|
|
76
|
-
*/
|
|
77
|
-
export declare function mountObject(mounts: MountObject): void;
|
|
78
50
|
/**
|
|
79
51
|
* @internal @hidden
|
|
80
52
|
*/
|
|
81
53
|
export declare function _statfs<const T extends boolean>(fs: FileSystem, bigint?: T): T extends true ? fs.BigIntStatsFs : fs.StatsFs;
|
|
82
54
|
/**
|
|
83
55
|
* Change the root path
|
|
84
|
-
* @param inPlace if true, this changes the root for the current context instead of creating a new one (if associated with a context).
|
|
85
56
|
* @category Backends and Configuration
|
|
86
57
|
*/
|
|
87
|
-
export declare function chroot(this: V_Context, path: string
|
|
88
|
-
export declare function chroot<T extends V_Context>(this: T, path: string, inPlace: true): T;
|
|
58
|
+
export declare function chroot(this: V_Context, path: string): void;
|
package/dist/vfs/shared.js
CHANGED
|
@@ -1,34 +1,11 @@
|
|
|
1
1
|
// Utilities and shared data
|
|
2
|
+
import { Errno, Exception, UV, withErrno } from 'kerium';
|
|
3
|
+
import { alert, debug, err, info, notice, warn } from 'kerium/log';
|
|
2
4
|
import { InMemory } from '../backends/memory.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { alert, debug, err, info, log_deprecated, notice, warn } from '../internal/log.js';
|
|
5
|
+
import { defaultContext } from '../internal/contexts.js';
|
|
6
|
+
import { join, resolve } from '../path.js';
|
|
6
7
|
import { normalizePath } from '../utils.js';
|
|
7
8
|
import { size_max } from './constants.js';
|
|
8
|
-
import { join, resolve } from './path.js';
|
|
9
|
-
// descriptors
|
|
10
|
-
/**
|
|
11
|
-
* @internal @hidden
|
|
12
|
-
*/
|
|
13
|
-
export const fdMap = new Map();
|
|
14
|
-
let nextFd = 100;
|
|
15
|
-
/**
|
|
16
|
-
* @internal @hidden
|
|
17
|
-
*/
|
|
18
|
-
export function file2fd(file) {
|
|
19
|
-
const fd = nextFd++;
|
|
20
|
-
fdMap.set(fd, file);
|
|
21
|
-
return fd;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* @internal @hidden
|
|
25
|
-
*/
|
|
26
|
-
export function fd2file(fd) {
|
|
27
|
-
if (!fdMap.has(fd)) {
|
|
28
|
-
throw new ErrnoError(Errno.EBADF);
|
|
29
|
-
}
|
|
30
|
-
return fdMap.get(fd);
|
|
31
|
-
}
|
|
32
9
|
/**
|
|
33
10
|
* The map of mount points
|
|
34
11
|
* @category Backends and Configuration
|
|
@@ -36,7 +13,7 @@ export function fd2file(fd) {
|
|
|
36
13
|
*/
|
|
37
14
|
export const mounts = new Map();
|
|
38
15
|
// Set a default root.
|
|
39
|
-
mount('/', InMemory.create({
|
|
16
|
+
mount('/', InMemory.create({ label: 'root' }));
|
|
40
17
|
/**
|
|
41
18
|
* Mounts the file system at `mountPoint`.
|
|
42
19
|
* @category Backends and Configuration
|
|
@@ -45,9 +22,9 @@ mount('/', InMemory.create({ name: 'root' }));
|
|
|
45
22
|
export function mount(mountPoint, fs) {
|
|
46
23
|
if (mountPoint[0] != '/')
|
|
47
24
|
mountPoint = '/' + mountPoint;
|
|
48
|
-
mountPoint = resolve(mountPoint);
|
|
25
|
+
mountPoint = resolve.call(this, mountPoint);
|
|
49
26
|
if (mounts.has(mountPoint))
|
|
50
|
-
throw err(
|
|
27
|
+
throw err(withErrno('EINVAL', 'Mount point is already in use: ' + mountPoint));
|
|
51
28
|
fs._mountPoint = mountPoint;
|
|
52
29
|
mounts.set(mountPoint, fs);
|
|
53
30
|
info(`Mounted ${fs.name} on ${mountPoint}`);
|
|
@@ -60,7 +37,7 @@ export function mount(mountPoint, fs) {
|
|
|
60
37
|
export function umount(mountPoint) {
|
|
61
38
|
if (mountPoint[0] != '/')
|
|
62
39
|
mountPoint = '/' + mountPoint;
|
|
63
|
-
mountPoint = resolve(mountPoint);
|
|
40
|
+
mountPoint = resolve.call(this, mountPoint);
|
|
64
41
|
if (!mounts.has(mountPoint)) {
|
|
65
42
|
warn(mountPoint + ' is already unmounted');
|
|
66
43
|
return;
|
|
@@ -73,7 +50,7 @@ export function umount(mountPoint) {
|
|
|
73
50
|
* @internal @hidden
|
|
74
51
|
*/
|
|
75
52
|
export function resolveMount(path, ctx) {
|
|
76
|
-
const root = (ctx === null || ctx === void 0 ? void 0 : ctx.root) ||
|
|
53
|
+
const root = (ctx === null || ctx === void 0 ? void 0 : ctx.root) || defaultContext.root;
|
|
77
54
|
path = normalizePath(join(root, path));
|
|
78
55
|
const sortedMounts = [...mounts].sort((a, b) => (a[0].length > b[0].length ? -1 : 1)); // descending order of the string length
|
|
79
56
|
for (const [mountPoint, fs] of sortedMounts) {
|
|
@@ -85,50 +62,8 @@ export function resolveMount(path, ctx) {
|
|
|
85
62
|
return { fs, path, mountPoint, root };
|
|
86
63
|
}
|
|
87
64
|
}
|
|
88
|
-
throw alert(new
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Reverse maps the paths in text from the mounted FileSystem to the global path
|
|
92
|
-
* @internal @hidden
|
|
93
|
-
*/
|
|
94
|
-
export function fixPaths(text, paths) {
|
|
95
|
-
for (const [from, to] of Object.entries(paths)) {
|
|
96
|
-
text = text === null || text === void 0 ? void 0 : text.replaceAll(from, to);
|
|
97
|
-
}
|
|
98
|
-
return text;
|
|
65
|
+
throw alert(new Exception(Errno.EIO, 'No file system for ' + path));
|
|
99
66
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Fix paths in error stacks
|
|
102
|
-
* @internal @hidden
|
|
103
|
-
*/
|
|
104
|
-
export function fixError(e, paths) {
|
|
105
|
-
if (typeof e.stack == 'string') {
|
|
106
|
-
e.stack = fixPaths(e.stack, paths);
|
|
107
|
-
}
|
|
108
|
-
try {
|
|
109
|
-
e.message = fixPaths(e.message, paths);
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
// `message` is read only
|
|
113
|
-
}
|
|
114
|
-
if (e.path)
|
|
115
|
-
e.path = fixPaths(e.path, paths);
|
|
116
|
-
return e;
|
|
117
|
-
}
|
|
118
|
-
/* node:coverage disable */
|
|
119
|
-
/**
|
|
120
|
-
* @internal @deprecated
|
|
121
|
-
*/
|
|
122
|
-
export function mountObject(mounts) {
|
|
123
|
-
log_deprecated('mountObject');
|
|
124
|
-
if ('/' in mounts) {
|
|
125
|
-
umount('/');
|
|
126
|
-
}
|
|
127
|
-
for (const [point, fs] of Object.entries(mounts)) {
|
|
128
|
-
mount(point, fs);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/* node:coverage enable */
|
|
132
67
|
/**
|
|
133
68
|
* @internal @hidden
|
|
134
69
|
*/
|
|
@@ -136,7 +71,7 @@ export function _statfs(fs, bigint) {
|
|
|
136
71
|
const md = fs.usage();
|
|
137
72
|
const bs = md.blockSize || 4096;
|
|
138
73
|
return {
|
|
139
|
-
type: (bigint ? BigInt : Number)(fs.
|
|
74
|
+
type: (bigint ? BigInt : Number)(fs.type),
|
|
140
75
|
bsize: (bigint ? BigInt : Number)(bs),
|
|
141
76
|
ffree: (bigint ? BigInt : Number)(md.freeNodes || size_max),
|
|
142
77
|
files: (bigint ? BigInt : Number)(md.totalNodes || size_max),
|
|
@@ -145,16 +80,25 @@ export function _statfs(fs, bigint) {
|
|
|
145
80
|
blocks: (bigint ? BigInt : Number)(md.totalSpace / bs),
|
|
146
81
|
};
|
|
147
82
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Change the root path
|
|
85
|
+
* @category Backends and Configuration
|
|
86
|
+
*/
|
|
87
|
+
export function chroot(path) {
|
|
88
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
89
|
+
const $ = this !== null && this !== void 0 ? this : defaultContext;
|
|
90
|
+
if (((_a = $.credentials) === null || _a === void 0 ? void 0 : _a.uid) !== 0 && ((_b = $.credentials) === null || _b === void 0 ? void 0 : _b.gid) !== 0 && ((_c = $.credentials) === null || _c === void 0 ? void 0 : _c.euid) !== 0 && ((_d = $.credentials) === null || _d === void 0 ? void 0 : _d.egid) !== 0)
|
|
91
|
+
throw withErrno('EPERM', 'Can not chroot() as non-root user');
|
|
92
|
+
(_e = $.root) !== null && _e !== void 0 ? _e : ($.root = '/');
|
|
93
|
+
const newRoot = join($.root, path);
|
|
94
|
+
for (const handle of (_g = (_f = $.descriptors) === null || _f === void 0 ? void 0 : _f.values()) !== null && _g !== void 0 ? _g : []) {
|
|
95
|
+
if (!handle.path.startsWith($.root))
|
|
96
|
+
throw UV('EBUSY', 'chroot', handle.path);
|
|
97
|
+
handle.path = handle.path.slice($.root.length);
|
|
156
98
|
}
|
|
157
|
-
|
|
99
|
+
if (newRoot.length > $.root.length)
|
|
100
|
+
throw withErrno('EPERM', 'Can not chroot() outside of current root');
|
|
101
|
+
$.root = newRoot;
|
|
158
102
|
}
|
|
159
103
|
/**
|
|
160
104
|
* @internal @hidden
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import type * as Node from 'node:fs';
|
|
2
|
-
import type { V_Context } from '
|
|
3
|
-
import type { InodeFields
|
|
4
|
-
import * as c from './vfs/constants.js';
|
|
5
|
-
/**
|
|
6
|
-
* Indicates the type of a file. Applied to 'mode'.
|
|
7
|
-
* @deprecated
|
|
8
|
-
*/
|
|
9
|
-
export type FileType = typeof c.S_IFREG | typeof c.S_IFDIR | typeof c.S_IFLNK;
|
|
2
|
+
import type { V_Context } from '../context.js';
|
|
3
|
+
import type { InodeFields } from '../internal/inode.js';
|
|
10
4
|
export interface StatsLike<T extends number | bigint = number | bigint> {
|
|
11
5
|
/**
|
|
12
6
|
* Size of the item in bytes.
|
|
@@ -91,12 +85,6 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
91
85
|
* Group ID of owner
|
|
92
86
|
*/
|
|
93
87
|
gid: T;
|
|
94
|
-
/**
|
|
95
|
-
* Some file systems stash data on stats objects.
|
|
96
|
-
* @todo [BREAKING] Remove this
|
|
97
|
-
* @deprecated @hidden
|
|
98
|
-
*/
|
|
99
|
-
fileData?: unknown;
|
|
100
88
|
/**
|
|
101
89
|
* Time of last access, since epoch
|
|
102
90
|
*/
|
|
@@ -126,12 +114,22 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
126
114
|
* For directories/symlinks, this is normally the size of the struct that represents the item.
|
|
127
115
|
*/
|
|
128
116
|
size: T;
|
|
117
|
+
/**
|
|
118
|
+
* @internal Used by inodes
|
|
119
|
+
*/
|
|
129
120
|
data?: number;
|
|
121
|
+
/**
|
|
122
|
+
* @internal Used by inodes
|
|
123
|
+
*/
|
|
130
124
|
flags?: number;
|
|
125
|
+
/**
|
|
126
|
+
* @internal Used by inodes
|
|
127
|
+
*/
|
|
128
|
+
version?: number;
|
|
131
129
|
/**
|
|
132
130
|
* Creates a new stats instance from a stats-like object. Can be used to copy stats (note)
|
|
133
131
|
*/
|
|
134
|
-
constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode, ino, ...rest }?: Partial<
|
|
132
|
+
constructor({ atimeMs, mtimeMs, ctimeMs, birthtimeMs, uid, gid, size, mode, ino, ...rest }?: Partial<StatsLike & InodeFields>);
|
|
135
133
|
isFile(): boolean;
|
|
136
134
|
isDirectory(): boolean;
|
|
137
135
|
isSymbolicLink(): boolean;
|
|
@@ -147,18 +145,6 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
147
145
|
* @internal
|
|
148
146
|
*/
|
|
149
147
|
hasAccess(mode: number, context?: V_Context): boolean;
|
|
150
|
-
/**
|
|
151
|
-
* Change the mode of the file.
|
|
152
|
-
* We use this helper function to prevent messing up the type of the file.
|
|
153
|
-
* @internal @deprecated
|
|
154
|
-
*/
|
|
155
|
-
chmod(mode: number): void;
|
|
156
|
-
/**
|
|
157
|
-
* Change the owner user/group of the file.
|
|
158
|
-
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
159
|
-
* @internal @deprecated
|
|
160
|
-
*/
|
|
161
|
-
chown(uid: number, gid: number): void;
|
|
162
148
|
get atimeNs(): bigint;
|
|
163
149
|
get mtimeNs(): bigint;
|
|
164
150
|
get ctimeNs(): bigint;
|
|
@@ -167,7 +153,7 @@ export declare abstract class StatsCommon<T extends number | bigint> implements
|
|
|
167
153
|
/**
|
|
168
154
|
* @hidden @internal
|
|
169
155
|
*/
|
|
170
|
-
export declare function _chown(stats: Partial<StatsLike<number>>, uid: number, gid: number):
|
|
156
|
+
export declare function _chown(stats: Partial<StatsLike<number>>, uid: number, gid: number): boolean;
|
|
171
157
|
/**
|
|
172
158
|
* Implementation of Node's `Stats`.
|
|
173
159
|
*
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { pick } from 'utilium';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { log_deprecated } from './internal/log.js';
|
|
5
|
-
import * as c from './vfs/constants.js';
|
|
2
|
+
import { _inode_fields, hasAccess } from '../internal/inode.js';
|
|
3
|
+
import * as c from './constants.js';
|
|
6
4
|
const n1000 = BigInt(1000);
|
|
7
5
|
/**
|
|
8
6
|
* Provides information about a particular entry in the file system.
|
|
@@ -118,65 +116,8 @@ export class StatsCommon {
|
|
|
118
116
|
* @internal
|
|
119
117
|
*/
|
|
120
118
|
hasAccess(mode, context) {
|
|
121
|
-
|
|
122
|
-
if (this.isSymbolicLink() || creds.euid === 0 || creds.egid === 0)
|
|
123
|
-
return true;
|
|
124
|
-
let perm = 0;
|
|
125
|
-
// Owner permissions
|
|
126
|
-
if (creds.uid === this.uid) {
|
|
127
|
-
if (this.mode & c.S_IRUSR)
|
|
128
|
-
perm |= c.R_OK;
|
|
129
|
-
if (this.mode & c.S_IWUSR)
|
|
130
|
-
perm |= c.W_OK;
|
|
131
|
-
if (this.mode & c.S_IXUSR)
|
|
132
|
-
perm |= c.X_OK;
|
|
133
|
-
}
|
|
134
|
-
// Group permissions
|
|
135
|
-
if (creds.gid === this.gid || creds.groups.includes(Number(this.gid))) {
|
|
136
|
-
if (this.mode & c.S_IRGRP)
|
|
137
|
-
perm |= c.R_OK;
|
|
138
|
-
if (this.mode & c.S_IWGRP)
|
|
139
|
-
perm |= c.W_OK;
|
|
140
|
-
if (this.mode & c.S_IXGRP)
|
|
141
|
-
perm |= c.X_OK;
|
|
142
|
-
}
|
|
143
|
-
// Others permissions
|
|
144
|
-
if (this.mode & c.S_IROTH)
|
|
145
|
-
perm |= c.R_OK;
|
|
146
|
-
if (this.mode & c.S_IWOTH)
|
|
147
|
-
perm |= c.W_OK;
|
|
148
|
-
if (this.mode & c.S_IXOTH)
|
|
149
|
-
perm |= c.X_OK;
|
|
150
|
-
// Perform the access check
|
|
151
|
-
return (perm & mode) === mode;
|
|
152
|
-
}
|
|
153
|
-
/* node:coverage disable */
|
|
154
|
-
/**
|
|
155
|
-
* Change the mode of the file.
|
|
156
|
-
* We use this helper function to prevent messing up the type of the file.
|
|
157
|
-
* @internal @deprecated
|
|
158
|
-
*/
|
|
159
|
-
chmod(mode) {
|
|
160
|
-
log_deprecated('StatsCommon#chmod');
|
|
161
|
-
this.mode = this._convert((this.mode & c.S_IFMT) | mode);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Change the owner user/group of the file.
|
|
165
|
-
* This function makes sure it is a valid UID/GID (that is, a 32 unsigned int)
|
|
166
|
-
* @internal @deprecated
|
|
167
|
-
*/
|
|
168
|
-
chown(uid, gid) {
|
|
169
|
-
log_deprecated('StatsCommon#chown');
|
|
170
|
-
uid = Number(uid);
|
|
171
|
-
gid = Number(gid);
|
|
172
|
-
if (!isNaN(uid) && 0 <= uid && uid < 2 ** 32) {
|
|
173
|
-
this.uid = this._convert(uid);
|
|
174
|
-
}
|
|
175
|
-
if (!isNaN(gid) && 0 <= gid && gid < 2 ** 32) {
|
|
176
|
-
this.gid = this._convert(gid);
|
|
177
|
-
}
|
|
119
|
+
return hasAccess(context, this._isBigint ? new Stats(this) : this, mode);
|
|
178
120
|
}
|
|
179
|
-
/* node:coverage enable */
|
|
180
121
|
get atimeNs() {
|
|
181
122
|
return BigInt(this.atimeMs) * n1000;
|
|
182
123
|
}
|
|
@@ -194,12 +135,16 @@ export class StatsCommon {
|
|
|
194
135
|
* @hidden @internal
|
|
195
136
|
*/
|
|
196
137
|
export function _chown(stats, uid, gid) {
|
|
197
|
-
|
|
138
|
+
let valid = true;
|
|
139
|
+
if (!isNaN(uid) && uid >= 0 && uid < c.size_max)
|
|
198
140
|
stats.uid = uid;
|
|
199
|
-
|
|
200
|
-
|
|
141
|
+
else
|
|
142
|
+
valid = false;
|
|
143
|
+
if (!isNaN(gid) && gid >= 0 && gid < c.size_max)
|
|
201
144
|
stats.gid = gid;
|
|
202
|
-
|
|
145
|
+
else
|
|
146
|
+
valid = false;
|
|
147
|
+
return valid;
|
|
203
148
|
}
|
|
204
149
|
/**
|
|
205
150
|
* Implementation of Node's `Stats`.
|
package/dist/vfs/streams.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export declare class ReadStream extends Readable implements fs.ReadStream {
|
|
|
48
48
|
private _path;
|
|
49
49
|
private _bytesRead;
|
|
50
50
|
private reader?;
|
|
51
|
+
private ready;
|
|
51
52
|
constructor(opts: CreateReadStreamOptions | undefined, handleOrPromise: FileHandle | Promise<FileHandle>);
|
|
52
53
|
_read(): Promise<void>;
|
|
53
54
|
close(callback?: Callback<[void], null>): void;
|
package/dist/vfs/streams.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { Errno, Exception, UV } from 'kerium';
|
|
2
|
+
import { warn } from 'kerium/log';
|
|
1
3
|
import { Readable, Writable } from 'readable-stream';
|
|
2
|
-
import { Errno, ErrnoError } from '../internal/error.js';
|
|
3
|
-
import { warn } from '../internal/log.js';
|
|
4
4
|
/**
|
|
5
5
|
* A ReadStream implementation that wraps an underlying global ReadableStream.
|
|
6
6
|
*/
|
|
@@ -11,28 +11,33 @@ export class ReadStream extends Readable {
|
|
|
11
11
|
this.pending = true;
|
|
12
12
|
this._path = '<unknown>';
|
|
13
13
|
this._bytesRead = 0;
|
|
14
|
-
Promise.resolve(handleOrPromise)
|
|
15
|
-
.then(
|
|
16
|
-
this._path =
|
|
17
|
-
const internal =
|
|
14
|
+
this.ready = Promise.resolve(handleOrPromise)
|
|
15
|
+
.then(handle => {
|
|
16
|
+
this._path = handle.path;
|
|
17
|
+
const internal = handle.readableWebStream({ start: opts.start, end: opts.end });
|
|
18
18
|
this.reader = internal.getReader();
|
|
19
19
|
this.pending = false;
|
|
20
|
-
return this._read();
|
|
21
20
|
})
|
|
22
|
-
.catch(err =>
|
|
21
|
+
.catch(err => {
|
|
22
|
+
this.destroy(err);
|
|
23
|
+
});
|
|
23
24
|
}
|
|
24
25
|
async _read() {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
|
|
26
|
+
try {
|
|
27
|
+
await this.ready;
|
|
28
|
+
if (!this.reader)
|
|
29
|
+
return;
|
|
30
|
+
const { done, value } = await this.reader.read();
|
|
31
|
+
if (done) {
|
|
32
|
+
this.push(null);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this._bytesRead += value.byteLength;
|
|
36
|
+
this.push(value);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
this.destroy(new Exception(Errno.EIO, err.toString()));
|
|
31
40
|
}
|
|
32
|
-
this._bytesRead += value.byteLength;
|
|
33
|
-
if (!this.push(value))
|
|
34
|
-
return;
|
|
35
|
-
await this._read();
|
|
36
41
|
}
|
|
37
42
|
close(callback = () => null) {
|
|
38
43
|
try {
|
|
@@ -41,7 +46,7 @@ export class ReadStream extends Readable {
|
|
|
41
46
|
callback(null);
|
|
42
47
|
}
|
|
43
48
|
catch (err) {
|
|
44
|
-
callback(new
|
|
49
|
+
callback(new Exception(Errno.EIO, err.toString()));
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
get path() {
|
|
@@ -65,9 +70,9 @@ export class WriteStream extends Writable {
|
|
|
65
70
|
this._path = '<unknown>';
|
|
66
71
|
this._bytesWritten = 0;
|
|
67
72
|
this.ready = Promise.resolve(handleOrPromise)
|
|
68
|
-
.then(
|
|
69
|
-
this._path =
|
|
70
|
-
const internal =
|
|
73
|
+
.then(handle => {
|
|
74
|
+
this._path = handle.path;
|
|
75
|
+
const internal = handle.writableWebStream({ start: opts.start });
|
|
71
76
|
this.writer = internal.getWriter();
|
|
72
77
|
this.pending = false;
|
|
73
78
|
})
|
|
@@ -76,9 +81,9 @@ export class WriteStream extends Writable {
|
|
|
76
81
|
async _write(chunk, encoding, callback) {
|
|
77
82
|
await this.ready;
|
|
78
83
|
if (!this.writer)
|
|
79
|
-
return callback(warn(
|
|
84
|
+
return callback(warn(UV('EAGAIN', 'write', this._path)));
|
|
80
85
|
if (encoding != 'buffer')
|
|
81
|
-
return callback(warn(
|
|
86
|
+
return callback(warn(UV('ENOTSUP', 'write', this._path)));
|
|
82
87
|
const data = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
83
88
|
try {
|
|
84
89
|
await this.writer.write(data);
|
|
@@ -86,7 +91,7 @@ export class WriteStream extends Writable {
|
|
|
86
91
|
callback();
|
|
87
92
|
}
|
|
88
93
|
catch (error) {
|
|
89
|
-
callback(new
|
|
94
|
+
callback(new Exception(Errno.EIO, error.toString()));
|
|
90
95
|
}
|
|
91
96
|
}
|
|
92
97
|
async _final(callback) {
|
|
@@ -98,7 +103,7 @@ export class WriteStream extends Writable {
|
|
|
98
103
|
callback();
|
|
99
104
|
}
|
|
100
105
|
catch (error) {
|
|
101
|
-
callback(new
|
|
106
|
+
callback(new Exception(Errno.EIO, error.toString()));
|
|
102
107
|
}
|
|
103
108
|
}
|
|
104
109
|
close(callback = () => null) {
|
|
@@ -108,7 +113,7 @@ export class WriteStream extends Writable {
|
|
|
108
113
|
callback(null);
|
|
109
114
|
}
|
|
110
115
|
catch (error) {
|
|
111
|
-
callback(new
|
|
116
|
+
callback(new Exception(Errno.EIO, error.toString()));
|
|
112
117
|
}
|
|
113
118
|
}
|
|
114
119
|
get path() {
|
package/dist/vfs/sync.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type * as fs from 'node:fs';
|
|
2
2
|
import type { V_Context } from '../context.js';
|
|
3
|
-
import type { Stats } from '../stats.js';
|
|
4
3
|
import type { FileContents, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
|
|
5
4
|
import { Buffer } from 'buffer';
|
|
6
|
-
import { BigIntStats } from '../stats.js';
|
|
7
5
|
import { Dir, Dirent } from './dir.js';
|
|
6
|
+
import { BigIntStats, Stats } from './stats.js';
|
|
8
7
|
export declare function renameSync(this: V_Context, oldPath: fs.PathLike, newPath: fs.PathLike): void;
|
|
9
8
|
/**
|
|
10
9
|
* Test whether or not `path` exists by checking with the file system.
|
|
@@ -31,7 +30,8 @@ export declare function truncateSync(this: V_Context, path: fs.PathLike, len?: n
|
|
|
31
30
|
export declare function unlinkSync(this: V_Context, path: fs.PathLike): void;
|
|
32
31
|
/**
|
|
33
32
|
* Synchronous file open.
|
|
34
|
-
* @see
|
|
33
|
+
* @see https://nodejs.org/api/fs.html#fsopensyncpath-flags-mode
|
|
34
|
+
* @param flag {@link https://nodejs.org/api/fs.html#file-system-flags}
|
|
35
35
|
*/
|
|
36
36
|
export declare function openSync(this: V_Context, path: fs.PathLike, flag: fs.OpenMode, mode?: fs.Mode | null): number;
|
|
37
37
|
/**
|