@gjsify/fs 0.0.4 → 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 -35
- 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 -40534
- 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/lib/esm/promises.js
CHANGED
|
@@ -1,47 +1,98 @@
|
|
|
1
1
|
import Gio from "@girs/gio-2.0";
|
|
2
2
|
import GLib from "@girs/glib-2.0";
|
|
3
|
-
import {
|
|
4
|
-
import { join } from "path";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
5
4
|
import { getEncodingFromOptions, encodeUint8Array, decode } from "./encoding.js";
|
|
6
|
-
import {
|
|
5
|
+
import { realpathSync, readdirSync as readdirSyncFn, renameSync, copyFileSync, accessSync, appendFileSync, readlinkSync, truncateSync, chmodSync, chownSync, linkSync } from "./sync.js";
|
|
7
6
|
import { FileHandle } from "./file-handle.js";
|
|
8
7
|
import { tempDirPath } from "./utils.js";
|
|
9
8
|
import { Dirent } from "./dirent.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { symlinkPromise as symlink } from "@gjsify/deno_std/node/_fs/_fs_symlink";
|
|
13
|
-
import { lstatPromise as lstat } from "@gjsify/deno_std/node/_fs/_fs_lstat";
|
|
14
|
-
import { statPromise as stat } from "@gjsify/deno_std/node/_fs/_fs_stat";
|
|
9
|
+
import { Stats, BigIntStats, STAT_ATTRIBUTES } from "./stats.js";
|
|
10
|
+
import { createNodeError } from "./errors.js";
|
|
15
11
|
async function mkdir(path, options) {
|
|
16
12
|
let recursive;
|
|
17
|
-
let
|
|
13
|
+
let _mode = 511;
|
|
18
14
|
if (typeof options === "object") {
|
|
19
|
-
if (options.recursive)
|
|
20
|
-
|
|
21
|
-
if (options.mode)
|
|
22
|
-
mode = options.mode;
|
|
15
|
+
if (options.recursive) recursive = options.recursive;
|
|
16
|
+
if (options.mode) _mode = options.mode;
|
|
23
17
|
} else {
|
|
24
|
-
|
|
18
|
+
_mode = options;
|
|
25
19
|
}
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
const pathStr = path.toString();
|
|
21
|
+
if (recursive) {
|
|
22
|
+
return mkdirRecursiveAsync(pathStr);
|
|
23
|
+
}
|
|
24
|
+
const file = Gio.File.new_for_path(pathStr);
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
file.make_directory_async(GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
27
|
+
try {
|
|
28
|
+
file.make_directory_finish(res);
|
|
29
|
+
resolve(void 0);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
reject(createNodeError(err, "mkdir", path));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
29
34
|
});
|
|
30
|
-
|
|
35
|
+
}
|
|
36
|
+
async function mkdirRecursiveAsync(pathStr) {
|
|
37
|
+
const file = Gio.File.new_for_path(pathStr);
|
|
38
|
+
try {
|
|
39
|
+
await new Promise((resolve, reject) => {
|
|
40
|
+
file.make_directory_async(GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
41
|
+
try {
|
|
42
|
+
file.make_directory_finish(res);
|
|
43
|
+
resolve();
|
|
44
|
+
} catch (err) {
|
|
45
|
+
reject(err);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
return pathStr;
|
|
50
|
+
} catch (err) {
|
|
51
|
+
const gErr = err;
|
|
52
|
+
if (gErr.code === Gio.IOErrorEnum.EXISTS) {
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
if (gErr.code === Gio.IOErrorEnum.NOT_FOUND) {
|
|
56
|
+
const parentPath = dirname(pathStr);
|
|
57
|
+
if (parentPath === pathStr) {
|
|
58
|
+
throw createNodeError(err, "mkdir", pathStr);
|
|
59
|
+
}
|
|
60
|
+
const firstCreated = await mkdirRecursiveAsync(parentPath);
|
|
61
|
+
const retryFile = Gio.File.new_for_path(pathStr);
|
|
62
|
+
await new Promise((resolve, reject) => {
|
|
63
|
+
retryFile.make_directory_async(GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
64
|
+
try {
|
|
65
|
+
retryFile.make_directory_finish(res);
|
|
66
|
+
resolve();
|
|
67
|
+
} catch (retryErr) {
|
|
68
|
+
reject(createNodeError(retryErr, "mkdir", pathStr));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
return firstCreated ?? pathStr;
|
|
73
|
+
}
|
|
74
|
+
throw createNodeError(err, "mkdir", pathStr);
|
|
75
|
+
}
|
|
31
76
|
}
|
|
32
77
|
async function readFile(path, options = { encoding: null, flag: "r" }) {
|
|
33
78
|
const file = Gio.File.new_for_path(path.toString());
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
79
|
+
let ok;
|
|
80
|
+
let data;
|
|
81
|
+
try {
|
|
82
|
+
[ok, data] = await new Promise((resolve, reject) => {
|
|
83
|
+
file.load_contents_async(null, (self, res) => {
|
|
84
|
+
try {
|
|
85
|
+
resolve(file.load_contents_finish(res));
|
|
86
|
+
} catch (error) {
|
|
87
|
+
reject(error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
41
90
|
});
|
|
42
|
-
})
|
|
91
|
+
} catch (error) {
|
|
92
|
+
throw createNodeError(error, "open", path.toString());
|
|
93
|
+
}
|
|
43
94
|
if (!ok) {
|
|
44
|
-
throw new Error("failed to read file");
|
|
95
|
+
throw createNodeError(new Error("failed to read file"), "open", path.toString());
|
|
45
96
|
}
|
|
46
97
|
return encodeUint8Array(getEncodingFromOptions(options, "buffer"), data);
|
|
47
98
|
}
|
|
@@ -55,20 +106,103 @@ async function mkdtemp(prefix, options) {
|
|
|
55
106
|
return decode(path, encoding);
|
|
56
107
|
}
|
|
57
108
|
async function writeFile(path, data) {
|
|
58
|
-
|
|
109
|
+
const file = Gio.File.new_for_path(path);
|
|
110
|
+
let bytes;
|
|
111
|
+
if (typeof data === "string") {
|
|
112
|
+
bytes = new TextEncoder().encode(data);
|
|
113
|
+
} else if (data instanceof Uint8Array) {
|
|
114
|
+
bytes = data;
|
|
115
|
+
} else {
|
|
116
|
+
bytes = new TextEncoder().encode(String(data));
|
|
117
|
+
}
|
|
118
|
+
const outputStream = await new Promise((resolve, reject) => {
|
|
119
|
+
file.replace_async(null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
120
|
+
try {
|
|
121
|
+
resolve(file.replace_finish(res));
|
|
122
|
+
} catch (err) {
|
|
123
|
+
reject(createNodeError(err, "open", path));
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
if (bytes.length > 0) {
|
|
128
|
+
const glibBytes = new GLib.Bytes(bytes);
|
|
129
|
+
await new Promise((resolve, reject) => {
|
|
130
|
+
outputStream.write_bytes_async(glibBytes, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
131
|
+
try {
|
|
132
|
+
outputStream.write_bytes_finish(res);
|
|
133
|
+
resolve();
|
|
134
|
+
} catch (err) {
|
|
135
|
+
reject(createNodeError(err, "write", path));
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
await new Promise((resolve, reject) => {
|
|
141
|
+
outputStream.close_async(GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
142
|
+
try {
|
|
143
|
+
outputStream.close_finish(res);
|
|
144
|
+
resolve();
|
|
145
|
+
} catch (err) {
|
|
146
|
+
reject(createNodeError(err, "close", path));
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
});
|
|
59
150
|
}
|
|
60
|
-
async function rmdir(path,
|
|
61
|
-
|
|
151
|
+
async function rmdir(path, _options) {
|
|
152
|
+
const file = Gio.File.new_for_path(path.toString());
|
|
153
|
+
const info = await new Promise((resolve, reject) => {
|
|
154
|
+
file.query_info_async("standard::type", Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
155
|
+
try {
|
|
156
|
+
resolve(file.query_info_finish(res));
|
|
157
|
+
} catch (err) {
|
|
158
|
+
reject(createNodeError(err, "rmdir", path));
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
if (info.get_file_type() !== Gio.FileType.DIRECTORY) {
|
|
163
|
+
const err = Object.assign(new Error(), { code: 4 });
|
|
164
|
+
throw createNodeError(err, "rmdir", path);
|
|
165
|
+
}
|
|
166
|
+
const children = await new Promise((resolve, reject) => {
|
|
167
|
+
file.enumerate_children_async("standard::name", Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
168
|
+
try {
|
|
169
|
+
resolve(file.enumerate_children_finish(res));
|
|
170
|
+
} catch (err) {
|
|
171
|
+
reject(createNodeError(err, "rmdir", path));
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
const firstChild = children.next_file(null);
|
|
176
|
+
if (firstChild !== null) {
|
|
177
|
+
const err = Object.assign(new Error(), { code: 5 });
|
|
178
|
+
throw createNodeError(err, "rmdir", path);
|
|
179
|
+
}
|
|
180
|
+
await new Promise((resolve, reject) => {
|
|
181
|
+
file.delete_async(GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
182
|
+
try {
|
|
183
|
+
file.delete_finish(res);
|
|
184
|
+
resolve();
|
|
185
|
+
} catch (err) {
|
|
186
|
+
reject(createNodeError(err, "rmdir", path));
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
});
|
|
62
190
|
}
|
|
63
191
|
async function unlink(path) {
|
|
64
|
-
|
|
192
|
+
const file = Gio.File.new_for_path(path);
|
|
193
|
+
await new Promise((resolve, reject) => {
|
|
194
|
+
file.delete_async(GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
195
|
+
try {
|
|
196
|
+
file.delete_finish(res);
|
|
197
|
+
resolve();
|
|
198
|
+
} catch (err) {
|
|
199
|
+
reject(createNodeError(err, "unlink", path));
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
});
|
|
65
203
|
}
|
|
66
204
|
async function open(path, flags, mode) {
|
|
67
|
-
return new FileHandle({
|
|
68
|
-
path,
|
|
69
|
-
flags,
|
|
70
|
-
mode
|
|
71
|
-
});
|
|
205
|
+
return new FileHandle({ path, flags, mode });
|
|
72
206
|
}
|
|
73
207
|
async function write(fd, data, positionOrOffset, encodingOrLength, position) {
|
|
74
208
|
if (typeof data === "string") {
|
|
@@ -77,53 +211,122 @@ async function write(fd, data, positionOrOffset, encodingOrLength, position) {
|
|
|
77
211
|
return _writeBuf(fd, data, positionOrOffset, encodingOrLength, position);
|
|
78
212
|
}
|
|
79
213
|
async function _writeBuf(fd, buffer, offset, length, position) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
buffer
|
|
84
|
-
};
|
|
214
|
+
const fileHandle = FileHandle.getInstance(fd);
|
|
215
|
+
const result = await fileHandle.write(buffer, offset, length, position);
|
|
216
|
+
return { bytesWritten: result.bytesWritten, buffer };
|
|
85
217
|
}
|
|
86
218
|
async function _writeStr(fd, data, position, encoding) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
219
|
+
const fileHandle = FileHandle.getInstance(fd);
|
|
220
|
+
const result = await fileHandle.write(data, position, encoding);
|
|
221
|
+
return { bytesWritten: result.bytesWritten, buffer: data };
|
|
222
|
+
}
|
|
223
|
+
function queryInfoAsync(path, flags, syscall, options) {
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
const file = Gio.File.new_for_path(path.toString());
|
|
226
|
+
file.query_info_async(STAT_ATTRIBUTES, flags, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
227
|
+
try {
|
|
228
|
+
const info = file.query_info_finish(res);
|
|
229
|
+
resolve(options?.bigint ? new BigIntStats(info, path) : new Stats(info, path));
|
|
230
|
+
} catch (err) {
|
|
231
|
+
reject(createNodeError(err, syscall, path));
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
async function stat(path, options) {
|
|
237
|
+
return queryInfoAsync(path, Gio.FileQueryInfoFlags.NONE, "stat", options);
|
|
238
|
+
}
|
|
239
|
+
async function lstat(path, options) {
|
|
240
|
+
return queryInfoAsync(path, Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, "lstat", options);
|
|
241
|
+
}
|
|
242
|
+
async function readdir(path, options) {
|
|
243
|
+
try {
|
|
244
|
+
return readdirSyncFn(path, options);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
throw createNodeError(error, "scandir", path);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async function realpath(path) {
|
|
250
|
+
return realpathSync(path);
|
|
251
|
+
}
|
|
252
|
+
async function symlink(target, path, _type) {
|
|
253
|
+
return new Promise((resolve, reject) => {
|
|
254
|
+
const file = Gio.File.new_for_path(path.toString());
|
|
255
|
+
file.make_symbolic_link_async(target.toString(), GLib.PRIORITY_DEFAULT, null, (_s, res) => {
|
|
256
|
+
try {
|
|
257
|
+
file.make_symbolic_link_finish(res);
|
|
258
|
+
resolve();
|
|
259
|
+
} catch (err) {
|
|
260
|
+
reject(createNodeError(err, "symlink", target, path));
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
});
|
|
92
264
|
}
|
|
93
265
|
async function rm(path, options) {
|
|
94
|
-
const
|
|
266
|
+
const pathStr = path.toString();
|
|
267
|
+
const file = Gio.File.new_for_path(pathStr);
|
|
95
268
|
const recursive = options?.recursive || false;
|
|
96
|
-
const
|
|
269
|
+
const force = options?.force || false;
|
|
270
|
+
let dirent;
|
|
271
|
+
try {
|
|
272
|
+
dirent = new Dirent(pathStr);
|
|
273
|
+
} catch (err) {
|
|
274
|
+
if (force) return;
|
|
275
|
+
throw createNodeError(err, "rm", path);
|
|
276
|
+
}
|
|
97
277
|
if (dirent.isDirectory()) {
|
|
98
278
|
const childFiles = await readdir(path, { withFileTypes: true });
|
|
99
279
|
if (!recursive && childFiles.length) {
|
|
100
|
-
|
|
280
|
+
const err = Object.assign(new Error(), { code: 5 });
|
|
281
|
+
throw createNodeError(err, "rm", path);
|
|
101
282
|
}
|
|
102
283
|
for (const childFile of childFiles) {
|
|
103
|
-
if (childFile
|
|
104
|
-
await
|
|
105
|
-
} else if (childFile.isFile()) {
|
|
106
|
-
await rm(join(path.toString(), childFile.name), options);
|
|
284
|
+
if (typeof childFile !== "string") {
|
|
285
|
+
await rm(join(pathStr, childFile.name), options);
|
|
107
286
|
}
|
|
108
287
|
}
|
|
109
288
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
289
|
+
await new Promise((resolve, reject) => {
|
|
290
|
+
file.delete_async(GLib.PRIORITY_DEFAULT, null, (_self, res) => {
|
|
291
|
+
try {
|
|
292
|
+
file.delete_finish(res);
|
|
293
|
+
resolve();
|
|
294
|
+
} catch (err) {
|
|
295
|
+
if (force) {
|
|
296
|
+
resolve();
|
|
297
|
+
return;
|
|
117
298
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
299
|
+
reject(createNodeError(err, "rm", path));
|
|
300
|
+
}
|
|
301
|
+
});
|
|
122
302
|
});
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
303
|
+
}
|
|
304
|
+
async function rename(oldPath, newPath) {
|
|
305
|
+
renameSync(oldPath, newPath);
|
|
306
|
+
}
|
|
307
|
+
async function copyFile(src, dest, mode) {
|
|
308
|
+
copyFileSync(src, dest, mode);
|
|
309
|
+
}
|
|
310
|
+
async function access(path, mode) {
|
|
311
|
+
accessSync(path, mode);
|
|
312
|
+
}
|
|
313
|
+
async function appendFile(path, data, options) {
|
|
314
|
+
appendFileSync(path, data, options);
|
|
315
|
+
}
|
|
316
|
+
async function readlink(path, options) {
|
|
317
|
+
return readlinkSync(path, options);
|
|
318
|
+
}
|
|
319
|
+
async function truncate(path, len) {
|
|
320
|
+
truncateSync(path, len);
|
|
321
|
+
}
|
|
322
|
+
async function chmod(path, mode) {
|
|
323
|
+
chmodSync(path, mode);
|
|
324
|
+
}
|
|
325
|
+
async function chown(path, uid, gid) {
|
|
326
|
+
chownSync(path, uid, gid);
|
|
327
|
+
}
|
|
328
|
+
async function link(existingPath, newPath) {
|
|
329
|
+
linkSync(existingPath, newPath);
|
|
127
330
|
}
|
|
128
331
|
var promises_default = {
|
|
129
332
|
readFile,
|
|
@@ -139,21 +342,39 @@ var promises_default = {
|
|
|
139
342
|
rm,
|
|
140
343
|
lstat,
|
|
141
344
|
symlink,
|
|
142
|
-
stat
|
|
345
|
+
stat,
|
|
346
|
+
rename,
|
|
347
|
+
copyFile,
|
|
348
|
+
access,
|
|
349
|
+
appendFile,
|
|
350
|
+
readlink,
|
|
351
|
+
truncate,
|
|
352
|
+
chmod,
|
|
353
|
+
chown,
|
|
354
|
+
link
|
|
143
355
|
};
|
|
144
356
|
export {
|
|
357
|
+
access,
|
|
358
|
+
appendFile,
|
|
359
|
+
chmod,
|
|
360
|
+
chown,
|
|
361
|
+
copyFile,
|
|
145
362
|
promises_default as default,
|
|
363
|
+
link,
|
|
146
364
|
lstat,
|
|
147
365
|
mkdir,
|
|
148
366
|
mkdtemp,
|
|
149
367
|
open,
|
|
150
368
|
readFile,
|
|
151
369
|
readdir,
|
|
370
|
+
readlink,
|
|
152
371
|
realpath,
|
|
372
|
+
rename,
|
|
153
373
|
rm,
|
|
154
374
|
rmdir,
|
|
155
375
|
stat,
|
|
156
376
|
symlink,
|
|
377
|
+
truncate,
|
|
157
378
|
unlink,
|
|
158
379
|
write,
|
|
159
380
|
writeFile
|
package/lib/esm/read-stream.js
CHANGED
|
@@ -1,71 +1,97 @@
|
|
|
1
|
+
import Gio from "@girs/gio-2.0";
|
|
1
2
|
import GLib from "@girs/glib-2.0";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { URL } from "url";
|
|
6
|
-
function fromFileUrl(url) {
|
|
7
|
-
url = url instanceof URL ? url : new URL(url);
|
|
8
|
-
if (url.protocol != "file:") {
|
|
9
|
-
throw new TypeError("Must be a file URL.");
|
|
10
|
-
}
|
|
11
|
-
return decodeURIComponent(
|
|
12
|
-
url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25")
|
|
13
|
-
);
|
|
14
|
-
}
|
|
3
|
+
import { Buffer } from "node:buffer";
|
|
4
|
+
import { Readable } from "node:stream";
|
|
5
|
+
import { URL, fileURLToPath } from "node:url";
|
|
15
6
|
class ReadStream extends Readable {
|
|
7
|
+
bytesRead = 0;
|
|
8
|
+
path;
|
|
9
|
+
pending = true;
|
|
10
|
+
fd = null;
|
|
11
|
+
_gioFile;
|
|
12
|
+
_inputStream = null;
|
|
13
|
+
_start;
|
|
14
|
+
_end;
|
|
15
|
+
_pos;
|
|
16
16
|
close(callback) {
|
|
17
|
-
|
|
17
|
+
if (this._inputStream) {
|
|
18
|
+
try {
|
|
19
|
+
this._inputStream.close(null);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
this._inputStream = null;
|
|
23
|
+
}
|
|
24
|
+
this.destroy();
|
|
25
|
+
if (callback) callback(null);
|
|
18
26
|
}
|
|
19
|
-
/**
|
|
20
|
-
* The number of bytes that have been read so far.
|
|
21
|
-
* @since v6.4.0
|
|
22
|
-
*/
|
|
23
|
-
bytesRead;
|
|
24
|
-
/**
|
|
25
|
-
* The path to the file the stream is reading from as specified in the first
|
|
26
|
-
* argument to `fs.createReadStream()`. If `path` is passed as a string, then`readStream.path` will be a string. If `path` is passed as a `Buffer`, then`readStream.path` will be a
|
|
27
|
-
* `Buffer`. If `fd` is specified, then`readStream.path` will be `undefined`.
|
|
28
|
-
* @since v0.1.93
|
|
29
|
-
*/
|
|
30
|
-
path;
|
|
31
|
-
/**
|
|
32
|
-
* This property is `true` if the underlying file has not been opened yet,
|
|
33
|
-
* i.e. before the `'ready'` event is emitted.
|
|
34
|
-
* @since v11.2.0, v10.16.0
|
|
35
|
-
*/
|
|
36
|
-
pending;
|
|
37
27
|
constructor(path, opts) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (hasBadOptions) {
|
|
41
|
-
notImplemented(
|
|
42
|
-
`fs.ReadStream.prototype.constructor with unsupported options (${JSON.stringify(opts)})`
|
|
43
|
-
);
|
|
28
|
+
if (path instanceof URL) {
|
|
29
|
+
path = fileURLToPath(path);
|
|
44
30
|
}
|
|
45
|
-
const file = GLib.IOChannel.new_file(path.toString(), "r");
|
|
46
|
-
const buffer = "";
|
|
47
31
|
super({
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
objectMode: false
|
|
51
|
-
|
|
32
|
+
highWaterMark: opts?.highWaterMark ?? 64 * 1024,
|
|
33
|
+
encoding: opts?.encoding,
|
|
34
|
+
objectMode: false
|
|
35
|
+
});
|
|
36
|
+
this.path = path.toString();
|
|
37
|
+
this._gioFile = Gio.File.new_for_path(this.path.toString());
|
|
38
|
+
this._start = opts?.start ?? 0;
|
|
39
|
+
this._end = opts?.end ?? Infinity;
|
|
40
|
+
this._pos = this._start;
|
|
41
|
+
Promise.resolve().then(() => {
|
|
42
|
+
if (!this._inputStream && !this.destroyed) {
|
|
52
43
|
try {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this.
|
|
44
|
+
this._inputStream = this._gioFile.read(null);
|
|
45
|
+
this.pending = false;
|
|
46
|
+
this.emit("open", 0);
|
|
47
|
+
this.emit("ready");
|
|
48
|
+
if (this._start > 0 && this._inputStream.can_seek()) {
|
|
49
|
+
this._inputStream.seek(this._start, GLib.SeekType.SET, null);
|
|
50
|
+
}
|
|
56
51
|
} catch (err) {
|
|
57
52
|
this.destroy(err);
|
|
58
53
|
}
|
|
59
|
-
},
|
|
60
|
-
destroy: (err, cb) => {
|
|
61
|
-
try {
|
|
62
|
-
file.close();
|
|
63
|
-
} catch {
|
|
64
|
-
}
|
|
65
|
-
cb(err);
|
|
66
54
|
}
|
|
67
55
|
});
|
|
68
|
-
|
|
56
|
+
}
|
|
57
|
+
_read(size) {
|
|
58
|
+
if (!this._inputStream) {
|
|
59
|
+
if (this.destroyed) return;
|
|
60
|
+
Promise.resolve().then(() => this._read(size));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
let toRead = size;
|
|
64
|
+
if (this._end !== Infinity) {
|
|
65
|
+
const remaining = this._end - this._pos + 1;
|
|
66
|
+
if (remaining <= 0) {
|
|
67
|
+
this.push(null);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
toRead = Math.min(size, remaining);
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const gbytes = this._inputStream.read_bytes(toRead, null);
|
|
74
|
+
const data = gbytes.get_data();
|
|
75
|
+
if (!data || data.length === 0) {
|
|
76
|
+
this.push(null);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.bytesRead += data.length;
|
|
80
|
+
this._pos += data.length;
|
|
81
|
+
this.push(Buffer.from(data));
|
|
82
|
+
} catch (err) {
|
|
83
|
+
this.destroy(err);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
_destroy(error, callback) {
|
|
87
|
+
if (this._inputStream) {
|
|
88
|
+
try {
|
|
89
|
+
this._inputStream.close(null);
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
this._inputStream = null;
|
|
93
|
+
}
|
|
94
|
+
callback(error);
|
|
69
95
|
}
|
|
70
96
|
}
|
|
71
97
|
function createReadStream(path, options) {
|
|
@@ -73,6 +99,5 @@ function createReadStream(path, options) {
|
|
|
73
99
|
}
|
|
74
100
|
export {
|
|
75
101
|
ReadStream,
|
|
76
|
-
createReadStream
|
|
77
|
-
fromFileUrl
|
|
102
|
+
createReadStream
|
|
78
103
|
};
|