@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
@@ -1,143 +1,123 @@
1
- import { Mod31Checksum } from './Mod31Checksum';
1
+ import { z } from 'zod/v4';
2
+ import { Mod31 } from './Mod31';
2
3
 
3
- /**
4
- * 统一社会信用代码
5
- *
6
- * - GB 11714-1997 全国组织机构代码编制规则
7
- */
8
- export namespace UnifiedSocialCreditCode {
9
- interface CodeValue {
10
- label: string;
11
- children?: Record<string, CodeValue>;
12
- }
4
+ interface CodeValue {
5
+ name: string;
6
+ children?: Record<string, CodeValue>;
7
+ }
13
8
 
14
- const CodeLabels: Record<string, CodeValue> = {
15
- 1: {
16
- label: '机构编制',
17
- children: {
18
- 1: { label: '机关' },
19
- 2: { label: '事业单位' },
20
- 3: { label: '中央编办直接管理机构编制的群众团体' },
21
- 9: { label: '其他' },
22
- },
9
+ const CodeNames: Record<string, CodeValue> = {
10
+ 1: {
11
+ name: '机构编制',
12
+ children: {
13
+ 1: { name: '机关' },
14
+ 2: { name: '事业单位' },
15
+ 3: { name: '中央编办直接管理机构编制的群众团体' },
16
+ 9: { name: '其他' },
23
17
  },
24
- 5: {
25
- label: '民政',
26
- children: {
27
- 1: { label: '社会团体' },
28
- 2: { label: '民办非企业单位' },
29
- 3: { label: '基金会' },
30
- 9: { label: '其他' },
31
- },
18
+ },
19
+ 5: {
20
+ name: '民政',
21
+ children: {
22
+ 1: { name: '社会团体' },
23
+ 2: { name: '民办非企业单位' },
24
+ 3: { name: '基金会' },
25
+ 9: { name: '其他' },
32
26
  },
33
- 9: {
34
- label: '工商',
35
- children: {
36
- 1: { label: '企业' },
37
- 2: { label: '个体工商户' },
38
- 3: { label: '农民专业合作社' },
39
- 9: { label: '其他' },
40
- },
27
+ },
28
+ 9: {
29
+ name: '工商',
30
+ children: {
31
+ 1: { name: '企业' },
32
+ 2: { name: '个体工商户' },
33
+ 3: { name: '农民专业合作社' },
34
+ 9: { name: '其他' },
41
35
  },
42
- Y: { label: '其他', children: { 1: { label: '其他' } } },
43
- };
36
+ },
37
+ Y: { name: '其他', children: { 1: { name: '其他' } } },
38
+ };
44
39
 
45
- export const pattern = /^([159][1239]|Y1)[0-9]{6}[0-9A-HJ-NP-RTUWXY]{10}$/; // 无 I O Z S V
40
+ export type ParsedUnifiedSocialCreditCode = z.infer<typeof ParsedUnifiedSocialCreditCodeSchema>;
41
+ export const ParsedUnifiedSocialCreditCodeSchema = z
42
+ .object({
43
+ raw: z.string().length(18).describe('统一社会信用代码'),
44
+ registrationAuthorityCode: z.string().length(1).describe('登记管理部门代码'),
45
+ entityCategoryCode: z.string().length(1).describe('机构类别代码'),
46
+ adminDivisionCode: z.string().length(6).describe('登记管理机关行政区划码 '),
47
+ organizationCode: z.string().length(9).describe('主体标识码/组织机构代码'),
48
+ checkDigit: z.string().length(1).describe('校验码'),
46
49
 
47
- export const Checksum = new Mod31Checksum();
50
+ codes: z.string().array().describe('代码数组'),
51
+ names: z.string().array().describe('代码名称'),
52
+ valid: z.boolean().optional().describe('是否有效'),
53
+ })
54
+ .describe('统一社会信用代码');
48
55
 
49
- export function parse(s: string): ParsedUnifiedSocialCreditCode {
50
- let bureau = s[0];
51
- let subjectType = s[1];
52
- let division = s.slice(2, 8); // 第3~8位,共6位,正确
53
- let subject = s.slice(8, 17); // 第9~17位,共9位
54
- let checksum = s.slice(17, 18); // 第18位,校验码
56
+ export const UnifiedSocialCreditCodeRegex = /^([159][1239]|Y1)[0-9]{6}[0-9A-HJ-NP-RTUWXY]{10}$/;
55
57
 
56
- const labels: string[] = [];
57
- let l1 = CodeLabels[bureau];
58
- l1 && labels.push(l1?.label);
59
- let l2 = l1?.children?.[subjectType];
60
- l2 && labels.push(l2?.label);
58
+ export function parseUnifiedSocialCreditCode(s: string): ParsedUnifiedSocialCreditCode | undefined {
59
+ if (!s || s.length !== 18) return undefined;
61
60
 
62
- return {
63
- bureau,
64
- subjectType,
65
- division,
66
- subject,
67
- checksum,
68
- codes: [bureau, subjectType, division, subject],
69
- labels,
70
- };
71
- }
61
+ const registrationAuthorityCode = s[0];
62
+ const entityCategoryCode = s[1];
63
+ const adminDivisionCode = s.slice(2, 8);
64
+ const organizationCode = s.slice(8, 17);
65
+ const checkDigit = s[17];
72
66
 
73
- export function format({
74
- bureau,
75
- subjectType,
76
- division,
77
- subject,
78
- checksum,
79
- }: {
80
- bureau: string;
81
- subjectType: string;
82
- division: string;
83
- subject: string;
84
- checksum?: string;
85
- }): string {
86
- const base = `${bureau}${subjectType}${division}${subject}`;
87
- checksum ||= Checksum.compute(base);
88
- return `${base}${checksum}`;
89
- }
67
+ const codes = [registrationAuthorityCode, entityCategoryCode, adminDivisionCode, organizationCode, checkDigit];
68
+ const names: string[] = [];
90
69
 
91
- export function next(s: string, delta: number = 1) {
92
- const sp = s.split('').map((v) => Checksum.numbers[v]);
93
- for (let i = sp.length - 1; i >= 0; i--) {
94
- if ((delta > 0 && sp[i] < 30) || (delta < 0 && sp[i] > 0)) {
95
- sp[i] += delta;
96
- break;
97
- } else if (delta > 0 && sp[i] === 30) {
98
- sp[i] = 0;
99
- } else if (delta < 0 && sp[i] === 0) {
100
- sp[i] = 30;
101
- }
70
+ const bureau = CodeNames[registrationAuthorityCode];
71
+ if (bureau) {
72
+ names.push(bureau.name);
73
+ const subject = bureau.children?.[entityCategoryCode];
74
+ if (subject) {
75
+ names.push(subject.name);
102
76
  }
103
- return sp.map((v) => Checksum.chars[v]).join('');
104
77
  }
105
- }
106
-
107
- /**
108
- * 解析后的统一社会信用代码信息
109
- */
110
- interface ParsedUnifiedSocialCreditCode {
111
- /**
112
- * @title 登记管理部门代码
113
- * 对应统一社会信用代码的第1位字符,用于标识发证机构类别(登记管理部门)。
114
- */
115
- bureau: string;
116
78
 
117
- /**
118
- * @title 机构类别代码
119
- * 对应统一社会信用代码的第2位字符,用于标识被赋码主体的类型(如企业、事业单位、社会组织等)。
120
- */
121
- subjectType: string;
122
-
123
- /**
124
- * @title 登记管理机关行政区划代码
125
- * 对应统一社会信用代码的第3至第8位字符,用于标识该主体登记机关所在的行政区划。
126
- */
127
- division: string;
128
-
129
- /**
130
- * @title 主体标识码
131
- * 对应统一社会信用代码的第9至第17位字符,用于标识特定的市场主体或法人单位。
132
- */
133
- subject: string;
79
+ return {
80
+ raw: s,
81
+ registrationAuthorityCode,
82
+ entityCategoryCode,
83
+ adminDivisionCode,
84
+ organizationCode,
85
+ checkDigit,
86
+ codes,
87
+ names,
88
+ valid: UnifiedSocialCreditCodeRegex.test(s) && Mod31.validate(s),
89
+ };
90
+ }
134
91
 
135
- /**
136
- * @title 校验码
137
- * 对应统一社会信用代码的最后一位字符,用特定算法计算,用于校验代码有效性。
138
- */
139
- checksum: string;
92
+ export function formatUnifiedSocialCreditCode({
93
+ registrationAuthorityCode,
94
+ entityCategoryCode,
95
+ adminDivisionCode,
96
+ organizationCode,
97
+ checkDigit,
98
+ }: {
99
+ registrationAuthorityCode: string;
100
+ entityCategoryCode: string;
101
+ adminDivisionCode: string;
102
+ organizationCode: string;
103
+ checkDigit?: string;
104
+ }): string {
105
+ const base = `${registrationAuthorityCode}${entityCategoryCode}${adminDivisionCode}${organizationCode}`;
106
+ checkDigit ||= Mod31.compute(base);
107
+ return `${base}${checkDigit}`;
108
+ }
140
109
 
141
- codes: string[];
142
- labels: string[];
110
+ export function next(s: string, delta: number = 1) {
111
+ const sp = s.split('').map((v) => Mod31.numbers[v]);
112
+ for (let i = sp.length - 1; i >= 0; i--) {
113
+ if ((delta > 0 && sp[i] < 30) || (delta < 0 && sp[i] > 0)) {
114
+ sp[i] += delta;
115
+ break;
116
+ } else if (delta > 0 && sp[i] === 30) {
117
+ sp[i] = 0;
118
+ } else if (delta < 0 && sp[i] === 0) {
119
+ sp[i] = 30;
120
+ }
121
+ }
122
+ return sp.map((v) => Mod31.chars[v]).join('');
143
123
  }
@@ -0,0 +1,14 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`ChineseResidentIdNo > should parse 1`] = `
4
+ {
5
+ "addressCode": "110105",
6
+ "age": 76,
7
+ "birthDate": "1949-12-31",
8
+ "checkDigit": 10,
9
+ "raw": "11010519491231002X",
10
+ "sequence": 2,
11
+ "sex": "Male",
12
+ "valid": true,
13
+ }
14
+ `;
@@ -2,40 +2,46 @@
2
2
 
3
3
  exports[`UnifiedSocialCreditCode > should parse 1`] = `
4
4
  {
5
- "bureau": "9",
6
- "checksum": "P",
5
+ "adminDivisionCode": "330106",
6
+ "checkDigit": "P",
7
7
  "codes": [
8
8
  "9",
9
9
  "1",
10
10
  "330106",
11
11
  "673959654",
12
+ "P",
12
13
  ],
13
- "division": "330106",
14
- "labels": [
14
+ "entityCategoryCode": "1",
15
+ "names": [
15
16
  "工商",
16
17
  "企业",
17
18
  ],
18
- "subject": "673959654",
19
- "subjectType": "1",
19
+ "organizationCode": "673959654",
20
+ "raw": "91330106673959654P",
21
+ "registrationAuthorityCode": "9",
22
+ "valid": true,
20
23
  }
21
24
  `;
22
25
 
23
26
  exports[`UnifiedSocialCreditCode > should parse 2`] = `
24
27
  {
25
- "bureau": "9",
26
- "checksum": "R",
28
+ "adminDivisionCode": "330106",
29
+ "checkDigit": "R",
27
30
  "codes": [
28
31
  "9",
29
32
  "1",
30
33
  "330106",
31
34
  "MA2CFLDG4",
35
+ "R",
32
36
  ],
33
- "division": "330106",
34
- "labels": [
37
+ "entityCategoryCode": "1",
38
+ "names": [
35
39
  "工商",
36
40
  "企业",
37
41
  ],
38
- "subject": "MA2CFLDG4",
39
- "subjectType": "1",
42
+ "organizationCode": "MA2CFLDG4",
43
+ "raw": "91330106MA2CFLDG4R",
44
+ "registrationAuthorityCode": "9",
45
+ "valid": true,
40
46
  }
41
47
  `;
package/src/cn/index.ts CHANGED
@@ -1,3 +1 @@
1
- export { ResidentIdentityCardNumber } from './ResidentIdentityCardNumber';
2
- export { DivisionCode } from './DivisionCode';
3
- export { UnifiedSocialCreditCode } from './UnifiedSocialCreditCode';
1
+ export { ChineseResidentIdNo, UnifiedSocialCreditCode, DivisionCode } from './mod';
package/src/cn/mod.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * as ChineseResidentIdNo from './ChineseResidentIdNo.mod';
2
+ export * as UnifiedSocialCreditCode from './UnifiedSocialCreditCode.mod';
3
+ export * as DivisionCode from './DivisionCode.mod';
@@ -1,9 +1,9 @@
1
- import colors from 'chalk';
1
+ import colors, { Chalk, type ChalkInstance } from 'chalk';
2
2
  import type { ConsolaOptions, FormatOptions, LogObject, LogType } from 'consola/core';
3
3
  import dayjs from 'dayjs';
4
4
  import { isDevelopment } from 'std-env';
5
5
 
6
- const levelColors: Record<LogType, (str: string) => string> = {
6
+ const LevelColors: Record<LogType, (str: string) => string> = {
7
7
  trace: colors.gray,
8
8
  debug: colors.cyan,
9
9
  info: colors.blueBright,
@@ -38,16 +38,24 @@ const levelShort: Record<LogType, string> = {
38
38
  };
39
39
  const start = Date.now();
40
40
 
41
+ const Colors: ChalkInstance = colors;
42
+ const NoColors = new Chalk({ level: 0 });
43
+
41
44
  export function formatLogObject(
42
45
  o: LogObject,
43
46
  ctx: {
44
47
  options: ConsolaOptions;
45
48
  },
46
49
  ) {
50
+ const shouldColor = Boolean(ctx.options?.formatOptions?.colors);
51
+
47
52
  let { date, type, tag } = o;
48
53
  type = type === 'log' ? 'info' : type;
49
-
50
- const color = levelColors[type] || colors.white;
54
+ const colors = shouldColor ? Colors : NoColors;
55
+ let color = LevelColors[type] || colors.white;
56
+ if (!shouldColor) {
57
+ color = (v) => v;
58
+ }
51
59
  const levelText = levelShort[type] || type.toUpperCase().slice(0, 4); // Get first 4 chars, consistent uppercase
52
60
 
53
61
  let line = '';
@@ -9,9 +9,13 @@ export function maybeNumber(v: MaybeNumber) {
9
9
  case 'number':
10
10
  return v;
11
11
  case 'bigint':
12
+ if (v > BigInt(Number.MAX_SAFE_INTEGER) || v < BigInt(Number.MIN_SAFE_INTEGER)) {
13
+ throw new Error(`bigint out of range`);
14
+ }
12
15
  return Number(v);
13
16
  case 'string':
14
- if (v === '') {
17
+ v = v.trim();
18
+ if (!v) {
15
19
  return undefined;
16
20
  }
17
21
  }
@@ -53,6 +53,6 @@ test(resolvePagination.name, () => {
53
53
  });
54
54
 
55
55
  test(`${resolvePagination.name} with options`, () => {
56
- expect(resolvePagination({ pageSize: '200' }, { maxPageSize: 50 })).toMatchObject({ pageSize: 50, limit: 50 });
56
+ expect(resolvePagination({ pageSize: '200' }, { maxLimit: 50 })).toMatchObject({ pageSize: 50, limit: 50 });
57
57
  expect(resolvePagination({}, { pageSize: 30 })).toMatchObject({ pageSize: 30, limit: 30 });
58
58
  });
@@ -1,5 +1,5 @@
1
1
  import { maybeFunction, type MaybeFunction } from '@wener/utils';
2
- import { clamp, mapValues, omitBy, pick } from 'es-toolkit';
2
+ import { mapValues, omitBy, pick } from 'es-toolkit';
3
3
  import { maybeNumber, type MaybeNumber } from './maybeNumber';
4
4
 
5
5
  export type PaginationInput = {
@@ -22,7 +22,8 @@ export function resolvePagination(
22
22
  page: PaginationInput,
23
23
  options: {
24
24
  pageSize?: MaybeFunction<number, [number | undefined]>;
25
- maxPageSize?: number;
25
+ maxLimit?: number;
26
+ maxOffset?: number;
26
27
  } = {},
27
28
  ): ResolvedPagination {
28
29
  let out = omitBy(
@@ -38,15 +39,23 @@ export function resolvePagination(
38
39
  if (options.pageSize) {
39
40
  pageSize = maybeFunction(options.pageSize, pageSize);
40
41
  }
41
- pageSize ??= 20;
42
- pageSize = clamp(pageSize, 1, options.maxPageSize ?? 1000);
42
+ pageSize ??= resolvePagination.pageSize;
43
43
 
44
- let { pageNumber = 1, pageIndex, limit, offset } = out;
44
+ let { pageNumber = 1, pageIndex } = out;
45
45
  // page index over page number
46
46
  pageNumber = Math.max(pageNumber, 1);
47
47
  pageIndex = Math.max(pageIndex ?? pageNumber - 1, 0);
48
- limit = Math.max(1, limit ?? pageSize);
49
- offset = Math.max(0, offset ?? pageSize * pageIndex);
48
+
49
+ let { limit = pageSize, offset = pageSize * pageIndex } = out;
50
+ limit = Math.max(1, limit);
51
+ offset = Math.max(0, offset);
52
+
53
+ if (options.maxLimit) {
54
+ limit = Math.min(limit, options.maxLimit);
55
+ }
56
+ if (options.maxOffset) {
57
+ offset = Math.min(offset, options.maxOffset);
58
+ }
50
59
 
51
60
  pageSize = limit;
52
61
  pageIndex = Math.floor(offset / pageSize);
@@ -58,3 +67,5 @@ export function resolvePagination(
58
67
  pageIndex,
59
68
  };
60
69
  }
70
+
71
+ resolvePagination.pageSize = 20;
@@ -31,3 +31,15 @@ type ListResult<T = any> = {
31
31
  /** Total number of items */
32
32
  total: number;
33
33
  };
34
+
35
+ type PageInfo = {
36
+ /** Whether there are more items */
37
+ hasNextPage: boolean;
38
+ /** Whether there are previous items */
39
+ hasPreviousPage: boolean;
40
+
41
+ // /** Start cursor */
42
+ // startCursor?: string;
43
+ // /** End cursor */
44
+ // endCursor?: string;
45
+ };
@@ -0,0 +1,40 @@
1
+ import dayjs from 'dayjs';
2
+ import advancedFormat from 'dayjs/plugin/advancedFormat';
3
+ import dayOfYear from 'dayjs/plugin/dayOfYear';
4
+ import duration from 'dayjs/plugin/duration';
5
+ import isBetween from 'dayjs/plugin/isBetween';
6
+ import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
7
+ import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
8
+ import isToday from 'dayjs/plugin/isToday';
9
+ import isTomorrow from 'dayjs/plugin/isTomorrow';
10
+ import isYesterday from 'dayjs/plugin/isYesterday';
11
+ import localeData from 'dayjs/plugin/localeData';
12
+ import objectSupport from 'dayjs/plugin/objectSupport';
13
+ import quarterOfYear from 'dayjs/plugin/quarterOfYear';
14
+ import relativeTime from 'dayjs/plugin/relativeTime';
15
+ import timezone from 'dayjs/plugin/timezone';
16
+ import toObject from 'dayjs/plugin/toObject';
17
+ import utc from 'dayjs/plugin/utc';
18
+ import 'dayjs/locale/zh-cn';
19
+ import 'dayjs/locale/zh';
20
+
21
+ dayjs.extend(advancedFormat);
22
+ dayjs.extend(dayOfYear);
23
+ dayjs.extend(duration);
24
+ dayjs.extend(isBetween);
25
+ dayjs.extend(isSameOrAfter);
26
+ dayjs.extend(isSameOrBefore);
27
+ dayjs.extend(isToday);
28
+ dayjs.extend(isTomorrow);
29
+ dayjs.extend(isYesterday);
30
+ dayjs.extend(localeData);
31
+ dayjs.extend(objectSupport);
32
+ dayjs.extend(quarterOfYear);
33
+ dayjs.extend(relativeTime);
34
+ dayjs.extend(timezone);
35
+ dayjs.extend(toObject);
36
+ dayjs.extend(utc);
37
+ dayjs.locale('zh-cn');
38
+ dayjs.tz.setDefault('Asia/Shanghai');
39
+
40
+ export { dayjs };
@@ -0,0 +1,14 @@
1
+ import { expect, test } from 'vitest';
2
+ import { formatDuration } from './formatDuration';
3
+
4
+ test('formatDuration', () => {
5
+ for (const [a, b] of [
6
+ [0, '0ms'],
7
+ [1000, '1s'],
8
+ [1000 * 60, '1m'],
9
+ [1000 * 60 + 1000, '1m1s'],
10
+ [1000 * 60 + 1000 + 1, '1m1s1ms'],
11
+ ]) {
12
+ expect(formatDuration(a)).toBe(b);
13
+ }
14
+ });
@@ -0,0 +1,86 @@
1
+ import { type OpUnitType, type UnitTypeLongPlural } from 'dayjs';
2
+ import { type Duration } from 'dayjs/plugin/duration';
3
+ import { parseDuration } from './parseDuration';
4
+
5
+ type FormatDurationOptions = {
6
+ humanize?: boolean;
7
+ format?: string | 'human' | 'humanize' | 'iso' | 'auto';
8
+ iso?: boolean;
9
+ };
10
+
11
+ export type MaybeDuration =
12
+ | number
13
+ | string
14
+ | Duration
15
+ | Partial<{
16
+ [unit in Exclude<UnitTypeLongPlural, 'dates'> | 'weeks']: number;
17
+ }>
18
+ | {
19
+ value: number;
20
+ unit?: Exclude<OpUnitType, 'date' | 'dates'>;
21
+ }
22
+ | undefined
23
+ | null;
24
+
25
+ export function formatDuration(value: MaybeDuration, o?: FormatDurationOptions): string | undefined {
26
+ const v = parseDuration(value);
27
+ if (v === undefined || v === null) {
28
+ return;
29
+ }
30
+
31
+ let { format, humanize, iso } = o || {};
32
+ // Use local variables instead of modifying o directly
33
+ switch (format) {
34
+ case 'human':
35
+ case 'humanize':
36
+ humanize = true;
37
+ format = undefined;
38
+ break;
39
+ case 'iso':
40
+ iso = true;
41
+ format = undefined;
42
+ break;
43
+ case 'auto':
44
+ format = undefined;
45
+ break;
46
+ }
47
+
48
+ if (humanize) {
49
+ return v.humanize();
50
+ }
51
+ if (iso) {
52
+ return v.toISOString();
53
+ }
54
+ if (format) {
55
+ return v.format(format);
56
+ }
57
+
58
+ // auto format
59
+ // 1h2m3s
60
+ if (v.asDays() > 1) {
61
+ let s = v.toISOString();
62
+ return s.replace('P', '').replace('T', '').toLowerCase();
63
+ }
64
+
65
+ {
66
+ let parts: string[] = [];
67
+ let h = v.hours();
68
+ let m = v.minutes();
69
+ let s = v.seconds();
70
+ let ms = v.milliseconds();
71
+
72
+ if (h > 0) {
73
+ parts.push(`${h}h`);
74
+ }
75
+ if (m > 0) {
76
+ parts.push(`${m}m`);
77
+ }
78
+ if (s > 0) {
79
+ parts.push(`${s}s`);
80
+ }
81
+ if (ms > 0 || (h === 0 && m === 0 && s === 0)) {
82
+ parts.push(`${ms}ms`);
83
+ }
84
+ return parts.join('');
85
+ }
86
+ }
@@ -0,0 +1,3 @@
1
+ export { dayjs } from './dayjs';
2
+ export { parseDuration } from './parseDuration';
3
+ export { formatDuration } from './formatDuration';
@@ -0,0 +1,40 @@
1
+ import type { OpUnitType, UnitTypeLongPlural } from 'dayjs';
2
+ import type { Duration } from 'dayjs/plugin/duration';
3
+ import { dayjs } from './dayjs';
4
+
5
+ export type MaybeDuration =
6
+ | number
7
+ | string
8
+ | Duration
9
+ | Partial<{
10
+ [unit in Exclude<UnitTypeLongPlural, 'dates'> | 'weeks']: number;
11
+ }>
12
+ | {
13
+ value: number;
14
+ unit?: Exclude<OpUnitType, 'date' | 'dates'>;
15
+ }
16
+ | undefined
17
+ | null;
18
+
19
+ export function parseDuration(value: MaybeDuration): Duration | undefined {
20
+ if (!value && value !== 0) {
21
+ return;
22
+ }
23
+ let duration: Duration;
24
+ if (typeof value === 'number') {
25
+ duration = dayjs.duration(value);
26
+ } else if (typeof value === 'string' && value.startsWith('P')) {
27
+ // PT0S
28
+ duration = dayjs.duration(value);
29
+ } else if (typeof value === 'object' && 'value' in value) {
30
+ duration = dayjs.duration(value.value, value.unit);
31
+ } else if (dayjs.isDuration(value)) {
32
+ duration = value;
33
+ } else if (typeof value === 'object') {
34
+ duration = dayjs.duration(value);
35
+ } else {
36
+ console.warn(`Invalid duration value:`, value);
37
+ return;
38
+ }
39
+ return duration;
40
+ }
@@ -0,0 +1 @@
1
+ export { parseDecimal } from './parseDecimal';
@@ -0,0 +1,16 @@
1
+ import Decimal from 'decimal.js';
2
+
3
+ export function parseDecimal(v: string | number | Decimal): Decimal;
4
+ export function parseDecimal(v: string | number | Decimal | undefined | null): Decimal | undefined;
5
+ export function parseDecimal(v: string | number | Decimal | undefined | null): Decimal | undefined {
6
+ switch (v) {
7
+ case '':
8
+ case undefined:
9
+ case null:
10
+ return undefined;
11
+ }
12
+ if (Decimal.isDecimal(v)) {
13
+ return v;
14
+ }
15
+ return new Decimal(v);
16
+ }