@wener/common 1.0.5 → 2.0.2

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 (222) hide show
  1. package/lib/cn/ChineseResidentIdNo.js +41 -0
  2. package/lib/cn/ChineseResidentIdNo.mod.js +1 -0
  3. package/lib/cn/ChineseResidentIdNo.test.js +22 -0
  4. package/lib/cn/DivisionCode.js +214 -280
  5. package/lib/cn/DivisionCode.mod.js +1 -0
  6. package/lib/cn/DivisionCode.test.js +134 -0
  7. package/lib/cn/Mod11.js +86 -0
  8. package/lib/cn/Mod31.js +98 -0
  9. package/lib/cn/UnifiedSocialCreditCode.js +130 -109
  10. package/lib/cn/UnifiedSocialCreditCode.mod.js +1 -0
  11. package/lib/cn/UnifiedSocialCreditCode.test.js +16 -0
  12. package/lib/cn/index.js +1 -4
  13. package/lib/cn/mod.js +6 -0
  14. package/lib/cn/types.d.js +0 -2
  15. package/lib/consola/createStandardConsolaReporter.js +6 -6
  16. package/lib/consola/formatLogObject.js +147 -34
  17. package/lib/consola/index.js +0 -1
  18. package/lib/data/formatSort.js +5 -6
  19. package/lib/data/formatSort.test.js +34 -0
  20. package/lib/data/index.js +0 -1
  21. package/lib/data/maybeNumber.js +11 -5
  22. package/lib/data/parseSort.js +28 -22
  23. package/lib/data/parseSort.test.js +188 -0
  24. package/lib/data/resolvePagination.js +27 -16
  25. package/lib/data/resolvePagination.test.js +232 -0
  26. package/lib/data/types.d.js +0 -2
  27. package/lib/dayjs/dayjs.js +38 -0
  28. package/lib/dayjs/formatDuration.js +58 -0
  29. package/lib/dayjs/formatDuration.test.js +90 -0
  30. package/lib/dayjs/index.js +3 -0
  31. package/lib/dayjs/parseDuration.js +32 -0
  32. package/lib/decimal/index.js +1 -0
  33. package/lib/decimal/parseDecimal.js +13 -0
  34. package/lib/foundation/schema/SexType.js +14 -0
  35. package/lib/foundation/schema/index.js +1 -0
  36. package/lib/foundation/schema/parseSexType.js +18 -0
  37. package/lib/foundation/schema/types.js +5 -0
  38. package/lib/index.js +0 -1
  39. package/lib/jsonschema/JsonSchema.js +78 -52
  40. package/lib/jsonschema/JsonSchema.test.js +137 -0
  41. package/lib/jsonschema/index.js +0 -1
  42. package/lib/jsonschema/types.d.js +5 -3
  43. package/lib/meta/defineFileType.js +103 -20
  44. package/lib/meta/defineInit.js +250 -31
  45. package/lib/meta/defineMetadata.js +140 -24
  46. package/lib/meta/defineMetadata.test.js +13 -0
  47. package/lib/meta/index.js +0 -1
  48. package/lib/password/PHC.js +87 -63
  49. package/lib/password/PHC.test.js +539 -0
  50. package/lib/password/Password.js +295 -30
  51. package/lib/password/Password.test.js +362 -0
  52. package/lib/password/createArgon2PasswordAlgorithm.js +191 -35
  53. package/lib/password/createBase64PasswordAlgorithm.js +141 -8
  54. package/lib/password/createBcryptPasswordAlgorithm.js +168 -13
  55. package/lib/password/createPBKDF2PasswordAlgorithm.js +228 -46
  56. package/lib/password/createScryptPasswordAlgorithm.js +211 -55
  57. package/lib/password/index.js +0 -1
  58. package/lib/password/server/index.js +0 -1
  59. package/lib/resource/Identifiable.js +1 -0
  60. package/lib/resource/ListQuery.js +119 -0
  61. package/lib/resource/getTitleOfResource.js +10 -0
  62. package/lib/resource/index.js +2 -0
  63. package/lib/resource/schema/AnyResourceSchema.js +89 -0
  64. package/lib/resource/schema/BaseResourceSchema.js +29 -0
  65. package/lib/resource/schema/ResourceActionType.js +118 -0
  66. package/lib/resource/schema/ResourceStatus.js +93 -0
  67. package/lib/resource/schema/ResourceType.js +24 -0
  68. package/lib/resource/schema/index.js +5 -0
  69. package/lib/resource/schema/types.js +89 -0
  70. package/lib/resource/schema/types.test.js +14 -0
  71. package/lib/schema/SchemaRegistry.js +45 -0
  72. package/lib/schema/SchemaRegistry.mod.js +2 -0
  73. package/lib/schema/TypeSchema.d.js +1 -0
  74. package/lib/schema/createSchemaData.js +173 -0
  75. package/lib/schema/findJsonSchemaByPath.js +49 -0
  76. package/lib/schema/getSchemaCache.js +11 -0
  77. package/lib/schema/getSchemaOptions.js +24 -0
  78. package/lib/schema/index.js +6 -0
  79. package/lib/schema/toJsonSchema.js +441 -0
  80. package/lib/schema/toJsonSchema.test.js +27 -0
  81. package/lib/schema/validate.js +124 -0
  82. package/lib/tools/generateSchema.js +197 -39
  83. package/lib/tools/renderJsonSchemaToMarkdownDoc.js +143 -55
  84. package/lib/utils/getEstimateProcessTime.js +20 -0
  85. package/lib/utils/index.js +1 -0
  86. package/package.json +38 -17
  87. package/src/cn/ChineseResidentIdNo.mod.ts +7 -0
  88. package/src/cn/ChineseResidentIdNo.test.ts +18 -0
  89. package/src/cn/ChineseResidentIdNo.ts +66 -0
  90. package/src/cn/DivisionCode.mod.ts +7 -0
  91. package/src/cn/DivisionCode.test.ts +3 -13
  92. package/src/cn/DivisionCode.ts +132 -195
  93. package/src/cn/{Mod11Checksum.ts → Mod11.ts} +3 -1
  94. package/src/cn/{Mod31Checksum.ts → Mod31.ts} +2 -0
  95. package/src/cn/UnifiedSocialCreditCode.mod.ts +7 -0
  96. package/src/cn/UnifiedSocialCreditCode.test.ts +2 -2
  97. package/src/cn/UnifiedSocialCreditCode.ts +105 -125
  98. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +14 -0
  99. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +18 -12
  100. package/src/cn/index.ts +1 -3
  101. package/src/cn/mod.ts +3 -0
  102. package/src/consola/formatLogObject.ts +12 -4
  103. package/src/data/maybeNumber.ts +5 -1
  104. package/src/data/resolvePagination.test.ts +1 -1
  105. package/src/data/resolvePagination.ts +18 -7
  106. package/src/data/types.d.ts +12 -0
  107. package/src/dayjs/dayjs.ts +40 -0
  108. package/src/dayjs/formatDuration.test.ts +14 -0
  109. package/src/dayjs/formatDuration.ts +86 -0
  110. package/src/dayjs/index.ts +3 -0
  111. package/src/dayjs/parseDuration.ts +40 -0
  112. package/src/decimal/index.ts +1 -0
  113. package/src/decimal/parseDecimal.ts +16 -0
  114. package/src/foundation/schema/SexType.ts +21 -0
  115. package/src/foundation/schema/index.ts +1 -0
  116. package/src/foundation/schema/parseSexType.ts +19 -0
  117. package/src/foundation/schema/types.ts +8 -0
  118. package/src/jsonschema/JsonSchema.test.ts +17 -0
  119. package/src/jsonschema/JsonSchema.ts +2 -2
  120. package/src/jsonschema/types.d.ts +63 -12
  121. package/src/password/Password.ts +2 -2
  122. package/src/resource/Identifiable.ts +3 -0
  123. package/src/resource/ListQuery.ts +53 -0
  124. package/src/resource/getTitleOfResource.tsx +6 -0
  125. package/src/resource/index.ts +4 -0
  126. package/src/resource/schema/AnyResourceSchema.ts +113 -0
  127. package/src/resource/schema/BaseResourceSchema.ts +32 -0
  128. package/src/resource/schema/ResourceActionType.ts +123 -0
  129. package/src/resource/schema/ResourceStatus.ts +94 -0
  130. package/src/resource/schema/ResourceType.ts +25 -0
  131. package/src/resource/schema/index.ts +5 -0
  132. package/src/resource/schema/types.test.ts +18 -0
  133. package/src/resource/schema/types.ts +105 -0
  134. package/src/schema/SchemaRegistry.mod.ts +1 -0
  135. package/src/schema/SchemaRegistry.ts +46 -0
  136. package/src/schema/TypeSchema.d.ts +32 -0
  137. package/src/schema/createSchemaData.ts +81 -0
  138. package/src/schema/findJsonSchemaByPath.ts +37 -0
  139. package/src/schema/getSchemaCache.ts +21 -0
  140. package/src/schema/getSchemaOptions.ts +24 -0
  141. package/src/schema/index.ts +7 -0
  142. package/src/schema/toJsonSchema.test.ts +37 -0
  143. package/src/schema/toJsonSchema.ts +200 -0
  144. package/src/schema/validate.ts +135 -0
  145. package/src/tools/generateSchema.ts +28 -28
  146. package/src/utils/getEstimateProcessTime.ts +36 -0
  147. package/src/utils/index.ts +1 -0
  148. package/lib/cn/DivisionCode.js.map +0 -1
  149. package/lib/cn/Mod11Checksum.js +0 -42
  150. package/lib/cn/Mod11Checksum.js.map +0 -1
  151. package/lib/cn/Mod31Checksum.js +0 -48
  152. package/lib/cn/Mod31Checksum.js.map +0 -1
  153. package/lib/cn/ResidentIdentityCardNumber.js +0 -50
  154. package/lib/cn/ResidentIdentityCardNumber.js.map +0 -1
  155. package/lib/cn/UnifiedSocialCreditCode.js.map +0 -1
  156. package/lib/cn/formatDate.js +0 -15
  157. package/lib/cn/formatDate.js.map +0 -1
  158. package/lib/cn/index.js.map +0 -1
  159. package/lib/cn/parseSex.js +0 -22
  160. package/lib/cn/parseSex.js.map +0 -1
  161. package/lib/cn/types.d.js.map +0 -1
  162. package/lib/consola/createStandardConsolaReporter.js.map +0 -1
  163. package/lib/consola/formatLogObject.js.map +0 -1
  164. package/lib/consola/index.js.map +0 -1
  165. package/lib/data/formatSort.js.map +0 -1
  166. package/lib/data/index.js.map +0 -1
  167. package/lib/data/maybeNumber.js.map +0 -1
  168. package/lib/data/parseSort.js.map +0 -1
  169. package/lib/data/resolvePagination.js.map +0 -1
  170. package/lib/data/types.d.js.map +0 -1
  171. package/lib/index.js.map +0 -1
  172. package/lib/jsonschema/JsonSchema.js.map +0 -1
  173. package/lib/jsonschema/index.js.map +0 -1
  174. package/lib/jsonschema/types.d.js.map +0 -1
  175. package/lib/meta/defineFileType.js.map +0 -1
  176. package/lib/meta/defineInit.js.map +0 -1
  177. package/lib/meta/defineMetadata.js.map +0 -1
  178. package/lib/meta/index.js.map +0 -1
  179. package/lib/password/PHC.js.map +0 -1
  180. package/lib/password/Password.js.map +0 -1
  181. package/lib/password/createArgon2PasswordAlgorithm.js.map +0 -1
  182. package/lib/password/createBase64PasswordAlgorithm.js.map +0 -1
  183. package/lib/password/createBcryptPasswordAlgorithm.js.map +0 -1
  184. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +0 -1
  185. package/lib/password/createScryptPasswordAlgorithm.js.map +0 -1
  186. package/lib/password/index.js.map +0 -1
  187. package/lib/password/server/index.js.map +0 -1
  188. package/lib/search/AdvanceSearch.js +0 -10
  189. package/lib/search/AdvanceSearch.js.map +0 -1
  190. package/lib/search/formatAdvanceSearch.js +0 -64
  191. package/lib/search/formatAdvanceSearch.js.map +0 -1
  192. package/lib/search/index.js +0 -2
  193. package/lib/search/index.js.map +0 -1
  194. package/lib/search/optimizeAdvanceSearch.js +0 -89
  195. package/lib/search/optimizeAdvanceSearch.js.map +0 -1
  196. package/lib/search/parseAdvanceSearch.js +0 -20
  197. package/lib/search/parseAdvanceSearch.js.map +0 -1
  198. package/lib/search/parser.d.js +0 -3
  199. package/lib/search/parser.d.js.map +0 -1
  200. package/lib/search/parser.js +0 -3065
  201. package/lib/search/parser.js.map +0 -1
  202. package/lib/search/types.d.js +0 -3
  203. package/lib/search/types.d.js.map +0 -1
  204. package/lib/tools/generateSchema.js.map +0 -1
  205. package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +0 -1
  206. package/src/cn/ResidentIdentityCardNumber.test.ts +0 -17
  207. package/src/cn/ResidentIdentityCardNumber.ts +0 -96
  208. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +0 -15
  209. package/src/cn/formatDate.ts +0 -12
  210. package/src/cn/parseSex.ts +0 -13
  211. package/src/search/AdvanceSearch.test.ts +0 -149
  212. package/src/search/AdvanceSearch.ts +0 -14
  213. package/src/search/Makefile +0 -2
  214. package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +0 -675
  215. package/src/search/formatAdvanceSearch.ts +0 -52
  216. package/src/search/index.ts +0 -1
  217. package/src/search/optimizeAdvanceSearch.ts +0 -77
  218. package/src/search/parseAdvanceSearch.ts +0 -23
  219. package/src/search/parser.d.ts +0 -8
  220. package/src/search/parser.js +0 -2794
  221. package/src/search/parser.peggy +0 -237
  222. package/src/search/types.d.ts +0 -45
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod/v4';
2
+ import type { EnumValues } from './types';
3
+
4
+ export const ResourceStatus = Object.freeze({
5
+ __proto__: null,
6
+ Active: 'Active',
7
+ Approved: 'Approved',
8
+ Cancelled: 'Cancelled',
9
+ Closed: 'Closed',
10
+ Completed: 'Completed',
11
+ Confirmed: 'Confirmed',
12
+ Contacted: 'Contacted',
13
+ Contacting: 'Contacting',
14
+ Deleted: 'Deleted',
15
+ Denied: 'Denied',
16
+ Disabled: 'Disabled',
17
+ Disqualified: 'Disqualified',
18
+ Draft: 'Draft',
19
+ Enabled: 'Enabled',
20
+ Expired: 'Expired',
21
+ Failed: 'Failed',
22
+ InProgress: 'InProgress',
23
+ Inactive: 'Inactive',
24
+ Initial: 'Initial',
25
+ Lost: 'Lost',
26
+ New: 'New',
27
+ Nurturing: 'Nurturing',
28
+ OnHold: 'OnHold',
29
+ Open: 'Open',
30
+ Overdue: 'Overdue',
31
+ Paid: 'Paid',
32
+ PartiallyPaid: 'PartiallyPaid',
33
+ Pending: 'Pending',
34
+ PendingAcceptance: 'PendingAcceptance',
35
+ PendingApproval: 'PendingApproval',
36
+ PendingConfirmation: 'PendingConfirmation',
37
+ PendingResubmission: 'PendingResubmission',
38
+ Posted: 'Posted',
39
+ Published: 'Published',
40
+ Qualified: 'Qualified',
41
+ Rejected: 'Rejected',
42
+ Submitted: 'Submitted',
43
+ Suspended: 'Suspended',
44
+ Terminated: 'Terminated',
45
+ Unqualified: 'Unqualified',
46
+ Void: 'Void',
47
+ Won: 'Won',
48
+ } as const);
49
+ export type ResourceStatus = EnumValues<typeof ResourceStatus>;
50
+ export const ResourceStatusSchema = z
51
+ .union([
52
+ z.literal(ResourceStatus.Active).describe('活跃'),
53
+ z.literal(ResourceStatus.Approved).describe('已通过'),
54
+ z.literal(ResourceStatus.Cancelled).describe('已取消'),
55
+ z.literal(ResourceStatus.Closed).describe('已关闭'),
56
+ z.literal(ResourceStatus.Completed).describe('已完成'),
57
+ z.literal(ResourceStatus.Confirmed).describe('已确认'),
58
+ z.literal(ResourceStatus.Contacted).describe('已联系'),
59
+ z.literal(ResourceStatus.Contacting).describe('联系中'),
60
+ z.literal(ResourceStatus.Deleted).describe('已删除'),
61
+ z.literal(ResourceStatus.Denied).describe('已拒绝'),
62
+ z.literal(ResourceStatus.Disabled).describe('已禁用'),
63
+ z.literal(ResourceStatus.Disqualified).describe('不合格'),
64
+ z.literal(ResourceStatus.Draft).describe('草稿'),
65
+ z.literal(ResourceStatus.Enabled).describe('已启用'),
66
+ z.literal(ResourceStatus.Expired).describe('已过期'),
67
+ z.literal(ResourceStatus.InProgress).describe('进行中'),
68
+ z.literal(ResourceStatus.Inactive).describe('停用'),
69
+ z.literal(ResourceStatus.Initial).describe('初始'),
70
+ z.literal(ResourceStatus.Lost).describe('已失去'),
71
+ z.literal(ResourceStatus.New).describe('新建'),
72
+ z.literal(ResourceStatus.Nurturing).describe('培育中'),
73
+ z.literal(ResourceStatus.OnHold).describe('搁置'),
74
+ z.literal(ResourceStatus.Open).describe('开放'),
75
+ z.literal(ResourceStatus.Overdue).describe('逾期'),
76
+ z.literal(ResourceStatus.Paid).describe('已支付'),
77
+ z.literal(ResourceStatus.PartiallyPaid).describe('部分支付'),
78
+ z.literal(ResourceStatus.Pending).describe('待审核'),
79
+ z.literal(ResourceStatus.PendingAcceptance).describe('待接受'),
80
+ z.literal(ResourceStatus.PendingApproval).describe('待批准'),
81
+ z.literal(ResourceStatus.PendingConfirmation).describe('待确认'),
82
+ z.literal(ResourceStatus.PendingResubmission).describe('待重新提交'),
83
+ z.literal(ResourceStatus.Posted).describe('已过账'),
84
+ z.literal(ResourceStatus.Published).describe('已发布'),
85
+ z.literal(ResourceStatus.Qualified).describe('已合格'),
86
+ z.literal(ResourceStatus.Rejected).describe('已驳回'),
87
+ z.literal(ResourceStatus.Submitted).describe('已提交'),
88
+ z.literal(ResourceStatus.Suspended).describe('暂停'),
89
+ z.literal(ResourceStatus.Terminated).describe('终止'),
90
+ z.literal(ResourceStatus.Unqualified).describe('未达标'),
91
+ z.literal(ResourceStatus.Void).describe('作废'),
92
+ z.literal(ResourceStatus.Won).describe('已赢得'),
93
+ ])
94
+ .meta({ title: 'ResourceStatus', description: '资源状态', type: 'string' });
@@ -0,0 +1,25 @@
1
+ import { z } from 'zod/v4';
2
+ import type { EnumValues } from './types';
3
+
4
+ export const ResourceType = Object.freeze({
5
+ __proto__: null,
6
+ User: 'User',
7
+ Customer: 'Customer',
8
+ Contact: 'Contact',
9
+ Account: 'Account',
10
+ Order: 'Order',
11
+ Lead: 'Lead',
12
+ Opportunity: 'Opportunity',
13
+ } as const);
14
+ export type ResourceType = EnumValues<typeof ResourceType>;
15
+ export const ResourceTypeSchema = z
16
+ .union([
17
+ z.literal(ResourceType.User).describe('用户'),
18
+ z.literal(ResourceType.Customer).describe('客户'),
19
+ z.literal(ResourceType.Contact).describe('联系人'),
20
+ z.literal(ResourceType.Account).describe('账户'),
21
+ z.literal(ResourceType.Order).describe('订单'),
22
+ z.literal(ResourceType.Lead).describe('线索'),
23
+ z.literal(ResourceType.Opportunity).describe('商机'),
24
+ ])
25
+ .meta({ title: 'ResourceType', description: '资源类型', type: 'string' });
@@ -0,0 +1,5 @@
1
+ export { ResourceStatus, ResourceStatusSchema } from './ResourceStatus';
2
+ export { ResourceActionType, ResourceActionTypeSchema, ResourceActionDataSchema } from './ResourceActionType';
3
+ export { AnyResourceSchema, type AnyResource } from './AnyResourceSchema';
4
+ export { rz, type EnumValues } from './types';
5
+ export { BaseResourceSchema } from './BaseResourceSchema';
@@ -0,0 +1,18 @@
1
+ import { describe, it } from 'vitest';
2
+ import { createSchemaData, toJsonSchema } from '../../schema';
3
+ import { renderJsonSchemaToMarkdownDoc } from '../../tools/renderJsonSchemaToMarkdownDoc';
4
+ import { AnyResourceSchema } from './AnyResourceSchema';
5
+
6
+ describe('schema', () => {
7
+ it('should be convert to jsonschema', () => {
8
+ console.log(renderJsonSchemaToMarkdownDoc(toJsonSchema(AnyResourceSchema)));
9
+ });
10
+
11
+ it('should create from schema', () => {
12
+ console.log(
13
+ createSchemaData(AnyResourceSchema, {
14
+ all: true,
15
+ }),
16
+ );
17
+ });
18
+ });
@@ -0,0 +1,105 @@
1
+ import { isValid } from 'date-fns';
2
+ import dayjs from 'dayjs';
3
+ import { z } from 'zod/v4';
4
+
5
+ const TypeIdSchema = z
6
+ .string()
7
+ .regex(/^[a-zA-Z0-9]+_[a-zA-Z0-9]+$/, {
8
+ error: 'ID格式错误',
9
+ })
10
+ .describe('ID');
11
+
12
+ /*
13
+ XXX-XXX-XXXX
14
+ National: (XXX) XXX-XXXX
15
+ Human: XXX.XXX.XXXX xXXX
16
+ International: +XX (XXX) XXX-XXXX
17
+
18
+ 中国
19
+ XXX XXXX XXXX
20
+ XXX-XXXX-XXXX
21
+ XXXXXXXXXXX
22
+ +86 XXX XXXX XXXX
23
+ +86 XXXXXXXXXXX
24
+
25
+ 0XX-XXXXXXXX
26
+ 0XXX-XXXXXXXX
27
+ (0XX) XXXXXXXX
28
+ 0XX XXXX XXXX
29
+ 0XXXXXXXX
30
+
31
+ https://uibakery.io/regex-library/phone-number
32
+ https://fakerjs.dev/api/phone
33
+ */
34
+
35
+ const PhoneNumberSchema = z
36
+ .string()
37
+ .trim()
38
+ .max(20)
39
+ .regex(/(^$)|(^[0-9]*$)/, {
40
+ error: '电话号码只能包含数字',
41
+ })
42
+ .meta({
43
+ format: 'phone',
44
+ });
45
+
46
+ function resourceIdOf(entity: string) {
47
+ return rz.resourceId.meta({ 'x-ref-entity': entity });
48
+ }
49
+
50
+ // allow empty string
51
+ const JsonDateSchema = z.coerce
52
+ .string()
53
+ .trim()
54
+ .overwrite((v) => {
55
+ if (v && !/^\d{4}-\d{2}-\d{2}$/.test(v)) {
56
+ let val = dayjs(v);
57
+ if (val.isValid()) {
58
+ return val.format('YYYY-MM-DD');
59
+ }
60
+ }
61
+ return v;
62
+ })
63
+ .regex(/(^$)|(^\d{4}-\d{2}-\d{2}$)/, { error: '错误的日期格式' })
64
+ .refine((value) => !value || isValid(new Date(value)), {
65
+ error: '错误的日期',
66
+ })
67
+ .nullish()
68
+ .overwrite((v) => v || undefined)
69
+ .meta({ format: 'date' });
70
+
71
+ const JsonDateTimeSchema = z.coerce.date().meta({ format: 'date-time', type: 'string' });
72
+
73
+ const LoginNameSchema = z
74
+ .string()
75
+ .trim()
76
+ .regex(/^[a-z0-9]{3,16}$/, { error: '登录名只能包含小写字母和数字,长度为3-16位' });
77
+
78
+ // maybe check valid cjk
79
+ const FriendlyNameSchema = z
80
+ .string()
81
+ .trim()
82
+ .max(50)
83
+ .refine((v) => !/\p{C}/u.test(v), { message: '包含无效字符' })
84
+ .describe('名称');
85
+
86
+ const PasswordSchema = z
87
+ .string()
88
+ .min(6, { error: '密码长度至少 6 位' })
89
+ .max(36, { error: '密码长度最多 36 位' })
90
+ .regex(/^\S*$/, { error: '密码不能包含空格' })
91
+ .describe('密码')
92
+ .meta({ sensitive: true });
93
+
94
+ export const rz = {
95
+ resourceIdOf: resourceIdOf,
96
+ date: JsonDateSchema,
97
+ dateTime: JsonDateTimeSchema,
98
+ resourceId: TypeIdSchema,
99
+ phoneNumber: PhoneNumberSchema,
100
+ loginName: LoginNameSchema,
101
+ password: PasswordSchema,
102
+ friendlyName: FriendlyNameSchema,
103
+ } as const;
104
+
105
+ export type EnumValues<T> = T[Exclude<keyof T, '__proto__'>];
@@ -0,0 +1 @@
1
+ export * as SchemaRegistry from './SchemaRegistry';
@@ -0,0 +1,46 @@
1
+ import { getGlobalStates } from '@wener/utils';
2
+ import type { JsonSchemaDef } from '../jsonschema';
3
+ import { toJsonSchema, type SchemaOutput, type TypeSchema } from './index';
4
+
5
+ const types = getGlobalStates('@wener/common/resource/schema/SchemaRegistry', () => new Map<string, JsonSchemaDef>());
6
+
7
+ export function get(name: string): JsonSchemaDef;
8
+ export function get<S extends TypeSchema>(schema: S): JsonSchemaDef<SchemaOutput<S>>;
9
+ export function get(needle: TypeSchema | string) {
10
+ let key = getKey(needle);
11
+ let found = types.get(key);
12
+ if (found) {
13
+ return found;
14
+ } else {
15
+ if (needle && typeof needle !== 'string') {
16
+ return toJsonSchema(needle);
17
+ }
18
+ }
19
+ throw new Error(`Schema not found: ${key}`);
20
+ }
21
+
22
+ function getKey(s: TypeSchema | string) {
23
+ let key;
24
+ if (typeof s === 'string') {
25
+ key = s;
26
+ } else {
27
+ let js = toJsonSchema(s);
28
+ key = js.$id || js.title;
29
+ }
30
+ if (!key) {
31
+ throw new Error(`Schema must have $id or title`);
32
+ }
33
+ return key;
34
+ }
35
+
36
+ export function set(key: TypeSchema | string, def: TypeSchema): void;
37
+ export function set(key: TypeSchema, def?: TypeSchema): void;
38
+ export function set(key: TypeSchema | string, def?: TypeSchema) {
39
+ if (!def) {
40
+ def = key as TypeSchema;
41
+ if (!def || typeof def !== 'object') {
42
+ throw new Error(`Invalid schema definition for: ${getKey(key)}`);
43
+ }
44
+ }
45
+ types.set(getKey(key), toJsonSchema(def));
46
+ }
@@ -0,0 +1,32 @@
1
+ import type {
2
+ TSchema,
3
+ StaticDecode as TypeBoxStaticDecode,
4
+ StaticEncode as TypeBoxStaticEncode,
5
+ } from '@sinclair/typebox';
6
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
7
+ import type { z } from 'zod/v4';
8
+ import type { JsonSchemaDef } from '../jsonschema';
9
+
10
+ export type TypeSchema<I = unknown, O = I> = TSchema | z.ZodSchema<O, I> | JsonSchemaDef | StandardSchemaV1<I, O>;
11
+
12
+ export type SchemaOutput<S extends TypeSchema> =
13
+ S extends StandardSchemaV1<infer I, infer O>
14
+ ? O
15
+ : S extends z.ZodSchema<infer O, infer I>
16
+ ? O
17
+ : S extends TSchema
18
+ ? TypeBoxStaticEncode<S>
19
+ : S extends JsonSchemaDef<infer I, infer O>
20
+ ? O
21
+ : never;
22
+
23
+ export type SchemaInput<S extends TypeSchema> =
24
+ S extends StandardSchemaV1<infer I, infer O>
25
+ ? I
26
+ : S extends z.ZodSchema<infer O, infer I>
27
+ ? I
28
+ : S extends TSchema
29
+ ? TypeBoxStaticDecode<S>
30
+ : S extends JsonSchemaDef<infer I, infer O>
31
+ ? I
32
+ : never;
@@ -0,0 +1,81 @@
1
+ import { match, P } from 'ts-pattern';
2
+ import type { JsonSchemaDef } from '../jsonschema';
3
+ import { toJsonSchema } from './toJsonSchema';
4
+ import type { SchemaOutput, TypeSchema } from './TypeSchema';
5
+
6
+ export function createSchemaData<S extends TypeSchema>(
7
+ ts: S,
8
+ options: CreateSchemaDataOptions = {},
9
+ ): Partial<SchemaOutput<S>> {
10
+ const schema = toJsonSchema(ts);
11
+ return createJsonSchemaData(schema, options);
12
+ }
13
+
14
+ type CreateSchemaDataOptions = Partial<CreateOptions> & {
15
+ all?: boolean;
16
+ };
17
+
18
+ function createJsonSchemaData(schema: JsonSchemaDef, options: CreateSchemaDataOptions): any {
19
+ let skip: CreateOptions['skip'] = (s, ctx) => Boolean(!ctx.required && s.nullable);
20
+ if (options.all) {
21
+ skip = () => false;
22
+ }
23
+ if (options.skip) {
24
+ skip = options.skip;
25
+ }
26
+ return _create(
27
+ schema,
28
+ {
29
+ skip,
30
+ },
31
+ { required: false },
32
+ );
33
+ }
34
+
35
+ type CreateOptions = {
36
+ skip: (schema: JsonSchemaDef, ctx: { required: boolean }) => boolean;
37
+ };
38
+
39
+ function _create(schema: JsonSchemaDef, options: CreateOptions, ctx: { required: boolean }): any {
40
+ const { skip } = options;
41
+ if (skip(schema, ctx)) {
42
+ return schema.default;
43
+ }
44
+ if (schema.default !== undefined) {
45
+ return schema.default;
46
+ }
47
+ return match(schema as JsonSchemaDef)
48
+ .returnType<any>()
49
+ .with({ default: P.select() }, (v) => v)
50
+ .with({ const: P.nonNullable }, (v) => v.const)
51
+ .with({ anyOf: P.nonNullable }, (schema) => {
52
+ return _create(schema.anyOf[0], options, { required: false });
53
+ })
54
+ .with({ oneOf: P.nonNullable }, (schema) => {
55
+ return _create(schema.oneOf[0], options, { required: false });
56
+ })
57
+ .with({ type: 'string' }, (schema) => '')
58
+ .with({ type: P.union('number', 'integer') }, (schema) => 0)
59
+ .with({ type: 'object' }, () => {
60
+ const out: Record<string, any> = {};
61
+
62
+ let required = Array.isArray(schema.required) ? schema.required : [];
63
+ for (const [k, v] of Object.entries(schema.properties || {}) as [string, JsonSchemaDef][]) {
64
+ const value = _create(v, options, {
65
+ required: required.includes(k),
66
+ });
67
+ if (value === undefined) {
68
+ continue;
69
+ }
70
+ out[k] = value;
71
+ }
72
+
73
+ return out;
74
+ })
75
+ .with({ type: 'null' }, () => null)
76
+ .with({ type: 'boolean' }, (schema) => false)
77
+ .with({ type: 'array' }, (schema) => [])
78
+ .otherwise(() => {
79
+ return undefined;
80
+ });
81
+ }
@@ -0,0 +1,37 @@
1
+ import { firstOfMaybeArray } from '@wener/utils';
2
+ import { toJsonSchema } from './toJsonSchema';
3
+ import type { TypeSchema } from './TypeSchema';
4
+
5
+ export function findJsonSchemaByPath(schema: TypeSchema, objectPath: string) {
6
+ schema = toJsonSchema(schema);
7
+ if (!objectPath || !schema) {
8
+ return undefined;
9
+ }
10
+
11
+ const segments = objectPath.split('.');
12
+ let currentSchema = schema;
13
+
14
+ for (const segment of segments) {
15
+ // 检查当前 schema 是否是对象类型且有 properties
16
+ if (
17
+ currentSchema
18
+ && typeof currentSchema === 'object'
19
+ && currentSchema.properties
20
+ && currentSchema.properties[segment]
21
+ ) {
22
+ currentSchema = currentSchema.properties[segment];
23
+ continue;
24
+ }
25
+
26
+ if (/^\d$/.test(segment) || segment === '[]') {
27
+ if (currentSchema.items) {
28
+ currentSchema = firstOfMaybeArray(currentSchema.items);
29
+ continue;
30
+ }
31
+ }
32
+
33
+ return undefined;
34
+ }
35
+
36
+ return currentSchema;
37
+ }
@@ -0,0 +1,21 @@
1
+ import type { JsonSchemaDef } from '../jsonschema';
2
+ import type { TypeSchema } from './TypeSchema';
3
+
4
+ type SchemaCache = {
5
+ jsonschema?: JsonSchemaDef;
6
+ options?: Array<{ value: string; label: string }>;
7
+ };
8
+ const _cache = new WeakMap<any, SchemaCache>();
9
+
10
+ export function getSchemaCache<K extends keyof SchemaCache>(
11
+ obj: TypeSchema,
12
+ key: K,
13
+ compute: () => NonNullable<SchemaCache[K]>,
14
+ ): NonNullable<SchemaCache[K]> {
15
+ let c = _cache.get(obj);
16
+ if (!c) {
17
+ c = {};
18
+ _cache.set(obj, c);
19
+ }
20
+ return (c[key] ??= compute());
21
+ }
@@ -0,0 +1,24 @@
1
+ import { deepFreeze } from '@wener/utils';
2
+ import { getSchemaCache } from './getSchemaCache';
3
+ import { SchemaRegistry } from './SchemaRegistry.mod';
4
+ import type { TypeSchema } from './TypeSchema';
5
+
6
+ export function getSchemaOptions(s: TypeSchema): Array<{ value: string; label: string }> {
7
+ let js = SchemaRegistry.get(s);
8
+ return getSchemaCache(s, 'options', () => {
9
+ let out =
10
+ (js.anyOf || js.oneOf)?.map((v) => {
11
+ let value = v.const;
12
+ return {
13
+ label: String(v.description || v.title || value),
14
+ value: value ? String(value) : '',
15
+ };
16
+ }) || [];
17
+ out = deepFreeze(out);
18
+ return out;
19
+ });
20
+ }
21
+
22
+ export function getSchemaOptionLabel(schema: TypeSchema, value: string | undefined | null): string | undefined {
23
+ return getSchemaOptions(schema).find((v) => v.value === value)?.label;
24
+ }
@@ -0,0 +1,7 @@
1
+ export type * from './TypeSchema';
2
+ export { isJsonSchema, isZodSchema, isTypeBoxSchema, validate, parseData, type ValidationResult } from './validate';
3
+ export { getSchemaOptions, getSchemaOptionLabel } from './getSchemaOptions';
4
+ export { toJsonSchema } from './toJsonSchema';
5
+ export { findJsonSchemaByPath } from './findJsonSchemaByPath';
6
+ export { createSchemaData } from './createSchemaData';
7
+ export { SchemaRegistry } from './SchemaRegistry.mod';
@@ -0,0 +1,37 @@
1
+ import { inspect } from 'node:util';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { z } from 'zod/v4';
4
+ import { toJsonSchema } from './toJsonSchema';
5
+
6
+ describe('toJsonSchema', () => {
7
+ it('should handle discriminatedUnion', () => {
8
+ console.log(
9
+ inspect(
10
+ toJsonSchema(
11
+ z.discriminatedUnion('type', [
12
+ z.object({
13
+ type: z.literal('string'),
14
+ value: z.string(),
15
+ }),
16
+ z.object({
17
+ type: z.literal('number'),
18
+ value: z.number(),
19
+ }),
20
+ ]),
21
+ ),
22
+ {
23
+ depth: 10,
24
+ colors: true,
25
+ },
26
+ ),
27
+ );
28
+ });
29
+
30
+ it('should cache', () => {
31
+ let zs = z.object({
32
+ name: z.string(),
33
+ });
34
+
35
+ expect(toJsonSchema(zs)).toBe(toJsonSchema(zs));
36
+ });
37
+ });