@fgv/ts-web-extras 5.1.0-0 → 5.1.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 (332) hide show
  1. package/.rush/temp/chunked-rush-logs/ts-web-extras.build.chunks.jsonl +56 -33
  2. package/.rush/temp/chunked-rush-logs/ts-web-extras.test.chunks.jsonl +70 -0
  3. package/.rush/temp/operation/build/all.log +56 -33
  4. package/.rush/temp/operation/build/error.log +18 -0
  5. package/.rush/temp/operation/build/log-chunks.jsonl +56 -33
  6. package/.rush/temp/operation/build/state.json +1 -1
  7. package/.rush/temp/operation/test/all.log +70 -0
  8. package/.rush/temp/operation/test/error.log +16 -0
  9. package/.rush/temp/operation/test/log-chunks.jsonl +70 -0
  10. package/.rush/temp/operation/test/state.json +3 -0
  11. package/dist/packlets/file-tree/fileApiTreeAccessors.js +15 -0
  12. package/dist/packlets/file-tree/fileApiTreeAccessors.js.map +1 -1
  13. package/dist/packlets/file-tree/fileSystemAccessTreeAccessors.js +79 -10
  14. package/dist/packlets/file-tree/fileSystemAccessTreeAccessors.js.map +1 -1
  15. package/dist/packlets/file-tree/httpTreeAccessors.js +279 -0
  16. package/dist/packlets/file-tree/httpTreeAccessors.js.map +1 -0
  17. package/dist/packlets/file-tree/index.js +1 -0
  18. package/dist/packlets/file-tree/index.js.map +1 -1
  19. package/dist/packlets/file-tree/localStorageTreeAccessors.js +51 -0
  20. package/dist/packlets/file-tree/localStorageTreeAccessors.js.map +1 -1
  21. package/dist/test/unit/fileApiTreeAccessors.test.js +51 -0
  22. package/dist/test/unit/fileApiTreeAccessors.test.js.map +1 -1
  23. package/dist/test/unit/fileSystemAccessTreeAccessors.test.js +265 -160
  24. package/dist/test/unit/fileSystemAccessTreeAccessors.test.js.map +1 -1
  25. package/dist/test/unit/httpTreeAccessors.test.js +1000 -0
  26. package/dist/test/unit/httpTreeAccessors.test.js.map +1 -0
  27. package/dist/test/unit/localStorageTreeAccessors.test.js +218 -1
  28. package/dist/test/unit/localStorageTreeAccessors.test.js.map +1 -1
  29. package/dist/ts-web-extras.d.ts +124 -0
  30. package/docs/@fgv/namespaces/CryptoUtils/README.md +18 -0
  31. package/docs/@fgv/namespaces/CryptoUtils/classes/BrowserCryptoProvider.md +203 -0
  32. package/docs/@fgv/namespaces/CryptoUtils/classes/BrowserHashProvider.md +63 -0
  33. package/docs/@fgv/namespaces/CryptoUtils/functions/createBrowserCryptoProvider.md +18 -0
  34. package/docs/@fgv/namespaces/FileTreeHelpers/README.md +19 -0
  35. package/docs/@fgv/namespaces/FileTreeHelpers/functions/extractFileListMetadata.md +23 -0
  36. package/docs/@fgv/namespaces/FileTreeHelpers/functions/extractFileMetadata.md +23 -0
  37. package/docs/@fgv/namespaces/FileTreeHelpers/functions/fromDirectoryUpload.md +33 -0
  38. package/docs/@fgv/namespaces/FileTreeHelpers/functions/fromFileList.md +33 -0
  39. package/docs/@fgv/namespaces/FileTreeHelpers/functions/getOriginalFile.md +25 -0
  40. package/docs/@fgv/namespaces/FileTreeHelpers/variables/defaultFileApiTreeInitParams.md +11 -0
  41. package/docs/README.md +78 -0
  42. package/docs/classes/DirectoryHandleStore.md +116 -0
  43. package/docs/classes/FileApiTreeAccessors.md +286 -0
  44. package/docs/classes/FileSystemAccessTreeAccessors.md +557 -0
  45. package/docs/classes/HttpTreeAccessors.md +508 -0
  46. package/docs/classes/LocalStorageTreeAccessors.md +520 -0
  47. package/docs/functions/exportAsJson.md +23 -0
  48. package/docs/functions/exportUsingFileSystemAPI.md +26 -0
  49. package/docs/functions/extractDirectoryPath.md +23 -0
  50. package/docs/functions/isDirectoryHandle.md +23 -0
  51. package/docs/functions/isFileHandle.md +23 -0
  52. package/docs/functions/isFilePath.md +21 -0
  53. package/docs/functions/parseContextFilter.md +22 -0
  54. package/docs/functions/parseQualifierDefaults.md +22 -0
  55. package/docs/functions/parseResourceTypes.md +22 -0
  56. package/docs/functions/parseUrlParameters.md +15 -0
  57. package/docs/functions/safeShowDirectoryPicker.md +24 -0
  58. package/docs/functions/safeShowOpenFilePicker.md +24 -0
  59. package/docs/functions/safeShowSaveFilePicker.md +24 -0
  60. package/docs/functions/supportsFileSystemAccess.md +23 -0
  61. package/docs/interfaces/FilePickerAcceptType.md +16 -0
  62. package/docs/interfaces/FileSystemCreateWritableOptions.md +15 -0
  63. package/docs/interfaces/FileSystemDirectoryHandle.md +187 -0
  64. package/docs/interfaces/FileSystemFileHandle.md +106 -0
  65. package/docs/interfaces/FileSystemGetDirectoryOptions.md +15 -0
  66. package/docs/interfaces/FileSystemGetFileOptions.md +15 -0
  67. package/docs/interfaces/FileSystemHandle.md +69 -0
  68. package/docs/interfaces/FileSystemHandlePermissionDescriptor.md +15 -0
  69. package/docs/interfaces/FileSystemRemoveOptions.md +15 -0
  70. package/docs/interfaces/FileSystemWritableFileStream.md +127 -0
  71. package/docs/interfaces/IDirectoryHandleTreeInitializer.md +17 -0
  72. package/docs/interfaces/IFileHandleTreeInitializer.md +16 -0
  73. package/docs/interfaces/IFileListTreeInitializer.md +15 -0
  74. package/docs/interfaces/IFileMetadata.md +19 -0
  75. package/docs/interfaces/IFileSystemAccessTreeParams.md +30 -0
  76. package/docs/interfaces/IFsAccessApis.md +57 -0
  77. package/docs/interfaces/IHttpTreeParams.md +32 -0
  78. package/docs/interfaces/ILocalStorageTreeParams.md +30 -0
  79. package/docs/interfaces/IUrlConfigOptions.md +27 -0
  80. package/docs/interfaces/ShowDirectoryPickerOptions.md +17 -0
  81. package/docs/interfaces/ShowOpenFilePickerOptions.md +19 -0
  82. package/docs/interfaces/ShowSaveFilePickerOptions.md +19 -0
  83. package/docs/type-aliases/TreeInitializer.md +11 -0
  84. package/docs/type-aliases/WellKnownDirectory.md +11 -0
  85. package/docs/type-aliases/WindowWithFsAccess.md +11 -0
  86. package/docs/variables/DEFAULT_DIRECTORY_HANDLE_DB.md +11 -0
  87. package/docs/variables/DEFAULT_DIRECTORY_HANDLE_STORE.md +11 -0
  88. package/etc/ts-web-extras.api.md +33 -0
  89. package/lib/packlets/file-tree/fileApiTreeAccessors.d.ts +9 -0
  90. package/lib/packlets/file-tree/fileApiTreeAccessors.d.ts.map +1 -1
  91. package/lib/packlets/file-tree/fileApiTreeAccessors.js +15 -0
  92. package/lib/packlets/file-tree/fileApiTreeAccessors.js.map +1 -1
  93. package/lib/packlets/file-tree/fileSystemAccessTreeAccessors.d.ts +17 -1
  94. package/lib/packlets/file-tree/fileSystemAccessTreeAccessors.d.ts.map +1 -1
  95. package/lib/packlets/file-tree/fileSystemAccessTreeAccessors.js +78 -9
  96. package/lib/packlets/file-tree/fileSystemAccessTreeAccessors.js.map +1 -1
  97. package/lib/packlets/file-tree/httpTreeAccessors.d.ts +88 -0
  98. package/lib/packlets/file-tree/httpTreeAccessors.d.ts.map +1 -0
  99. package/lib/packlets/file-tree/httpTreeAccessors.js +283 -0
  100. package/lib/packlets/file-tree/httpTreeAccessors.js.map +1 -0
  101. package/lib/packlets/file-tree/index.d.ts +1 -0
  102. package/lib/packlets/file-tree/index.d.ts.map +1 -1
  103. package/lib/packlets/file-tree/index.js +1 -0
  104. package/lib/packlets/file-tree/index.js.map +1 -1
  105. package/lib/packlets/file-tree/localStorageTreeAccessors.d.ts +12 -0
  106. package/lib/packlets/file-tree/localStorageTreeAccessors.d.ts.map +1 -1
  107. package/lib/packlets/file-tree/localStorageTreeAccessors.js +51 -0
  108. package/lib/packlets/file-tree/localStorageTreeAccessors.js.map +1 -1
  109. package/lib/test/unit/fileApiTreeAccessors.test.js +51 -0
  110. package/lib/test/unit/fileApiTreeAccessors.test.js.map +1 -1
  111. package/lib/test/unit/fileSystemAccessTreeAccessors.test.js +265 -160
  112. package/lib/test/unit/fileSystemAccessTreeAccessors.test.js.map +1 -1
  113. package/lib/test/unit/httpTreeAccessors.test.d.ts +2 -0
  114. package/lib/test/unit/httpTreeAccessors.test.d.ts.map +1 -0
  115. package/lib/test/unit/httpTreeAccessors.test.js +1002 -0
  116. package/lib/test/unit/httpTreeAccessors.test.js.map +1 -0
  117. package/lib/test/unit/localStorageTreeAccessors.test.js +218 -1
  118. package/lib/test/unit/localStorageTreeAccessors.test.js.map +1 -1
  119. package/package.json +25 -25
  120. package/rush-logs/ts-web-extras.build.cache.log +0 -3
  121. package/rush-logs/ts-web-extras.build.error.log +18 -0
  122. package/rush-logs/ts-web-extras.build.log +56 -33
  123. package/rush-logs/ts-web-extras.test.cache.log +1 -0
  124. package/rush-logs/ts-web-extras.test.error.log +16 -0
  125. package/rush-logs/ts-web-extras.test.log +70 -0
  126. package/src/packlets/file-tree/fileApiTreeAccessors.ts +18 -0
  127. package/src/packlets/file-tree/fileSystemAccessTreeAccessors.ts +100 -8
  128. package/src/packlets/file-tree/httpTreeAccessors.ts +381 -0
  129. package/src/packlets/file-tree/index.ts +1 -0
  130. package/src/packlets/file-tree/localStorageTreeAccessors.ts +53 -0
  131. package/src/test/unit/fileApiTreeAccessors.test.ts +69 -0
  132. package/src/test/unit/fileSystemAccessTreeAccessors.test.ts +341 -188
  133. package/src/test/unit/httpTreeAccessors.test.ts +1278 -0
  134. package/src/test/unit/localStorageTreeAccessors.test.ts +269 -1
  135. package/temp/build/typescript/ts_8nwakTlr.json +1 -1
  136. package/temp/coverage/crypto/browserHashProvider.ts.html +304 -0
  137. package/temp/coverage/crypto/index.html +116 -0
  138. package/temp/coverage/crypto-utils/browserCryptoProvider.ts.html +1 -1
  139. package/temp/coverage/crypto-utils/browserHashProvider.ts.html +1 -1
  140. package/temp/coverage/crypto-utils/index.html +1 -1
  141. package/temp/coverage/file-tree/directoryHandleStore.ts.html +1 -1
  142. package/temp/coverage/file-tree/fileApiTreeAccessors.ts.html +60 -6
  143. package/temp/coverage/file-tree/fileSystemAccessTreeAccessors.ts.html +410 -134
  144. package/temp/coverage/file-tree/httpTreeAccessors.ts.html +1228 -0
  145. package/temp/coverage/file-tree/index.html +35 -20
  146. package/temp/coverage/file-tree/localStorageTreeAccessors.ts.html +318 -159
  147. package/temp/coverage/helpers/fileTreeHelpers.ts.html +1 -1
  148. package/temp/coverage/helpers/index.html +1 -1
  149. package/temp/coverage/index.html +11 -11
  150. package/temp/coverage/lcov-report/crypto/browserHashProvider.ts.html +304 -0
  151. package/temp/coverage/lcov-report/crypto/index.html +116 -0
  152. package/temp/coverage/lcov-report/crypto-utils/browserCryptoProvider.ts.html +1 -1
  153. package/temp/coverage/lcov-report/crypto-utils/browserHashProvider.ts.html +1 -1
  154. package/temp/coverage/lcov-report/crypto-utils/index.html +1 -1
  155. package/temp/coverage/lcov-report/file-tree/directoryHandleStore.ts.html +1 -1
  156. package/temp/coverage/lcov-report/file-tree/fileApiTreeAccessors.ts.html +60 -6
  157. package/temp/coverage/lcov-report/file-tree/fileSystemAccessTreeAccessors.ts.html +410 -134
  158. package/temp/coverage/lcov-report/file-tree/httpTreeAccessors.ts.html +1228 -0
  159. package/temp/coverage/lcov-report/file-tree/index.html +35 -20
  160. package/temp/coverage/lcov-report/file-tree/localStorageTreeAccessors.ts.html +318 -159
  161. package/temp/coverage/lcov-report/helpers/fileTreeHelpers.ts.html +1 -1
  162. package/temp/coverage/lcov-report/helpers/index.html +1 -1
  163. package/temp/coverage/lcov-report/index.html +11 -11
  164. package/temp/coverage/lcov-report/url-utils/index.html +1 -1
  165. package/temp/coverage/lcov-report/url-utils/urlParams.ts.html +1 -1
  166. package/temp/coverage/lcov.info +1920 -1196
  167. package/temp/coverage/url-utils/index.html +1 -1
  168. package/temp/coverage/url-utils/urlParams.ts.html +1 -1
  169. package/temp/test/jest/haste-map-b931e4e63102f86c5bd4949f7dced44f-9d713eb41149188b4e5c0ae3d86d0a57-2ad8e16b24e391b8cdbe50b55c137169 +0 -0
  170. package/temp/test/jest/perf-cache-b931e4e63102f86c5bd4949f7dced44f-da39a3ee5e6b4b0d3255bfef95601890 +1 -0
  171. package/temp/ts-web-extras.api.json +1313 -354
  172. package/temp/ts-web-extras.api.md +33 -0
  173. package/.rush/temp/81e0881271ff236956b2f52e8ca99da6574c6e1e.tar.log +0 -223
  174. package/docs/index.md +0 -34
  175. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider._constructor_.md +0 -50
  176. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.decrypt.md +0 -104
  177. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.derivekey.md +0 -88
  178. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.encrypt.md +0 -72
  179. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.frombase64.md +0 -56
  180. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.generatekey.md +0 -19
  181. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.generaterandombytes.md +0 -56
  182. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.md +0 -169
  183. package/docs/ts-web-extras.cryptoutils.browsercryptoprovider.tobase64.md +0 -56
  184. package/docs/ts-web-extras.cryptoutils.browserhashprovider.hashparts.md +0 -88
  185. package/docs/ts-web-extras.cryptoutils.browserhashprovider.hashstring.md +0 -72
  186. package/docs/ts-web-extras.cryptoutils.browserhashprovider.md +0 -66
  187. package/docs/ts-web-extras.cryptoutils.createbrowsercryptoprovider.md +0 -19
  188. package/docs/ts-web-extras.cryptoutils.md +0 -71
  189. package/docs/ts-web-extras.exportasjson.md +0 -70
  190. package/docs/ts-web-extras.exportusingfilesystemapi.md +0 -104
  191. package/docs/ts-web-extras.extractdirectorypath.md +0 -52
  192. package/docs/ts-web-extras.fileapitreeaccessors.create.md +0 -72
  193. package/docs/ts-web-extras.fileapitreeaccessors.createfromlocalstorage.md +0 -74
  194. package/docs/ts-web-extras.fileapitreeaccessors.createpersistent.md +0 -76
  195. package/docs/ts-web-extras.fileapitreeaccessors.extractfilemetadata.md +0 -54
  196. package/docs/ts-web-extras.fileapitreeaccessors.fromdirectoryupload.md +0 -72
  197. package/docs/ts-web-extras.fileapitreeaccessors.fromfilelist.md +0 -72
  198. package/docs/ts-web-extras.fileapitreeaccessors.getoriginalfile.md +0 -72
  199. package/docs/ts-web-extras.fileapitreeaccessors.md +0 -146
  200. package/docs/ts-web-extras.filepickeraccepttype.accept.md +0 -11
  201. package/docs/ts-web-extras.filepickeraccepttype.description.md +0 -11
  202. package/docs/ts-web-extras.filepickeraccepttype.md +0 -75
  203. package/docs/ts-web-extras.filesystemaccesstreeaccessors._constructor_.md +0 -114
  204. package/docs/ts-web-extras.filesystemaccesstreeaccessors.fileismutable.md +0 -52
  205. package/docs/ts-web-extras.filesystemaccesstreeaccessors.fromdirectoryhandle.md +0 -72
  206. package/docs/ts-web-extras.filesystemaccesstreeaccessors.getdirtypaths.md +0 -17
  207. package/docs/ts-web-extras.filesystemaccesstreeaccessors.isdirty.md +0 -17
  208. package/docs/ts-web-extras.filesystemaccesstreeaccessors.md +0 -159
  209. package/docs/ts-web-extras.filesystemaccesstreeaccessors.savefilecontents.md +0 -66
  210. package/docs/ts-web-extras.filesystemaccesstreeaccessors.synctodisk.md +0 -17
  211. package/docs/ts-web-extras.filesystemcreatewritableoptions_2.keepexistingdata.md +0 -11
  212. package/docs/ts-web-extras.filesystemcreatewritableoptions_2.md +0 -58
  213. package/docs/ts-web-extras.filesystemdirectoryhandle_2._symbol.asynciterator_.md +0 -15
  214. package/docs/ts-web-extras.filesystemdirectoryhandle_2.entries.md +0 -15
  215. package/docs/ts-web-extras.filesystemdirectoryhandle_2.getdirectoryhandle.md +0 -66
  216. package/docs/ts-web-extras.filesystemdirectoryhandle_2.getfilehandle.md +0 -66
  217. package/docs/ts-web-extras.filesystemdirectoryhandle_2.keys.md +0 -15
  218. package/docs/ts-web-extras.filesystemdirectoryhandle_2.kind.md +0 -11
  219. package/docs/ts-web-extras.filesystemdirectoryhandle_2.md +0 -146
  220. package/docs/ts-web-extras.filesystemdirectoryhandle_2.removeentry.md +0 -66
  221. package/docs/ts-web-extras.filesystemdirectoryhandle_2.resolve.md +0 -50
  222. package/docs/ts-web-extras.filesystemdirectoryhandle_2.values.md +0 -15
  223. package/docs/ts-web-extras.filesystemfilehandle_2.createwritable.md +0 -52
  224. package/docs/ts-web-extras.filesystemfilehandle_2.getfile.md +0 -15
  225. package/docs/ts-web-extras.filesystemfilehandle_2.kind.md +0 -11
  226. package/docs/ts-web-extras.filesystemfilehandle_2.md +0 -92
  227. package/docs/ts-web-extras.filesystemgetdirectoryoptions_2.create.md +0 -11
  228. package/docs/ts-web-extras.filesystemgetdirectoryoptions_2.md +0 -58
  229. package/docs/ts-web-extras.filesystemgetfileoptions_2.create.md +0 -11
  230. package/docs/ts-web-extras.filesystemgetfileoptions_2.md +0 -58
  231. package/docs/ts-web-extras.filesystemhandle_2.issameentry.md +0 -50
  232. package/docs/ts-web-extras.filesystemhandle_2.kind.md +0 -11
  233. package/docs/ts-web-extras.filesystemhandle_2.md +0 -119
  234. package/docs/ts-web-extras.filesystemhandle_2.name.md +0 -11
  235. package/docs/ts-web-extras.filesystemhandle_2.querypermission.md +0 -52
  236. package/docs/ts-web-extras.filesystemhandle_2.requestpermission.md +0 -52
  237. package/docs/ts-web-extras.filesystemhandlepermissiondescriptor.md +0 -58
  238. package/docs/ts-web-extras.filesystemhandlepermissiondescriptor.mode.md +0 -11
  239. package/docs/ts-web-extras.filesystemremoveoptions_2.md +0 -58
  240. package/docs/ts-web-extras.filesystemremoveoptions_2.recursive.md +0 -11
  241. package/docs/ts-web-extras.filesystemwritablefilestream_2.md +0 -57
  242. package/docs/ts-web-extras.filesystemwritablefilestream_2.seek.md +0 -50
  243. package/docs/ts-web-extras.filesystemwritablefilestream_2.truncate.md +0 -50
  244. package/docs/ts-web-extras.filesystemwritablefilestream_2.write.md +0 -50
  245. package/docs/ts-web-extras.filetreehelpers.defaultfileapitreeinitparams.md +0 -13
  246. package/docs/ts-web-extras.filetreehelpers.extractfilelistmetadata.md +0 -56
  247. package/docs/ts-web-extras.filetreehelpers.extractfilemetadata.md +0 -56
  248. package/docs/ts-web-extras.filetreehelpers.fromdirectoryupload.md +0 -76
  249. package/docs/ts-web-extras.filetreehelpers.fromfilelist.md +0 -76
  250. package/docs/ts-web-extras.filetreehelpers.getoriginalfile.md +0 -72
  251. package/docs/ts-web-extras.filetreehelpers.md +0 -102
  252. package/docs/ts-web-extras.idirectoryhandletreeinitializer.dirhandles.md +0 -11
  253. package/docs/ts-web-extras.idirectoryhandletreeinitializer.md +0 -100
  254. package/docs/ts-web-extras.idirectoryhandletreeinitializer.nonrecursive.md +0 -11
  255. package/docs/ts-web-extras.idirectoryhandletreeinitializer.prefix.md +0 -11
  256. package/docs/ts-web-extras.ifilehandletreeinitializer.filehandles.md +0 -11
  257. package/docs/ts-web-extras.ifilehandletreeinitializer.md +0 -79
  258. package/docs/ts-web-extras.ifilehandletreeinitializer.prefix.md +0 -11
  259. package/docs/ts-web-extras.ifilelisttreeinitializer.filelist.md +0 -11
  260. package/docs/ts-web-extras.ifilelisttreeinitializer.md +0 -58
  261. package/docs/ts-web-extras.ifilemetadata.lastmodified.md +0 -11
  262. package/docs/ts-web-extras.ifilemetadata.md +0 -124
  263. package/docs/ts-web-extras.ifilemetadata.name.md +0 -11
  264. package/docs/ts-web-extras.ifilemetadata.path.md +0 -11
  265. package/docs/ts-web-extras.ifilemetadata.size.md +0 -11
  266. package/docs/ts-web-extras.ifilemetadata.type.md +0 -11
  267. package/docs/ts-web-extras.ifilesystemaccesstreeparams.autosync.md +0 -13
  268. package/docs/ts-web-extras.ifilesystemaccesstreeparams.md +0 -78
  269. package/docs/ts-web-extras.ifilesystemaccesstreeparams.requirewritepermission.md +0 -13
  270. package/docs/ts-web-extras.ifsaccessapis.md +0 -56
  271. package/docs/ts-web-extras.ifsaccessapis.showdirectorypicker.md +0 -52
  272. package/docs/ts-web-extras.ifsaccessapis.showopenfilepicker.md +0 -52
  273. package/docs/ts-web-extras.ifsaccessapis.showsavefilepicker.md +0 -52
  274. package/docs/ts-web-extras.ilocalstoragetreeparams.autosync.md +0 -13
  275. package/docs/ts-web-extras.ilocalstoragetreeparams.md +0 -97
  276. package/docs/ts-web-extras.ilocalstoragetreeparams.pathtokeymap.md +0 -13
  277. package/docs/ts-web-extras.ilocalstoragetreeparams.storage.md +0 -13
  278. package/docs/ts-web-extras.isdirectoryhandle.md +0 -56
  279. package/docs/ts-web-extras.isfilehandle.md +0 -56
  280. package/docs/ts-web-extras.isfilepath.md +0 -52
  281. package/docs/ts-web-extras.iurlconfigoptions.config.md +0 -13
  282. package/docs/ts-web-extras.iurlconfigoptions.configstartdir.md +0 -13
  283. package/docs/ts-web-extras.iurlconfigoptions.contextfilter.md +0 -13
  284. package/docs/ts-web-extras.iurlconfigoptions.input.md +0 -13
  285. package/docs/ts-web-extras.iurlconfigoptions.inputstartdir.md +0 -13
  286. package/docs/ts-web-extras.iurlconfigoptions.interactive.md +0 -13
  287. package/docs/ts-web-extras.iurlconfigoptions.loadzip.md +0 -13
  288. package/docs/ts-web-extras.iurlconfigoptions.maxdistance.md +0 -13
  289. package/docs/ts-web-extras.iurlconfigoptions.md +0 -286
  290. package/docs/ts-web-extras.iurlconfigoptions.qualifierdefaults.md +0 -13
  291. package/docs/ts-web-extras.iurlconfigoptions.reducequalifiers.md +0 -13
  292. package/docs/ts-web-extras.iurlconfigoptions.resourcetypes.md +0 -13
  293. package/docs/ts-web-extras.iurlconfigoptions.zipfile.md +0 -13
  294. package/docs/ts-web-extras.iurlconfigoptions.zippath.md +0 -13
  295. package/docs/ts-web-extras.localstoragetreeaccessors.fileismutable.md +0 -56
  296. package/docs/ts-web-extras.localstoragetreeaccessors.fromstorage.md +0 -56
  297. package/docs/ts-web-extras.localstoragetreeaccessors.getdirtypaths.md +0 -19
  298. package/docs/ts-web-extras.localstoragetreeaccessors.isdirty.md +0 -19
  299. package/docs/ts-web-extras.localstoragetreeaccessors.md +0 -131
  300. package/docs/ts-web-extras.localstoragetreeaccessors.savefilecontents.md +0 -72
  301. package/docs/ts-web-extras.localstoragetreeaccessors.synctodisk.md +0 -19
  302. package/docs/ts-web-extras.md +0 -558
  303. package/docs/ts-web-extras.parsecontextfilter.md +0 -52
  304. package/docs/ts-web-extras.parsequalifierdefaults.md +0 -52
  305. package/docs/ts-web-extras.parseresourcetypes.md +0 -52
  306. package/docs/ts-web-extras.parseurlparameters.md +0 -17
  307. package/docs/ts-web-extras.safeshowdirectorypicker.md +0 -72
  308. package/docs/ts-web-extras.safeshowopenfilepicker.md +0 -72
  309. package/docs/ts-web-extras.safeshowsavefilepicker.md +0 -72
  310. package/docs/ts-web-extras.showdirectorypickeroptions.id.md +0 -11
  311. package/docs/ts-web-extras.showdirectorypickeroptions.md +0 -96
  312. package/docs/ts-web-extras.showdirectorypickeroptions.mode.md +0 -11
  313. package/docs/ts-web-extras.showdirectorypickeroptions.startin.md +0 -11
  314. package/docs/ts-web-extras.showopenfilepickeroptions.excludeacceptalloption.md +0 -11
  315. package/docs/ts-web-extras.showopenfilepickeroptions.id.md +0 -11
  316. package/docs/ts-web-extras.showopenfilepickeroptions.md +0 -134
  317. package/docs/ts-web-extras.showopenfilepickeroptions.multiple.md +0 -11
  318. package/docs/ts-web-extras.showopenfilepickeroptions.startin.md +0 -11
  319. package/docs/ts-web-extras.showopenfilepickeroptions.types.md +0 -11
  320. package/docs/ts-web-extras.showsavefilepickeroptions.excludeacceptalloption.md +0 -11
  321. package/docs/ts-web-extras.showsavefilepickeroptions.id.md +0 -11
  322. package/docs/ts-web-extras.showsavefilepickeroptions.md +0 -134
  323. package/docs/ts-web-extras.showsavefilepickeroptions.startin.md +0 -11
  324. package/docs/ts-web-extras.showsavefilepickeroptions.suggestedname.md +0 -11
  325. package/docs/ts-web-extras.showsavefilepickeroptions.types.md +0 -11
  326. package/docs/ts-web-extras.supportsfilesystemaccess.md +0 -56
  327. package/docs/ts-web-extras.treeinitializer.md +0 -15
  328. package/docs/ts-web-extras.wellknowndirectory.md +0 -13
  329. package/docs/ts-web-extras.windowwithfsaccess.md +0 -15
  330. package/temp/test/jest/haste-map-7492f1b44480e0cdd1f220078fb3afd8-c8dd6c3430605adeb2f1cadf4f75e791-8c9336785555d572065b28c111982ba4 +0 -0
  331. package/temp/test/jest/perf-cache-7492f1b44480e0cdd1f220078fb3afd8-da39a3ee5e6b4b0d3255bfef95601890 +0 -1
  332. /package/temp/test/jest/{jest-transform-cache-7492f1b44480e0cdd1f220078fb3afd8-79ef2876fae7ca75eedb2aa53dc48338/8d/package_8dcbedef69e4299f0f51fcda8f4f1c8e → jest-transform-cache-b931e4e63102f86c5bd4949f7dced44f-79ef2876fae7ca75eedb2aa53dc48338/b5/package_b5f57afc9ec2c011239b1608ee5bdfa5} +0 -0
