@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.
Files changed (91) hide show
  1. package/README.md +31 -2
  2. package/lib/esm/callback.js +251 -15
  3. package/lib/esm/dirent.js +47 -6
  4. package/lib/esm/encoding.js +2 -3
  5. package/lib/esm/errors.js +13 -0
  6. package/lib/esm/file-handle.js +108 -66
  7. package/lib/esm/fs-watcher.js +44 -7
  8. package/lib/esm/index.js +140 -5
  9. package/lib/esm/promises.js +290 -69
  10. package/lib/esm/read-stream.js +82 -57
  11. package/lib/esm/stats.js +138 -18
  12. package/lib/esm/sync.js +293 -44
  13. package/lib/esm/write-stream.js +4 -4
  14. package/lib/types/callback.d.ts +233 -0
  15. package/lib/types/dirent.d.ts +77 -0
  16. package/lib/types/encoding.d.ts +6 -0
  17. package/lib/types/errors.d.ts +7 -0
  18. package/lib/types/file-handle.d.ts +367 -0
  19. package/lib/types/fs-watcher.d.ts +17 -0
  20. package/lib/types/index.d.ts +149 -0
  21. package/lib/types/promises.d.ts +158 -0
  22. package/lib/types/read-stream.d.ts +21 -0
  23. package/lib/types/stats.d.ts +67 -0
  24. package/lib/types/sync.d.ts +109 -0
  25. package/lib/types/types/encoding-option.d.ts +2 -0
  26. package/lib/types/types/file-read-options.d.ts +15 -0
  27. package/lib/types/types/file-read-result.d.ts +4 -0
  28. package/lib/types/types/flag-and-open-mode.d.ts +5 -0
  29. package/lib/types/types/index.d.ts +6 -0
  30. package/lib/types/types/open-flags.d.ts +1 -0
  31. package/lib/types/types/read-options.d.ts +5 -0
  32. package/lib/types/utils.d.ts +2 -0
  33. package/lib/types/write-stream.d.ts +45 -0
  34. package/package.json +22 -34
  35. package/src/callback.spec.ts +284 -30
  36. package/src/callback.ts +352 -39
  37. package/src/dirent.ts +56 -8
  38. package/src/encoding.ts +7 -2
  39. package/src/errors.spec.ts +389 -0
  40. package/src/errors.ts +19 -0
  41. package/src/extended.spec.ts +706 -0
  42. package/src/file-handle.spec.ts +104 -23
  43. package/src/file-handle.ts +147 -79
  44. package/src/fs-watcher.ts +55 -8
  45. package/src/index.ts +146 -2
  46. package/src/new-apis.spec.ts +505 -0
  47. package/src/promises.spec.ts +651 -11
  48. package/src/promises.ts +353 -81
  49. package/src/read-stream.ts +98 -74
  50. package/src/stat.spec.ts +22 -14
  51. package/src/stats.ts +176 -75
  52. package/src/streams.spec.ts +455 -0
  53. package/src/symlink.spec.ts +176 -26
  54. package/src/sync.spec.ts +204 -32
  55. package/src/sync.ts +363 -58
  56. package/src/test.mts +7 -2
  57. package/src/types/encoding-option.ts +1 -1
  58. package/src/types/flag-and-open-mode.ts +1 -1
  59. package/src/types/read-options.ts +2 -2
  60. package/src/utils.ts +2 -0
  61. package/src/write-stream.ts +9 -7
  62. package/tsconfig.json +23 -10
  63. package/tsconfig.tsbuildinfo +1 -0
  64. package/lib/cjs/callback.js +0 -112
  65. package/lib/cjs/dirent.js +0 -98
  66. package/lib/cjs/encoding.js +0 -34
  67. package/lib/cjs/file-handle.js +0 -444
  68. package/lib/cjs/fs-watcher.js +0 -50
  69. package/lib/cjs/index.js +0 -95
  70. package/lib/cjs/promises.js +0 -160
  71. package/lib/cjs/read-stream.js +0 -78
  72. package/lib/cjs/stats.js +0 -45
  73. package/lib/cjs/sync.js +0 -126
  74. package/lib/cjs/types/encoding-option.js +0 -0
  75. package/lib/cjs/types/file-read-options.js +0 -0
  76. package/lib/cjs/types/file-read-result.js +0 -0
  77. package/lib/cjs/types/flag-and-open-mode.js +0 -0
  78. package/lib/cjs/types/index.js +0 -6
  79. package/lib/cjs/types/open-flags.js +0 -0
  80. package/lib/cjs/types/read-options.js +0 -0
  81. package/lib/cjs/utils.js +0 -18
  82. package/lib/cjs/write-stream.js +0 -116
  83. package/test/watch.js +0 -1
  84. package/test.gjs.js +0 -35359
  85. package/test.gjs.js.map +0 -7
  86. package/test.gjs.mjs +0 -40570
  87. package/test.gjs.mjs.meta.json +0 -1
  88. package/test.node.js +0 -1479
  89. package/test.node.js.map +0 -7
  90. package/test.node.mjs +0 -710
  91. package/tsconfig.types.json +0 -8
