@gjsify/fs 0.3.21 → 0.4.3
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/lib/esm/_virtual/_rolldown/runtime.js +1 -1
- package/lib/esm/callback.js +1 -1
- package/lib/esm/cp.js +1 -1
- package/lib/esm/dir.js +1 -1
- package/lib/esm/dirent.js +1 -1
- package/lib/esm/encoding.js +1 -1
- package/lib/esm/errors.js +1 -1
- package/lib/esm/fd-ops.js +1 -1
- package/lib/esm/file-handle.js +1 -1
- package/lib/esm/fs-watcher.js +1 -1
- package/lib/esm/glob.js +1 -1
- package/lib/esm/read-stream.js +1 -1
- package/lib/esm/stat-watcher.js +1 -1
- package/lib/esm/statfs.js +1 -1
- package/lib/esm/stats.js +1 -1
- package/lib/esm/sync.js +1 -1
- package/lib/esm/utils.js +1 -1
- package/lib/esm/utimes.js +1 -1
- package/lib/esm/write-stream.js +1 -1
- package/package.json +51 -48
- package/src/callback.spec.ts +0 -296
- package/src/callback.ts +0 -684
- package/src/cp.spec.ts +0 -181
- package/src/cp.ts +0 -328
- package/src/dir.spec.ts +0 -204
- package/src/dir.ts +0 -199
- package/src/dirent.ts +0 -165
- package/src/encoding.ts +0 -45
- package/src/errors.spec.ts +0 -389
- package/src/errors.ts +0 -19
- package/src/extended.spec.ts +0 -706
- package/src/fd-ops.spec.ts +0 -234
- package/src/fd-ops.ts +0 -251
- package/src/file-handle.spec.ts +0 -115
- package/src/file-handle.ts +0 -856
- package/src/fs-watcher.ts +0 -198
- package/src/glob.spec.ts +0 -201
- package/src/glob.ts +0 -205
- package/src/index.ts +0 -313
- package/src/new-apis.spec.ts +0 -505
- package/src/promises.spec.ts +0 -812
- package/src/promises.ts +0 -686
- package/src/read-stream.ts +0 -128
- package/src/stat-watcher.ts +0 -116
- package/src/stat.spec.ts +0 -87
- package/src/statfs.spec.ts +0 -67
- package/src/statfs.ts +0 -92
- package/src/stats.ts +0 -207
- package/src/streams.spec.ts +0 -513
- package/src/symlink.spec.ts +0 -188
- package/src/sync.spec.ts +0 -377
- package/src/sync.ts +0 -562
- package/src/test.mts +0 -27
- package/src/types/encoding-option.ts +0 -3
- package/src/types/file-read-options.ts +0 -15
- package/src/types/file-read-result.ts +0 -4
- package/src/types/flag-and-open-mode.ts +0 -6
- package/src/types/index.ts +0 -6
- package/src/types/open-flags.ts +0 -14
- package/src/types/read-options.ts +0 -9
- package/src/utils.ts +0 -31
- package/src/utimes.spec.ts +0 -113
- package/src/utimes.ts +0 -97
- package/src/watch.spec.ts +0 -171
- package/src/watchfile.spec.ts +0 -185
- package/src/write-stream.ts +0 -142
- package/test/file.txt +0 -1
- package/tsconfig.json +0 -29
- package/tsconfig.tsbuildinfo +0 -1
package/src/promises.ts
DELETED
|
@@ -1,686 +0,0 @@
|
|
|
1
|
-
// Reference: Node.js lib/internal/fs/promises.js
|
|
2
|
-
// Reimplemented for GJS using Gio.File
|
|
3
|
-
|
|
4
|
-
import Gio from '@girs/gio-2.0';
|
|
5
|
-
import GLib from '@girs/glib-2.0';
|
|
6
|
-
import { join, dirname } from 'node:path';
|
|
7
|
-
import { getEncodingFromOptions, encodeUint8Array, decode } from './encoding.js';
|
|
8
|
-
import { realpathSync, readdirSync as readdirSyncFn, renameSync, copyFileSync, accessSync, appendFileSync, readlinkSync, truncateSync, chmodSync, chownSync, linkSync } from './sync.js';
|
|
9
|
-
import { cpAsync } from './cp.js';
|
|
10
|
-
import { opendirAsync, Dir } from './dir.js';
|
|
11
|
-
import { globAsync } from './glob.js';
|
|
12
|
-
import { watchAsync } from './fs-watcher.js';
|
|
13
|
-
import { statfsAsync } from './statfs.js';
|
|
14
|
-
import { utimesAsync, lutimesAsync, lchownAsync, lchmodAsync } from './utimes.js';
|
|
15
|
-
import {
|
|
16
|
-
fstatAsync,
|
|
17
|
-
ftruncateAsync,
|
|
18
|
-
fdatasyncAsync,
|
|
19
|
-
fsyncAsync,
|
|
20
|
-
fchmodAsync,
|
|
21
|
-
fchownAsync,
|
|
22
|
-
futimesAsync,
|
|
23
|
-
readvAsync,
|
|
24
|
-
writevAsync,
|
|
25
|
-
openAsBlob,
|
|
26
|
-
} from './fd-ops.js';
|
|
27
|
-
import { FileHandle } from './file-handle.js';
|
|
28
|
-
import { tempDirPath, normalizePath } from './utils.js';
|
|
29
|
-
import { Dirent } from './dirent.js';
|
|
30
|
-
import { Stats, BigIntStats, STAT_ATTRIBUTES } from './stats.js';
|
|
31
|
-
import { createNodeError } from './errors.js';
|
|
32
|
-
|
|
33
|
-
import type {
|
|
34
|
-
OpenFlags,
|
|
35
|
-
ReadOptions,
|
|
36
|
-
} from './types/index.js';
|
|
37
|
-
import type {
|
|
38
|
-
PathLike,
|
|
39
|
-
Mode,
|
|
40
|
-
RmOptions,
|
|
41
|
-
ObjectEncodingOptions,
|
|
42
|
-
BufferEncodingOption,
|
|
43
|
-
MakeDirectoryOptions,
|
|
44
|
-
RmDirOptions
|
|
45
|
-
} from 'node:fs';
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Asynchronously creates a directory.
|
|
49
|
-
*
|
|
50
|
-
* The optional `options` argument can be an integer specifying `mode` (permission
|
|
51
|
-
* and sticky bits), or an object with a `mode` property and a `recursive`property indicating whether parent directories should be created. Calling`fsPromises.mkdir()` when `path` is a directory
|
|
52
|
-
* that exists results in a
|
|
53
|
-
* rejection only when `recursive` is false.
|
|
54
|
-
* @since v10.0.0
|
|
55
|
-
* @return Upon success, fulfills with `undefined` if `recursive` is `false`, or the first directory path created if `recursive` is `true`.
|
|
56
|
-
*/
|
|
57
|
-
async function mkdir(
|
|
58
|
-
path: PathLike,
|
|
59
|
-
options: MakeDirectoryOptions & {
|
|
60
|
-
recursive: true;
|
|
61
|
-
}
|
|
62
|
-
): Promise<string | undefined>;
|
|
63
|
-
/**
|
|
64
|
-
* Asynchronous mkdir(2) - create a directory.
|
|
65
|
-
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
66
|
-
* @param options Either the file mode, or an object optionally specifying the file mode and whether parent folders
|
|
67
|
-
* should be created. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`.
|
|
68
|
-
*/
|
|
69
|
-
async function mkdir(
|
|
70
|
-
path: PathLike,
|
|
71
|
-
options?:
|
|
72
|
-
| Mode
|
|
73
|
-
| (MakeDirectoryOptions & {
|
|
74
|
-
recursive?: false | undefined;
|
|
75
|
-
})
|
|
76
|
-
| null
|
|
77
|
-
): Promise<void>;
|
|
78
|
-
/**
|
|
79
|
-
* Asynchronous mkdir(2) - create a directory.
|
|
80
|
-
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
81
|
-
* @param options Either the file mode, or an object optionally specifying the file mode and whether parent folders
|
|
82
|
-
* should be created. If a string is passed, it is parsed as an octal integer. If not specified, defaults to `0o777`.
|
|
83
|
-
*/
|
|
84
|
-
async function mkdir(path: PathLike, options?: Mode | MakeDirectoryOptions | null): Promise<string | undefined>
|
|
85
|
-
|
|
86
|
-
async function mkdir(path: PathLike, options?: Mode | MakeDirectoryOptions | null): Promise<string | undefined | void> {
|
|
87
|
-
|
|
88
|
-
let recursive: boolean | undefined;
|
|
89
|
-
let _mode: Mode | undefined = 0o777;
|
|
90
|
-
|
|
91
|
-
if (typeof options === 'object') {
|
|
92
|
-
if(options.recursive) recursive = options.recursive;
|
|
93
|
-
if(options.mode) _mode = options.mode
|
|
94
|
-
} else {
|
|
95
|
-
_mode = options;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const pathStr = normalizePath(path);
|
|
99
|
-
|
|
100
|
-
if (recursive) {
|
|
101
|
-
return mkdirRecursiveAsync(pathStr);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
105
|
-
return new Promise<undefined>((resolve, reject) => {
|
|
106
|
-
file.make_directory_async(GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
107
|
-
try {
|
|
108
|
-
file.make_directory_finish(res);
|
|
109
|
-
resolve(undefined);
|
|
110
|
-
} catch (err: unknown) {
|
|
111
|
-
reject(createNodeError(err, 'mkdir', pathStr));
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Recursively creates directories, similar to `mkdir -p`.
|
|
119
|
-
* Returns the first directory path created, or undefined if all directories already existed.
|
|
120
|
-
*/
|
|
121
|
-
async function mkdirRecursiveAsync(pathStr: string): Promise<string | undefined> {
|
|
122
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
123
|
-
|
|
124
|
-
// Try to create the directory directly first
|
|
125
|
-
try {
|
|
126
|
-
await new Promise<void>((resolve, reject) => {
|
|
127
|
-
file.make_directory_async(GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
128
|
-
try {
|
|
129
|
-
file.make_directory_finish(res);
|
|
130
|
-
resolve();
|
|
131
|
-
} catch (err: unknown) {
|
|
132
|
-
reject(err);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
// This directory was created; it's the deepest one.
|
|
137
|
-
// Now check if we also created parents by recursing on the parent first.
|
|
138
|
-
// Since we succeeded directly, this is the "first created" path candidate.
|
|
139
|
-
return pathStr;
|
|
140
|
-
} catch (err: unknown) {
|
|
141
|
-
const gErr = err as { code?: number };
|
|
142
|
-
// If it already exists, nothing to create
|
|
143
|
-
if (gErr.code === Gio.IOErrorEnum.EXISTS) {
|
|
144
|
-
return undefined;
|
|
145
|
-
}
|
|
146
|
-
// If parent doesn't exist, create parent first then retry
|
|
147
|
-
if (gErr.code === Gio.IOErrorEnum.NOT_FOUND) {
|
|
148
|
-
const parentPath = dirname(pathStr);
|
|
149
|
-
if (parentPath === pathStr) {
|
|
150
|
-
// Reached root, cannot go further
|
|
151
|
-
throw createNodeError(err, 'mkdir', pathStr);
|
|
152
|
-
}
|
|
153
|
-
const firstCreated = await mkdirRecursiveAsync(parentPath);
|
|
154
|
-
// Now create this directory
|
|
155
|
-
const retryFile = Gio.File.new_for_path(pathStr);
|
|
156
|
-
await new Promise<void>((resolve, reject) => {
|
|
157
|
-
retryFile.make_directory_async(GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
158
|
-
try {
|
|
159
|
-
retryFile.make_directory_finish(res);
|
|
160
|
-
resolve();
|
|
161
|
-
} catch (retryErr: unknown) {
|
|
162
|
-
reject(createNodeError(retryErr, 'mkdir', pathStr));
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
return firstCreated ?? pathStr;
|
|
167
|
-
}
|
|
168
|
-
throw createNodeError(err, 'mkdir', pathStr);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async function readFile(path: PathLike | FileHandle, options: ReadOptions = { encoding: null, flag: 'r' }) {
|
|
173
|
-
const pathStr = normalizePath(path as PathLike);
|
|
174
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
175
|
-
|
|
176
|
-
let ok: boolean;
|
|
177
|
-
let data: Uint8Array;
|
|
178
|
-
try {
|
|
179
|
-
[ok, data] = await new Promise<[boolean, Uint8Array, string]>((resolve, reject) => {
|
|
180
|
-
file.load_contents_async(null, (self, res) => {
|
|
181
|
-
try {
|
|
182
|
-
resolve(file.load_contents_finish(res));
|
|
183
|
-
} catch (error) {
|
|
184
|
-
reject(error);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
} catch (error) {
|
|
189
|
-
throw createNodeError(error, 'open', pathStr);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (!ok) {
|
|
193
|
-
throw createNodeError(new Error('failed to read file'), 'open', pathStr);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return encodeUint8Array(getEncodingFromOptions(options, 'buffer'), data);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Creates a unique temporary directory. A unique directory name is generated by
|
|
201
|
-
* appending six random characters to the end of the provided `prefix`. Due to
|
|
202
|
-
* platform inconsistencies, avoid trailing `X` characters in `prefix`. Some
|
|
203
|
-
* platforms, notably the BSDs, can return more than six random characters, and
|
|
204
|
-
* replace trailing `X` characters in `prefix` with random characters.
|
|
205
|
-
*
|
|
206
|
-
* The optional `options` argument can be a string specifying an encoding, or an
|
|
207
|
-
* object with an `encoding` property specifying the character encoding to use.
|
|
208
|
-
*
|
|
209
|
-
* ```js
|
|
210
|
-
* import { mkdtemp } from 'node:fs/promises';
|
|
211
|
-
*
|
|
212
|
-
* try {
|
|
213
|
-
* await mkdtemp(path.join(os.tmpdir(), 'foo-'));
|
|
214
|
-
* } catch (err) {
|
|
215
|
-
* console.error(err);
|
|
216
|
-
* }
|
|
217
|
-
* ```
|
|
218
|
-
*
|
|
219
|
-
* The `fsPromises.mkdtemp()` method will append the six randomly selected
|
|
220
|
-
* characters directly to the `prefix` string. For instance, given a directory`/tmp`, if the intention is to create a temporary directory _within_`/tmp`, the`prefix` must end with a trailing
|
|
221
|
-
* platform-specific path separator
|
|
222
|
-
* (`require('path').sep`).
|
|
223
|
-
* @since v10.0.0
|
|
224
|
-
* @return Fulfills with a string containing the filesystem path of the newly created temporary directory.
|
|
225
|
-
*/
|
|
226
|
-
async function mkdtemp(prefix: string, options?: ObjectEncodingOptions | BufferEncoding | null): Promise<string>;
|
|
227
|
-
/**
|
|
228
|
-
* Asynchronously creates a unique temporary directory.
|
|
229
|
-
* Generates six random characters to be appended behind a required `prefix` to create a unique temporary directory.
|
|
230
|
-
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
|
|
231
|
-
*/
|
|
232
|
-
async function mkdtemp(prefix: string, options: BufferEncodingOption): Promise<Buffer>;
|
|
233
|
-
/**
|
|
234
|
-
* Asynchronously creates a unique temporary directory.
|
|
235
|
-
* Generates six random characters to be appended behind a required `prefix` to create a unique temporary directory.
|
|
236
|
-
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
|
|
237
|
-
*/
|
|
238
|
-
async function mkdtemp(prefix: string, options?: ObjectEncodingOptions | BufferEncoding | null): Promise<string | Buffer>;
|
|
239
|
-
|
|
240
|
-
async function mkdtemp(prefix: string, options?: BufferEncodingOption | ObjectEncodingOptions | BufferEncoding | null): Promise<string | Buffer> {
|
|
241
|
-
const encoding: string | undefined = getEncodingFromOptions(options);
|
|
242
|
-
const path = tempDirPath(prefix);
|
|
243
|
-
|
|
244
|
-
await mkdir(
|
|
245
|
-
path,
|
|
246
|
-
{ recursive: false, mode: 0o700 }
|
|
247
|
-
)
|
|
248
|
-
|
|
249
|
-
return decode(path, encoding);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
async function writeFile(path: PathLike, data: string | Uint8Array | unknown) {
|
|
253
|
-
const pathStr = normalizePath(path);
|
|
254
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
255
|
-
|
|
256
|
-
// Convert data to Uint8Array if it's a string
|
|
257
|
-
let bytes: Uint8Array;
|
|
258
|
-
if (typeof data === 'string') {
|
|
259
|
-
bytes = new TextEncoder().encode(data);
|
|
260
|
-
} else if (data instanceof Uint8Array) {
|
|
261
|
-
bytes = data;
|
|
262
|
-
} else {
|
|
263
|
-
// Fallback: convert to string first
|
|
264
|
-
bytes = new TextEncoder().encode(String(data));
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Open the file for writing (replace contents), creating if needed
|
|
268
|
-
const outputStream = await new Promise<Gio.FileOutputStream>((resolve, reject) => {
|
|
269
|
-
file.replace_async(null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
270
|
-
try {
|
|
271
|
-
resolve(file.replace_finish(res));
|
|
272
|
-
} catch (err: unknown) {
|
|
273
|
-
reject(createNodeError(err, 'open', pathStr));
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
// Write the bytes to the stream (skip if empty — GLib rejects null/empty buffer)
|
|
279
|
-
if (bytes.length > 0) {
|
|
280
|
-
const glibBytes = new GLib.Bytes(bytes);
|
|
281
|
-
await new Promise<void>((resolve, reject) => {
|
|
282
|
-
outputStream.write_bytes_async(glibBytes, GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
283
|
-
try {
|
|
284
|
-
outputStream.write_bytes_finish(res);
|
|
285
|
-
resolve();
|
|
286
|
-
} catch (err: unknown) {
|
|
287
|
-
reject(createNodeError(err, 'write', pathStr));
|
|
288
|
-
}
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Close the output stream
|
|
294
|
-
await new Promise<void>((resolve, reject) => {
|
|
295
|
-
outputStream.close_async(GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
296
|
-
try {
|
|
297
|
-
outputStream.close_finish(res);
|
|
298
|
-
resolve();
|
|
299
|
-
} catch (err: unknown) {
|
|
300
|
-
reject(createNodeError(err, 'close', pathStr));
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Removes the directory identified by `path`.
|
|
308
|
-
*
|
|
309
|
-
* Using `fsPromises.rmdir()` on a file (not a directory) results in the
|
|
310
|
-
* promise being rejected with an `ENOENT` error on Windows and an `ENOTDIR`error on POSIX.
|
|
311
|
-
*
|
|
312
|
-
* To get a behavior similar to the `rm -rf` Unix command, use `fsPromises.rm()` with options `{ recursive: true, force: true }`.
|
|
313
|
-
* @since v10.0.0
|
|
314
|
-
* @return Fulfills with `undefined` upon success.
|
|
315
|
-
*/
|
|
316
|
-
async function rmdir(path: PathLike, _options?: RmDirOptions): Promise<void> {
|
|
317
|
-
const pathStr = normalizePath(path);
|
|
318
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
319
|
-
// Check if it's a directory
|
|
320
|
-
const info = await new Promise<Gio.FileInfo>((resolve, reject) => {
|
|
321
|
-
file.query_info_async('standard::type', Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
322
|
-
try {
|
|
323
|
-
resolve(file.query_info_finish(res));
|
|
324
|
-
} catch (err: unknown) {
|
|
325
|
-
reject(createNodeError(err, 'rmdir', pathStr));
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
if (info.get_file_type() !== Gio.FileType.DIRECTORY) {
|
|
330
|
-
const err = Object.assign(new Error(), { code: 4 }); // Gio.IOErrorEnum.NOT_DIRECTORY
|
|
331
|
-
throw createNodeError(err, 'rmdir', pathStr);
|
|
332
|
-
}
|
|
333
|
-
// Check if empty
|
|
334
|
-
const children = await new Promise<Gio.FileEnumerator>((resolve, reject) => {
|
|
335
|
-
file.enumerate_children_async('standard::name', Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
336
|
-
try {
|
|
337
|
-
resolve(file.enumerate_children_finish(res));
|
|
338
|
-
} catch (err: unknown) {
|
|
339
|
-
reject(createNodeError(err, 'rmdir', pathStr));
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
const firstChild = children.next_file(null);
|
|
344
|
-
if (firstChild !== null) {
|
|
345
|
-
const err = Object.assign(new Error(), { code: 5 }); // Gio.IOErrorEnum.NOT_EMPTY
|
|
346
|
-
throw createNodeError(err, 'rmdir', pathStr);
|
|
347
|
-
}
|
|
348
|
-
// Delete the empty directory
|
|
349
|
-
await new Promise<void>((resolve, reject) => {
|
|
350
|
-
file.delete_async(GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
351
|
-
try {
|
|
352
|
-
file.delete_finish(res);
|
|
353
|
-
resolve();
|
|
354
|
-
} catch (err: unknown) {
|
|
355
|
-
reject(createNodeError(err, 'rmdir', pathStr));
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
async function unlink(path: PathLike): Promise<void> {
|
|
362
|
-
const pathStr = normalizePath(path);
|
|
363
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
364
|
-
await new Promise<void>((resolve, reject) => {
|
|
365
|
-
file.delete_async(GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
366
|
-
try {
|
|
367
|
-
file.delete_finish(res);
|
|
368
|
-
resolve();
|
|
369
|
-
} catch (err: unknown) {
|
|
370
|
-
reject(createNodeError(err, 'unlink', pathStr));
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
async function open(path: PathLike, flags?: OpenFlags | number, mode?: Mode): Promise<FileHandle> {
|
|
377
|
-
// FileHandle constructor maps GLib.FileError to NodeJS.ErrnoException on failure.
|
|
378
|
-
return new FileHandle({ path, flags: flags as OpenFlags | undefined, mode });
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
async function write<TBuffer extends Uint8Array>(
|
|
382
|
-
fd: number,
|
|
383
|
-
buffer: TBuffer,
|
|
384
|
-
offset?: number | null,
|
|
385
|
-
length?: number | null,
|
|
386
|
-
position?: number | null
|
|
387
|
-
): Promise<{
|
|
388
|
-
bytesWritten: number;
|
|
389
|
-
buffer: TBuffer;
|
|
390
|
-
}>
|
|
391
|
-
|
|
392
|
-
async function write(
|
|
393
|
-
fd: number,
|
|
394
|
-
data: string,
|
|
395
|
-
position?: number | null,
|
|
396
|
-
encoding?: BufferEncoding | null
|
|
397
|
-
): Promise<{
|
|
398
|
-
bytesWritten: number;
|
|
399
|
-
buffer: string;
|
|
400
|
-
}>
|
|
401
|
-
|
|
402
|
-
async function write<TBuffer extends Uint8Array>(
|
|
403
|
-
fd: number,
|
|
404
|
-
data: string | TBuffer,
|
|
405
|
-
positionOrOffset?: number | null,
|
|
406
|
-
encodingOrLength?: BufferEncoding | null | number,
|
|
407
|
-
position?: number | null
|
|
408
|
-
): Promise<{
|
|
409
|
-
bytesWritten: number;
|
|
410
|
-
buffer: string;
|
|
411
|
-
}> {
|
|
412
|
-
if(typeof data === 'string') {
|
|
413
|
-
return _writeStr(fd, data, positionOrOffset, encodingOrLength as BufferEncoding | null);
|
|
414
|
-
}
|
|
415
|
-
return _writeBuf(fd, data, positionOrOffset as number | null, encodingOrLength as null | number, position) as unknown as Promise<{ bytesWritten: number; buffer: string }>;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
async function _writeBuf<TBuffer extends Uint8Array>(
|
|
419
|
-
fd: number,
|
|
420
|
-
buffer: TBuffer,
|
|
421
|
-
offset?: number | null,
|
|
422
|
-
length?: number | null,
|
|
423
|
-
position?: number | null
|
|
424
|
-
): Promise<{
|
|
425
|
-
bytesWritten: number;
|
|
426
|
-
buffer: TBuffer;
|
|
427
|
-
}> {
|
|
428
|
-
const fileHandle = FileHandle.getInstance(fd);
|
|
429
|
-
const result = await fileHandle.write(buffer, offset, length, position);
|
|
430
|
-
return { bytesWritten: result.bytesWritten, buffer };
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
async function _writeStr(
|
|
434
|
-
fd: number,
|
|
435
|
-
data: string,
|
|
436
|
-
position?: number | null,
|
|
437
|
-
encoding?: BufferEncoding | null
|
|
438
|
-
): Promise<{
|
|
439
|
-
bytesWritten: number;
|
|
440
|
-
buffer: string;
|
|
441
|
-
}> {
|
|
442
|
-
const fileHandle = FileHandle.getInstance(fd);
|
|
443
|
-
const result = await fileHandle.write(data, position, encoding);
|
|
444
|
-
return { bytesWritten: result.bytesWritten, buffer: data };
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// --- helpers ---
|
|
448
|
-
|
|
449
|
-
function queryInfoAsync(path: PathLike, flags: Gio.FileQueryInfoFlags, syscall: string, options?: { bigint?: boolean }): Promise<Stats | BigIntStats> {
|
|
450
|
-
const pathStr = normalizePath(path);
|
|
451
|
-
return new Promise((resolve, reject) => {
|
|
452
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
453
|
-
file.query_info_async(STAT_ATTRIBUTES, flags, GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
454
|
-
try {
|
|
455
|
-
const info = file.query_info_finish(res);
|
|
456
|
-
resolve(options?.bigint ? new BigIntStats(info, pathStr) : new Stats(info, pathStr));
|
|
457
|
-
} catch (err: unknown) {
|
|
458
|
-
reject(createNodeError(err, syscall, pathStr));
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// --- stat / lstat ---
|
|
465
|
-
|
|
466
|
-
async function stat(path: PathLike, options?: { bigint?: boolean }): Promise<Stats | BigIntStats> {
|
|
467
|
-
return queryInfoAsync(path, Gio.FileQueryInfoFlags.NONE, 'stat', options);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
async function lstat(path: PathLike, options?: { bigint?: boolean }): Promise<Stats | BigIntStats> {
|
|
471
|
-
return queryInfoAsync(path, Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, 'lstat', options);
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// --- readdir / realpath / symlink — delegate to sync (sync is the canonical impl) ---
|
|
475
|
-
|
|
476
|
-
async function readdir(path: PathLike, options?: { withFileTypes?: boolean; encoding?: string; recursive?: boolean }): Promise<string[] | Dirent[]> {
|
|
477
|
-
try {
|
|
478
|
-
return readdirSyncFn(path, options);
|
|
479
|
-
} catch (error) {
|
|
480
|
-
throw createNodeError(error, 'scandir', path);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
async function realpath(path: PathLike): Promise<string> {
|
|
485
|
-
return realpathSync(path);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
async function symlink(target: PathLike, path: PathLike, _type?: string): Promise<void> {
|
|
489
|
-
const pathStr = normalizePath(path);
|
|
490
|
-
const targetStr = normalizePath(target);
|
|
491
|
-
return new Promise((resolve, reject) => {
|
|
492
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
493
|
-
file.make_symbolic_link_async(targetStr, GLib.PRIORITY_DEFAULT, null, (_s: unknown, res: Gio.AsyncResult) => {
|
|
494
|
-
try {
|
|
495
|
-
file.make_symbolic_link_finish(res);
|
|
496
|
-
resolve();
|
|
497
|
-
} catch (err: unknown) {
|
|
498
|
-
reject(createNodeError(err, 'symlink', targetStr, pathStr));
|
|
499
|
-
}
|
|
500
|
-
});
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Removes files and directories (modeled on the standard POSIX `rm` utility).
|
|
506
|
-
* @since v14.14.0
|
|
507
|
-
* @return Fulfills with `undefined` upon success.
|
|
508
|
-
*/
|
|
509
|
-
async function rm(path: PathLike, options?: RmOptions): Promise<void> {
|
|
510
|
-
const pathStr = normalizePath(path);
|
|
511
|
-
const file = Gio.File.new_for_path(pathStr);
|
|
512
|
-
const recursive = options?.recursive || false;
|
|
513
|
-
const force = options?.force || false;
|
|
514
|
-
|
|
515
|
-
let dirent: Dirent;
|
|
516
|
-
try {
|
|
517
|
-
dirent = new Dirent(pathStr);
|
|
518
|
-
} catch (err: unknown) {
|
|
519
|
-
if (force) return; // force: ignore non-existent paths
|
|
520
|
-
throw createNodeError(err, 'rm', path);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if (dirent.isDirectory()) {
|
|
524
|
-
const childFiles = await readdir(path, { withFileTypes: true });
|
|
525
|
-
|
|
526
|
-
if (!recursive && childFiles.length) {
|
|
527
|
-
const err = Object.assign(new Error(), { code: 5 }); // Gio.IOErrorEnum.NOT_EMPTY
|
|
528
|
-
throw createNodeError(err, 'rm', path);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
for (const childFile of childFiles) {
|
|
532
|
-
if (typeof childFile !== 'string') {
|
|
533
|
-
await rm(join(pathStr, childFile.name), options);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
await new Promise<void>((resolve, reject) => {
|
|
539
|
-
file.delete_async(GLib.PRIORITY_DEFAULT, null, (_self: unknown, res: Gio.AsyncResult) => {
|
|
540
|
-
try {
|
|
541
|
-
file.delete_finish(res);
|
|
542
|
-
resolve();
|
|
543
|
-
} catch (err: unknown) {
|
|
544
|
-
if (force) { resolve(); return; }
|
|
545
|
-
reject(createNodeError(err, 'rm', path));
|
|
546
|
-
}
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// --- rename ---
|
|
552
|
-
async function rename(oldPath: PathLike, newPath: PathLike): Promise<void> {
|
|
553
|
-
renameSync(oldPath, newPath);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// --- copyFile ---
|
|
557
|
-
async function copyFile(src: PathLike, dest: PathLike, mode?: number): Promise<void> {
|
|
558
|
-
copyFileSync(src, dest, mode);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// --- access ---
|
|
562
|
-
async function access(path: PathLike, mode?: number): Promise<void> {
|
|
563
|
-
accessSync(path, mode);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
// --- appendFile ---
|
|
567
|
-
async function appendFile(path: PathLike, data: string | Uint8Array, options?: { encoding?: string; mode?: number; flag?: string } | string): Promise<void> {
|
|
568
|
-
appendFileSync(path, data, options);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// --- readlink ---
|
|
572
|
-
async function readlink(path: PathLike, options?: { encoding?: string } | string): Promise<string | Buffer> {
|
|
573
|
-
return readlinkSync(path, options);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
// --- truncate ---
|
|
577
|
-
async function truncate(path: PathLike, len?: number): Promise<void> {
|
|
578
|
-
truncateSync(path, len);
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
// --- chmod ---
|
|
582
|
-
async function chmod(path: PathLike, mode: number | string): Promise<void> {
|
|
583
|
-
chmodSync(path, mode);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
// --- chown ---
|
|
587
|
-
async function chown(path: PathLike, uid: number, gid: number): Promise<void> {
|
|
588
|
-
chownSync(path, uid, gid);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// --- link ---
|
|
592
|
-
async function link(existingPath: PathLike, newPath: PathLike): Promise<void> {
|
|
593
|
-
linkSync(existingPath, newPath);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
export type { Dir };
|
|
597
|
-
|
|
598
|
-
export {
|
|
599
|
-
readFile,
|
|
600
|
-
mkdir,
|
|
601
|
-
mkdtemp,
|
|
602
|
-
realpath,
|
|
603
|
-
readdir,
|
|
604
|
-
writeFile,
|
|
605
|
-
rmdir,
|
|
606
|
-
unlink,
|
|
607
|
-
open,
|
|
608
|
-
write,
|
|
609
|
-
rm,
|
|
610
|
-
lstat,
|
|
611
|
-
symlink,
|
|
612
|
-
stat,
|
|
613
|
-
rename,
|
|
614
|
-
copyFile,
|
|
615
|
-
access,
|
|
616
|
-
appendFile,
|
|
617
|
-
readlink,
|
|
618
|
-
truncate,
|
|
619
|
-
chmod,
|
|
620
|
-
chown,
|
|
621
|
-
link,
|
|
622
|
-
cpAsync as cp,
|
|
623
|
-
opendirAsync as opendir,
|
|
624
|
-
globAsync as glob,
|
|
625
|
-
watchAsync as watch,
|
|
626
|
-
statfsAsync as statfs,
|
|
627
|
-
utimesAsync as utimes,
|
|
628
|
-
lutimesAsync as lutimes,
|
|
629
|
-
lchownAsync as lchown,
|
|
630
|
-
lchmodAsync as lchmod,
|
|
631
|
-
fstatAsync as fstat,
|
|
632
|
-
ftruncateAsync as ftruncate,
|
|
633
|
-
fdatasyncAsync as fdatasync,
|
|
634
|
-
fsyncAsync as fsync,
|
|
635
|
-
fchmodAsync as fchmod,
|
|
636
|
-
fchownAsync as fchown,
|
|
637
|
-
futimesAsync as futimes,
|
|
638
|
-
readvAsync as readv,
|
|
639
|
-
writevAsync as writev,
|
|
640
|
-
openAsBlob,
|
|
641
|
-
};
|
|
642
|
-
|
|
643
|
-
export default {
|
|
644
|
-
readFile,
|
|
645
|
-
mkdir,
|
|
646
|
-
mkdtemp,
|
|
647
|
-
realpath,
|
|
648
|
-
readdir,
|
|
649
|
-
writeFile,
|
|
650
|
-
rmdir,
|
|
651
|
-
unlink,
|
|
652
|
-
open,
|
|
653
|
-
write,
|
|
654
|
-
rm,
|
|
655
|
-
lstat,
|
|
656
|
-
symlink,
|
|
657
|
-
stat,
|
|
658
|
-
rename,
|
|
659
|
-
copyFile,
|
|
660
|
-
access,
|
|
661
|
-
appendFile,
|
|
662
|
-
readlink,
|
|
663
|
-
truncate,
|
|
664
|
-
chmod,
|
|
665
|
-
chown,
|
|
666
|
-
link,
|
|
667
|
-
cp: cpAsync,
|
|
668
|
-
opendir: opendirAsync,
|
|
669
|
-
glob: globAsync,
|
|
670
|
-
watch: watchAsync,
|
|
671
|
-
statfs: statfsAsync,
|
|
672
|
-
utimes: utimesAsync,
|
|
673
|
-
lutimes: lutimesAsync,
|
|
674
|
-
lchown: lchownAsync,
|
|
675
|
-
lchmod: lchmodAsync,
|
|
676
|
-
fstat: fstatAsync,
|
|
677
|
-
ftruncate: ftruncateAsync,
|
|
678
|
-
fdatasync: fdatasyncAsync,
|
|
679
|
-
fsync: fsyncAsync,
|
|
680
|
-
fchmod: fchmodAsync,
|
|
681
|
-
fchown: fchownAsync,
|
|
682
|
-
futimes: futimesAsync,
|
|
683
|
-
readv: readvAsync,
|
|
684
|
-
writev: writevAsync,
|
|
685
|
-
openAsBlob,
|
|
686
|
-
};
|