@@ -22,6 +22,7 @@
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  require("@fgv/ts-utils-jest");
25
+ const ts_utils_1 = require("@fgv/ts-utils");
25
26
  const file_tree_1 = require("../../packlets/file-tree");
26
27
  const file_tree_2 = require("../../packlets/file-tree");
27
28
  const ts_json_base_1 = require("@fgv/ts-json-base");
@@ -333,186 +334,290 @@ describe('FileSystemAccessTreeAccessors', () => {
333
334
  })).orThrow();
334
335
  accessors.saveFileContents('/test.txt', 'modified').orThrow();
335
336
  // Verify file is marked dirty but not synced
336
- expect(accessors.isDirty()).toBe(true);
337
337
  expect(accessors.getDirtyPaths()).toContain('/test.txt');
338
338
  // In-memory content should be modified
339
339
  expect(accessors.getFileContents('/test.txt')).toSucceedWith('modified');
340
340
  });
341
- });
342
- });
343
- describe('fileIsMutable', () => {
344
- test('returns persistent detail when write permission granted', async () => {
345
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
346
- 'test.txt': { content: 'test', type: 'text/plain' }
347
- });
348
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
349
- const result = accessors.fileIsMutable('/test.txt');
350
- expect(result).toSucceedWithDetail(true, 'persistent');
351
- });
352
- test('returns transient detail when write permission not granted', async () => {
353
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { hasWritePermission: false });
354
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
355
- mutable: true,
356
- requireWritePermission: false
357
- })).orThrow();
358
- const result = accessors.fileIsMutable('/test.txt');
359
- expect(result).toSucceedWithDetail(true, 'transient');
360
- });
361
- test('returns not-mutable when mutability disabled', async () => {
362
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
363
- 'test.txt': { content: 'test', type: 'text/plain' }
341
+ test('logs when save auto-sync returns a failure Result', async () => {
342
+ const logger = {
343
+ detail: jest.fn(),
344
+ info: jest.fn(),
345
+ warn: jest.fn(),
346
+ error: jest.fn()
347
+ };
348
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
349
+ 'test.txt': { content: 'original', type: 'text/plain' }
350
+ });
351
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
352
+ mutable: true,
353
+ autoSync: true,
354
+ logger
355
+ })).orThrow();
356
+ accessors._syncFile = async () => (0, ts_utils_1.fail)('simulated save sync failure');
357
+ accessors.saveFileContents('/test.txt', 'modified').orThrow();
358
+ await new Promise((resolve) => setTimeout(resolve, 0));
359
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('simulated save sync failure'));
360
+ });
361
+ test('logs when delete auto-sync throws unexpectedly', async () => {
362
+ const logger = {
363
+ detail: jest.fn(),
364
+ info: jest.fn(),
365
+ warn: jest.fn(),
366
+ error: jest.fn()
367
+ };
368
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
369
+ 'test.txt': { content: 'original', type: 'text/plain' }
370
+ });
371
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
372
+ mutable: true,
373
+ autoSync: true,
374
+ logger
375
+ })).orThrow();
376
+ accessors._deleteFileFromDisk = async () => {
377
+ throw new Error('simulated delete throw');
378
+ };
379
+ accessors.deleteFile('/test.txt').orThrow();
380
+ await new Promise((resolve) => setTimeout(resolve, 0));
381
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('simulated delete throw'));
364
382
  });
