@heyputer/puter.js 2.0.0 → 2.0.1

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 (74) hide show
  1. package/README.md +3 -1
  2. package/index.d.ts +479 -0
  3. package/package.json +15 -4
  4. package/APACHE_LICENSE.txt +0 -201
  5. package/doc/devlog.md +0 -49
  6. package/src/bg.png +0 -0
  7. package/src/bg.webp +0 -0
  8. package/src/lib/APICallLogger.js +0 -110
  9. package/src/lib/EventListener.js +0 -51
  10. package/src/lib/RequestError.js +0 -6
  11. package/src/lib/filesystem/APIFS.js +0 -73
  12. package/src/lib/filesystem/CacheFS.js +0 -243
  13. package/src/lib/filesystem/PostMessageFS.js +0 -40
  14. package/src/lib/filesystem/definitions.js +0 -39
  15. package/src/lib/path.js +0 -509
  16. package/src/lib/polyfills/localStorage.js +0 -92
  17. package/src/lib/polyfills/xhrshim.js +0 -233
  18. package/src/lib/socket.io/socket.io.esm.min.js +0 -7
  19. package/src/lib/socket.io/socket.io.esm.min.js.map +0 -1
  20. package/src/lib/socket.io/socket.io.js +0 -4385
  21. package/src/lib/socket.io/socket.io.js.map +0 -1
  22. package/src/lib/socket.io/socket.io.min.js +0 -7
  23. package/src/lib/socket.io/socket.io.min.js.map +0 -1
  24. package/src/lib/socket.io/socket.io.msgpack.min.js +0 -7
  25. package/src/lib/socket.io/socket.io.msgpack.min.js.map +0 -1
  26. package/src/lib/utils.js +0 -620
  27. package/src/lib/xdrpc.js +0 -104
  28. package/src/modules/AI.js +0 -680
  29. package/src/modules/Apps.js +0 -215
  30. package/src/modules/Auth.js +0 -171
  31. package/src/modules/Debug.js +0 -39
  32. package/src/modules/Drivers.js +0 -278
  33. package/src/modules/FSItem.js +0 -139
  34. package/src/modules/FileSystem/index.js +0 -187
  35. package/src/modules/FileSystem/operations/copy.js +0 -64
  36. package/src/modules/FileSystem/operations/deleteFSEntry.js +0 -59
  37. package/src/modules/FileSystem/operations/getReadUrl.js +0 -42
  38. package/src/modules/FileSystem/operations/mkdir.js +0 -62
  39. package/src/modules/FileSystem/operations/move.js +0 -75
  40. package/src/modules/FileSystem/operations/read.js +0 -46
  41. package/src/modules/FileSystem/operations/readdir.js +0 -102
  42. package/src/modules/FileSystem/operations/rename.js +0 -58
  43. package/src/modules/FileSystem/operations/sign.js +0 -103
  44. package/src/modules/FileSystem/operations/space.js +0 -40
  45. package/src/modules/FileSystem/operations/stat.js +0 -95
  46. package/src/modules/FileSystem/operations/symlink.js +0 -55
  47. package/src/modules/FileSystem/operations/upload.js +0 -440
  48. package/src/modules/FileSystem/operations/write.js +0 -65
  49. package/src/modules/FileSystem/utils/getAbsolutePathForApp.js +0 -21
  50. package/src/modules/Hosting.js +0 -138
  51. package/src/modules/KV.js +0 -301
  52. package/src/modules/OS.js +0 -95
  53. package/src/modules/Perms.js +0 -109
  54. package/src/modules/PuterDialog.js +0 -481
  55. package/src/modules/Threads.js +0 -75
  56. package/src/modules/UI.js +0 -1555
  57. package/src/modules/Util.js +0 -38
  58. package/src/modules/Workers.js +0 -120
  59. package/src/modules/networking/PSocket.js +0 -87
  60. package/src/modules/networking/PTLS.js +0 -100
  61. package/src/modules/networking/PWispHandler.js +0 -89
  62. package/src/modules/networking/parsers.js +0 -157
  63. package/src/modules/networking/requests.js +0 -282
  64. package/src/services/APIAccess.js +0 -46
  65. package/src/services/FSRelay.js +0 -20
  66. package/src/services/Filesystem.js +0 -122
  67. package/src/services/NoPuterYet.js +0 -20
  68. package/src/services/XDIncoming.js +0 -44
  69. package/test/ai.test.js +0 -214
  70. package/test/fs.test.js +0 -798
  71. package/test/index.html +0 -1183
  72. package/test/kv.test.js +0 -548
  73. package/test/txt2speech.test.js +0 -178
  74. package/webpack.config.js +0 -25
