@gjsify/fs 0.1.15 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/lib/esm/callback.js +22 -13
  2. package/lib/esm/cp.js +253 -0
  3. package/lib/esm/dir.js +160 -0
  4. package/lib/esm/fd-ops.js +189 -0
  5. package/lib/esm/file-handle.js +263 -84
  6. package/lib/esm/fs-watcher.js +88 -4
  7. package/lib/esm/glob.js +164 -0
  8. package/lib/esm/index.js +128 -2
  9. package/lib/esm/promises.js +90 -27
  10. package/lib/esm/read-stream.js +53 -43
  11. package/lib/esm/stat-watcher.js +121 -0
  12. package/lib/esm/statfs.js +57 -0
  13. package/lib/esm/sync.js +70 -52
  14. package/lib/esm/utils.js +7 -0
  15. package/lib/esm/utimes.js +62 -0
  16. package/lib/esm/write-stream.js +2 -5
  17. package/lib/types/cp.d.ts +18 -0
  18. package/lib/types/cp.spec.d.ts +2 -0
  19. package/lib/types/dir.d.ts +29 -0
  20. package/lib/types/dir.spec.d.ts +2 -0
  21. package/lib/types/fd-ops.d.ts +57 -0
  22. package/lib/types/fd-ops.spec.d.ts +2 -0
  23. package/lib/types/file-handle.d.ts +34 -4
  24. package/lib/types/fs-watcher.d.ts +9 -2
  25. package/lib/types/glob.d.ts +8 -0
  26. package/lib/types/glob.spec.d.ts +2 -0
  27. package/lib/types/index.d.ts +51 -1
  28. package/lib/types/promises.d.ts +31 -4
  29. package/lib/types/read-stream.d.ts +3 -1
  30. package/lib/types/stat-watcher.d.ts +21 -0
  31. package/lib/types/statfs.d.ts +35 -0
  32. package/lib/types/statfs.spec.d.ts +2 -0
  33. package/lib/types/sync.d.ts +4 -7
  34. package/lib/types/utils.d.ts +2 -0
  35. package/lib/types/utimes.d.ts +13 -0
  36. package/lib/types/utimes.spec.d.ts +2 -0
  37. package/lib/types/watch.spec.d.ts +2 -0
  38. package/lib/types/watchfile.spec.d.ts +2 -0
  39. package/lib/types/write-stream.d.ts +1 -2
  40. package/package.json +12 -12
  41. package/src/callback.ts +22 -13
  42. package/src/cp.spec.ts +181 -0
  43. package/src/cp.ts +328 -0
  44. package/src/dir.spec.ts +204 -0
  45. package/src/dir.ts +199 -0
  46. package/src/fd-ops.spec.ts +234 -0
  47. package/src/fd-ops.ts +251 -0
  48. package/src/file-handle.ts +264 -94
  49. package/src/fs-watcher.ts +101 -6
  50. package/src/glob.spec.ts +201 -0
  51. package/src/glob.ts +205 -0
  52. package/src/index.ts +74 -0
  53. package/src/promises.ts +94 -29
  54. package/src/read-stream.ts +49 -43
  55. package/src/stat-watcher.ts +116 -0
  56. package/src/statfs.spec.ts +67 -0
  57. package/src/statfs.ts +92 -0
  58. package/src/streams.spec.ts +58 -0
  59. package/src/sync.ts +75 -57
  60. package/src/test.mts +13 -2
  61. package/src/utils.ts +10 -0
  62. package/src/utimes.spec.ts +113 -0
  63. package/src/utimes.ts +97 -0
  64. package/src/watch.spec.ts +171 -0
  65. package/src/watchfile.spec.ts +185 -0
  66. package/src/write-stream.ts +5 -8
  67. package/tsconfig.tsbuildinfo +1 -1
@@ -6,17 +6,19 @@ import { Buffer } from "node:buffer";
6
6
  import { Stats, BigIntStats, STAT_ATTRIBUTES } from "./stats.js";
7
7
  import { createNodeError } from "./errors.js";
8
8
  import { realpathSync, readdirSync, renameSync, copyFileSync, accessSync, appendFileSync, readlinkSync, truncateSync, chmodSync, chownSync, mkdirSync, rmdirSync, readFileSync, writeFileSync } from "./sync.js";
