@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,288 @@
1
+ import { expect } from 'vitest';
2
+ import { FileSystemError, FileSystemErrorCode } from '../FileSystemError';
3
+ import type { IFileSystem } from '../IFileSystem';
4
+
5
+ export type RunFileSystemTestOptions = {
6
+ writableStream?: boolean;
7
+ readableStream?: boolean;
8
+ readStream?: boolean;
9
+ writeStream?: boolean;
10
+ abort?: boolean;
11
+ };
12
+
13
+ export async function runFileSystemTest(fs: IFileSystem, options: RunFileSystemTestOptions = {}) {
14
+ const { writableStream = true, readableStream = true, readStream = true, writeStream = true, abort = true } = options;
15
+ // should be implemented
16
+ const stat = await fs.stat('/README.txt');
17
+ expect(stat).toMatchObject({
18
+ path: '/README.txt',
19
+ directory: '/',
20
+ name: 'README.txt',
21
+ kind: 'file',
22
+ size: 5,
23
+ });
24
+ await fs.mkdir('/');
25
+ const entries = await fs.readdir('/');
26
+ expect(entries.some((e) => e.name === 'README.txt')).toBe(true);
27
+ await fs.mkdir('/test');
28
+
29
+ if (fs.getUrl) {
30
+ expect(fs.getUrl(await fs.stat('/README.txt'))).toBeTypeOf('string');
31
+ }
32
+
33
+ // should handle AbortSignal
34
+ if (abort) {
35
+ const controller = new AbortController();
36
+ controller.abort();
37
+
38
+ await expect(fs.stat('/README.txt', { signal: controller.signal })).rejects.toThrow(Error);
39
+ await expect(fs.readdir('/', { signal: controller.signal })).rejects.toThrow(Error);
40
+ await expect(fs.mkdir('/test', { signal: controller.signal })).rejects.toThrow(Error);
41
+ await expect(fs.readFile('/README.txt', { signal: controller.signal })).rejects.toThrow(Error);
42
+ await expect(fs.writeFile('/test.txt', 'test', { signal: controller.signal })).rejects.toThrow(Error);
43
+ await expect(fs.rm('/README.txt', { signal: controller.signal })).rejects.toThrow(Error);
44
+ await expect(fs.rename('/README.txt', '/new.txt', { signal: controller.signal })).rejects.toThrow(Error);
45
+ await expect(fs.copy('/README.txt', '/copy.txt', { signal: controller.signal })).rejects.toThrow(Error);
46
+ }
47
+
48
+ // should validate input parameters
49
+ await expect(fs.stat('')).rejects.toThrow(FileSystemError);
50
+ await expect(fs.stat('')).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
51
+ await expect(fs.stat(null as any)).rejects.toThrow(FileSystemError);
52
+ await expect(fs.stat(null as any)).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
53
+ await expect(fs.stat(undefined as any)).rejects.toThrow(FileSystemError);
54
+ await expect(fs.stat(undefined as any)).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
55
+ await expect(fs.stat(123 as any)).rejects.toThrow(FileSystemError);
56
+ await expect(fs.stat(123 as any)).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
57
+
58
+ await expect(fs.writeFile('', 'test')).rejects.toThrow(FileSystemError);
59
+ await expect(fs.writeFile('', 'test')).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
60
+ await expect(fs.writeFile('/test', null as any)).rejects.toThrow(FileSystemError);
61
+ await expect(fs.writeFile('/test', null as any)).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
62
+ await expect(fs.writeFile('/test', undefined as any)).rejects.toThrow(FileSystemError);
63
+ await expect(fs.writeFile('/test', undefined as any)).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
64
+ await expect(fs.writeFile('/', 'test')).rejects.toThrow(FileSystemError);
65
+ await expect(fs.writeFile('/', 'test')).rejects.toMatchObject({ code: FileSystemErrorCode.EINVAL });
66
+
67
+ // should support streaming operations
68
+ if (readStream && fs.createReadStream) {
69
+ await fs.writeFile('/stream.txt', 'Hello, World!');
70
+
71
+ // Test createReadStream
72
+ const readStream = fs.createReadStream('/stream.txt');
73
+ expect(readStream).toBeDefined();
74
+
75
+ const chunks: Buffer[] = [];
76
+ for await (const chunk of readStream) {
77
+ chunks.push(chunk);
78
+ }
79
+ expect(Buffer.concat(chunks).toString()).toBe('Hello, World!');
80
+
81
+ // Test createReadStream with range
82
+ const rangeStream = fs.createReadStream('/stream.txt', { range: { start: 0, end: 4 } });
83
+ const rangeChunks: Buffer[] = [];
84
+ for await (const chunk of rangeStream) {
85
+ rangeChunks.push(chunk);
86
+ }
87
+ expect(Buffer.concat(rangeChunks).toString()).toBe('Hello');
88
+ }
89
+
90
+ if (writeStream && fs.createWriteStream) {
91
+ // Test createWriteStream
92
+ const writeStream = fs.createWriteStream('/write-test.txt');
93
+ expect(writeStream).toBeDefined();
94
+
95
+ writeStream.write('Test content');
96
+ writeStream.end();
97
+
98
+ await new Promise((resolve) => writeStream.on('finish', resolve));
99
+ expect(await fs.readFile('/write-test.txt', { encoding: 'text' })).toBe('Test content');
100
+ }
101
+
102
+ // should support Web Streams API
103
+ if (readableStream) {
104
+ await fs.writeFile('/webstream.txt', 'Web Stream Test');
105
+
106
+ // Test createReadableStream
107
+ const readableStream = fs.createReadableStream('/webstream.txt');
108
+ expect(readableStream).toBeDefined();
109
+
110
+ const reader = readableStream.getReader();
111
+ const { value } = await reader.read();
112
+ expect(value?.toString()).toBe('Web Stream Test');
113
+ }
114
+
115
+ if (writableStream) {
116
+ // Test createWritableStream
117
+ const writableStream = fs.createWritableStream('/web-write-test.txt');
118
+ expect(writableStream).toBeDefined();
119
+
120
+ const writer = writableStream.getWriter();
121
+ await writer.write(Buffer.from('Web Stream Write Test'));
122
+ await writer.close();
123
+
124
+ expect(await fs.readFile('/web-write-test.txt', { encoding: 'text' })).toBe('Web Stream Write Test');
125
+ }
126
+
127
+ // should handle streaming errors
128
+ if (abort && readStream && fs.createReadStream) {
129
+ const controller2 = new AbortController();
130
+
131
+ // Test read stream with abort
132
+ const readStream = fs.createReadStream('/README.txt', { signal: controller2.signal });
133
+ controller2.abort();
134
+
135
+ await expect(
136
+ new Promise((_, reject) => {
137
+ readStream.on('error', reject);
138
+ }),
139
+ ).rejects.toThrow(Error);
140
+ }
141
+
142
+ if (abort && writeStream && fs.createWriteStream) {
143
+ // Test write stream with abort
144
+ const controller3 = new AbortController();
145
+ const writeStream = fs.createWriteStream('/abort-test.txt', { signal: controller3.signal });
146
+ controller3.abort();
147
+
148
+ await expect(
149
+ new Promise((_, reject) => {
150
+ writeStream.on('error', reject);
151
+ writeStream.write('test');
152
+ }),
153
+ ).rejects.toThrow(Error);
154
+ }
155
+
156
+ // should handle file operations correctly
157
+ // Test file creation
158
+ await fs.writeFile('/newfile.txt', 'New content');
159
+ expect(await fs.exists('/newfile.txt')).toBe(true);
160
+
161
+ const stat2 = await fs.stat('/newfile.txt');
162
+ expect(stat2.kind).toBe('file');
163
+ expect(stat2.size).toBe(11); // "New content" is 11 bytes
164
+
165
+ // Test file reading
166
+ const content = await fs.readFile('/newfile.txt', { encoding: 'text' });
167
+ expect(content).toBe('New content');
168
+
169
+ // Test file reading as binary
170
+ const binary = await fs.readFile('/newfile.txt');
171
+ expect(Buffer.from(binary).toString()).toBe('New content');
172
+
173
+ // Test file overwrite
174
+ await fs.writeFile('/newfile.txt', 'Updated content');
175
+ expect(await fs.readFile('/newfile.txt', { encoding: 'text' })).toBe('Updated content');
176
+
177
+ // Test file overwrite protection
178
+ await expect(fs.writeFile('/newfile.txt', 'Should fail', { overwrite: false })).rejects.toThrow(FileSystemError);
179
+ await expect(fs.writeFile('/newfile.txt', 'Should fail', { overwrite: false })).rejects.toMatchObject({
180
+ code: FileSystemErrorCode.EEXIST,
181
+ });
182
+
183
+ // Test large file write (should use file_node_content table)
184
+ // Create ~1KB data to test large file handling
185
+ const largeData = 'x'.repeat(1024); // 1KB of data
186
+ await fs.writeFile('/largefile.txt', largeData);
187
+ const largeFileStat = await fs.stat('/largefile.txt');
188
+ expect(largeFileStat.size).toBe(1024);
189
+ const largeFileContent = await fs.readFile('/largefile.txt', { encoding: 'text' });
190
+ expect(largeFileContent).toBe(largeData);
191
+ expect(largeFileContent.length).toBe(1024);
192
+
193
+ // should handle directory operations correctly
194
+ // Test directory creation
195
+ await fs.mkdir('/newdir');
196
+ expect(await fs.exists('/newdir')).toBe(true);
197
+
198
+ const stat3 = await fs.stat('/newdir');
199
+ expect(stat3.kind).toBe('directory');
200
+
201
+ // Test recursive directory creation
202
+ await fs.mkdir('/deep/nested/dir', { recursive: true });
203
+ expect(await fs.exists('/deep/nested/dir')).toBe(true);
204
+
205
+ // Test non-recursive directory creation failure
206
+ await expect(fs.mkdir('/another/deep/dir')).rejects.toThrow(FileSystemError);
207
+ await expect(fs.mkdir('/another/deep/dir')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
208
+
209
+ // Test directory listing
210
+ await fs.writeFile('/newdir/file1.txt', 'File 1');
211
+ await fs.writeFile('/newdir/file2.txt', 'File 2');
212
+
213
+ const contents = await fs.readdir('/newdir');
214
+ expect(contents).toHaveLength(2);
215
+ expect(contents.map((f) => f.name)).toContain('file1.txt');
216
+ expect(contents.map((f) => f.name)).toContain('file2.txt');
217
+
218
+ // should handle file removal correctly
219
+ await fs.writeFile('/toremove.txt', 'Remove me');
220
+ expect(await fs.exists('/toremove.txt')).toBe(true);
221
+
222
+ await fs.rm('/toremove.txt');
223
+ expect(await fs.exists('/toremove.txt')).toBe(false);
224
+
225
+ // Test force removal
226
+ await expect(fs.rm('/nonexistent.txt')).rejects.toThrow(FileSystemError);
227
+ await expect(fs.rm('/nonexistent.txt')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
228
+ await fs.rm('/nonexistent.txt', { force: true }); // Should not throw
229
+
230
+ // Test recursive removal
231
+ await fs.mkdir('/dirwithfiles', { recursive: true });
232
+ await fs.writeFile('/dirwithfiles/file.txt', 'content');
233
+ await expect(fs.rm('/dirwithfiles')).rejects.toThrow(FileSystemError);
234
+ await expect(fs.rm('/dirwithfiles')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOTEMPTY });
235
+ await fs.rm('/dirwithfiles', { recursive: true });
236
+ expect(await fs.exists('/dirwithfiles')).toBe(false);
237
+
238
+ // should handle file rename correctly
239
+ await fs.writeFile('/rename.txt', 'Original content');
240
+ expect(await fs.exists('/rename.txt')).toBe(true);
241
+
242
+ await fs.rename('/rename.txt', '/renamed.txt');
243
+ expect(await fs.exists('/rename.txt')).toBe(false);
244
+ expect(await fs.exists('/renamed.txt')).toBe(true);
245
+ expect(await fs.readFile('/renamed.txt', { encoding: 'text' })).toBe('Original content');
246
+
247
+ // should handle file copy correctly
248
+ await fs.writeFile('/copy.txt', 'Copy me');
249
+ expect(await fs.exists('/copy.txt')).toBe(true);
250
+
251
+ await fs.copy('/copy.txt', '/copied.txt');
252
+ expect(await fs.exists('/copy.txt')).toBe(true);
253
+ expect(await fs.exists('/copied.txt')).toBe(true);
254
+ expect(await fs.readFile('/copied.txt', { encoding: 'text' })).toBe('Copy me');
255
+
256
+ // Test copy overwrite
257
+ await fs.writeFile('/target2.txt', 'Target content');
258
+ await expect(fs.copy('/copy.txt', '/target2.txt')).rejects.toThrow(FileSystemError);
259
+ await expect(fs.copy('/copy.txt', '/target2.txt')).rejects.toMatchObject({ code: FileSystemErrorCode.EEXIST });
260
+ await fs.copy('/copy.txt', '/target2.txt', { overwrite: true });
261
+ expect(await fs.readFile('/target2.txt', { encoding: 'text' })).toBe('Copy me');
262
+
263
+ // should handle edge cases correctly
264
+ // Test root directory operations
265
+ await expect(fs.stat('/')).resolves.toBeDefined();
266
+ await expect(fs.readdir('/')).resolves.toBeDefined();
267
+ await fs.mkdir('/'); // Should not throw
268
+
269
+ // Test path normalization
270
+ await fs.writeFile('/normalize.txt', 'test');
271
+ expect(await fs.exists('/normalize.txt')).toBe(true);
272
+ expect(await fs.exists('/./normalize.txt')).toBe(true);
273
+ // Note: the exists method may return true for files with trailing slashes due to normalization
274
+
275
+ // Test error cases
276
+ await expect(fs.stat('/nonexistent')).rejects.toThrow(FileSystemError);
277
+ await expect(fs.stat('/nonexistent')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
278
+ await expect(fs.readdir('/nonexistent')).rejects.toThrow(FileSystemError);
279
+ await expect(fs.readdir('/nonexistent')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
280
+ await expect(fs.readFile('/nonexistent')).rejects.toThrow(FileSystemError);
281
+ await expect(fs.readFile('/nonexistent')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
282
+ await expect(fs.rm('/nonexistent')).rejects.toThrow(FileSystemError);
283
+ await expect(fs.rm('/nonexistent')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
284
+ await expect(fs.rename('/nonexistent', '/new')).rejects.toThrow(FileSystemError);
285
+ await expect(fs.rename('/nonexistent', '/new')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
286
+ await expect(fs.copy('/nonexistent', '/new')).rejects.toThrow(FileSystemError);
287
+ await expect(fs.copy('/nonexistent', '/new')).rejects.toMatchObject({ code: FileSystemErrorCode.ENOENT });
288
+ }
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod/v4';
2
+
3
+ type EnumValues<T> = T[Exclude<keyof T, '__proto__'>];
4
+ export const FileKind = Object.freeze({
5
+ __proto__: null,
6
+ directory: 'directory',
7
+ file: 'file',
8
+ });
9
+ export type FileKind = EnumValues<typeof FileKind>;
10
+ export const FileKindSchema = z.enum(['directory', 'file']);
11
+
12
+ export type ReaddirOptions = z.infer<typeof ReaddirOptionsSchema>;
13
+ export const ReaddirOptionsSchema = z.object({
14
+ recursive: z.boolean().optional(),
15
+ depth: z.number().optional(),
16
+ glob: z.string().optional(),
17
+ kind: FileKindSchema.optional(),
18
+ cursor: z.string().optional(),
19
+ hidden: z.boolean().default(false),
20
+ });
21
+
22
+ export type FileUrlOptions = z.infer<typeof FileUrlOptionsSchema>;
23
+ export const FileUrlOptionsSchema = z.object({
24
+ size: z.coerce.number().optional(),
25
+ width: z.number().optional(),
26
+ height: z.number().optional(),
27
+ quality: z.number().optional(),
28
+ thumbnail: z.boolean().optional(),
29
+ });
@@ -0,0 +1,44 @@
1
+ import type { IFileStat, IFileSystem } from '../IFileSystem';
2
+ import type { FileUrlOptions } from '../types';
3
+
4
+ export function getFileUrl(
5
+ fs: IFileSystem,
6
+ needle?: IFileStat | string,
7
+ {
8
+ ...options
9
+ }: FileUrlOptions & {
10
+ fs?: IFileSystem;
11
+ } = {},
12
+ ) {
13
+ const [file, path] = resolveFilePath(needle);
14
+ if (!path || !needle) return;
15
+
16
+ let out: string | undefined;
17
+ if (fs?.getUrl) {
18
+ try {
19
+ out = fs.getUrl(needle, options);
20
+ } catch (e) {
21
+ console.error(`failed to get file url`, needle, e);
22
+ }
23
+ }
24
+ if (!out && file) {
25
+ out = file.meta?.url || (file as any).url;
26
+ }
27
+ return out;
28
+ }
29
+
30
+ export function resolveFilePath(needle: IFileStat): [IFileStat, string];
31
+ export function resolveFilePath(needle: string): [undefined, string];
32
+ export function resolveFilePath(needle?: IFileStat | string): [IFileStat | undefined, string | undefined];
33
+ export function resolveFilePath(needle?: IFileStat | string): [IFileStat | undefined, string | undefined] {
34
+ if (!needle) {
35
+ return [undefined, undefined];
36
+ }
37
+ let file = typeof needle === 'string' ? undefined : needle;
38
+ let path = typeof needle === 'string' ? needle : needle.path;
39
+
40
+ if (file && !path) {
41
+ path = file.path;
42
+ }
43
+ return [file, path];
44
+ }
@@ -0,0 +1,23 @@
1
+ import { ArrayBuffers, classOf } from '@wener/utils';
2
+ import type { IFileStat, WritableData } from './IFileSystem';
3
+
4
+ export function resolveData(data: WritableData) {
5
+ let buf: Uint8Array;
6
+ if (typeof data === 'string') {
7
+ buf = ArrayBuffers.toUint8Array(ArrayBuffers.from(data, 'utf8'));
8
+ } else if (data instanceof ArrayBuffer) {
9
+ buf = new Uint8Array(data);
10
+ } else if (data instanceof Uint8Array) {
11
+ buf = data;
12
+ } else {
13
+ throw new Error(`unable to resolve data: ${typeof data} ${classOf(data)}`);
14
+ }
15
+ return buf;
16
+ }
17
+
18
+ export function getPath(f: IFileStat | string) {
19
+ if (typeof f === 'string') {
20
+ return f;
21
+ }
22
+ return f.path;
23
+ }
@@ -1,26 +1,25 @@
1
1
  import type { Static, TSchema } from '@sinclair/typebox';
2
+ import { isNil } from '@wener/utils';
2
3
  import Ajv, { type ErrorObject, type Options } from 'ajv';
3
4
  import addFormats from 'ajv-formats';
4
- // import localize from 'ajv-i18n/localize/zh';
5
5
  import addKeywords from 'ajv-keywords';
6
- import { isNil } from 'es-toolkit';
7
6
  import { match, P } from 'ts-pattern';
8
7
  import type { JsonSchemaDef } from './types';
9
8
 
10
- function _createAjv(opt: Options) {
9
+ function _createValidator(opt: Options) {
11
10
  const ajv = new Ajv(opt);
12
11
  addKeywords(ajv);
13
12
  addFormats(ajv);
14
13
  return ajv;
15
14
  }
16
15
 
17
- type ValidateOptions = { mutate?: boolean; clone?: boolean; ajv?: Ajv };
16
+ type ValidateOptions = { mutate?: boolean; clone?: boolean; validator?: Ajv };
18
17
 
19
18
  type ValidateResult<T> =
20
19
  | { data: T; success: true; message: undefined }
21
20
  | { data: undefined; success: false; message: string; errors: ErrorObject[] };
22
21
 
23
- function validate({ schema, data, mutate, clone, ajv }: ValidateOptions & { schema: any; data: any }) {
22
+ function validate({ schema, data, mutate, clone, validator }: ValidateOptions & { schema: any; data: any }) {
24
23
  let opts: Options = {
25
24
  // strict: 'log',
26
25
  strict: true,
@@ -35,11 +34,11 @@ function validate({ schema, data, mutate, clone, ajv }: ValidateOptions & { sche
35
34
  data = structuredClone(data);
36
35
  }
37
36
 
38
- if (!ajv) {
39
- ajv = JsonSchema.createAjv(opts);
37
+ if (!validator) {
38
+ validator = JsonSchema.createValidator(opts);
40
39
  }
41
40
 
42
- const validate = ajv.compile(schema);
41
+ const validate = validator.compile(schema);
43
42
 
44
43
  // consider reusing validate instance
45
44
 
@@ -47,119 +46,128 @@ function validate({ schema, data, mutate, clone, ajv }: ValidateOptions & { sche
47
46
  const errors = validate.errors;
48
47
  // localize(errors);
49
48
 
50
- return { data, success: valid, message: ajv.errorsText(errors), errors: errors };
49
+ return { data, success: valid, message: validator.errorsText(errors), errors: errors };
51
50
  }
52
51
 
53
52
  type TypeOfSchema<S> = S extends TSchema ? Static<S> : any;
54
53
 
55
- export namespace JsonSchema {
56
- export let schemas: JsonSchemaDef[] = [];
57
-
58
- export let createAjv = _createAjv;
59
-
60
- export function addSchema(
61
- schema: JsonSchemaDef,
62
- {
63
- onConflict = 'throw',
64
- }: {
65
- onConflict?: 'throw' | 'ignore' | 'replace' | ((old: JsonSchemaDef, neo: JsonSchemaDef) => JsonSchemaDef);
66
- } = {},
67
- ) {
68
- if (!schema.$id) throw new Error('Schema must have $id');
69
- switch (onConflict) {
70
- case 'ignore':
71
- onConflict = (old) => old;
72
- break;
73
- case 'replace':
74
- onConflict = (_, neo) => neo;
75
- break;
76
- case 'throw':
77
- onConflict = (old, neo) => {
78
- throw new Error(`Schema ${neo.$id} already exists`);
79
- };
80
- break;
81
- }
82
- let idx = schemas.findIndex((s) => s.$id === schema.$id);
83
- if (idx >= 0) {
84
- schemas[idx] = onConflict(schemas[idx], schema);
85
- } else {
86
- schemas.push(schema);
87
- }
54
+ let schemas: JsonSchemaDef[] = [];
55
+
56
+ let createValidator = _createValidator;
57
+
58
+ function addSchema(
59
+ schema: JsonSchemaDef,
60
+ {
61
+ onConflict = 'throw',
62
+ }: {
63
+ onConflict?: 'throw' | 'ignore' | 'replace' | ((old: JsonSchemaDef, neo: JsonSchemaDef) => JsonSchemaDef);
64
+ } = {},
65
+ ) {
66
+ if (!schema.$id) throw new Error('Schema must have $id');
67
+ switch (onConflict) {
68
+ case 'ignore':
69
+ onConflict = (old) => old;
70
+ break;
71
+ case 'replace':
72
+ onConflict = (_, neo) => neo;
73
+ break;
74
+ case 'throw':
75
+ onConflict = (old, neo) => {
76
+ throw new Error(`Schema ${neo.$id} already exists`);
77
+ };
78
+ break;
88
79
  }
89
-
90
- /**
91
- * Check data is valid, will not use default
92
- */
93
- export function check<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {
94
- return validate({ schema, data, mutate: false, clone: true }) as any;
80
+ let idx = schemas.findIndex((s) => s.$id === schema.$id);
81
+ if (idx >= 0) {
82
+ schemas[idx] = onConflict(schemas[idx], schema);
83
+ } else {
84
+ schemas.push(schema);
95
85
  }
86
+ }
96
87
 
97
- /**
98
- * Parse data with default value and coerceTypes
99
- */
100
- export function safeParse<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {
101
- return validate({ schema, data, mutate: true, clone: true }) as any;
102
- }
88
+ /**
89
+ * Check data is valid, will not use default
90
+ */
91
+ function check<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {
92
+ return validate({ schema, data, mutate: false, clone: true }) as any;
93
+ }
103
94
 
104
- export function parse<S>(schema: S, data: any): TypeOfSchema<S> {
105
- const { data: out, message, errors } = validate({ schema, data, mutate: true, clone: true });
106
- if (errors) {
107
- throw new Error(message);
108
- }
109
- return out;
95
+ /**
96
+ * Parse data with default value and coerceTypes
97
+ */
98
+ function safeParse<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {
99
+ return validate({ schema, data, mutate: true, clone: true }) as any;
100
+ }
101
+
102
+ function parse<S>(schema: S, data: any): TypeOfSchema<S> {
103
+ const { data: out, message, errors } = validate({ schema, data, mutate: true, clone: true });
104
+ if (errors) {
105
+ throw new Error(message);
110
106
  }
107
+ return out;
108
+ }
111
109
 
112
- export function create<S>(schema: S, data?: any): TypeOfSchema<S> {
113
- // will not ensure value match the rule
114
- return match(schema as JsonSchemaDef)
115
- .returnType<any>()
116
- .with({ const: P.nonNullable }, (v) => v)
117
- .with({ default: P.select() }, (v) => v)
118
- .with({ anyOf: P.nonNullable }, (schema) => {
119
- return create(schema.anyOf[0]);
120
- })
121
- .with({ oneOf: P.nonNullable }, (schema) => {
122
- return create(schema.oneOf[0]);
123
- })
124
- .with({ type: 'string' }, (schema) => '')
125
- .with({ type: P.union('number', 'integer') }, (schema) => 0)
126
- .with({ type: 'object' }, (schema) => {
127
- let out = validate({ schema, data: data ?? {}, mutate: true });
128
- if (!out.success) {
129
- // fallback
130
- let obj = data || {};
131
- schema.required?.forEach((key) => {
132
- if (!(key in obj)) {
133
- let last = obj[key];
134
- let prop = schema.properties?.[key];
135
- if (prop && isNil(last)) obj[key] = JsonSchema.create(prop, last);
136
- }
137
- });
138
- out = validate({ schema, data: obj, mutate: true });
139
- if (!out.success) {
140
- console.warn(`Failed to create object with schema: ${out.message}`);
110
+ function create<S>(schema: S, data?: any): TypeOfSchema<S> {
111
+ // will not ensure value match the rule
112
+ return match(schema as JsonSchemaDef)
113
+ .returnType<any>()
114
+ .with({ const: P.nonNullable }, (v) => v)
115
+ .with({ default: P.select() }, (v) => v)
116
+ .with({ anyOf: P.nonNullable }, (schema) => {
117
+ return create(schema.anyOf[0]);
118
+ })
119
+ .with({ oneOf: P.nonNullable }, (schema) => {
120
+ return create(schema.oneOf[0]);
121
+ })
122
+ .with({ type: 'string' }, (schema) => '')
123
+ .with({ type: P.union('number', 'integer') }, (schema) => 0)
124
+ .with({ type: 'object' }, (schema: JsonSchemaDef) => {
125
+ let out = validate({ schema, data: data ?? {}, mutate: true });
126
+ if (!out.success) {
127
+ // fallback
128
+ let obj = data || {};
129
+ schema.required?.forEach((key) => {
130
+ if (!(key in obj)) {
131
+ let last = obj[key];
132
+ let prop = schema.properties?.[key];
133
+ if (prop && isNil(last)) obj[key] = JsonSchema.create(prop, last);
141
134
  }
135
+ });
136
+ out = validate({ schema, data: obj, mutate: true });
137
+ if (!out.success) {
138
+ console.warn(`Failed to create object with schema: ${out.message}`);
142
139
  }
143
- return out.data;
144
- })
145
- .with({ type: 'null' }, () => null)
146
- .with({ type: 'boolean' }, (schema) => false)
147
- .with({ type: 'array' }, (schema) => [])
148
- .otherwise(() => {
149
- return undefined;
150
- });
151
- }
140
+ }
141
+ return out.data;
142
+ })
143
+ .with({ type: 'null' }, () => null)
144
+ .with({ type: 'boolean' }, (schema) => false)
145
+ .with({ type: 'array' }, (schema) => [])
146
+ .otherwise(() => {
147
+ return undefined;
148
+ });
149
+ }
152
150
 
153
- export function isPrimitiveType(schema: any): boolean {
154
- return match(schema as JsonSchemaDef)
155
- .returnType<boolean>()
156
- .with({ type: P.union('number', 'integer', 'string', 'boolean') }, () => true)
157
- .with({ anyOf: P.nonNullable }, (schema) => {
158
- return isPrimitiveType(schema.anyOf[0]);
159
- })
160
- .with({ oneOf: P.nonNullable }, (schema) => {
161
- return isPrimitiveType(schema.oneOf[0]);
162
- })
163
- .otherwise(() => false);
164
- }
151
+ function isPrimitiveType(schema: any): boolean {
152
+ return match(schema as JsonSchemaDef)
153
+ .returnType<boolean>()
154
+ .with({ type: P.union('number', 'integer', 'string', 'boolean') }, () => true)
155
+ .with({ anyOf: P.nonNullable }, (schema) => {
156
+ return isPrimitiveType(schema.anyOf[0]);
157
+ })
158
+ .with({ oneOf: P.nonNullable }, (schema) => {
159
+ return isPrimitiveType(schema.oneOf[0]);
160
+ })
161
+ .otherwise(() => false);
165
162
  }
163
+
164
+ export const JsonSchema = {
165
+ createValidator,
166
+ addSchema,
167
+ schemas,
168
+ check,
169
+ safeParse,
170
+ parse,
171
+ create,
172
+ isPrimitiveType,
173
+ } as const;