365
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: false })).orThrow();
366
- const result = accessors.fileIsMutable('/test.txt');
367
- expect(result).toFailWithDetail(/mutability is disabled/i, 'not-mutable');
368
383
  });
369
- });
370
- describe('integration with FileApiTreeAccessors', () => {
371
- test('createPersistent creates FileTree with persistent accessors', async () => {
372
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
373
- 'test.txt': { content: 'test content', type: 'text/plain' }
384
+ describe('fileIsMutable', () => {
385
+ test('returns persistent detail when write permission granted', async () => {
386
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
387
+ 'test.txt': { content: 'test', type: 'text/plain' }
388
+ });
389
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
390
+ const result = accessors.fileIsMutable('/test.txt');
391
+ expect(result).toSucceedWithDetail(true, 'persistent');
374
392
  });
375
- const result = await file_tree_2.FileApiTreeAccessors.createPersistent(dirHandle, { mutable: true });
376
- expect(result).toSucceed();
377
- const tree = result.orThrow();
378
- expect(tree).toBeInstanceOf(ts_json_base_1.FileTree.FileTree);
379
- expect(ts_json_base_1.FileTree.isPersistentAccessors(tree.hal)).toBe(true);
380
- const file = tree.getFile('/test.txt').orThrow();
381
- expect(file.getIsMutable()).toSucceedWithDetail(true, 'persistent');
382
- });
383
- test('createPersistent with autoSync option', async () => {
384
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
385
- 'test.txt': { content: 'original', type: 'text/plain' }
393
+ test('returns transient detail when write permission not granted', async () => {
394
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { hasWritePermission: false });
395
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
396
+ mutable: true,
397
+ requireWritePermission: false
398
+ })).orThrow();
399
+ const result = accessors.fileIsMutable('/test.txt');
400
+ expect(result).toSucceedWithDetail(true, 'transient');
386
401
  });
