@wener/common 2.0.3 → 2.0.5

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 (168) hide show
  1. package/lib/ai/qwen3vl/utils.js.map +1 -1
  2. package/lib/cn/ChineseResidentIdNo.js +1 -1
  3. package/lib/cn/ChineseResidentIdNo.js.map +1 -1
  4. package/lib/cn/Mod11.js +1 -1
  5. package/lib/cn/Mod11.js.map +1 -1
  6. package/lib/consola/formatLogObject.js +5 -5
  7. package/lib/consola/formatLogObject.js.map +1 -1
  8. package/lib/data/maybeNumber.js +1 -1
  9. package/lib/data/maybeNumber.js.map +1 -1
  10. package/lib/data/types.d.js.map +1 -1
  11. package/lib/dayjs/formatDuration.js.map +1 -1
  12. package/lib/dayjs/resolveRelativeTime.js +9 -80
  13. package/lib/dayjs/resolveRelativeTime.js.map +1 -1
  14. package/lib/drain3/Drain.js +356 -0
  15. package/lib/drain3/Drain.js.map +1 -0
  16. package/lib/drain3/LogCluster.js +38 -0
  17. package/lib/drain3/LogCluster.js.map +1 -0
  18. package/lib/drain3/Node.js +39 -0
  19. package/lib/drain3/Node.js.map +1 -0
  20. package/lib/drain3/TemplateMiner.js +204 -0
  21. package/lib/drain3/TemplateMiner.js.map +1 -0
  22. package/lib/drain3/index.js +31 -0
  23. package/lib/drain3/index.js.map +1 -0
  24. package/lib/drain3/persistence/FilePersistence.js +24 -0
  25. package/lib/drain3/persistence/FilePersistence.js.map +1 -0
  26. package/lib/drain3/persistence/MemoryPersistence.js +18 -0
  27. package/lib/drain3/persistence/MemoryPersistence.js.map +1 -0
  28. package/lib/drain3/persistence/PersistenceHandler.js +5 -0
  29. package/lib/drain3/persistence/PersistenceHandler.js.map +1 -0
  30. package/lib/drain3/types.js +7 -0
  31. package/lib/drain3/types.js.map +1 -0
  32. package/lib/fs/IFileSystem.d.js.map +1 -1
  33. package/lib/fs/createBrowserFileSystem.js +4 -2
  34. package/lib/fs/createBrowserFileSystem.js.map +1 -1
  35. package/lib/fs/createMemoryFileSystem.js +7 -6
  36. package/lib/fs/createMemoryFileSystem.js.map +1 -1
  37. package/lib/fs/createSandboxFileSystem.js.map +1 -1
  38. package/lib/fs/createWebDavFileSystem.js +22 -5
  39. package/lib/fs/createWebDavFileSystem.js.map +1 -1
  40. package/lib/fs/createWebFileSystem.js +225 -0
  41. package/lib/fs/createWebFileSystem.js.map +1 -0
  42. package/lib/fs/findMimeType.js +1 -1
  43. package/lib/fs/findMimeType.js.map +1 -1
  44. package/lib/fs/index.js +1 -1
  45. package/lib/fs/index.js.map +1 -1
  46. package/lib/fs/minio/createMinioFileSystem.js +974 -0
  47. package/lib/fs/minio/createMinioFileSystem.js.map +1 -0
  48. package/lib/fs/minio/index.js +2 -0
  49. package/lib/fs/minio/index.js.map +1 -0
  50. package/lib/fs/orpc/createContractClientFileSystem.js +3 -3
  51. package/lib/fs/orpc/createContractClientFileSystem.js.map +1 -1
  52. package/lib/fs/orpc/server/createFileSystemContractImpl.js.map +1 -1
  53. package/lib/fs/s3/createS3MiniFileSystem.js +116 -68
  54. package/lib/fs/s3/createS3MiniFileSystem.js.map +1 -1
  55. package/lib/fs/server/createDatabaseFileSystem.js +7 -7
  56. package/lib/fs/server/createDatabaseFileSystem.js.map +1 -1
  57. package/lib/fs/server/createNodeFileSystem.js +30 -5
  58. package/lib/fs/server/createNodeFileSystem.js.map +1 -1
  59. package/lib/fs/tests/runFileSystemTest.js +27 -26
  60. package/lib/fs/tests/runFileSystemTest.js.map +1 -1
  61. package/lib/fs/utils.js.map +1 -1
  62. package/lib/fs/webdav/index.js +2 -0
  63. package/lib/fs/webdav/index.js.map +1 -0
  64. package/lib/jsonschema/JsonSchema.js +5 -5
  65. package/lib/jsonschema/JsonSchema.js.map +1 -1
  66. package/lib/jsonschema/forEachJsonSchema.js +1 -1
  67. package/lib/jsonschema/forEachJsonSchema.js.map +1 -1
  68. package/lib/jsonschema/types.d.js.map +1 -1
  69. package/lib/meta/defineMetadata.js.map +1 -1
  70. package/lib/orpc/createOpenApiContractClient.js.map +1 -1
  71. package/lib/password/PHC.js +2 -2
  72. package/lib/password/PHC.js.map +1 -1
  73. package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
  74. package/lib/password/createBase64PasswordAlgorithm.js +1 -1
  75. package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
  76. package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
  77. package/lib/password/createPBKDF2PasswordAlgorithm.js +1 -1
  78. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
  79. package/lib/password/createScryptPasswordAlgorithm.js +3 -3
  80. package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
  81. package/lib/resource/ListQuery.js.map +1 -1
  82. package/lib/resource/index.js.map +1 -1
  83. package/lib/s3/formatS3Url.js +2 -2
  84. package/lib/s3/formatS3Url.js.map +1 -1
  85. package/lib/s3/parseS3Url.js +1 -1
  86. package/lib/s3/parseS3Url.js.map +1 -1
  87. package/lib/schema/SchemaRegistry.js.map +1 -1
  88. package/lib/schema/TypeSchema.d.js.map +1 -1
  89. package/lib/schema/createSchemaData.js +4 -4
  90. package/lib/schema/createSchemaData.js.map +1 -1
  91. package/lib/schema/findJsonSchemaByPath.js.map +1 -1
  92. package/lib/schema/formatZodError.js +42 -44
  93. package/lib/schema/formatZodError.js.map +1 -1
  94. package/lib/schema/toJsonSchema.js +4 -4
  95. package/lib/schema/toJsonSchema.js.map +1 -1
  96. package/lib/schema/validate.js +1 -1
  97. package/lib/schema/validate.js.map +1 -1
  98. package/lib/utils/buildRedactorFormSchema.js +1 -1
  99. package/lib/utils/buildRedactorFormSchema.js.map +1 -1
  100. package/package.json +32 -13
  101. package/src/ai/qwen3vl/utils.ts +1 -1
  102. package/src/cn/ChineseResidentIdNo.ts +1 -1
  103. package/src/cn/Mod11.ts +1 -1
  104. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +1 -1
  105. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +0 -23
  106. package/src/cn/parseChineseNumber.test.ts +4 -4
  107. package/src/consola/formatLogObject.ts +6 -6
  108. package/src/data/maybeNumber.ts +1 -1
  109. package/src/data/parseSort.test.ts +0 -1
  110. package/src/data/types.d.ts +2 -2
  111. package/src/dayjs/formatDuration.ts +2 -2
  112. package/src/dayjs/resolveRelativeTime.ts +11 -14
  113. package/src/drain3/Drain.test.ts +378 -0
  114. package/src/drain3/Drain.ts +394 -0
  115. package/src/drain3/LogCluster.ts +46 -0
  116. package/src/drain3/Node.ts +53 -0
  117. package/src/drain3/TemplateMiner.ts +246 -0
  118. package/src/drain3/index.ts +36 -0
  119. package/src/drain3/persistence/FilePersistence.ts +24 -0
  120. package/src/drain3/persistence/MemoryPersistence.ts +23 -0
  121. package/src/drain3/persistence/PersistenceHandler.ts +19 -0
  122. package/src/drain3/types.ts +75 -0
  123. package/src/fs/IFileSystem.d.ts +1 -2
  124. package/src/fs/createBrowserFileSystem.ts +7 -5
  125. package/src/fs/createMemoryFileSystem.ts +9 -13
  126. package/src/fs/createSandboxFileSystem.ts +1 -1
  127. package/src/fs/createWebDavFileSystem.ts +28 -10
  128. package/src/fs/createWebFileSystem.ts +242 -0
  129. package/src/fs/findMimeType.ts +1 -4
  130. package/src/fs/index.ts +1 -1
  131. package/src/fs/minio/createMinioFileSystem.ts +1148 -0
  132. package/src/fs/minio/index.ts +1 -0
  133. package/src/fs/orpc/createContractClientFileSystem.ts +5 -5
  134. package/src/fs/orpc/server/createFileSystemContractImpl.ts +1 -1
  135. package/src/fs/s3/createS3MiniFileSystem.ts +119 -78
  136. package/src/fs/s3/s3fs.test.ts +441 -0
  137. package/src/fs/s3/s3mini.test.ts +2 -2
  138. package/src/fs/server/createDatabaseFileSystem.ts +7 -7
  139. package/src/fs/server/createNodeFileSystem.ts +32 -13
  140. package/src/fs/server/dbfs.test.ts +2 -1
  141. package/src/fs/tests/runFileSystemTest.ts +29 -28
  142. package/src/fs/utils.ts +1 -1
  143. package/src/fs/webdav/index.ts +1 -0
  144. package/src/jsonschema/JsonSchema.ts +5 -5
  145. package/src/jsonschema/forEachJsonSchema.ts +1 -1
  146. package/src/jsonschema/types.d.ts +1 -1
  147. package/src/meta/defineMetadata.ts +1 -1
  148. package/src/orpc/createOpenApiContractClient.ts +2 -2
  149. package/src/password/PHC.ts +3 -3
  150. package/src/password/createArgon2PasswordAlgorithm.ts +1 -1
  151. package/src/password/createBase64PasswordAlgorithm.ts +2 -2
  152. package/src/password/createBcryptPasswordAlgorithm.ts +4 -2
  153. package/src/password/createPBKDF2PasswordAlgorithm.ts +2 -2
  154. package/src/password/createScryptPasswordAlgorithm.ts +4 -4
  155. package/src/resource/ListQuery.ts +4 -1
  156. package/src/resource/index.ts +2 -2
  157. package/src/s3/formatS3Url.test.ts +1 -1
  158. package/src/s3/formatS3Url.ts +2 -2
  159. package/src/s3/parseS3Url.ts +1 -1
  160. package/src/schema/SchemaRegistry.ts +1 -1
  161. package/src/schema/TypeSchema.d.ts +6 -6
  162. package/src/schema/createSchemaData.ts +4 -4
  163. package/src/schema/findJsonSchemaByPath.ts +4 -4
  164. package/src/schema/formatZodError.test.ts +2 -1
  165. package/src/schema/formatZodError.ts +50 -62
  166. package/src/schema/toJsonSchema.ts +6 -6
  167. package/src/schema/validate.ts +1 -1
  168. package/src/utils/buildRedactorFormSchema.ts +3 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schema/formatZodError.ts"],"sourcesContent":["import { ZodError } from 'zod/v4';\nimport { findJsonSchemaByPath } from './findJsonSchemaByPath';\nimport type { TypeSchema } from './TypeSchema';\n\nexport function formatZodError(error: ZodError, schema?: TypeSchema): string {\n\tif (!error.issues || error.issues.length === 0) {\n\t\treturn error.message || '验证失败';\n\t}\n\n\tconst messages: string[] = [];\n\n\t// Iterate through issues and format each one\n\t// We use manual iteration instead of error.format() to have better control\n\t// over field name formatting with schema descriptions\n\tfor (const issue of error.issues) {\n\t\tconst formatted = formatIssueMessage(issue, schema);\n\t\tif (formatted) {\n\t\t\tconst path = issue.path.map((p) => (typeof p === 'symbol' ? String(p) : p)) as (string | number)[];\n\t\t\tlet fieldName = formatPath(path);\n\n\t\t\t// Try to get field description from schema\n\t\t\tif (schema && path.length > 0) {\n\t\t\t\tconst fieldPath = path.map(String).join('.');\n\t\t\t\tconst fieldSchema = findJsonSchemaByPath(schema, fieldPath);\n\t\t\t\tif (fieldSchema?.description) {\n\t\t\t\t\tfieldName = fieldSchema.description;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmessages.push(`${fieldName}: ${formatted}`);\n\t\t}\n\t}\n\n\treturn messages.join(';');\n}\n\nfunction formatIssueMessage(issue: ZodError['issues'][number], schema?: TypeSchema): string {\n\tlet message = issue.message;\n\n\t// 处理常见的错误类型,生成更友好的消息\n\t// Use string comparison to avoid TypeScript narrowing issues with Zod v4\n\tconst code = issue.code as string;\n\tswitch (code) {\n\t\tcase 'invalid_type': {\n\t\t\tconst invalidTypeIssue = issue as typeof issue & {\n\t\t\t\texpected: string;\n\t\t\t\treceived: string;\n\t\t\t};\n\t\t\tif (invalidTypeIssue.received === 'undefined') {\n\t\t\t\tmessage = '必填';\n\t\t\t} else if (invalidTypeIssue.received === 'null') {\n\t\t\t\tmessage = '不能为空';\n\t\t\t} else {\n\t\t\t\tmessage = issue.message || `期望类型 ${invalidTypeIssue.expected},但收到 ${invalidTypeIssue.received}`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_string': {\n\t\t\tconst invalidStringIssue = issue as typeof issue & {\n\t\t\t\tvalidation?: string;\n\t\t\t};\n\t\t\tif (invalidStringIssue.validation === 'email') {\n\t\t\t\tmessage = '请输入有效的邮箱地址';\n\t\t\t} else if (invalidStringIssue.validation === 'url') {\n\t\t\t\tmessage = '请输入有效的 URL';\n\t\t\t} else if (invalidStringIssue.validation === 'uuid') {\n\t\t\t\tmessage = '请输入有效的 UUID';\n\t\t\t} else if (invalidStringIssue.validation === 'date') {\n\t\t\t\tmessage = '请输入有效的日期';\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'too_small': {\n\t\t\tconst tooSmallIssue = issue as typeof issue & {\n\t\t\t\ttype: string;\n\t\t\t\tminimum: number;\n\t\t\t};\n\t\t\tif (tooSmallIssue.type === 'string' && tooSmallIssue.minimum === 1) {\n\t\t\t\tmessage = '不能为空';\n\t\t\t} else if (tooSmallIssue.type === 'number') {\n\t\t\t\tmessage = `至少需要 ${tooSmallIssue.minimum}`;\n\t\t\t} else if (tooSmallIssue.type === 'array') {\n\t\t\t\tmessage = `至少需要 ${tooSmallIssue.minimum} 项`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'too_big': {\n\t\t\tconst tooBigIssue = issue as typeof issue & {\n\t\t\t\ttype: string;\n\t\t\t\tmaximum: number;\n\t\t\t};\n\t\t\tif (tooBigIssue.type === 'string') {\n\t\t\t\tmessage = `最多 ${tooBigIssue.maximum} 个字符`;\n\t\t\t} else if (tooBigIssue.type === 'number') {\n\t\t\t\tmessage = `最多 ${tooBigIssue.maximum}`;\n\t\t\t} else if (tooBigIssue.type === 'array') {\n\t\t\t\tmessage = `最多 ${tooBigIssue.maximum} 项`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_enum_value': {\n\t\t\tconst enumIssue = issue as typeof issue & {\n\t\t\t\toptions: readonly unknown[];\n\t\t\t};\n\t\t\tmessage = `必须是以下值之一: ${enumIssue.options?.map(String).join(', ') || '未知选项'}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'unrecognized_keys': {\n\t\t\tconst unrecognizedIssue = issue as typeof issue & {\n\t\t\t\tkeys: readonly string[];\n\t\t\t};\n\t\t\tmessage = `不支持的字段: ${unrecognizedIssue.keys?.join(', ') || '未知字段'}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_union': {\n\t\t\tmessage = '不符合任何允许的类型';\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_union_discriminator': {\n\t\t\tconst discriminatorIssue = issue as typeof issue & {\n\t\t\t\toptions: readonly unknown[];\n\t\t\t};\n\t\t\tmessage = `必须是以下值之一: ${discriminatorIssue.options?.map(String).join(', ') || '未知选项'}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_literal': {\n\t\t\tconst literalIssue = issue as typeof issue & {\n\t\t\t\texpected: unknown;\n\t\t\t};\n\t\t\tmessage = `必须是 ${String(literalIssue.expected)}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'custom': {\n\t\t\t// 保留自定义错误消息\n\t\t\tmessage = issue.message;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\t// 保留原始消息\n\t\t\tmessage = issue.message;\n\t}\n\n\treturn message;\n}\n\nfunction formatPath(path: (string | number)[]): string {\n\tif (path.length === 0) {\n\t\treturn '表单';\n\t}\n\treturn path.map(String).join('.');\n}\n"],"names":["findJsonSchemaByPath","formatZodError","error","schema","issues","length","message","messages","issue","formatted","formatIssueMessage","path","map","p","String","fieldName","formatPath","fieldPath","join","fieldSchema","description","push","code","invalidTypeIssue","received","expected","invalidStringIssue","validation","tooSmallIssue","type","minimum","tooBigIssue","maximum","enumIssue","options","unrecognizedIssue","keys","discriminatorIssue","literalIssue"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/schema/formatZodError.ts"],"sourcesContent":["import type { core, ZodError } from 'zod/v4';\nimport { findJsonSchemaByPath } from './findJsonSchemaByPath';\nimport type { TypeSchema } from './TypeSchema';\n\n// Zod 4 issue types with proper typing\ntype ZodIssue = core.$ZodIssue;\ntype ZodIssueInvalidType = core.$ZodIssueInvalidType;\ntype ZodIssueTooSmall = core.$ZodIssueTooSmall;\ntype ZodIssueTooBig = core.$ZodIssueTooBig;\ntype ZodIssueInvalidStringFormat = core.$ZodIssueInvalidStringFormat;\ntype ZodIssueInvalidValue = core.$ZodIssueInvalidValue;\ntype ZodIssueUnrecognizedKeys = core.$ZodIssueUnrecognizedKeys;\n\nexport function formatZodError(error: ZodError, schema?: TypeSchema): string {\n\tif (!error.issues || error.issues.length === 0) {\n\t\treturn error.message || '验证失败';\n\t}\n\n\tconst messages: string[] = [];\n\n\t// Iterate through issues and format each one\n\t// We use manual iteration instead of error.format() to have better control\n\t// over field name formatting with schema descriptions\n\tfor (const issue of error.issues) {\n\t\tconst formatted = formatIssueMessage(issue, schema);\n\t\tif (formatted) {\n\t\t\tconst path = issue.path.map((p) => (typeof p === 'symbol' ? String(p) : p)) as (string | number)[];\n\t\t\tlet fieldName = formatPath(path);\n\n\t\t\t// Try to get field description from schema\n\t\t\tif (schema && path.length > 0) {\n\t\t\t\tconst fieldPath = path.map(String).join('.');\n\t\t\t\tconst fieldSchema = findJsonSchemaByPath(schema, fieldPath);\n\t\t\t\tif (fieldSchema?.description) {\n\t\t\t\t\tfieldName = fieldSchema.description;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmessages.push(`${fieldName}: ${formatted}`);\n\t\t}\n\t}\n\n\treturn messages.join(';');\n}\n\nfunction formatIssueMessage(issue: ZodIssue, _schema?: TypeSchema): string {\n\tlet message = issue.message;\n\n\t// 处理常见的错误类型,生成更友好的消息\n\tswitch (issue.code) {\n\t\tcase 'invalid_type': {\n\t\t\tconst i = issue as ZodIssueInvalidType;\n\t\t\t// Zod v4 doesn't have 'received' field directly, extract from message\n\t\t\tconst match = issue.message.match(/received (\\w+)/);\n\t\t\tconst received = match?.[1];\n\t\t\tif (received === 'undefined') {\n\t\t\t\tmessage = '必填';\n\t\t\t} else if (received === 'null') {\n\t\t\t\tmessage = '不能为空';\n\t\t\t} else {\n\t\t\t\tmessage = issue.message || `期望类型 ${i.expected},但收到 ${received}`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_format': {\n\t\t\tconst i = issue as ZodIssueInvalidStringFormat;\n\t\t\tif (i.format === 'email') {\n\t\t\t\tmessage = '请输入有效的邮箱地址';\n\t\t\t} else if (i.format === 'url') {\n\t\t\t\tmessage = '请输入有效的 URL';\n\t\t\t} else if (i.format === 'uuid') {\n\t\t\t\tmessage = '请输入有效的 UUID';\n\t\t\t} else if (i.format === 'date') {\n\t\t\t\tmessage = '请输入有效的日期';\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'too_small': {\n\t\t\tconst i = issue as ZodIssueTooSmall;\n\t\t\tif (i.origin === 'string' && i.minimum === 1) {\n\t\t\t\tmessage = '不能为空';\n\t\t\t} else if (i.origin === 'string') {\n\t\t\t\tmessage = `至少需要 ${i.minimum} 个字符`;\n\t\t\t} else if (i.origin === 'number' || i.origin === 'int') {\n\t\t\t\tmessage = `至少需要 ${i.minimum}`;\n\t\t\t} else if (i.origin === 'array') {\n\t\t\t\tmessage = `至少需要 ${i.minimum} 项`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'too_big': {\n\t\t\tconst i = issue as ZodIssueTooBig;\n\t\t\tif (i.origin === 'string') {\n\t\t\t\tmessage = `最多 ${i.maximum} 个字符`;\n\t\t\t} else if (i.origin === 'number' || i.origin === 'int') {\n\t\t\t\tmessage = `最多 ${i.maximum}`;\n\t\t\t} else if (i.origin === 'array') {\n\t\t\t\tmessage = `最多 ${i.maximum} 项`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_value': {\n\t\t\tconst i = issue as ZodIssueInvalidValue;\n\t\t\tif (i.values.length === 1) {\n\t\t\t\t// Single value means it's a literal check\n\t\t\t\tmessage = `必须是 ${String(i.values[0])}`;\n\t\t\t} else {\n\t\t\t\tmessage = `必须是以下值之一: ${i.values.map(String).join(', ')}`;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase 'unrecognized_keys': {\n\t\t\tconst i = issue as ZodIssueUnrecognizedKeys;\n\t\t\tmessage = `不支持的字段: ${i.keys.join(', ')}`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'invalid_union': {\n\t\t\tmessage = '不符合任何允许的类型';\n\t\t\tbreak;\n\t\t}\n\t\tcase 'custom': {\n\t\t\t// 保留自定义错误消息\n\t\t\tmessage = issue.message;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\t// 保留原始消息\n\t\t\tmessage = issue.message;\n\t}\n\n\treturn message;\n}\n\nfunction formatPath(path: (string | number)[]): string {\n\tif (path.length === 0) {\n\t\treturn '表单';\n\t}\n\treturn path.map(String).join('.');\n}\n"],"names":["findJsonSchemaByPath","formatZodError","error","schema","issues","length","message","messages","issue","formatted","formatIssueMessage","path","map","p","String","fieldName","formatPath","fieldPath","join","fieldSchema","description","push","_schema","code","i","match","received","expected","format","origin","minimum","maximum","values","keys"],"mappings":"AACA,SAASA,oBAAoB,QAAQ,yBAAyB;AAY9D,OAAO,SAASC,eAAeC,KAAe,EAAEC,MAAmB;IAClE,IAAI,CAACD,MAAME,MAAM,IAAIF,MAAME,MAAM,CAACC,MAAM,KAAK,GAAG;QAC/C,OAAOH,MAAMI,OAAO,IAAI;IACzB;IAEA,MAAMC,WAAqB,EAAE;IAE7B,6CAA6C;IAC7C,2EAA2E;IAC3E,sDAAsD;IACtD,KAAK,MAAMC,SAASN,MAAME,MAAM,CAAE;QACjC,MAAMK,YAAYC,mBAAmBF,OAAOL;QAC5C,IAAIM,WAAW;YACd,MAAME,OAAOH,MAAMG,IAAI,CAACC,GAAG,CAAC,CAACC,IAAO,OAAOA,MAAM,WAAWC,OAAOD,KAAKA;YACxE,IAAIE,YAAYC,WAAWL;YAE3B,2CAA2C;YAC3C,IAAIR,UAAUQ,KAAKN,MAAM,GAAG,GAAG;gBAC9B,MAAMY,YAAYN,KAAKC,GAAG,CAACE,QAAQI,IAAI,CAAC;gBACxC,MAAMC,cAAcnB,qBAAqBG,QAAQc;gBACjD,IAAIE,aAAaC,aAAa;oBAC7BL,YAAYI,YAAYC,WAAW;gBACpC;YACD;YAEAb,SAASc,IAAI,CAAC,GAAGN,UAAU,EAAE,EAAEN,WAAW;QAC3C;IACD;IAEA,OAAOF,SAASW,IAAI,CAAC;AACtB;AAEA,SAASR,mBAAmBF,KAAe,EAAEc,OAAoB;IAChE,IAAIhB,UAAUE,MAAMF,OAAO;IAE3B,qBAAqB;IACrB,OAAQE,MAAMe,IAAI;QACjB,KAAK;YAAgB;gBACpB,MAAMC,IAAIhB;gBACV,sEAAsE;gBACtE,MAAMiB,QAAQjB,MAAMF,OAAO,CAACmB,KAAK,CAAC;gBAClC,MAAMC,WAAWD,OAAO,CAAC,EAAE;gBAC3B,IAAIC,aAAa,aAAa;oBAC7BpB,UAAU;gBACX,OAAO,IAAIoB,aAAa,QAAQ;oBAC/BpB,UAAU;gBACX,OAAO;oBACNA,UAAUE,MAAMF,OAAO,IAAI,CAAC,KAAK,EAAEkB,EAAEG,QAAQ,CAAC,KAAK,EAAED,UAAU;gBAChE;gBACA;YACD;QACA,KAAK;YAAkB;gBACtB,MAAMF,IAAIhB;gBACV,IAAIgB,EAAEI,MAAM,KAAK,SAAS;oBACzBtB,UAAU;gBACX,OAAO,IAAIkB,EAAEI,MAAM,KAAK,OAAO;oBAC9BtB,UAAU;gBACX,OAAO,IAAIkB,EAAEI,MAAM,KAAK,QAAQ;oBAC/BtB,UAAU;gBACX,OAAO,IAAIkB,EAAEI,MAAM,KAAK,QAAQ;oBAC/BtB,UAAU;gBACX;gBACA;YACD;QACA,KAAK;YAAa;gBACjB,MAAMkB,IAAIhB;gBACV,IAAIgB,EAAEK,MAAM,KAAK,YAAYL,EAAEM,OAAO,KAAK,GAAG;oBAC7CxB,UAAU;gBACX,OAAO,IAAIkB,EAAEK,MAAM,KAAK,UAAU;oBACjCvB,UAAU,CAAC,KAAK,EAAEkB,EAAEM,OAAO,CAAC,IAAI,CAAC;gBAClC,OAAO,IAAIN,EAAEK,MAAM,KAAK,YAAYL,EAAEK,MAAM,KAAK,OAAO;oBACvDvB,UAAU,CAAC,KAAK,EAAEkB,EAAEM,OAAO,EAAE;gBAC9B,OAAO,IAAIN,EAAEK,MAAM,KAAK,SAAS;oBAChCvB,UAAU,CAAC,KAAK,EAAEkB,EAAEM,OAAO,CAAC,EAAE,CAAC;gBAChC;gBACA;YACD;QACA,KAAK;YAAW;gBACf,MAAMN,IAAIhB;gBACV,IAAIgB,EAAEK,MAAM,KAAK,UAAU;oBAC1BvB,UAAU,CAAC,GAAG,EAAEkB,EAAEO,OAAO,CAAC,IAAI,CAAC;gBAChC,OAAO,IAAIP,EAAEK,MAAM,KAAK,YAAYL,EAAEK,MAAM,KAAK,OAAO;oBACvDvB,UAAU,CAAC,GAAG,EAAEkB,EAAEO,OAAO,EAAE;gBAC5B,OAAO,IAAIP,EAAEK,MAAM,KAAK,SAAS;oBAChCvB,UAAU,CAAC,GAAG,EAAEkB,EAAEO,OAAO,CAAC,EAAE,CAAC;gBAC9B;gBACA;YACD;QACA,KAAK;YAAiB;gBACrB,MAAMP,IAAIhB;gBACV,IAAIgB,EAAEQ,MAAM,CAAC3B,MAAM,KAAK,GAAG;oBAC1B,0CAA0C;oBAC1CC,UAAU,CAAC,IAAI,EAAEQ,OAAOU,EAAEQ,MAAM,CAAC,EAAE,GAAG;gBACvC,OAAO;oBACN1B,UAAU,CAAC,UAAU,EAAEkB,EAAEQ,MAAM,CAACpB,GAAG,CAACE,QAAQI,IAAI,CAAC,OAAO;gBACzD;gBACA;YACD;QACA,KAAK;YAAqB;gBACzB,MAAMM,IAAIhB;gBACVF,UAAU,CAAC,QAAQ,EAAEkB,EAAES,IAAI,CAACf,IAAI,CAAC,OAAO;gBACxC;YACD;QACA,KAAK;YAAiB;gBACrBZ,UAAU;gBACV;YACD;QACA,KAAK;YAAU;gBACd,YAAY;gBACZA,UAAUE,MAAMF,OAAO;gBACvB;YACD;QACA;YACC,SAAS;YACTA,UAAUE,MAAMF,OAAO;IACzB;IAEA,OAAOA;AACR;AAEA,SAASU,WAAWL,IAAyB;IAC5C,IAAIA,KAAKN,MAAM,KAAK,GAAG;QACtB,OAAO;IACR;IACA,OAAOM,KAAKC,GAAG,CAACE,QAAQI,IAAI,CAAC;AAC9B"}
@@ -36,7 +36,7 @@ export function toJsonSchema(schema) {
36
36
  }
37
37
  ]
