@wener/common 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/lib/ai/qwen3vl/index.js +2 -0
  2. package/lib/ai/qwen3vl/index.js.map +1 -0
  3. package/lib/ai/qwen3vl/utils.js +31 -0
  4. package/lib/ai/qwen3vl/utils.js.map +1 -0
  5. package/lib/ai/vision/DocLayoutElementTypeSchema.js +28 -0
  6. package/lib/ai/vision/DocLayoutElementTypeSchema.js.map +1 -0
  7. package/lib/ai/vision/ImageAnnotationSchema.js +50 -0
  8. package/lib/ai/vision/ImageAnnotationSchema.js.map +1 -0
  9. package/lib/ai/vision/index.js +3 -0
  10. package/lib/ai/vision/index.js.map +1 -0
  11. package/lib/ai/vision/resolveImageAnnotation.js +105 -0
  12. package/lib/ai/vision/resolveImageAnnotation.js.map +1 -0
  13. package/lib/cn/ChineseResidentIdNo.js +48 -0
  14. package/lib/cn/ChineseResidentIdNo.js.map +1 -0
  15. package/lib/cn/ChineseResidentIdNo.mod.js +1 -0
  16. package/lib/cn/{ResidentIdentityCardNumber.test.js → ChineseResidentIdNo.test.js} +7 -6
  17. package/lib/cn/DivisionCode.js +217 -301
  18. package/lib/cn/DivisionCode.js.map +1 -0
  19. package/lib/cn/DivisionCode.mod.js +1 -0
  20. package/lib/cn/DivisionCode.test.js +9 -15
  21. package/lib/cn/Mod11.js +43 -0
  22. package/lib/cn/Mod11.js.map +1 -0
  23. package/lib/cn/Mod31.js +49 -0
  24. package/lib/cn/Mod31.js.map +1 -0
  25. package/lib/cn/UnifiedSocialCreditCode.js +137 -113
  26. package/lib/cn/UnifiedSocialCreditCode.js.map +1 -0
  27. package/lib/cn/UnifiedSocialCreditCode.mod.js +1 -0
  28. package/lib/cn/UnifiedSocialCreditCode.test.js +1 -1
  29. package/lib/cn/formatChineseAmount.js +77 -0
  30. package/lib/cn/formatChineseAmount.js.map +1 -0
  31. package/lib/cn/index.js +6 -2
  32. package/lib/cn/index.js.map +1 -0
  33. package/lib/cn/mod.js +6 -0
  34. package/lib/cn/parseChineseNumber.js +94 -0
  35. package/lib/cn/parseChineseNumber.js.map +1 -0
  36. package/lib/cn/parseChineseNumber.test.js +278 -0
  37. package/lib/cn/pinyin/cartesianProduct.js +22 -0
  38. package/lib/cn/pinyin/cartesianProduct.js.map +1 -0
  39. package/lib/cn/pinyin/cartesianProduct.test.js +179 -0
  40. package/lib/cn/pinyin/data.json +23573 -0
  41. package/lib/cn/pinyin/loader.js +14 -0
  42. package/lib/cn/pinyin/loader.js.map +1 -0
  43. package/lib/cn/pinyin/preload.js +3 -0
  44. package/lib/cn/pinyin/preload.js.map +1 -0
  45. package/lib/cn/pinyin/toPinyin.test.js +167 -0
  46. package/lib/cn/pinyin/toPinyinPure.js +33 -0
  47. package/lib/cn/pinyin/toPinyinPure.js.map +1 -0
  48. package/lib/cn/pinyin/transform.js +14 -0
  49. package/lib/cn/pinyin/transform.js.map +1 -0
  50. package/lib/cn/types.d.js +2 -0
  51. package/lib/cn/types.d.js.map +1 -0
  52. package/lib/consola/createStandardConsolaReporter.js +6 -6
  53. package/lib/consola/createStandardConsolaReporter.js.map +1 -0
  54. package/lib/consola/formatLogObject.js +67 -135
  55. package/lib/consola/formatLogObject.js.map +1 -0
  56. package/lib/consola/formatLogObject.test.js +184 -0
  57. package/lib/consola/index.js +1 -0
  58. package/lib/consola/index.js.map +1 -0
  59. package/lib/data/formatSort.js +6 -5
  60. package/lib/data/formatSort.js.map +1 -0
  61. package/lib/data/index.js +1 -0
  62. package/lib/data/index.js.map +1 -0
  63. package/lib/data/maybeNumber.js +5 -7
  64. package/lib/data/maybeNumber.js.map +1 -0
  65. package/lib/data/parseSort.js +22 -28
  66. package/lib/data/parseSort.js.map +1 -0
  67. package/lib/data/resolvePagination.js +13 -17
  68. package/lib/data/resolvePagination.js.map +1 -0
  69. package/lib/data/types.d.js +2 -0
  70. package/lib/data/types.d.js.map +1 -0
  71. package/lib/dayjs/dayjs.js +40 -0
  72. package/lib/dayjs/dayjs.js.map +1 -0
  73. package/lib/dayjs/formatDuration.js +59 -0
  74. package/lib/dayjs/formatDuration.js.map +1 -0
  75. package/lib/dayjs/formatDuration.test.js +90 -0
  76. package/lib/dayjs/index.js +5 -0
  77. package/lib/dayjs/index.js.map +1 -0
  78. package/lib/dayjs/parseDuration.js +29 -0
  79. package/lib/dayjs/parseDuration.js.map +1 -0
  80. package/lib/dayjs/parseRelativeTime.js +90 -0
  81. package/lib/dayjs/parseRelativeTime.js.map +1 -0
  82. package/lib/dayjs/parseRelativeTime.test.js +247 -0
  83. package/lib/dayjs/resolveRelativeTime.js +158 -0
  84. package/lib/dayjs/resolveRelativeTime.js.map +1 -0
  85. package/lib/dayjs/resolveRelativeTime.test.js +310 -0
  86. package/lib/decimal/index.js +2 -0
  87. package/lib/decimal/index.js.map +1 -0
  88. package/lib/decimal/parseDecimal.js +15 -0
  89. package/lib/decimal/parseDecimal.js.map +1 -0
  90. package/lib/emittery/emitter.js +10 -0
  91. package/lib/emittery/emitter.js.map +1 -0
  92. package/lib/emittery/index.js +2 -0
  93. package/lib/emittery/index.js.map +1 -0
  94. package/lib/foundation/schema/SexType.js +16 -0
  95. package/lib/foundation/schema/SexType.js.map +1 -0
  96. package/lib/foundation/schema/index.js +2 -0
  97. package/lib/foundation/schema/index.js.map +1 -0
  98. package/lib/foundation/schema/parseSexType.js +19 -0
  99. package/lib/foundation/schema/parseSexType.js.map +1 -0
  100. package/lib/foundation/schema/types.js +7 -0
  101. package/lib/foundation/schema/types.js.map +1 -0
  102. package/lib/fs/FileSystemError.js +23 -0
  103. package/lib/fs/FileSystemError.js.map +1 -0
  104. package/lib/fs/IFileSystem.d.js +3 -0
  105. package/lib/fs/IFileSystem.d.js.map +1 -0
  106. package/lib/fs/MemoryFileSystem.test.js +188 -0
  107. package/lib/fs/createBrowserFileSystem.js +248 -0
  108. package/lib/fs/createBrowserFileSystem.js.map +1 -0
  109. package/lib/fs/createMemoryFileSystem.js +516 -0
  110. package/lib/fs/createMemoryFileSystem.js.map +1 -0
  111. package/lib/fs/createSandboxFileSystem.js +108 -0
  112. package/lib/fs/createSandboxFileSystem.js.map +1 -0
  113. package/lib/fs/createWebDavFileSystem.js +137 -0
  114. package/lib/fs/createWebDavFileSystem.js.map +1 -0
  115. package/lib/fs/findMimeType.js +17 -0
  116. package/lib/fs/findMimeType.js.map +1 -0
  117. package/lib/fs/index.js +8 -0
  118. package/lib/fs/index.js.map +1 -0
  119. package/lib/fs/orpc/FileSystemContract.js +93 -0
  120. package/lib/fs/orpc/FileSystemContract.js.map +1 -0
  121. package/lib/fs/orpc/createContractClientFileSystem.js +93 -0
  122. package/lib/fs/orpc/createContractClientFileSystem.js.map +1 -0
  123. package/lib/fs/orpc/index.js +3 -0
  124. package/lib/fs/orpc/index.js.map +1 -0
  125. package/lib/fs/orpc/server/createFileSystemContractImpl.js +63 -0
  126. package/lib/fs/orpc/server/createFileSystemContractImpl.js.map +1 -0
  127. package/lib/fs/orpc/server/index.js +2 -0
  128. package/lib/fs/orpc/server/index.js.map +1 -0
  129. package/lib/fs/s3/createS3MiniFileSystem.js +705 -0
  130. package/lib/fs/s3/createS3MiniFileSystem.js.map +1 -0
  131. package/lib/fs/s3/index.js +2 -0
  132. package/lib/fs/s3/index.js.map +1 -0
  133. package/lib/fs/s3/s3mini.test.js +584 -0
  134. package/lib/fs/scandir.js +59 -0
  135. package/lib/fs/scandir.js.map +1 -0
  136. package/lib/fs/server/createDatabaseFileSystem.js +750 -0
  137. package/lib/fs/server/createDatabaseFileSystem.js.map +1 -0
  138. package/lib/fs/server/createNodeFileSystem.js +401 -0
  139. package/lib/fs/server/createNodeFileSystem.js.map +1 -0
  140. package/lib/fs/server/dbfs.test.js +221 -0
  141. package/lib/fs/server/index.js +2 -0
  142. package/lib/fs/server/index.js.map +1 -0
  143. package/lib/fs/server/loadTestDatabase.js +127 -0
  144. package/lib/fs/server/loadTestDatabase.js.map +1 -0
  145. package/lib/fs/tests/runFileSystemTest.js +318 -0
  146. package/lib/fs/tests/runFileSystemTest.js.map +1 -0
  147. package/lib/fs/types.js +27 -0
  148. package/lib/fs/types.js.map +1 -0
  149. package/lib/fs/utils/getFileUrl.js +35 -0
  150. package/lib/fs/utils/getFileUrl.js.map +1 -0
  151. package/lib/fs/utils.js +22 -0
  152. package/lib/fs/utils.js.map +1 -0
  153. package/lib/index.js +1 -0
  154. package/lib/index.js.map +1 -0
  155. package/lib/jsonschema/JsonSchema.js +146 -172
  156. package/lib/jsonschema/JsonSchema.js.map +1 -0
  157. package/lib/jsonschema/forEachJsonSchema.js +44 -0
  158. package/lib/jsonschema/forEachJsonSchema.js.map +1 -0
  159. package/lib/jsonschema/index.js +2 -0
  160. package/lib/jsonschema/index.js.map +1 -0
  161. package/lib/jsonschema/types.d.js +2 -0
  162. package/lib/jsonschema/types.d.js.map +1 -0
  163. package/lib/meta/defineFileType.js +20 -103
  164. package/lib/meta/defineFileType.js.map +1 -0
  165. package/lib/meta/defineInit.js +31 -250
  166. package/lib/meta/defineInit.js.map +1 -0
  167. package/lib/meta/defineMetadata.js +24 -140
  168. package/lib/meta/defineMetadata.js.map +1 -0
  169. package/lib/meta/index.js +1 -0
  170. package/lib/meta/index.js.map +1 -0
  171. package/lib/orpc/createOpenApiContractClient.js +27 -0
  172. package/lib/orpc/createOpenApiContractClient.js.map +1 -0
  173. package/lib/orpc/createRpcContractClient.js +34 -0
  174. package/lib/orpc/createRpcContractClient.js.map +1 -0
  175. package/lib/orpc/index.js +3 -0
  176. package/lib/orpc/index.js.map +1 -0
  177. package/lib/orpc/resolveLinkPlugins.js +28 -0
  178. package/lib/orpc/resolveLinkPlugins.js.map +1 -0
  179. package/lib/password/PHC.js +63 -87
  180. package/lib/password/PHC.js.map +1 -0
  181. package/lib/password/PHC.test.js +11 -3
  182. package/lib/password/Password.js +30 -292
  183. package/lib/password/Password.js.map +1 -0
  184. package/lib/password/Password.test.js +35 -22
  185. package/lib/password/createArgon2PasswordAlgorithm.js +35 -191
  186. package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -0
  187. package/lib/password/createBase64PasswordAlgorithm.js +8 -141
  188. package/lib/password/createBase64PasswordAlgorithm.js.map +1 -0
  189. package/lib/password/createBcryptPasswordAlgorithm.js +13 -168
  190. package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -0
  191. package/lib/password/createPBKDF2PasswordAlgorithm.js +46 -228
  192. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -0
  193. package/lib/password/createScryptPasswordAlgorithm.js +55 -211
  194. package/lib/password/createScryptPasswordAlgorithm.js.map +1 -0
  195. package/lib/password/index.js +1 -0
  196. package/lib/password/index.js.map +1 -0
  197. package/lib/password/server/index.js +1 -0
  198. package/lib/password/server/index.js.map +1 -0
  199. package/lib/resource/Identifiable.js +2 -0
  200. package/lib/resource/Identifiable.js.map +1 -0
  201. package/lib/resource/ListQuery.js +47 -0
  202. package/lib/resource/ListQuery.js.map +1 -0
  203. package/lib/resource/getTitleOfResource.js +3 -5
  204. package/lib/resource/getTitleOfResource.js.map +1 -0
  205. package/lib/resource/index.js +2 -0
  206. package/lib/resource/index.js.map +1 -0
  207. package/lib/resource/schema/AnyResourceSchema.js +3 -2
  208. package/lib/resource/schema/AnyResourceSchema.js.map +1 -0
  209. package/lib/resource/schema/BaseResourceSchema.js +2 -1
  210. package/lib/resource/schema/BaseResourceSchema.js.map +1 -0
  211. package/lib/resource/schema/ResourceActionType.js +6 -4
  212. package/lib/resource/schema/ResourceActionType.js.map +1 -0
  213. package/lib/resource/schema/ResourceStatus.js +5 -3
  214. package/lib/resource/schema/ResourceStatus.js.map +1 -0
  215. package/lib/resource/schema/ResourceType.js +5 -3
  216. package/lib/resource/schema/ResourceType.js.map +1 -0
  217. package/lib/resource/schema/index.js +6 -0
  218. package/lib/resource/schema/index.js.map +1 -0
  219. package/lib/resource/schema/types.js +16 -20
  220. package/lib/resource/schema/types.js.map +1 -0
  221. package/lib/s3/formatS3Url.js +65 -0
  222. package/lib/s3/formatS3Url.js.map +1 -0
  223. package/lib/s3/formatS3Url.test.js +262 -0
  224. package/lib/s3/index.js +3 -0
  225. package/lib/s3/index.js.map +1 -0
  226. package/lib/s3/parseS3Url.js +65 -0
  227. package/lib/s3/parseS3Url.js.map +1 -0
  228. package/lib/s3/parseS3Url.test.js +270 -0
  229. package/lib/schema/SchemaRegistry.js +45 -0
  230. package/lib/schema/SchemaRegistry.js.map +1 -0
  231. package/lib/schema/SchemaRegistry.mod.js +2 -0
  232. package/lib/schema/TypeSchema.d.js +2 -0
  233. package/lib/schema/TypeSchema.d.js.map +1 -0
  234. package/lib/schema/createSchemaData.js +26 -125
  235. package/lib/schema/createSchemaData.js.map +1 -0
  236. package/lib/schema/findJsonSchemaByPath.js +13 -36
  237. package/lib/schema/findJsonSchemaByPath.js.map +1 -0
  238. package/lib/schema/formatZodError.js +140 -0
  239. package/lib/schema/formatZodError.js.map +1 -0
  240. package/lib/schema/formatZodError.test.js +196 -0
  241. package/lib/schema/getSchemaCache.js +5 -5
  242. package/lib/schema/getSchemaCache.js.map +1 -0
  243. package/lib/schema/getSchemaOptions.js +8 -11
  244. package/lib/schema/getSchemaOptions.js.map +1 -0
  245. package/lib/schema/index.js +2 -0
  246. package/lib/schema/index.js.map +1 -0
  247. package/lib/schema/toJsonSchema.js +47 -290
  248. package/lib/schema/toJsonSchema.js.map +1 -0
  249. package/lib/schema/validate.js +33 -45
  250. package/lib/schema/validate.js.map +1 -0
  251. package/lib/tools/generateSchema.js +39 -197
  252. package/lib/tools/generateSchema.js.map +1 -0
  253. package/lib/tools/renderJsonSchemaToMarkdownDoc.js +55 -143
  254. package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -0
  255. package/lib/utils/buildBaseUrl.js +13 -0
  256. package/lib/utils/buildBaseUrl.js.map +1 -0
  257. package/lib/utils/buildRedactorFormSchema.js +59 -0
  258. package/lib/utils/buildRedactorFormSchema.js.map +1 -0
  259. package/lib/utils/getEstimateProcessTime.js +21 -0
  260. package/lib/utils/getEstimateProcessTime.js.map +1 -0
  261. package/lib/utils/index.js +4 -0
  262. package/lib/utils/index.js.map +1 -0
  263. package/lib/utils/resolveFeatureOptions.js +12 -0
  264. package/lib/utils/resolveFeatureOptions.js.map +1 -0
  265. package/package.json +77 -20
  266. package/src/ai/qwen3vl/index.ts +1 -0
  267. package/src/ai/qwen3vl/utils.ts +36 -0
  268. package/src/ai/vision/DocLayoutElementTypeSchema.ts +30 -0
  269. package/src/ai/vision/ImageAnnotationSchema.ts +60 -0
  270. package/src/ai/vision/index.ts +2 -0
  271. package/src/ai/vision/resolveImageAnnotation.ts +135 -0
  272. package/src/cn/ChineseResidentIdNo.test.ts +18 -0
  273. package/src/cn/ChineseResidentIdNo.ts +74 -0
  274. package/src/cn/DivisionCode.test.ts +3 -13
  275. package/src/cn/DivisionCode.ts +138 -193
  276. package/src/cn/{Mod11Checksum.ts → Mod11.ts} +3 -1
  277. package/src/cn/{Mod31Checksum.ts → Mod31.ts} +2 -0
  278. package/src/cn/UnifiedSocialCreditCode.test.ts +2 -2
  279. package/src/cn/UnifiedSocialCreditCode.ts +119 -124
  280. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +14 -0
  281. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +41 -12
  282. package/src/cn/formatChineseAmount.ts +61 -0
  283. package/src/cn/index.ts +6 -2
  284. package/src/cn/parseChineseNumber.test.ts +159 -0
  285. package/src/cn/parseChineseNumber.ts +97 -0
  286. package/src/cn/pinyin/cartesianProduct.test.ts +64 -0
  287. package/src/cn/pinyin/cartesianProduct.ts +24 -0
  288. package/src/cn/pinyin/data.json +23573 -0
  289. package/src/cn/pinyin/loader.ts +12 -0
  290. package/src/cn/pinyin/preload.ts +3 -0
  291. package/src/cn/pinyin/toPinyin.test.ts +12 -0
  292. package/src/cn/pinyin/toPinyinPure.ts +43 -0
  293. package/src/cn/pinyin/transform.ts +12 -0
  294. package/src/consola/formatLogObject.test.ts +27 -0
  295. package/src/consola/formatLogObject.ts +46 -10
  296. package/src/dayjs/dayjs.ts +40 -0
  297. package/src/dayjs/formatDuration.test.ts +14 -0
  298. package/src/dayjs/formatDuration.ts +86 -0
  299. package/src/dayjs/index.ts +5 -0
  300. package/src/dayjs/parseDuration.ts +40 -0
  301. package/src/dayjs/parseRelativeTime.test.ts +185 -0
  302. package/src/dayjs/parseRelativeTime.ts +115 -0
  303. package/src/dayjs/resolveRelativeTime.test.ts +357 -0
  304. package/src/dayjs/resolveRelativeTime.ts +167 -0
  305. package/src/decimal/index.ts +1 -0
  306. package/src/decimal/parseDecimal.ts +16 -0
  307. package/src/emittery/emitter.ts +9 -0
  308. package/src/emittery/index.ts +1 -0
  309. package/src/foundation/schema/SexType.ts +21 -0
  310. package/src/foundation/schema/index.ts +1 -0
  311. package/src/foundation/schema/parseSexType.ts +19 -0
  312. package/src/foundation/schema/types.ts +8 -0
  313. package/src/fs/FileSystemError.ts +26 -0
  314. package/src/fs/IFileSystem.d.ts +102 -0
  315. package/src/fs/MemoryFileSystem.test.ts +37 -0
  316. package/src/fs/createBrowserFileSystem.ts +291 -0
  317. package/src/fs/createMemoryFileSystem.ts +604 -0
  318. package/src/fs/createSandboxFileSystem.ts +136 -0
  319. package/src/fs/createWebDavFileSystem.ts +172 -0
  320. package/src/fs/findMimeType.ts +23 -0
  321. package/src/fs/index.ts +8 -0
  322. package/src/fs/orpc/FileSystemContract.ts +92 -0
  323. package/src/fs/orpc/createContractClientFileSystem.ts +115 -0
  324. package/src/fs/orpc/index.ts +2 -0
  325. package/src/fs/orpc/server/createFileSystemContractImpl.ts +64 -0
  326. package/src/fs/orpc/server/index.ts +1 -0
  327. package/src/fs/s3/createS3MiniFileSystem.ts +830 -0
  328. package/src/fs/s3/index.ts +1 -0
  329. package/src/fs/s3/s3mini.test.ts +264 -0
  330. package/src/fs/scandir.ts +75 -0
  331. package/src/fs/server/createDatabaseFileSystem.ts +668 -0
  332. package/src/fs/server/createNodeFileSystem.ts +499 -0
  333. package/src/fs/server/dbfs.test.ts +47 -0
  334. package/src/fs/server/index.ts +1 -0
  335. package/src/fs/server/loadTestDatabase.ts +131 -0
  336. package/src/fs/tests/runFileSystemTest.ts +288 -0
  337. package/src/fs/types.ts +29 -0
  338. package/src/fs/utils/getFileUrl.ts +44 -0
  339. package/src/fs/utils.ts +23 -0
  340. package/src/jsonschema/JsonSchema.ts +118 -110
  341. package/src/jsonschema/forEachJsonSchema.ts +50 -0
  342. package/src/jsonschema/index.ts +1 -0
  343. package/src/orpc/createOpenApiContractClient.ts +52 -0
  344. package/src/orpc/createRpcContractClient.ts +50 -0
  345. package/src/orpc/index.ts +2 -0
  346. package/src/orpc/resolveLinkPlugins.ts +29 -0
  347. package/src/password/PHC.ts +3 -3
  348. package/src/password/Password.test.ts +1 -1
  349. package/src/password/Password.ts +2 -2
  350. package/src/password/createPBKDF2PasswordAlgorithm.ts +2 -2
  351. package/src/resource/ListQuery.ts +53 -0
  352. package/src/resource/index.ts +1 -0
  353. package/src/resource/schema/AnyResourceSchema.ts +17 -3
  354. package/src/resource/schema/index.ts +5 -0
  355. package/src/s3/formatS3Url.test.ts +254 -0
  356. package/src/s3/formatS3Url.ts +84 -0
  357. package/src/s3/index.ts +2 -0
  358. package/src/s3/parseS3Url.test.ts +258 -0
  359. package/src/s3/parseS3Url.ts +88 -0
  360. package/src/schema/SchemaRegistry.ts +48 -0
  361. package/src/schema/createSchemaData.ts +1 -1
  362. package/src/schema/formatZodError.test.ts +196 -0
  363. package/src/schema/formatZodError.ts +151 -0
  364. package/src/schema/getSchemaOptions.ts +3 -3
  365. package/src/schema/index.ts +1 -0
  366. package/src/utils/buildBaseUrl.ts +12 -0
  367. package/src/utils/buildRedactorFormSchema.ts +85 -0
  368. package/src/utils/getEstimateProcessTime.ts +36 -0
  369. package/src/utils/index.ts +5 -0
  370. package/src/utils/resolveFeatureOptions.ts +14 -0
  371. package/lib/cn/Mod11Checksum.js +0 -85
  372. package/lib/cn/Mod31Checksum.js +0 -97
  373. package/lib/cn/ResidentIdentityCardNumber.js +0 -50
  374. package/lib/cn/formatDate.js +0 -13
  375. package/lib/cn/parseSex.js +0 -20
  376. package/lib/resource/schema/SchemaRegistry.js +0 -38
  377. package/lib/resource/schema/SexType.js +0 -10
  378. package/lib/search/AdvanceSearch.js +0 -9
  379. package/lib/search/AdvanceSearch.test.js +0 -435
  380. package/lib/search/formatAdvanceSearch.js +0 -78
  381. package/lib/search/index.js +0 -1
  382. package/lib/search/optimizeAdvanceSearch.js +0 -143
  383. package/lib/search/parseAdvanceSearch.js +0 -20
  384. package/lib/search/parser.d.js +0 -1
  385. package/lib/search/parser.js +0 -3088
  386. package/lib/search/types.d.js +0 -1
  387. package/src/cn/ResidentIdentityCardNumber.test.ts +0 -17
  388. package/src/cn/ResidentIdentityCardNumber.ts +0 -96
  389. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +0 -15
  390. package/src/cn/formatDate.ts +0 -12
  391. package/src/cn/parseSex.ts +0 -13
  392. package/src/resource/schema/SchemaRegistry.ts +0 -42
  393. package/src/resource/schema/SexType.ts +0 -13
  394. package/src/search/AdvanceSearch.test.ts +0 -149
  395. package/src/search/AdvanceSearch.ts +0 -14
  396. package/src/search/Makefile +0 -2
  397. package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +0 -675
  398. package/src/search/formatAdvanceSearch.ts +0 -52
  399. package/src/search/index.ts +0 -1
  400. package/src/search/optimizeAdvanceSearch.ts +0 -77
  401. package/src/search/parseAdvanceSearch.ts +0 -23
  402. package/src/search/parser.d.ts +0 -8
  403. package/src/search/parser.js +0 -2794
  404. package/src/search/parser.peggy +0 -237
  405. package/src/search/types.d.ts +0 -45