387
- const result = await file_tree_2.FileApiTreeAccessors.createPersistent(dirHandle, {
388
- mutable: true,
389
- autoSync: true
402
+ test('returns not-mutable when mutability disabled', async () => {
403
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
404
+ 'test.txt': { content: 'test', type: 'text/plain' }
405
+ });
406
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: false })).orThrow();
407
+ const result = accessors.fileIsMutable('/test.txt');
408
+ expect(result).toFailWithDetail(/mutability is disabled/i, 'not-mutable');
390
409
  });
391
- expect(result).toSucceedAndSatisfy((tree) => {
410
+ });
411
+ describe('integration with FileApiTreeAccessors', () => {
412
+ test('createPersistent creates FileTree with persistent accessors', async () => {
413
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
414
+ 'test.txt': { content: 'test content', type: 'text/plain' }
415
+ });
416
+ const result = await file_tree_2.FileApiTreeAccessors.createPersistent(dirHandle, { mutable: true });
417
+ expect(result).toSucceed();
418
+ const tree = result.orThrow();
392
419
  expect(tree).toBeInstanceOf(ts_json_base_1.FileTree.FileTree);
420
+ expect(ts_json_base_1.FileTree.isPersistentAccessors(tree.hal)).toBe(true);
421
+ const file = tree.getFile('/test.txt').orThrow();
422
+ expect(ts_json_base_1.FileTree.isMutableFileItem(file)).toBe(true);
423
+ if (ts_json_base_1.FileTree.isMutableFileItem(file)) {
424
+ expect(file.getIsMutable()).toSucceedWithDetail(true, 'persistent');
425
+ }
393
426
  });
