@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.
Files changed (69) hide show
  1. package/lib/esm/_virtual/_rolldown/runtime.js +1 -1
  2. package/lib/esm/callback.js +1 -1
  3. package/lib/esm/cp.js +1 -1
  4. package/lib/esm/dir.js +1 -1
  5. package/lib/esm/dirent.js +1 -1
  6. package/lib/esm/encoding.js +1 -1
  7. package/lib/esm/errors.js +1 -1
  8. package/lib/esm/fd-ops.js +1 -1
  9. package/lib/esm/file-handle.js +1 -1
  10. package/lib/esm/fs-watcher.js +1 -1
  11. package/lib/esm/glob.js +1 -1
  12. package/lib/esm/read-stream.js +1 -1
  13. package/lib/esm/stat-watcher.js +1 -1
  14. package/lib/esm/statfs.js +1 -1
  15. package/lib/esm/stats.js +1 -1
  16. package/lib/esm/sync.js +1 -1
  17. package/lib/esm/utils.js +1 -1
  18. package/lib/esm/utimes.js +1 -1
  19. package/lib/esm/write-stream.js +1 -1
  20. package/package.json +51 -48
  21. package/src/callback.spec.ts +0 -296
  22. package/src/callback.ts +0 -684
  23. package/src/cp.spec.ts +0 -181
  24. package/src/cp.ts +0 -328
  25. package/src/dir.spec.ts +0 -204
  26. package/src/dir.ts +0 -199
  27. package/src/dirent.ts +0 -165
  28. package/src/encoding.ts +0 -45
  29. package/src/errors.spec.ts +0 -389
  30. package/src/errors.ts +0 -19
  31. package/src/extended.spec.ts +0 -706
  32. package/src/fd-ops.spec.ts +0 -234
  33. package/src/fd-ops.ts +0 -251
  34. package/src/file-handle.spec.ts +0 -115
  35. package/src/file-handle.ts +0 -856
  36. package/src/fs-watcher.ts +0 -198
  37. package/src/glob.spec.ts +0 -201
  38. package/src/glob.ts +0 -205
  39. package/src/index.ts +0 -313
  40. package/src/new-apis.spec.ts +0 -505
  41. package/src/promises.spec.ts +0 -812
  42. package/src/promises.ts +0 -686
  43. package/src/read-stream.ts +0 -128
  44. package/src/stat-watcher.ts +0 -116
  45. package/src/stat.spec.ts +0 -87
  46. package/src/statfs.spec.ts +0 -67
  47. package/src/statfs.ts +0 -92
  48. package/src/stats.ts +0 -207
  49. package/src/streams.spec.ts +0 -513
  50. package/src/symlink.spec.ts +0 -188
  51. package/src/sync.spec.ts +0 -377
  52. package/src/sync.ts +0 -562
  53. package/src/test.mts +0 -27
  54. package/src/types/encoding-option.ts +0 -3
  55. package/src/types/file-read-options.ts +0 -15
  56. package/src/types/file-read-result.ts +0 -4
  57. package/src/types/flag-and-open-mode.ts +0 -6
  58. package/src/types/index.ts +0 -6
  59. package/src/types/open-flags.ts +0 -14
  60. package/src/types/read-options.ts +0 -9
  61. package/src/utils.ts +0 -31
  62. package/src/utimes.spec.ts +0 -113
  63. package/src/utimes.ts +0 -97
  64. package/src/watch.spec.ts +0 -171
  65. package/src/watchfile.spec.ts +0 -185
  66. package/src/write-stream.ts +0 -142
  67. package/test/file.txt +0 -1
  68. package/tsconfig.json +0 -29
  69. package/tsconfig.tsbuildinfo +0 -1
