@zenfs/core 0.9.6 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backends/AsyncStore.d.ts +3 -2
- package/dist/backends/AsyncStore.js +40 -33
- package/dist/backends/Fetch.d.ts +84 -0
- package/dist/backends/Fetch.js +171 -0
- package/dist/backends/InMemory.d.ts +1 -1
- package/dist/backends/Index.d.ts +7 -10
- package/dist/backends/Index.js +26 -24
- package/dist/backends/Locked.d.ts +11 -11
- package/dist/backends/Locked.js +50 -49
- package/dist/backends/Overlay.js +22 -22
- package/dist/backends/SyncStore.d.ts +6 -6
- package/dist/backends/SyncStore.js +30 -30
- package/dist/backends/backend.d.ts +5 -4
- package/dist/backends/backend.js +6 -6
- package/dist/backends/port/fs.d.ts +124 -0
- package/dist/backends/port/fs.js +241 -0
- package/dist/backends/port/rpc.d.ts +60 -0
- package/dist/backends/port/rpc.js +71 -0
- package/dist/backends/port/store.d.ts +30 -0
- package/dist/backends/port/store.js +142 -0
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/config.d.ts +9 -11
- package/dist/config.js +13 -13
- package/dist/emulation/async.d.ts +76 -77
- package/dist/emulation/async.js +45 -45
- package/dist/emulation/dir.js +8 -7
- package/dist/emulation/index.d.ts +1 -1
- package/dist/emulation/index.js +1 -1
- package/dist/emulation/path.d.ts +3 -2
- package/dist/emulation/path.js +19 -45
- package/dist/emulation/promises.d.ts +112 -113
- package/dist/emulation/promises.js +167 -173
- package/dist/emulation/shared.d.ts +6 -17
- package/dist/emulation/shared.js +9 -9
- package/dist/emulation/streams.js +3 -2
- package/dist/emulation/sync.d.ts +71 -64
- package/dist/emulation/sync.js +62 -63
- package/dist/{ApiError.d.ts → error.d.ts} +15 -15
- package/dist/error.js +292 -0
- package/dist/file.d.ts +6 -4
- package/dist/file.js +17 -9
- package/dist/filesystem.d.ts +1 -1
- package/dist/filesystem.js +18 -15
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/mutex.js +4 -3
- package/dist/stats.d.ts +7 -7
- package/dist/stats.js +50 -10
- package/dist/utils.d.ts +10 -9
- package/dist/utils.js +15 -15
- package/package.json +5 -5
- package/readme.md +19 -11
- package/src/backends/AsyncStore.ts +42 -36
- package/src/backends/Fetch.ts +230 -0
- package/src/backends/Index.ts +33 -29
- package/src/backends/Locked.ts +50 -49
- package/src/backends/Overlay.ts +24 -24
- package/src/backends/SyncStore.ts +34 -34
- package/src/backends/backend.ts +13 -11
- package/src/backends/port/fs.ts +308 -0
- package/src/backends/port/readme.md +59 -0
- package/src/backends/port/rpc.ts +144 -0
- package/src/backends/port/store.ts +187 -0
- package/src/config.ts +25 -29
- package/src/emulation/async.ts +191 -199
- package/src/emulation/dir.ts +8 -8
- package/src/emulation/index.ts +1 -1
- package/src/emulation/path.ts +25 -49
- package/src/emulation/promises.ts +286 -287
- package/src/emulation/shared.ts +14 -23
- package/src/emulation/streams.ts +9 -8
- package/src/emulation/sync.ts +182 -182
- package/src/{ApiError.ts → error.ts} +91 -89
- package/src/file.ts +23 -13
- package/src/filesystem.ts +26 -22
- package/src/index.ts +4 -1
- package/src/mutex.ts +6 -4
- package/src/stats.ts +32 -23
- package/src/utils.ts +23 -24
- package/tsconfig.json +4 -3
- package/dist/ApiError.js +0 -292
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
|
-
import type * as
|
|
2
|
+
import type * as fs from 'node:fs';
|
|
3
3
|
import type * as promises from 'node:fs/promises';
|
|
4
4
|
import type { CreateReadStreamOptions, CreateWriteStreamOptions, FileChangeInfo, FileReadResult, FlagAndOpenMode } from 'node:fs/promises';
|
|
5
|
+
import type { Stream } from 'node:stream';
|
|
5
6
|
import type { ReadableStream as TReadableStream } from 'node:stream/web';
|
|
6
7
|
import type { Interface as ReadlineInterface } from 'readline';
|
|
7
|
-
import {
|
|
8
|
+
import type { ReadableStreamController } from 'stream/web';
|
|
9
|
+
import { ErrnoError, Errno } from '../error.js';
|
|
8
10
|
import { ActionType, File, isAppendable, isReadable, isWriteable, parseFlag, pathExistsAction, pathNotExistsAction } from '../file.js';
|
|
9
|
-
import { FileContents
|
|
11
|
+
import type { FileContents } from '../filesystem.js';
|
|
10
12
|
import { BigIntStats, FileType, type BigIntStatsFs, type Stats, type StatsFs } from '../stats.js';
|
|
11
13
|
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
|
|
12
14
|
import * as constants from './constants.js';
|
|
13
15
|
import { Dir, Dirent } from './dir.js';
|
|
14
16
|
import { dirname, join, parse } from './path.js';
|
|
15
|
-
import
|
|
16
|
-
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, resolveMount } from './shared.js';
|
|
17
|
+
import { cred, fd2file, fdMap, file2fd, fixError, mounts, resolveMount } from './shared.js';
|
|
17
18
|
import { ReadStream, WriteStream } from './streams.js';
|
|
18
19
|
export * as constants from './constants.js';
|
|
19
20
|
|
|
20
21
|
export class FileHandle implements promises.FileHandle {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
public readonly fd: number
|
|
26
|
-
) {}
|
|
22
|
+
/**
|
|
23
|
+
* The file descriptor for this file handle.
|
|
24
|
+
*/
|
|
25
|
+
public readonly fd: number;
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
28
|
* @internal
|
|
29
|
+
* The file for this file handle
|
|
30
30
|
*/
|
|
31
|
-
public
|
|
32
|
-
|
|
31
|
+
public readonly file: File;
|
|
32
|
+
|
|
33
|
+
public constructor(fdOrFile: number | File) {
|
|
34
|
+
const isFile = typeof fdOrFile != 'number';
|
|
35
|
+
this.fd = isFile ? file2fd(fdOrFile) : fdOrFile;
|
|
36
|
+
this.file = isFile ? fdOrFile : fd2file(fdOrFile);
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
/**
|
|
@@ -43,10 +47,10 @@ export class FileHandle implements promises.FileHandle {
|
|
|
43
47
|
* Asynchronous fchmod(2) - Change permissions of a file.
|
|
44
48
|
* @param mode A file mode. If a string is passed, it is parsed as an octal integer.
|
|
45
49
|
*/
|
|
46
|
-
public chmod(mode:
|
|
50
|
+
public chmod(mode: fs.Mode): Promise<void> {
|
|
47
51
|
const numMode = normalizeMode(mode, -1);
|
|
48
52
|
if (numMode < 0) {
|
|
49
|
-
throw new
|
|
53
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid mode.');
|
|
50
54
|
}
|
|
51
55
|
return this.file.chmod(numMode);
|
|
52
56
|
}
|
|
@@ -69,9 +73,10 @@ export class FileHandle implements promises.FileHandle {
|
|
|
69
73
|
* Asynchronous ftruncate(2) - Truncate a file to a specified length.
|
|
70
74
|
* @param len If not specified, defaults to `0`.
|
|
71
75
|
*/
|
|
72
|
-
public truncate(len?: number): Promise<void> {
|
|
76
|
+
public truncate(len?: number | null): Promise<void> {
|
|
77
|
+
len ||= 0;
|
|
73
78
|
if (len < 0) {
|
|
74
|
-
throw new
|
|
79
|
+
throw new ErrnoError(Errno.EINVAL);
|
|
75
80
|
}
|
|
76
81
|
return this.file.truncate(len);
|
|
77
82
|
}
|
|
@@ -95,16 +100,16 @@ export class FileHandle implements promises.FileHandle {
|
|
|
95
100
|
* If `mode` is a string, it is parsed as an octal integer.
|
|
96
101
|
* If `flag` is not supplied, the default of `'a'` is used.
|
|
97
102
|
*/
|
|
98
|
-
public async appendFile(data: string | Uint8Array, _options
|
|
103
|
+
public async appendFile(data: string | Uint8Array, _options: (fs.ObjectEncodingOptions & FlagAndOpenMode) | BufferEncoding = {}): Promise<void> {
|
|
99
104
|
const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
|
|
100
105
|
const flag = parseFlag(options.flag);
|
|
101
106
|
if (!isAppendable(flag)) {
|
|
102
|
-
throw new
|
|
107
|
+
throw new ErrnoError(Errno.EINVAL, 'Flag passed to appendFile must allow for appending.');
|
|
103
108
|
}
|
|
104
109
|
if (typeof data != 'string' && !options.encoding) {
|
|
105
|
-
throw new
|
|
110
|
+
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
106
111
|
}
|
|
107
|
-
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
112
|
+
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding!) : data;
|
|
108
113
|
await this.file.write(encodedData, 0, encodedData.length, null);
|
|
109
114
|
}
|
|
110
115
|
|
|
@@ -116,11 +121,11 @@ export class FileHandle implements promises.FileHandle {
|
|
|
116
121
|
* @param length The number of bytes to read.
|
|
117
122
|
* @param position The offset from the beginning of the file from which data should be read. If `null`, data will be read from the current position.
|
|
118
123
|
*/
|
|
119
|
-
public read<TBuffer extends NodeJS.ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<FileReadResult<TBuffer>> {
|
|
120
|
-
if (isNaN(+position)) {
|
|
121
|
-
position = this.file.position
|
|
124
|
+
public read<TBuffer extends NodeJS.ArrayBufferView>(buffer: TBuffer, offset?: number, length?: number, position?: number | null): Promise<FileReadResult<TBuffer>> {
|
|
125
|
+
if (isNaN(+position!)) {
|
|
126
|
+
position = this.file.position;
|
|
122
127
|
}
|
|
123
|
-
return this.file.read(buffer, offset, length, position);
|
|
128
|
+
return this.file.read(buffer, offset, length, position!);
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
/**
|
|
@@ -129,13 +134,13 @@ export class FileHandle implements promises.FileHandle {
|
|
|
129
134
|
* @param _options An object that may contain an optional flag.
|
|
130
135
|
* If a flag is not provided, it defaults to `'r'`.
|
|
131
136
|
*/
|
|
132
|
-
public async readFile(_options?: { flag?:
|
|
133
|
-
public async readFile(_options: (
|
|
134
|
-
public async readFile(_options?: (
|
|
137
|
+
public async readFile(_options?: { flag?: fs.OpenMode }): Promise<Buffer>;
|
|
138
|
+
public async readFile(_options: (fs.ObjectEncodingOptions & FlagAndOpenMode) | BufferEncoding): Promise<string>;
|
|
139
|
+
public async readFile(_options?: (fs.ObjectEncodingOptions & FlagAndOpenMode) | BufferEncoding): Promise<string | Buffer> {
|
|
135
140
|
const options = normalizeOptions(_options, null, 'r', 0o444);
|
|
136
141
|
const flag = parseFlag(options.flag);
|
|
137
142
|
if (!isReadable(flag)) {
|
|
138
|
-
throw new
|
|
143
|
+
throw new ErrnoError(Errno.EINVAL, 'Flag passed must allow for reading.');
|
|
139
144
|
}
|
|
140
145
|
|
|
141
146
|
const { size } = await this.stat();
|
|
@@ -156,18 +161,18 @@ export class FileHandle implements promises.FileHandle {
|
|
|
156
161
|
* @since v17.0.0
|
|
157
162
|
* @experimental
|
|
158
163
|
*/
|
|
159
|
-
public readableWebStream(options
|
|
164
|
+
public readableWebStream(options: promises.ReadableWebStreamOptions = {}): TReadableStream<Uint8Array> {
|
|
160
165
|
// Note: using an arrow function to preserve `this`
|
|
161
|
-
const start = async ({ close, enqueue, error }) => {
|
|
166
|
+
const start = async ({ close, enqueue, error }: ReadableStreamController<Uint8Array>) => {
|
|
162
167
|
try {
|
|
163
168
|
const chunkSize = 64 * 1024,
|
|
164
169
|
maxChunks = 1e7;
|
|
165
170
|
let i = 0,
|
|
166
171
|
position = 0,
|
|
167
|
-
|
|
172
|
+
bytesRead = NaN;
|
|
168
173
|
|
|
169
|
-
while (
|
|
170
|
-
result = await this.read(new Uint8Array(chunkSize), 0, chunkSize, position);
|
|
174
|
+
while (bytesRead > 0) {
|
|
175
|
+
const result = await this.read(new Uint8Array(chunkSize), 0, chunkSize, position);
|
|
171
176
|
if (!result.bytesRead) {
|
|
172
177
|
close();
|
|
173
178
|
return;
|
|
@@ -175,19 +180,20 @@ export class FileHandle implements promises.FileHandle {
|
|
|
175
180
|
enqueue(result.buffer.slice(0, result.bytesRead));
|
|
176
181
|
position += result.bytesRead;
|
|
177
182
|
if (++i >= maxChunks) {
|
|
178
|
-
throw new
|
|
183
|
+
throw new ErrnoError(Errno.EFBIG, 'Too many iterations on readable stream', this.file.path, 'FileHandle.readableWebStream');
|
|
179
184
|
}
|
|
185
|
+
bytesRead = result.bytesRead;
|
|
180
186
|
}
|
|
181
187
|
} catch (e) {
|
|
182
188
|
error(e);
|
|
183
189
|
}
|
|
184
190
|
};
|
|
185
191
|
|
|
186
|
-
return new globalThis.ReadableStream({ start, type: options.type });
|
|
192
|
+
return new (globalThis as any).ReadableStream({ start, type: options.type });
|
|
187
193
|
}
|
|
188
194
|
|
|
189
195
|
public readLines(options?: promises.CreateReadStreamOptions): ReadlineInterface {
|
|
190
|
-
throw
|
|
196
|
+
throw ErrnoError.With('ENOSYS', this.file.path, 'FileHandle.readLines');
|
|
191
197
|
}
|
|
192
198
|
|
|
193
199
|
public [Symbol.asyncDispose](): Promise<void> {
|
|
@@ -197,40 +203,34 @@ export class FileHandle implements promises.FileHandle {
|
|
|
197
203
|
/**
|
|
198
204
|
* Asynchronous fstat(2) - Get file status.
|
|
199
205
|
*/
|
|
200
|
-
public async stat(opts:
|
|
201
|
-
public async stat(opts?:
|
|
202
|
-
public async stat(opts?:
|
|
206
|
+
public async stat(opts: fs.BigIntOptions): Promise<BigIntStats>;
|
|
207
|
+
public async stat(opts?: fs.StatOptions & { bigint?: false }): Promise<Stats>;
|
|
208
|
+
public async stat(opts?: fs.StatOptions): Promise<Stats | BigIntStats> {
|
|
203
209
|
const stats = await this.file.stat();
|
|
204
210
|
return opts?.bigint ? new BigIntStats(stats) : stats;
|
|
205
211
|
}
|
|
206
212
|
|
|
207
|
-
public async write(data: FileContents, posOrOff?: number, lenOrEnc?: BufferEncoding | number, position?: number): Promise<{ bytesWritten: number; buffer: FileContents }>;
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Asynchronously writes `buffer` to the file.
|
|
211
|
-
* The `FileHandle` must have been opened for writing.
|
|
212
|
-
* @param buffer The buffer that the data will be written to.
|
|
213
|
-
* @param offset The part of the buffer to be written. If not supplied, defaults to `0`.
|
|
214
|
-
* @param length The number of bytes to write. If not supplied, defaults to `buffer.length - offset`.
|
|
215
|
-
* @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position.
|
|
216
|
-
*/
|
|
217
|
-
public async write<TBuffer extends Uint8Array>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{ bytesWritten: number; buffer: TBuffer }>;
|
|
218
|
-
|
|
219
213
|
/**
|
|
220
214
|
* Asynchronously writes `string` to the file.
|
|
221
215
|
* The `FileHandle` must have been opened for writing.
|
|
222
216
|
* It is unsafe to call `write()` multiple times on the same file without waiting for the `Promise`
|
|
223
217
|
* to be resolved (or rejected). For this scenario, `fs.createWriteStream` is strongly recommended.
|
|
224
|
-
* @param string A string to write.
|
|
225
|
-
* @param position The offset from the beginning of the file where this data should be written. If not supplied, defaults to the current position.
|
|
226
|
-
* @param encoding The expected string encoding.
|
|
227
218
|
*/
|
|
219
|
+
public async write(
|
|
220
|
+
data: FileContents,
|
|
221
|
+
posOrOff?: number | null,
|
|
222
|
+
lenOrEnc?: BufferEncoding | number,
|
|
223
|
+
position?: number | null
|
|
224
|
+
): Promise<{ bytesWritten: number; buffer: FileContents }>;
|
|
225
|
+
public async write<TBuffer extends Uint8Array>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{ bytesWritten: number; buffer: TBuffer }>;
|
|
228
226
|
public async write(data: string, position?: number, encoding?: BufferEncoding): Promise<{ bytesWritten: number; buffer: string }>;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
227
|
+
public async write(
|
|
228
|
+
data: FileContents,
|
|
229
|
+
posOrOff?: number,
|
|
230
|
+
lenOrEnc?: BufferEncoding | number,
|
|
231
|
+
position?: number | null
|
|
232
|
+
): Promise<{ bytesWritten: number; buffer: FileContents }> {
|
|
233
|
+
let buffer: Uint8Array, offset: number | null | undefined, length: number;
|
|
234
234
|
if (typeof data === 'string') {
|
|
235
235
|
// Signature 1: (fd, string, [position?, [encoding?]])
|
|
236
236
|
position = typeof posOrOff === 'number' ? posOrOff : null;
|
|
@@ -240,13 +240,12 @@ export class FileHandle implements promises.FileHandle {
|
|
|
240
240
|
length = buffer.length;
|
|
241
241
|
} else {
|
|
242
242
|
// Signature 2: (fd, buffer, offset, length, position?)
|
|
243
|
-
buffer = data;
|
|
243
|
+
buffer = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
244
244
|
offset = posOrOff;
|
|
245
245
|
length = lenOrEnc as number;
|
|
246
246
|
position = typeof position === 'number' ? position : null;
|
|
247
247
|
}
|
|
248
|
-
|
|
249
|
-
position ??= this.file.position!;
|
|
248
|
+
position ??= this.file.position;
|
|
250
249
|
const bytesWritten = await this.file.write(buffer, offset, length, position);
|
|
251
250
|
return { buffer, bytesWritten };
|
|
252
251
|
}
|
|
@@ -262,16 +261,16 @@ export class FileHandle implements promises.FileHandle {
|
|
|
262
261
|
* If `mode` is a string, it is parsed as an octal integer.
|
|
263
262
|
* If `flag` is not supplied, the default of `'w'` is used.
|
|
264
263
|
*/
|
|
265
|
-
public async writeFile(data: string | Uint8Array, _options
|
|
264
|
+
public async writeFile(data: string | Uint8Array, _options: fs.WriteFileOptions = {}): Promise<void> {
|
|
266
265
|
const options = normalizeOptions(_options, 'utf8', 'w', 0o644);
|
|
267
266
|
const flag = parseFlag(options.flag);
|
|
268
267
|
if (!isWriteable(flag)) {
|
|
269
|
-
throw new
|
|
268
|
+
throw new ErrnoError(Errno.EINVAL, 'Flag passed must allow for writing.');
|
|
270
269
|
}
|
|
271
270
|
if (typeof data != 'string' && !options.encoding) {
|
|
272
|
-
throw new
|
|
271
|
+
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
273
272
|
}
|
|
274
|
-
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
273
|
+
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding!) : data;
|
|
275
274
|
await this.file.write(encodedData, 0, encodedData.length, 0);
|
|
276
275
|
}
|
|
277
276
|
|
|
@@ -289,11 +288,11 @@ export class FileHandle implements promises.FileHandle {
|
|
|
289
288
|
* @param position The position in the file where to begin writing.
|
|
290
289
|
* @returns The number of bytes written.
|
|
291
290
|
*/
|
|
292
|
-
public async writev(buffers: Uint8Array[], position?: number): Promise<
|
|
291
|
+
public async writev(buffers: Uint8Array[], position?: number): Promise<fs.WriteVResult> {
|
|
293
292
|
let bytesWritten = 0;
|
|
294
293
|
|
|
295
294
|
for (const buffer of buffers) {
|
|
296
|
-
bytesWritten += (await this.write(buffer, 0, buffer.length, position + bytesWritten)).bytesWritten;
|
|
295
|
+
bytesWritten += (await this.write(buffer, 0, buffer.length, position! + bytesWritten)).bytesWritten;
|
|
297
296
|
}
|
|
298
297
|
|
|
299
298
|
return { bytesWritten, buffers };
|
|
@@ -305,11 +304,11 @@ export class FileHandle implements promises.FileHandle {
|
|
|
305
304
|
* @param position The position in the file where to begin reading.
|
|
306
305
|
* @returns The number of bytes read.
|
|
307
306
|
*/
|
|
308
|
-
public async readv(buffers: NodeJS.ArrayBufferView[], position?: number): Promise<
|
|
307
|
+
public async readv(buffers: NodeJS.ArrayBufferView[], position?: number): Promise<fs.ReadVResult> {
|
|
309
308
|
let bytesRead = 0;
|
|
310
309
|
|
|
311
310
|
for (const buffer of buffers) {
|
|
312
|
-
bytesRead += (await this.read(buffer, 0, buffer.byteLength, position + bytesRead)).bytesRead;
|
|
311
|
+
bytesRead += (await this.read(buffer, 0, buffer.byteLength, position! + bytesRead)).bytesRead;
|
|
313
312
|
}
|
|
314
313
|
|
|
315
314
|
return { bytesRead, buffers };
|
|
@@ -322,9 +321,9 @@ export class FileHandle implements promises.FileHandle {
|
|
|
322
321
|
* @returns A `ReadStream` object.
|
|
323
322
|
*/
|
|
324
323
|
public createReadStream(options?: CreateReadStreamOptions): ReadStream {
|
|
325
|
-
const
|
|
324
|
+
const stream = new ReadStream({
|
|
326
325
|
highWaterMark: options?.highWaterMark || 64 * 1024,
|
|
327
|
-
encoding: options
|
|
326
|
+
encoding: options!.encoding!,
|
|
328
327
|
|
|
329
328
|
read: async (size: number) => {
|
|
330
329
|
try {
|
|
@@ -332,12 +331,11 @@ export class FileHandle implements promises.FileHandle {
|
|
|
332
331
|
stream.push(!result.bytesRead ? null : result.buffer.slice(0, result.bytesRead)); // Push data or null for EOF
|
|
333
332
|
this.file.position += result.bytesRead;
|
|
334
333
|
} catch (error) {
|
|
335
|
-
stream.destroy(error);
|
|
334
|
+
stream.destroy(error as Error);
|
|
336
335
|
}
|
|
337
336
|
},
|
|
338
|
-
};
|
|
337
|
+
});
|
|
339
338
|
|
|
340
|
-
const stream = new ReadStream(streamOptions);
|
|
341
339
|
stream.path = this.file.path;
|
|
342
340
|
return stream;
|
|
343
341
|
}
|
|
@@ -358,7 +356,7 @@ export class FileHandle implements promises.FileHandle {
|
|
|
358
356
|
const { bytesWritten } = await this.write(chunk, null, encoding);
|
|
359
357
|
callback(bytesWritten == chunk.length ? null : new Error('Failed to write full chunk'));
|
|
360
358
|
} catch (error) {
|
|
361
|
-
callback(error);
|
|
359
|
+
callback(error as Error);
|
|
362
360
|
}
|
|
363
361
|
},
|
|
364
362
|
};
|
|
@@ -369,44 +367,12 @@ export class FileHandle implements promises.FileHandle {
|
|
|
369
367
|
}
|
|
370
368
|
}
|
|
371
369
|
|
|
372
|
-
type FileSystemMethod = {
|
|
373
|
-
[K in keyof FileSystem]: FileSystem[K] extends (...args) => unknown
|
|
374
|
-
? (name: K, resolveSymlinks: boolean, ...args: Parameters<FileSystem[K]>) => ReturnType<FileSystem[K]>
|
|
375
|
-
: never;
|
|
376
|
-
}[keyof FileSystem]; // https://stackoverflow.com/a/76335220/17637456
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Utility for FS ops. It handles
|
|
380
|
-
* - path normalization (for the first parameter to the FS op)
|
|
381
|
-
* - path translation for errors
|
|
382
|
-
* - FS/mount point resolution
|
|
383
|
-
*
|
|
384
|
-
* It can't be used for functions which may operate on multiple mounted FSs or paths (e.g. `rename`)
|
|
385
|
-
* @param name the function name
|
|
386
|
-
* @param resolveSymlinks whether to resolve symlinks
|
|
387
|
-
* @param args the rest of the parameters are passed to the FS function. Note that the first parameter is required to be a path
|
|
388
|
-
* @returns
|
|
389
|
-
*/
|
|
390
|
-
async function doOp<M extends FileSystemMethod, RT extends ReturnType<M> = ReturnType<M>>(...[name, resolveSymlinks, rawPath, ...args]: Parameters<M>): Promise<RT> {
|
|
391
|
-
rawPath = normalizePath(rawPath);
|
|
392
|
-
const _path = resolveSymlinks && (await exists(rawPath)) ? await realpath(rawPath) : rawPath;
|
|
393
|
-
const { fs, path } = resolveMount(_path);
|
|
394
|
-
try {
|
|
395
|
-
// @ts-expect-error 2556 (since ...args is not correctly picked up as being a tuple)
|
|
396
|
-
return fs[name](path, ...args) as Promise<RT>;
|
|
397
|
-
} catch (e) {
|
|
398
|
-
throw fixError(e, { [path]: rawPath });
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// fs.promises
|
|
403
|
-
|
|
404
370
|
/**
|
|
405
371
|
* Renames a file
|
|
406
372
|
* @param oldPath
|
|
407
373
|
* @param newPath
|
|
408
374
|
*/
|
|
409
|
-
export async function rename(oldPath: PathLike, newPath: PathLike): Promise<void> {
|
|
375
|
+
export async function rename(oldPath: fs.PathLike, newPath: fs.PathLike): Promise<void> {
|
|
410
376
|
oldPath = normalizePath(oldPath);
|
|
411
377
|
newPath = normalizePath(newPath);
|
|
412
378
|
const src = resolveMount(oldPath);
|
|
@@ -419,21 +385,21 @@ export async function rename(oldPath: PathLike, newPath: PathLike): Promise<void
|
|
|
419
385
|
await writeFile(newPath, await readFile(oldPath));
|
|
420
386
|
await unlink(oldPath);
|
|
421
387
|
} catch (e) {
|
|
422
|
-
throw fixError(e, { [src.path]: oldPath, [dst.path]: newPath });
|
|
388
|
+
throw fixError(e as Error, { [src.path]: oldPath, [dst.path]: newPath });
|
|
423
389
|
}
|
|
424
390
|
}
|
|
425
391
|
rename satisfies typeof promises.rename;
|
|
426
392
|
|
|
427
393
|
/**
|
|
428
394
|
* Test whether or not the given path exists by checking with the file system.
|
|
429
|
-
* @param
|
|
395
|
+
* @param path
|
|
430
396
|
*/
|
|
431
|
-
export async function exists(
|
|
397
|
+
export async function exists(path: fs.PathLike): Promise<boolean> {
|
|
432
398
|
try {
|
|
433
|
-
const { fs, path } = resolveMount(await realpath(
|
|
434
|
-
return await fs.exists(
|
|
399
|
+
const { fs, path: resolved } = resolveMount(await realpath(path));
|
|
400
|
+
return await fs.exists(resolved, cred);
|
|
435
401
|
} catch (e) {
|
|
436
|
-
if (
|
|
402
|
+
if (e instanceof ErrnoError && e.code == 'ENOENT') {
|
|
437
403
|
return false;
|
|
438
404
|
}
|
|
439
405
|
|
|
@@ -446,12 +412,18 @@ export async function exists(_path: PathLike): Promise<boolean> {
|
|
|
446
412
|
* @param path
|
|
447
413
|
* @returns Stats
|
|
448
414
|
*/
|
|
449
|
-
export async function stat(path: PathLike, options:
|
|
450
|
-
export async function stat(path: PathLike, options?: { bigint?: false }): Promise<Stats>;
|
|
451
|
-
export async function stat(path: PathLike, options?:
|
|
452
|
-
export async function stat(path: PathLike, options?:
|
|
453
|
-
|
|
454
|
-
|
|
415
|
+
export async function stat(path: fs.PathLike, options: fs.BigIntOptions): Promise<BigIntStats>;
|
|
416
|
+
export async function stat(path: fs.PathLike, options?: { bigint?: false }): Promise<Stats>;
|
|
417
|
+
export async function stat(path: fs.PathLike, options?: fs.StatOptions): Promise<Stats | BigIntStats>;
|
|
418
|
+
export async function stat(path: fs.PathLike, options?: fs.StatOptions): Promise<Stats | BigIntStats> {
|
|
419
|
+
path = normalizePath(path);
|
|
420
|
+
const { fs, path: resolved } = resolveMount((await exists(path)) ? await realpath(path) : path);
|
|
421
|
+
try {
|
|
422
|
+
const stats = await fs.stat(resolved, cred);
|
|
423
|
+
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
424
|
+
} catch (e) {
|
|
425
|
+
throw fixError(e as Error, { [resolved]: path });
|
|
426
|
+
}
|
|
455
427
|
}
|
|
456
428
|
stat satisfies typeof promises.stat;
|
|
457
429
|
|
|
@@ -462,11 +434,17 @@ stat satisfies typeof promises.stat;
|
|
|
462
434
|
* @param path
|
|
463
435
|
* @return
|
|
464
436
|
*/
|
|
465
|
-
export async function lstat(path: PathLike, options?: { bigint?:
|
|
466
|
-
export async function lstat(path: PathLike, options: { bigint: true }): Promise<BigIntStats>;
|
|
467
|
-
export async function lstat(path: PathLike, options?:
|
|
468
|
-
|
|
469
|
-
|
|
437
|
+
export async function lstat(path: fs.PathLike, options?: { bigint?: boolean }): Promise<Stats>;
|
|
438
|
+
export async function lstat(path: fs.PathLike, options: { bigint: true }): Promise<BigIntStats>;
|
|
439
|
+
export async function lstat(path: fs.PathLike, options?: fs.StatOptions): Promise<Stats | BigIntStats> {
|
|
440
|
+
path = normalizePath(path);
|
|
441
|
+
const { fs, path: resolved } = resolveMount(path);
|
|
442
|
+
try {
|
|
443
|
+
const stats = await fs.stat(resolved, cred);
|
|
444
|
+
return options?.bigint ? new BigIntStats(stats) : stats;
|
|
445
|
+
} catch (e) {
|
|
446
|
+
throw fixError(e as Error, { [resolved]: path });
|
|
447
|
+
}
|
|
470
448
|
}
|
|
471
449
|
lstat satisfies typeof promises.lstat;
|
|
472
450
|
|
|
@@ -477,7 +455,7 @@ lstat satisfies typeof promises.lstat;
|
|
|
477
455
|
* @param path
|
|
478
456
|
* @param len
|
|
479
457
|
*/
|
|
480
|
-
export async function truncate(path: PathLike, len: number = 0): Promise<void> {
|
|
458
|
+
export async function truncate(path: fs.PathLike, len: number = 0): Promise<void> {
|
|
481
459
|
const handle = await open(path, 'r+');
|
|
482
460
|
try {
|
|
483
461
|
await handle.truncate(len);
|
|
@@ -491,8 +469,14 @@ truncate satisfies typeof promises.truncate;
|
|
|
491
469
|
* `unlink`.
|
|
492
470
|
* @param path
|
|
493
471
|
*/
|
|
494
|
-
export async function unlink(path: PathLike): Promise<void> {
|
|
495
|
-
|
|
472
|
+
export async function unlink(path: fs.PathLike): Promise<void> {
|
|
473
|
+
path = normalizePath(path);
|
|
474
|
+
const { fs, path: resolved } = resolveMount(path);
|
|
475
|
+
try {
|
|
476
|
+
await fs.unlink(resolved, cred);
|
|
477
|
+
} catch (e) {
|
|
478
|
+
throw fixError(e as Error, { [resolved]: path });
|
|
479
|
+
}
|
|
496
480
|
}
|
|
497
481
|
unlink satisfies typeof promises.unlink;
|
|
498
482
|
|
|
@@ -500,15 +484,18 @@ unlink satisfies typeof promises.unlink;
|
|
|
500
484
|
* Opens a file. This helper handles the complexity of file flags.
|
|
501
485
|
* @internal
|
|
502
486
|
*/
|
|
503
|
-
async function _open(
|
|
504
|
-
|
|
505
|
-
|
|
487
|
+
async function _open(path: fs.PathLike, _flag: fs.OpenMode, _mode: fs.Mode = 0o644, resolveSymlinks: boolean): Promise<FileHandle> {
|
|
488
|
+
path = normalizePath(path);
|
|
489
|
+
const mode = normalizeMode(_mode, 0o644),
|
|
506
490
|
flag = parseFlag(_flag);
|
|
507
491
|
|
|
492
|
+
path = resolveSymlinks && (await exists(path)) ? await realpath(path) : path;
|
|
493
|
+
const { fs, path: resolved } = resolveMount(path);
|
|
494
|
+
|
|
508
495
|
try {
|
|
509
496
|
switch (pathExistsAction(flag)) {
|
|
510
497
|
case ActionType.THROW:
|
|
511
|
-
throw
|
|
498
|
+
throw ErrnoError.With('EEXIST', path, '_open');
|
|
512
499
|
case ActionType.TRUNCATE:
|
|
513
500
|
/*
|
|
514
501
|
In a previous implementation, we deleted the file and
|
|
@@ -516,32 +503,29 @@ async function _open(_path: PathLike, _flag: string, _mode: Node.Mode = 0o644, r
|
|
|
516
503
|
asynchronous request was trying to read the file, as the file
|
|
517
504
|
would not exist for a small period of time.
|
|
518
505
|
*/
|
|
519
|
-
const file: File = await
|
|
520
|
-
if (!file) {
|
|
521
|
-
throw new ApiError(ErrorCode.EIO, 'Impossible code path reached');
|
|
522
|
-
}
|
|
506
|
+
const file: File = await fs.openFile(resolved, flag, cred);
|
|
523
507
|
await file.truncate(0);
|
|
524
508
|
await file.sync();
|
|
525
|
-
return file;
|
|
509
|
+
return new FileHandle(file);
|
|
526
510
|
case ActionType.NOP:
|
|
527
511
|
// Must await so thrown errors are caught by the catch below
|
|
528
|
-
return await
|
|
512
|
+
return new FileHandle(await fs.openFile(resolved, flag, cred));
|
|
529
513
|
default:
|
|
530
|
-
throw new
|
|
514
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid file flag');
|
|
531
515
|
}
|
|
532
516
|
} catch (e) {
|
|
533
517
|
switch (pathNotExistsAction(flag)) {
|
|
534
518
|
case ActionType.CREATE:
|
|
535
519
|
// Ensure parent exists.
|
|
536
|
-
const parentStats: Stats = await
|
|
520
|
+
const parentStats: Stats = await fs.stat(dirname(resolved), cred);
|
|
537
521
|
if (parentStats && !parentStats.isDirectory()) {
|
|
538
|
-
throw
|
|
522
|
+
throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
|
|
539
523
|
}
|
|
540
|
-
return await
|
|
524
|
+
return new FileHandle(await fs.createFile(resolved, flag, mode, cred));
|
|
541
525
|
case ActionType.THROW:
|
|
542
|
-
throw
|
|
526
|
+
throw ErrnoError.With('ENOENT', path, '_open');
|
|
543
527
|
default:
|
|
544
|
-
throw new
|
|
528
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid file flag');
|
|
545
529
|
}
|
|
546
530
|
}
|
|
547
531
|
}
|
|
@@ -552,39 +536,11 @@ async function _open(_path: PathLike, _flag: string, _mode: Node.Mode = 0o644, r
|
|
|
552
536
|
* @param flags Handles the complexity of the various file modes. See its API for more details.
|
|
553
537
|
* @param mode Mode to use to open the file. Can be ignored if the filesystem doesn't support permissions.
|
|
554
538
|
*/
|
|
555
|
-
export async function open(path: PathLike, flag:
|
|
556
|
-
|
|
557
|
-
return new FileHandle(getFdForFile(file));
|
|
539
|
+
export async function open(path: fs.PathLike, flag: fs.OpenMode = 'r', mode: fs.Mode = 0o644): Promise<FileHandle> {
|
|
540
|
+
return await _open(path, flag, mode, true);
|
|
558
541
|
}
|
|
559
542
|
open satisfies typeof promises.open;
|
|
560
543
|
|
|
561
|
-
/**
|
|
562
|
-
* Opens a file without resolving symlinks
|
|
563
|
-
* @internal
|
|
564
|
-
*/
|
|
565
|
-
export async function lopen(path: PathLike, flag: string, mode: Node.Mode = 0o644): Promise<FileHandle> {
|
|
566
|
-
const file: File = await _open(path, flag, mode, false);
|
|
567
|
-
return new FileHandle(getFdForFile(file));
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* Asynchronously reads the entire contents of a file.
|
|
572
|
-
*/
|
|
573
|
-
async function _readFile(fname: string, flag: string, resolveSymlinks: boolean): Promise<Uint8Array> {
|
|
574
|
-
const file = await _open(normalizePath(fname), flag, 0o644, resolveSymlinks);
|
|
575
|
-
|
|
576
|
-
try {
|
|
577
|
-
const stat = await file.stat();
|
|
578
|
-
const data = new Uint8Array(stat.size);
|
|
579
|
-
await file.read(data, 0, stat.size, 0);
|
|
580
|
-
await file.close();
|
|
581
|
-
return data;
|
|
582
|
-
} catch (e) {
|
|
583
|
-
await file.close();
|
|
584
|
-
throw e;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
544
|
/**
|
|
589
545
|
* Asynchronously reads the entire contents of a file.
|
|
590
546
|
* @param filename
|
|
@@ -593,17 +549,24 @@ async function _readFile(fname: string, flag: string, resolveSymlinks: boolean):
|
|
|
593
549
|
* options.flag Defaults to `'r'`.
|
|
594
550
|
* @returns file data
|
|
595
551
|
*/
|
|
596
|
-
export async function readFile(
|
|
597
|
-
export async function readFile(
|
|
598
|
-
export async function readFile(
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
552
|
+
export async function readFile(path: fs.PathLike | promises.FileHandle, options?: { encoding?: null; flag?: fs.OpenMode } | null): Promise<Buffer>;
|
|
553
|
+
export async function readFile(path: fs.PathLike | promises.FileHandle, options: { encoding: BufferEncoding; flag?: fs.OpenMode } | BufferEncoding): Promise<string>;
|
|
554
|
+
export async function readFile(
|
|
555
|
+
path: fs.PathLike | promises.FileHandle,
|
|
556
|
+
options?: (fs.ObjectEncodingOptions & { flag?: fs.OpenMode }) | BufferEncoding | null
|
|
557
|
+
): Promise<string | Buffer>;
|
|
558
|
+
export async function readFile(
|
|
559
|
+
path: fs.PathLike | promises.FileHandle,
|
|
560
|
+
_options?: (fs.ObjectEncodingOptions & { flag?: fs.OpenMode }) | BufferEncoding | null
|
|
561
|
+
): Promise<Buffer | string> {
|
|
562
|
+
const options = normalizeOptions(_options, null, 'r', 0o644);
|
|
563
|
+
const handle: FileHandle | promises.FileHandle = typeof path == 'object' && 'fd' in path ? path : await open(path as string, options.flag, options.mode);
|
|
604
564
|
|
|
605
|
-
|
|
606
|
-
|
|
565
|
+
try {
|
|
566
|
+
return await handle.readFile(options);
|
|
567
|
+
} finally {
|
|
568
|
+
await handle.close();
|
|
569
|
+
}
|
|
607
570
|
}
|
|
608
571
|
readFile satisfies typeof promises.readFile;
|
|
609
572
|
|
|
@@ -611,41 +574,36 @@ readFile satisfies typeof promises.readFile;
|
|
|
611
574
|
* Asynchronously writes data to a file, replacing the file if it already exists.
|
|
612
575
|
*
|
|
613
576
|
* The encoding option is ignored if data is a buffer.
|
|
614
|
-
* @param
|
|
615
|
-
* @param data
|
|
577
|
+
* @param path
|
|
578
|
+
* @param data Note:
|
|
616
579
|
* @param _options
|
|
617
580
|
* @option options encoding Defaults to `'utf8'`.
|
|
618
581
|
* @option options mode Defaults to `0644`.
|
|
619
582
|
* @option options flag Defaults to `'w'`.
|
|
620
583
|
*/
|
|
621
|
-
export async function writeFile(
|
|
584
|
+
export async function writeFile(
|
|
585
|
+
path: fs.PathLike | promises.FileHandle,
|
|
586
|
+
data: FileContents | Stream | Iterable<string | ArrayBufferView> | AsyncIterable<string | ArrayBufferView>,
|
|
587
|
+
_options?: (fs.ObjectEncodingOptions & { mode?: fs.Mode; flag?: fs.OpenMode; flush?: boolean }) | BufferEncoding | null
|
|
588
|
+
): Promise<void> {
|
|
622
589
|
const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
|
|
623
|
-
const handle = await open(
|
|
590
|
+
const handle = path instanceof FileHandle ? path : await open(path.toString(), options.flag, options.mode);
|
|
624
591
|
try {
|
|
625
|
-
|
|
592
|
+
const _data = typeof data == 'string' ? data : data;
|
|
593
|
+
if (typeof _data != 'string' && !(_data instanceof Uint8Array)) {
|
|
594
|
+
throw new ErrnoError(Errno.EINVAL, 'Iterables and streams not supported', handle.file.path, 'writeFile');
|
|
595
|
+
}
|
|
596
|
+
await handle.writeFile(_data, options);
|
|
626
597
|
} finally {
|
|
627
598
|
await handle.close();
|
|
628
599
|
}
|
|
629
600
|
}
|
|
630
601
|
writeFile satisfies typeof promises.writeFile;
|
|
631
602
|
|
|
632
|
-
/**
|
|
633
|
-
* Asynchronously append data to a file, creating the file if
|
|
634
|
-
* it not yet exists.
|
|
635
|
-
*/
|
|
636
|
-
async function _appendFile(fname: string, data: Uint8Array, flag: string, mode: number, resolveSymlinks: boolean): Promise<void> {
|
|
637
|
-
const file = await _open(fname, flag, mode, resolveSymlinks);
|
|
638
|
-
try {
|
|
639
|
-
await file.write(data, 0, data.length, null);
|
|
640
|
-
} finally {
|
|
641
|
-
await file.close();
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
|
|
645
603
|
/**
|
|
646
604
|
* Asynchronously append data to a file, creating the file if it not yet
|
|
647
605
|
* exists.
|
|
648
|
-
* @param
|
|
606
|
+
* @param path
|
|
649
607
|
* @param data
|
|
650
608
|
* @param options
|
|
651
609
|
* @option options encoding Defaults to `'utf8'`.
|
|
@@ -653,20 +611,26 @@ async function _appendFile(fname: string, data: Uint8Array, flag: string, mode:
|
|
|
653
611
|
* @option options flag Defaults to `'a'`.
|
|
654
612
|
*/
|
|
655
613
|
export async function appendFile(
|
|
656
|
-
|
|
614
|
+
path: fs.PathLike | promises.FileHandle,
|
|
657
615
|
data: FileContents,
|
|
658
|
-
_options?: BufferEncoding | (
|
|
616
|
+
_options?: BufferEncoding | (fs.EncodingOption & { mode?: fs.Mode; flag?: fs.OpenMode }) | null
|
|
659
617
|
): Promise<void> {
|
|
660
618
|
const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
|
|
661
619
|
const flag = parseFlag(options.flag);
|
|
662
620
|
if (!isAppendable(flag)) {
|
|
663
|
-
throw new
|
|
621
|
+
throw new ErrnoError(Errno.EINVAL, 'Flag passed to appendFile must allow for appending.');
|
|
664
622
|
}
|
|
665
623
|
if (typeof data != 'string' && !options.encoding) {
|
|
666
|
-
throw new
|
|
624
|
+
throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
|
|
625
|
+
}
|
|
626
|
+
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding!) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
627
|
+
const handle: FileHandle | promises.FileHandle = typeof path == 'object' && 'fd' in path ? path : await open(path as string, options.flag, options.mode);
|
|
628
|
+
|
|
629
|
+
try {
|
|
630
|
+
await handle.appendFile(encodedData, options);
|
|
631
|
+
} finally {
|
|
632
|
+
await handle.close();
|
|
667
633
|
}
|
|
668
|
-
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
669
|
-
await _appendFile(filename, encodedData, options.flag, options.mode, true);
|
|
670
634
|
}
|
|
671
635
|
appendFile satisfies typeof promises.appendFile;
|
|
672
636
|
|
|
@@ -676,38 +640,65 @@ appendFile satisfies typeof promises.appendFile;
|
|
|
676
640
|
* `rmdir`.
|
|
677
641
|
* @param path
|
|
678
642
|
*/
|
|
679
|
-
export async function rmdir(path: PathLike): Promise<void> {
|
|
680
|
-
|
|
643
|
+
export async function rmdir(path: fs.PathLike): Promise<void> {
|
|
644
|
+
path = normalizePath(path);
|
|
645
|
+
path = (await exists(path)) ? await realpath(path) : path;
|
|
646
|
+
const { fs, path: resolved } = resolveMount(path);
|
|
647
|
+
try {
|
|
648
|
+
await fs.rmdir(resolved, cred);
|
|
649
|
+
} catch (e) {
|
|
650
|
+
throw fixError(e as Error, { [resolved]: path });
|
|
651
|
+
}
|
|
681
652
|
}
|
|
682
653
|
rmdir satisfies typeof promises.rmdir;
|
|
683
654
|
|
|
684
655
|
/**
|
|
685
|
-
*
|
|
686
|
-
* @param path
|
|
687
|
-
* @param mode
|
|
656
|
+
* Asynchronous mkdir(2) - create a directory.
|
|
657
|
+
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
658
|
+
* @param options Either the file mode, or an object optionally specifying the file mode and whether parent folders
|
|
659
|
+
* should be created. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`.
|
|
688
660
|
*/
|
|
689
|
-
export async function mkdir(path: PathLike,
|
|
690
|
-
export async function mkdir(path: PathLike,
|
|
691
|
-
export async function mkdir(path: PathLike,
|
|
692
|
-
|
|
661
|
+
export async function mkdir(path: fs.PathLike, options: fs.MakeDirectoryOptions & { recursive: true }): Promise<string | undefined>;
|
|
662
|
+
export async function mkdir(path: fs.PathLike, options?: fs.Mode | (fs.MakeDirectoryOptions & { recursive?: false | undefined }) | null): Promise<void>;
|
|
663
|
+
export async function mkdir(path: fs.PathLike, options?: fs.Mode | fs.MakeDirectoryOptions | null): Promise<string | undefined>;
|
|
664
|
+
export async function mkdir(path: fs.PathLike, options?: fs.Mode | fs.MakeDirectoryOptions | null): Promise<string | undefined | void> {
|
|
665
|
+
path = normalizePath(path);
|
|
666
|
+
path = (await exists(path)) ? await realpath(path) : path;
|
|
667
|
+
const { fs, path: resolved } = resolveMount(path);
|
|
668
|
+
try {
|
|
669
|
+
await fs.mkdir(resolved, normalizeMode(typeof options == 'object' ? options?.mode : options, 0o777), cred);
|
|
670
|
+
} catch (e) {
|
|
671
|
+
throw fixError(e as Error, { [resolved]: path });
|
|
672
|
+
}
|
|
693
673
|
}
|
|
694
674
|
mkdir satisfies typeof promises.mkdir;
|
|
695
675
|
|
|
696
676
|
/**
|
|
697
|
-
*
|
|
698
|
-
* @param path
|
|
677
|
+
* Asynchronous readdir(3) - read a directory.
|
|
678
|
+
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
679
|
+
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
|
|
699
680
|
*/
|
|
700
|
-
export async function readdir(path: PathLike, options?: (
|
|
701
|
-
export async function readdir(path: PathLike, options:
|
|
702
|
-
export async function readdir(
|
|
681
|
+
export async function readdir(path: fs.PathLike, options?: (fs.ObjectEncodingOptions & { withFileTypes?: false; recursive?: boolean }) | BufferEncoding | null): Promise<string[]>;
|
|
682
|
+
export async function readdir(path: fs.PathLike, options: fs.BufferEncodingOption & { withFileTypes?: false; recursive?: boolean }): Promise<Buffer[]>;
|
|
683
|
+
export async function readdir(
|
|
684
|
+
path: fs.PathLike,
|
|
685
|
+
options?: (fs.ObjectEncodingOptions & { withFileTypes?: false; recursive?: boolean }) | BufferEncoding | null
|
|
686
|
+
): Promise<string[] | Buffer[]>;
|
|
687
|
+
export async function readdir(path: fs.PathLike, options: fs.ObjectEncodingOptions & { withFileTypes: true; recursive?: boolean }): Promise<Dirent[]>;
|
|
703
688
|
export async function readdir(
|
|
704
|
-
path: PathLike,
|
|
705
|
-
options?:
|
|
689
|
+
path: fs.PathLike,
|
|
690
|
+
options?: { withFileTypes?: boolean; recursive?: boolean; encoding?: BufferEncoding | 'buffer' | null } | BufferEncoding | 'buffer' | null
|
|
706
691
|
): Promise<string[] | Dirent[] | Buffer[]> {
|
|
707
692
|
path = normalizePath(path);
|
|
708
|
-
|
|
709
|
-
const
|
|
710
|
-
|
|
693
|
+
path = (await exists(path)) ? await realpath(path) : path;
|
|
694
|
+
const { fs, path: resolved } = resolveMount(path);
|
|
695
|
+
let entries: string[];
|
|
696
|
+
try {
|
|
697
|
+
entries = await fs.readdir(resolved, cred);
|
|
698
|
+
} catch (e) {
|
|
699
|
+
throw fixError(e as Error, { [resolved]: path });
|
|
700
|
+
}
|
|
701
|
+
for (const point of mounts.keys()) {
|
|
711
702
|
if (point.startsWith(path)) {
|
|
712
703
|
const entry = point.slice(path.length);
|
|
713
704
|
if (entry.includes('/') || entry.length == 0) {
|
|
@@ -732,9 +723,15 @@ readdir satisfies typeof promises.readdir;
|
|
|
732
723
|
* @param existing
|
|
733
724
|
* @param newpath
|
|
734
725
|
*/
|
|
735
|
-
export async function link(existing: PathLike, newpath: PathLike): Promise<void> {
|
|
726
|
+
export async function link(existing: fs.PathLike, newpath: fs.PathLike): Promise<void> {
|
|
727
|
+
existing = normalizePath(existing);
|
|
736
728
|
newpath = normalizePath(newpath);
|
|
737
|
-
|
|
729
|
+
const { fs, path: resolved } = resolveMount(newpath);
|
|
730
|
+
try {
|
|
731
|
+
return await fs.link(existing, newpath, cred);
|
|
732
|
+
} catch (e) {
|
|
733
|
+
throw fixError(e as Error, { [resolved]: newpath });
|
|
734
|
+
}
|
|
738
735
|
}
|
|
739
736
|
link satisfies typeof promises.link;
|
|
740
737
|
|
|
@@ -744,18 +741,18 @@ link satisfies typeof promises.link;
|
|
|
744
741
|
* @param path link path
|
|
745
742
|
* @param type can be either `'dir'` or `'file'` (default is `'file'`)
|
|
746
743
|
*/
|
|
747
|
-
export async function symlink(target: PathLike, path: PathLike, type:
|
|
748
|
-
if (!['file', 'dir', 'junction'].includes(type)) {
|
|
749
|
-
throw new
|
|
744
|
+
export async function symlink(target: fs.PathLike, path: fs.PathLike, type: fs.symlink.Type | string | null = 'file'): Promise<void> {
|
|
745
|
+
if (!['file', 'dir', 'junction'].includes(type!)) {
|
|
746
|
+
throw new ErrnoError(Errno.EINVAL, 'Invalid symlink type: ' + type);
|
|
750
747
|
}
|
|
751
748
|
|
|
752
749
|
if (await exists(path)) {
|
|
753
|
-
throw
|
|
750
|
+
throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
|
|
754
751
|
}
|
|
755
752
|
|
|
756
|
-
await writeFile(path, target);
|
|
757
|
-
const
|
|
758
|
-
await file._setType(FileType.SYMLINK);
|
|
753
|
+
await writeFile(path, target.toString());
|
|
754
|
+
const handle = await _open(path, 'r+', 0o644, false);
|
|
755
|
+
await handle.file._setType(FileType.SYMLINK);
|
|
759
756
|
}
|
|
760
757
|
symlink satisfies typeof promises.symlink;
|
|
761
758
|
|
|
@@ -763,15 +760,18 @@ symlink satisfies typeof promises.symlink;
|
|
|
763
760
|
* readlink.
|
|
764
761
|
* @param path
|
|
765
762
|
*/
|
|
766
|
-
export async function readlink(path: PathLike, options:
|
|
767
|
-
export async function readlink(path: PathLike, options?:
|
|
768
|
-
export async function readlink(path: PathLike, options?:
|
|
769
|
-
|
|
770
|
-
const
|
|
771
|
-
|
|
772
|
-
|
|
763
|
+
export async function readlink(path: fs.PathLike, options: fs.BufferEncodingOption): Promise<Buffer>;
|
|
764
|
+
export async function readlink(path: fs.PathLike, options?: fs.EncodingOption | null): Promise<string>;
|
|
765
|
+
export async function readlink(path: fs.PathLike, options?: fs.BufferEncodingOption | fs.EncodingOption | string | null): Promise<string | Buffer>;
|
|
766
|
+
export async function readlink(path: fs.PathLike, options?: fs.BufferEncodingOption | fs.EncodingOption | string | null): Promise<string | Buffer> {
|
|
767
|
+
const handle = await _open(normalizePath(path), 'r', 0o644, false);
|
|
768
|
+
try {
|
|
769
|
+
const value = await handle.readFile();
|
|
770
|
+
const encoding = typeof options == 'object' ? options?.encoding : options;
|
|
771
|
+
return encoding == 'buffer' ? value : value.toString(encoding! as BufferEncoding);
|
|
772
|
+
} finally {
|
|
773
|
+
await handle.close();
|
|
773
774
|
}
|
|
774
|
-
return value.toString(encoding);
|
|
775
775
|
}
|
|
776
776
|
readlink satisfies typeof promises.readlink;
|
|
777
777
|
|
|
@@ -783,7 +783,7 @@ readlink satisfies typeof promises.readlink;
|
|
|
783
783
|
* @param uid
|
|
784
784
|
* @param gid
|
|
785
785
|
*/
|
|
786
|
-
export async function chown(path: PathLike, uid: number, gid: number): Promise<void> {
|
|
786
|
+
export async function chown(path: fs.PathLike, uid: number, gid: number): Promise<void> {
|
|
787
787
|
const handle = await open(path, 'r+');
|
|
788
788
|
try {
|
|
789
789
|
await handle.chown(uid, gid);
|
|
@@ -799,8 +799,8 @@ chown satisfies typeof promises.chown;
|
|
|
799
799
|
* @param uid
|
|
800
800
|
* @param gid
|
|
801
801
|
*/
|
|
802
|
-
export async function lchown(path: PathLike, uid: number, gid: number): Promise<void> {
|
|
803
|
-
const handle = await
|
|
802
|
+
export async function lchown(path: fs.PathLike, uid: number, gid: number): Promise<void> {
|
|
803
|
+
const handle: FileHandle = await _open(path, 'r+', 0o644, false);
|
|
804
804
|
try {
|
|
805
805
|
await handle.chown(uid, gid);
|
|
806
806
|
} finally {
|
|
@@ -814,7 +814,7 @@ lchown satisfies typeof promises.lchown;
|
|
|
814
814
|
* @param path
|
|
815
815
|
* @param mode
|
|
816
816
|
*/
|
|
817
|
-
export async function chmod(path: PathLike, mode:
|
|
817
|
+
export async function chmod(path: fs.PathLike, mode: fs.Mode): Promise<void> {
|
|
818
818
|
const handle = await open(path, 'r+');
|
|
819
819
|
try {
|
|
820
820
|
await handle.chmod(mode);
|
|
@@ -829,8 +829,8 @@ chmod satisfies typeof promises.chmod;
|
|
|
829
829
|
* @param path
|
|
830
830
|
* @param mode
|
|
831
831
|
*/
|
|
832
|
-
export async function lchmod(path: PathLike, mode:
|
|
833
|
-
const handle = await
|
|
832
|
+
export async function lchmod(path: fs.PathLike, mode: fs.Mode): Promise<void> {
|
|
833
|
+
const handle: FileHandle = await _open(path, 'r+', 0o644, false);
|
|
834
834
|
try {
|
|
835
835
|
await handle.chmod(mode);
|
|
836
836
|
} finally {
|
|
@@ -845,7 +845,7 @@ lchmod satisfies typeof promises.lchmod;
|
|
|
845
845
|
* @param atime
|
|
846
846
|
* @param mtime
|
|
847
847
|
*/
|
|
848
|
-
export async function utimes(path: PathLike, atime: string | number | Date, mtime: string | number | Date): Promise<void> {
|
|
848
|
+
export async function utimes(path: fs.PathLike, atime: string | number | Date, mtime: string | number | Date): Promise<void> {
|
|
849
849
|
const handle = await open(path, 'r+');
|
|
850
850
|
try {
|
|
851
851
|
await handle.utimes(atime, mtime);
|
|
@@ -861,10 +861,10 @@ utimes satisfies typeof promises.utimes;
|
|
|
861
861
|
* @param atime
|
|
862
862
|
* @param mtime
|
|
863
863
|
*/
|
|
864
|
-
export async function lutimes(path: PathLike, atime:
|
|
865
|
-
const handle = await
|
|
864
|
+
export async function lutimes(path: fs.PathLike, atime: fs.TimeLike, mtime: fs.TimeLike): Promise<void> {
|
|
865
|
+
const handle: FileHandle = await _open(path, 'r+', 0o644, false);
|
|
866
866
|
try {
|
|
867
|
-
await handle.utimes(atime, mtime);
|
|
867
|
+
await handle.utimes(new Date(atime), new Date(mtime));
|
|
868
868
|
} finally {
|
|
869
869
|
await handle.close();
|
|
870
870
|
}
|
|
@@ -875,12 +875,10 @@ lutimes satisfies typeof promises.lutimes;
|
|
|
875
875
|
* Asynchronous realpath(3) - return the canonicalized absolute pathname.
|
|
876
876
|
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
877
877
|
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
|
|
878
|
-
*
|
|
879
|
-
* Note: This *Can not* use doOp since doOp depends on it
|
|
880
878
|
*/
|
|
881
|
-
export async function realpath(path: PathLike, options:
|
|
882
|
-
export async function realpath(path: PathLike, options?:
|
|
883
|
-
export async function realpath(path: PathLike, options?:
|
|
879
|
+
export async function realpath(path: fs.PathLike, options: fs.BufferEncodingOption): Promise<Buffer>;
|
|
880
|
+
export async function realpath(path: fs.PathLike, options?: fs.EncodingOption | BufferEncoding): Promise<string>;
|
|
881
|
+
export async function realpath(path: fs.PathLike, options?: fs.EncodingOption | BufferEncoding | fs.BufferEncodingOption): Promise<string | Buffer> {
|
|
884
882
|
path = normalizePath(path);
|
|
885
883
|
const { base, dir } = parse(path);
|
|
886
884
|
const lpath = join(dir == '/' ? '/' : await realpath(dir), base);
|
|
@@ -894,7 +892,7 @@ export async function realpath(path: PathLike, options?: Node.EncodingOption | B
|
|
|
894
892
|
|
|
895
893
|
return realpath(mountPoint + (await readlink(lpath)));
|
|
896
894
|
} catch (e) {
|
|
897
|
-
throw fixError(e, { [resolvedPath]: lpath });
|
|
895
|
+
throw fixError(e as Error, { [resolvedPath]: lpath });
|
|
898
896
|
}
|
|
899
897
|
}
|
|
900
898
|
realpath satisfies typeof promises.realpath;
|
|
@@ -902,10 +900,11 @@ realpath satisfies typeof promises.realpath;
|
|
|
902
900
|
/**
|
|
903
901
|
* @todo Implement
|
|
904
902
|
*/
|
|
905
|
-
export function watch(filename: PathLike, options
|
|
906
|
-
export function watch(filename: PathLike, options
|
|
907
|
-
export function watch(filename: PathLike, options
|
|
908
|
-
|
|
903
|
+
export function watch(filename: fs.PathLike, options?: fs.WatchOptions | BufferEncoding): AsyncIterable<FileChangeInfo<string>>;
|
|
904
|
+
export function watch(filename: fs.PathLike, options: fs.WatchOptions | fs.BufferEncodingOption): AsyncIterable<FileChangeInfo<Buffer>>;
|
|
905
|
+
export function watch(filename: fs.PathLike, options?: fs.WatchOptions | string): AsyncIterable<FileChangeInfo<string>> | AsyncIterable<FileChangeInfo<Buffer>>;
|
|
906
|
+
export function watch(filename: fs.PathLike, options: fs.WatchOptions | string = {}): AsyncIterable<FileChangeInfo<string>> | AsyncIterable<FileChangeInfo<Buffer>> {
|
|
907
|
+
throw ErrnoError.With('ENOSYS', filename.toString(), 'watch');
|
|
909
908
|
}
|
|
910
909
|
watch satisfies typeof promises.watch;
|
|
911
910
|
|
|
@@ -914,10 +913,10 @@ watch satisfies typeof promises.watch;
|
|
|
914
913
|
* @param path
|
|
915
914
|
* @param mode
|
|
916
915
|
*/
|
|
917
|
-
export async function access(path: PathLike, mode: number = constants.F_OK): Promise<void> {
|
|
916
|
+
export async function access(path: fs.PathLike, mode: number = constants.F_OK): Promise<void> {
|
|
918
917
|
const stats = await stat(path);
|
|
919
918
|
if (!stats.hasAccess(mode, cred)) {
|
|
920
|
-
throw new
|
|
919
|
+
throw new ErrnoError(Errno.EACCES);
|
|
921
920
|
}
|
|
922
921
|
}
|
|
923
922
|
access satisfies typeof promises.access;
|
|
@@ -926,7 +925,7 @@ access satisfies typeof promises.access;
|
|
|
926
925
|
* Asynchronous `rm`. Removes files or directories (recursively).
|
|
927
926
|
* @param path The path to the file or directory to remove.
|
|
928
927
|
*/
|
|
929
|
-
export async function rm(path: PathLike, options?:
|
|
928
|
+
export async function rm(path: fs.PathLike, options?: fs.RmOptions) {
|
|
930
929
|
path = normalizePath(path);
|
|
931
930
|
|
|
932
931
|
const stats = await stat(path);
|
|
@@ -950,7 +949,7 @@ export async function rm(path: PathLike, options?: Node.RmOptions) {
|
|
|
950
949
|
case constants.S_IFIFO:
|
|
951
950
|
case constants.S_IFSOCK:
|
|
952
951
|
default:
|
|
953
|
-
throw new
|
|
952
|
+
throw new ErrnoError(Errno.EPERM, 'File type not supported', path, 'rm');
|
|
954
953
|
}
|
|
955
954
|
}
|
|
956
955
|
rm satisfies typeof promises.rm;
|
|
@@ -961,10 +960,10 @@ rm satisfies typeof promises.rm;
|
|
|
961
960
|
* @param options The encoding (or an object including `encoding`).
|
|
962
961
|
* @returns The path to the created temporary directory, encoded as a string or buffer.
|
|
963
962
|
*/
|
|
964
|
-
export async function mkdtemp(prefix: string, options?:
|
|
965
|
-
export async function mkdtemp(prefix: string, options?:
|
|
966
|
-
export async function mkdtemp(prefix: string, options?:
|
|
967
|
-
const encoding = typeof options === 'object' ? options
|
|
963
|
+
export async function mkdtemp(prefix: string, options?: fs.EncodingOption): Promise<string>;
|
|
964
|
+
export async function mkdtemp(prefix: string, options?: fs.BufferEncodingOption): Promise<Buffer>;
|
|
965
|
+
export async function mkdtemp(prefix: string, options?: fs.EncodingOption | fs.BufferEncodingOption): Promise<string | Buffer> {
|
|
966
|
+
const encoding = typeof options === 'object' ? options?.encoding : options || 'utf8';
|
|
968
967
|
const fsName = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
969
968
|
const resolvedPath = '/tmp/' + fsName;
|
|
970
969
|
|
|
@@ -981,12 +980,12 @@ mkdtemp satisfies typeof promises.mkdtemp;
|
|
|
981
980
|
* @param mode Optional flags for the copy operation. Currently supports these flags:
|
|
982
981
|
* * `fs.constants.COPYFILE_EXCL`: If the destination file already exists, the operation fails.
|
|
983
982
|
*/
|
|
984
|
-
export async function copyFile(src: PathLike, dest: PathLike, mode?: number): Promise<void> {
|
|
983
|
+
export async function copyFile(src: fs.PathLike, dest: fs.PathLike, mode?: number): Promise<void> {
|
|
985
984
|
src = normalizePath(src);
|
|
986
985
|
dest = normalizePath(dest);
|
|
987
986
|
|
|
988
987
|
if (mode && mode & constants.COPYFILE_EXCL && (await exists(dest))) {
|
|
989
|
-
throw new
|
|
988
|
+
throw new ErrnoError(Errno.EEXIST, 'Destination file already exists.', dest, 'copyFile');
|
|
990
989
|
}
|
|
991
990
|
|
|
992
991
|
await writeFile(dest, await readFile(src));
|
|
@@ -999,7 +998,7 @@ copyFile satisfies typeof promises.copyFile;
|
|
|
999
998
|
* @param options Options for opening the directory.
|
|
1000
999
|
* @returns A `Dir` object representing the opened directory.
|
|
1001
1000
|
*/
|
|
1002
|
-
export async function opendir(path: PathLike, options?:
|
|
1001
|
+
export async function opendir(path: fs.PathLike, options?: fs.OpenDirOptions): Promise<Dir> {
|
|
1003
1002
|
path = normalizePath(path);
|
|
1004
1003
|
return new Dir(path);
|
|
1005
1004
|
}
|
|
@@ -1017,20 +1016,20 @@ opendir satisfies typeof promises.opendir;
|
|
|
1017
1016
|
* * `preserveTimestamps`: Preserve file timestamps.
|
|
1018
1017
|
* * `recursive`: If `true`, copies directories recursively.
|
|
1019
1018
|
*/
|
|
1020
|
-
export async function cp(source: PathLike, destination: PathLike, opts?:
|
|
1019
|
+
export async function cp(source: fs.PathLike, destination: fs.PathLike, opts?: fs.CopyOptions): Promise<void> {
|
|
1021
1020
|
source = normalizePath(source);
|
|
1022
1021
|
destination = normalizePath(destination);
|
|
1023
1022
|
|
|
1024
1023
|
const srcStats = await lstat(source); // Use lstat to follow symlinks if not dereferencing
|
|
1025
1024
|
|
|
1026
1025
|
if (opts?.errorOnExist && (await exists(destination))) {
|
|
1027
|
-
throw new
|
|
1026
|
+
throw new ErrnoError(Errno.EEXIST, 'Destination file or directory already exists.', destination, 'cp');
|
|
1028
1027
|
}
|
|
1029
1028
|
|
|
1030
1029
|
switch (srcStats.mode & constants.S_IFMT) {
|
|
1031
1030
|
case constants.S_IFDIR:
|
|
1032
1031
|
if (!opts?.recursive) {
|
|
1033
|
-
throw new
|
|
1032
|
+
throw new ErrnoError(Errno.EISDIR, source + ' is a directory (not copied)', source, 'cp');
|
|
1034
1033
|
}
|
|
1035
1034
|
await mkdir(destination, { recursive: true }); // Ensure the destination directory exists
|
|
1036
1035
|
for (const dirent of await readdir(source, { withFileTypes: true })) {
|
|
@@ -1049,7 +1048,7 @@ export async function cp(source: PathLike, destination: PathLike, opts?: Node.Co
|
|
|
1049
1048
|
case constants.S_IFIFO:
|
|
1050
1049
|
case constants.S_IFSOCK:
|
|
1051
1050
|
default:
|
|
1052
|
-
throw new
|
|
1051
|
+
throw new ErrnoError(Errno.EPERM, 'File type not supported', source, 'rm');
|
|
1053
1052
|
}
|
|
1054
1053
|
|
|
1055
1054
|
// Optionally preserve timestamps
|
|
@@ -1063,9 +1062,9 @@ cp satisfies typeof promises.cp;
|
|
|
1063
1062
|
* @since v18.15.0
|
|
1064
1063
|
* @return Fulfills with an {fs.StatFs} for the file system.
|
|
1065
1064
|
*/
|
|
1066
|
-
export async function statfs(path: PathLike, opts?:
|
|
1067
|
-
export async function statfs(path: PathLike, opts:
|
|
1068
|
-
export async function statfs(path: PathLike, opts?:
|
|
1069
|
-
export async function statfs(path: PathLike, opts?:
|
|
1070
|
-
throw
|
|
1065
|
+
export async function statfs(path: fs.PathLike, opts?: fs.StatFsOptions & { bigint?: false }): Promise<StatsFs>;
|
|
1066
|
+
export async function statfs(path: fs.PathLike, opts: fs.StatFsOptions & { bigint: true }): Promise<BigIntStatsFs>;
|
|
1067
|
+
export async function statfs(path: fs.PathLike, opts?: fs.StatFsOptions): Promise<StatsFs | BigIntStatsFs>;
|
|
1068
|
+
export async function statfs(path: fs.PathLike, opts?: fs.StatFsOptions): Promise<StatsFs | BigIntStatsFs> {
|
|
1069
|
+
throw ErrnoError.With('ENOSYS', path.toString(), 'statfs');
|
|
1071
1070
|
}
|