394
- const tree = result.orThrow();
395
- const file = tree.getFile('/test.txt').orThrow();
396
- file.setRawContents('modified').orThrow();
397
- // Give auto-sync time to complete
398
- await new Promise((resolve) => setTimeout(resolve, 10));
399
- // Verify file was written
400
- const fileHandle = await dirHandle.getFileHandle('test.txt');
401
- const diskFile = await fileHandle.getFile();
402
- const content = await diskFile.text();
403
- expect(content).toBe('modified');
404
- });
405
- test('createPersistent fails with appropriate error', async () => {
406
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { hasWritePermission: false });
407
- const result = await file_tree_2.FileApiTreeAccessors.createPersistent(dirHandle, {
408
- requireWritePermission: true
427
+ test('createPersistent with autoSync option', async () => {
428
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
429
+ 'test.txt': { content: 'original', type: 'text/plain' }
430
+ });
431
+ const result = await file_tree_2.FileApiTreeAccessors.createPersistent(dirHandle, {
432
+ mutable: true,
433
+ autoSync: true
434
+ });
435
+ expect(result).toSucceedAndSatisfy((tree) => {
436
+ expect(tree).toBeInstanceOf(ts_json_base_1.FileTree.FileTree);
437
+ });
438
+ const tree = result.orThrow();
439
+ const file = tree.getFile('/test.txt').orThrow();
440
+ expect(ts_json_base_1.FileTree.isMutableFileItem(file)).toBe(true);
441
+ if (ts_json_base_1.FileTree.isMutableFileItem(file)) {
442
+ file.setRawContents('modified').orThrow();
443
+ }
444
+ // Give auto-sync time to complete
445
+ await new Promise((resolve) => setTimeout(resolve, 10));
446
+ // Verify file was written
447
+ const fileHandle = await dirHandle.getFileHandle('test.txt');
448
+ const diskFile = await fileHandle.getFile();
449
+ const content = await diskFile.text();
450
+ expect(content).toBe('modified');
409
451
  });
410
- expect(result).toFailWith(/write permission required/i);
411
- });
412
- });
413
- describe('error handling', () => {
414
- test('handles permission query errors gracefully', async () => {
415
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { permissionError: true });
416
- const result = await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
417
- requireWritePermission: false
452
+ test('createPersistent fails with appropriate error', async () => {
453
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { hasWritePermission: false });
454
+ const result = await file_tree_2.FileApiTreeAccessors.createPersistent(dirHandle, {
455
+ requireWritePermission: true
456
+ });
457
+ expect(result).toFailWith(/write permission required/i);
418
458
  });
419
- // Should succeed but without write permission due to error
420
- expect(result).toSucceed();
421
459
  });