package/src/cp.spec.ts DELETED
@@ -1,181 +0,0 @@
1
- // Ported from refs/bun/test/js/node/fs/cp.test.ts and
2
- // refs/node-test/parallel/test-fs-cp-sync-*.mjs
3
- // Original: MIT, Oven & contributors / Node.js contributors.
4
- // Rewritten for @gjsify/unit — behavior preserved, assertion dialect adapted.
5
-
6
- import { describe, it, expect } from '@gjsify/unit';
7
- import { cpSync, promises, existsSync, mkdirSync, writeFileSync, readFileSync, mkdtempSync, rmSync } from 'node:fs';
8
- import { join } from 'node:path';
9
- import { tmpdir } from 'node:os';
10
-
11
- function makeTmp(): string {
12
- return mkdtempSync(join(tmpdir(), 'gjsify-cp-'));
13
- }
14
-
15
- export default async () => {
16
- await describe('fs.cpSync', async () => {
17
- await it('copies a single file', async () => {
18
- const tmp = makeTmp();
19
- writeFileSync(join(tmp, 'a.txt'), 'hello');
20
-
21
- cpSync(join(tmp, 'a.txt'), join(tmp, 'b.txt'));
22
-
23
- expect(readFileSync(join(tmp, 'b.txt'), 'utf8')).toBe('hello');
24
- rmSync(tmp, { recursive: true, force: true });
25
- });
26
-
27
- await it('throws EISDIR when src is directory and recursive is false', async () => {
28
- const tmp = makeTmp();
29
- mkdirSync(join(tmp, 'src'));
30
-
31
- let threw = false;
32
- try {
33
- cpSync(join(tmp, 'src'), join(tmp, 'dest'));
34
- } catch (e: any) {
35
- threw = true;
36
- expect(e.code).toBe('ERR_FS_EISDIR');
37
- }
38
- expect(threw).toBe(true);
39
- rmSync(tmp, { recursive: true, force: true });
40
- });
41
-
42
- await it('recursively copies a directory tree', async () => {
43
- const tmp = makeTmp();
44
- mkdirSync(join(tmp, 'src', 'sub'), { recursive: true });
45
- writeFileSync(join(tmp, 'src', 'a.txt'), 'a');
46
- writeFileSync(join(tmp, 'src', 'sub', 'b.txt'), 'b');
47
-
48
- cpSync(join(tmp, 'src'), join(tmp, 'dst'), { recursive: true });
49
-
50
- expect(readFileSync(join(tmp, 'dst', 'a.txt'), 'utf8')).toBe('a');
51
- expect(readFileSync(join(tmp, 'dst', 'sub', 'b.txt'), 'utf8')).toBe('b');
52
- rmSync(tmp, { recursive: true, force: true });
53
- });
54
-
55
- await it('overwrites existing file by default (force=true)', async () => {
56
- const tmp = makeTmp();
57
- writeFileSync(join(tmp, 'src.txt'), 'new');
58
- writeFileSync(join(tmp, 'dst.txt'), 'old');
59
-
60
- cpSync(join(tmp, 'src.txt'), join(tmp, 'dst.txt'));
61
-
62
- expect(readFileSync(join(tmp, 'dst.txt'), 'utf8')).toBe('new');
63
- rmSync(tmp, { recursive: true, force: true });
64
- });
65
-
66
- await it('does not overwrite when force=false', async () => {
67
- const tmp = makeTmp();
68
- writeFileSync(join(tmp, 'src.txt'), 'new');
69
- writeFileSync(join(tmp, 'dst.txt'), 'old');
70
-
71
- cpSync(join(tmp, 'src.txt'), join(tmp, 'dst.txt'), { force: false });
72
-
73
- expect(readFileSync(join(tmp, 'dst.txt'), 'utf8')).toBe('old');
74
- rmSync(tmp, { recursive: true, force: true });
75
- });
76
-
77
- await it('throws EEXIST when force=false and errorOnExist=true', async () => {
78
- const tmp = makeTmp();
79
- writeFileSync(join(tmp, 'src.txt'), 'new');
80
- writeFileSync(join(tmp, 'dst.txt'), 'old');
81
-
82
- let threw = false;
83
- try {
84
- cpSync(join(tmp, 'src.txt'), join(tmp, 'dst.txt'), { force: false, errorOnExist: true });
85
- } catch (e: any) {
86
- threw = true;
87
- expect(e.code).toBe('ERR_FS_CP_EEXIST');
88
- }
89
- expect(threw).toBe(true);
90
- rmSync(tmp, { recursive: true, force: true });
91
- });
92
-
93
- await it('applies filter function — skips excluded entries', async () => {
94
- const tmp = makeTmp();
95
- mkdirSync(join(tmp, 'src'));
96
- writeFileSync(join(tmp, 'src', 'keep.txt'), 'keep');
97
- writeFileSync(join(tmp, 'src', 'skip.log'), 'skip');
98
-
99
- cpSync(join(tmp, 'src'), join(tmp, 'dst'), {
100
- recursive: true,
101
- filter: (_src, _dst) => !_src.endsWith('.log'),
102
- });
103
-
104
- expect(existsSync(join(tmp, 'dst', 'keep.txt'))).toBe(true);
105
- expect(existsSync(join(tmp, 'dst', 'skip.log'))).toBe(false);
106
- rmSync(tmp, { recursive: true, force: true });
107
- });
108
-
109
- await it('throws ENOENT when src does not exist', async () => {
110
- const tmp = makeTmp();
111
-
112
- let threw = false;
113
- try {
114
- cpSync(join(tmp, 'nonexistent.txt'), join(tmp, 'dst.txt'));
115
- } catch (e: any) {
116
- threw = true;
117
- expect(e.code).toBe('ENOENT');
118
- }
119
- expect(threw).toBe(true);
120
- rmSync(tmp, { recursive: true, force: true });
121
- });
122
- });
123
-
124
- await describe('fs.promises.cp', async () => {
125
- await it('copies a single file', async () => {
126
- const tmp = makeTmp();
127
- writeFileSync(join(tmp, 'a.txt'), 'hello');
128
-
129
- await promises.cp(join(tmp, 'a.txt'), join(tmp, 'b.txt'));
130
-
131
- expect(readFileSync(join(tmp, 'b.txt'), 'utf8')).toBe('hello');
132
- rmSync(tmp, { recursive: true, force: true });
133
- });
134
-
135
- await it('throws EISDIR when src is directory and recursive is false', async () => {
136
- const tmp = makeTmp();
137
- mkdirSync(join(tmp, 'src'));
138
-
139
- let threw = false;
140
- try {
141
- await promises.cp(join(tmp, 'src'), join(tmp, 'dest'));
142
- } catch (e: any) {
143
- threw = true;
144
- expect(e.code).toBe('ERR_FS_EISDIR');
145
- }
146
- expect(threw).toBe(true);
147
- rmSync(tmp, { recursive: true, force: true });
148
- });
149
-
150
- await it('recursively copies a directory tree', async () => {
151
- const tmp = makeTmp();
152
- mkdirSync(join(tmp, 'src', 'sub'), { recursive: true });
153
- writeFileSync(join(tmp, 'src', 'a.txt'), 'a');
154
- writeFileSync(join(tmp, 'src', 'sub', 'b.txt'), 'b');
155
-
156
- await promises.cp(join(tmp, 'src'), join(tmp, 'dst'), { recursive: true });
157
-
158
- expect(readFileSync(join(tmp, 'dst', 'a.txt'), 'utf8')).toBe('a');
159
- expect(readFileSync(join(tmp, 'dst', 'sub', 'b.txt'), 'utf8')).toBe('b');
160
- rmSync(tmp, { recursive: true, force: true });
161
- });
162
-
163
- await it('applies async filter function', async () => {
164
- const tmp = makeTmp();
165
- mkdirSync(join(tmp, 'src'));
166
- writeFileSync(join(tmp, 'src', 'keep.ts'), 'ts');
167
- writeFileSync(join(tmp, 'src', 'skip.js'), 'js');
168
-
169
- await promises.cp(join(tmp, 'src'), join(tmp, 'dst'), {
170
- recursive: true,
171
- filter: async (_src, _dst) => {
172
- return !_src.endsWith('.js');
173
- },
174
- });
175
-
176
- expect(existsSync(join(tmp, 'dst', 'keep.ts'))).toBe(true);
177
- expect(existsSync(join(tmp, 'dst', 'skip.js'))).toBe(false);
178
- rmSync(tmp, { recursive: true, force: true });
179
- });
180
- });
181
- };
package/src/cp.ts DELETED
@@ -1,328 +0,0 @@
1
- // fs.cp / fs.cpSync / fs.promises.cp — recursive copy
2
- // Reference: Node.js lib/internal/fs/cpSync.js
3
- // Reimplemented for GJS using Gio.File synchronous operations
4
-
5
- import Gio from '@girs/gio-2.0';
6
- import { join } from 'node:path';
7
- import { normalizePath } from './utils.js';
8
- import { createNodeError } from './errors.js';
9
-
10
- import type { PathLike } from 'node:fs';
11
-
12
- export interface CpSyncOptions {
13
- dereference?: boolean;
14
- errorOnExist?: boolean;
15
- filter?: (src: string, dest: string) => boolean;
16
- force?: boolean;
17
- mode?: number;
18
- preserveTimestamps?: boolean;
19
- recursive?: boolean;
20
- verbatimSymlinks?: boolean;
21
- }
22
-
23
- export interface CpOptions extends Omit<CpSyncOptions, 'filter'> {
24
- filter?: (src: string, dest: string) => boolean | Promise<boolean>;
25
- }
26
-
27
- function makeEEXIST(destStr: string): NodeJS.ErrnoException {
28
- const e: NodeJS.ErrnoException = new Error(`ERR_FS_CP_EEXIST: file already exists, copyfile '${destStr}'`);
29
- e.code = 'ERR_FS_CP_EEXIST';
30
- e.syscall = 'copyfile';
31
- e.path = destStr;
32
- return e;
33
- }
34
-
35
- function makeEISDIR(srcStr: string): NodeJS.ErrnoException {
36
- const e: NodeJS.ErrnoException = new Error(`ERR_FS_EISDIR: illegal operation on a directory, copyfile '${srcStr}'`);
37
- e.code = 'ERR_FS_EISDIR';
38
- e.syscall = 'copyfile';
39
- e.path = srcStr;
40
- return e;
41
- }
42
-
43
- function makeENOTDIR(srcStr: string, destStr: string): NodeJS.ErrnoException {
44
- const e: NodeJS.ErrnoException = new Error(`ENOTDIR: not a directory, copyfile '${srcStr}' -> '${destStr}'`);
45
- e.code = 'ENOTDIR';
46
- e.syscall = 'copyfile';
47
- e.path = srcStr;
48
- (e as any).dest = destStr;
49
- return e;
50
- }
51
-
52
- function makeSYMLINKLOOP(srcStr: string, destStr: string): NodeJS.ErrnoException {
53
- const e: NodeJS.ErrnoException = new Error(`ELOOP: too many levels of symbolic links, copyfile '${srcStr}' -> '${destStr}'`);
54
- e.code = 'ELOOP';
55
- e.syscall = 'copyfile';
56
- e.path = srcStr;
57
- (e as any).dest = destStr;
58
- return e;
59
- }
60
-
61
- function queryCopyFlags(opts: CpSyncOptions | CpOptions): Gio.FileCopyFlags {
62
- const force = opts.force ?? true;
63
- let flags = Gio.FileCopyFlags.NONE;
64
- if (force) flags |= Gio.FileCopyFlags.OVERWRITE;
65
- if (opts.preserveTimestamps) flags |= Gio.FileCopyFlags.TARGET_DEFAULT_MODIFIED_TIME;
66
- if (!opts.dereference) flags |= Gio.FileCopyFlags.NOFOLLOW_SYMLINKS;
67
- return flags;
68
- }
69
-
70
- function copyOneSyncFile(srcFile: Gio.File, destFile: Gio.File, srcStr: string, destStr: string, opts: CpSyncOptions | CpOptions): void {
71
- const force = opts.force ?? true;
72
-
73
- // Check dest is not a directory
74
- try {
75
- const destInfo = destFile.query_info('standard::type', Gio.FileQueryInfoFlags.NONE, null);
76
- if (destInfo.get_file_type() === Gio.FileType.DIRECTORY) {
77
- throw makeENOTDIR(srcStr, destStr);
78
- }
79
- if (!force) {
80
- if (opts.errorOnExist) throw makeEEXIST(destStr);
81
- return; // silent skip when force=false and no errorOnExist
82
- }
83
- } catch (e: any) {
84
- if (typeof e.code === 'string') throw e; // re-throw Node-style errors (string codes)
85
- // Gio errors have numeric codes (e.g. NOT_FOUND=1) — dest doesn't exist, fine
86
- }
87
-
88
- const flags = queryCopyFlags(opts);
89
- try {
90
- srcFile.copy(destFile, flags, null, null);
91
- } catch (err: unknown) {
92
- throw createNodeError(err, 'copyfile', srcStr, destStr);
93
- }
94
- }
95
-
96
- function cpOneDirSync(srcFile: Gio.File, destFile: Gio.File, srcStr: string, destStr: string, opts: CpSyncOptions | CpOptions): void {
97
- // Detect src ⊂ dest cycle (if dest path starts with srcStr + separator)
98
- const sep = srcStr.endsWith('/') ? '' : '/';
99
- if (destStr.startsWith(srcStr + sep) && destStr !== srcStr) {
100
- throw makeSYMLINKLOOP(srcStr, destStr);
101
- }
102
-
103
- // Create dest directory if it doesn't exist
104
- if (!destFile.query_exists(null)) {
105
- try {
106
- destFile.make_directory_with_parents(null);
107
- } catch (err: unknown) {
108
- throw createNodeError(err, 'mkdir', destStr);
109
- }
110
- } else {
111
- // dest exists — must be a directory
112
- try {
113
- const destInfo = destFile.query_info('standard::type', Gio.FileQueryInfoFlags.NONE, null);
114
- if (destInfo.get_file_type() !== Gio.FileType.DIRECTORY) {
115
- throw makeENOTDIR(destStr, srcStr);
116
- }
117
- } catch (e: any) {
118
- if (typeof e.code === 'string') throw e;
119
- }
120
- }
121
-
122
- // Enumerate children
123
- let enumerator: Gio.FileEnumerator;
124
- try {
125
- enumerator = srcFile.enumerate_children(
126
- 'standard::name,standard::type,standard::is-symlink',
127
- opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
128
- null,
129
- );
130
- } catch (err: unknown) {
131
- throw createNodeError(err, 'scandir', srcStr);
132
- }
133
-
134
- let childInfo = enumerator.next_file(null);
135
- while (childInfo !== null) {
136
- const name = childInfo.get_name();
137
- const childSrc = join(srcStr, name);
138
- const childDest = join(destStr, name);
139
-
140
- const filter = (opts as CpSyncOptions).filter;
141
- if (filter && !filter(childSrc, childDest)) {
142
- childInfo = enumerator.next_file(null);
143
- continue;
144
- }
145
-
146
- cpSyncInternal(childSrc, childDest, opts);
147
- childInfo = enumerator.next_file(null);
148
- }
149
- }
150
-
151
- function cpSyncInternal(srcStr: string, destStr: string, opts: CpSyncOptions | CpOptions): void {
152
- const srcFile = Gio.File.new_for_path(srcStr);
153
- const destFile = Gio.File.new_for_path(destStr);
154
-
155
- let info: Gio.FileInfo;
156
- try {
157
- info = srcFile.query_info(
158
- 'standard::type,standard::is-symlink',
159
- opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
160
- null,
161
- );
162
- } catch (err: unknown) {
163
- throw createNodeError(err, 'stat', srcStr);
164
- }
165
-
166
- const type = info.get_file_type();
167
-
168
- if (type === Gio.FileType.DIRECTORY) {
169
- if (!opts.recursive) throw makeEISDIR(srcStr);
170
- cpOneDirSync(srcFile, destFile, srcStr, destStr, opts);
171
- } else {
172
- copyOneSyncFile(srcFile, destFile, srcStr, destStr, opts);
173
- }
174
- }
175
-
176
- // ─── Public API ──────────────────────────────────────────────────────────────
177
-
178
- export function cpSync(src: PathLike, dest: PathLike, options?: CpSyncOptions): void {
179
- const srcStr = normalizePath(src);
180
- const destStr = normalizePath(dest);
181
- const opts: CpSyncOptions = options ?? {};
182
-
183
- const srcFile = Gio.File.new_for_path(srcStr);
184
-
185
- // Apply top-level filter before doing anything
186
- const filter = opts.filter;
187
- if (filter && !filter(srcStr, destStr)) return;
188
-
189
- // Check src is a directory without recursive option
190
- try {
191
- const info = srcFile.query_info(
192
- 'standard::type',
193
- opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
194
- null,
195
- );
196
- if (info.get_file_type() === Gio.FileType.DIRECTORY && !opts.recursive) {
197
- throw makeEISDIR(srcStr);
198
- }
199
- } catch (e: any) {
200
- if (typeof e.code === 'string') throw e;
201
- throw createNodeError(e, 'stat', srcStr);
202
- }
203
-
204
- cpSyncInternal(srcStr, destStr, opts);
205
- }
206
-
207
- export function cp(
208
- src: PathLike,
209
- dest: PathLike,
210
- options: CpOptions | ((err: NodeJS.ErrnoException | null) => void),
211
- callback?: (err: NodeJS.ErrnoException | null) => void,
212
- ): void {
213
- let opts: CpOptions;
214
- let cb: (err: NodeJS.ErrnoException | null) => void;
215
-
216
- if (typeof options === 'function') {
217
- cb = options;
218
- opts = {};
219
- } else {
220
- cb = callback!;
221
- opts = options;
222
- }
223
-
224
- const asyncFilter = opts.filter;
225
- if (asyncFilter) {
226
- // Wrap async filter through a sync-compatible adapter by running
227
- // a mini async pipeline: resolve filter for each entry, then cpSync.
228
- // For simplicity, resolve the top-level filter and then run cpSync
229
- // with a synchronous shim. Full async recursive filtering uses the
230
- // promise variant.
231
- Promise.resolve(asyncFilter(normalizePath(src), normalizePath(dest))).then((include) => {
232
- if (!include) { cb(null); return; }
233
- try {
234
- // For directories, we must run asynchronously through promises.cp
235
- cpPromises(src, dest, opts).then(() => cb(null)).catch(cb);
236
- } catch (e: any) {
237
- cb(e);
238
- }
239
- }).catch(cb);
240
- return;
241
- }
242
-
243
- // No async filter — use synchronous implementation on next tick
244
- Promise.resolve().then(() => {
245
- try {
246
- cpSync(src, dest, opts as CpSyncOptions);
247
- cb(null);
248
- } catch (e: any) {
249
- cb(e);
250
- }
251
- });
252
- }
253
-
254
- // ─── promises.cp ─────────────────────────────────────────────────────────────
255
-
256
- async function cpPromisesDir(srcStr: string, destStr: string, opts: CpOptions): Promise<void> {
257
- const sep = srcStr.endsWith('/') ? '' : '/';
258
- if (destStr.startsWith(srcStr + sep) && destStr !== srcStr) {
259
- throw makeSYMLINKLOOP(srcStr, destStr);
260
- }
261
-
262
- const destFile = Gio.File.new_for_path(destStr);
263
- if (!destFile.query_exists(null)) {
264
- try {
265
- destFile.make_directory_with_parents(null);
266
- } catch (err: unknown) {
267
- throw createNodeError(err, 'mkdir', destStr);
268
- }
269
- }
270
-
271
- const srcFile = Gio.File.new_for_path(srcStr);
272
- let enumerator: Gio.FileEnumerator;
273
- try {
274
- enumerator = srcFile.enumerate_children(
275
- 'standard::name,standard::type',
276
- opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
277
- null,
278
- );
279
- } catch (err: unknown) {
280
- throw createNodeError(err, 'scandir', srcStr);
281
- }
282
-
283
- let childInfo = enumerator.next_file(null);
284
- while (childInfo !== null) {
285
- const name = childInfo.get_name();
286
- const childSrc = join(srcStr, name);
287
- const childDest = join(destStr, name);
288
-
289
- const filter = opts.filter;
290
- if (filter) {
291
- const include = await Promise.resolve(filter(childSrc, childDest));
292
- if (!include) {
293
- childInfo = enumerator.next_file(null);
294
- continue;
295
- }
296
- }
297
-
298
- await cpPromises(childSrc, childDest, opts);
299
- childInfo = enumerator.next_file(null);
300
- }
301
- }
302
-
303
- async function cpPromises(src: PathLike, dest: PathLike, opts: CpOptions = {}): Promise<void> {
304
- const srcStr = normalizePath(src);
305
- const destStr = normalizePath(dest);
306
-
307
- const srcFile = Gio.File.new_for_path(srcStr);
308
- let info: Gio.FileInfo;
309
- try {
310
- info = srcFile.query_info(
311
- 'standard::type',
312
- opts.dereference ? Gio.FileQueryInfoFlags.NONE : Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
313
- null,
314
- );
315
- } catch (err: unknown) {
316
- throw createNodeError(err, 'stat', srcStr);
317
- }
318
-
319
- if (info.get_file_type() === Gio.FileType.DIRECTORY) {
320
- if (!opts.recursive) throw makeEISDIR(srcStr);
321
- await cpPromisesDir(srcStr, destStr, opts);
322
- } else {
323
- const destFile = Gio.File.new_for_path(destStr);
324
- copyOneSyncFile(srcFile, destFile, srcStr, destStr, opts);
325
- }
326
- }
327
-
328
- export { cpPromises as cpAsync };