@@ -0,0 +1,499 @@
1
+ import {
2
+ createReadStream as nodeCreateReadStream,
3
+ createWriteStream as nodeCreateWriteStream,
4
+ type Stats,
5
+ } from 'node:fs';
6
+ import fsp from 'node:fs/promises';
7
+ import path from 'node:path';
8
+ import { Readable, type Writable } from 'node:stream';
9
+ import { pathToFileURL } from 'node:url';
10
+ import type {
11
+ CopyOptions,
12
+ CreateReadStreamOptions,
13
+ CreateWriteStreamOptions,
14
+ IFileStat,
15
+ IFileSystem,
16
+ MkdirOptions,
17
+ ReaddirOptions,
18
+ ReadFileOptions,
19
+ RenameOptions,
20
+ RmOptions,
21
+ StatOptions,
22
+ WriteFileOptions,
23
+ } from '../IFileSystem';
24
+
25
+ export type INodeFileSystem = IFileSystem & {
26
+ readonly root: string;
27
+ resolvePath(filePath: string): string;
28
+ };
29
+
30
+ /**
31
+ * Creates a Node.js filesystem adapter that implements the IFileSystem interface
32
+ * @param options Configuration options for the filesystem
33
+ * @param options.root Optional root directory to restrict all operations within
34
+ */
35
+ export function createNodeFileSystem(options: { root?: string } = {}): INodeFileSystem {
36
+ return new NodeFs(options);
37
+ }
38
+
39
+ type IFS = typeof import('fs/promises');
40
+
41
+ class NodeFs implements IFileSystem, INodeFileSystem {
42
+ readonly root: string;
43
+ private readonly fs: IFS;
44
+
45
+ constructor({
46
+ root,
47
+ fs = fsp,
48
+ }: {
49
+ root?: string;
50
+ fs?: IFS;
51
+ } = {}) {
52
+ // Normalize the root path if provided
53
+ if (root) {
54
+ this.root = path.resolve(root);
55
+ } else {
56
+ this.root = '';
57
+ }
58
+ this.fs = fs;
59
+ }
60
+
61
+ // Helper method to handle aborted signals consistently
62
+ private checkAborted(signal?: AbortSignal): void {
63
+ if (signal?.aborted) {
64
+ throw new Error('The operation was aborted');
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Resolves and secures a path by:
70
+ * 1. Normalizing the path
71
+ * 2. Prepending the root directory if one is set
72
+ * 3. Verifying the resulting path is within the root directory
73
+ *
74
+ * This prevents path traversal attacks.
75
+ */
76
+ resolvePath(filePath: string): string {
77
+ // Handle empty paths
78
+ if (!filePath) {
79
+ return this.root || '';
80
+ }
81
+
82
+ // Normalize to remove any '..' segments and handle slashes
83
+ const normalizedPath = path.normalize(filePath);
84
+
85
+ // If no root is set, just return the normalized path
86
+ if (!this.root) {
87
+ return normalizedPath;
88
+ }
89
+
90
+ // Join with root and resolve to absolute path
91
+ const resolvedPath = path.resolve(path.join(this.root, normalizedPath));
92
+
93
+ // Security check: ensure the path is within the root directory
94
+ if (!resolvedPath.startsWith(this.root)) {
95
+ throw new Error(`Security violation: Path ${filePath} attempts to access outside of the root directory`);
96
+ }
97
+
98
+ return resolvedPath;
99
+ }
100
+
101
+ /**
102
+ * Removes the root prefix from a path for external representation
103
+ */
104
+ private stripRoot(fullPath: string): string {
105
+ if (!this.root || !fullPath.startsWith(this.root)) {
106
+ return fullPath;
107
+ }
108
+
109
+ // Remove the root prefix and ensure there's a leading slash
110
+ let relativePath = fullPath.substring(this.root.length);
111
+ if (!relativePath) {
112
+ return '/';
113
+ }
114
+
115
+ if (!relativePath.startsWith('/') && !relativePath.startsWith('\\')) {
116
+ relativePath = '/' + relativePath;
117
+ }
118
+
119
+ // Normalize to ensure consistent path separators
120
+ return path.normalize(relativePath).replace(/\\/g, '/');
121
+ }
122
+
123
+ /**
124
+ * Converts a system file stat to our IFileStat interface,
125
+ * stripping the root prefix from paths
126
+ */
127
+ private toFileStat(fullPath: string, fsStats: Stats): IFileStat {
128
+ const normalizedPath = this.stripRoot(fullPath);
129
+ const directoryPath = path.dirname(normalizedPath);
130
+ const directory = directoryPath === '.' ? '/' : directoryPath.replace(/\\/g, '/');
131
+
132
+ return {
133
+ directory,
134
+ path: normalizedPath,
135
+ name: path.basename(fullPath),
136
+ kind: fsStats.isDirectory() ? 'directory' : 'file',
137
+ mtime: fsStats.mtimeMs,
138
+ size: fsStats.size,
139
+ meta: {},
140
+ };
141
+ }
142
+
143
+ async readdir(dir: string, options: ReaddirOptions = {}): Promise<IFileStat[]> {
144
+ const { fs } = this;
145
+ const { glob, recursive, depth = 1, kind, hidden = true, signal } = options;
146
+ this.checkAborted(signal);
147
+
148
+ // Resolve the directory path with security checks
149
+ const resolvedDir = this.resolvePath(dir);
150
+
151
+ // Basic file listing
152
+ const entries = await fs.readdir(resolvedDir, { withFileTypes: true });
153
+ let results = await Promise.all(
154
+ entries
155
+ .filter((entry) => hidden || !entry.name.startsWith('.'))
156
+ .filter((entry) => !kind || (kind === 'directory' ? entry.isDirectory() : entry.isFile()))
157
+ .map(async (entry) => {
158
+ this.checkAborted(signal);
159
+
160
+ const entryFullPath = path.join(resolvedDir, entry.name);
161
+ const stat = await fs.stat(entryFullPath);
162
+
163
+ // Convert to external representation
164
+ return {
165
+ directory: this.stripRoot(resolvedDir),
166
+ path: this.stripRoot(entryFullPath),
167
+ name: entry.name,
168
+ kind: entry.isDirectory() ? 'directory' : 'file',
169
+ mtime: stat.mtimeMs,
170
+ size: stat.size,
171
+ meta: {},
172
+ } as IFileStat;
173
+ }),
174
+ );
175
+
176
+ // Handle recursive option
177
+ if (recursive || depth > 1) {
178
+ const subdirs = results.filter((entry) => entry.kind === 'directory');
179
+
180
+ for (const subdir of subdirs) {
181
+ this.checkAborted(signal);
182
+
183
+ const maxDepth = recursive ? Infinity : depth - 1;
184
+ if (maxDepth > 0) {
185
+ // Need to convert the path back to a full path for the recursive call
186
+ const subdirFullPath = this.resolvePath(subdir.path);
187
+
188
+ const subEntries = await this.readdir(subdir.path, {
189
+ ...options,
190
+ depth: maxDepth,
191
+ });
192
+ results = [...results, ...subEntries];
193
+ }
194
+ }
195
+ }
196
+
197
+ // Handle glob filtering
198
+ if (glob) {
199
+ const { matcher } = await import('micromatch');
200
+ const match = matcher(glob);
201
+ results = results.filter((entry) => match(entry.path));
202
+ }
203
+
204
+ return results;
205
+ }
206
+
207
+ async stat(filePath: string, options: StatOptions = {}): Promise<IFileStat> {
208
+ const { fs } = this;
209
+
210
+ const { signal } = options;
211
+ this.checkAborted(signal);
212
+
213
+ const resolvedPath = this.resolvePath(filePath);
214
+
215
+ try {
216
+ const stat = await fs.stat(resolvedPath);
217
+ return this.toFileStat(resolvedPath, stat);
218
+ } catch (err: any) {
219
+ if (err.code === 'ENOENT') {
220
+ throw new Error(`File not found: ${filePath}`);
221
+ }
222
+ throw err;
223
+ }
224
+ }
225
+
226
+ async mkdir(dirPath: string, options: MkdirOptions = {}): Promise<void> {
227
+ const { fs } = this;
228
+
229
+ const { recursive = false, signal } = options;
230
+ this.checkAborted(signal);
231
+
232
+ const resolvedPath = this.resolvePath(dirPath);
233
+
234
+ try {
235
+ await fs.mkdir(resolvedPath, { recursive });
236
+ } catch (err: any) {
237
+ if (err.code === 'EEXIST' && recursive) {
238
+ // Ignore if directory exists and recursive is true
239
+ return;
240
+ }
241
+ throw err;
242
+ }
243
+ }
244
+
245
+ async readFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;
246
+ async readFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;
247
+ async readFile(path: string, options: ReadFileOptions = {}): Promise<string | Uint8Array> {
248
+ const { fs } = this;
249
+
250
+ const { encoding = 'binary', signal, onDownloadProgress } = options;
251
+ this.checkAborted(signal);
252
+
253
+ const resolvedPath = this.resolvePath(path);
254
+
255
+ try {
256
+ // Handle progress reporting if needed
257
+ if (onDownloadProgress) {
258
+ const stat = await fs.stat(resolvedPath);
259
+ const stream = this.createReadStream(path, { signal });
260
+
261
+ return new Promise((resolve, reject) => {
262
+ const chunks: Buffer[] = [];
263
+ let loaded = 0;
264
+
265
+ stream.on('data', (chunk) => {
266
+ chunks.push(Buffer.from(chunk));
267
+ loaded += chunk.length;
268
+ onDownloadProgress({ loaded, total: stat.size });
269
+ });
270
+
271
+ stream.on('end', () => {
272
+ const buffer = Buffer.concat(chunks);
273
+ if (encoding === 'text') {
274
+ resolve(buffer.toString('utf-8'));
275
+ } else {
276
+ resolve(buffer);
277
+ }
278
+ });
279
+
280
+ stream.on('error', reject);
281
+ });
282
+ }
283
+
284
+ // Standard file reading
285
+ if (encoding === 'text') {
286
+ return await fs.readFile(resolvedPath, { encoding: 'utf-8' });
287
+ } else {
288
+ return await fs.readFile(resolvedPath);
289
+ }
290
+ } catch (err: any) {
291
+ if (err.code === 'ENOENT') {
292
+ throw new Error(`File not found: ${path}`);
293
+ }
294
+ throw err;
295
+ }
296
+ }
297
+
298
+ async writeFile(
299
+ path: string,
300
+ data: string | Buffer | ArrayBuffer | Readable,
301
+ options: WriteFileOptions = {},
302
+ ): Promise<void> {
303
+ const { fs } = this;
304
+
305
+ const { signal, overwrite = true, onUploadProgress } = options;
306
+ this.checkAborted(signal);
307
+
308
+ const resolvedPath = this.resolvePath(path);
309
+
310
+ // Check if file exists and overwrite is false
311
+ if (!overwrite) {
312
+ const exists = await this.exists(path);
313
+ if (exists) {
314
+ throw new Error(`File already exists: ${path}`);
315
+ }
316
+ }
317
+
318
+ // Create parent directories if they don't exist
319
+ const directory = this.getDirectoryName(resolvedPath);
320
+ if (directory !== resolvedPath) {
321
+ try {
322
+ await this.mkdir(this.stripRoot(directory), { recursive: true });
323
+ } catch (err: any) {
324
+ // Ignore directory exists error
325
+ if (err?.code !== 'EEXIST') {
326
+ throw err;
327
+ }
328
+ }
329
+ }
330
+
331
+ if (data instanceof Readable) {
332
+ let _data = data;
333
+ return new Promise((resolve, reject) => {
334
+ const writeStream = this.createWriteStream(path, options);
335
+ let totalBytes = 0;
336
+
337
+ if (onUploadProgress) {
338
+ _data.on('data', (chunk) => {
339
+ totalBytes += chunk.length;
340
+ onUploadProgress({ loaded: totalBytes, total: -1 });
341
+ });
342
+ }
343
+
344
+ _data.pipe(writeStream);
345
+
346
+ writeStream.on('finish', () => resolve());
347
+ writeStream.on('error', reject);
348
+
349
+ if (signal) {
350
+ signal.addEventListener('abort', () => {
351
+ _data.destroy();
352
+ writeStream.destroy();
353
+ reject(new Error('The operation was aborted'));
354
+ });
355
+ }
356
+ });
357
+ } else {
358
+ // Convert ArrayBuffer to Buffer if necessary
359
+ if (data instanceof ArrayBuffer) {
360
+ data = Buffer.from(data);
361
+ }
362
+ await fs.writeFile(resolvedPath, data);
363
+ }
364
+ }
365
+
366
+ async rm(path: string, options: RmOptions = {}): Promise<void> {
367
+ const { fs } = this;
368
+
369
+ const { recursive = false, force = false, signal } = options;
370
+ this.checkAborted(signal);
371
+
372
+ const resolvedPath = this.resolvePath(path);
373
+
374
+ try {
375
+ await fs.rm(resolvedPath, { recursive, force });
376
+ } catch (err: any) {
377
+ if (force && err.code === 'ENOENT') {
378
+ return;
379
+ }
380
+ throw err;
381
+ }
382
+ }
383
+
384
+ async rename(oldPath: string, newPath: string, options: RenameOptions = {}): Promise<void> {
385
+ const { fs } = this;
386
+
387
+ const { signal, overwrite = false } = options;
388
+ this.checkAborted(signal);
389
+
390
+ const resolvedOldPath = this.resolvePath(oldPath);
391
+ const resolvedNewPath = this.resolvePath(newPath);
392
+
393
+ // Check if target exists and overwrite is false
394
+ if (!overwrite) {
395
+ const exists = await this.exists(newPath);
396
+ if (exists) {
397
+ throw new Error(`Destination already exists: ${newPath}`);
398
+ }
399
+ }
400
+
401
+ try {
402
+ await fs.rename(resolvedOldPath, resolvedNewPath);
403
+ } catch (err: any) {
404
+ if (err.code === 'ENOENT') {
405
+ throw new Error(`Source file not found: ${oldPath}`);
406
+ }
407
+ throw err;
408
+ }
409
+ }
410
+
411
+ async exists(path: string): Promise<boolean> {
412
+ const { fs } = this;
413
+
414
+ try {
415
+ await fs.access(this.resolvePath(path));
416
+ return true;
417
+ } catch {
418
+ return false;
419
+ }
420
+ }
421
+
422
+ async copy(src: string, dest: string, options: CopyOptions = {}): Promise<void> {
423
+ const { fs } = this;
424
+
425
+ const { signal, overwrite = true, shallow = false } = options;
426
+ this.checkAborted(signal);
427
+
428
+ const resolvedSrc = this.resolvePath(src);
429
+ const resolvedDest = this.resolvePath(dest);
430
+
431
+ // Check if source exists
432
+ try {
433
+ const stat = await fs.stat(resolvedSrc);
434
+
435
+ // Check if destination exists and overwrite is false
436
+ if (!overwrite) {
437
+ const exists = await this.exists(dest);
438
+ if (exists) {
439
+ throw new Error(`Destination already exists: ${dest}`);
440
+ }
441
+ }
442
+
443
+ // Create parent directory if it doesn't exist
444
+ const parentDir = this.getDirectoryName(resolvedDest);
445
+ await this.mkdir(this.stripRoot(parentDir), { recursive: true });
446
+
447
+ // Copy recursively or not based on shallow and if it's a directory
448
+ await fs.cp(resolvedSrc, resolvedDest, {
449
+ recursive: !shallow && stat.isDirectory(),
450
+ force: overwrite,
451
+ });
452
+ } catch (err: any) {
453
+ if (err.code === 'ENOENT') {
454
+ throw new Error(`Source file not found: ${src}`);
455
+ }
456
+ throw err;
457
+ }
458
+ }
459
+
460
+ createReadStream(filePath: string, options: CreateReadStreamOptions = {}): Readable {
461
+ const resolvedPath = this.resolvePath(filePath);
462
+ const { signal, range } = options;
463
+ const stream = nodeCreateReadStream(resolvedPath, {
464
+ start: range?.start,
465
+ end: range?.end,
466
+ });
467
+
468
+ signal?.addEventListener('abort', () => stream.destroy(new Error('The operation was aborted')));
469
+
470
+ return stream;
471
+ }
472
+
473
+ createWriteStream(filePath: string, options: CreateWriteStreamOptions = {}): Writable {
474
+ const resolvedPath = this.resolvePath(filePath);
475
+ const { signal } = options;
476
+ const stream = nodeCreateWriteStream(resolvedPath, { flags: options.overwrite === false ? 'wx' : 'w' });
477
+
478
+ signal?.addEventListener('abort', () => stream.destroy(new Error('The operation was aborted')));
479
+
480
+ return stream;
481
+ }
482
+
483
+ // Helper to extract directory name correctly
484
+ private getDirectoryName(filePath: string): string {
485
+ return path.dirname(filePath);
486
+ }
487
+
488
+ getUrl(needle: IFileStat | string) {
489
+ if (typeof needle === 'object' && needle?.kind !== 'file') {
490
+ return;
491
+ }
492
+ let path = typeof needle === 'string' ? needle : needle.path;
493
+ if (!path) {
494
+ return;
495
+ }
496
+ // file://
497
+ return pathToFileURL(this.resolvePath(path)).toString();
498
+ }
499
+ }
@@ -0,0 +1,47 @@
1
+ import type { EntityManager } from '@mikro-orm/knex';
2
+ import { beforeEach, describe, test } from 'vitest';
3
+ import { runFileSystemTest } from '../tests/runFileSystemTest';
4
+ import { createDatabaseFileSystem, FileNodeMetaEntity } from './createDatabaseFileSystem';
5
+ import { loadTestDatabase } from './loadTestDatabase';
6
+
7
+ describe('DatabaseFileSystem', () => {
8
+ let fs: ReturnType<typeof createDatabaseFileSystem>;
9
+ let em: EntityManager;
10
+
11
+ beforeEach(async () => {
12
+ const { em: entityManager } = await loadTestDatabase();
13
+ em = entityManager as any; // Type cast to match expected EntityManager type
14
+
15
+ fs = createDatabaseFileSystem({
16
+ getEntityManager: () => em as any,
17
+ });
18
+
19
+ // Setup initial state: ensure root directory exists and create /README.txt
20
+ const rootNode = await fs.ensureRootNode();
21
+
22
+ // Create /README.txt file using EntityManager
23
+ const content = Buffer.from('Hello');
24
+ const readmeFile = em.create(FileNodeMetaEntity, {
25
+ filename: 'README.txt',
26
+ parent: rootNode,
27
+ kind: 'file',
28
+ size: content.length,
29
+ content: content,
30
+ atime: new Date(),
31
+ btime: new Date(),
32
+ ctime: new Date(),
33
+ mtime: new Date(),
34
+ });
35
+ await em.persistAndFlush(readmeFile);
36
+ }, 30000); // Increase timeout to 30 seconds
37
+
38
+ test('common tests', async () => {
39
+ await runFileSystemTest(fs, {
40
+ writableStream: false,
41
+ readableStream: false,
42
+ readStream: false,
43
+ writeStream: false,
44
+ abort: false,
45
+ });
46
+ }, 60000); // Increase timeout to 60 seconds
47
+ });
@@ -0,0 +1 @@
1
+ export { createNodeFileSystem } from './createNodeFileSystem';
@@ -0,0 +1,131 @@
1
+ import { inspect } from 'node:util';
2
+ import type { Options as BetterSqliteOptions } from '@mikro-orm/better-sqlite';
3
+ import { Errors, ulid } from '@wener/utils';
4
+ import type { Database } from 'better-sqlite3';
5
+ import { FileNodeContentEntity, FileNodeMetaEntity } from './createDatabaseFileSystem';
6
+
7
+ export async function loadTestDatabase({ options }: { options?: BetterSqliteOptions } = {}) {
8
+ const { MikroORM: SqliteMikroORM } = await import('@mikro-orm/better-sqlite');
9
+
10
+ const orm = await SqliteMikroORM.init({
11
+ dbName: ':memory:',
12
+ entities: [FileNodeContentEntity, FileNodeMetaEntity],
13
+ discovery: {
14
+ disableDynamicFileAccess: true,
15
+ requireEntitiesArray: true,
16
+ },
17
+ serialization: {
18
+ includePrimaryKeys: true,
19
+ forceObject: true,
20
+ },
21
+ findOneOrFailHandler(entityName, where) {
22
+ throw Errors.NotFound.asError(`未找到数据: ${entityName} ${inspect(where)}`);
23
+ },
24
+ findExactlyOneOrFailHandler(entityName, where) {
25
+ throw Errors.BadRequest.asError(`错误的数据数量: ${entityName} ${inspect(where)}`);
26
+ },
27
+ ...options,
28
+ });
29
+
30
+ const knex = orm.em.getKnex();
31
+ {
32
+ const db: Database = await knex.client.acquireConnection();
33
+ db.function('ulid', () => ulid());
34
+ await knex.client.releaseConnection(db);
35
+ }
36
+
37
+ // Execute schema creation
38
+ for (const stmt of FileSystemSchema.split(';')) {
39
+ const sql = stmt.trim();
40
+ if (sql) {
41
+ await knex.raw(sql);
42
+ }
43
+ }
44
+
45
+ return {
46
+ orm,
47
+ em: orm.em.fork(),
48
+ };
49
+ }
50
+
51
+ export const FileSystemSchema = `
52
+ CREATE TABLE IF NOT EXISTS "file_node_meta"
53
+ (
54
+ -- Base fields
55
+ "id" TEXT PRIMARY KEY NOT NULL DEFAULT (ulid()),
56
+ "tid" TEXT,
57
+ "uid" TEXT,
58
+ "eid" TEXT,
59
+ "created_at" TEXT NOT NULL DEFAULT (datetime('now')),
60
+ "updated_at" TEXT NOT NULL DEFAULT (datetime('now')),
61
+ "deleted_at" TEXT,
62
+ "attributes" TEXT,
63
+ "properties" TEXT,
64
+ "extensions" TEXT,
65
+
66
+ -- File identification
67
+ "filename" TEXT NOT NULL,
68
+ "size" INTEGER NOT NULL DEFAULT 0,
69
+ "kind" TEXT NOT NULL,
70
+
71
+ -- Timestamps
72
+ "atime" TEXT NOT NULL,
73
+ "btime" TEXT NOT NULL,
74
+ "ctime" TEXT NOT NULL,
75
+ "mtime" TEXT NOT NULL,
76
+
77
+ -- Metadata
78
+ "metadata" TEXT NOT NULL DEFAULT '{}',
79
+
80
+ -- Hierarchy
81
+ "parent_id" TEXT,
82
+
83
+ -- Small file content (for files < 64KB)
84
+ "content" BLOB,
85
+
86
+ FOREIGN KEY ("parent_id") REFERENCES "file_node_meta" ("id")
87
+ );
88
+
89
+ CREATE INDEX IF NOT EXISTS "idx_file_node_meta_filename" ON "file_node_meta" ("filename");
90
+ CREATE INDEX IF NOT EXISTS "idx_file_node_meta_parent_id" ON "file_node_meta" ("parent_id");
91
+ CREATE INDEX IF NOT EXISTS "idx_file_node_meta_tid_parent_filename" ON "file_node_meta" ("tid", "parent_id", "filename");
92
+
93
+ CREATE TABLE IF NOT EXISTS "file_node_content"
94
+ (
95
+ -- Base fields
96
+ "id" TEXT PRIMARY KEY NOT NULL DEFAULT (ulid()),
97
+ "node_id" TEXT NOT NULL UNIQUE,
98
+ "tid" TEXT,
99
+ "uid" TEXT,
100
+ "eid" TEXT,
101
+ "created_at" TEXT NOT NULL DEFAULT (datetime('now')),
102
+ "updated_at" TEXT NOT NULL DEFAULT (datetime('now')),
103
+ "deleted_at" TEXT,
104
+ "attributes" TEXT,
105
+ "properties" TEXT,
106
+ "extensions" TEXT,
107
+
108
+ -- Content information
109
+ "size" INTEGER NOT NULL,
110
+ "content" BLOB,
111
+
112
+ -- File properties
113
+ "mime_type" TEXT,
114
+
115
+ -- Checksums
116
+ "md5" TEXT,
117
+ "sha256" TEXT,
118
+
119
+ -- Content metadata
120
+ "text" TEXT,
121
+ "width" INTEGER,
122
+ "height" INTEGER,
123
+
124
+ -- Additional metadata
125
+ "metadata" TEXT NOT NULL DEFAULT '{}',
126
+
127
+ FOREIGN KEY ("node_id") REFERENCES "file_node_meta" ("id") ON DELETE CASCADE
128
+ );
129
+
130
+ CREATE INDEX IF NOT EXISTS "idx_file_node_content_node_id" ON "file_node_content" ("node_id");
131
+ `;