@zenfs/core 1.11.4 → 2.0.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 +31 -15
- package/dist/backends/cow.d.ts +20 -30
- package/dist/backends/cow.js +52 -142
- package/dist/backends/fetch.d.ts +1 -0
- package/dist/backends/fetch.js +3 -1
- 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 -22
- package/dist/backends/passthrough.js +85 -160
- package/dist/backends/port.d.ts +207 -0
- package/dist/backends/port.js +297 -0
- package/dist/backends/single_buffer.d.ts +11 -5
- package/dist/backends/single_buffer.js +18 -12
- package/dist/backends/store/fs.d.ts +11 -27
- package/dist/backends/store/fs.js +67 -91
- package/dist/backends/store/store.d.ts +7 -12
- package/dist/config.d.ts +1 -10
- package/dist/config.js +7 -8
- 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 +76 -279
- package/dist/internal/file_index.js +3 -3
- package/dist/internal/filesystem.d.ts +31 -89
- package/dist/internal/filesystem.js +21 -20
- package/dist/internal/index.d.ts +0 -1
- package/dist/internal/index.js +0 -1
- package/dist/internal/index_fs.d.ts +12 -30
- package/dist/internal/index_fs.js +23 -55
- package/dist/internal/inode.d.ts +147 -9
- package/dist/internal/inode.js +333 -25
- package/dist/internal/log.d.ts +19 -13
- package/dist/internal/log.js +81 -80
- package/dist/mixins/async.js +26 -90
- package/dist/mixins/mutexed.d.ts +17 -16
- package/dist/mixins/mutexed.js +29 -31
- package/dist/mixins/readonly.d.ts +7 -6
- package/dist/mixins/readonly.js +6 -0
- 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/readline.d.ts +134 -0
- package/dist/readline.js +623 -0
- package/dist/utils.d.ts +4 -35
- package/dist/utils.js +8 -73
- package/dist/vfs/acl.d.ts +42 -0
- package/dist/vfs/acl.js +249 -0
- package/dist/vfs/async.d.ts +7 -21
- package/dist/vfs/async.js +19 -19
- 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 +9 -8
- package/dist/vfs/file.d.ts +106 -0
- package/dist/vfs/file.js +235 -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 +87 -0
- package/dist/vfs/ioctl.js +304 -0
- package/dist/vfs/promises.d.ts +78 -16
- package/dist/vfs/promises.js +273 -122
- package/dist/vfs/shared.d.ts +7 -26
- package/dist/vfs/shared.js +25 -53
- 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 +24 -19
- package/dist/vfs/sync.d.ts +4 -3
- package/dist/vfs/sync.js +143 -128
- package/dist/vfs/watchers.d.ts +2 -2
- package/dist/vfs/watchers.js +6 -6
- package/dist/vfs/xattr.d.ts +116 -0
- package/dist/vfs/xattr.js +218 -0
- package/package.json +3 -3
- package/readme.md +1 -1
- package/tests/backend/config.worker.js +4 -1
- package/tests/backend/fetch.test.ts +3 -0
- package/tests/backend/port.test.ts +21 -35
- package/tests/backend/remote.worker.js +4 -1
- package/tests/backend/single-buffer.test.ts +24 -0
- package/tests/common/context.test.ts +1 -1
- package/tests/common/handle.test.ts +17 -12
- 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 +1 -1
- package/tests/fs/links.test.ts +1 -1
- package/tests/fs/permissions.test.ts +7 -6
- package/tests/fs/readFile.test.ts +3 -3
- package/tests/fs/stat.test.ts +6 -6
- package/tests/fs/streams.test.ts +2 -11
- package/tests/fs/times.test.ts +1 -1
- 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 +1 -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/vfs/shared.d.ts
CHANGED
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
import type * as fs from 'node:fs';
|
|
2
|
-
import type { File } from '../internal/file.js';
|
|
3
2
|
import type { FileSystem } from '../internal/filesystem.js';
|
|
4
|
-
import type {
|
|
5
|
-
import { type BoundContext, type V_Context } from '../context.js';
|
|
3
|
+
import type { V_Context } from '../context.js';
|
|
6
4
|
import { ErrnoError } from '../internal/error.js';
|
|
7
|
-
import {
|
|
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;
|
|
5
|
+
import type { InodeLike } from '../internal/inode.js';
|
|
6
|
+
import { type AbsolutePath } from '../path.js';
|
|
20
7
|
/**
|
|
21
8
|
* @internal @hidden
|
|
22
9
|
*/
|
|
@@ -32,12 +19,12 @@ export declare const mounts: Map<string, FileSystem>;
|
|
|
32
19
|
* @category Backends and Configuration
|
|
33
20
|
* @internal
|
|
34
21
|
*/
|
|
35
|
-
export declare function mount(mountPoint: string, fs: FileSystem): void;
|
|
22
|
+
export declare function mount(this: V_Context, mountPoint: string, fs: FileSystem): void;
|
|
36
23
|
/**
|
|
37
24
|
* Unmounts the file system at `mountPoint`.
|
|
38
25
|
* @category Backends and Configuration
|
|
39
26
|
*/
|
|
40
|
-
export declare function umount(mountPoint: string): void;
|
|
27
|
+
export declare function umount(this: V_Context, mountPoint: string): void;
|
|
41
28
|
/**
|
|
42
29
|
* @internal @hidden
|
|
43
30
|
*/
|
|
@@ -54,7 +41,7 @@ export interface ResolvedPath extends ResolvedMount {
|
|
|
54
41
|
/** The real, absolute path */
|
|
55
42
|
fullPath: string;
|
|
56
43
|
/** Stats */
|
|
57
|
-
stats?:
|
|
44
|
+
stats?: InodeLike;
|
|
58
45
|
}
|
|
59
46
|
/**
|
|
60
47
|
* Gets the internal `FileSystem` for the path, then returns it along with the path relative to the FS' root
|
|
@@ -71,18 +58,12 @@ export declare function fixPaths(text: string, paths: Record<string, string>): s
|
|
|
71
58
|
* @internal @hidden
|
|
72
59
|
*/
|
|
73
60
|
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
61
|
/**
|
|
79
62
|
* @internal @hidden
|
|
80
63
|
*/
|
|
81
64
|
export declare function _statfs<const T extends boolean>(fs: FileSystem, bigint?: T): T extends true ? fs.BigIntStatsFs : fs.StatsFs;
|
|
82
65
|
/**
|
|
83
66
|
* 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
67
|
* @category Backends and Configuration
|
|
86
68
|
*/
|
|
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;
|
|
69
|
+
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
2
|
import { InMemory } from '../backends/memory.js';
|
|
3
|
-
import {
|
|
3
|
+
import { defaultContext } from '../internal/contexts.js';
|
|
4
4
|
import { Errno, ErrnoError } from '../internal/error.js';
|
|
5
|
-
import { alert, debug, err, info,
|
|
5
|
+
import { alert, debug, err, info, notice, warn } from '../internal/log.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,7 +22,7 @@ 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
27
|
throw err(new ErrnoError(Errno.EINVAL, 'Mount point is already in use: ' + mountPoint));
|
|
51
28
|
fs._mountPoint = 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) {
|
|
@@ -115,20 +92,6 @@ export function fixError(e, paths) {
|
|
|
115
92
|
e.path = fixPaths(e.path, paths);
|
|
116
93
|
return e;
|
|
117
94
|
}
|
|
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
95
|
/**
|
|
133
96
|
* @internal @hidden
|
|
134
97
|
*/
|
|
@@ -136,7 +99,7 @@ export function _statfs(fs, bigint) {
|
|
|
136
99
|
const md = fs.usage();
|
|
137
100
|
const bs = md.blockSize || 4096;
|
|
138
101
|
return {
|
|
139
|
-
type: (bigint ? BigInt : Number)(fs.
|
|
102
|
+
type: (bigint ? BigInt : Number)(fs.type),
|
|
140
103
|
bsize: (bigint ? BigInt : Number)(bs),
|
|
141
104
|
ffree: (bigint ? BigInt : Number)(md.freeNodes || size_max),
|
|
142
105
|
files: (bigint ? BigInt : Number)(md.totalNodes || size_max),
|
|
@@ -145,16 +108,25 @@ export function _statfs(fs, bigint) {
|
|
|
145
108
|
blocks: (bigint ? BigInt : Number)(md.totalSpace / bs),
|
|
146
109
|
};
|
|
147
110
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Change the root path
|
|
113
|
+
* @category Backends and Configuration
|
|
114
|
+
*/
|
|
115
|
+
export function chroot(path) {
|
|
116
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
117
|
+
const $ = this !== null && this !== void 0 ? this : defaultContext;
|
|
118
|
+
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)
|
|
151
119
|
throw new ErrnoError(Errno.EPERM, 'Can not chroot() as non-root user');
|
|
120
|
+
(_e = $.root) !== null && _e !== void 0 ? _e : ($.root = '/');
|
|
121
|
+
const newRoot = join($.root, path);
|
|
122
|
+
for (const handle of (_g = (_f = $.descriptors) === null || _f === void 0 ? void 0 : _f.values()) !== null && _g !== void 0 ? _g : []) {
|
|
123
|
+
if (!handle.path.startsWith($.root))
|
|
124
|
+
throw ErrnoError.With('EBUSY', handle.path, 'chroot');
|
|
125
|
+
handle.path = handle.path.slice($.root.length);
|
|
152
126
|
}
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
return bindContext(join((this === null || this === void 0 ? void 0 : this.root) || '/', path), creds);
|
|
127
|
+
if (newRoot.length > $.root.length)
|
|
128
|
+
throw new ErrnoError(Errno.EPERM, 'Can not chroot() outside of current root');
|
|
129
|
+
$.root = newRoot;
|
|
158
130
|
}
|
|
159
131
|
/**
|
|
160
132
|
* @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
|
@@ -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 ErrnoError(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 {
|
|
@@ -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
|
})
|
package/dist/vfs/sync.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type * as fs from 'node:fs';
|
|
2
2
|
import type { V_Context } from '../context.js';
|
|
3
|
-
import
|
|
3
|
+
import { Stats } from './stats.js';
|
|
4
4
|
import type { FileContents, NullEnc, ReaddirOptions, ReaddirOptsI, ReaddirOptsU } from './types.js';
|
|
5
5
|
import { Buffer } from 'buffer';
|
|
6
|
-
import { BigIntStats } from '../stats.js';
|
|
7
6
|
import { Dir, Dirent } from './dir.js';
|
|
7
|
+
import { BigIntStats } from './stats.js';
|
|
8
8
|
export declare function renameSync(this: V_Context, oldPath: fs.PathLike, newPath: fs.PathLike): void;
|
|
9
9
|
/**
|
|
10
10
|
* Test whether or not `path` exists by checking with the file system.
|
|
@@ -31,7 +31,8 @@ export declare function truncateSync(this: V_Context, path: fs.PathLike, len?: n
|
|
|
31
31
|
export declare function unlinkSync(this: V_Context, path: fs.PathLike): void;
|
|
32
32
|
/**
|
|
33
33
|
* Synchronous file open.
|
|
34
|
-
* @see
|
|
34
|
+
* @see https://nodejs.org/api/fs.html#fsopensyncpath-flags-mode
|
|
35
|
+
* @param flag {@link https://nodejs.org/api/fs.html#file-system-flags}
|
|
35
36
|
*/
|
|
36
37
|
export declare function openSync(this: V_Context, path: fs.PathLike, flag: fs.OpenMode, mode?: fs.Mode | null): number;
|
|
37
38
|
/**
|