422
- test('handles permission status "prompt" by requesting permission', async () => {
423
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { permissionStatus: 'prompt', requestGranted: true });
424
- const result = await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
425
- requireWritePermission: true
460
+ describe('error handling', () => {
461
+ test('handles permission query errors gracefully', async () => {
462
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { permissionError: true });
463
+ const result = await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
464
+ requireWritePermission: false
465
+ });
466
+ // Should succeed but without write permission due to error
467
+ expect(result).toSucceed();
426
468
  });
427
- expect(result).toSucceedAndSatisfy((accessors) => {
428
- expect(accessors).toBeInstanceOf(file_tree_1.FileSystemAccessTreeAccessors);
469
+ test('handles permission status "prompt" by requesting permission', async () => {
470
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', { 'test.txt': { content: 'test', type: 'text/plain' } }, { permissionStatus: 'prompt', requestGranted: true });
471
+ const result = await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, {
472
+ requireWritePermission: true
473
+ });
474
+ expect(result).toSucceedAndSatisfy((accessors) => {
475
+ expect(accessors).toBeInstanceOf(file_tree_1.FileSystemAccessTreeAccessors);
476
+ });
429
477
  });
430
- });
431
- test('handles sync failures with aggregated errors', async () => {
432
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
433
- 'file1.txt': { content: 'content1', type: 'text/plain' },
434
- 'file2.txt': { content: 'content2', type: 'text/plain' }
435
- });
436
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
437
- // Modify files
438
- accessors.saveFileContents('/file1.txt', 'modified1').orThrow();
439
- accessors.saveFileContents('/file2.txt', 'modified2').orThrow();
440
- // Replace the file handles with ones that fail to write
441
- const handles = accessors._handles;
442
- for (const [, handle] of handles) {
443
- handle.createWritable = jest.fn().mockRejectedValue(new Error('Write permission denied'));
444
- }
445
- const syncResult = await accessors.syncToDisk();
446
- expect(syncResult).toFailWith(/Failed to sync 2 file\(s\)/i);
447
- });
448
- test('handles getFileContents failure during sync', async () => {
449
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
450
- 'test.txt': { content: 'original', type: 'text/plain' }
451
- });
452
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
453
- // Add a new file
454
- accessors.saveFileContents('/newfile.txt', 'new content').orThrow();
455
- // Override getFileContents to fail
456
- const originalGetFileContents = accessors.getFileContents.bind(accessors);
457
- accessors.getFileContents = jest.fn((path) => {
458
- if (path === '/newfile.txt') {
459
- return { isSuccess: () => false, isFailure: () => true, message: 'File read error' };
478
+ test('handles sync failures with aggregated errors', async () => {
479
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
480
+ 'file1.txt': { content: 'content1', type: 'text/plain' },
481
+ 'file2.txt': { content: 'content2', type: 'text/plain' }
482
+ });
483
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
484
+ // Modify files
485
+ accessors.saveFileContents('/file1.txt', 'modified1').orThrow();
486
+ accessors.saveFileContents('/file2.txt', 'modified2').orThrow();
487
+ // Replace the file handles with ones that fail to write
488
+ const handles = accessors._handles;
489
+ for (const [, handle] of handles) {
490
+ handle.createWritable = jest.fn().mockRejectedValue(new Error('Write permission denied'));
460
491
  }
461
- return originalGetFileContents(path);
492
+ const syncResult = await accessors.syncToDisk();
493
+ expect(syncResult).toFailWith(/Failed to sync 2 file\(s\)/i);
462
494
  });
463
- const syncResult = await accessors.syncToDisk();
464
- expect(syncResult).toFailWith(/File read error/i);
465
- });
466
- test('handles file write failure during sync', async () => {
467
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
468
- 'test.txt': { content: 'original', type: 'text/plain' }
469
- });
470
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
471
- accessors.saveFileContents('/test.txt', 'modified').orThrow();
472
- // Replace the handle with one that fails to write
473
- const handles = accessors._handles;
474
- const handle = handles.get('/test.txt');
475
- handle.createWritable = jest.fn().mockRejectedValue(new Error('Disk full'));
476
- const syncResult = await accessors.syncToDisk();
477
- expect(syncResult).toFailWith(/Failed to write file.*Disk full/i);
478
- });
479
- test('handles invalid file path with no filename', async () => {
480
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
481
- 'existing.txt': { content: 'existing', type: 'text/plain' }
482
- });
483
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
484
- // Override resolveAbsolutePath to return an empty path to trigger the error
485
- const originalResolveAbsolutePath = accessors.resolveAbsolutePath.bind(accessors);
486
- accessors.resolveAbsolutePath = jest.fn((path) => {
487
- if (path === '/badpath') {
488
- return ''; // This will result in no parts after split
495
+ test('handles getFileContents failure during sync', async () => {
496
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
497
+ 'test.txt': { content: 'original', type: 'text/plain' }
498
+ });
499
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
500
+ // Add a new file
501
+ accessors.saveFileContents('/newfile.txt', 'new content').orThrow();
502
+ // Override getFileContents to fail
503
+ const originalGetFileContents = accessors.getFileContents.bind(accessors);
504
+ accessors.getFileContents = jest.fn((path) => {
505
+ if (path === '/newfile.txt') {
506
+ return { isSuccess: () => false, isFailure: () => true, message: 'File read error' };
507
+ }
508
+ return originalGetFileContents(path);
509
+ });
510
+ const syncResult = await accessors.syncToDisk();
511
+ expect(syncResult).toFailWith(/File read error/i);
512
+ });
513
+ test('handles file write failure during sync', async () => {
514
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
515
+ 'test.txt': { content: 'original', type: 'text/plain' }
516
+ });
517
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
518
+ accessors.saveFileContents('/test.txt', 'modified').orThrow();
519
+ // Replace the handle with one that fails to write
520
+ const handles = accessors._handles;
521
+ const handle = handles.get('/test.txt');
522
+ handle.createWritable = jest.fn().mockRejectedValue(new Error('Disk full'));
523
+ const syncResult = await accessors.syncToDisk();
524
+ expect(syncResult).toFailWith(/Failed to write file.*Disk full/i);
525
+ });
526
+ test('handles invalid file path with no filename', async () => {
527
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
528
+ 'existing.txt': { content: 'existing', type: 'text/plain' }
529
+ });
530
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
531
+ // Override resolveAbsolutePath to return an empty path to trigger the error
532
+ const originalResolveAbsolutePath = accessors.resolveAbsolutePath.bind(accessors);
533
+ accessors.resolveAbsolutePath = jest.fn((path) => {
534
+ if (path === '/badpath') {
535
+ return ''; // This will result in no parts after split
536
+ }
537
+ return originalResolveAbsolutePath(path);
538
+ });
539
+ // Create a new file with the bad path - don't throw if it fails
540
+ const saveResult = accessors.saveFileContents('/badpath', 'content');
541
+ if (saveResult.isFailure()) {
542
+ // saveFileContents itself might reject the path
543
+ expect(saveResult).toFailWith(/invalid file path/i);
544
+ }
545
+ else {
546
+ // If save succeeded, sync should fail
547
+ const syncResult = await accessors.syncToDisk();
548
+ expect(syncResult).toFailWith(/Invalid file path/i);
489
549
  }