9
+ import { normalizePath } from "./utils.js";
9
10
  function parseOptsCb(optionsOrCallback, maybeCallback) {
10
11
  return typeof optionsOrCallback === "function" ? { options: {}, callback: optionsOrCallback } : { options: optionsOrCallback ?? {}, callback: maybeCallback };
11
12
  }
12
13
  function statImpl(path, flags, syscall, options, callback) {
13
- const file = Gio.File.new_for_path(path.toString());
14
+ const pathStr = normalizePath(path);
15
+ const file = Gio.File.new_for_path(pathStr);
14
16
  file.query_info_async(STAT_ATTRIBUTES, flags, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
15
17
  try {
16
18
  const info = file.query_info_finish(res);
17
- callback(null, options?.bigint ? new BigIntStats(info, path) : new Stats(info, path));
19
+ callback(null, options?.bigint ? new BigIntStats(info, pathStr) : new Stats(info, pathStr));
18
20
  } catch (err) {
19
- callback(createNodeError(err, syscall, path));
21
+ callback(createNodeError(err, syscall, pathStr));
20
22
  }
21
23
  });
22
24
  }
@@ -53,13 +55,15 @@ function symlink(target, path, typeOrCallback, maybeCallback) {
53
55
  if (typeof callback !== "function") {
54
56
  throw new TypeError("Callback must be a function. Received " + typeof callback);
55
57
  }
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
+ const pathStr = normalizePath(path);
59
+ const targetStr = normalizePath(target);
60
+ const file = Gio.File.new_for_path(pathStr);
61
+ file.make_symbolic_link_async(targetStr, GLib.PRIORITY_DEFAULT, null, (_s, res) => {
58
62
  try {
59
63
  file.make_symbolic_link_finish(res);
60
64
  callback(null);
61
65
  } catch (err) {
62
- callback(createNodeError(err, "symlink", target, path));
66
+ callback(createNodeError(err, "symlink", targetStr, pathStr));
63
67
  }
64
68
  });
65
69
  }
