@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.
- package/lib/cn/ChineseResidentIdNo.js +41 -0
- package/lib/cn/ChineseResidentIdNo.mod.js +1 -0
- package/lib/cn/ChineseResidentIdNo.test.js +22 -0
- package/lib/cn/DivisionCode.js +214 -280
- package/lib/cn/DivisionCode.mod.js +1 -0
- package/lib/cn/DivisionCode.test.js +134 -0
- package/lib/cn/Mod11.js +86 -0
- package/lib/cn/Mod31.js +98 -0
- package/lib/cn/UnifiedSocialCreditCode.js +130 -109
- package/lib/cn/UnifiedSocialCreditCode.mod.js +1 -0
- package/lib/cn/UnifiedSocialCreditCode.test.js +16 -0
- package/lib/cn/index.js +1 -4
- package/lib/cn/mod.js +6 -0
- package/lib/cn/types.d.js +0 -2
- package/lib/consola/createStandardConsolaReporter.js +6 -6
- package/lib/consola/formatLogObject.js +147 -34
- package/lib/consola/index.js +0 -1
- package/lib/data/formatSort.js +5 -6
- package/lib/data/formatSort.test.js +34 -0
- package/lib/data/index.js +0 -1
- package/lib/data/maybeNumber.js +11 -5
- package/lib/data/parseSort.js +28 -22
- package/lib/data/parseSort.test.js +188 -0
- package/lib/data/resolvePagination.js +27 -16
- package/lib/data/resolvePagination.test.js +232 -0
- package/lib/data/types.d.js +0 -2
- package/lib/dayjs/dayjs.js +38 -0
- package/lib/dayjs/formatDuration.js +58 -0
- package/lib/dayjs/formatDuration.test.js +90 -0
- package/lib/dayjs/index.js +3 -0
- package/lib/dayjs/parseDuration.js +32 -0
- package/lib/decimal/index.js +1 -0
- package/lib/decimal/parseDecimal.js +13 -0
- package/lib/foundation/schema/SexType.js +14 -0
- package/lib/foundation/schema/index.js +1 -0
- package/lib/foundation/schema/parseSexType.js +18 -0
- package/lib/foundation/schema/types.js +5 -0
- package/lib/index.js +0 -1
- package/lib/jsonschema/JsonSchema.js +78 -52
- package/lib/jsonschema/JsonSchema.test.js +137 -0
- package/lib/jsonschema/index.js +0 -1
- package/lib/jsonschema/types.d.js +5 -3
- package/lib/meta/defineFileType.js +103 -20
- package/lib/meta/defineInit.js +250 -31
- package/lib/meta/defineMetadata.js +140 -24
- package/lib/meta/defineMetadata.test.js +13 -0
- package/lib/meta/index.js +0 -1
- package/lib/password/PHC.js +87 -63
- package/lib/password/PHC.test.js +539 -0
- package/lib/password/Password.js +295 -30
- package/lib/password/Password.test.js +362 -0
- package/lib/password/createArgon2PasswordAlgorithm.js +191 -35
- package/lib/password/createBase64PasswordAlgorithm.js +141 -8
- package/lib/password/createBcryptPasswordAlgorithm.js +168 -13
- package/lib/password/createPBKDF2PasswordAlgorithm.js +228 -46
- package/lib/password/createScryptPasswordAlgorithm.js +211 -55
- package/lib/password/index.js +0 -1
- package/lib/password/server/index.js +0 -1
- package/lib/resource/Identifiable.js +1 -0
- package/lib/resource/ListQuery.js +119 -0
- package/lib/resource/getTitleOfResource.js +10 -0
- package/lib/resource/index.js +2 -0
- package/lib/resource/schema/AnyResourceSchema.js +89 -0
- package/lib/resource/schema/BaseResourceSchema.js +29 -0
- package/lib/resource/schema/ResourceActionType.js +118 -0
- package/lib/resource/schema/ResourceStatus.js +93 -0
- package/lib/resource/schema/ResourceType.js +24 -0
- package/lib/resource/schema/index.js +5 -0
- package/lib/resource/schema/types.js +89 -0
- package/lib/resource/schema/types.test.js +14 -0
- package/lib/schema/SchemaRegistry.js +45 -0
- package/lib/schema/SchemaRegistry.mod.js +2 -0
- package/lib/schema/TypeSchema.d.js +1 -0
- package/lib/schema/createSchemaData.js +173 -0
- package/lib/schema/findJsonSchemaByPath.js +49 -0
- package/lib/schema/getSchemaCache.js +11 -0
- package/lib/schema/getSchemaOptions.js +24 -0
- package/lib/schema/index.js +6 -0
- package/lib/schema/toJsonSchema.js +441 -0
- package/lib/schema/toJsonSchema.test.js +27 -0
- package/lib/schema/validate.js +124 -0
- package/lib/tools/generateSchema.js +197 -39
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js +143 -55
- package/lib/utils/getEstimateProcessTime.js +20 -0
- package/lib/utils/index.js +1 -0
- package/package.json +38 -17
- package/src/cn/ChineseResidentIdNo.mod.ts +7 -0
- package/src/cn/ChineseResidentIdNo.test.ts +18 -0
- package/src/cn/ChineseResidentIdNo.ts +66 -0
- package/src/cn/DivisionCode.mod.ts +7 -0
- package/src/cn/DivisionCode.test.ts +3 -13
- package/src/cn/DivisionCode.ts +132 -195
- package/src/cn/{Mod11Checksum.ts → Mod11.ts} +3 -1
- package/src/cn/{Mod31Checksum.ts → Mod31.ts} +2 -0
- package/src/cn/UnifiedSocialCreditCode.mod.ts +7 -0
- package/src/cn/UnifiedSocialCreditCode.test.ts +2 -2
- package/src/cn/UnifiedSocialCreditCode.ts +105 -125
- package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +14 -0
- package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +18 -12
- package/src/cn/index.ts +1 -3
- package/src/cn/mod.ts +3 -0
- package/src/consola/formatLogObject.ts +12 -4
- package/src/data/maybeNumber.ts +5 -1
- package/src/data/resolvePagination.test.ts +1 -1
- package/src/data/resolvePagination.ts +18 -7
- package/src/data/types.d.ts +12 -0
- package/src/dayjs/dayjs.ts +40 -0
- package/src/dayjs/formatDuration.test.ts +14 -0
- package/src/dayjs/formatDuration.ts +86 -0
- package/src/dayjs/index.ts +3 -0
- package/src/dayjs/parseDuration.ts +40 -0
- package/src/decimal/index.ts +1 -0
- package/src/decimal/parseDecimal.ts +16 -0
- package/src/foundation/schema/SexType.ts +21 -0
- package/src/foundation/schema/index.ts +1 -0
- package/src/foundation/schema/parseSexType.ts +19 -0
- package/src/foundation/schema/types.ts +8 -0
- package/src/jsonschema/JsonSchema.test.ts +17 -0
- package/src/jsonschema/JsonSchema.ts +2 -2
- package/src/jsonschema/types.d.ts +63 -12
- package/src/password/Password.ts +2 -2
- package/src/resource/Identifiable.ts +3 -0
- package/src/resource/ListQuery.ts +53 -0
- package/src/resource/getTitleOfResource.tsx +6 -0
- package/src/resource/index.ts +4 -0
- package/src/resource/schema/AnyResourceSchema.ts +113 -0
- package/src/resource/schema/BaseResourceSchema.ts +32 -0
- package/src/resource/schema/ResourceActionType.ts +123 -0
- package/src/resource/schema/ResourceStatus.ts +94 -0
- package/src/resource/schema/ResourceType.ts +25 -0
- package/src/resource/schema/index.ts +5 -0
- package/src/resource/schema/types.test.ts +18 -0
- package/src/resource/schema/types.ts +105 -0
- package/src/schema/SchemaRegistry.mod.ts +1 -0
- package/src/schema/SchemaRegistry.ts +46 -0
- package/src/schema/TypeSchema.d.ts +32 -0
- package/src/schema/createSchemaData.ts +81 -0
- package/src/schema/findJsonSchemaByPath.ts +37 -0
- package/src/schema/getSchemaCache.ts +21 -0
- package/src/schema/getSchemaOptions.ts +24 -0
- package/src/schema/index.ts +7 -0
- package/src/schema/toJsonSchema.test.ts +37 -0
- package/src/schema/toJsonSchema.ts +200 -0
- package/src/schema/validate.ts +135 -0
- package/src/tools/generateSchema.ts +28 -28
- package/src/utils/getEstimateProcessTime.ts +36 -0
- package/src/utils/index.ts +1 -0
- package/lib/cn/DivisionCode.js.map +0 -1
- package/lib/cn/Mod11Checksum.js +0 -42
- package/lib/cn/Mod11Checksum.js.map +0 -1
- package/lib/cn/Mod31Checksum.js +0 -48
- package/lib/cn/Mod31Checksum.js.map +0 -1
- package/lib/cn/ResidentIdentityCardNumber.js +0 -50
- package/lib/cn/ResidentIdentityCardNumber.js.map +0 -1
- package/lib/cn/UnifiedSocialCreditCode.js.map +0 -1
- package/lib/cn/formatDate.js +0 -15
- package/lib/cn/formatDate.js.map +0 -1
- package/lib/cn/index.js.map +0 -1
- package/lib/cn/parseSex.js +0 -22
- package/lib/cn/parseSex.js.map +0 -1
- package/lib/cn/types.d.js.map +0 -1
- package/lib/consola/createStandardConsolaReporter.js.map +0 -1
- package/lib/consola/formatLogObject.js.map +0 -1
- package/lib/consola/index.js.map +0 -1
- package/lib/data/formatSort.js.map +0 -1
- package/lib/data/index.js.map +0 -1
- package/lib/data/maybeNumber.js.map +0 -1
- package/lib/data/parseSort.js.map +0 -1
- package/lib/data/resolvePagination.js.map +0 -1
- package/lib/data/types.d.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/jsonschema/JsonSchema.js.map +0 -1
- package/lib/jsonschema/index.js.map +0 -1
- package/lib/jsonschema/types.d.js.map +0 -1
- package/lib/meta/defineFileType.js.map +0 -1
- package/lib/meta/defineInit.js.map +0 -1
- package/lib/meta/defineMetadata.js.map +0 -1
- package/lib/meta/index.js.map +0 -1
- package/lib/password/PHC.js.map +0 -1
- package/lib/password/Password.js.map +0 -1
- package/lib/password/createArgon2PasswordAlgorithm.js.map +0 -1
- package/lib/password/createBase64PasswordAlgorithm.js.map +0 -1
- package/lib/password/createBcryptPasswordAlgorithm.js.map +0 -1
- package/lib/password/createPBKDF2PasswordAlgorithm.js.map +0 -1
- package/lib/password/createScryptPasswordAlgorithm.js.map +0 -1
- package/lib/password/index.js.map +0 -1
- package/lib/password/server/index.js.map +0 -1
- package/lib/search/AdvanceSearch.js +0 -10
- package/lib/search/AdvanceSearch.js.map +0 -1
- package/lib/search/formatAdvanceSearch.js +0 -64
- package/lib/search/formatAdvanceSearch.js.map +0 -1
- package/lib/search/index.js +0 -2
- package/lib/search/index.js.map +0 -1
- package/lib/search/optimizeAdvanceSearch.js +0 -89
- package/lib/search/optimizeAdvanceSearch.js.map +0 -1
- package/lib/search/parseAdvanceSearch.js +0 -20
- package/lib/search/parseAdvanceSearch.js.map +0 -1
- package/lib/search/parser.d.js +0 -3
- package/lib/search/parser.d.js.map +0 -1
- package/lib/search/parser.js +0 -3065
- package/lib/search/parser.js.map +0 -1
- package/lib/search/types.d.js +0 -3
- package/lib/search/types.d.js.map +0 -1
- package/lib/tools/generateSchema.js.map +0 -1
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +0 -1
- package/src/cn/ResidentIdentityCardNumber.test.ts +0 -17
- package/src/cn/ResidentIdentityCardNumber.ts +0 -96
- package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +0 -15
- package/src/cn/formatDate.ts +0 -12
- package/src/cn/parseSex.ts +0 -13
- package/src/search/AdvanceSearch.test.ts +0 -149
- package/src/search/AdvanceSearch.ts +0 -14
- package/src/search/Makefile +0 -2
- package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +0 -675
- package/src/search/formatAdvanceSearch.ts +0 -52
- package/src/search/index.ts +0 -1
- package/src/search/optimizeAdvanceSearch.ts +0 -77
- package/src/search/parseAdvanceSearch.ts +0 -23
- package/src/search/parser.d.ts +0 -8
- package/src/search/parser.js +0 -2794
- package/src/search/parser.peggy +0 -237
- package/src/search/types.d.ts +0 -45
|
@@ -1,143 +1,123 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { Mod31 } from './Mod31';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
},
|
|
18
|
+
},
|
|
19
|
+
5: {
|
|
20
|
+
name: '民政',
|
|
21
|
+
children: {
|
|
22
|
+
1: { name: '社会团体' },
|
|
23
|
+
2: { name: '民办非企业单位' },
|
|
24
|
+
3: { name: '基金会' },
|
|
25
|
+
9: { name: '其他' },
|
|
32
26
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
},
|
|
27
|
+
},
|
|
28
|
+
9: {
|
|
29
|
+
name: '工商',
|
|
30
|
+
children: {
|
|
31
|
+
1: { name: '企业' },
|
|
32
|
+
2: { name: '个体工商户' },
|
|
33
|
+
3: { name: '农民专业合作社' },
|
|
34
|
+
9: { name: '其他' },
|
|
41
35
|
},
|
|
42
|
-
|
|
43
|
-
}
|
|
36
|
+
},
|
|
37
|
+
Y: { name: '其他', children: { 1: { name: '其他' } } },
|
|
38
|
+
};
|
|
44
39
|
|
|
45
|
-
|
|
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
|
-
|
|
50
|
+
codes: z.string().array().describe('代码数组'),
|
|
51
|
+
names: z.string().array().describe('代码名称'),
|
|
52
|
+
valid: z.boolean().optional().describe('是否有效'),
|
|
53
|
+
})
|
|
54
|
+
.describe('统一社会信用代码');
|
|
48
55
|
|
|
49
|
-
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
|
|
142
|
-
|
|
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
|
-
"
|
|
6
|
-
"
|
|
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
|
-
"
|
|
14
|
-
"
|
|
14
|
+
"entityCategoryCode": "1",
|
|
15
|
+
"names": [
|
|
15
16
|
"工商",
|
|
16
17
|
"企业",
|
|
17
18
|
],
|
|
18
|
-
"
|
|
19
|
-
"
|
|
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
|
-
"
|
|
26
|
-
"
|
|
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
|
-
"
|
|
34
|
-
"
|
|
37
|
+
"entityCategoryCode": "1",
|
|
38
|
+
"names": [
|
|
35
39
|
"工商",
|
|
36
40
|
"企业",
|
|
37
41
|
],
|
|
38
|
-
"
|
|
39
|
-
"
|
|
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 {
|
|
2
|
-
export { DivisionCode } from './DivisionCode';
|
|
3
|
-
export { UnifiedSocialCreditCode } from './UnifiedSocialCreditCode';
|
|
1
|
+
export { ChineseResidentIdNo, UnifiedSocialCreditCode, DivisionCode } from './mod';
|
package/src/cn/mod.ts
ADDED
|
@@ -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
|
|
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
|
-
|
|
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 = '';
|
package/src/data/maybeNumber.ts
CHANGED
|
@@ -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
|
-
|
|
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' }, {
|
|
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 {
|
|
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
|
-
|
|
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 ??=
|
|
42
|
-
pageSize = clamp(pageSize, 1, options.maxPageSize ?? 1000);
|
|
42
|
+
pageSize ??= resolvePagination.pageSize;
|
|
43
43
|
|
|
44
|
-
let { pageNumber = 1, pageIndex
|
|
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
|
-
|
|
49
|
-
|
|
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;
|
package/src/data/types.d.ts
CHANGED
|
@@ -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,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
|
+
}
|