490
- return originalResolveAbsolutePath(path);
491
- });
492
- // Create a new file with the bad path - don't throw if it fails
493
- const saveResult = accessors.saveFileContents('/badpath', 'content');
494
- if (saveResult.isFailure()) {
495
- // saveFileContents itself might reject the path
496
- expect(saveResult).toFailWith(/invalid file path/i);
497
- }
498
- else {
499
- // If save succeeded, sync should fail
550
+ });
551
+ test('handles file creation failure in _createAndWriteFile', async () => {
552
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
553
+ 'existing.txt': { content: 'existing', type: 'text/plain' }
554
+ });
555
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
556
+ // Add a new file that will need to be created
557
+ accessors.saveFileContents('/newdir/newfile.txt', 'new content').orThrow();
558
+ // Mock getDirectoryHandle to fail
559
+ const rootDir = accessors._rootDir;
560
+ rootDir.getDirectoryHandle = jest.fn().mockRejectedValue(new Error('Permission denied'));
500
561
  const syncResult = await accessors.syncToDisk();
501
- expect(syncResult).toFailWith(/Invalid file path/i);
502
- }
503
- });
504
- test('handles file creation failure in _createAndWriteFile', async () => {
505
- const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
506
- 'existing.txt': { content: 'existing', type: 'text/plain' }
507
- });
508
- const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
509
- // Add a new file that will need to be created
510
- accessors.saveFileContents('/newdir/newfile.txt', 'new content').orThrow();
511
- // Mock getDirectoryHandle to fail
512
- const rootDir = accessors._rootDir;
513
- rootDir.getDirectoryHandle = jest.fn().mockRejectedValue(new Error('Permission denied'));
514
- const syncResult = await accessors.syncToDisk();
515
- expect(syncResult).toFailWith(/Failed to create file.*Permission denied/i);
562
+ expect(syncResult).toFailWith(/Failed to create file.*Permission denied/i);
563
+ });
564
+ test('successfully deletes a root-level file from disk via syncToDisk pending deletions', async () => {
565
+ // Covers lines 329-333: the pending deletions loop in syncToDisk
566
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
567
+ 'toDelete.txt': { content: 'will be deleted', type: 'text/plain' },
568
+ 'keep.txt': { content: 'stays', type: 'text/plain' }
569
+ });
570
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
571
+ // Delete the file from in-memory tree
572
+ accessors.deleteFile('/toDelete.txt').orThrow();
573
+ expect(accessors.isDirty()).toBe(true);
574
+ expect(accessors.getDirtyPaths()).toContain('/toDelete.txt');
575
+ // syncToDisk should process the pending deletion
576
+ const syncResult = await accessors.syncToDisk();
577
+ expect(syncResult).toSucceed();
578
+ expect(accessors.isDirty()).toBe(false);
579
+ });
580
+ test('successfully deletes a nested file from disk via syncToDisk (navigates parent dirs)', async () => {
581
+ // Covers lines 468-469: getDirectoryHandle navigation loop in _deleteFileFromDisk
582
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
583
+ 'src/utils/helper.txt': { content: 'to be deleted', type: 'text/plain' },
584
+ 'src/index.txt': { content: 'stays', type: 'text/plain' }
585
+ });
586
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
587
+ // Delete the nested file
588
+ accessors.deleteFile('/src/utils/helper.txt').orThrow();
589
+ expect(accessors.isDirty()).toBe(true);
590
+ const syncResult = await accessors.syncToDisk();
591
+ expect(syncResult).toSucceed();
592
+ expect(accessors.isDirty()).toBe(false);
593
+ });
594
+ test('aggregates deletion errors when _deleteFileFromDisk fails during syncToDisk', async () => {
595
+ // Covers lines 330-332: the error aggregation when _deleteFileFromDisk returns failure
596
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
597
+ 'toDelete.txt': { content: 'content', type: 'text/plain' }
598
+ });
599
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
600
+ accessors.deleteFile('/toDelete.txt').orThrow();
601
+ // Make removeEntry fail to trigger the error path in _deleteFileFromDisk
602
+ const rootDir = accessors._rootDir;
603
+ rootDir.removeEntry = jest.fn().mockRejectedValue(new Error('Cannot delete: file locked'));
604
+ const syncResult = await accessors.syncToDisk();
605
+ expect(syncResult).toFailWith(/Failed to sync 1 file/i);
606
+ expect(syncResult).toFailWith(/delete.*toDelete\.txt/i);
607
+ });
608
+ test('catch block in _deleteFileFromDisk when removeEntry throws', async () => {
609
+ // Covers lines 473-476: the catch block in _deleteFileFromDisk
610
+ const dirHandle = (0, fileSystemAccessMocks_1.createMockDirectoryHandle)('/', {
611
+ 'target.txt': { content: 'content', type: 'text/plain' }
612
+ });
613
+ const accessors = (await file_tree_1.FileSystemAccessTreeAccessors.fromDirectoryHandle(dirHandle, { mutable: true })).orThrow();
614
+ accessors.deleteFile('/target.txt').orThrow();
615
+ // Directly make _rootDir.removeEntry throw a non-Error value to test the catch branch
616
+ const rootDir = accessors._rootDir;
617
+ rootDir.removeEntry = jest.fn().mockRejectedValue('non-error string');
618
+ const syncResult = await accessors.syncToDisk();
619
+ expect(syncResult).toFailWith(/Failed to delete file.*non-error string/i);
620
+ });
516
621
  });
517
622
  });
518
623
  });