@gjsify/fs 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -2
- package/lib/esm/callback.js +251 -15
- package/lib/esm/dirent.js +47 -6
- package/lib/esm/encoding.js +2 -3
- package/lib/esm/errors.js +13 -0
- package/lib/esm/file-handle.js +108 -66
- package/lib/esm/fs-watcher.js +44 -7
- package/lib/esm/index.js +140 -5
- package/lib/esm/promises.js +290 -69
- package/lib/esm/read-stream.js +82 -57
- package/lib/esm/stats.js +138 -18
- package/lib/esm/sync.js +293 -44
- package/lib/esm/write-stream.js +4 -4
- package/lib/types/callback.d.ts +233 -0
- package/lib/types/dirent.d.ts +77 -0
- package/lib/types/encoding.d.ts +6 -0
- package/lib/types/errors.d.ts +7 -0
- package/lib/types/file-handle.d.ts +367 -0
- package/lib/types/fs-watcher.d.ts +17 -0
- package/lib/types/index.d.ts +149 -0
- package/lib/types/promises.d.ts +158 -0
- package/lib/types/read-stream.d.ts +21 -0
- package/lib/types/stats.d.ts +67 -0
- package/lib/types/sync.d.ts +109 -0
- package/lib/types/types/encoding-option.d.ts +2 -0
- package/lib/types/types/file-read-options.d.ts +15 -0
- package/lib/types/types/file-read-result.d.ts +4 -0
- package/lib/types/types/flag-and-open-mode.d.ts +5 -0
- package/lib/types/types/index.d.ts +6 -0
- package/lib/types/types/open-flags.d.ts +1 -0
- package/lib/types/types/read-options.d.ts +5 -0
- package/lib/types/utils.d.ts +2 -0
- package/lib/types/write-stream.d.ts +45 -0
- package/package.json +22 -34
- package/src/callback.spec.ts +284 -30
- package/src/callback.ts +352 -39
- package/src/dirent.ts +56 -8
- package/src/encoding.ts +7 -2
- package/src/errors.spec.ts +389 -0
- package/src/errors.ts +19 -0
- package/src/extended.spec.ts +706 -0
- package/src/file-handle.spec.ts +104 -23
- package/src/file-handle.ts +147 -79
- package/src/fs-watcher.ts +55 -8
- package/src/index.ts +146 -2
- package/src/new-apis.spec.ts +505 -0
- package/src/promises.spec.ts +651 -11
- package/src/promises.ts +353 -81
- package/src/read-stream.ts +98 -74
- package/src/stat.spec.ts +22 -14
- package/src/stats.ts +176 -75
- package/src/streams.spec.ts +455 -0
- package/src/symlink.spec.ts +176 -26
- package/src/sync.spec.ts +204 -32
- package/src/sync.ts +363 -58
- package/src/test.mts +7 -2
- package/src/types/encoding-option.ts +1 -1
- package/src/types/flag-and-open-mode.ts +1 -1
- package/src/types/read-options.ts +2 -2
- package/src/utils.ts +2 -0
- package/src/write-stream.ts +9 -7
- package/tsconfig.json +23 -10
- package/tsconfig.tsbuildinfo +1 -0
- package/lib/cjs/callback.js +0 -112
- package/lib/cjs/dirent.js +0 -98
- package/lib/cjs/encoding.js +0 -34
- package/lib/cjs/file-handle.js +0 -444
- package/lib/cjs/fs-watcher.js +0 -50
- package/lib/cjs/index.js +0 -95
- package/lib/cjs/promises.js +0 -160
- package/lib/cjs/read-stream.js +0 -78
- package/lib/cjs/stats.js +0 -45
- package/lib/cjs/sync.js +0 -126
- package/lib/cjs/types/encoding-option.js +0 -0
- package/lib/cjs/types/file-read-options.js +0 -0
- package/lib/cjs/types/file-read-result.js +0 -0
- package/lib/cjs/types/flag-and-open-mode.js +0 -0
- package/lib/cjs/types/index.js +0 -6
- package/lib/cjs/types/open-flags.js +0 -0
- package/lib/cjs/types/read-options.js +0 -0
- package/lib/cjs/utils.js +0 -18
- package/lib/cjs/write-stream.js +0 -116
- package/test/watch.js +0 -1
- package/test.gjs.js +0 -35359
- package/test.gjs.js.map +0 -7
- package/test.gjs.mjs +0 -40570
- package/test.gjs.mjs.meta.json +0 -1
- package/test.node.js +0 -1479
- package/test.node.js.map +0 -7
- package/test.node.mjs +0 -710
- package/tsconfig.types.json +0 -8
package/README.md
CHANGED
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
# @gjsify/fs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
GJS implementation of the Node.js `fs` module using Gio. Supports sync, callback, and promises APIs, streams, and FSWatcher.
|
|
4
|
+
|
|
5
|
+
Part of the [gjsify](https://github.com/gjsify/gjsify) project — Node.js and Web APIs for GJS (GNOME JavaScript).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @gjsify/fs
|
|
11
|
+
# or
|
|
12
|
+
yarn add @gjsify/fs
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { readFileSync, writeFileSync } from '@gjsify/fs';
|
|
19
|
+
import { readFile } from '@gjsify/fs/promises';
|
|
20
|
+
|
|
21
|
+
const content = readFileSync('/path/to/file', 'utf-8');
|
|
22
|
+
writeFileSync('/path/to/output', 'hello world');
|
|
23
|
+
|
|
24
|
+
const data = await readFile('/path/to/file', 'utf-8');
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Inspirations and credits
|
|
28
|
+
|
|
4
29
|
- https://github.com/cgjs/cgjs/blob/master/packages/fs/index.js
|
|
5
30
|
- https://github.com/geut/brode/blob/main/packages/browser-node-core/src/fs.js
|
|
6
31
|
- https://github.com/mafintosh/level-filesystem/blob/master/index.js
|
|
7
|
-
- https://github.com/denoland/deno_std/blob/main/node/fs.ts
|
|
32
|
+
- https://github.com/denoland/deno_std/blob/main/node/fs.ts
|
|
33
|
+
|
|
34
|
+
## License
|
|
35
|
+
|
|
36
|
+
MIT
|
package/lib/esm/callback.js
CHANGED
|
@@ -1,12 +1,68 @@
|
|
|
1
|
+
import GLib from "@girs/glib-2.0";
|
|
2
|
+
import Gio from "@girs/gio-2.0";
|
|
1
3
|
import { open as openP, rm as rmP } from "./promises.js";
|
|
2
|
-
import { warnNotImplemented } from "@gjsify/utils";
|
|
3
4
|
import { FileHandle } from "./file-handle.js";
|
|
4
|
-
import { Buffer } from "buffer";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
import { Buffer } from "node:buffer";
|
|
6
|
+
import { Stats, BigIntStats, STAT_ATTRIBUTES } from "./stats.js";
|
|
7
|
+
import { createNodeError } from "./errors.js";
|
|
8
|
+
import { realpathSync, readdirSync, renameSync, copyFileSync, accessSync, appendFileSync, readlinkSync, truncateSync, chmodSync, chownSync, mkdirSync, rmdirSync, readFileSync, writeFileSync } from "./sync.js";
|
|
9
|
+
function parseOptsCb(optionsOrCallback, maybeCallback) {
|
|
10
|
+
return typeof optionsOrCallback === "function" ? { options: {}, callback: optionsOrCallback } : { options: optionsOrCallback ?? {}, callback: maybeCallback };
|
|
11
|
+
}
|
|
12
|
+
function statImpl(path, flags, syscall, options, callback) {
|
|
13
|
+
const file = Gio.File.new_for_path(path.toString());
|
|
14
|
+
file.query_info_async(STAT_ATTRIBUTES, flags, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
15
|
+
try {
|
|
16
|
+
const info = file.query_info_finish(res);
|
|
17
|
+
callback(null, options?.bigint ? new BigIntStats(info, path) : new Stats(info, path));
|
|
18
|
+
} catch (err) {
|
|
19
|
+
callback(createNodeError(err, syscall, path));
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function stat(path, optionsOrCallback, maybeCallback) {
|
|
24
|
+
const { options, callback } = parseOptsCb(optionsOrCallback, maybeCallback);
|
|
25
|
+
statImpl(path, Gio.FileQueryInfoFlags.NONE, "stat", options, callback);
|
|
26
|
+
}
|
|
27
|
+
function lstat(path, optionsOrCallback, maybeCallback) {
|
|
28
|
+
const { options, callback } = parseOptsCb(optionsOrCallback, maybeCallback);
|
|
29
|
+
statImpl(path, Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, "lstat", options, callback);
|
|
30
|
+
}
|
|
31
|
+
function readdir(path, optionsOrCallback, maybeCallback) {
|
|
32
|
+
const { options, callback } = parseOptsCb(optionsOrCallback, maybeCallback);
|
|
33
|
+
Promise.resolve().then(() => {
|
|
34
|
+
try {
|
|
35
|
+
callback(null, readdirSync(path, options));
|
|
36
|
+
} catch (err) {
|
|
37
|
+
callback(createNodeError(err, "readdir", path));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function realpath(path, optionsOrCallback, maybeCallback) {
|
|
42
|
+
const { callback } = parseOptsCb(optionsOrCallback, maybeCallback);
|
|
43
|
+
Promise.resolve().then(() => {
|
|
44
|
+
try {
|
|
45
|
+
callback(null, realpathSync(path));
|
|
46
|
+
} catch (err) {
|
|
47
|
+
callback(err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function symlink(target, path, typeOrCallback, maybeCallback) {
|
|
52
|
+
const callback = typeof typeOrCallback === "function" ? typeOrCallback : maybeCallback;
|
|
53
|
+
if (typeof callback !== "function") {
|
|
54
|
+
throw new TypeError("Callback must be a function. Received " + typeof callback);
|
|
55
|
+
}
|
|
56
|
+
const file = Gio.File.new_for_path(path.toString());
|
|
57
|
+
file.make_symbolic_link_async(target.toString(), GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
58
|
+
try {
|
|
59
|
+
file.make_symbolic_link_finish(res);
|
|
60
|
+
callback(null);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
callback(createNodeError(err, "symlink", target, path));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
10
66
|
function open(path, ...args) {
|
|
11
67
|
let flags;
|
|
12
68
|
let mode;
|
|
@@ -36,8 +92,10 @@ function open(path, ...args) {
|
|
|
36
92
|
function write(fd, data, ...args) {
|
|
37
93
|
const fileHandle = FileHandle.getInstance(fd);
|
|
38
94
|
if (typeof data === "string") {
|
|
39
|
-
const callback2 = args
|
|
40
|
-
|
|
95
|
+
const callback2 = args.pop();
|
|
96
|
+
const position2 = args[0];
|
|
97
|
+
const encoding = args[1];
|
|
98
|
+
fileHandle.write(data, position2, encoding).then((res) => {
|
|
41
99
|
callback2(null, res.bytesWritten, res.buffer);
|
|
42
100
|
}).catch((err) => {
|
|
43
101
|
callback2(err, 0, "");
|
|
@@ -57,13 +115,12 @@ function write(fd, data, ...args) {
|
|
|
57
115
|
function read(fd, ...args) {
|
|
58
116
|
const fileHandle = FileHandle.getInstance(fd);
|
|
59
117
|
const callback = args[args.length - 1];
|
|
60
|
-
const err = new Error(warnNotImplemented("fs.read"));
|
|
61
|
-
callback(err, 0, Buffer.from(""));
|
|
62
118
|
let buffer;
|
|
63
119
|
let offset;
|
|
64
120
|
let length;
|
|
65
121
|
let position;
|
|
66
|
-
if (
|
|
122
|
+
if (args.length <= 1) {
|
|
123
|
+
} else if (typeof args[0] === "object" && !ArrayBuffer.isView(args[0])) {
|
|
67
124
|
const options = args[0];
|
|
68
125
|
buffer = options.buffer;
|
|
69
126
|
offset = options.offset;
|
|
@@ -77,8 +134,8 @@ function read(fd, ...args) {
|
|
|
77
134
|
}
|
|
78
135
|
fileHandle.read(buffer, offset, length, position).then((res) => {
|
|
79
136
|
callback(null, res.bytesRead, res.buffer);
|
|
80
|
-
}).catch((
|
|
81
|
-
callback(
|
|
137
|
+
}).catch((err) => {
|
|
138
|
+
callback(err, 0, Buffer.from([]));
|
|
82
139
|
});
|
|
83
140
|
}
|
|
84
141
|
function close(fd, callback) {
|
|
@@ -98,15 +155,194 @@ function rm(path, ...args) {
|
|
|
98
155
|
callback(err);
|
|
99
156
|
});
|
|
100
157
|
}
|
|
158
|
+
function rename(oldPath, newPath, callback) {
|
|
159
|
+
Promise.resolve().then(() => {
|
|
160
|
+
try {
|
|
161
|
+
renameSync(oldPath, newPath);
|
|
162
|
+
callback(null);
|
|
163
|
+
} catch (err) {
|
|
164
|
+
callback(err);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function copyFile(src, dest, modeOrCb, maybeCb) {
|
|
169
|
+
const mode = typeof modeOrCb === "function" ? 0 : modeOrCb;
|
|
170
|
+
const callback = typeof modeOrCb === "function" ? modeOrCb : maybeCb;
|
|
171
|
+
Promise.resolve().then(() => {
|
|
172
|
+
try {
|
|
173
|
+
copyFileSync(src, dest, mode);
|
|
174
|
+
callback(null);
|
|
175
|
+
} catch (err) {
|
|
176
|
+
callback(err);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function access(path, modeOrCb, maybeCb) {
|
|
181
|
+
const mode = typeof modeOrCb === "function" ? void 0 : modeOrCb;
|
|
182
|
+
const callback = typeof modeOrCb === "function" ? modeOrCb : maybeCb;
|
|
183
|
+
Promise.resolve().then(() => {
|
|
184
|
+
try {
|
|
185
|
+
accessSync(path, mode);
|
|
186
|
+
callback(null);
|
|
187
|
+
} catch (err) {
|
|
188
|
+
callback(err);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function appendFile(path, data, optsOrCb, maybeCb) {
|
|
193
|
+
const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
|
|
194
|
+
const options = typeof optsOrCb === "function" ? void 0 : optsOrCb;
|
|
195
|
+
Promise.resolve().then(() => {
|
|
196
|
+
try {
|
|
197
|
+
appendFileSync(path, data, options);
|
|
198
|
+
callback(null);
|
|
199
|
+
} catch (err) {
|
|
200
|
+
callback(err);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function readlink(path, optsOrCb, maybeCb) {
|
|
205
|
+
const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
|
|
206
|
+
const options = typeof optsOrCb === "function" ? void 0 : optsOrCb;
|
|
207
|
+
Promise.resolve().then(() => {
|
|
208
|
+
try {
|
|
209
|
+
callback(null, readlinkSync(path, options));
|
|
210
|
+
} catch (err) {
|
|
211
|
+
callback(err, "");
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function truncate(path, lenOrCb, maybeCb) {
|
|
216
|
+
const len = typeof lenOrCb === "function" ? 0 : lenOrCb;
|
|
217
|
+
const callback = typeof lenOrCb === "function" ? lenOrCb : maybeCb;
|
|
218
|
+
Promise.resolve().then(() => {
|
|
219
|
+
try {
|
|
220
|
+
truncateSync(path, len);
|
|
221
|
+
callback(null);
|
|
222
|
+
} catch (err) {
|
|
223
|
+
callback(err);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function chmod(path, mode, callback) {
|
|
228
|
+
Promise.resolve().then(() => {
|
|
229
|
+
try {
|
|
230
|
+
chmodSync(path, mode);
|
|
231
|
+
callback(null);
|
|
232
|
+
} catch (err) {
|
|
233
|
+
callback(err);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function chown(path, uid, gid, callback) {
|
|
238
|
+
Promise.resolve().then(() => {
|
|
239
|
+
try {
|
|
240
|
+
chownSync(path, uid, gid);
|
|
241
|
+
callback(null);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
callback(err);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function mkdir(path, optsOrCb, maybeCb) {
|
|
248
|
+
const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
|
|
249
|
+
const options = typeof optsOrCb === "function" ? void 0 : optsOrCb;
|
|
250
|
+
Promise.resolve().then(() => {
|
|
251
|
+
try {
|
|
252
|
+
mkdirSync(path, options);
|
|
253
|
+
callback(null);
|
|
254
|
+
} catch (err) {
|
|
255
|
+
callback(err);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
function rmdir(path, optsOrCb, maybeCb) {
|
|
260
|
+
const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
|
|
261
|
+
const options = typeof optsOrCb === "function" ? void 0 : optsOrCb;
|
|
262
|
+
Promise.resolve().then(() => {
|
|
263
|
+
try {
|
|
264
|
+
rmdirSync(path, options);
|
|
265
|
+
callback(null);
|
|
266
|
+
} catch (err) {
|
|
267
|
+
callback(err);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function readFile(path, optsOrCb, maybeCb) {
|
|
272
|
+
const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
|
|
273
|
+
const options = typeof optsOrCb === "function" ? void 0 : optsOrCb;
|
|
274
|
+
Promise.resolve().then(() => {
|
|
275
|
+
try {
|
|
276
|
+
const readOpts = typeof options === "string" ? { encoding: options, flag: "r" } : { encoding: options?.encoding ?? null, flag: options?.flag ?? "r" };
|
|
277
|
+
callback(null, readFileSync(path.toString(), readOpts));
|
|
278
|
+
} catch (err) {
|
|
279
|
+
callback(err, null);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
function writeFile(path, data, optsOrCb, maybeCb) {
|
|
284
|
+
const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
|
|
285
|
+
Promise.resolve().then(() => {
|
|
286
|
+
try {
|
|
287
|
+
writeFileSync(path.toString(), data);
|
|
288
|
+
callback(null);
|
|
289
|
+
} catch (err) {
|
|
290
|
+
callback(err);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
function link(existingPath, newPath, callback) {
|
|
295
|
+
Promise.resolve().then(() => {
|
|
296
|
+
try {
|
|
297
|
+
const result = GLib.spawn_command_line_sync(`ln ${existingPath.toString()} ${newPath.toString()}`);
|
|
298
|
+
if (!result[0]) {
|
|
299
|
+
throw Object.assign(new Error(`EPERM: operation not permitted, link '${existingPath}' -> '${newPath}'`), {
|
|
300
|
+
code: "EPERM",
|
|
301
|
+
errno: -1,
|
|
302
|
+
syscall: "link",
|
|
303
|
+
path: existingPath.toString(),
|
|
304
|
+
dest: newPath.toString()
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
callback(null);
|
|
308
|
+
} catch (err) {
|
|
309
|
+
callback(err);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
function unlink(path, callback) {
|
|
314
|
+
Promise.resolve().then(() => {
|
|
315
|
+
try {
|
|
316
|
+
GLib.unlink(path.toString());
|
|
317
|
+
callback(null);
|
|
318
|
+
} catch (err) {
|
|
319
|
+
callback(err);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
101
323
|
export {
|
|
324
|
+
access,
|
|
325
|
+
appendFile,
|
|
326
|
+
chmod,
|
|
327
|
+
chown,
|
|
102
328
|
close,
|
|
329
|
+
copyFile,
|
|
330
|
+
link,
|
|
103
331
|
lstat,
|
|
332
|
+
mkdir,
|
|
104
333
|
open,
|
|
105
334
|
read,
|
|
335
|
+
readFile,
|
|
106
336
|
readdir,
|
|
337
|
+
readlink,
|
|
107
338
|
realpath,
|
|
339
|
+
rename,
|
|
108
340
|
rm,
|
|
341
|
+
rmdir,
|
|
109
342
|
stat,
|
|
110
343
|
symlink,
|
|
111
|
-
|
|
344
|
+
truncate,
|
|
345
|
+
unlink,
|
|
346
|
+
write,
|
|
347
|
+
writeFile
|
|
112
348
|
};
|
package/lib/esm/dirent.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import Gio from "@girs/gio-2.0";
|
|
2
|
-
import { basename } from "path";
|
|
2
|
+
import { basename, dirname } from "node:path";
|
|
3
|
+
const S_IFMT = 61440;
|
|
4
|
+
const S_IFSOCK = 49152;
|
|
5
|
+
const S_IFLNK = 40960;
|
|
6
|
+
const S_IFREG = 32768;
|
|
7
|
+
const S_IFBLK = 24576;
|
|
8
|
+
const S_IFDIR = 16384;
|
|
9
|
+
const S_IFCHR = 8192;
|
|
10
|
+
const S_IFIFO = 4096;
|
|
3
11
|
class Dirent {
|
|
4
12
|
/**
|
|
5
13
|
* The file name that this `fs.Dirent` object refers to. The type of this
|
|
@@ -7,6 +15,11 @@ class Dirent {
|
|
|
7
15
|
* @since v10.10.0
|
|
8
16
|
*/
|
|
9
17
|
name;
|
|
18
|
+
/**
|
|
19
|
+
* The path to the parent directory of the file this `fs.Dirent` object refers to.
|
|
20
|
+
* @since v20.12.0, v18.20.0
|
|
21
|
+
*/
|
|
22
|
+
parentPath;
|
|
10
23
|
_isFile = false;
|
|
11
24
|
_isDirectory = false;
|
|
12
25
|
_isBlockDevice = false;
|
|
@@ -17,12 +30,12 @@ class Dirent {
|
|
|
17
30
|
/** This is not part of node.fs and is used internal by gjsify */
|
|
18
31
|
_file;
|
|
19
32
|
/** This is not part of node.fs and is used internal by gjsify */
|
|
20
|
-
constructor(path, filename) {
|
|
21
|
-
if (!filename)
|
|
22
|
-
filename = basename(path);
|
|
33
|
+
constructor(path, filename, fileType) {
|
|
34
|
+
if (!filename) filename = basename(path);
|
|
23
35
|
this.name = filename;
|
|
36
|
+
this.parentPath = dirname(path);
|
|
24
37
|
this._file = Gio.File.new_for_path(path);
|
|
25
|
-
const type = this._file.query_file_type(Gio.FileQueryInfoFlags.NONE, null);
|
|
38
|
+
const type = fileType ?? this._file.query_file_type(Gio.FileQueryInfoFlags.NONE, null);
|
|
26
39
|
switch (type) {
|
|
27
40
|
case Gio.FileType.DIRECTORY:
|
|
28
41
|
this._isDirectory = true;
|
|
@@ -37,10 +50,38 @@ class Dirent {
|
|
|
37
50
|
this._isSymbolicLink = true;
|
|
38
51
|
break;
|
|
39
52
|
case Gio.FileType.SPECIAL:
|
|
40
|
-
this.
|
|
53
|
+
this._classifySpecialFile(path);
|
|
41
54
|
break;
|
|
42
55
|
}
|
|
43
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Classify a SPECIAL file type using the unix::mode attribute from Gio.FileInfo.
|
|
59
|
+
* Falls back to marking nothing if the mode attribute is unavailable.
|
|
60
|
+
*/
|
|
61
|
+
_classifySpecialFile(path) {
|
|
62
|
+
try {
|
|
63
|
+
const file = Gio.File.new_for_path(path);
|
|
64
|
+
const info = file.query_info("unix::mode", Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
|
|
65
|
+
const mode = info.get_attribute_uint32("unix::mode");
|
|
66
|
+
if (mode === 0) return;
|
|
67
|
+
const fmt = mode & S_IFMT;
|
|
68
|
+
switch (fmt) {
|
|
69
|
+
case S_IFBLK:
|
|
70
|
+
this._isBlockDevice = true;
|
|
71
|
+
break;
|
|
72
|
+
case S_IFCHR:
|
|
73
|
+
this._isCharacterDevice = true;
|
|
74
|
+
break;
|
|
75
|
+
case S_IFSOCK:
|
|
76
|
+
this._isSocket = true;
|
|
77
|
+
break;
|
|
78
|
+
case S_IFIFO:
|
|
79
|
+
this._isFIFO = true;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
}
|
|
44
85
|
/**
|
|
45
86
|
* Returns `true` if the `fs.Dirent` object describes a regular file.
|
|
46
87
|
* @since v10.10.0
|
package/lib/esm/encoding.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Buffer } from "buffer";
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
2
|
function getEncodingFromOptions(options = { encoding: null, flag: "r" }, defaultEncoding = "utf8") {
|
|
3
3
|
if (options === null) {
|
|
4
4
|
return defaultEncoding;
|
|
@@ -19,8 +19,7 @@ function encodeUint8Array(encoding, data) {
|
|
|
19
19
|
return decoder.decode(data);
|
|
20
20
|
}
|
|
21
21
|
function decode(str, encoding) {
|
|
22
|
-
if (!encoding)
|
|
23
|
-
return str;
|
|
22
|
+
if (!encoding) return str;
|
|
24
23
|
else {
|
|
25
24
|
const decoder = new TextDecoder(encoding);
|
|
26
25
|
const encoder = new TextEncoder();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createNodeError as createNodeErrorGeneric, isNotFoundError } from "@gjsify/utils";
|
|
2
|
+
function createNodeError(err, syscall, path, dest) {
|
|
3
|
+
const pathStr = path.toString();
|
|
4
|
+
const error = createNodeErrorGeneric(err, syscall, {
|
|
5
|
+
path: pathStr,
|
|
6
|
+
dest: dest?.toString()
|
|
7
|
+
});
|
|
8
|
+
return error;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
createNodeError,
|
|
12
|
+
isNotFoundError
|
|
13
|
+
};
|