38
38
  }, (select) => {
39
- delete js["anyOf"];
39
+ delete js.anyOf;
40
40
  Object.assign(js, select);
41
41
  js.nullable = true;
42
42
  }).otherwise((js) => {
@@ -65,7 +65,7 @@ export function toJsonSchema(schema) {
65
65
  return schema;
66
66
  }
67
67
  function visit(js, f) {
68
- const _visit = (js, f, parent, path, k) => {
68
+ const _visit = (js, f, _parent, path, _k) => {
69
69
  if (!js) {
70
70
  return;
71
71
  }
@@ -105,7 +105,7 @@ function visit(js, f) {
105
105
  };
106
106
  _visit(js, f, undefined, []);
107
107
  }
108
- function resolveJsonSchemaDef(js, ctx) {
108
+ function _resolveJsonSchemaDef(js, _ctx) {
109
109
  return match(js).with({
110
110
  anyOf: [
111
111
  P.select(),
@@ -127,7 +127,7 @@ function resolveJsonSchemaDef(js, ctx) {
127
127
  for (const key in schema.properties) {
128
128
  const prop = schema.properties[key];
129
129
  if (prop) {
130
- schema.properties[key] = resolveJsonSchemaDef(prop, {
130
+ schema.properties[key] = _resolveJsonSchemaDef(prop, {
131
131
  parent: schema,
132
132
  key
133
133
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schema/toJsonSchema.ts"],"sourcesContent":["import { omit, remove } from 'es-toolkit';\nimport { match, P } from 'ts-pattern';\nimport { z } from 'zod/v4';\nimport type { JsonSchemaDef } from '../jsonschema';\nimport { getSchemaCache } from './getSchemaCache';\nimport type { TypeSchema } from './TypeSchema';\nimport { isTypeBoxSchema, isZodSchema } from './validate';\n\nexport function toJsonSchema(schema: TypeSchema): JsonSchemaDef {\n\tif (isZodSchema(schema)) {\n\t\treturn getSchemaCache(schema, 'jsonschema', () => {\n\t\t\t// zod v4\n\t\t\tlet js = z.toJSONSchema(schema, {\n\t\t\t\tunrepresentable: 'any',\n\t\t\t\toverride: ({ zodSchema, jsonSchema: js }) => {\n\t\t\t\t\tconst def = zodSchema._zod.def;\n\t\t\t\t\tconst meta = z.globalRegistry.get(zodSchema);\n\t\t\t\t\tif (meta) {\n\t\t\t\t\t\tObject.assign(js, meta);\n\t\t\t\t\t}\n\t\t\t\t\tswitch (def.type) {\n\t\t\t\t\t\tcase 'union':\n\t\t\t\t\t\t\tif (zodSchema._zod.traits.has('ZodDiscriminatedUnion')) {\n\t\t\t\t\t\t\t\tresolveDiscriminator(js as JsonSchemaDef);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'nonoptional':\n\t\t\t\t\t\t\t// js._ref maybe true\n\t\t\t\t\t\t\tjs.nullable = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'nullable':\n\t\t\t\t\t\tcase 'optional':\n\t\t\t\t\t\t\t// prefer nullable\n\t\t\t\t\t\t\tmatch(js)\n\t\t\t\t\t\t\t\t.with({ anyOf: [P.select(), { type: 'null' }] }, (select) => {\n\t\t\t\t\t\t\t\t\tdelete js['anyOf'];\n\t\t\t\t\t\t\t\t\tObject.assign(js, select);\n\t\t\t\t\t\t\t\t\tjs.nullable = true;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.otherwise((js) => {\n\t\t\t\t\t\t\t\t\tjs.nullable = true;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}) as JsonSchemaDef;\n\n\t\t\t// remove redundant nullable, ensure required is sorted\n\t\t\tvisit(js, (v) => {\n\t\t\t\tif (v.nullable === false) {\n\t\t\t\t\tdelete v.nullable;\n\t\t\t\t}\n\t\t\t\tif (v.required) {\n\t\t\t\t\tv.required.sort();\n\t\t\t\t}\n\t\t\t});\n\t\t\t// maybe freeze\n\t\t\treturn js;\n\t\t});\n\t}\n\n\tif (isTypeBoxSchema(schema)) {\n\t\treturn schema as JsonSchemaDef;\n\t}\n\n\treturn schema as JsonSchemaDef;\n}\n\nfunction visit(js: JsonSchemaDef, f: (js: JsonSchemaDef) => void) {\n\tconst _visit = (\n\t\tjs: JsonSchemaDef,\n\t\tf: (js: JsonSchemaDef) => void,\n\t\tparent: JsonSchemaDef | undefined,\n\t\tpath: string[],\n\t\tk?: string,\n\t) => {\n\t\tif (!js) {\n\t\t\treturn;\n\t\t}\n\t\tf(js);\n\t\tif (js.properties) {\n\t\t\tfor (const [k, v] of Object.entries(js.properties)) {\n\t\t\t\tif (v) {\n\t\t\t\t\t_visit(v, f, js, path.concat(k), 'properties');\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (js.items) {\n\t\t\tif (Array.isArray(js.items)) {\n\t\t\t\tfor (const v of js.items) {\n\t\t\t\t\t_visit(v, f, js, path, 'items');\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t_visit(js.items, f, js, path, 'items');\n\t\t\t}\n\t\t} else if (js.anyOf) {\n\t\t\tfor (const v of js.anyOf) {\n\t\t\t\t_visit(v, f, js, path, 'anyOf');\n\t\t\t}\n\t\t} else if (js.oneOf) {\n\t\t\tfor (const v of js.oneOf) {\n\t\t\t\t_visit(v, f, js, path, 'oneOf');\n\t\t\t}\n\t\t} else if (js.allOf) {\n\t\t\tfor (const v of js.allOf) {\n\t\t\t\t_visit(v, f, js, path, 'allOf');\n\t\t\t}\n\t\t}\n\t};\n\t_visit(js, f, undefined, []);\n}\n\nfunction resolveJsonSchemaDef(\n\tjs: JsonSchemaDef,\n\tctx?: {\n\t\tparent: JsonSchemaDef;\n\t\tkey: string;\n\t},\n) {\n\treturn match(js)\n\t\t.with(\n\t\t\t{\n\t\t\t\tanyOf: [P.select(), { type: 'null' }],\n\t\t\t},\n\t\t\t(select) => {\n\t\t\t\treturn { ...omit(js, ['anyOf']), ...select, nullable: true };\n\t\t\t},\n\t\t)\n\t\t.with({ properties: P.nonNullable }, (schema: JsonSchemaDef) => {\n\t\t\tfor (const key in schema.properties) {\n\t\t\t\tconst prop = schema.properties[key];\n\t\t\t\tif (prop) {\n\t\t\t\t\tschema.properties[key] = resolveJsonSchemaDef(prop, { parent: schema, key });\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn schema;\n\t\t})\n\t\t.otherwise(() => {\n\t\t\treturn js;\n\t\t});\n}\n\nfunction resolveDiscriminator(jsd: JsonSchemaDef) {\n\tif (!(jsd.anyOf && jsd.anyOf.length > 1)) {\n\t\treturn;\n\t}\n\tif (jsd.discriminator) {\n\t\treturn;\n\t}\n\n\tlet names: string[] = [];\n\t{\n\t\t// candidate for discriminator\n\t\tconst v = jsd.anyOf[0];\n\t\tif (v && v.type === 'object' && v.properties) {\n\t\t\tif (Array.isArray(v.required)) {\n\t\t\t\tfor (const k of v.required) {\n\t\t\t\t\tif (v.properties[k].const !== undefined) {\n\t\t\t\t\t\tnames.push(k);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (names.length >= 1) {\n\t\tfor (let i = 0; i < jsd.anyOf.length; i++) {\n\t\t\tif (i === 0) {\n\t\t\t\t// skip first\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!names.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst v = jsd.anyOf[i];\n\t\t\tif (v && v.type === 'object' && v.properties) {\n\t\t\t\tconst props = v.properties;\n\t\t\t\tremove(names, (k) => {\n\t\t\t\t\t// dont care the mapping\n\t\t\t\t\tlet p = props[k];\n\t\t\t\t\tswitch (typeof p.const) {\n\t\t\t\t\t\tcase 'string':\n\t\t\t\t\t\tcase 'number':\n\t\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnames = [];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif (names.length === 1) {\n\t\tjsd.discriminator = {\n\t\t\tpropertyName: names[0],\n\t\t};\n\t}\n}\n"],"names":["omit","remove","match","P","z","getSchemaCache","isTypeBoxSchema","isZodSchema","toJsonSchema","schema","js","toJSONSchema","unrepresentable","override","zodSchema","jsonSchema","def","_zod","meta","globalRegistry","get","Object","assign","type","traits","has","resolveDiscriminator","nullable","with","anyOf","select","otherwise","visit","v","required","sort","f","_visit","parent","path","k","properties","entries","concat","items","Array","isArray","oneOf","allOf","undefined","resolveJsonSchemaDef","ctx","nonNullable","key","prop","jsd","length","discriminator","names","const","push","i","props","p","propertyName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/schema/toJsonSchema.ts"],"sourcesContent":["import { omit, remove } from 'es-toolkit';\nimport { match, P } from 'ts-pattern';\nimport { z } from 'zod/v4';\nimport type { JsonSchemaDef } from '../jsonschema';\nimport { getSchemaCache } from './getSchemaCache';\nimport type { TypeSchema } from './TypeSchema';\nimport { isTypeBoxSchema, isZodSchema } from './validate';\n\nexport function toJsonSchema(schema: TypeSchema): JsonSchemaDef {\n\tif (isZodSchema(schema)) {\n\t\treturn getSchemaCache(schema, 'jsonschema', () => {\n\t\t\t// zod v4\n\t\t\tlet js = z.toJSONSchema(schema, {\n\t\t\t\tunrepresentable: 'any',\n\t\t\t\toverride: ({ zodSchema, jsonSchema: js }) => {\n\t\t\t\t\tconst def = zodSchema._zod.def;\n\t\t\t\t\tconst meta = z.globalRegistry.get(zodSchema);\n\t\t\t\t\tif (meta) {\n\t\t\t\t\t\tObject.assign(js, meta);\n\t\t\t\t\t}\n\t\t\t\t\tswitch (def.type) {\n\t\t\t\t\t\tcase 'union':\n\t\t\t\t\t\t\tif (zodSchema._zod.traits.has('ZodDiscriminatedUnion')) {\n\t\t\t\t\t\t\t\tresolveDiscriminator(js as JsonSchemaDef);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'nonoptional':\n\t\t\t\t\t\t\t// js._ref maybe true\n\t\t\t\t\t\t\tjs.nullable = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'nullable':\n\t\t\t\t\t\tcase 'optional':\n\t\t\t\t\t\t\t// prefer nullable\n\t\t\t\t\t\t\tmatch(js)\n\t\t\t\t\t\t\t\t.with({ anyOf: [P.select(), { type: 'null' }] }, (select) => {\n\t\t\t\t\t\t\t\t\tdelete js.anyOf;\n\t\t\t\t\t\t\t\t\tObject.assign(js, select);\n\t\t\t\t\t\t\t\t\tjs.nullable = true;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.otherwise((js) => {\n\t\t\t\t\t\t\t\t\tjs.nullable = true;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}) as JsonSchemaDef;\n\n\t\t\t// remove redundant nullable, ensure required is sorted\n\t\t\tvisit(js, (v) => {\n\t\t\t\tif (v.nullable === false) {\n\t\t\t\t\tdelete v.nullable;\n\t\t\t\t}\n\t\t\t\tif (v.required) {\n\t\t\t\t\tv.required.sort();\n\t\t\t\t}\n\t\t\t});\n\t\t\t// maybe freeze\n\t\t\treturn js;\n\t\t});\n\t}\n\n\tif (isTypeBoxSchema(schema)) {\n\t\treturn schema as JsonSchemaDef;\n\t}\n\n\treturn schema as JsonSchemaDef;\n}\n\nfunction visit(js: JsonSchemaDef, f: (js: JsonSchemaDef) => void) {\n\tconst _visit = (\n\t\tjs: JsonSchemaDef,\n\t\tf: (js: JsonSchemaDef) => void,\n\t\t_parent: JsonSchemaDef | undefined,\n\t\tpath: string[],\n\t\t_k?: string,\n\t) => {\n\t\tif (!js) {\n\t\t\treturn;\n\t\t}\n\t\tf(js);\n\t\tif (js.properties) {\n\t\t\tfor (const [k, v] of Object.entries(js.properties)) {\n\t\t\t\tif (v) {\n\t\t\t\t\t_visit(v, f, js, path.concat(k), 'properties');\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (js.items) {\n\t\t\tif (Array.isArray(js.items)) {\n\t\t\t\tfor (const v of js.items) {\n\t\t\t\t\t_visit(v, f, js, path, 'items');\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t_visit(js.items, f, js, path, 'items');\n\t\t\t}\n\t\t} else if (js.anyOf) {\n\t\t\tfor (const v of js.anyOf) {\n\t\t\t\t_visit(v, f, js, path, 'anyOf');\n\t\t\t}\n\t\t} else if (js.oneOf) {\n\t\t\tfor (const v of js.oneOf) {\n\t\t\t\t_visit(v, f, js, path, 'oneOf');\n\t\t\t}\n\t\t} else if (js.allOf) {\n\t\t\tfor (const v of js.allOf) {\n\t\t\t\t_visit(v, f, js, path, 'allOf');\n\t\t\t}\n\t\t}\n\t};\n\t_visit(js, f, undefined, []);\n}\n\nfunction _resolveJsonSchemaDef(\n\tjs: JsonSchemaDef,\n\t_ctx?: {\n\t\tparent: JsonSchemaDef;\n\t\tkey: string;\n\t},\n) {\n\treturn match(js)\n\t\t.with(\n\t\t\t{\n\t\t\t\tanyOf: [P.select(), { type: 'null' }],\n\t\t\t},\n\t\t\t(select) => {\n\t\t\t\treturn { ...omit(js, ['anyOf']), ...select, nullable: true };\n\t\t\t},\n\t\t)\n\t\t.with({ properties: P.nonNullable }, (schema: JsonSchemaDef) => {\n\t\t\tfor (const key in schema.properties) {\n\t\t\t\tconst prop = schema.properties[key];\n\t\t\t\tif (prop) {\n\t\t\t\t\tschema.properties[key] = _resolveJsonSchemaDef(prop, { parent: schema, key });\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn schema;\n\t\t})\n\t\t.otherwise(() => {\n\t\t\treturn js;\n\t\t});\n}\n\nfunction resolveDiscriminator(jsd: JsonSchemaDef) {\n\tif (!(jsd.anyOf && jsd.anyOf.length > 1)) {\n\t\treturn;\n\t}\n\tif (jsd.discriminator) {\n\t\treturn;\n\t}\n\n\tlet names: string[] = [];\n\t{\n\t\t// candidate for discriminator\n\t\tconst v = jsd.anyOf[0];\n\t\tif (v && v.type === 'object' && v.properties) {\n\t\t\tif (Array.isArray(v.required)) {\n\t\t\t\tfor (const k of v.required) {\n\t\t\t\t\tif (v.properties[k].const !== undefined) {\n\t\t\t\t\t\tnames.push(k);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (names.length >= 1) {\n\t\tfor (let i = 0; i < jsd.anyOf.length; i++) {\n\t\t\tif (i === 0) {\n\t\t\t\t// skip first\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!names.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst v = jsd.anyOf[i];\n\t\t\tif (v && v.type === 'object' && v.properties) {\n\t\t\t\tconst props = v.properties;\n\t\t\t\tremove(names, (k) => {\n\t\t\t\t\t// dont care the mapping\n\t\t\t\t\tlet p = props[k];\n\t\t\t\t\tswitch (typeof p.const) {\n\t\t\t\t\t\tcase 'string':\n\t\t\t\t\t\tcase 'number':\n\t\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnames = [];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif (names.length === 1) {\n\t\tjsd.discriminator = {\n\t\t\tpropertyName: names[0],\n\t\t};\n\t}\n}\n"],"names":["omit","remove","match","P","z","getSchemaCache","isTypeBoxSchema","isZodSchema","toJsonSchema","schema","js","toJSONSchema","unrepresentable","override","zodSchema","jsonSchema","def","_zod","meta","globalRegistry","get","Object","assign","type","traits","has","resolveDiscriminator","nullable","with","anyOf","select","otherwise","visit","v","required","sort","f","_visit","_parent","path","_k","properties","k","entries","concat","items","Array","isArray","oneOf","allOf","undefined","_resolveJsonSchemaDef","_ctx","nonNullable","key","prop","parent","jsd","length","discriminator","names","const","push","i","props","p","propertyName"],"mappings":"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"}
@@ -95,7 +95,7 @@ export function parseData(schema, data) {
95
95
  issues: result.issues
96
96
  });
97
97
  }
98
- function formatIssues(schema, issues) {
98
+ function _formatIssues(_schema, _issues) {
99
99
  return '';
100
100
  }
101
101
  export function isZodSchema(schema) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schema/validate.ts"],"sourcesContent":["import { Kind as TypeBoxKind, type TSchema } from '@sinclair/typebox';\nimport '@sinclair/typebox';\nimport { TypeCompiler } from '@sinclair/typebox/compiler';\nimport { ifPresent } from '@wener/utils';\nimport { Ajv } from 'ajv';\nimport addFormats from 'ajv-formats';\nimport type { ZodType } from 'zod/v4';\nimport type { JsonSchemaDef } from '../jsonschema';\nimport type { SchemaOutput, TypeSchema } from './TypeSchema';\n\n/*\nhttps://github.com/react-hook-form/resolvers\nhttps://github.com/decs/typeschema/tree/main/packages\n*/\n\nexport function validate<S extends TypeSchema>(schema: S, data: unknown): ValidationResult<SchemaOutput<S>> {\n\tif (isZodSchema(schema)) {\n\t\tconst result = schema.safeParse(data);\n\t\tif (result.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: result.data as any,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tissues: result.error.issues.map(({ message, path, code }) => ({ message, path, code })),\n\t\t\t// message: z.prettifyError(result.error),\n\t\t\tsuccess: false,\n\t\t};\n\t}\n\n\tif (isTypeBoxSchema(schema)) {\n\t\tconst checker = TypeCompiler.Compile(schema);\n\t\tif (checker.Check(data)) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: data as any,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tissues: Array.from(checker.Errors(data)).map(({ message, path }) => {\n\t\t\t\treturn { message, path: [path] };\n\t\t\t}),\n\t\t\t// message: '',\n\t\t\tsuccess: false,\n\t\t};\n\t}\n\n\tif (isJsonSchema(schema)) {\n\t\tconst ajv = new Ajv({\n\t\t\tallErrors: true,\n\t\t\tvalidateSchema: true,\n\t\t});\n\t\taddFormats(ajv);\n\t\tconst validator = ajv.compile(schema);\n\t\tif (validator(data)) {\n\t\t\treturn {\n\t\t\t\tdata: data as any,\n\t\t\t\tsuccess: true,\n\t\t\t};\n\t\t}\n\n\t\tconst issues =\n\t\t\tvalidator.errors?.map((error) => {\n\t\t\t\tconst message = error.message || 'Unknown error';\n\t\t\t\tconst path = error.instancePath\n\t\t\t\t\t.split('/')\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t.map((p) => p as PropertyKey);\n\t\t\t\treturn { message, path };\n\t\t\t}) || [];\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\t// message: 'Invalid data',\n\t\t\tissues,\n\t\t};\n\t}\n\n\treturn {\n\t\tsuccess: false,\n\t\t// message: 'Invalid schema',\n\t\tissues: [\n\t\t\t{\n\t\t\t\tmessage: 'Unknown schema type',\n\t\t\t},\n\t\t],\n\t};\n}\n\nexport function parseData<S extends TypeSchema>(schema: S, data: unknown): SchemaOutput<S> {\n\tlet result = validate(schema, data);\n\tif (result.success) {\n\t\treturn result.data;\n\t}\n\tthrow Object.assign(\n\t\tnew Error(\n\t\t\tresult.issues\n\t\t\t\t.map((v) => {\n\t\t\t\t\treturn `${ifPresent(v.path?.join(), (v) => `[${v}]`)}: ${v.message}`;\n\t\t\t\t})\n\t\t\t\t.join('; '),\n\t\t),\n\t\t{\n\t\t\tissues: result.issues,\n\t\t},\n\t);\n}\n\nfunction formatIssues(schema: TypeSchema, issues: Array<ValidationIssue>): string {\n\treturn '';\n}\n\nexport function isZodSchema<I = any, O = any>(schema: any | TypeSchema<I, O>): schema is ZodType<O, I> {\n\treturn typeof schema === 'object' && 'parse' in schema;\n}\n\nexport function isTypeBoxSchema(schema: any): schema is TSchema {\n\treturn typeof schema === 'object' && TypeBoxKind in schema;\n}\n\nexport function isJsonSchema(schema: any): schema is JsonSchemaDef {\n\tlet sc: JsonSchemaDef = schema;\n\treturn typeof schema === 'object' && Boolean(sc.type || sc.properties || sc.anyOf || sc.oneOf || sc.$ref || sc.items);\n}\n\nexport type ValidationIssue = {\n\tmessage: string;\n\tpath?: Array<PropertyKey>;\n\tcode?: string;\n};\n\nexport type ValidationResult<TOutput> =\n\t| { success: true; data: TOutput }\n\t| { success: false; issues: Array<ValidationIssue> };\n"],"names":["Kind","TypeBoxKind","TypeCompiler","ifPresent","Ajv","addFormats","validate","schema","data","isZodSchema","result","safeParse","success","issues","error","map","message","path","code","isTypeBoxSchema","checker","Compile","Check","Array","from","Errors","isJsonSchema","ajv","allErrors","validateSchema","validator","compile","errors","instancePath","split","filter","Boolean","p","parseData","Object","assign","Error","v","join","formatIssues","sc","type","properties","anyOf","oneOf","$ref","items"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/schema/validate.ts"],"sourcesContent":["import { Kind as TypeBoxKind, type TSchema } from '@sinclair/typebox';\nimport '@sinclair/typebox';\nimport { TypeCompiler } from '@sinclair/typebox/compiler';\nimport { ifPresent } from '@wener/utils';\nimport { Ajv } from 'ajv';\nimport addFormats from 'ajv-formats';\nimport type { ZodType } from 'zod/v4';\nimport type { JsonSchemaDef } from '../jsonschema';\nimport type { SchemaOutput, TypeSchema } from './TypeSchema';\n\n/*\nhttps://github.com/react-hook-form/resolvers\nhttps://github.com/decs/typeschema/tree/main/packages\n*/\n\nexport function validate<S extends TypeSchema>(schema: S, data: unknown): ValidationResult<SchemaOutput<S>> {\n\tif (isZodSchema(schema)) {\n\t\tconst result = schema.safeParse(data);\n\t\tif (result.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: result.data as any,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tissues: result.error.issues.map(({ message, path, code }) => ({ message, path, code })),\n\t\t\t// message: z.prettifyError(result.error),\n\t\t\tsuccess: false,\n\t\t};\n\t}\n\n\tif (isTypeBoxSchema(schema)) {\n\t\tconst checker = TypeCompiler.Compile(schema);\n\t\tif (checker.Check(data)) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: data as any,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tissues: Array.from(checker.Errors(data)).map(({ message, path }) => {\n\t\t\t\treturn { message, path: [path] };\n\t\t\t}),\n\t\t\t// message: '',\n\t\t\tsuccess: false,\n\t\t};\n\t}\n\n\tif (isJsonSchema(schema)) {\n\t\tconst ajv = new Ajv({\n\t\t\tallErrors: true,\n\t\t\tvalidateSchema: true,\n\t\t});\n\t\taddFormats(ajv);\n\t\tconst validator = ajv.compile(schema);\n\t\tif (validator(data)) {\n\t\t\treturn {\n\t\t\t\tdata: data as any,\n\t\t\t\tsuccess: true,\n\t\t\t};\n\t\t}\n\n\t\tconst issues =\n\t\t\tvalidator.errors?.map((error) => {\n\t\t\t\tconst message = error.message || 'Unknown error';\n\t\t\t\tconst path = error.instancePath\n\t\t\t\t\t.split('/')\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t.map((p) => p as PropertyKey);\n\t\t\t\treturn { message, path };\n\t\t\t}) || [];\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\t// message: 'Invalid data',\n\t\t\tissues,\n\t\t};\n\t}\n\n\treturn {\n\t\tsuccess: false,\n\t\t// message: 'Invalid schema',\n\t\tissues: [\n\t\t\t{\n\t\t\t\tmessage: 'Unknown schema type',\n\t\t\t},\n\t\t],\n\t};\n}\n\nexport function parseData<S extends TypeSchema>(schema: S, data: unknown): SchemaOutput<S> {\n\tlet result = validate(schema, data);\n\tif (result.success) {\n\t\treturn result.data;\n\t}\n\tthrow Object.assign(\n\t\tnew Error(\n\t\t\tresult.issues\n\t\t\t\t.map((v) => {\n\t\t\t\t\treturn `${ifPresent(v.path?.join(), (v) => `[${v}]`)}: ${v.message}`;\n\t\t\t\t})\n\t\t\t\t.join('; '),\n\t\t),\n\t\t{\n\t\t\tissues: result.issues,\n\t\t},\n\t);\n}\n\nfunction _formatIssues(_schema: TypeSchema, _issues: Array<ValidationIssue>): string {\n\treturn '';\n}\n\nexport function isZodSchema<I = any, O = any>(schema: any | TypeSchema<I, O>): schema is ZodType<O, I> {\n\treturn typeof schema === 'object' && 'parse' in schema;\n}\n\nexport function isTypeBoxSchema(schema: any): schema is TSchema {\n\treturn typeof schema === 'object' && TypeBoxKind in schema;\n}\n\nexport function isJsonSchema(schema: any): schema is JsonSchemaDef {\n\tlet sc: JsonSchemaDef = schema;\n\treturn typeof schema === 'object' && Boolean(sc.type || sc.properties || sc.anyOf || sc.oneOf || sc.$ref || sc.items);\n}\n\nexport type ValidationIssue = {\n\tmessage: string;\n\tpath?: Array<PropertyKey>;\n\tcode?: string;\n};\n\nexport type ValidationResult<TOutput> =\n\t| { success: true; data: TOutput }\n\t| { success: false; issues: Array<ValidationIssue> };\n"],"names":["Kind","TypeBoxKind","TypeCompiler","ifPresent","Ajv","addFormats","validate","schema","data","isZodSchema","result","safeParse","success","issues","error","map","message","path","code","isTypeBoxSchema","checker","Compile","Check","Array","from","Errors","isJsonSchema","ajv","allErrors","validateSchema","validator","compile","errors","instancePath","split","filter","Boolean","p","parseData","Object","assign","Error","v","join","_formatIssues","_schema","_issues","sc","type","properties","anyOf","oneOf","$ref","items"],"mappings":"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"}
@@ -44,7 +44,7 @@ export function buildRedactorFormSchema(ts, { shouldRedact = (schema) => schema[
44
44
  return root;
45
45
  };
46
46
  }
47
- function buildReversibleRedactText({ id, type, key, timestamp } = {}) {
47
+ function _buildReversibleRedactText({ id, type: _type, key: _key, timestamp } = {}) {
48
48
  if (!id) {
49
49
  return RedactedText;
50
50
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/buildRedactorFormSchema.ts"],"sourcesContent":["import { forEachJsonSchema, type JsonSchemaDef } from '../jsonschema';\nimport { toJsonSchema, type TypeSchema } from '../schema';\n\nexport const RedactedText = '[redacted]';\n\nexport function buildRedactorFormSchema(\n\tts: TypeSchema,\n\t{\n\t\tshouldRedact = (schema) => schema['x-sensitive'] === true,\n\t\treplacer = () => RedactedText,\n\t}: {\n\t\tshouldRedact?: (schema: JsonSchemaDef) => boolean;\n\t\treplacer?: (key: string, value: any) => any;\n\t},\n) {\n\tlet js = toJsonSchema(ts);\n\n\tlet paths: string[][] = [];\n\n\tforEachJsonSchema(js, (js, { path }) => {\n\t\tif (shouldRedact(js)) {\n\t\t\tpaths.push(path);\n\t\t}\n\t});\n\tconst vis = (root: any, path: string[]) => {\n\t\tswitch (root) {\n\t\t\tcase null:\n\t\t\tcase undefined:\n\t\t\t\treturn;\n\t\t}\n\n\t\tlet c = root;\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tlet k = path[i];\n\t\t\tif (c && typeof c === 'object' && k in c) {\n\t\t\t\tlet v = c[k];\n\t\t\t\tif (path.length === 1) {\n\t\t\t\t\tc[k] = replacer(k, v);\n\t\t\t\t} else if (Array.isArray(v)) {\n\t\t\t\t\tfor (let vv of v) {\n\t\t\t\t\t\tvis(vv, path.slice(i + 1));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvis(v, path.slice(i + 1));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\treturn (root: any) => {\n\t\tif (!paths.length) {\n\t\t\treturn root;\n\t\t}\n\n\t\tpaths.forEach((path) => {\n\t\t\tvis(root, path);\n\t\t});\n\n\t\treturn root;\n\t};\n}\n\nfunction buildReversibleRedactText({\n\tid,\n\ttype,\n\tkey,\n\ttimestamp,\n}: {\n\tid?: string | number;\n\ttype?: string;\n\tkey?: string;\n\ttimestamp?: number | boolean;\n} = {}) {\n\tif (!id) {\n\t\treturn RedactedText;\n\t}\n\tif (timestamp === true) {\n\t\ttimestamp = Date.now();\n\t}\n\treturn `[redacted ${id}]`;\n}\n\nexport function isRedactedText(v: any) {\n\treturn v === RedactedText || (typeof v === 'string' && v.startsWith('[redacted ') && v.endsWith(']'));\n}\n"],"names":["forEachJsonSchema","toJsonSchema","RedactedText","buildRedactorFormSchema","ts","shouldRedact","schema","replacer","js","paths","path","push","vis","root","undefined","c","i","length","k","v","Array","isArray","vv","slice","forEach","buildReversibleRedactText","id","type","key","timestamp","Date","now","isRedactedText","startsWith","endsWith"],"mappings":"AAAA,SAASA,iBAAiB,QAA4B,gBAAgB;AACtE,SAASC,YAAY,QAAyB,YAAY;AAE1D,OAAO,MAAMC,eAAe,aAAa;AAEzC,OAAO,SAASC,wBACfC,EAAc,EACd,EACCC,eAAe,CAACC,SAAWA,MAAM,CAAC,cAAc,KAAK,IAAI,EACzDC,WAAW,IAAML,YAAY,EAI7B;IAED,IAAIM,KAAKP,aAAaG;IAEtB,IAAIK,QAAoB,EAAE;IAE1BT,kBAAkBQ,IAAI,CAACA,IAAI,EAAEE,IAAI,EAAE;QAClC,IAAIL,aAAaG,KAAK;YACrBC,MAAME,IAAI,CAACD;QACZ;IACD;IACA,MAAME,MAAM,CAACC,MAAWH;QACvB,OAAQG;YACP,KAAK;YACL,KAAKC;gBACJ;QACF;QAEA,IAAIC,IAAIF;QACR,IAAK,IAAIG,IAAI,GAAGA,IAAIN,KAAKO,MAAM,EAAED,IAAK;YACrC,IAAIE,IAAIR,IAAI,CAACM,EAAE;YACf,IAAID,KAAK,OAAOA,MAAM,YAAYG,KAAKH,GAAG;gBACzC,IAAII,IAAIJ,CAAC,CAACG,EAAE;gBACZ,IAAIR,KAAKO,MAAM,KAAK,GAAG;oBACtBF,CAAC,CAACG,EAAE,GAAGX,SAASW,GAAGC;gBACpB,OAAO,IAAIC,MAAMC,OAAO,CAACF,IAAI;oBAC5B,KAAK,IAAIG,MAAMH,EAAG;wBACjBP,IAAIU,IAAIZ,KAAKa,KAAK,CAACP,IAAI;oBACxB;gBACD,OAAO;oBACNJ,IAAIO,GAAGT,KAAKa,KAAK,CAACP,IAAI;gBACvB;YACD;QACD;IACD;IAEA,OAAO,CAACH;QACP,IAAI,CAACJ,MAAMQ,MAAM,EAAE;YAClB,OAAOJ;QACR;QAEAJ,MAAMe,OAAO,CAAC,CAACd;YACdE,IAAIC,MAAMH;QACX;QAEA,OAAOG;IACR;AACD;AAEA,SAASY,0BAA0B,EAClCC,EAAE,EACFC,IAAI,EACJC,GAAG,EACHC,SAAS,EAMT,GAAG,CAAC,CAAC;IACL,IAAI,CAACH,IAAI;QACR,OAAOxB;IACR;IACA,IAAI2B,cAAc,MAAM;QACvBA,YAAYC,KAAKC,GAAG;IACrB;IACA,OAAO,CAAC,UAAU,EAAEL,GAAG,CAAC,CAAC;AAC1B;AAEA,OAAO,SAASM,eAAeb,CAAM;IACpC,OAAOA,MAAMjB,gBAAiB,OAAOiB,MAAM,YAAYA,EAAEc,UAAU,CAAC,iBAAiBd,EAAEe,QAAQ,CAAC;AACjG"}
1
+ {"version":3,"sources":["../../src/utils/buildRedactorFormSchema.ts"],"sourcesContent":["import { forEachJsonSchema, type JsonSchemaDef } from '../jsonschema';\nimport { toJsonSchema, type TypeSchema } from '../schema';\n\nexport const RedactedText = '[redacted]';\n\nexport function buildRedactorFormSchema(\n\tts: TypeSchema,\n\t{\n\t\tshouldRedact = (schema) => schema['x-sensitive'] === true,\n\t\treplacer = () => RedactedText,\n\t}: {\n\t\tshouldRedact?: (schema: JsonSchemaDef) => boolean;\n\t\treplacer?: (key: string, value: any) => any;\n\t},\n) {\n\tlet js = toJsonSchema(ts);\n\n\tlet paths: string[][] = [];\n\n\tforEachJsonSchema(js, (js, { path }) => {\n\t\tif (shouldRedact(js)) {\n\t\t\tpaths.push(path);\n\t\t}\n\t});\n\tconst vis = (root: any, path: string[]) => {\n\t\tswitch (root) {\n\t\t\tcase null:\n\t\t\tcase undefined:\n\t\t\t\treturn;\n\t\t}\n\n\t\tlet c = root;\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tlet k = path[i];\n\t\t\tif (c && typeof c === 'object' && k in c) {\n\t\t\t\tlet v = c[k];\n\t\t\t\tif (path.length === 1) {\n\t\t\t\t\tc[k] = replacer(k, v);\n\t\t\t\t} else if (Array.isArray(v)) {\n\t\t\t\t\tfor (let vv of v) {\n\t\t\t\t\t\tvis(vv, path.slice(i + 1));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvis(v, path.slice(i + 1));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\treturn (root: any) => {\n\t\tif (!paths.length) {\n\t\t\treturn root;\n\t\t}\n\n\t\tpaths.forEach((path) => {\n\t\t\tvis(root, path);\n\t\t});\n\n\t\treturn root;\n\t};\n}\n\nfunction _buildReversibleRedactText({\n\tid,\n\ttype: _type,\n\tkey: _key,\n\ttimestamp,\n}: {\n\tid?: string | number;\n\ttype?: string;\n\tkey?: string;\n\ttimestamp?: number | boolean;\n} = {}) {\n\tif (!id) {\n\t\treturn RedactedText;\n\t}\n\tif (timestamp === true) {\n\t\ttimestamp = Date.now();\n\t}\n\treturn `[redacted ${id}]`;\n}\n\nexport function isRedactedText(v: any) {\n\treturn v === RedactedText || (typeof v === 'string' && v.startsWith('[redacted ') && v.endsWith(']'));\n}\n"],"names":["forEachJsonSchema","toJsonSchema","RedactedText","buildRedactorFormSchema","ts","shouldRedact","schema","replacer","js","paths","path","push","vis","root","undefined","c","i","length","k","v","Array","isArray","vv","slice","forEach","_buildReversibleRedactText","id","type","_type","key","_key","timestamp","Date","now","isRedactedText","startsWith","endsWith"],"mappings":"AAAA,SAASA,iBAAiB,QAA4B,gBAAgB;AACtE,SAASC,YAAY,QAAyB,YAAY;AAE1D,OAAO,MAAMC,eAAe,aAAa;AAEzC,OAAO,SAASC,wBACfC,EAAc,EACd,EACCC,eAAe,CAACC,SAAWA,MAAM,CAAC,cAAc,KAAK,IAAI,EACzDC,WAAW,IAAML,YAAY,EAI7B;IAED,IAAIM,KAAKP,aAAaG;IAEtB,IAAIK,QAAoB,EAAE;IAE1BT,kBAAkBQ,IAAI,CAACA,IAAI,EAAEE,IAAI,EAAE;QAClC,IAAIL,aAAaG,KAAK;YACrBC,MAAME,IAAI,CAACD;QACZ;IACD;IACA,MAAME,MAAM,CAACC,MAAWH;QACvB,OAAQG;YACP,KAAK;YACL,KAAKC;gBACJ;QACF;QAEA,IAAIC,IAAIF;QACR,IAAK,IAAIG,IAAI,GAAGA,IAAIN,KAAKO,MAAM,EAAED,IAAK;YACrC,IAAIE,IAAIR,IAAI,CAACM,EAAE;YACf,IAAID,KAAK,OAAOA,MAAM,YAAYG,KAAKH,GAAG;gBACzC,IAAII,IAAIJ,CAAC,CAACG,EAAE;gBACZ,IAAIR,KAAKO,MAAM,KAAK,GAAG;oBACtBF,CAAC,CAACG,EAAE,GAAGX,SAASW,GAAGC;gBACpB,OAAO,IAAIC,MAAMC,OAAO,CAACF,IAAI;oBAC5B,KAAK,IAAIG,MAAMH,EAAG;wBACjBP,IAAIU,IAAIZ,KAAKa,KAAK,CAACP,IAAI;oBACxB;gBACD,OAAO;oBACNJ,IAAIO,GAAGT,KAAKa,KAAK,CAACP,IAAI;gBACvB;YACD;QACD;IACD;IAEA,OAAO,CAACH;QACP,IAAI,CAACJ,MAAMQ,MAAM,EAAE;YAClB,OAAOJ;QACR;QAEAJ,MAAMe,OAAO,CAAC,CAACd;YACdE,IAAIC,MAAMH;QACX;QAEA,OAAOG;IACR;AACD;AAEA,SAASY,2BAA2B,EACnCC,EAAE,EACFC,MAAMC,KAAK,EACXC,KAAKC,IAAI,EACTC,SAAS,EAMT,GAAG,CAAC,CAAC;IACL,IAAI,CAACL,IAAI;QACR,OAAOxB;IACR;IACA,IAAI6B,cAAc,MAAM;QACvBA,YAAYC,KAAKC,GAAG;IACrB;IACA,OAAO,CAAC,UAAU,EAAEP,GAAG,CAAC,CAAC;AAC1B;AAEA,OAAO,SAASQ,eAAef,CAAM;IACpC,OAAOA,MAAMjB,gBAAiB,OAAOiB,MAAM,YAAYA,EAAEgB,UAAU,CAAC,iBAAiBhB,EAAEiB,QAAQ,CAAC;AACjG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wener/common",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "type": "module",
5
5
  "description": "Common utils for console & server",
6
6
  "repository": {
@@ -36,26 +36,38 @@
36
36
  "types": "./src/decimal/index.ts",
37
37
  "default": "./lib/decimal/index.js"
38
38
  },
39
+ "./drain3": {
40
+ "types": "./src/drain3/index.ts",
41
+ "default": "./lib/drain3/index.js"
42
+ },
39
43
  "./fs": {
40
44
  "types": "./src/fs/index.ts",
41
45
  "default": "./lib/fs/index.js"
42
46
  },
43
- "./fs/orpc": {
44
- "types": "./src/fs/orpc/index.ts",
45
- "default": "./lib/fs/orpc/index.js"
47
+ "./fs/webdav": {
48
+ "types": "./src/fs/webdav/index.ts",
49
+ "default": "./lib/fs/webdav/index.js"
46
50
  },
47
- "./fs/orpc/server": {
48
- "types": "./src/fs/orpc/server/index.ts",
49
- "default": "./lib/fs/orpc/server/index.js"
50
- },
51
- "./fs/s3": {
51
+ "./fs/s3mini": {
52
52
  "types": "./src/fs/s3/index.ts",
53
53
  "default": "./lib/fs/s3/index.js"
54
54
  },
55
+ "./fs/minio": {
56
+ "types": "./src/fs/minio/index.ts",
57
+ "default": "./lib/fs/minio/index.js"
58
+ },
55
59
  "./fs/server": {
56
60
  "types": "./src/fs/server/index.ts",
57
61
  "default": "./lib/fs/server/index.js"
58
62
  },
63
+ "./fs/orpc": {
64
+ "types": "./src/fs/orpc/index.ts",
65
+ "default": "./lib/fs/orpc/index.js"
66
+ },
67
+ "./fs/orpc/server": {
68
+ "types": "./src/fs/orpc/server/index.ts",
69
+ "default": "./lib/fs/orpc/server/index.js"
70
+ },
59
71
  "./jsonschema": {
60
72
  "types": "./src/jsonschema/index.ts",
61
73
  "default": "./lib/jsonschema/index.js"
@@ -109,18 +121,23 @@
109
121
  "@standard-schema/spec": "^1.1.0",
110
122
  "@wener/utils": "^1.1.58",
111
123
  "date-fns": "^4.1.0",
112
- "es-toolkit": "^1.43.0",
124
+ "es-toolkit": "^1.44.0",
113
125
  "std-env": "^3.10.0",
114
126
  "ts-pattern": "^5.9.0"
115
127
  },
116
128
  "devDependencies": {
129
+ "@mikro-orm/better-sqlite": "^6.6.6",
130
+ "@mikro-orm/core": "^6.6.6",
131
+ "@mikro-orm/knex": "^6.6.6",
117
132
  "@orpc/client": "^1.13.4",
118
133
  "@orpc/contract": "^1.13.4",
119
134
  "@orpc/openapi-client": "^1.13.4",
120
- "@sinclair/typebox": "^0.34.47",
135
+ "@orpc/server": "^1.13.4",
136
+ "@sinclair/typebox": "^0.34.48",
121
137
  "@sinclair/typebox-codegen": "^0.11.1",
122
138
  "@types/argon2-browser": "^1.18.4",
123
139
  "@types/bcrypt": "^6.0.0",
140
+ "@types/better-sqlite3": "^7.6.13",
124
141
  "@types/micromatch": "^4.0.10",
125
142
  "@types/mime-types": "^3.0.1",
126
143
  "ajv-formats": "^3.0.1",
@@ -137,9 +154,11 @@
137
154
  "emittery": "^1.2.0",
138
155
  "micromatch": "^4.0.8",
139
156
  "mime-types": "^3.0.2",
157
+ "minio": "^8.0.6",
140
158
  "pathe": "^2.0.3",
141
- "s3mini": "^0.8.1",
142
- "zod": "^4.3.5"
159
+ "s3mini": "^0.9.1",
160
+ "webdav": "^5.8.0",
161
+ "zod": "^4.3.6"
143
162
  },
144
163
  "scripts": {
145
164
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -2,7 +2,7 @@
2
2
  type Bbox2d = [number, number, number, number];
3
3
  type Dimensions = { width: number; height: number };
4
4
  // x_center, y_center, z_center, x_size, y_size, z_size, roll, pitch, yaw
5
- type Bbox3d = [number, number, number, number, number, number, number, number, number];
5
+ type _Bbox3d = [number, number, number, number, number, number, number, number, number];
6
6
  /**
7
7
  * Convert Qwen3V format bbox (0-1000 range) to absolute pixel coordinates
8
8
  * @param dimensions Image dimensions {width, height}
@@ -32,7 +32,7 @@ export function parseChineseResidentIdNo(idNo: string): ParsedChineseResidentIdN
32
32
  addressCode: division,
33
33
  birthDate: `${year}-${month}-${day}`,
34
34
  sequence: seq,
35
- checkDigit: checkDigit.toUpperCase() === 'X' ? 10 : parseInt(checkDigit),
35
+ checkDigit: checkDigit.toUpperCase() === 'X' ? 10 : parseInt(checkDigit, 10),
36
36
  sex: seq % 2 === 0 ? SexType.Male : SexType.Female,
37
37
  age: new Date().getFullYear() - parseInt(year, 10),
38
38
  valid: Mod11.validate(idNo),
package/src/cn/Mod11.ts CHANGED
@@ -12,7 +12,7 @@ export class Mod11Checksum {
12
12
  const { weights } = this;
13
13
  let sum = 0;
14
14
  for (let i = 0; i < s.length; i++) {
15
- sum += parseInt(s[i]) * weights[i];
15
+ sum += parseInt(s[i], 10) * weights[i];
16
16
  }
17
17
  const num = (12 - (sum % 11)) % 11;
18
18
  if (num < 10) {
@@ -3,7 +3,7 @@
3
3
  exports[`ChineseResidentIdNo > should parse 1`] = `
4
4
  {
5
5
  "addressCode": "110105",
6
- "age": 76,
6
+ "age": 77,
7
7
  "birthDate": "1949-12-31",
8
8
  "checkDigit": 10,
9
9
  "raw": "11010519491231002X",
@@ -45,26 +45,3 @@ exports[`UnifiedSocialCreditCode > should parse 2`] = `
45
45
  "valid": true,
46
46
  }
47
47
  `;
48
-
49
- exports[`UnifiedSocialCreditCode > should parse 3`] = `
50
- {
51
- "adminDivisionCode": "310120",
52
- "checkDigit": "0",
53
- "codes": [
54
- "9",
55
- "1",
56
- "310120",
57
- "MAEXK9GG9",
58
- "0",
59
- ],
60
- "entityCategoryCode": "1",
61
- "names": [
62
- "工商",
63
- "企业",
64
- ],
65
- "organizationCode": "MAEXK9GG9",
66
- "raw": "91310120MAEXK9GG90",
67
- "registrationAuthorityCode": "9",
68
- "valid": false,
69
- }
70
- `;
@@ -36,7 +36,7 @@ test('parseChineseNumber', () => {
36
36
 
37
37
  function formatChineseNumber(v: number): string {
38
38
  if (v < 0) {
39
- return '负' + formatChineseNumber(-v);
39
+ return `负${formatChineseNumber(-v)}`;
40
40
  }
41
41
 
42
42
  // 数字对应的中文表示
@@ -88,7 +88,7 @@ function formatChineseNumber(v: number): string {
88
88
  export function formatChineseAmount0(amount: number): string {
89
89
  // 检查金额是否合理
90
90
  if (amount < 0) {
91
- return '(负)' + formatChineseAmount0(-amount);
91
+ return `(负)${formatChineseAmount0(-amount)}`;
92
92
  }
93
93
  // 大写数字和单位
94
94
  const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
@@ -111,10 +111,10 @@ export function formatChineseAmount0(amount: number): string {
111
111
  integerAmount = Math.floor(integerAmount / 100); // 转为元为单位
112
112
 
113
113
  if (fen > 0) {
114
- result = digits[fen] + '分' + result;
114
+ result = `${digits[fen]}分${result}`;
115
115
  }
116
116
  if (jiao > 0) {
117
- result = digits[jiao] + '角' + result;
117
+ result = `${digits[jiao]}角${result}`;
118
118
  }
119
119
  if (cents === 0) {
120
120
  result += '整';
@@ -90,7 +90,7 @@ export function formatLogObject(
90
90
  }
91
91
 
92
92
  if (type === 'trace') {
93
- const _err = new Error('Trace: ' + o.message);
93
+ const _err = new Error(`Trace: ${o.message}`);
94
94
  line += formatStack(_err.stack || '', _err.message);
95
95
  }
96
96
  }
@@ -139,11 +139,11 @@ function parseStack(stack: string, message: string) {
139
139
  function formatStack(stack: string, message: string, opts?: FormatOptions) {
140
140
  const indent = ' '.repeat((opts?.errorLevel || 0) + 1);
141
141
  return (
142
- `\n${indent}`
143
- + parseStack(stack, message)
142
+ `\n${indent}` +
143
+ parseStack(stack, message)
144
144
  .map(
145
145
  (line) =>
146
- ' ' + line.replace(/^at +/, (m) => colors.gray(m)).replace(/\((.+)\)/, (_, m) => `(${colors.cyan(m)})`),
146
+ ` ${line.replace(/^at +/, (m) => colors.gray(m)).replace(/\((.+)\)/, (_, m) => `(${colors.cyan(m)})`)}`,
147
147
  )
148
148
  .join(`\n${indent}`)
149
149
  );
@@ -201,7 +201,7 @@ function formatError(err: any, opts: FormatOptions): string {
201
201
 
202
202
  const level = opts?.errorLevel || 0;
203
203
  const causedPrefix = level > 0 ? `${' '.repeat(level)}[cause]: ` : '';
204
- const causedError = err.cause ? '\n\n' + formatError(err.cause, { ...opts, errorLevel: level + 1 }) : '';
204
+ const causedError = err.cause ? `\n\n${formatError(err.cause, { ...opts, errorLevel: level + 1 })}` : '';
205
205
 
206
- return causedPrefix + message + '\n' + stack + causedError;
206
+ return `${causedPrefix + message}\n${stack}${causedError}`;
207
207
  }
@@ -20,7 +20,7 @@ export function maybeNumber(v: MaybeNumber) {
20
20
  }
21
21
  }
22
22
  const n = Number(v);
23
- if (isNaN(n)) {
23
+ if (Number.isNaN(n)) {
24
24
  return undefined;
25
25
  }
26
26
  return n;
@@ -1,5 +1,4 @@
1
1
  import { describe, expect, test } from 'vitest';
2
- import { formatSort } from './formatSort';
3
2
  import { parseSort } from './parseSort';
4
3
 
5
4
  describe('parseSort', () => {
@@ -25,14 +25,14 @@ export type ListQueryInput = {
25
25
  deleted?: boolean;
26
26
  };
27
27
 
28
- type ListResult<T = any> = {
28
+ type _ListResult<T = any> = {
29
29
  /** List of items */
30
30
  data: T[];
31
31
  /** Total number of items */
32
32
  total: number;
33
33
  };
34
34
 
35
- type PageInfo = {
35
+ type _PageInfo = {
36
36
  /** Whether there are more items */
37
37
  hasNextPage: boolean;
38
38
  /** Whether there are previous items */
@@ -1,5 +1,5 @@
1
- import { type OpUnitType, type UnitTypeLongPlural } from 'dayjs';
2
- import { type Duration } from 'dayjs/plugin/duration';
1
+ import type { OpUnitType, UnitTypeLongPlural } from 'dayjs';
2
+ import type { Duration } from 'dayjs/plugin/duration';
3
3
  import { parseDuration } from './parseDuration';
4
4
 
5
5
  type FormatDurationOptions = {
@@ -1,3 +1,4 @@
1
+ import { parseDate, type MaybeDate } from '@wener/utils';
1
2
  import dayjs from 'dayjs';
2
3
  import duration from 'dayjs/plugin/duration';
3
4
  import quarterOfYear from 'dayjs/plugin/quarterOfYear';
@@ -75,26 +76,22 @@ dayjs.extend(weekOfYear);
75
76
  * resolveRelativeTime('now\\d', refDate); // End of reference day
76
77
  * ```
77
78
  */
78
- export function resolveRelativeTime(s: string | Date | number, now?: Date | undefined): Date {
79
+ export function resolveRelativeTime(s: string | Date | number, now?: Date | undefined): Date;
80
+ export function resolveRelativeTime(s: MaybeDate, now?: Date | undefined): Date | undefined;
81
+ export function resolveRelativeTime(s: MaybeDate, now?: Date | undefined): Date | undefined {
79
82
  {
80
- let out: Date | undefined;
81
- if (!s) {
82
- } else if (s instanceof Date) {
83
- out = s;
84
- } else if (typeof s === 'number') {
85
- out = new Date(s);
86
- } else if (!s.startsWith('now')) {
87
- out = new Date(s);
88
- }
83
+ let out = parseDate(s);
89
84
  if (out) {
90
- if (isNaN(out.getTime())) {
91
- throw new Error(`Invalid date: ${s}`);
92
- }
93
85
  return out;
94
86
  }
87
+ if (s == null) {
88
+ return;
89
+ }
95
90
  }
96
91
 
97
- if (typeof s !== 'string' || !s.startsWith('now')) {
92
+ if (typeof s === 'string' && s.startsWith('now')) {
93
+ // valid
94
+ } else {
98
95
  throw new Error(`Invalid relative time format: ${s}`);
99
96
  }
100
97