@@ -271,10 +275,11 @@ function rmdir(path, optsOrCb, maybeCb) {
271
275
  function readFile(path, optsOrCb, maybeCb) {
272
276
  const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
273
277
  const options = typeof optsOrCb === "function" ? void 0 : optsOrCb;
278
+ const pathStr = normalizePath(path);
274
279
  Promise.resolve().then(() => {
275
280
  try {
276
281
  const readOpts = typeof options === "string" ? { encoding: options, flag: "r" } : { encoding: options?.encoding ?? null, flag: options?.flag ?? "r" };
277
- callback(null, readFileSync(path.toString(), readOpts));
282
+ callback(null, readFileSync(pathStr, readOpts));
278
283
  } catch (err) {
279
284
  callback(err, null);
280
285
  }
@@ -282,9 +287,10 @@ function readFile(path, optsOrCb, maybeCb) {
282
287
  }
283
288
  function writeFile(path, data, optsOrCb, maybeCb) {
284
289
  const callback = typeof optsOrCb === "function" ? optsOrCb : maybeCb;
290
+ const pathStr = normalizePath(path);
285
291
  Promise.resolve().then(() => {
286
292
  try {
287
- writeFileSync(path.toString(), data);
293
+ writeFileSync(pathStr, data);
288
294
  callback(null);
289
295
  } catch (err) {
290
296
  callback(err);
@@ -292,16 +298,18 @@ function writeFile(path, data, optsOrCb, maybeCb) {
292
298
  });
293
299
  }
294
300
  function link(existingPath, newPath, callback) {
301
+ const existingStr = normalizePath(existingPath);
302
+ const newStr = normalizePath(newPath);
295
303
  Promise.resolve().then(() => {
296
304
  try {
297
- const result = GLib.spawn_command_line_sync(`ln ${existingPath.toString()} ${newPath.toString()}`);
305
+ const result = GLib.spawn_command_line_sync(`ln ${existingStr} ${newStr}`);
298
306
  if (!result[0]) {
299
- throw Object.assign(new Error(`EPERM: operation not permitted, link '${existingPath}' -> '${newPath}'`), {
307
+ throw Object.assign(new Error(`EPERM: operation not permitted, link '${existingStr}' -> '${newStr}'`), {
300
308
  code: "EPERM",
301
309
  errno: -1,
302
310
  syscall: "link",
303
- path: existingPath.toString(),
304
- dest: newPath.toString()
311
+ path: existingStr,
312
+ dest: newStr
305
313
  });
306
314
  }
307
315
  callback(null);
@@ -311,9 +319,10 @@ function link(existingPath, newPath, callback) {
311
319
  });
312
320
  }
313
321
  function unlink(path, callback) {
322
+ const pathStr = normalizePath(path);
314
323
  Promise.resolve().then(() => {
315
324
  try {
316
- GLib.unlink(path.toString());
325
+ GLib.unlink(pathStr);
317
326
  callback(null);
318
327
  } catch (err) {
319
328
  callback(err);
package/lib/esm/cp.js ADDED
@@ -0,0 +1,253 @@
1
+ import Gio from "@girs/gio-2.0";
2
+ import { join } from "node:path";
3
+ import { normalizePath } from "./utils.js";
4
+ import { createNodeError } from "./errors.js";
5
+ function makeEEXIST(destStr) {
6
+ const e = new Error(`ERR_FS_CP_EEXIST: file already exists, copyfile '${destStr}'`);
7
+ e.code = "ERR_FS_CP_EEXIST";
8
+ e.syscall = "copyfile";
9
+ e.path = destStr;
10
+ return e;
11
+ }
12
+ function makeEISDIR(srcStr) {
13
+ const e = new Error(`ERR_FS_EISDIR: illegal operation on a directory, copyfile '${srcStr}'`);
14
+ e.code = "ERR_FS_EISDIR";
15
+ e.syscall = "copyfile";
16
+ e.path = srcStr;
17
+ return e;
18
+ }
19
+ function makeENOTDIR(srcStr, destStr) {
20
+ const e = new Error(`ENOTDIR: not a directory, copyfile '${srcStr}' -> '${destStr}'`);
21
+ e.code = "ENOTDIR";
22
+ e.syscall = "copyfile";
23
+ e.path = srcStr;
24
+ e.dest = destStr;
25
+ return e;
26
+ }
27
+ function makeSYMLINKLOOP(srcStr, destStr) {
28
+ const e = new Error(`ELOOP: too many levels of symbolic links, copyfile '${srcStr}' -> '${destStr}'`);
29
+ e.code = "ELOOP";
30
+ e.syscall = "copyfile";
31
+ e.path = srcStr;
32
+ e.dest = destStr;
33
+ return e;
34
+ }
35
+ function queryCopyFlags(opts) {
36
+ const force = opts.force ?? true;
37
+ let flags = Gio.FileCopyFlags.NONE;
38
+ if (force) flags |= Gio.FileCopyFlags.OVERWRITE;
39
+ if (opts.preserveTimestamps) flags |= Gio.FileCopyFlags.TARGET_DEFAULT_MODIFIED_TIME;
40
+ if (!opts.dereference) flags |= Gio.FileCopyFlags.NOFOLLOW_SYMLINKS;
41
+ return flags;
42
+ }
43
+ function copyOneSyncFile(srcFile, destFile, srcStr, destStr, opts) {
44
+ const force = opts.force ?? true;
45
+ try {
46
+ const destInfo = destFile.query_info("standard::type", Gio.FileQueryInfoFlags.NONE, null);
47
+ if (destInfo.get_file_type() === Gio.FileType.DIRECTORY) {
48
+ throw makeENOTDIR(srcStr, destStr);
49
+ }
50
+ if (!force) {
51
+ if (opts.errorOnExist) throw makeEEXIST(destStr);
52
+ return;
53
+ }
54
+ } catch (e) {
55
+ if (typeof e.code === "string") throw e;
56
+ }
57
+ const flags = queryCopyFlags(opts);
58
+ try {
59
+ srcFile.copy(destFile, flags, null, null);
60
+ } catch (err) {
61
+ throw createNodeError(err, "copyfile", srcStr, destStr);
62
+ }
63
+ }
64
+ function cpOneDirSync(srcFile, destFile, srcStr, destStr, opts) {
65
+ const sep = srcStr.endsWith("/") ? "" : "/";
66
+ if (destStr.startsWith(srcStr + sep) && destStr !== srcStr) {
67
+ throw makeSYMLINKLOOP(srcStr, destStr);
68
+ }
69
+ if (!destFile.query_exists(null)) {
70
+ try {
71
+ destFile.make_directory_with_parents(null);
72
+ } catch (err) {
73
+ throw createNodeError(err, "mkdir", destStr);
74
+ }
75
+ } else {
76
+ try {
77
+ const destInfo = destFile.query_info("standard::type", Gio.FileQueryInfoFlags.NONE, null);
78
+ if (destInfo.get_file_type() !== Gio.FileType.DIRECTORY) {
79
+ throw makeENOTDIR(destStr, srcStr);
80
+ }
81
+ } catch (e) {
82
+ if (typeof e.code === "string") throw e;
83
+ }
84
+ }
85
+ let enumerator;
86
+ try {
87
+ enumerator = srcFile.enumerate_children(
88
+ "standard::name,standard::type,standard::is-symlink",
89
+ opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
90
+ null
91
+ );
92
+ } catch (err) {
93
+ throw createNodeError(err, "scandir", srcStr);
94
+ }
95
+ let childInfo = enumerator.next_file(null);
96
+ while (childInfo !== null) {
97
+ const name = childInfo.get_name();
98
+ const childSrc = join(srcStr, name);
99
+ const childDest = join(destStr, name);
100
+ const filter = opts.filter;
101
+ if (filter && !filter(childSrc, childDest)) {
102
+ childInfo = enumerator.next_file(null);
103
+ continue;
104
+ }
105
+ cpSyncInternal(childSrc, childDest, opts);
106
+ childInfo = enumerator.next_file(null);
107
+ }
108
+ }
109
+ function cpSyncInternal(srcStr, destStr, opts) {
110
+ const srcFile = Gio.File.new_for_path(srcStr);
111
+ const destFile = Gio.File.new_for_path(destStr);
112
+ let info;
113
+ try {
114
+ info = srcFile.query_info(
115
+ "standard::type,standard::is-symlink",
116
+ opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
117
+ null
118
+ );
119
+ } catch (err) {
120
+ throw createNodeError(err, "stat", srcStr);
121
+ }
122
+ const type = info.get_file_type();
123
+ if (type === Gio.FileType.DIRECTORY) {
124
+ if (!opts.recursive) throw makeEISDIR(srcStr);
125
+ cpOneDirSync(srcFile, destFile, srcStr, destStr, opts);
126
+ } else {
127
+ copyOneSyncFile(srcFile, destFile, srcStr, destStr, opts);
128
+ }
129
+ }
130
+ function cpSync(src, dest, options) {
131
+ const srcStr = normalizePath(src);
132
+ const destStr = normalizePath(dest);
133
+ const opts = options ?? {};
134
+ const srcFile = Gio.File.new_for_path(srcStr);
135
+ const filter = opts.filter;
136
+ if (filter && !filter(srcStr, destStr)) return;
137
+ try {
138
+ const info = srcFile.query_info(
139
+ "standard::type",
140
+ opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
141
+ null
142
+ );
143
+ if (info.get_file_type() === Gio.FileType.DIRECTORY && !opts.recursive) {
144
+ throw makeEISDIR(srcStr);
145
+ }
146
+ } catch (e) {
147
+ if (typeof e.code === "string") throw e;
148
+ throw createNodeError(e, "stat", srcStr);
149
+ }
150
+ cpSyncInternal(srcStr, destStr, opts);
151
+ }
152
+ function cp(src, dest, options, callback) {
153
+ let opts;
154
+ let cb;
155
+ if (typeof options === "function") {
156
+ cb = options;
157
+ opts = {};
158
+ } else {
159
+ cb = callback;
160
+ opts = options;
161
+ }
162
+ const asyncFilter = opts.filter;
163
+ if (asyncFilter) {
164
+ Promise.resolve(asyncFilter(normalizePath(src), normalizePath(dest))).then((include) => {
165
+ if (!include) {
166
+ cb(null);
167
+ return;
168
+ }
169
+ try {
170
+ cpPromises(src, dest, opts).then(() => cb(null)).catch(cb);
171
+ } catch (e) {
172
+ cb(e);
173
+ }
174
+ }).catch(cb);
175
+ return;
176
+ }
177
+ Promise.resolve().then(() => {
178
+ try {
179
+ cpSync(src, dest, opts);
180
+ cb(null);
181
+ } catch (e) {
182
+ cb(e);
183
+ }
184
+ });
185
+ }
186
+ async function cpPromisesDir(srcStr, destStr, opts) {
187
+ const sep = srcStr.endsWith("/") ? "" : "/";
188
+ if (destStr.startsWith(srcStr + sep) && destStr !== srcStr) {
189
+ throw makeSYMLINKLOOP(srcStr, destStr);
190
+ }
191
+ const destFile = Gio.File.new_for_path(destStr);
192
+ if (!destFile.query_exists(null)) {
193
+ try {
194
+ destFile.make_directory_with_parents(null);
195
+ } catch (err) {
196
+ throw createNodeError(err, "mkdir", destStr);
197
+ }
198
+ }
199
+ const srcFile = Gio.File.new_for_path(srcStr);
200
+ let enumerator;
201
+ try {
202
+ enumerator = srcFile.enumerate_children(
203
+ "standard::name,standard::type",
204
+ opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
205
+ null
206
+ );
207
+ } catch (err) {
208
+ throw createNodeError(err, "scandir", srcStr);
209
+ }
210
+ let childInfo = enumerator.next_file(null);
211
+ while (childInfo !== null) {
212
+ const name = childInfo.get_name();
213
+ const childSrc = join(srcStr, name);
214
+ const childDest = join(destStr, name);
215
+ const filter = opts.filter;
216
+ if (filter) {
217
+ const include = await Promise.resolve(filter(childSrc, childDest));
218
+ if (!include) {
219
+ childInfo = enumerator.next_file(null);
220
+ continue;
221
+ }
222
+ }
223
+ await cpPromises(childSrc, childDest, opts);
224
+ childInfo = enumerator.next_file(null);
225
+ }
226
+ }
227
+ async function cpPromises(src, dest, opts = {}) {
228
+ const srcStr = normalizePath(src);
229
+ const destStr = normalizePath(dest);
230
+ const srcFile = Gio.File.new_for_path(srcStr);
231
+ let info;
232
+ try {
233
+ info = srcFile.query_info(
234
+ "standard::type",
235
+ opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
236
+ null
237
+ );
238
+ } catch (err) {
239
+ throw createNodeError(err, "stat", srcStr);
240
+ }
241
+ if (info.get_file_type() === Gio.FileType.DIRECTORY) {
242
+ if (!opts.recursive) throw makeEISDIR(srcStr);
243
+ await cpPromisesDir(srcStr, destStr, opts);
244
+ } else {
245
+ const destFile = Gio.File.new_for_path(destStr);
246
+ copyOneSyncFile(srcFile, destFile, srcStr, destStr, opts);
247
+ }
248
+ }
249
+ export {
250
+ cp,
251
+ cpPromises as cpAsync,
252
+ cpSync
253
+ };
package/lib/esm/dir.js ADDED
@@ -0,0 +1,160 @@
1
+ import Gio from "@girs/gio-2.0";
2
+ import GLib from "@girs/glib-2.0";
3
+ import { normalizePath } from "./utils.js";
4
+ import { Dirent } from "./dirent.js";
5
+ import { createNodeError } from "./errors.js";
6
+ const DIR_ATTRS = "standard::name,standard::type,standard::is-symlink,standard::size,standard::symlink-target,unix::uid,unix::gid,unix::mode,time::modified,time::access,time::created";
7
+ class Dir {
8
+ path;
9
+ _enumerator;
10
+ _closed = false;
11
+ constructor(path, enumerator) {
12
+ this.path = path;
13
+ this._enumerator = enumerator;
14
+ }
15
+ _assertOpen() {
16
+ if (this._closed) {
17
+ const err = new Error("Directory handle was closed");
18
+ err.code = "ERR_DIR_CLOSED";
19
+ throw err;
20
+ }
21
+ }
22
+ readSync() {
23
+ this._assertOpen();
24
+ try {
25
+ const info = this._enumerator.next_file(null);
26
+ if (info === null) return null;
27
+ const name = info.get_name();
28
+ const fileType = info.get_file_type();
29
+ const childPath = this.path.endsWith("/") ? this.path + name : this.path + "/" + name;
30
+ return new Dirent(childPath, name, fileType);
31
+ } catch (err) {
32
+ throw createNodeError(err, "readdir", this.path);
33
+ }
34
+ }
35
+ read(callback) {
36
+ if (callback !== void 0) {
37
+ if (typeof callback !== "function") {
38
+ throw new TypeError('The "callback" argument must be of type function');
39
+ }
40
+ try {
41
+ this._assertOpen();
42
+ const dirent = this.readSync();
43
+ Promise.resolve().then(() => callback(null, dirent));
44
+ } catch (err) {
45
+ Promise.resolve().then(() => callback(err, null));
46
+ }
47
+ return;
48
+ }
49
+ return new Promise((resolve, reject) => {
50
+ try {
51
+ this._assertOpen();
52
+ resolve(this.readSync());
53
+ } catch (err) {
54
+ reject(err);
55
+ }
56
+ });
57
+ }
58
+ closeSync() {
59
+ this._assertOpen();
60
+ this._closed = true;
61
+ try {
62
+ this._enumerator.close(null);
63
+ } catch {
64
+ }
65
+ this._enumerator = null;
66
+ }
67
+ close(callback) {
68
+ if (callback !== void 0) {
69
+ if (typeof callback !== "function") {
70
+ throw new TypeError('The "callback" argument must be of type function');
71
+ }
72
+ try {
73
+ this.closeSync();
74
+ Promise.resolve().then(() => callback(null));
75
+ } catch (err) {
76
+ Promise.resolve().then(() => callback(err));
77
+ }
78
+ return;
79
+ }
80
+ return new Promise((resolve, reject) => {
81
+ try {
82
+ this.closeSync();
83
+ resolve();
84
+ } catch (err) {
85
+ reject(err);
86
+ }
87
+ });
88
+ }
89
+ async *[Symbol.asyncIterator]() {
90
+ try {
91
+ while (true) {
92
+ const dirent = await this.read();
93
+ if (dirent === null) break;
94
+ yield dirent;
95
+ }
96
+ } finally {
97
+ if (!this._closed) {
98
+ await this.close();
99
+ }
100
+ }
101
+ }
102
+ }
103
+ function _openDir(pathStr) {
104
+ const file = Gio.File.new_for_path(pathStr);
105
+ let enumerator;
106
+ try {
107
+ enumerator = file.enumerate_children(DIR_ATTRS, Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
108
+ } catch (err) {
109
+ throw createNodeError(err, "opendir", pathStr);
110
+ }
111
+ return new Dir(pathStr, enumerator);
112
+ }
113
+ function opendirSync(path) {
114
+ return _openDir(normalizePath(path));
115
+ }
116
+ function opendir(path, optionsOrCallback, callback) {
117
+ let cb;
118
+ if (typeof optionsOrCallback === "function") {
119
+ cb = optionsOrCallback;
120
+ } else {
121
+ cb = callback;
122
+ }
123
+ if (typeof cb !== "function") {
124
+ throw new TypeError('The "callback" argument must be of type function');
125
+ }
126
+ Promise.resolve().then(() => {
127
+ try {
128
+ const dir = opendirSync(path);
129
+ cb(null, dir);
130
+ } catch (err) {
131
+ cb(err, null);
132
+ }
133
+ });
134
+ }
135
+ async function opendirAsync(path, _options) {
136
+ return new Promise((resolve, reject) => {
137
+ const pathStr = normalizePath(path);
138
+ const file = Gio.File.new_for_path(pathStr);
139
+ file.enumerate_children_async(
140
+ DIR_ATTRS,
141
+ Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
142
+ GLib.PRIORITY_DEFAULT,
143
+ null,
144
+ (_source, result) => {
145
+ try {
146
+ const enumerator = file.enumerate_children_finish(result);
147
+ resolve(new Dir(pathStr, enumerator));
148
+ } catch (err) {
149
+ reject(createNodeError(err, "opendir", pathStr));
150
+ }
151
+ }
152
+ );
153
+ });
154
+ }
155
+ export {
156
+ Dir,
157
+ opendir,
158
+ opendirAsync,
159
+ opendirSync
160
+ };
@@ -0,0 +1,189 @@
1
+ import { FileHandle } from "./file-handle.js";
2
+ import { statSync, truncateSync, chmodSync, chownSync, readFileSync } from "./sync.js";
3
+ import { utimesSync } from "./utimes.js";
4
+ import { normalizePath } from "./utils.js";
5
+ function getFH(fd) {
6
+ if (fd instanceof FileHandle) return FileHandle.getInstance(fd.fd);
7
+ return FileHandle.getInstance(fd);
8
+ }
9
+ function fstatSync(fd, options) {
10
+ return statSync(normalizePath(getFH(fd).options.path), options);
11
+ }
12
+ function fstat(fd, optionsOrCb, callback) {
13
+ if (typeof optionsOrCb === "function") {
14
+ callback = optionsOrCb;
15
+ optionsOrCb = {};
16
+ }
17
+ Promise.resolve().then(() => fstatSync(fd, optionsOrCb)).then((s) => callback(null, s), callback);
18
+ }
19
+ async function fstatAsync(fd, options) {
20
+ return fstatSync(fd, options);
21
+ }
22
+ function ftruncateSync(fd, len = 0) {
23
+ truncateSync(normalizePath(getFH(fd).options.path), len);
24
+ }
25
+ function ftruncate(fd, lenOrCb, callback) {
26
+ if (typeof lenOrCb === "function") {
27
+ callback = lenOrCb;
28
+ lenOrCb = 0;
29
+ }
30
+ Promise.resolve().then(() => ftruncateSync(fd, lenOrCb)).then(() => callback(null), callback);
31
+ }
32
+ async function ftruncateAsync(fd, len = 0) {
33
+ ftruncateSync(fd, len);
34
+ }
35
+ function fdatasyncSync(fd) {
36
+ getFH(fd)._flushSync();
37
+ }
38
+ function fdatasync(fd, callback) {
39
+ Promise.resolve().then(() => fdatasyncSync(fd)).then(() => callback(null), callback);
40
+ }
41
+ async function fdatasyncAsync(fd) {
42
+ fdatasyncSync(fd);
43
+ }
44
+ function fsyncSync(fd) {
45
+ getFH(fd)._flushSync();
46
+ }
47
+ function fsync(fd, callback) {
48
+ Promise.resolve().then(() => fsyncSync(fd)).then(() => callback(null), callback);
49
+ }
50
+ async function fsyncAsync(fd) {
51
+ fsyncSync(fd);
52
+ }
53
+ function fchmodSync(fd, mode) {
54
+ chmodSync(normalizePath(getFH(fd).options.path), mode);
55
+ }
56
+ function fchmod(fd, mode, callback) {
57
+ Promise.resolve().then(() => fchmodSync(fd, mode)).then(() => callback(null), callback);
58
+ }
59
+ async function fchmodAsync(fd, mode) {
60
+ fchmodSync(fd, mode);
61
+ }
62
+ function fchownSync(fd, uid, gid) {
63
+ chownSync(normalizePath(getFH(fd).options.path), uid, gid);
64
+ }
65
+ function fchown(fd, uid, gid, callback) {
66
+ Promise.resolve().then(() => fchownSync(fd, uid, gid)).then(() => callback(null), callback);
67
+ }
68
+ async function fchownAsync(fd, uid, gid) {
69
+ fchownSync(fd, uid, gid);
70
+ }
71
+ function futimesSync(fd, atime, mtime) {
72
+ utimesSync(normalizePath(getFH(fd).options.path), atime, mtime);
73
+ }
74
+ function futimes(fd, atime, mtime, callback) {
75
+ Promise.resolve().then(() => futimesSync(fd, atime, mtime)).then(() => callback(null), callback);
76
+ }
77
+ async function futimesAsync(fd, atime, mtime) {
78
+ futimesSync(fd, atime, mtime);
79
+ }
80
+ function closeSync(fd) {
81
+ getFH(fd)._closeSync();
82
+ }
83
+ function readSync(fd, buffer, offsetOrOptions, length, position) {
84
+ let offset = 0;
85
+ if (offsetOrOptions !== null && typeof offsetOrOptions === "object") {
86
+ offset = offsetOrOptions.offset ?? 0;
87
+ length = offsetOrOptions.length ?? buffer.byteLength;
88
+ position = offsetOrOptions.position ?? null;
89
+ } else {
90
+ offset = offsetOrOptions ?? 0;
91
+ length = length ?? buffer.byteLength - offset;
92
+ }
93
+ return getFH(fd)._readSync(buffer, offset, length, position ?? null);
94
+ }
95
+ function writeSync(fd, bufferOrString, offsetOrPosition, lengthOrEncoding, position) {
96
+ let data;
97
+ if (typeof bufferOrString === "string") {
98
+ data = new TextEncoder().encode(bufferOrString);
99
+ if (typeof offsetOrPosition === "number") position = offsetOrPosition;
100
+ } else {
101
+ const offset = typeof offsetOrPosition === "number" ? offsetOrPosition : 0;
102
+ const len = typeof lengthOrEncoding === "number" ? lengthOrEncoding : bufferOrString.byteLength - offset;
103
+ data = new Uint8Array(bufferOrString.buffer, bufferOrString.byteOffset + offset, len);
104
+ }
105
+ return getFH(fd)._writeSync(data, position ?? null);
106
+ }
107
+ function readvSync(fd, buffers, position) {
108
+ let bytesRead = 0;
109
+ for (const buf of buffers) {
110
+ const n = readSync(fd, buf, 0, buf.byteLength, position != null ? position + bytesRead : null);
111
+ bytesRead += n;
112
+ if (n < buf.byteLength) break;
113
+ }
114
+ return bytesRead;
115
+ }
116
+ function readv(fd, buffers, positionOrCb, callback) {
117
+ if (typeof positionOrCb === "function") {
118
+ callback = positionOrCb;
119
+ positionOrCb = null;
120
+ }
121
+ Promise.resolve().then(() => ({ bytesRead: readvSync(fd, buffers, positionOrCb), buffers })).then((r) => callback(null, r.bytesRead, r.buffers), callback);
122
+ }
123
+ async function readvAsync(fd, buffers, position) {
124
+ return { bytesRead: readvSync(fd, buffers, position), buffers };
125
+ }
126
+ function writevSync(fd, buffers, position) {
127
+ let bytesWritten = 0;
128
+ for (const buf of buffers) {
129
+ const n = writeSync(fd, buf, 0, buf.byteLength, position != null ? position + bytesWritten : null);
130
+ bytesWritten += n;
131
+ }
132
+ return bytesWritten;
133
+ }
134
+ function writev(fd, buffers, positionOrCb, callback) {
135
+ if (typeof positionOrCb === "function") {
136
+ callback = positionOrCb;
137
+ positionOrCb = null;
138
+ }
139
+ Promise.resolve().then(() => ({ bytesWritten: writevSync(fd, buffers, positionOrCb), buffers })).then((r) => callback(null, r.bytesWritten, r.buffers), callback);
140
+ }
141
+ async function writevAsync(fd, buffers, position) {
142
+ return { bytesWritten: writevSync(fd, buffers, position), buffers };
143
+ }
144
+ function exists(path, callback) {
145
+ try {
146
+ statSync(normalizePath(path));
147
+ callback(true);
148
+ } catch {
149
+ callback(false);
150
+ }
151
+ }
152
+ async function openAsBlob(path, options) {
153
+ const data = readFileSync(normalizePath(path));
154
+ return new Blob([data], { type: options?.type ?? "" });
155
+ }
156
+ export {
157
+ closeSync,
158
+ exists,
159
+ fchmod,
160
+ fchmodAsync,
161
+ fchmodSync,
162
+ fchown,
163
+ fchownAsync,
164
+ fchownSync,
165
+ fdatasync,
166
+ fdatasyncAsync,
167
+ fdatasyncSync,
168
+ fstat,
169
+ fstatAsync,
170
+ fstatSync,
171
+ fsync,
172
+ fsyncAsync,
173
+ fsyncSync,
174
+ ftruncate,
175
+ ftruncateAsync,
176
+ ftruncateSync,
177
+ futimes,
178
+ futimesAsync,
179
+ futimesSync,
180
+ openAsBlob,
181
+ readSync,
182
+ readv,
183
+ readvAsync,
184
+ readvSync,
185
+ writeSync,
186
+ writev,
187
+ writevAsync,
188
+ writevSync
189
+ };