package/test/fs.test.js DELETED
@@ -1,798 +0,0 @@
1
- /* eslint-disable */
2
- // TODO: Make these more compatible with eslint
3
- naughtyStrings = [
4
- "文件.txt", // Chinese characters
5
- "файл.txt", // Cyrillic characters
6
- "ファイル.txt", // Japanese characters
7
- "파일.txt", // Korean characters
8
- "ملف.txt", // Arabic characters
9
- "फ़ाइल.txt", // Hindi characters
10
- "archivo.txt", // Spanish characters
11
- "fichier.txt", // French characters
12
- "αρχείο.txt", // Greek characters
13
- "datei.txt", // German characters
14
- "fil.txt", // Swedish characters
15
- "קובץ.txt", // Hebrew characters
16
- "文件名.txt", // Chinese characters
17
- "файлы.txt", // Russian characters
18
- "फ़ाइलें.txt", // Hindi characters
19
- "📄_emoji.txt", // Emoji
20
- "file name with spaces.txt",
21
- "file-name-with-dashes.txt",
22
- "file_name_with_underscores.txt",
23
- "file.name.with.periods.txt",
24
- "file,name,with,commas.txt",
25
- "file;name;with;semicolons.txt",
26
- "file(name)with(parentheses).txt",
27
- "file[name]with[brackets].txt",
28
- "file{name}with{braces}.txt",
29
- "file!name!with!exclamations!.txt",
30
- "file@name@with@ats.txt",
31
- "file#name#with#hashes#.txt",
32
- "file$name$with$dollars$.txt",
33
- "file%name%with%percentages%.txt",
34
- "file^name^with^carats^.txt",
35
- "file&name&with&amps&.txt",
36
- "file*name*with*asterisks*.txt",
37
- "file_name_with_long_name_exceeding_255_characters_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.txt",
38
- "file👍name👍with👍thumbs👍up.txt",
39
- "invisible\u200Bname.txt", // Invisible Unicode character (Zero Width Space)
40
- "invisible\u200Cname.txt", // Invisible Unicode character (Zero Width Non-Joiner)
41
- "invisible\u200Dname.txt", // Invisible Unicode character (Zero Width Joiner)
42
- "invisible\uFEFFname.txt", // Invisible Unicode character (Zero Width No-Break Space)
43
- "invisible\u180Ename.txt", // Invisible Unicode character (Mongolian Vowel Separator)
44
- "hash#tag.txt",
45
- "percent%20encoded.txt",
46
- "plus+sign.txt",
47
- "ampersand&symbol.txt",
48
- "at@symbol.txt",
49
- "parentheses(1).txt",
50
- "brackets[1].txt",
51
- "curly{braces}.txt",
52
- "angle<tags>.txt",
53
- "exclamation!point.txt",
54
- "question?mark.txt",
55
- "colon:separated.txt",
56
- "semicolon;separated.txt",
57
- "single'quote.txt",
58
- "double\"quote.txt",
59
- "backtick`char.txt",
60
- "tilde~sign.txt",
61
- "underscore_character.txt",
62
- "hyphen-character.txt",
63
- "equal=sign.txt",
64
- "plus+sign.txt",
65
- "asterisk*char.txt",
66
- "caret^char.txt",
67
- "percent%sign.txt",
68
- "dollar$sign.txt",
69
- "pound#sign.txt",
70
- "at@sign.txt",
71
- "exclamation!mark.txt",
72
- "question?mark.txt",
73
- "backslash\\char.txt",
74
- "pipe|char.txt",
75
- "colon:char.txt",
76
- "semicolon;char.txt",
77
- "quote'char.txt",
78
- "double\"quote.txt",
79
- "backtick`char.txt",
80
- "braces{char}.txt",
81
- "brackets[char].txt",
82
- "parentheses(char).txt",
83
- "angle<brackets>.txt",
84
- "ellipsis….txt",
85
- "accentué.txt",
86
- "ümlaut.txt",
87
- "tildeñ.txt",
88
- "çedilla.txt",
89
- "špecial.txt",
90
- "russianЯ.txt",
91
- "chinese中文.txt",
92
- "arabicعربى.txt",
93
- "hebrewעברית.txt",
94
- "japanese日本語.txt",
95
- "korean한국어.txt",
96
- "vietnameseTiếng Việt.txt",
97
- ]
98
-
99
- window.fsTests = [
100
- {
101
- name: "testFSWrite",
102
- description: "Test writing text content to a new file and verify it returns a valid UID",
103
- test: async function() {
104
- try {
105
- let randName = puter.randName();
106
- const result = await puter.fs.write(randName, 'testValue');
107
- assert(result.uid, "Failed to write to file");
108
- pass("testFSWrite passed");
109
- // delete the file
110
- try {
111
- await puter.fs.delete(randName);
112
- } catch (error) {
113
- throw("testFSWrite failed to delete file:", error);
114
- }
115
- } catch (error) {
116
- if(puter.debugMode)
117
- console.log(error);
118
- throw("testFSWrite failed:", error);
119
- }
120
- }
121
- },
122
- {
123
- name: "testFSRead",
124
- description: "Test reading text content from a file and verify it matches the written content",
125
- test: async function() {
126
- try {
127
- let randName = puter.randName();
128
- await puter.fs.write(randName, 'testValue');
129
- const result = await (await puter.fs.read(randName)).text();
130
- assert(result === 'testValue', "Failed to read from file");
131
- pass("testFSRead passed");
132
- // delete the file
133
- try {
134
- await puter.fs.delete(randName);
135
- } catch (error) {
136
- fail("testFSRead failed to delete file:", error);
137
- }
138
- } catch (error) {
139
- fail("testFSRead failed:", error);
140
- }
141
- }
142
- },
143
- {
144
- name: "testFSWriteWithoutData",
145
- description: "Test creating an empty file without providing content data",
146
- test: async function() {
147
- try {
148
- let randName = puter.randName();
149
- const result = await puter.fs.write(randName);
150
- assert(result.uid, "Failed to write to file");
151
- pass("testFSWriteWithoutData passed");
152
- if(randName !== result.name) {
153
- fail(`testFSWriteWithoutData failed: Names do not match ${randName} ${result.name}`);
154
- }
155
- // delete the file
156
- try {
157
- await puter.fs.delete(randName);
158
- } catch (error) {
159
- fail("testFSWriteWithoutData failed to delete file:", error);
160
- }
161
- } catch (error) {
162
- fail("testFSWriteWithoutData failed:", error);
163
- }
164
- }
165
- },
166
- {
167
- name: "testFSReadWithoutData",
168
- description: "Test reading from an empty file and verify it returns an empty string",
169
- test: async function() {
170
- try {
171
- let randName = puter.randName();
172
- await puter.fs.write(randName);
173
- const result = await (await puter.fs.read(randName)).text();
174
- assert(result === '', "Failed to read from file");
175
- pass("testFSReadWithoutData passed");
176
- // delete the file
177
- try {
178
- await puter.fs.delete(randName);
179
- } catch (error) {
180
- fail("testFSReadWithoutData failed to delete file:", error);
181
- }
182
- } catch (error) {
183
- fail("testFSReadWithoutData failed:", error);
184
- }
185
- }
186
- },
187
- {
188
- name: "testFSWriteToExistingFile",
189
- description: "Test overwriting an existing file with new content",
190
- test: async function() {
191
- try {
192
- let randName = puter.randName();
193
- await puter.fs.write(randName, 'testValue');
194
- const result = await puter.fs.write(randName, 'updatedValue');
195
- assert(result.uid, "Failed to write to file");
196
- pass("testFSWriteToExistingFile passed");
197
- // delete the file
198
- try {
199
- await puter.fs.delete(randName);
200
- } catch (error) {
201
- fail("testFSWriteToExistingFile failed to delete file:", error);
202
- }
203
- } catch (error) {
204
- fail("testFSWriteToExistingFile failed:", error);
205
- }
206
- }
207
- },
208
- {
209
- name: "testFSWriteToExistingFileWithoutOverwriteAndDedupe",
210
- description: "Test writing to an existing file with overwrite and dedupe disabled - should fail",
211
- test: async function() {
212
- try {
213
- let randName = puter.randName();
214
- await puter.fs.write(randName, 'testValue');
215
- const result = await puter.fs.write(randName, 'updatedValue', { overwrite: false, dedupeName: false });
216
- assert(!result.uid, "Failed to write to file");
217
- fail("testFSWriteToExistingFileWithoutOverwriteAndDedupe failed");
218
- // delete the file
219
- try {
220
- await puter.fs.delete(randName);
221
- } catch (error) {
222
- fail("testFSWriteToExistingFileWithoutOverwriteAndDedupe failed to delete file:", error);
223
- }
224
- } catch (error) {
225
- pass("testFSWriteToExistingFileWithoutOverwriteAndDedupe passed");
226
- }
227
- }
228
- },
229
- {
230
- name: "testFSWriteToExistingFileWithoutOverwriteButWithDedupe",
231
- description: "Test writing to an existing file with overwrite disabled but dedupe enabled - should create new file",
232
- test: async function() {
233
- try {
234
- let randName = puter.randName();
235
- await puter.fs.write(randName, 'testValue');
236
- const result = await puter.fs.write(randName, 'updatedValue', { overwrite: false, dedupeName: true });
237
- assert(result.uid, "Failed to write to file");
238
- pass("testFSWriteToExistingFileWithoutOverwriteButWithDedupe passed");
239
- // delete the file
240
- try {
241
- await puter.fs.delete(randName);
242
- } catch (error) {
243
- fail("testFSWriteToExistingFileWithoutOverwriteButWithDedupe failed to delete file:", error);
244
- }
245
- } catch (error) {
246
- fail("testFSWriteToExistingFileWithoutOverwriteButWithDedupe failed:", error);
247
- }
248
- }
249
- },
250
- {
251
- name: "testFSWriteToExistingFileWithOverwriteButWithoutDedupe",
252
- description: "Test writing to an existing file with overwrite enabled but dedupe disabled - should overwrite",
253
- test: async function() {
254
- try {
255
- let randName = puter.randName();
256
- await puter.fs.write(randName, 'testValue');
257
- const result = await puter.fs.write(randName, 'updatedValue', { overwrite: true, dedupeName: false });
258
- assert(result.uid, "Failed to write to file");
259
- pass("testFSWriteToExistingFileWithOverwriteButWithoutDedupe passed");
260
- // delete the file
261
- try {
262
- await puter.fs.delete(randName);
263
- } catch (error) {
264
- fail("testFSWriteToExistingFileWithOverwriteButWithoutDedupe failed to delete file:", error);
265
- }
266
- } catch (error) {
267
- fail("testFSWriteToExistingFileWithOverwriteButWithoutDedupe failed:", error);
268
- }
269
- }
270
- },
271
- {
272
- name: "testFSCreateDir",
273
- description: "Test creating a new directory and verify it returns a valid UID",
274
- test: async function() {
275
- try {
276
- let randName = puter.randName();
277
- const result = await puter.fs.mkdir(randName);
278
- assert(result.uid, "Failed to create directory");
279
- pass("testFSCreateDir passed");
280
- } catch (error) {
281
- fail("testFSCreateDir failed:", error);
282
- }
283
- }
284
- },
285
- {
286
- name: "testFSReadDir",
287
- description: "Test reading directory contents after creating multiple files within it",
288
- test: async function() {
289
- try {
290
- let randName = puter.randName();
291
- await puter.fs.mkdir(randName);
292
- await puter.fs.write(randName + '/file1', 'testValue');
293
- await puter.fs.write(randName + '/file2', 'testValue');
294
- await puter.fs.write(randName + '/file3', 'testValue');
295
- const result = await puter.fs.readdir(randName);
296
- assert(result.length === 3, "Failed to read directory");
297
- pass("testFSReadDir passed");
298
- } catch (error) {
299
- fail("testFSReadDir failed:", error);
300
- }
301
- }
302
- },
303
- {
304
- name: "testFSDelete",
305
- description: "Test deleting a file and verify it no longer exists",
306
- test: async function() {
307
- try {
308
- let randName = puter.randName();
309
- await puter.fs.write(randName, 'testValue');
310
- const result = await puter.fs.delete(randName);
311
- assert(!result.uid, "Failed to delete file");
312
- pass("testFSDelete passed");
313
- } catch (error) {
314
- fail("testFSDelete failed:", error);
315
- }
316
- }
317
- },
318
- {
319
- name: "testFSDeleteDir",
320
- description: "Test deleting a directory containing multiple files",
321
- test: async function() {
322
- try {
323
- let randName = puter.randName();
324
- await puter.fs.mkdir(randName);
325
- await puter.fs.write(randName + '/file1', 'testValue');
326
- await puter.fs.write(randName + '/file2', 'testValue');
327
- await puter.fs.write(randName + '/file3', 'testValue');
328
- const result = await puter.fs.delete(randName);
329
- assert(!result.uid, "Failed to delete directory");
330
- pass("testFSDeleteDir passed");
331
- } catch (error) {
332
- fail("testFSDeleteDir failed:", error);
333
- }
334
- }
335
- },
336
- {
337
- name: "testFSDeleteNonExistentFile",
338
- description: "Test attempting to delete a non-existent file and verify it returns a valid response",
339
- test: async function() {
340
- try {
341
- let randName = puter.randName();
342
- const result = await puter.fs.delete(randName);
343
- assert(!result.uid, "Failed to delete non-existent file");
344
- pass("testFSDeleteNonExistentFile passed");
345
- } catch (error) {
346
- if(error.code !== "subject_does_not_exist")
347
- fail("testFSDeleteNonExistentFile failed:", error);
348
- else
349
- pass("testFSDeleteNonExistentFile passed");
350
- }
351
- }
352
- },
353
- {
354
- name: "testFSReadNonExistentFile",
355
- description: "Test attempting to read from a non-existent file and verify it returns a valid response",
356
- test: async function() {
357
- try {
358
- let randName = puter.randName();
359
- const result = await puter.fs.read(randName);
360
- fail("testFSReadNonExistentFile failed");
361
- } catch (error) {
362
- if(error.code !== "subject_does_not_exist")
363
- fail("testFSReadNonExistentFile failed:", error);
364
- else
365
- pass("testFSReadNonExistentFile passed");
366
- }
367
- }
368
- },
369
- {
370
- name: "testFSWriteWithSpecialCharacters",
371
- description: "Test writing text content to a file with special characters and verify it returns a valid UID",
372
- test: async function() {
373
- let randName
374
- try {
375
- randName = 'testFileWithSpecialCharacte rs!@#$%^&*()_+{}|:"<>?`~'
376
- const result = await puter.fs.write(randName, 'testValue', { specialCharacters: true });
377
- assert(result.uid, "Failed to write to file");
378
- pass("testFSWriteWithSpecialCharacters passed");
379
- } catch (error) {
380
- fail("testFSWriteWithSpecialCharacters failed:", error);
381
- }
382
-
383
- // delete the file
384
- try {
385
- await puter.fs.delete(randName);
386
- } catch (error) {
387
- fail("testFSWriteWithSpecialCharacters failed to delete file:", error);
388
- }
389
- }
390
- },
391
- {
392
- name: "testFSReadWithSpecialCharacters",
393
- description: "Test reading text content from a file with special characters and verify it matches the written content",
394
- test: async function() {
395
- try {
396
- let randName = 'testFileWithSpecialCharacte rs!@#$%^&*()_+{}|:"<>?`~'
397
- await puter.fs.write(randName, 'testValue');
398
- const result = await (await puter.fs.read(randName)).text();
399
- assert(result === 'testValue', "Failed to read from file");
400
- pass("testFSReadWithSpecialCharacters passed");
401
- } catch (error) {
402
- fail("testFSReadWithSpecialCharacters failed:", error);
403
- }
404
- }
405
- },
406
- {
407
- name: "testFSWriteLargeFile",
408
- description: "Test writing large text content to a file and verify it returns a valid UID",
409
- test: async function() {
410
- try {
411
- let randName = puter.randName();
412
- const result = await puter.fs.write(randName, 'testValue'.repeat(100000));
413
- assert(result.uid, "Failed to write to file");
414
- pass("testFSWriteLargeFile passed");
415
- } catch (error) {
416
- fail("testFSWriteLargeFile failed:", error);
417
- }
418
- }
419
- },
420
- {
421
- name: "testFSReadLargeFile",
422
- description: "Test reading large text content from a file and verify it matches the written content",
423
- test: async function() {
424
- try {
425
- let randName = puter.randName();
426
- await puter.fs.write(randName, 'testValue'.repeat(100000));
427
- const result = await (await puter.fs.read(randName)).text();
428
- assert(result === 'testValue'.repeat(100000), "Failed to read from file");
429
- pass("testFSReadLargeFile passed");
430
- } catch (error) {
431
- fail("testFSReadLargeFile failed:", error);
432
- }
433
- }
434
- },
435
- {
436
- name: "testFSRenameFile",
437
- description: "Test renaming a file and verify the old file is gone",
438
- test: async function() {
439
- try {
440
- let randName = puter.randName();
441
- let randName2 = puter.randName();
442
- await puter.fs.write(randName, 'testValue');
443
- const result = await puter.fs.rename(randName, randName2);
444
- assert(result.name, "Failed to rename file");
445
- pass("testFSRenameFile passed");
446
- // check that the old file is gone
447
- try {
448
- await puter.fs.read(randName);
449
- fail("testFSRenameFile failed to delete old file");
450
- } catch (error) {
451
- if(error.code !== "subject_does_not_exist")
452
- fail("testFSRenameFile failed to delete old file:", error);
453
- else
454
- pass("testFSRenameFile passed");
455
- }
456
- } catch (error) {
457
- fail("testFSRenameFile failed:", error);
458
- }
459
- }
460
- },
461
- {
462
- name: "testFSMoveFile",
463
- description: "Test moving a file to a new directory and verify the old file is gone",
464
- test: async function() {
465
- try {
466
- let randName = puter.randName();
467
- let randName2 = puter.randName();
468
- await puter.fs.write(randName, 'testValue');
469
- await puter.fs.mkdir(randName2);
470
- let result = await puter.fs.move(randName, randName2);
471
- assert(result.moved, "Failed to move file");
472
- // check that the old file is gone
473
- try {
474
- await puter.fs.read(randName);
475
- fail("testFSMoveFile failed to delete old file");
476
- } catch (error) {
477
- if(error.code !== "subject_does_not_exist")
478
- fail("testFSMoveFile failed to delete old file:", error);
479
- else
480
- pass("testFSMoveFile passed");
481
- }
482
- } catch (error) {
483
- fail("testFSMoveFile failed:", error);
484
- }
485
- }
486
- },
487
- {
488
- name: "testFSCopyFile",
489
- description: "Test copying a file to a new directory and verify the old file is still there",
490
- test: async function() {
491
- try {
492
- let randName = puter.randName();
493
- let randName2 = puter.randName();
494
- await puter.fs.write(randName, 'testValue');
495
- await puter.fs.mkdir(randName2);
496
- let result = await puter.fs.copy(randName, randName2);
497
- assert(Array.isArray(result) && result[0].copied.uid, "Failed to copy file");
498
- // check that the old file is still there
499
- try {
500
- await puter.fs.read(randName);
501
- pass("testFSCopyFile passed");
502
- } catch (error) {
503
- fail("testFSCopyFile failed to keep old file:", error);
504
- }
505
- } catch (error) {
506
- fail("testFSCopyFile failed:", error);
507
- }
508
- }
509
- },
510
- {
511
- name: "testFSCopyFileWithNewName",
512
- description: "Test copying a file to a new directory with a new name and verify the old file is still there",
513
- test: async function() {
514
- try {
515
- let randName = puter.randName();
516
- let randName2 = puter.randName();
517
- await puter.fs.write(randName, 'testValue');
518
- await puter.fs.mkdir(randName2);
519
- let result = await puter.fs.copy(randName, randName2, { newName: 'newName' });
520
- assert(Array.isArray(result) && result[0].copied.uid, "Failed to copy file");
521
- // check file name
522
- assert(result[0].copied.name === 'newName', "Failed to copy file with new name");
523
- // check that the old file is still there
524
- try {
525
- await puter.fs.read(randName);
526
- pass("testFSCopyFileWithNewName passed");
527
- } catch (error) {
528
- fail("testFSCopyFileWithNewName failed to keep old file:", error);
529
- }
530
- } catch (error) {
531
- fail("testFSCopyFileWithNewName failed:", error);
532
- }
533
- }
534
- },
535
- {
536
- name: "testFSStat",
537
- description: "Test getting file metadata and verify it returns a valid UID",
538
- test: async function() {
539
- try {
540
- let randName = puter.randName();
541
- await puter.fs.write(randName, 'testValue');
542
- let result = await puter.fs.stat(randName);
543
- assert(result.uid, "Failed to stat file");
544
- pass("testFSStat passed");
545
- } catch (error) {
546
- fail("testFSStat failed:", error);
547
- }
548
- }
549
- },
550
- {
551
- name: "testFSStatDir",
552
- description: "Test getting directory metadata and verify it returns a valid UID",
553
- test: async function() {
554
- try {
555
- let randName = puter.randName();
556
- await puter.fs.mkdir(randName);
557
- let result = await puter.fs.stat(randName);
558
- assert(result.uid, "Failed to stat directory");
559
- pass("testFSStatDir passed");
560
- } catch (error) {
561
- fail("testFSStatDir failed:", error);
562
- }
563
- }
564
- },
565
- {
566
- name: "testFSStatNonExistent",
567
- description: "Test attempting to get metadata from a non-existent file or directory and verify it returns a valid response",
568
- test: async function() {
569
- try {
570
- let randName = puter.randName();
571
- let result = await puter.fs.stat(randName);
572
- fail("testFSStatNonExistent failed");
573
- } catch (error) {
574
- if(error.code !== "subject_does_not_exist")
575
- fail("testFSStatNonExistent failed:", error);
576
- else
577
- pass("testFSStatNonExistent passed");
578
- }
579
- }
580
- },
581
- {
582
- name: "testFSDeleteDirWithFiles",
583
- description: "Test deleting a directory containing multiple files and verify it no longer exists",
584
- test: async function() {
585
- try {
586
- let randName = puter.randName();
587
- await puter.fs.mkdir(randName);
588
- await puter.fs.write(randName + '/file1', 'testValue');
589
- await puter.fs.write(randName + '/file2', 'testValue');
590
- await puter.fs.write(randName + '/file3', 'testValue');
591
- const result = await puter.fs.delete(randName, { recursive: true });
592
- assert(!result.uid, "Failed to delete directory");
593
- pass("testFSDeleteDirWithFiles passed");
594
- } catch (error) {
595
- fail("testFSDeleteDirWithFiles failed:", error);
596
- }
597
- }
598
- },
599
- {
600
- name: "testFSStatDirReturnsAttrs",
601
- description: "Test getting directory metadata and verifying it returns the expected attributes",
602
- test: async function() {
603
- try {
604
- let randName = puter.randName();
605
- await puter.fs.mkdir(randName);
606
- let result = await puter.fs.stat(randName);
607
- assert(result.name && typeof result.name === 'string', "Failed to stat directory (name)");
608
- assert(result.path && typeof result.path === 'string', "Failed to stat directory (path)");
609
- assert(result.immutable !== undefined, "Failed to stat directory (immutable)");
610
- assert(result.metadata !== undefined, "Failed to stat directory (metadata)");
611
- assert(result.modified !== undefined, "Failed to stat directory (modified)");
612
- assert(result.created !== undefined, "Failed to stat directory (created)");
613
- assert(result.accessed !== undefined, "Failed to stat directory (accessed)");
614
- assert(result.size !== undefined, "Failed to stat directory (size)");
615
- assert(result.layout !== undefined, "Failed to stat directory (layout)");
616
- assert(result.owner !== undefined && typeof result.owner === 'object', "Failed to stat directory (owner)");
617
- assert(result.dirname !== undefined && typeof result.dirname === 'string', "Failed to stat directory (dirname)");
618
- assert(result.parent_id !== undefined && typeof result.parent_id === 'string', "Failed to stat directory (parent_id)");
619
- // todo this will fail for now until is_dir is turned into boolean
620
- assert(result.is_dir !== undefined && typeof result.is_dir === 'boolean' && result.is_dir === true, "Failed to stat directory (is_dir)");
621
- assert(result.is_empty !== undefined && typeof result.is_empty === 'boolean', "Failed to stat directory (is_empty)");
622
- pass("testFSStatDirReturnsAttrs passed");
623
- } catch (error) {
624
- throw("testFSStatDirReturnsAttrs failed:", error);
625
- }
626
- }
627
- },
628
- {
629
- name: "testFSReadWithWriteResult",
630
- description: "Test reading text content from a file using the object returned by write()",
631
- test: async function() {
632
- try {
633
- let randName = puter.randName();
634
- let writeResult = await puter.fs.write(randName, 'testValue');
635
- let result = await (await puter.fs.read(writeResult)).text();
636
- assert(result === 'testValue', "Failed to read from file");
637
- pass("testFSReadWithWriteResult passed");
638
- // delete the file
639
- try {
640
- await puter.fs.delete(randName);
641
- } catch (error) {
642
- fail("testFSReadWithWriteResult failed to delete file:", error);
643
- }
644
- } catch (error) {
645
- fail("testFSReadWithWriteResult failed:", error);
646
- }
647
- }
648
- },
649
- {
650
- name: "testFSStatWithWriteResult",
651
- description: "Test getting file metadata using the object returned by write()",
652
- test: async function() {
653
- try {
654
- let randName = puter.randName();
655
- let writeResult = await puter.fs.write(randName, 'testValue');
656
- let result = await puter.fs.stat(writeResult);
657
- assert(result.uid, "Failed to stat file");
658
- pass("testFSStatWithWriteResult passed");
659
- // delete the file
660
- try {
661
- await puter.fs.delete(randName);
662
- } catch (error) {
663
- fail("testFSStatWithWriteResult failed to delete file:", error);
664
- }
665
- } catch (error) {
666
- fail("testFSStatWithWriteResult failed:", error);
667
- }
668
- }
669
- },
670
- {
671
- name: "testFSWriteWithNaughtyStrings",
672
- description: "Test writing text content to files with names from naughtyStrings and verify it returns a valid UID",
673
- test: async function() {
674
- try {
675
- let randName = puter.randName();
676
- for(let i = 0; i < naughtyStrings.length; i++) {
677
- let filename = randName + naughtyStrings[i];
678
- let result = await puter.fs.write(filename, 'testValue');
679
- assert(result.uid, "Failed to write to file");
680
- // check name
681
- assert(result.name === filename, "Failed to write to file with naughty name: " + filename);
682
- // delete the file
683
- try {
684
- await puter.fs.delete(filename);
685
- } catch (error) {
686
- fail("testFSWriteWithNaughtyStrings failed to delete file: " + filename, error);
687
- }
688
- }
689
- pass("testFSWriteWithNaughtyStrings passed");
690
- } catch (error) {
691
- console.log(error);
692
- fail("testFSWriteWithNaughtyStrings failed:", error);
693
- }
694
- }
695
- },
696
- {
697
- name: "testFSWriteReadBinaryFile",
698
- description: "Test writing and reading binary file data and verify it remains intact",
699
- test: async function() {
700
- try {
701
- let randName = puter.randName() + '.webp';
702
-
703
- // Create some binary data - a simple byte array representing a small binary file
704
- const binaryData = new Uint8Array([
705
- 0x52, 0x49, 0x46, 0x46, 0x24, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38, 0x20,
706
- 0x18, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x9D, 0x01, 0x2A, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00,
707
- 0x34, 0x25, 0xA4, 0x00, 0x03, 0x70, 0x00, 0xFE, 0xFB, 0xFD, 0x50, 0x00
708
- ]);
709
-
710
- // Write the binary data to a file
711
- const writeResult = await puter.fs.write(randName, binaryData);
712
- assert(writeResult.uid, "Failed to write binary file");
713
-
714
- // Read the binary data back
715
- const readResult = await puter.fs.read(randName);
716
- const readBinaryData = new Uint8Array(await readResult.arrayBuffer());
717
-
718
- // Verify the binary data is identical
719
- assert(readBinaryData.length === binaryData.length, "Binary data length mismatch");
720
- for (let i = 0; i < binaryData.length; i++) {
721
- assert(readBinaryData[i] === binaryData[i], `Binary data mismatch at byte ${i}: expected ${binaryData[i]}, got ${readBinaryData[i]}`);
722
- }
723
-
724
- pass("testFSWriteReadBinaryFile passed");
725
-
726
- // Clean up - delete the test file
727
- try {
728
- await puter.fs.delete(randName);
729
- } catch (error) {
730
- fail("testFSWriteReadBinaryFile failed to delete file:", error);
731
- }
732
- } catch (error) {
733
- fail("testFSWriteReadBinaryFile failed:", error);
734
- }
735
- }
736
- },
737
- {
738
- name: "testFSAppDirectoryIsolation",
739
- description: "Test that filesystem operations are properly sandboxed to the app directory and cannot access files outside of it",
740
- test: async function() {
741
- try {
742
- // Test 1: Try to access parent directory with ../
743
- try {
744
- await puter.fs.readdir('~/Desktop');
745
- fail("testFSAppDirectoryIsolation failed: Should not be able to read Desktop directory");
746
- } catch (error) {
747
- if (error.code !== "subject_does_not_exist") {
748
- fail("testFSAppDirectoryIsolation failed: Wrong error code for Desktop directory access: " + error.code);
749
- }
750
- }
751
-
752
- // Test 2: Try to access absolute path outside app directory
753
- try {
754
- await puter.fs.read('/some/absolute/path.txt');
755
- fail("testFSAppDirectoryIsolation failed: Should not be able to read absolute paths");
756
- } catch (error) {
757
- if (error.code !== "access_denied" && error.code !== "invalid_path" && error.code !== "subject_does_not_exist") {
758
- fail("testFSAppDirectoryIsolation failed: Wrong error code for absolute path access: " + error.code);
759
- }
760
- }
761
-
762
- // Test 3: Try to write outside app directory
763
- try {
764
- await puter.fs.write('../escape_file.txt', 'should not work');
765
- fail("testFSAppDirectoryIsolation failed: Should not be able to write outside app directory");
766
- } catch (error) {
767
- if (error.code !== "subject_does_not_exist") {
768
- fail("testFSAppDirectoryIsolation failed: Wrong error code for writing outside directory: " + error.code);
769
- }
770
- }
771
-
772
- // Test 4: Try to create directory outside app directory
773
- try {
774
- await puter.fs.mkdir('../escape_dir');
775
- fail("testFSAppDirectoryIsolation failed: Should not be able to create directory outside app directory");
776
- } catch (error) {
777
- if (error.code !== "subject_does_not_exist") {
778
- fail("testFSAppDirectoryIsolation failed: Wrong error code for creating directory outside: " + error.code);
779
- }
780
- }
781
-
782
- // Test 5: Try to access home directory directly
783
- try {
784
- await puter.fs.read('~/some_file.txt');
785
- fail("testFSAppDirectoryIsolation failed: Should not be able to read from home directory");
786
- } catch (error) {
787
- if (error.code !== "access_denied" && error.code !== "invalid_path" && error.code !== "subject_does_not_exist") {
788
- fail("testFSAppDirectoryIsolation failed: Wrong error code for home directory access: " + error.code);
789
- }
790
- }
791
-
792
- pass("testFSAppDirectoryIsolation passed");
793
- } catch (error) {
794
- fail("testFSAppDirectoryIsolation failed:", error);
795
- }
796
- }
797
- },
798
- ];