@@ -1,42 +1,296 @@
1
+ // Ported from refs/node-test/parallel/test-fs-read-file*.js, test-fs-write-file*.js
2
+ // Original: MIT license, Node.js contributors
3
+
1
4
  import { describe, it, expect } from '@gjsify/unit';
2
- import { open, write, close, rm } from 'fs';
3
- import { Buffer } from 'buffer';
5
+ import {
6
+ open, close, write, read, rm,
7
+ stat, lstat, readdir, readFile, writeFile,
8
+ rename, copyFile, access, appendFile, truncate,
9
+ mkdir, rmdir, chmod,
10
+ } from 'node:fs';
11
+ import { constants } from 'node:fs';
12
+ import { Buffer } from 'node:buffer';
13
+
14
+ const TEST_DIR = './test-callback-' + Date.now();
4
15
 
5
16
  export default async () => {
6
- await describe('fs.open', async () => {
7
- await it(`should open a file for writing`, () => {
8
- const path = './test/open.txt';
9
- open(path, 'w+', 0o666, (err, fd) => {
17
+ await describe('fs callback API', async () => {
18
+
19
+ // ==================== stat / lstat ====================
20
+ await describe('stat', async () => {
21
+ await it('should stat current directory', async () => {
22
+ await new Promise<void>((resolve, reject) => {
23
+ stat('.', (err, stats) => {
24
+ if (err) return reject(err);
25
+ expect(stats).toBeDefined();
26
+ expect(stats.isDirectory()).toBe(true);
27
+ expect(stats.isFile()).toBe(false);
28
+ expect(typeof stats.size).toBe('number');
29
+ expect(typeof stats.mode).toBe('number');
30
+ resolve();
31
+ });
32
+ });
33
+ });
34
+
35
+ await it('should return error for non-existent path', async () => {
36
+ await new Promise<void>((resolve) => {
37
+ stat('/non/existent/path/xyz', (err) => {
38
+ expect(err).toBeDefined();
39
+ expect(err!.code).toBe('ENOENT');
40
+ resolve();
41
+ });
42
+ });
43
+ });
44
+ });
45
+
46
+ await describe('lstat', async () => {
47
+ await it('should lstat current directory', async () => {
48
+ await new Promise<void>((resolve, reject) => {
49
+ lstat('.', (err, stats) => {
50
+ if (err) return reject(err);
51
+ expect(stats).toBeDefined();
52
+ expect(stats.isDirectory()).toBe(true);
53
+ resolve();
54
+ });
55
+ });
56
+ });
57
+ });
58
+
59
+ // ==================== readdir ====================
60
+ await describe('readdir', async () => {
61
+ await it('should list files in current directory', async () => {
62
+ await new Promise<void>((resolve, reject) => {
63
+ readdir('.', (err, files) => {
64
+ if (err) return reject(err);
65
+ expect(Array.isArray(files)).toBe(true);
66
+ expect(files.length).toBeGreaterThan(0);
67
+ resolve();
68
+ });
69
+ });
70
+ });
71
+ });
72
+
73
+ // ==================== mkdir / rmdir ====================
74
+ await describe('mkdir and rmdir', async () => {
75
+ await it('should create and remove a directory', async () => {
76
+ const dir = TEST_DIR + '-mkdir';
77
+ await new Promise<void>((resolve, reject) => {
78
+ mkdir(dir, (err) => {
79
+ if (err) return reject(err);
80
+ stat(dir, (err2, stats) => {
81
+ if (err2) return reject(err2);
82
+ expect(stats.isDirectory()).toBe(true);
83
+ rmdir(dir, (err3) => {
84
+ if (err3) return reject(err3);
85
+ resolve();
86
+ });
87
+ });
88
+ });
89
+ });
90
+ });
91
+ });
92
+
93
+ // ==================== writeFile / readFile ====================
94
+ await describe('writeFile and readFile', async () => {
95
+ await it('should write and read a file', async () => {
96
+ const path = TEST_DIR + '-rw.txt';
97
+ const content = 'Hello callback world';
98
+
99
+ await new Promise<void>((resolve, reject) => {
100
+ writeFile(path, content, 'utf8', (err) => {
101
+ if (err) return reject(err);
102
+ readFile(path, 'utf8', (err2, data) => {
103
+ if (err2) return reject(err2);
104
+ expect(data).toBe(content);
105
+ rm(path, (err3) => {
106
+ if (err3) return reject(err3);
107
+ resolve();
108
+ });
109
+ });
110
+ });
111
+ });
112
+ });
113
+
114
+ await it('should write and read Buffer data', async () => {
115
+ const path = TEST_DIR + '-buf.txt';
116
+ const buf = Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // "Hello"
117
+
118
+ await new Promise<void>((resolve, reject) => {
119
+ writeFile(path, buf, (err) => {
120
+ if (err) return reject(err);
121
+ readFile(path, (err2, data) => {
122
+ if (err2) return reject(err2);
123
+ expect(Buffer.isBuffer(data)).toBe(true);
124
+ expect(data.toString()).toBe('Hello');
125
+ rm(path, () => resolve());
126
+ });
127
+ });
128
+ });
129
+ });
130
+
131
+ await it('should return error when reading non-existent file', async () => {
132
+ await new Promise<void>((resolve) => {
133
+ readFile('/non/existent/file.txt', (err) => {
134
+ expect(err).toBeDefined();
135
+ expect(err!.code).toBe('ENOENT');
136
+ resolve();
137
+ });
138
+ });
139
+ });
140
+ });
141
+
142
+ // ==================== open / write / read / close ====================
143
+ await describe('open, write, read, close', async () => {
144
+ await it('should open, write, read, and close a file', async () => {
145
+ const path = TEST_DIR + '-open.txt';
146
+
147
+ await new Promise<void>((resolve, reject) => {
148
+ open(path, 'w+', 0o666, (err, fd) => {
149
+ if (err) return reject(err);
150
+ expect(typeof fd).toBe('number');
10
151
 
11
- expect(err).toBeNull();
152
+ const buf = Buffer.from('Hello World', 'utf8');
153
+ write(fd, buf, 0, buf.length, 0, (err2, written) => {
154
+ if (err2) return reject(err2);
155
+ expect(written).toBe(buf.length);
12
156
 
13
- console.log('fs.open: file open');
157
+ close(fd, (err3) => {
158
+ if (err3) return reject(err3);
159
+ rm(path, () => resolve());
160
+ });
161
+ });
162
+ });
163
+ });
164
+ });
165
+ });
14
166
 
15
- let buffWrite = Buffer.from('Hello World', 'utf8'),
16
- buffStart = 0,
17
- buffLength = buffWrite.length,
18
- filePos = 0;
19
- write(fd, buffWrite, buffStart, buffLength, filePos, (err, written, buffer) => {
20
- expect(err).toBeNull();
167
+ // ==================== access ====================
168
+ await describe('access', async () => {
169
+ await it('should succeed for existing file', async () => {
170
+ const path = TEST_DIR + '-access.txt';
171
+ await new Promise<void>((resolve, reject) => {
172
+ writeFile(path, 'test', (err) => {
173
+ if (err) return reject(err);
174
+ access(path, constants.F_OK, (err2) => {
175
+ expect(err2).toBeNull();
176
+ rm(path, () => resolve());
177
+ });
178
+ });
179
+ });
180
+ });
21
181
 
22
- console.log('fs.open: file written');
182
+ await it('should fail for non-existent file', async () => {
183
+ await new Promise<void>((resolve) => {
184
+ access('/non/existent/file', constants.F_OK, (err) => {
185
+ expect(err).toBeDefined();
186
+ expect(err!.code).toBe('ENOENT');
187
+ resolve();
188
+ });
189
+ });
190
+ });
191
+ });
23
192
 
24
- expect(written).toBe(buffWrite.length);
193
+ // ==================== appendFile ====================
194
+ await describe('appendFile', async () => {
195
+ await it('should append to a file', async () => {
196
+ const path = TEST_DIR + '-append.txt';
197
+ await new Promise<void>((resolve, reject) => {
198
+ writeFile(path, 'Hello', 'utf8', (err) => {
199
+ if (err) return reject(err);
200
+ appendFile(path, ' World', 'utf8', (err2) => {
201
+ if (err2) return reject(err2);
202
+ readFile(path, 'utf8', (err3, data) => {
203
+ if (err3) return reject(err3);
204
+ expect(data).toBe('Hello World');
205
+ rm(path, () => resolve());
206
+ });
207
+ });
208
+ });
209
+ });
210
+ });
211
+ });
25
212
 
26
- expect(buffer).toBe(buffWrite);
213
+ // ==================== rename ====================
214
+ await describe('rename', async () => {
215
+ await it('should rename a file', async () => {
216
+ const oldPath = TEST_DIR + '-rename-old.txt';
217
+ const newPath = TEST_DIR + '-rename-new.txt';
218
+ await new Promise<void>((resolve, reject) => {
219
+ writeFile(oldPath, 'rename test', (err) => {
220
+ if (err) return reject(err);
221
+ rename(oldPath, newPath, (err2) => {
222
+ if (err2) return reject(err2);
223
+ readFile(newPath, 'utf8', (err3, data) => {
224
+ if (err3) return reject(err3);
225
+ expect(data).toBe('rename test');
226
+ rm(newPath, () => resolve());
227
+ });
228
+ });
229
+ });
230
+ });
231
+ });
232
+ });
27
233
 
28
- close(fd, (err) => {
29
- expect(err).toBeNull();
234
+ // ==================== copyFile ====================
235
+ await describe('copyFile', async () => {
236
+ await it('should copy a file', async () => {
237
+ const src = TEST_DIR + '-copy-src.txt';
238
+ const dst = TEST_DIR + '-copy-dst.txt';
239
+ await new Promise<void>((resolve, reject) => {
240
+ writeFile(src, 'copy test', (err) => {
241
+ if (err) return reject(err);
242
+ copyFile(src, dst, (err2) => {
243
+ if (err2) return reject(err2);
244
+ readFile(dst, 'utf8', (err3, data) => {
245
+ if (err3) return reject(err3);
246
+ expect(data).toBe('copy test');
247
+ rm(src, () => rm(dst, () => resolve()));
248
+ });
249
+ });
250
+ });
251
+ });
252
+ });
253
+ });
30
254
 
31
- console.log('fs.open: file closed');
255
+ // ==================== truncate ====================
256
+ await describe('truncate', async () => {
257
+ await it('should truncate a file', async () => {
258
+ const path = TEST_DIR + '-truncate.txt';
259
+ await new Promise<void>((resolve, reject) => {
260
+ writeFile(path, 'Hello World', (err) => {
261
+ if (err) return reject(err);
262
+ truncate(path, 5, (err2) => {
263
+ if (err2) return reject(err2);
264
+ readFile(path, 'utf8', (err3, data) => {
265
+ if (err3) return reject(err3);
266
+ expect(data).toBe('Hello');
267
+ rm(path, () => resolve());
268
+ });
269
+ });
270
+ });
271
+ });
272
+ });
273
+ });
32
274
 
33
- rm(path, (err) => {
34
- expect(err).toBeNull();
35
- console.log('fs.open: file removed');
36
- });
37
- });
38
- });
39
- });
40
- });
41
- });
42
- }
275
+ // ==================== chmod ====================
276
+ await describe('chmod', async () => {
277
+ await it('should change file mode', async () => {
278
+ const path = TEST_DIR + '-chmod.txt';
279
+ await new Promise<void>((resolve, reject) => {
280
+ writeFile(path, 'chmod test', (err) => {
281
+ if (err) return reject(err);
282
+ chmod(path, 0o644, (err2) => {
283
+ if (err2) return reject(err2);
284
+ stat(path, (err3, stats) => {
285
+ if (err3) return reject(err3);
286
+ // Check that mode includes the permission bits
287
+ expect((stats.mode & 0o777)).toBe(0o644);
288
+ rm(path, () => resolve());
289
+ });
290
+ });
291
+ });
292
+ });
293
+ });
294
+ });
295
+ });
296
+ };