@wener/common 2.0.3 → 2.0.6

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 (312) hide show
  1. package/lib/ai/qwen3vl/index.js +1 -1
  2. package/lib/ai/qwen3vl/utils.js +15 -15
  3. package/lib/ai/qwen3vl/utils.js.map +1 -1
  4. package/lib/ai/vision/DocLayoutElementTypeSchema.js +22 -22
  5. package/lib/ai/vision/ImageAnnotationSchema.js +63 -47
  6. package/lib/ai/vision/index.js +2 -2
  7. package/lib/ai/vision/resolveImageAnnotation.js +81 -95
  8. package/lib/cn/ChineseResidentIdNo.js +55 -41
  9. package/lib/cn/ChineseResidentIdNo.js.map +1 -1
  10. package/lib/cn/ChineseResidentIdNo.mod.js +6 -1
  11. package/lib/cn/ChineseResidentIdNo.test.js +22 -21
  12. package/lib/cn/DivisionCode.js +220 -235
  13. package/lib/cn/DivisionCode.mod.js +6 -1
  14. package/lib/cn/DivisionCode.test.js +92 -121
  15. package/lib/cn/Mod11.js +18 -37
  16. package/lib/cn/Mod11.js.map +1 -1
  17. package/lib/cn/Mod31.js +23 -41
  18. package/lib/cn/UnifiedSocialCreditCode.js +143 -137
  19. package/lib/cn/UnifiedSocialCreditCode.mod.js +6 -1
  20. package/lib/cn/UnifiedSocialCreditCode.test.js +21 -15
  21. package/lib/cn/formatChineseAmount.js +46 -71
  22. package/lib/cn/index.js +6 -6
  23. package/lib/cn/mod.js +5 -3
  24. package/lib/cn/parseChineseNumber.js +81 -85
  25. package/lib/cn/parseChineseNumber.test.js +183 -261
  26. package/lib/cn/pinyin/cartesianProduct.js +19 -19
  27. package/lib/cn/pinyin/cartesianProduct.test.js +78 -178
  28. package/lib/cn/pinyin/loader.js +13 -11
  29. package/lib/cn/pinyin/preload.js +2 -1
  30. package/lib/cn/pinyin/toPinyin.test.js +149 -161
  31. package/lib/cn/pinyin/toPinyinPure.js +28 -23
  32. package/lib/cn/pinyin/transform.js +11 -11
  33. package/lib/cn/types.d.js +2 -2
  34. package/lib/consola/createStandardConsolaReporter.js +14 -15
  35. package/lib/consola/formatLogObject.js +149 -133
  36. package/lib/consola/formatLogObject.js.map +1 -1
  37. package/lib/consola/formatLogObject.test.js +167 -178
  38. package/lib/consola/index.js +2 -2
  39. package/lib/data/formatSort.js +14 -12
  40. package/lib/data/formatSort.test.js +33 -33
  41. package/lib/data/index.js +3 -3
  42. package/lib/data/maybeNumber.js +23 -23
  43. package/lib/data/maybeNumber.js.map +1 -1
  44. package/lib/data/parseSort.js +75 -68
  45. package/lib/data/parseSort.test.js +196 -187
  46. package/lib/data/resolvePagination.js +38 -39
  47. package/lib/data/resolvePagination.test.js +228 -218
  48. package/lib/data/types.d.js +2 -2
  49. package/lib/data/types.d.js.map +1 -1
  50. package/lib/dayjs/dayjs.js +20 -20
  51. package/lib/dayjs/formatDuration.js +56 -56
  52. package/lib/dayjs/formatDuration.js.map +1 -1
  53. package/lib/dayjs/formatDuration.test.js +63 -77
  54. package/lib/dayjs/index.js +4 -4
  55. package/lib/dayjs/parseDuration.js +21 -26
  56. package/lib/dayjs/parseRelativeTime.js +65 -66
  57. package/lib/dayjs/parseRelativeTime.test.js +227 -243
  58. package/lib/dayjs/resolveRelativeTime.js +74 -144
  59. package/lib/dayjs/resolveRelativeTime.js.map +1 -1
  60. package/lib/dayjs/resolveRelativeTime.test.js +296 -307
  61. package/lib/decimal/index.js +1 -1
  62. package/lib/decimal/parseDecimal.js +12 -12
  63. package/lib/drain3/Drain.js +321 -0
  64. package/lib/drain3/Drain.js.map +1 -0
  65. package/lib/drain3/LogCluster.js +38 -0
  66. package/lib/drain3/LogCluster.js.map +1 -0
  67. package/lib/drain3/Node.js +39 -0
  68. package/lib/drain3/Node.js.map +1 -0
  69. package/lib/drain3/TemplateMiner.js +205 -0
  70. package/lib/drain3/TemplateMiner.js.map +1 -0
  71. package/lib/drain3/index.js +31 -0
  72. package/lib/drain3/index.js.map +1 -0
  73. package/lib/drain3/persistence/FilePersistence.js +24 -0
  74. package/lib/drain3/persistence/FilePersistence.js.map +1 -0
  75. package/lib/drain3/persistence/MemoryPersistence.js +18 -0
  76. package/lib/drain3/persistence/MemoryPersistence.js.map +1 -0
  77. package/lib/drain3/persistence/PersistenceHandler.js +5 -0
  78. package/lib/drain3/persistence/PersistenceHandler.js.map +1 -0
  79. package/lib/drain3/types.js +7 -0
  80. package/lib/drain3/types.js.map +1 -0
  81. package/lib/emittery/emitter.js +7 -7
  82. package/lib/emittery/index.js +1 -1
  83. package/lib/foundation/schema/SexType.js +15 -12
  84. package/lib/foundation/schema/index.js +1 -1
  85. package/lib/foundation/schema/parseSexType.js +15 -16
  86. package/lib/foundation/schema/types.js +8 -6
  87. package/lib/fs/FileSystemError.js +18 -18
  88. package/lib/fs/IFileSystem.d.js +2 -2
  89. package/lib/fs/IFileSystem.d.js.map +1 -1
  90. package/lib/fs/MemoryFileSystem.test.js +172 -181
  91. package/lib/fs/createBrowserFileSystem.js +222 -233
  92. package/lib/fs/createBrowserFileSystem.js.map +1 -1
  93. package/lib/fs/createMemoryFileSystem.js +473 -510
  94. package/lib/fs/createMemoryFileSystem.js.map +1 -1
  95. package/lib/fs/createSandboxFileSystem.js +102 -101
  96. package/lib/fs/createSandboxFileSystem.js.map +1 -1
  97. package/lib/fs/createWebDavFileSystem.js +162 -132
  98. package/lib/fs/createWebDavFileSystem.js.map +1 -1
  99. package/lib/fs/createWebFileSystem.js +202 -0
  100. package/lib/fs/createWebFileSystem.js.map +1 -0
  101. package/lib/fs/findMimeType.js +14 -14
  102. package/lib/fs/findMimeType.js.map +1 -1
  103. package/lib/fs/index.js +7 -7
  104. package/lib/fs/index.js.map +1 -1
  105. package/lib/fs/minio/createMinioFileSystem.js +977 -0
  106. package/lib/fs/minio/createMinioFileSystem.js.map +1 -0
  107. package/lib/fs/minio/index.js +2 -0
  108. package/lib/fs/minio/index.js.map +1 -0
  109. package/lib/fs/orpc/FileSystemContract.js +57 -57
  110. package/lib/fs/orpc/createContractClientFileSystem.js +88 -88
  111. package/lib/fs/orpc/createContractClientFileSystem.js.map +1 -1
  112. package/lib/fs/orpc/index.js +2 -2
  113. package/lib/fs/orpc/server/createFileSystemContractImpl.js +62 -60
  114. package/lib/fs/orpc/server/createFileSystemContractImpl.js.map +1 -1
  115. package/lib/fs/orpc/server/index.js +1 -1
  116. package/lib/fs/s3/createS3MiniFileSystem.js +756 -689
  117. package/lib/fs/s3/createS3MiniFileSystem.js.map +1 -1
  118. package/lib/fs/s3/index.js +1 -1
  119. package/lib/fs/s3/s3mini.test.js +524 -553
  120. package/lib/fs/scandir.js +56 -56
  121. package/lib/fs/server/createDatabaseFileSystem.js +834 -741
  122. package/lib/fs/server/createDatabaseFileSystem.js.map +1 -1
  123. package/lib/fs/server/createNodeFileSystem.js +407 -380
  124. package/lib/fs/server/createNodeFileSystem.js.map +1 -1
  125. package/lib/fs/server/dbfs.test.js +201 -214
  126. package/lib/fs/server/index.js +1 -1
  127. package/lib/fs/server/loadTestDatabase.js +40 -43
  128. package/lib/fs/tests/runFileSystemTest.js +352 -315
  129. package/lib/fs/tests/runFileSystemTest.js.map +1 -1
  130. package/lib/fs/types.js +17 -20
  131. package/lib/fs/utils/getFileUrl.js +24 -30
  132. package/lib/fs/utils.js +17 -17
  133. package/lib/fs/utils.js.map +1 -1
  134. package/lib/fs/webdav/index.js +2 -0
  135. package/lib/fs/webdav/index.js.map +1 -0
  136. package/lib/index.js +2 -2
  137. package/lib/jsonschema/JsonSchema.js +216 -155
  138. package/lib/jsonschema/JsonSchema.js.map +1 -1
  139. package/lib/jsonschema/JsonSchema.test.js +123 -124
  140. package/lib/jsonschema/forEachJsonSchema.js +41 -41
  141. package/lib/jsonschema/forEachJsonSchema.js.map +1 -1
  142. package/lib/jsonschema/index.js +2 -2
  143. package/lib/jsonschema/types.d.js +2 -2
  144. package/lib/jsonschema/types.d.js.map +1 -1
  145. package/lib/meta/defineFileType.js +32 -38
  146. package/lib/meta/defineInit.js +39 -35
  147. package/lib/meta/defineMetadata.js +37 -34
  148. package/lib/meta/defineMetadata.js.map +1 -1
  149. package/lib/meta/defineMetadata.test.js +13 -12
  150. package/lib/meta/index.js +3 -3
  151. package/lib/orpc/createOpenApiContractClient.js +26 -24
  152. package/lib/orpc/createOpenApiContractClient.js.map +1 -1
  153. package/lib/orpc/createRpcContractClient.js +37 -31
  154. package/lib/orpc/index.js +2 -2
  155. package/lib/orpc/resolveLinkPlugins.js +25 -25
  156. package/lib/password/PHC.js +187 -189
  157. package/lib/password/PHC.js.map +1 -1
  158. package/lib/password/PHC.test.js +517 -535
  159. package/lib/password/Password.js +85 -80
  160. package/lib/password/Password.test.js +330 -364
  161. package/lib/password/createArgon2PasswordAlgorithm.js +50 -51
  162. package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
  163. package/lib/password/createBase64PasswordAlgorithm.js +11 -11
  164. package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
  165. package/lib/password/createBcryptPasswordAlgorithm.js +20 -18
  166. package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
  167. package/lib/password/createPBKDF2PasswordAlgorithm.js +65 -52
  168. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
  169. package/lib/password/createScryptPasswordAlgorithm.js +74 -63
  170. package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
  171. package/lib/password/index.js +5 -5
  172. package/lib/password/server/index.js +1 -1
  173. package/lib/resource/Identifiable.js +2 -2
  174. package/lib/resource/ListQuery.js +42 -42
  175. package/lib/resource/ListQuery.js.map +1 -1
  176. package/lib/resource/getTitleOfResource.js +5 -5
  177. package/lib/resource/index.js +2 -2
  178. package/lib/resource/index.js.map +1 -1
  179. package/lib/resource/schema/AnyResourceSchema.js +91 -89
  180. package/lib/resource/schema/BaseResourceSchema.js +26 -26
  181. package/lib/resource/schema/ResourceActionType.js +117 -115
  182. package/lib/resource/schema/ResourceStatus.js +94 -92
  183. package/lib/resource/schema/ResourceType.js +25 -23
  184. package/lib/resource/schema/index.js +5 -5
  185. package/lib/resource/schema/types.js +86 -55
  186. package/lib/resource/schema/types.test.js +16 -13
  187. package/lib/s3/formatS3Url.js +60 -60
  188. package/lib/s3/formatS3Url.js.map +1 -1
  189. package/lib/s3/formatS3Url.test.js +238 -261
  190. package/lib/s3/index.js +2 -2
  191. package/lib/s3/parseS3Url.js +61 -60
  192. package/lib/s3/parseS3Url.js.map +1 -1
  193. package/lib/s3/parseS3Url.test.js +270 -269
  194. package/lib/schema/SchemaRegistry.js +41 -42
  195. package/lib/schema/SchemaRegistry.js.map +1 -1
  196. package/lib/schema/SchemaRegistry.mod.js +1 -1
  197. package/lib/schema/TypeSchema.d.js +2 -2
  198. package/lib/schema/TypeSchema.d.js.map +1 -1
  199. package/lib/schema/createSchemaData.js +113 -67
  200. package/lib/schema/createSchemaData.js.map +1 -1
  201. package/lib/schema/findJsonSchemaByPath.js +28 -23
  202. package/lib/schema/findJsonSchemaByPath.js.map +1 -1
  203. package/lib/schema/formatZodError.js +113 -134
  204. package/lib/schema/formatZodError.js.map +1 -1
  205. package/lib/schema/formatZodError.test.js +192 -195
  206. package/lib/schema/getSchemaCache.js +7 -7
  207. package/lib/schema/getSchemaOptions.js +17 -16
  208. package/lib/schema/index.js +6 -6
  209. package/lib/schema/toJsonSchema.js +196 -190
  210. package/lib/schema/toJsonSchema.js.map +1 -1
  211. package/lib/schema/toJsonSchema.test.js +34 -26
  212. package/lib/schema/validate.js +106 -97
  213. package/lib/schema/validate.js.map +1 -1
  214. package/lib/tools/generateSchema.js +40 -40
  215. package/lib/tools/renderJsonSchemaToMarkdownDoc.js +74 -74
  216. package/lib/utils/buildBaseUrl.js +8 -8
  217. package/lib/utils/buildRedactorFormSchema.js +55 -54
  218. package/lib/utils/buildRedactorFormSchema.js.map +1 -1
  219. package/lib/utils/getEstimateProcessTime.js +24 -19
  220. package/lib/utils/index.js +3 -3
  221. package/lib/utils/resolveFeatureOptions.js +9 -9
  222. package/package.json +37 -18
  223. package/src/ai/qwen3vl/utils.ts +1 -1
  224. package/src/ai/vision/index.ts +2 -2
  225. package/src/cn/ChineseResidentIdNo.ts +1 -1
  226. package/src/cn/Mod11.ts +1 -1
  227. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +1 -1
  228. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +0 -23
  229. package/src/cn/index.ts +1 -2
  230. package/src/cn/parseChineseNumber.test.ts +4 -4
  231. package/src/consola/formatLogObject.ts +6 -6
  232. package/src/consola/index.ts +1 -1
  233. package/src/data/index.ts +3 -4
  234. package/src/data/maybeNumber.ts +1 -1
  235. package/src/data/parseSort.test.ts +0 -1
  236. package/src/data/resolvePagination.ts +2 -2
  237. package/src/data/types.d.ts +2 -2
  238. package/src/dayjs/formatDuration.ts +10 -11
  239. package/src/dayjs/index.ts +1 -1
  240. package/src/dayjs/parseRelativeTime.ts +1 -1
  241. package/src/dayjs/resolveRelativeTime.ts +11 -14
  242. package/src/drain3/Drain.test.ts +378 -0
  243. package/src/drain3/Drain.ts +394 -0
  244. package/src/drain3/LogCluster.ts +46 -0
  245. package/src/drain3/Node.ts +53 -0
  246. package/src/drain3/TemplateMiner.ts +246 -0
  247. package/src/drain3/index.ts +34 -0
  248. package/src/drain3/persistence/FilePersistence.ts +24 -0
  249. package/src/drain3/persistence/MemoryPersistence.ts +23 -0
  250. package/src/drain3/persistence/PersistenceHandler.ts +19 -0
  251. package/src/drain3/types.ts +75 -0
  252. package/src/fs/IFileSystem.d.ts +1 -2
  253. package/src/fs/createBrowserFileSystem.ts +7 -5
  254. package/src/fs/createMemoryFileSystem.ts +9 -13
  255. package/src/fs/createSandboxFileSystem.ts +1 -1
  256. package/src/fs/createWebDavFileSystem.ts +30 -17
  257. package/src/fs/createWebFileSystem.ts +242 -0
  258. package/src/fs/findMimeType.ts +1 -4
  259. package/src/fs/index.ts +5 -5
  260. package/src/fs/minio/createMinioFileSystem.ts +1148 -0
  261. package/src/fs/minio/index.ts +1 -0
  262. package/src/fs/orpc/createContractClientFileSystem.ts +5 -5
  263. package/src/fs/orpc/server/createFileSystemContractImpl.ts +1 -1
  264. package/src/fs/s3/createS3MiniFileSystem.ts +120 -79
  265. package/src/fs/s3/s3fs.test.ts +441 -0
  266. package/src/fs/s3/s3mini.test.ts +2 -2
  267. package/src/fs/server/createDatabaseFileSystem.ts +78 -114
  268. package/src/fs/server/createNodeFileSystem.ts +32 -13
  269. package/src/fs/server/dbfs.test.ts +13 -8
  270. package/src/fs/server/index.ts +1 -0
  271. package/src/fs/server/loadTestDatabase.ts +8 -119
  272. package/src/fs/tests/runFileSystemTest.ts +29 -28
  273. package/src/fs/utils.ts +1 -1
  274. package/src/fs/webdav/index.ts +1 -0
  275. package/src/jsonschema/JsonSchema.ts +5 -5
  276. package/src/jsonschema/forEachJsonSchema.ts +1 -1
  277. package/src/jsonschema/index.ts +1 -1
  278. package/src/jsonschema/types.d.ts +1 -1
  279. package/src/meta/defineMetadata.ts +1 -1
  280. package/src/meta/index.ts +2 -3
  281. package/src/orm/createSqliteDialect.ts +17 -0
  282. package/src/orm/index.ts +1 -0
  283. package/src/orpc/createOpenApiContractClient.ts +3 -3
  284. package/src/orpc/index.ts +1 -1
  285. package/src/password/PHC.ts +3 -3
  286. package/src/password/createArgon2PasswordAlgorithm.ts +2 -2
  287. package/src/password/createBase64PasswordAlgorithm.ts +2 -2
  288. package/src/password/createBcryptPasswordAlgorithm.ts +4 -2
  289. package/src/password/createPBKDF2PasswordAlgorithm.ts +2 -2
  290. package/src/password/createScryptPasswordAlgorithm.ts +4 -4
  291. package/src/password/index.ts +2 -2
  292. package/src/resource/ListQuery.ts +4 -1
  293. package/src/resource/index.ts +3 -3
  294. package/src/resource/schema/index.ts +4 -4
  295. package/src/s3/formatS3Url.test.ts +1 -1
  296. package/src/s3/formatS3Url.ts +2 -2
  297. package/src/s3/index.ts +1 -1
  298. package/src/s3/parseS3Url.ts +1 -1
  299. package/src/schema/SchemaRegistry.ts +2 -2
  300. package/src/schema/TypeSchema.d.ts +6 -6
  301. package/src/schema/createSchemaData.ts +5 -5
  302. package/src/schema/findJsonSchemaByPath.ts +5 -5
  303. package/src/schema/formatZodError.test.ts +2 -1
  304. package/src/schema/formatZodError.ts +50 -62
  305. package/src/schema/index.ts +5 -5
  306. package/src/schema/toJsonSchema.ts +6 -6
  307. package/src/schema/validate.ts +2 -2
  308. package/src/utils/buildRedactorFormSchema.ts +4 -4
  309. package/src/utils/formatNumber.ts +18 -0
  310. package/src/utils/formatPercent.ts +17 -0
  311. package/src/utils/index.ts +3 -3
  312. package/src/utils/resolveFeatureOptions.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/fs/createMemoryFileSystem.ts"],"sourcesContent":["import type { Readable, Writable } from 'node:stream';\nimport { computeIfAbsent } from '@wener/utils';\nimport { basename, dirname, normalize } from 'pathe';\nimport { findMimeType } from './findMimeType';\nimport type {\n\tCopyOptions,\n\tCreateReadStreamOptions,\n\tCreateWriteStreamOptions,\n\tIFileStat,\n\tIFileSystem,\n\tMkdirOptions,\n\tReadFileOptions,\n\tRenameOptions,\n\tRmOptions,\n\tWriteFileOptions,\n} from './IFileSystem';\n\ntype MemoryNode = MemoryFile | MemoryDirectory;\n\ntype MemoryFile = IFileStat & {\n\tkind: 'file';\n\tcontent: string | Buffer;\n};\n\ntype MemoryDirectory = IFileStat & {\n\tkind: 'directory';\n\tchildren: MemoryNode[];\n};\n\nexport function createMemoryFileSystem(\n\toptions: {\n\t\troot?: MemoryDirectory;\n\t} = {},\n): IFileSystem {\n\treturn new MemFS(options);\n}\n\nclass MemoryFileSystemError extends Error {\n\tcode?: string;\n\n\tconstructor(message: string, code?: string) {\n\t\tsuper(message);\n\t\tthis.name = 'MemoryFileSystemError';\n\t\tthis.code = code;\n\t}\n}\n\ntype Cache = {\n\turl?: string;\n};\n\nclass MemFS implements IFileSystem {\n\tprivate readonly root: MemoryDirectory;\n\n\tprivate readonly cache = new WeakMap<MemoryNode, Cache>();\n\n\tconstructor({\n\t\troot,\n\t}: {\n\t\troot?: MemoryDirectory;\n\t} = {}) {\n\t\tthis.root = root || {\n\t\t\tname: '',\n\t\t\tkind: 'directory',\n\t\t\tpath: '/',\n\t\t\tdirectory: '',\n\t\t\tchildren: [],\n\t\t\tsize: 0,\n\t\t\tmtime: Date.now(),\n\t\t\tmeta: {},\n\t\t};\n\t}\n\n\t/**\n\t * 核心辅助方法:通过路径查找节点\n\t * @returns A tuple: [foundNode, parentNode, finalName]\n\t */\n\tprivate _getNodeByPath(path: string): [MemoryNode | null, MemoryDirectory | null, string] {\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tconst normalized = normalize(path);\n\t\tif (normalized === '/') {\n\t\t\t// the parent of root is itself\n\t\t\treturn [this.root, this.root, ''];\n\t\t}\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\t\tif (parts.length === 0) {\n\t\t\treturn [this.root, this.root, ''];\n\t\t}\n\n\t\tconst finalName = parts.pop()!;\n\n\t\tlet current: MemoryDirectory = this.root;\n\t\tfor (const part of parts) {\n\t\t\tif (!part) continue; // skip empty parts\n\n\t\t\tconst found = current.children.find((child) => child.name === part);\n\t\t\tif (!found || found.kind !== 'directory') {\n\t\t\t\treturn [null, null, finalName];\n\t\t\t}\n\t\t\tcurrent = found;\n\t\t}\n\n\t\tconst node = current.children.find((child) => child.name === finalName) ?? null;\n\t\treturn [node, current, finalName];\n\t}\n\n\t/**\n\t * 核心辅助方法:查找或创建目录\n\t */\n\tprivate _findOrCreateDirectory(path: string): MemoryDirectory {\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tconst normalized = normalize(path);\n\t\tif (normalized === '/') return this.root;\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\t\tif (parts.length === 0) return this.root;\n\n\t\tlet current: MemoryDirectory = this.root;\n\t\tlet currentPath = '';\n\n\t\tfor (const part of parts) {\n\t\t\tif (!part) continue; // skip empty parts\n\n\t\t\tcurrentPath = `${currentPath}/${part}`;\n\t\t\tlet found = current.children.find((child) => child.name === part);\n\t\t\tif (!found) {\n\t\t\t\tconst now = Date.now();\n\t\t\t\tconst newDir: MemoryDirectory = {\n\t\t\t\t\tname: part,\n\t\t\t\t\tkind: 'directory',\n\t\t\t\t\tpath: currentPath,\n\t\t\t\t\tdirectory: dirname(currentPath),\n\t\t\t\t\tchildren: [],\n\t\t\t\t\tsize: 0,\n\t\t\t\t\tmtime: now,\n\t\t\t\t\tmeta: {},\n\t\t\t\t};\n\t\t\t\tcurrent.children.push(newDir);\n\t\t\t\tcurrent = newDir;\n\t\t\t} else if (found.kind !== 'directory') {\n\t\t\t\tthrow new MemoryFileSystemError(`Path conflict: ${currentPath} is a file`, 'ENOTDIR');\n\t\t\t} else {\n\t\t\t\tcurrent = found;\n\t\t\t}\n\t\t}\n\t\treturn current;\n\t}\n\n\tasync stat(path: string, options?: { signal?: AbortSignal }): Promise<IFileStat> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\treturn { ...node };\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\tconst [node] = this._getNodeByPath(path);\n\t\treturn !!node;\n\t}\n\n\tasync readdir(path: string, options?: { signal?: AbortSignal }): Promise<IFileStat[]> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`Directory not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'directory') {\n\t\t\tthrow new MemoryFileSystemError(`Not a directory: ${path}`, 'ENOTDIR');\n\t\t}\n\t\t// 返回副本\n\t\treturn node.children.map((child) => ({ ...child }));\n\t}\n\n\tasync mkdir(path: string, options?: MkdirOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (node) {\n\t\t\tif (node.kind === 'file') throw new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\treturn; // 目录已存在\n\t\t}\n\n\t\tif (options?.recursive) {\n\t\t\tthis._findOrCreateDirectory(path);\n\t\t} else {\n\t\t\tconst parentPath = dirname(path);\n\t\t\tconst [, parent] = this._getNodeByPath(parentPath);\n\t\t\tif (!parent) {\n\t\t\t\tthrow new MemoryFileSystemError(`Parent directory does not exist: ${parentPath}`, 'ENOENT');\n\t\t\t}\n\t\t\tthis._findOrCreateDirectory(path);\n\t\t}\n\t}\n\n\treadFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;\n\treadFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;\n\tasync readFile(path: string, options?: ReadFileOptions): Promise<string | Uint8Array> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = 'content' in node ? node.content : '';\n\t\treturn options?.encoding === 'text' ? content.toString() : Buffer.from(content);\n\t}\n\n\tasync writeFile(path: string, data: string | Buffer, options: WriteFileOptions = {}): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tif (data === null || data === undefined) {\n\t\t\tthrow new MemoryFileSystemError('Invalid data: data cannot be null or undefined', 'EINVAL');\n\t\t}\n\n\t\tconst { overwrite = true } = options;\n\t\tconst parentPath = dirname(path);\n\t\tconst filename = basename(path);\n\n\t\tif (!filename) {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: filename cannot be empty', 'EINVAL');\n\t\t}\n\n\t\tconst parent = this._findOrCreateDirectory(parentPath);\n\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\tif (existingNode) {\n\t\t\tif (!overwrite) throw new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\tif (existingNode.kind === 'directory')\n\t\t\t\tthrow new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR');\n\n\t\t\t// 更新文件\n\t\t\texistingNode.content = data;\n\t\t\texistingNode.size = data.length;\n\t\t\texistingNode.mtime = Date.now();\n\t\t} else {\n\t\t\t// 创建新文件\n\t\t\tconst now = Date.now();\n\t\t\tconst newFile: MemoryFile = {\n\t\t\t\tname: filename,\n\t\t\t\tkind: 'file',\n\t\t\t\tpath: path,\n\t\t\t\tdirectory: parentPath,\n\t\t\t\tcontent: data,\n\t\t\t\tsize: data.length,\n\t\t\t\tmtime: now,\n\t\t\t\tmeta: {},\n\t\t\t};\n\t\t\tparent.children.push(newFile);\n\t\t}\n\t}\n\n\tasync rm(path: string, options: RmOptions = {}): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst { recursive = false, force = false } = options;\n\t\tconst [node, parent] = this._getNodeByPath(path);\n\n\t\tif (!node) {\n\t\t\tif (force) return;\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\n\t\tif (node.kind === 'directory' && node.children.length > 0 && !recursive) {\n\t\t\tthrow new MemoryFileSystemError(`Directory not empty: ${path}`, 'ENOTEMPTY');\n\t\t}\n\n\t\tif (parent) {\n\t\t\tconst index = parent.children.findIndex((child) => child.name === node.name);\n\t\t\tif (index !== -1) {\n\t\t\t\tparent.children.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync rename(oldPath: string, newPath: string, options?: RenameOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [oldNode, oldParent, oldName] = this._getNodeByPath(oldPath);\n\t\tif (!oldNode || !oldParent) throw new MemoryFileSystemError(`Source not found: ${oldPath}`, 'ENOENT');\n\n\t\tconst oldNodeIndex = oldParent.children.findIndex((c) => c.name === oldName);\n\t\toldParent.children.splice(oldNodeIndex, 1);\n\n\t\tconst newParentPath = dirname(newPath);\n\t\tconst newName = basename(newPath);\n\t\tconst newParent = this._findOrCreateDirectory(newParentPath);\n\n\t\tconst existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);\n\t\tif (existingNodeIndex !== -1) {\n\t\t\tif (!options?.overwrite) throw new MemoryFileSystemError(`Destination exists: ${newPath}`, 'EEXIST');\n\t\t\tnewParent.children.splice(existingNodeIndex, 1);\n\t\t}\n\n\t\toldNode.name = newName;\n\t\toldNode.path = newPath;\n\t\toldNode.directory = newParentPath;\n\t\toldNode.mtime = Date.now();\n\t\tnewParent.children.push(oldNode);\n\t}\n\n\tasync copy(srcPath: string, destPath: string, options?: CopyOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [srcNode] = this._getNodeByPath(srcPath);\n\t\tif (!srcNode) throw new MemoryFileSystemError(`Source not found: ${srcPath}`, 'ENOENT');\n\n\t\tconst deepClone = <T extends MemoryNode>(node: T): T => JSON.parse(JSON.stringify(node));\n\t\tconst newNode = deepClone(srcNode);\n\n\t\tconst newParentPath = dirname(destPath);\n\t\tconst newName = basename(destPath);\n\t\tconst newParent = this._findOrCreateDirectory(newParentPath);\n\n\t\tnewNode.name = newName;\n\t\tnewNode.path = destPath;\n\t\tnewNode.directory = newParentPath;\n\n\t\tconst existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);\n\t\tif (existingNodeIndex !== -1) {\n\t\t\tif (!options?.overwrite) throw new MemoryFileSystemError(`Destination exists: ${destPath}`, 'EEXIST');\n\t\t\tnewParent.children[existingNodeIndex] = newNode;\n\t\t} else {\n\t\t\tnewParent.children.push(newNode);\n\t\t}\n\t}\n\n\tcreateReadStream(path: string, options?: CreateReadStreamOptions): Readable {\n\t\tconst { signal, range } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = Buffer.from('content' in node ? node.content : '');\n\t\tconst { Readable } = require('node:stream');\n\n\t\tlet data = content;\n\t\tif (range) {\n\t\t\tconst start = range.start || 0;\n\t\t\tconst end = range.end || content.length - 1;\n\t\t\tdata = content.subarray(start, end + 1);\n\t\t}\n\n\t\tconst stream = Readable.from([data]);\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.destroy(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tcreateWriteStream(path: string, options?: CreateWriteStreamOptions): Writable {\n\t\tconst { signal, overwrite = true } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst { Writable } = require('node:stream');\n\t\tconst chunks: Buffer[] = [];\n\n\t\tconst self = this;\n\t\tconst stream = new Writable({\n\t\t\twrite(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null) => void) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tcallback(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tchunks.push(chunk);\n\t\t\t\tcallback();\n\t\t\t},\n\t\t\tfinal(callback: (error?: Error | null) => void) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tcallback(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst content = Buffer.concat(chunks);\n\t\t\t\t\tconst parentPath = dirname(path);\n\t\t\t\t\tconst filename = basename(path);\n\t\t\t\t\tconst parent = self._findOrCreateDirectory(parentPath);\n\n\t\t\t\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\t\t\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\t\t\t\tif (existingNode) {\n\t\t\t\t\t\tif (!overwrite) {\n\t\t\t\t\t\t\tcallback(new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST'));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (existingNode.kind === 'directory') {\n\t\t\t\t\t\t\tcallback(new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR'));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\texistingNode.content = content;\n\t\t\t\t\t\texistingNode.size = content.length;\n\t\t\t\t\t\texistingNode.mtime = Date.now();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\t\tconst newFile: MemoryFile = {\n\t\t\t\t\t\t\tname: filename,\n\t\t\t\t\t\t\tkind: 'file',\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\tdirectory: parentPath,\n\t\t\t\t\t\t\tcontent: content,\n\t\t\t\t\t\t\tsize: content.length,\n\t\t\t\t\t\t\tmtime: now,\n\t\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tparent.children.push(newFile);\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tcallback(error instanceof Error ? error : new MemoryFileSystemError('Unknown error', 'UNKNOWN'));\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.destroy(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tgetUrl(file: IFileStat | string) {\n\t\tlet node: IFileStat | null;\n\t\tif (typeof file === 'string') {\n\t\t\t[node] = this._getNodeByPath(file);\n\t\t} else {\n\t\t\tnode = file;\n\t\t}\n\t\tlet mf = node as MemoryFile;\n\t\tif (mf.content) {\n\t\t\tlet c = computeIfAbsent(this.cache, mf, () => ({}) as Cache);\n\t\t\tif (!c.url) {\n\t\t\t\tlet mime = findMimeType(mf.name) || 'application/octet-stream';\n\t\t\t\tc.url = URL.createObjectURL(new Blob([mf.content], { type: mime }));\n\t\t\t}\n\n\t\t\treturn c.url;\n\t\t}\n\t\treturn;\n\t}\n\n\tcreateReadableStream(path: string, options?: CreateReadStreamOptions): ReadableStream {\n\t\tconst { signal, range } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = Buffer.from('content' in node ? node.content : '');\n\n\t\tlet data = content;\n\t\tif (range) {\n\t\t\tconst start = range.start || 0;\n\t\t\tconst end = range.end || content.length - 1;\n\t\t\tdata = content.subarray(start, end + 1);\n\t\t}\n\n\t\tconst stream = new ReadableStream({\n\t\t\tstart(controller) {\n\t\t\t\tcontroller.enqueue(data);\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.cancel(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tcreateWritableStream(path: string, options?: CreateWriteStreamOptions): WritableStream {\n\t\tconst { signal, overwrite = true } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst chunks: Buffer[] = [];\n\n\t\tconst self = this;\n\t\tconst stream = new WritableStream({\n\t\t\twrite(chunk: Buffer) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t\t\t}\n\t\t\t\tchunks.push(chunk);\n\t\t\t},\n\t\t\tclose() {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t\t\t}\n\n\t\t\t\tconst content = Buffer.concat(chunks);\n\t\t\t\tconst parentPath = dirname(path);\n\t\t\t\tconst filename = basename(path);\n\t\t\t\tconst parent = self._findOrCreateDirectory(parentPath);\n\n\t\t\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\t\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\t\t\tif (existingNode) {\n\t\t\t\t\tif (!overwrite) {\n\t\t\t\t\t\tthrow new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\t\t\t}\n\t\t\t\t\tif (existingNode.kind === 'directory') {\n\t\t\t\t\t\tthrow new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR');\n\t\t\t\t\t}\n\n\t\t\t\t\texistingNode.content = content;\n\t\t\t\t\texistingNode.size = content.length;\n\t\t\t\t\texistingNode.mtime = Date.now();\n\t\t\t\t} else {\n\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\tconst newFile: MemoryFile = {\n\t\t\t\t\t\tname: filename,\n\t\t\t\t\t\tkind: 'file',\n\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\tdirectory: parentPath,\n\t\t\t\t\t\tcontent: content,\n\t\t\t\t\t\tsize: content.length,\n\t\t\t\t\t\tmtime: now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t};\n\t\t\t\t\tparent.children.push(newFile);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.abort(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n}\n"],"names":["computeIfAbsent","basename","dirname","normalize","findMimeType","createMemoryFileSystem","options","MemFS","MemoryFileSystemError","Error","code","message","name","root","cache","WeakMap","kind","path","directory","children","size","mtime","Date","now","meta","_getNodeByPath","normalized","parts","split","filter","p","length","finalName","pop","current","part","found","find","child","node","_findOrCreateDirectory","currentPath","newDir","push","stat","signal","aborted","exists","readdir","map","mkdir","recursive","parentPath","parent","readFile","content","encoding","toString","Buffer","from","writeFile","data","undefined","overwrite","filename","nodeIndex","findIndex","existingNode","newFile","rm","force","index","splice","rename","oldPath","newPath","oldNode","oldParent","oldName","oldNodeIndex","c","newParentPath","newName","newParent","existingNodeIndex","copy","srcPath","destPath","srcNode","deepClone","JSON","parse","stringify","newNode","createReadStream","range","Readable","require","start","end","subarray","stream","addEventListener","destroy","createWriteStream","Writable","chunks","self","write","chunk","callback","final","concat","error","getUrl","file","mf","url","mime","URL","createObjectURL","Blob","type","createReadableStream","ReadableStream","controller","enqueue","close","cancel","createWritableStream","WritableStream","abort"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/fs/createMemoryFileSystem.ts"],"sourcesContent":["import type { Readable, Writable } from 'node:stream';\nimport { computeIfAbsent } from '@wener/utils';\nimport { basename, dirname, normalize } from 'pathe';\nimport { FileSystemError } from './FileSystemError';\nimport { findMimeType } from './findMimeType';\nimport type {\n\tCopyOptions,\n\tCreateReadStreamOptions,\n\tCreateWriteStreamOptions,\n\tIFileStat,\n\tIFileSystem,\n\tMkdirOptions,\n\tReadFileOptions,\n\tRenameOptions,\n\tRmOptions,\n\tWriteFileOptions,\n} from './IFileSystem';\n\ntype MemoryNode = MemoryFile | MemoryDirectory;\n\ntype MemoryFile = IFileStat & {\n\tkind: 'file';\n\tcontent: string | Buffer;\n};\n\ntype MemoryDirectory = IFileStat & {\n\tkind: 'directory';\n\tchildren: MemoryNode[];\n};\n\nexport function createMemoryFileSystem(options: { root?: MemoryDirectory } = {}): IFileSystem {\n\treturn new MemFS(options);\n}\n\nclass MemoryFileSystemError extends FileSystemError {\n\tconstructor(message: string, code: string) {\n\t\tsuper(message, code);\n\t\tthis.name = 'MemoryFileSystemError';\n\t}\n}\n\ntype Cache = {\n\turl?: string;\n};\n\nclass MemFS implements IFileSystem {\n\tprivate readonly root: MemoryDirectory;\n\n\tprivate readonly cache = new WeakMap<MemoryNode, Cache>();\n\n\tconstructor({\n\t\troot,\n\t}: {\n\t\troot?: MemoryDirectory;\n\t} = {}) {\n\t\tthis.root = root || {\n\t\t\tname: '',\n\t\t\tkind: 'directory',\n\t\t\tpath: '/',\n\t\t\tdirectory: '',\n\t\t\tchildren: [],\n\t\t\tsize: 0,\n\t\t\tmtime: Date.now(),\n\t\t\tmeta: {},\n\t\t};\n\t}\n\n\t/**\n\t * 核心辅助方法:通过路径查找节点\n\t * @returns A tuple: [foundNode, parentNode, finalName]\n\t */\n\tprivate _getNodeByPath(path: string): [MemoryNode | null, MemoryDirectory | null, string] {\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tconst normalized = normalize(path);\n\t\tif (normalized === '/') {\n\t\t\t// the parent of root is itself\n\t\t\treturn [this.root, this.root, ''];\n\t\t}\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\t\tif (parts.length === 0) {\n\t\t\treturn [this.root, this.root, ''];\n\t\t}\n\n\t\tconst finalName = parts.pop()!;\n\n\t\tlet current: MemoryDirectory = this.root;\n\t\tfor (const part of parts) {\n\t\t\tif (!part) continue; // skip empty parts\n\n\t\t\tconst found = current.children.find((child) => child.name === part);\n\t\t\tif (!found || found.kind !== 'directory') {\n\t\t\t\treturn [null, null, finalName];\n\t\t\t}\n\t\t\tcurrent = found;\n\t\t}\n\n\t\tconst node = current.children.find((child) => child.name === finalName) ?? null;\n\t\treturn [node, current, finalName];\n\t}\n\n\t/**\n\t * 核心辅助方法:查找或创建目录\n\t */\n\tprivate _findOrCreateDirectory(path: string): MemoryDirectory {\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tconst normalized = normalize(path);\n\t\tif (normalized === '/') return this.root;\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\t\tif (parts.length === 0) return this.root;\n\n\t\tlet current: MemoryDirectory = this.root;\n\t\tlet currentPath = '';\n\n\t\tfor (const part of parts) {\n\t\t\tif (!part) continue; // skip empty parts\n\n\t\t\tcurrentPath = `${currentPath}/${part}`;\n\t\t\tlet found = current.children.find((child) => child.name === part);\n\t\t\tif (!found) {\n\t\t\t\tconst now = Date.now();\n\t\t\t\tconst newDir: MemoryDirectory = {\n\t\t\t\t\tname: part,\n\t\t\t\t\tkind: 'directory',\n\t\t\t\t\tpath: currentPath,\n\t\t\t\t\tdirectory: dirname(currentPath),\n\t\t\t\t\tchildren: [],\n\t\t\t\t\tsize: 0,\n\t\t\t\t\tmtime: now,\n\t\t\t\t\tmeta: {},\n\t\t\t\t};\n\t\t\t\tcurrent.children.push(newDir);\n\t\t\t\tcurrent = newDir;\n\t\t\t} else if (found.kind !== 'directory') {\n\t\t\t\tthrow new MemoryFileSystemError(`Path conflict: ${currentPath} is a file`, 'ENOTDIR');\n\t\t\t} else {\n\t\t\t\tcurrent = found;\n\t\t\t}\n\t\t}\n\t\treturn current;\n\t}\n\n\tasync stat(path: string, options?: { signal?: AbortSignal }): Promise<IFileStat> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\treturn { ...node };\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\tconst [node] = this._getNodeByPath(path);\n\t\treturn !!node;\n\t}\n\n\tasync readdir(path: string, options?: { signal?: AbortSignal }): Promise<IFileStat[]> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`Directory not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'directory') {\n\t\t\tthrow new MemoryFileSystemError(`Not a directory: ${path}`, 'ENOTDIR');\n\t\t}\n\t\t// 返回副本\n\t\treturn node.children.map((child) => ({ ...child }));\n\t}\n\n\tasync mkdir(path: string, options?: MkdirOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (node) {\n\t\t\tif (node.kind === 'file') throw new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\treturn; // 目录已存在\n\t\t}\n\n\t\tif (options?.recursive) {\n\t\t\tthis._findOrCreateDirectory(path);\n\t\t} else {\n\t\t\tconst parentPath = dirname(path);\n\t\t\tconst [, parent] = this._getNodeByPath(parentPath);\n\t\t\tif (!parent) {\n\t\t\t\tthrow new MemoryFileSystemError(`Parent directory does not exist: ${parentPath}`, 'ENOENT');\n\t\t\t}\n\t\t\tthis._findOrCreateDirectory(path);\n\t\t}\n\t}\n\n\treadFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;\n\treadFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;\n\tasync readFile(path: string, options?: ReadFileOptions): Promise<string | Uint8Array> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = 'content' in node ? node.content : '';\n\t\treturn options?.encoding === 'text' ? content.toString() : Buffer.from(content);\n\t}\n\n\tasync writeFile(path: string, data: string | Buffer, options: WriteFileOptions = {}): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tif (data === null || data === undefined) {\n\t\t\tthrow new MemoryFileSystemError('Invalid data: data cannot be null or undefined', 'EINVAL');\n\t\t}\n\n\t\tconst { overwrite = true } = options;\n\t\tconst parentPath = dirname(path);\n\t\tconst filename = basename(path);\n\n\t\tif (!filename) {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: filename cannot be empty', 'EINVAL');\n\t\t}\n\n\t\tconst parent = this._findOrCreateDirectory(parentPath);\n\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\tif (existingNode) {\n\t\t\tif (!overwrite) throw new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\tif (existingNode.kind === 'directory')\n\t\t\t\tthrow new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR');\n\n\t\t\t// 更新文件\n\t\t\texistingNode.content = data;\n\t\t\texistingNode.size = data.length;\n\t\t\texistingNode.mtime = Date.now();\n\t\t} else {\n\t\t\t// 创建新文件\n\t\t\tconst now = Date.now();\n\t\t\tconst newFile: MemoryFile = {\n\t\t\t\tname: filename,\n\t\t\t\tkind: 'file',\n\t\t\t\tpath: path,\n\t\t\t\tdirectory: parentPath,\n\t\t\t\tcontent: data,\n\t\t\t\tsize: data.length,\n\t\t\t\tmtime: now,\n\t\t\t\tmeta: {},\n\t\t\t};\n\t\t\tparent.children.push(newFile);\n\t\t}\n\t}\n\n\tasync rm(path: string, options: RmOptions = {}): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst { recursive = false, force = false } = options;\n\t\tconst [node, parent] = this._getNodeByPath(path);\n\n\t\tif (!node) {\n\t\t\tif (force) return;\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\n\t\tif (node.kind === 'directory' && node.children.length > 0 && !recursive) {\n\t\t\tthrow new MemoryFileSystemError(`Directory not empty: ${path}`, 'ENOTEMPTY');\n\t\t}\n\n\t\tif (parent) {\n\t\t\tconst index = parent.children.findIndex((child) => child.name === node.name);\n\t\t\tif (index !== -1) {\n\t\t\t\tparent.children.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync rename(oldPath: string, newPath: string, options?: RenameOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [oldNode, oldParent, oldName] = this._getNodeByPath(oldPath);\n\t\tif (!oldNode || !oldParent) throw new MemoryFileSystemError(`Source not found: ${oldPath}`, 'ENOENT');\n\n\t\tconst oldNodeIndex = oldParent.children.findIndex((c) => c.name === oldName);\n\t\toldParent.children.splice(oldNodeIndex, 1);\n\n\t\tconst newParentPath = dirname(newPath);\n\t\tconst newName = basename(newPath);\n\t\tconst newParent = this._findOrCreateDirectory(newParentPath);\n\n\t\tconst existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);\n\t\tif (existingNodeIndex !== -1) {\n\t\t\tif (!options?.overwrite) throw new MemoryFileSystemError(`Destination exists: ${newPath}`, 'EEXIST');\n\t\t\tnewParent.children.splice(existingNodeIndex, 1);\n\t\t}\n\n\t\toldNode.name = newName;\n\t\toldNode.path = newPath;\n\t\toldNode.directory = newParentPath;\n\t\toldNode.mtime = Date.now();\n\t\tnewParent.children.push(oldNode);\n\t}\n\n\tasync copy(srcPath: string, destPath: string, options?: CopyOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [srcNode] = this._getNodeByPath(srcPath);\n\t\tif (!srcNode) throw new MemoryFileSystemError(`Source not found: ${srcPath}`, 'ENOENT');\n\n\t\tconst deepClone = <T extends MemoryNode>(node: T): T => JSON.parse(JSON.stringify(node));\n\t\tconst newNode = deepClone(srcNode);\n\n\t\tconst newParentPath = dirname(destPath);\n\t\tconst newName = basename(destPath);\n\t\tconst newParent = this._findOrCreateDirectory(newParentPath);\n\n\t\tnewNode.name = newName;\n\t\tnewNode.path = destPath;\n\t\tnewNode.directory = newParentPath;\n\n\t\tconst existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);\n\t\tif (existingNodeIndex !== -1) {\n\t\t\tif (!options?.overwrite) throw new MemoryFileSystemError(`Destination exists: ${destPath}`, 'EEXIST');\n\t\t\tnewParent.children[existingNodeIndex] = newNode;\n\t\t} else {\n\t\t\tnewParent.children.push(newNode);\n\t\t}\n\t}\n\n\tcreateReadStream(path: string, options?: CreateReadStreamOptions): Readable {\n\t\tconst { signal, range } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = Buffer.from('content' in node ? node.content : '');\n\t\tconst { Readable } = require('node:stream');\n\n\t\tlet data = content;\n\t\tif (range) {\n\t\t\tconst start = range.start || 0;\n\t\t\tconst end = range.end || content.length - 1;\n\t\t\tdata = content.subarray(start, end + 1);\n\t\t}\n\n\t\tconst stream = Readable.from([data]);\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.destroy(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tcreateWriteStream(path: string, options?: CreateWriteStreamOptions): Writable {\n\t\tconst { signal, overwrite = true } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst { Writable } = require('node:stream');\n\t\tconst chunks: Buffer[] = [];\n\n\t\tconst self = this;\n\t\tconst stream = new Writable({\n\t\t\twrite(chunk: Buffer, _encoding: BufferEncoding, callback: (error?: Error | null) => void) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tcallback(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tchunks.push(chunk);\n\t\t\t\tcallback();\n\t\t\t},\n\t\t\tfinal(callback: (error?: Error | null) => void) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tcallback(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst content = Buffer.concat(chunks);\n\t\t\t\t\tconst parentPath = dirname(path);\n\t\t\t\t\tconst filename = basename(path);\n\t\t\t\t\tconst parent = self._findOrCreateDirectory(parentPath);\n\n\t\t\t\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\t\t\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\t\t\t\tif (existingNode) {\n\t\t\t\t\t\tif (!overwrite) {\n\t\t\t\t\t\t\tcallback(new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST'));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (existingNode.kind === 'directory') {\n\t\t\t\t\t\t\tcallback(new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR'));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\texistingNode.content = content;\n\t\t\t\t\t\texistingNode.size = content.length;\n\t\t\t\t\t\texistingNode.mtime = Date.now();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\t\tconst newFile: MemoryFile = {\n\t\t\t\t\t\t\tname: filename,\n\t\t\t\t\t\t\tkind: 'file',\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\tdirectory: parentPath,\n\t\t\t\t\t\t\tcontent: content,\n\t\t\t\t\t\t\tsize: content.length,\n\t\t\t\t\t\t\tmtime: now,\n\t\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tparent.children.push(newFile);\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tcallback(error instanceof Error ? error : new MemoryFileSystemError('Unknown error', 'UNKNOWN'));\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.destroy(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tgetUrl(file: IFileStat | string) {\n\t\tlet node: IFileStat | null;\n\t\tif (typeof file === 'string') {\n\t\t\t[node] = this._getNodeByPath(file);\n\t\t} else {\n\t\t\tnode = file;\n\t\t}\n\t\tlet mf = node as MemoryFile;\n\t\tif (mf.content) {\n\t\t\tlet c = computeIfAbsent(this.cache, mf, () => ({}) as Cache);\n\t\t\tif (!c.url) {\n\t\t\t\tlet mime = findMimeType(mf.name) || 'application/octet-stream';\n\t\t\t\t// Convert Buffer to Uint8Array for Blob compatibility with TypeScript 5.x strict typing\n\t\t\t\tconst blobPart = typeof mf.content === 'string' ? mf.content : new Uint8Array(mf.content);\n\t\t\t\tc.url = URL.createObjectURL(new Blob([blobPart], { type: mime }));\n\t\t\t}\n\n\t\t\treturn c.url;\n\t\t}\n\t\treturn;\n\t}\n\n\tcreateReadableStream(path: string, options?: CreateReadStreamOptions): ReadableStream {\n\t\tconst { signal, range } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = Buffer.from('content' in node ? node.content : '');\n\n\t\tlet data = content;\n\t\tif (range) {\n\t\t\tconst start = range.start || 0;\n\t\t\tconst end = range.end || content.length - 1;\n\t\t\tdata = content.subarray(start, end + 1);\n\t\t}\n\n\t\tconst stream = new ReadableStream({\n\t\t\tstart(controller) {\n\t\t\t\tcontroller.enqueue(data);\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.cancel(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tcreateWritableStream(path: string, options?: CreateWriteStreamOptions): WritableStream {\n\t\tconst { signal, overwrite = true } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst chunks: Buffer[] = [];\n\n\t\tconst self = this;\n\t\tconst stream = new WritableStream({\n\t\t\twrite(chunk: Buffer) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t\t\t}\n\t\t\t\tchunks.push(chunk);\n\t\t\t},\n\t\t\tclose() {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t\t\t}\n\n\t\t\t\tconst content = Buffer.concat(chunks);\n\t\t\t\tconst parentPath = dirname(path);\n\t\t\t\tconst filename = basename(path);\n\t\t\t\tconst parent = self._findOrCreateDirectory(parentPath);\n\n\t\t\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\t\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\t\t\tif (existingNode) {\n\t\t\t\t\tif (!overwrite) {\n\t\t\t\t\t\tthrow new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\t\t\t}\n\t\t\t\t\tif (existingNode.kind === 'directory') {\n\t\t\t\t\t\tthrow new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR');\n\t\t\t\t\t}\n\n\t\t\t\t\texistingNode.content = content;\n\t\t\t\t\texistingNode.size = content.length;\n\t\t\t\t\texistingNode.mtime = Date.now();\n\t\t\t\t} else {\n\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\tconst newFile: MemoryFile = {\n\t\t\t\t\t\tname: filename,\n\t\t\t\t\t\tkind: 'file',\n\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\tdirectory: parentPath,\n\t\t\t\t\t\tcontent: content,\n\t\t\t\t\t\tsize: content.length,\n\t\t\t\t\t\tmtime: now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t};\n\t\t\t\t\tparent.children.push(newFile);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.abort(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n}\n"],"names":["computeIfAbsent","basename","dirname","normalize","FileSystemError","findMimeType","createMemoryFileSystem","options","MemFS","MemoryFileSystemError","message","code","name","root","cache","WeakMap","kind","path","directory","children","size","mtime","Date","now","meta","_getNodeByPath","normalized","parts","split","filter","p","length","finalName","pop","current","part","found","find","child","node","_findOrCreateDirectory","currentPath","newDir","push","stat","signal","aborted","exists","readdir","map","mkdir","recursive","parentPath","parent","readFile","content","encoding","toString","Buffer","from","writeFile","data","undefined","overwrite","filename","nodeIndex","findIndex","existingNode","newFile","rm","force","index","splice","rename","oldPath","newPath","oldNode","oldParent","oldName","oldNodeIndex","c","newParentPath","newName","newParent","existingNodeIndex","copy","srcPath","destPath","srcNode","deepClone","JSON","parse","stringify","newNode","createReadStream","range","Readable","require","start","end","subarray","stream","addEventListener","destroy","createWriteStream","Writable","chunks","self","write","chunk","_encoding","callback","final","concat","error","Error","getUrl","file","mf","url","mime","blobPart","Uint8Array","URL","createObjectURL","Blob","type","createReadableStream","ReadableStream","controller","enqueue","close","cancel","createWritableStream","WritableStream","abort"],"mappings":"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"}
@@ -1,108 +1,109 @@
1
- import { join, normalize, relative, sep } from "pathe";
2
- import { getPath } from "./utils";
1
+ import { join, normalize, relative, sep } from 'pathe';
2
+ import { getPath } from './utils';
3
+
3
4
  let SandboxSecurityError = class SandboxSecurityError extends Error {
4
- constructor(message){
5
- super(message);
6
- this.name = 'SandboxSecurityError';
7
- }
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = 'SandboxSecurityError';
8
+ }
8
9
  };
9
10
  export function createSandboxFileSystem(fs, basePath) {
10
- return new SandboxFS(fs, basePath);
11
+ return new SandboxFS(fs, basePath);
11
12
  }
12
13
  let SandboxFS = class SandboxFS {
13
- fs;
14
- basePath;
15
- constructor(fs, basePath){
16
- this.fs = fs;
17
- this.basePath = normalize(basePath);
18
- }
19
- _resolvePath(userPath) {
20
- const fullPath = join(this.basePath, userPath);
21
- const normalizedFullPath = normalize(fullPath);
22
- const rel = relative(this.basePath, normalizedFullPath);
23
- if (rel.startsWith('..') || rel === '..') {
24
- throw new SandboxSecurityError(`Path traversal attempt detected: ${userPath}`);
25
- }
26
- return normalizedFullPath;
27
- }
28
- _stripPath(fullPath) {
29
- const relPath = relative(this.basePath, fullPath);
30
- // 保证返回的是一个以 '/' 开头的绝对路径(在沙箱内)
31
- return sep + relPath.split(sep).join('/');
32
- }
33
- _processStat(stat) {
34
- stat.path = this._stripPath(stat.path);
35
- stat.directory = this._stripPath(stat.directory);
36
- return stat;
37
- }
38
- async stat(path, options) {
39
- const fullPath = this._resolvePath(path);
40
- const result = await this.fs.stat(fullPath, options);
41
- return this._processStat(result);
42
- }
43
- async readdir(dir, options) {
44
- const fullPath = this._resolvePath(dir);
45
- const results = await this.fs.readdir(fullPath, options);
46
- return results.map((stat)=>this._processStat(stat));
47
- }
48
- async exists(path) {
49
- try {
50
- const fullPath = this._resolvePath(path);
51
- return await this.fs.exists(fullPath);
52
- } catch (e) {
53
- if (e instanceof SandboxSecurityError) {
54
- return false; // 越界访问视为不存在
55
- }
56
- throw e;
57
- }
58
- }
59
- mkdir(path, options) {
60
- const fullPath = this._resolvePath(path);
61
- return this.fs.mkdir(fullPath, options);
62
- }
63
- readFile(path, options) {
64
- const fullPath = this._resolvePath(path);
65
- return this.fs.readFile(fullPath, options);
66
- }
67
- writeFile(path, data, options) {
68
- const fullPath = this._resolvePath(path);
69
- return this.fs.writeFile(fullPath, data, options);
70
- }
71
- rm(path, options) {
72
- const fullPath = this._resolvePath(path);
73
- return this.fs.rm(fullPath, options);
74
- }
75
- rename(oldPath, newPath, options) {
76
- const fullOldPath = this._resolvePath(oldPath);
77
- const fullNewPath = this._resolvePath(newPath);
78
- return this.fs.rename(fullOldPath, fullNewPath, options);
79
- }
80
- copy(src, dest, options) {
81
- const fullSrc = this._resolvePath(src);
82
- const fullDest = this._resolvePath(dest);
83
- return this.fs.copy(fullSrc, fullDest, options);
84
- }
85
- createReadStream(path, options) {
86
- const fullPath = this._resolvePath(path);
87
- if (!this.fs.createReadStream) {
88
- throw new Error('Underlying filesystem does not support createReadStream');
89
- }
90
- return this.fs.createReadStream(fullPath, options);
91
- }
92
- createWriteStream(path, options) {
93
- const fullPath = this._resolvePath(path);
94
- if (!this.fs.createWriteStream) {
95
- throw new Error('Underlying filesystem does not support createWriteStream');
96
- }
97
- return this.fs.createWriteStream(fullPath, options);
98
- }
99
- getUrl(file, options) {
100
- let path = this._resolvePath(getPath(file.path));
101
- if (this.fs.getUrl) {
102
- return this.fs.getUrl(path, options);
103
- }
104
- return;
105
- }
14
+ fs;
15
+ basePath;
16
+ constructor(fs, basePath) {
17
+ this.fs = fs;
18
+ this.basePath = normalize(basePath);
19
+ }
20
+ _resolvePath(userPath) {
21
+ const fullPath = join(this.basePath, userPath);
22
+ const normalizedFullPath = normalize(fullPath);
23
+ const rel = relative(this.basePath, normalizedFullPath);
24
+ if (rel.startsWith('..') || rel === '..') {
25
+ throw new SandboxSecurityError(`Path traversal attempt detected: ${userPath}`);
26
+ }
27
+ return normalizedFullPath;
28
+ }
29
+ _stripPath(fullPath) {
30
+ const relPath = relative(this.basePath, fullPath);
31
+ // 保证返回的是一个以 '/' 开头的绝对路径(在沙箱内)
32
+ return sep + relPath.split(sep).join('/');
33
+ }
34
+ _processStat(stat) {
35
+ stat.path = this._stripPath(stat.path);
36
+ stat.directory = this._stripPath(stat.directory);
37
+ return stat;
38
+ }
39
+ async stat(path, options) {
40
+ const fullPath = this._resolvePath(path);
41
+ const result = await this.fs.stat(fullPath, options);
42
+ return this._processStat(result);
43
+ }
44
+ async readdir(dir, options) {
45
+ const fullPath = this._resolvePath(dir);
46
+ const results = await this.fs.readdir(fullPath, options);
47
+ return results.map((stat) => this._processStat(stat));
48
+ }
49
+ async exists(path) {
50
+ try {
51
+ const fullPath = this._resolvePath(path);
52
+ return await this.fs.exists(fullPath);
53
+ } catch (e) {
54
+ if (e instanceof SandboxSecurityError) {
55
+ return false; // 越界访问视为不存在
56
+ }
57
+ throw e;
58
+ }
59
+ }
60
+ mkdir(path, options) {
61
+ const fullPath = this._resolvePath(path);
62
+ return this.fs.mkdir(fullPath, options);
63
+ }
64
+ readFile(path, options) {
65
+ const fullPath = this._resolvePath(path);
66
+ return this.fs.readFile(fullPath, options);
67
+ }
68
+ writeFile(path, data, options) {
69
+ const fullPath = this._resolvePath(path);
70
+ return this.fs.writeFile(fullPath, data, options);
71
+ }
72
+ rm(path, options) {
73
+ const fullPath = this._resolvePath(path);
74
+ return this.fs.rm(fullPath, options);
75
+ }
76
+ rename(oldPath, newPath, options) {
77
+ const fullOldPath = this._resolvePath(oldPath);
78
+ const fullNewPath = this._resolvePath(newPath);
79
+ return this.fs.rename(fullOldPath, fullNewPath, options);
80
+ }
81
+ copy(src, dest, options) {
82
+ const fullSrc = this._resolvePath(src);
83
+ const fullDest = this._resolvePath(dest);
84
+ return this.fs.copy(fullSrc, fullDest, options);
85
+ }
86
+ createReadStream(path, options) {
87
+ const fullPath = this._resolvePath(path);
88
+ if (!this.fs.createReadStream) {
89
+ throw new Error('Underlying filesystem does not support createReadStream');
90
+ }
91
+ return this.fs.createReadStream(fullPath, options);
92
+ }
93
+ createWriteStream(path, options) {
94
+ const fullPath = this._resolvePath(path);
95
+ if (!this.fs.createWriteStream) {
96
+ throw new Error('Underlying filesystem does not support createWriteStream');
97
+ }
98
+ return this.fs.createWriteStream(fullPath, options);
99
+ }
100
+ getUrl(file, options) {
101
+ let path = this._resolvePath(getPath(file.path));
102
+ if (this.fs.getUrl) {
103
+ return this.fs.getUrl(path, options);
104
+ }
105
+ return;
106
+ }
106
107
  };
107
108
 
108
- //# sourceMappingURL=createSandboxFileSystem.js.map
109
+ //# sourceMappingURL=createSandboxFileSystem.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/fs/createSandboxFileSystem.ts"],"sourcesContent":["import { join, normalize, relative, sep } from 'pathe';\nimport type { IFileStat, IFileSystem, IServerFileSystem, ReadFileOptions } from './IFileSystem';\nimport { getPath } from './utils';\n\nclass SandboxSecurityError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = 'SandboxSecurityError';\n\t}\n}\n\nexport function createSandboxFileSystem(\n\tfs: IServerFileSystem,\n\tbasePath: string,\n): IServerFileSystem & {\n\tfs: IServerFileSystem;\n\tbasePath: string;\n} {\n\treturn new SandboxFS(fs, basePath);\n}\n\nclass SandboxFS implements IServerFileSystem {\n\tfs: IServerFileSystem;\n\tbasePath: string;\n\n\tconstructor(fs: IServerFileSystem, basePath: string) {\n\t\tthis.fs = fs;\n\t\tthis.basePath = normalize(basePath);\n\t}\n\n\tprivate _resolvePath(userPath: string): string {\n\t\tconst fullPath = join(this.basePath, userPath);\n\n\t\tconst normalizedFullPath = normalize(fullPath);\n\n\t\tconst rel = relative(this.basePath, normalizedFullPath);\n\t\tif (rel.startsWith('..') || rel === '..') {\n\t\t\tthrow new SandboxSecurityError(`Path traversal attempt detected: ${userPath}`);\n\t\t}\n\t\treturn normalizedFullPath;\n\t}\n\n\tprivate _stripPath(fullPath: string): string {\n\t\tconst relPath = relative(this.basePath, fullPath);\n\t\t// 保证返回的是一个以 '/' 开头的绝对路径(在沙箱内)\n\t\treturn sep + relPath.split(sep).join('/');\n\t}\n\n\tprivate _processStat(stat: IFileStat): IFileStat {\n\t\tstat.path = this._stripPath(stat.path);\n\t\tstat.directory = this._stripPath(stat.directory);\n\t\treturn stat;\n\t}\n\n\tasync stat(path: string, options?: any): Promise<IFileStat> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\tconst result = await this.fs.stat(fullPath, options);\n\t\treturn this._processStat(result);\n\t}\n\n\tasync readdir(dir: string, options?: any): Promise<IFileStat[]> {\n\t\tconst fullPath = this._resolvePath(dir);\n\t\tconst results = await this.fs.readdir(fullPath, options);\n\t\treturn results.map((stat) => this._processStat(stat));\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst fullPath = this._resolvePath(path);\n\t\t\treturn await this.fs.exists(fullPath);\n\t\t} catch (e) {\n\t\t\tif (e instanceof SandboxSecurityError) {\n\t\t\t\treturn false; // 越界访问视为不存在\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tmkdir(path: string, options?: any): Promise<void> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.mkdir(fullPath, options);\n\t}\n\n\treadFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;\n\treadFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;\n\treadFile(path: string, options?: ReadFileOptions): Promise<string | Uint8Array> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.readFile(fullPath, options);\n\t}\n\n\twriteFile(path: string, data: any, options?: any): Promise<void> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.writeFile(fullPath, data, options);\n\t}\n\n\trm(path: string, options?: any): Promise<void> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.rm(fullPath, options);\n\t}\n\n\trename(oldPath: string, newPath: string, options?: any): Promise<void> {\n\t\tconst fullOldPath = this._resolvePath(oldPath);\n\t\tconst fullNewPath = this._resolvePath(newPath);\n\t\treturn this.fs.rename(fullOldPath, fullNewPath, options);\n\t}\n\n\tcopy(src: string, dest: string, options?: any): Promise<void> {\n\t\tconst fullSrc = this._resolvePath(src);\n\t\tconst fullDest = this._resolvePath(dest);\n\t\treturn this.fs.copy(fullSrc, fullDest, options);\n\t}\n\n\tcreateReadStream(path: string, options?: any): any {\n\t\tconst fullPath = this._resolvePath(path);\n\t\tif (!this.fs.createReadStream) {\n\t\t\tthrow new Error('Underlying filesystem does not support createReadStream');\n\t\t}\n\t\treturn this.fs.createReadStream(fullPath, options);\n\t}\n\n\tcreateWriteStream(path: string, options?: any): any {\n\t\tconst fullPath = this._resolvePath(path);\n\t\tif (!this.fs.createWriteStream) {\n\t\t\tthrow new Error('Underlying filesystem does not support createWriteStream');\n\t\t}\n\t\treturn this.fs.createWriteStream(fullPath, options);\n\t}\n\n\tgetUrl(file: IFileStat, options?: any): string | undefined {\n\t\tlet path = this._resolvePath(getPath(file.path));\n\t\tif (this.fs.getUrl) {\n\t\t\treturn this.fs.getUrl(path, options);\n\t\t}\n\t\treturn;\n\t}\n}\n"],"names":["join","normalize","relative","sep","getPath","SandboxSecurityError","Error","message","name","createSandboxFileSystem","fs","basePath","SandboxFS","_resolvePath","userPath","fullPath","normalizedFullPath","rel","startsWith","_stripPath","relPath","split","_processStat","stat","path","directory","options","result","readdir","dir","results","map","exists","e","mkdir","readFile","writeFile","data","rm","rename","oldPath","newPath","fullOldPath","fullNewPath","copy","src","dest","fullSrc","fullDest","createReadStream","createWriteStream","getUrl","file"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/fs/createSandboxFileSystem.ts"],"sourcesContent":["import { join, normalize, relative, sep } from 'pathe';\nimport type { IFileStat, IServerFileSystem, ReadFileOptions } from './IFileSystem';\nimport { getPath } from './utils';\n\nclass SandboxSecurityError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = 'SandboxSecurityError';\n\t}\n}\n\nexport function createSandboxFileSystem(\n\tfs: IServerFileSystem,\n\tbasePath: string,\n): IServerFileSystem & {\n\tfs: IServerFileSystem;\n\tbasePath: string;\n} {\n\treturn new SandboxFS(fs, basePath);\n}\n\nclass SandboxFS implements IServerFileSystem {\n\tfs: IServerFileSystem;\n\tbasePath: string;\n\n\tconstructor(fs: IServerFileSystem, basePath: string) {\n\t\tthis.fs = fs;\n\t\tthis.basePath = normalize(basePath);\n\t}\n\n\tprivate _resolvePath(userPath: string): string {\n\t\tconst fullPath = join(this.basePath, userPath);\n\n\t\tconst normalizedFullPath = normalize(fullPath);\n\n\t\tconst rel = relative(this.basePath, normalizedFullPath);\n\t\tif (rel.startsWith('..') || rel === '..') {\n\t\t\tthrow new SandboxSecurityError(`Path traversal attempt detected: ${userPath}`);\n\t\t}\n\t\treturn normalizedFullPath;\n\t}\n\n\tprivate _stripPath(fullPath: string): string {\n\t\tconst relPath = relative(this.basePath, fullPath);\n\t\t// 保证返回的是一个以 '/' 开头的绝对路径(在沙箱内)\n\t\treturn sep + relPath.split(sep).join('/');\n\t}\n\n\tprivate _processStat(stat: IFileStat): IFileStat {\n\t\tstat.path = this._stripPath(stat.path);\n\t\tstat.directory = this._stripPath(stat.directory);\n\t\treturn stat;\n\t}\n\n\tasync stat(path: string, options?: any): Promise<IFileStat> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\tconst result = await this.fs.stat(fullPath, options);\n\t\treturn this._processStat(result);\n\t}\n\n\tasync readdir(dir: string, options?: any): Promise<IFileStat[]> {\n\t\tconst fullPath = this._resolvePath(dir);\n\t\tconst results = await this.fs.readdir(fullPath, options);\n\t\treturn results.map((stat) => this._processStat(stat));\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst fullPath = this._resolvePath(path);\n\t\t\treturn await this.fs.exists(fullPath);\n\t\t} catch (e) {\n\t\t\tif (e instanceof SandboxSecurityError) {\n\t\t\t\treturn false; // 越界访问视为不存在\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tmkdir(path: string, options?: any): Promise<void> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.mkdir(fullPath, options);\n\t}\n\n\treadFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;\n\treadFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;\n\treadFile(path: string, options?: ReadFileOptions): Promise<string | Uint8Array> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.readFile(fullPath, options);\n\t}\n\n\twriteFile(path: string, data: any, options?: any): Promise<void> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.writeFile(fullPath, data, options);\n\t}\n\n\trm(path: string, options?: any): Promise<void> {\n\t\tconst fullPath = this._resolvePath(path);\n\t\treturn this.fs.rm(fullPath, options);\n\t}\n\n\trename(oldPath: string, newPath: string, options?: any): Promise<void> {\n\t\tconst fullOldPath = this._resolvePath(oldPath);\n\t\tconst fullNewPath = this._resolvePath(newPath);\n\t\treturn this.fs.rename(fullOldPath, fullNewPath, options);\n\t}\n\n\tcopy(src: string, dest: string, options?: any): Promise<void> {\n\t\tconst fullSrc = this._resolvePath(src);\n\t\tconst fullDest = this._resolvePath(dest);\n\t\treturn this.fs.copy(fullSrc, fullDest, options);\n\t}\n\n\tcreateReadStream(path: string, options?: any): any {\n\t\tconst fullPath = this._resolvePath(path);\n\t\tif (!this.fs.createReadStream) {\n\t\t\tthrow new Error('Underlying filesystem does not support createReadStream');\n\t\t}\n\t\treturn this.fs.createReadStream(fullPath, options);\n\t}\n\n\tcreateWriteStream(path: string, options?: any): any {\n\t\tconst fullPath = this._resolvePath(path);\n\t\tif (!this.fs.createWriteStream) {\n\t\t\tthrow new Error('Underlying filesystem does not support createWriteStream');\n\t\t}\n\t\treturn this.fs.createWriteStream(fullPath, options);\n\t}\n\n\tgetUrl(file: IFileStat, options?: any): string | undefined {\n\t\tlet path = this._resolvePath(getPath(file.path));\n\t\tif (this.fs.getUrl) {\n\t\t\treturn this.fs.getUrl(path, options);\n\t\t}\n\t\treturn;\n\t}\n}\n"],"names":["join","normalize","relative","sep","getPath","SandboxSecurityError","Error","message","name","createSandboxFileSystem","fs","basePath","SandboxFS","_resolvePath","userPath","fullPath","normalizedFullPath","rel","startsWith","_stripPath","relPath","split","_processStat","stat","path","directory","options","result","readdir","dir","results","map","exists","e","mkdir","readFile","writeFile","data","rm","rename","oldPath","newPath","fullOldPath","fullNewPath","copy","src","dest","fullSrc","fullDest","createReadStream","createWriteStream","getUrl","file"],"mappings":"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"}