@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.
Files changed (135) hide show
  1. package/dist/backends/backend.d.ts +19 -15
  2. package/dist/backends/backend.js +36 -19
  3. package/dist/backends/cow.d.ts +20 -30
  4. package/dist/backends/cow.js +83 -192
  5. package/dist/backends/fetch.d.ts +1 -0
  6. package/dist/backends/fetch.js +30 -30
  7. package/dist/backends/index.d.ts +1 -1
  8. package/dist/backends/index.js +1 -1
  9. package/dist/backends/memory.d.ts +5 -7
  10. package/dist/backends/memory.js +2 -3
  11. package/dist/backends/passthrough.d.ts +19 -23
  12. package/dist/backends/passthrough.js +98 -288
  13. package/dist/backends/port.d.ts +220 -0
  14. package/dist/backends/port.js +328 -0
  15. package/dist/backends/single_buffer.d.ts +59 -47
  16. package/dist/backends/single_buffer.js +468 -219
  17. package/dist/backends/store/fs.d.ts +25 -35
  18. package/dist/backends/store/fs.js +276 -315
  19. package/dist/backends/store/store.d.ts +10 -15
  20. package/dist/backends/store/store.js +11 -10
  21. package/dist/config.d.ts +3 -12
  22. package/dist/config.js +17 -19
  23. package/dist/context.d.ts +8 -21
  24. package/dist/context.js +33 -10
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +2 -1
  27. package/dist/internal/contexts.d.ts +63 -0
  28. package/dist/internal/contexts.js +15 -0
  29. package/dist/internal/credentials.d.ts +2 -11
  30. package/dist/internal/credentials.js +0 -19
  31. package/dist/internal/devices.d.ts +18 -80
  32. package/dist/internal/devices.js +103 -316
  33. package/dist/internal/error.d.ts +9 -204
  34. package/dist/internal/error.js +19 -288
  35. package/dist/internal/file_index.d.ts +1 -1
  36. package/dist/internal/file_index.js +11 -11
  37. package/dist/internal/filesystem.d.ts +51 -94
  38. package/dist/internal/filesystem.js +21 -20
  39. package/dist/internal/index.d.ts +1 -2
  40. package/dist/internal/index.js +1 -2
  41. package/dist/internal/index_fs.d.ts +12 -30
  42. package/dist/internal/index_fs.js +37 -69
  43. package/dist/internal/inode.d.ts +140 -24
  44. package/dist/internal/inode.js +515 -66
  45. package/dist/mixins/async.js +52 -112
  46. package/dist/mixins/mutexed.d.ts +19 -18
  47. package/dist/mixins/mutexed.js +62 -64
  48. package/dist/mixins/readonly.d.ts +7 -6
  49. package/dist/mixins/readonly.js +24 -18
  50. package/dist/mixins/sync.js +8 -8
  51. package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
  52. package/dist/{vfs/path.js → path.js} +6 -9
  53. package/dist/polyfills.js +1 -1
  54. package/dist/readline.d.ts +134 -0
  55. package/dist/readline.js +623 -0
  56. package/dist/utils.d.ts +9 -37
  57. package/dist/utils.js +17 -85
  58. package/dist/vfs/acl.d.ts +42 -0
  59. package/dist/vfs/acl.js +268 -0
  60. package/dist/vfs/async.d.ts +9 -23
  61. package/dist/vfs/async.js +25 -27
  62. package/dist/vfs/config.d.ts +6 -18
  63. package/dist/vfs/config.js +8 -18
  64. package/dist/vfs/dir.d.ts +3 -3
  65. package/dist/vfs/dir.js +12 -12
  66. package/dist/vfs/file.d.ts +106 -0
  67. package/dist/vfs/file.js +244 -0
  68. package/dist/vfs/flags.d.ts +19 -0
  69. package/dist/vfs/flags.js +62 -0
  70. package/dist/vfs/index.d.ts +4 -10
  71. package/dist/vfs/index.js +4 -13
  72. package/dist/vfs/ioctl.d.ts +88 -0
  73. package/dist/vfs/ioctl.js +409 -0
  74. package/dist/vfs/promises.d.ts +81 -19
  75. package/dist/vfs/promises.js +404 -288
  76. package/dist/vfs/shared.d.ts +7 -37
  77. package/dist/vfs/shared.js +29 -85
  78. package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
  79. package/dist/{stats.js → vfs/stats.js} +11 -66
  80. package/dist/vfs/streams.d.ts +1 -0
  81. package/dist/vfs/streams.js +32 -27
  82. package/dist/vfs/sync.d.ts +3 -3
  83. package/dist/vfs/sync.js +263 -260
  84. package/dist/vfs/watchers.d.ts +2 -2
  85. package/dist/vfs/watchers.js +12 -12
  86. package/dist/vfs/xattr.d.ts +116 -0
  87. package/dist/vfs/xattr.js +201 -0
  88. package/package.json +5 -3
  89. package/readme.md +1 -1
  90. package/scripts/test.js +2 -2
  91. package/tests/assignment.ts +1 -1
  92. package/tests/backend/config.worker.js +4 -1
  93. package/tests/backend/fetch.test.ts +3 -0
  94. package/tests/backend/port.test.ts +19 -33
  95. package/tests/backend/remote.worker.js +4 -1
  96. package/tests/backend/single-buffer.test.ts +53 -0
  97. package/tests/backend/single-buffer.worker.js +30 -0
  98. package/tests/common/context.test.ts +3 -3
  99. package/tests/common/handle.test.ts +17 -12
  100. package/tests/common/mutex.test.ts +9 -9
  101. package/tests/common/path.test.ts +1 -1
  102. package/tests/common/readline.test.ts +104 -0
  103. package/tests/common.ts +4 -19
  104. package/tests/fetch/fetch.ts +2 -2
  105. package/tests/fs/append.test.ts +4 -4
  106. package/tests/fs/directory.test.ts +25 -25
  107. package/tests/fs/errors.test.ts +15 -19
  108. package/tests/fs/links.test.ts +4 -3
  109. package/tests/fs/open.test.ts +4 -21
  110. package/tests/fs/permissions.test.ts +14 -18
  111. package/tests/fs/read.test.ts +10 -9
  112. package/tests/fs/readFile.test.ts +10 -26
  113. package/tests/fs/rename.test.ts +4 -9
  114. package/tests/fs/stat.test.ts +8 -8
  115. package/tests/fs/streams.test.ts +2 -11
  116. package/tests/fs/times.test.ts +7 -7
  117. package/tests/fs/truncate.test.ts +8 -36
  118. package/tests/fs/watch.test.ts +10 -10
  119. package/tests/fs/write.test.ts +77 -13
  120. package/tests/fs/xattr.test.ts +85 -0
  121. package/tests/logs.js +22 -0
  122. package/tests/setup/context.ts +1 -1
  123. package/tests/setup/index.ts +3 -3
  124. package/tests/setup/port.ts +7 -1
  125. package/dist/backends/port/fs.d.ts +0 -84
  126. package/dist/backends/port/fs.js +0 -151
  127. package/dist/backends/port/rpc.d.ts +0 -77
  128. package/dist/backends/port/rpc.js +0 -100
  129. package/dist/backends/store/simple.d.ts +0 -20
  130. package/dist/backends/store/simple.js +0 -13
  131. package/dist/internal/file.d.ts +0 -359
  132. package/dist/internal/file.js +0 -751
  133. package/dist/internal/log.d.ts +0 -133
  134. package/dist/internal/log.js +0 -218
  135. package/tests/fs/writeFile.test.ts +0 -70
@@ -1,22 +1,8 @@
1
1
  import type * as fs from 'node:fs';
2
- import type { File } from '../internal/file.js';
2
+ import type { V_Context } from '../context.js';
3
3
  import type { FileSystem } from '../internal/filesystem.js';
4
- import type { Stats } from '../stats.js';
5
- import { type BoundContext, type V_Context } from '../context.js';
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?: 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, inPlace?: false): BoundContext;
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;
@@ -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 { bindContext } from '../context.js';
4
- import { Errno, ErrnoError } from '../internal/error.js';
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({ name: 'root' }));
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(new ErrnoError(Errno.EINVAL, 'Mount point is already in use: ' + mountPoint));
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 ErrnoError(Errno.EIO, 'No file system', path));
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.id),
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
- export function chroot(path, inPlace) {
149
- const creds = this === null || this === void 0 ? void 0 : this.credentials;
150
- if ((creds === null || creds === void 0 ? void 0 : creds.uid) && (creds === null || creds === void 0 ? void 0 : creds.gid) && (creds === null || creds === void 0 ? void 0 : creds.euid) && (creds === null || creds === void 0 ? void 0 : creds.egid)) {
151
- throw new ErrnoError(Errno.EPERM, 'Can not chroot() as non-root user');
152
- }
153
- if (inPlace && this) {
154
- this.root += path;
155
- return this;
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
- return bindContext(join((this === null || this === void 0 ? void 0 : this.root) || '/', path), creds);
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 './context.js';
3
- import type { InodeFields, InodeLike } from './internal/inode.js';
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<InodeLike>);
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): void;
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 { credentials } from './internal/credentials.js';
3
- import { _inode_fields } from './internal/inode.js';
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
- const creds = (context === null || context === void 0 ? void 0 : context.credentials) || credentials;
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
- if (!isNaN(uid) && 0 <= uid && uid < c.size_max) {
138
+ let valid = true;
139
+ if (!isNaN(uid) && uid >= 0 && uid < c.size_max)
198
140
  stats.uid = uid;
199
- }
200
- if (!isNaN(gid) && 0 <= gid && gid < 2 ** 32) {
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`.
@@ -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;
@@ -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(({ file }) => {
16
- this._path = file.path;
17
- const internal = file.streamRead({ start: opts.start, end: opts.end });
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 => this.destroy(err));
21
+ .catch(err => {
22
+ this.destroy(err);
23
+ });
23
24
  }
24
25
  async _read() {
25
- if (!this.reader)
26
- return;
27
- const { done, value } = await this.reader.read();
28
- if (done) {
29
- this.push(null);
30
- return;
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 ErrnoError(Errno.EIO, err.toString()));
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(({ file }) => {
69
- this._path = file.path;
70
- const internal = file.streamWrite({ start: opts.start });
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(new ErrnoError(Errno.EAGAIN, 'Underlying writable stream not ready', this._path)));
84
+ return callback(warn(UV('EAGAIN', 'write', this._path)));
80
85
  if (encoding != 'buffer')
81
- return callback(warn(new ErrnoError(Errno.ENOTSUP, 'Unsupported encoding for stream', this._path)));
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 ErrnoError(Errno.EIO, error.toString()));
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 ErrnoError(Errno.EIO, error.toString()));
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 ErrnoError(Errno.EIO, error.toString()));
116
+ callback(new Exception(Errno.EIO, error.toString()));
112
117
  }
113
118
  }
114
119
  get path() {
@@ -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 http://www.manpagez.com/man/2/open/
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
  /**