@wener/common 1.0.2 → 1.0.4
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/DivisionCode.js +311 -0
- package/lib/cn/DivisionCode.js.map +1 -0
- package/lib/cn/Mod11Checksum.js +42 -0
- package/lib/cn/Mod11Checksum.js.map +1 -0
- package/lib/cn/Mod31Checksum.js +48 -0
- package/lib/cn/Mod31Checksum.js.map +1 -0
- package/lib/cn/ResidentIdentityCardNumber.js +50 -0
- package/lib/cn/ResidentIdentityCardNumber.js.map +1 -0
- package/lib/cn/UnifiedSocialCreditCode.js +118 -0
- package/lib/cn/UnifiedSocialCreditCode.js.map +1 -0
- package/lib/cn/formatDate.js +15 -0
- package/lib/cn/formatDate.js.map +1 -0
- package/lib/cn/index.js +4 -0
- package/lib/cn/index.js.map +1 -0
- package/lib/cn/parseSex.js +22 -0
- package/lib/cn/parseSex.js.map +1 -0
- package/lib/cn/types.d.js +8 -0
- package/lib/cn/types.d.js.map +1 -0
- package/lib/data/formatSort.js +15 -0
- package/lib/data/formatSort.js.map +1 -0
- package/lib/data/index.js +4 -0
- package/lib/data/index.js.map +1 -0
- package/lib/data/maybeNumber.js +22 -0
- package/lib/data/maybeNumber.js.map +1 -0
- package/lib/data/parseSort.js +95 -0
- package/lib/data/parseSort.js.map +1 -0
- package/lib/data/resolvePagination.js +36 -0
- package/lib/data/resolvePagination.js.map +1 -0
- package/lib/data/types.d.js +3 -0
- package/lib/data/types.d.js.map +1 -0
- package/lib/index.js +6 -2
- package/lib/index.js.map +1 -1
- package/lib/jsonschema/JsonSchema.js +4 -4
- package/lib/jsonschema/JsonSchema.js.map +1 -1
- package/lib/jsonschema/types.d.js.map +1 -1
- package/lib/meta/defineFileType.js +44 -0
- package/lib/meta/defineFileType.js.map +1 -0
- package/lib/meta/defineInit.js.map +1 -1
- package/lib/meta/defineMetadata.js +14 -3
- package/lib/meta/defineMetadata.js.map +1 -1
- package/lib/meta/index.js +1 -0
- package/lib/meta/index.js.map +1 -1
- package/lib/password/PHC.js +8 -8
- package/lib/password/PHC.js.map +1 -1
- package/lib/password/Password.js.map +1 -1
- package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
- package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
- package/lib/search/AdvanceSearch.js.map +1 -1
- package/lib/search/formatAdvanceSearch.js +1 -1
- package/lib/search/formatAdvanceSearch.js.map +1 -1
- package/lib/search/optimizeAdvanceSearch.js.map +1 -1
- package/lib/search/parseAdvanceSearch.js.map +1 -1
- package/lib/search/parser.d.js.map +1 -1
- package/lib/search/parser.js +380 -76
- package/lib/search/parser.js.map +1 -1
- package/lib/search/types.d.js.map +1 -1
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -1
- package/package.json +14 -5
- package/src/cn/DivisionCode.test.ts +43 -0
- package/src/cn/DivisionCode.ts +209 -0
- package/src/cn/Mod11Checksum.ts +24 -0
- package/src/cn/Mod31Checksum.ts +36 -0
- package/src/cn/ResidentIdentityCardNumber.test.ts +17 -0
- package/src/cn/ResidentIdentityCardNumber.ts +96 -0
- package/src/cn/UnifiedSocialCreditCode.test.ts +16 -0
- package/src/cn/UnifiedSocialCreditCode.ts +143 -0
- package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +15 -0
- package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +41 -0
- package/src/cn/formatDate.ts +12 -0
- package/src/cn/index.ts +3 -0
- package/src/cn/parseSex.ts +13 -0
- package/src/cn/types.d.ts +51 -0
- package/src/data/formatSort.test.ts +13 -0
- package/src/data/formatSort.ts +18 -0
- package/src/data/index.ts +5 -0
- package/src/data/maybeNumber.ts +23 -0
- package/src/data/parseSort.test.ts +67 -0
- package/src/data/parseSort.ts +108 -0
- package/src/data/resolvePagination.test.ts +58 -0
- package/src/data/resolvePagination.ts +60 -0
- package/src/data/types.d.ts +33 -0
- package/src/index.ts +8 -2
- package/src/jsonschema/JsonSchema.test.ts +13 -22
- package/src/jsonschema/JsonSchema.ts +145 -177
- package/src/jsonschema/types.d.ts +151 -161
- package/src/meta/defineFileType.tsx +68 -0
- package/src/meta/defineInit.ts +32 -53
- package/src/meta/defineMetadata.test.ts +5 -7
- package/src/meta/defineMetadata.ts +35 -40
- package/src/meta/index.ts +2 -0
- package/src/password/PHC.test.ts +186 -277
- package/src/password/PHC.ts +243 -243
- package/src/password/Password.test.ts +38 -50
- package/src/password/Password.ts +73 -95
- package/src/password/createArgon2PasswordAlgorithm.ts +65 -69
- package/src/password/createBase64PasswordAlgorithm.ts +9 -9
- package/src/password/createBcryptPasswordAlgorithm.ts +20 -22
- package/src/password/createPBKDF2PasswordAlgorithm.ts +49 -61
- package/src/password/createScryptPasswordAlgorithm.ts +48 -59
- package/src/search/AdvanceSearch.test.ts +136 -143
- package/src/search/AdvanceSearch.ts +6 -6
- package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +3 -3
- package/src/search/formatAdvanceSearch.ts +44 -53
- package/src/search/optimizeAdvanceSearch.ts +70 -83
- package/src/search/parseAdvanceSearch.ts +16 -19
- package/src/search/parser.d.ts +3 -3
- package/src/search/parser.js +325 -73
- package/src/search/parser.peggy +42 -9
- package/src/search/types.d.ts +28 -54
- package/src/tools/renderJsonSchemaToMarkdownDoc.ts +69 -69
- package/lib/normalizePagination.js +0 -14
- package/lib/normalizePagination.js.map +0 -1
- package/lib/parseSort.js +0 -91
- package/lib/parseSort.js.map +0 -1
- package/src/normalizePagination.ts +0 -25
- package/src/parseSort.test.ts +0 -42
- package/src/parseSort.ts +0 -115
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/search/types.d.ts"],"sourcesContent":["export type Exprs = Expr[];\nexport type Expr =\n
|
|
1
|
+
{"version":3,"sources":["../../src/search/types.d.ts"],"sourcesContent":["export type Exprs = Expr[];\nexport type Expr =\n\t| CommentExpr\n\t| ParenthesesExpr\n\t| KeywordCondition\n\t| LogicalCondition\n\t| NotCondition\n\t| CompareCondition;\n\nexport type CommentExpr = { type: 'comment'; value: string };\n\nexport type ParenthesesExpr = { type: 'parentheses'; value: Expr[] };\n\nexport type KeywordCondition = { type: 'keyword'; value: string; negative?: boolean; exact?: boolean };\n\nexport type LogicalCondition = { type: 'logical'; operator: 'and' | 'or'; value: Expr[] };\n\nexport type NotCondition = { type: 'not'; value: Expr };\n\nexport type CompareCondition = {\n\ttype: 'compare';\n\tfield: string;\n\t/**\n\t * mention value for eq, ne only\n\t * range require range value\n\t */\n\toperator: 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte' | 'range' | 'match';\n\tnegative?: boolean;\n\tmention?: boolean;\n\tvalue: Value;\n};\n\nexport type Value = LiteralValue | RangeValue | MentionValue;\n\nexport type LiteralValue = { type?: 'literal'; format?: 'date' | 'date-time'; value: string | number | null };\n\nexport type MentionValue = { type?: 'literal'; format: 'mention'; value: string };\n\nexport type RangeValue = {\n\ttype: 'range';\n\tminimum: LiteralValue | undefined;\n\tmaximum: LiteralValue | undefined;\n\tminimumExclusive: boolean;\n\tmaximumExclusive: boolean;\n};\n"],"names":[],"mappings":"AAsCA,WAME"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tools/renderJsonSchemaToMarkdownDoc.ts"],"sourcesContent":["import type { TObject, TSchema } from '@sinclair/typebox';\n\nexport function renderJsonSchemaToMarkdownDoc(rootSchema: any) {\n
|
|
1
|
+
{"version":3,"sources":["../../src/tools/renderJsonSchemaToMarkdownDoc.ts"],"sourcesContent":["import type { TObject, TSchema } from '@sinclair/typebox';\n\nexport function renderJsonSchemaToMarkdownDoc(rootSchema: any) {\n\t// markdown\n\tconst out: string[] = [];\n\tconst all = new Set();\n\tconst pending: TSchema[] = [];\n\n\tconst addObject = (o: TSchema) => {\n\t\tif (all.has(o.$id)) {\n\t\t\treturn;\n\t\t}\n\t\tall.add(o.$id);\n\t\tpending.push(o);\n\t};\n\n\tconst writeObjectProps = (T: TObject, { prefix = '' }: { prefix?: string } = {}) => {\n\t\tif (!T?.properties) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const [name, schema] of Object.entries(T.properties)) {\n\t\t\tlet typ = schema.$id || schema.type;\n\n\t\t\tif (typ === 'array') {\n\t\t\t\ttyp = `${schema.items.$id || schema.items.type}[]`;\n\t\t\t\tif (schema.items.$id) {\n\t\t\t\t\taddObject(schema.items);\n\t\t\t\t}\n\t\t\t} else if (schema.$id) {\n\t\t\t\taddObject(schema);\n\t\t\t}\n\t\t\tif (!typ) {\n\t\t\t\tif ('anyOf' in schema) {\n\t\t\t\t\ttyp = 'enum';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tout.push(`| ${prefix}${name} | ${typ} | ${schema.title || schema.description || ''} |`);\n\n\t\t\tif (typ === 'object') {\n\t\t\t\twriteObjectProps(schema as TObject, { prefix: `${prefix}${name}.` });\n\t\t\t} else if (schema.type === 'array') {\n\t\t\t\tif (schema.items.type === 'object' && !schema.items.$id) {\n\t\t\t\t\twriteObjectProps(schema.items as TObject, { prefix: `${prefix}${name}[].` });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\tconst writeObject = (T: TObject) => {\n\t\tout.push(`### ${T.title || T.$id}`);\n\t\tout.push(`\n| $id | 名字 |\n| --- | --- |\n| ${T.$id || ''} | ${T.title || ''} | \n `);\n\t\tif (T.description) {\n\t\t\tout.push('');\n\t\t\tout.push(`> ${T.description}`);\n\t\t\tout.push('');\n\t\t}\n\n\t\tout.push(`| 名字 | 类型 | 说明 |`);\n\t\tout.push(`| --- | --- | --- |`);\n\n\t\twriteObjectProps(T);\n\n\t\tout.push('');\n\t};\n\n\twriteObject(rootSchema);\n\n\tfor (const schema of pending) {\n\t\tif (schema.type === 'object') {\n\t\t\twriteObject(schema as TObject);\n\t\t} else if ('anyOf' in schema) {\n\t\t\tout.push(`### ${schema.$id || schema.title}`);\n\t\t\tout.push(`\n| $id | 名字 |\n| --- | --- |\n| ${schema.$id || ''} | ${schema.title || ''} | \n `);\n\n\t\t\tout.push(`| 值 | 说明 |`);\n\t\t\tout.push(`| --- | --- |`);\n\t\t\tfor (const item of schema.anyOf) {\n\t\t\t\tout.push(`| ${item.const} | ${item.title || item.description || ''} |`);\n\t\t\t}\n\t\t\tout.push('');\n\t\t}\n\t}\n\n\treturn out.join('\\n');\n}\n"],"names":["renderJsonSchemaToMarkdownDoc","rootSchema","out","all","Set","pending","addObject","o","has","$id","add","push","writeObjectProps","T","prefix","properties","name","schema","Object","entries","typ","type","items","title","description","writeObject","item","anyOf","const","join"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wener/common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "",
|
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
"types": "./src/index.ts",
|
|
11
11
|
"default": "./lib/index.js"
|
|
12
12
|
},
|
|
13
|
+
"./cn": {
|
|
14
|
+
"types": "./src/cn/index.ts",
|
|
15
|
+
"default": "./lib/cn/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./data": {
|
|
18
|
+
"types": "./src/data/index.ts",
|
|
19
|
+
"default": "./lib/data/index.js"
|
|
20
|
+
},
|
|
13
21
|
"./jsonschema": {
|
|
14
22
|
"types": "./src/jsonschema/index.ts",
|
|
15
23
|
"default": "./lib/jsonschema/index.js"
|
|
@@ -36,12 +44,13 @@
|
|
|
36
44
|
],
|
|
37
45
|
"keywords": [],
|
|
38
46
|
"dependencies": {
|
|
39
|
-
"es-toolkit": "^1.
|
|
40
|
-
"ts-pattern": "^5.
|
|
47
|
+
"es-toolkit": "^1.32.0",
|
|
48
|
+
"ts-pattern": "^5.6.2",
|
|
49
|
+
"zod": "^3.24.2",
|
|
41
50
|
"@wener/utils": "1.1.51"
|
|
42
51
|
},
|
|
43
52
|
"devDependencies": {
|
|
44
|
-
"@sinclair/typebox": "^0.34.
|
|
53
|
+
"@sinclair/typebox": "^0.34.28",
|
|
45
54
|
"@types/argon2-browser": "^1.18.4",
|
|
46
55
|
"@types/bcrypt": "^5.0.2",
|
|
47
56
|
"@types/bcryptjs": "^2.4.6",
|
|
@@ -52,7 +61,7 @@
|
|
|
52
61
|
"argon2": "^0.41.1",
|
|
53
62
|
"argon2-browser": "^1.18.0",
|
|
54
63
|
"bcrypt": "^5.1.1",
|
|
55
|
-
"bcryptjs": "^
|
|
64
|
+
"bcryptjs": "^3.0.2"
|
|
56
65
|
},
|
|
57
66
|
"scripts": {
|
|
58
67
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { DivisionCode } from './DivisionCode';
|
|
3
|
+
|
|
4
|
+
describe('DivisionCode', () => {
|
|
5
|
+
it('should parse', () => {
|
|
6
|
+
for (const [a, b] of [
|
|
7
|
+
[
|
|
8
|
+
'441900003001',
|
|
9
|
+
{
|
|
10
|
+
province: '44',
|
|
11
|
+
city: '19',
|
|
12
|
+
county: '00',
|
|
13
|
+
town: '003',
|
|
14
|
+
village: '001',
|
|
15
|
+
codes: ['44', '19', '00', '003', '001'],
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
[
|
|
19
|
+
441900003001,
|
|
20
|
+
{
|
|
21
|
+
province: '44',
|
|
22
|
+
city: '19',
|
|
23
|
+
county: '00',
|
|
24
|
+
town: '003',
|
|
25
|
+
village: '001',
|
|
26
|
+
codes: ['44', '19', '00', '003', '001'],
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
[441900, { province: '44', city: '19', county: '00' }],
|
|
30
|
+
['31', { province: '31' }],
|
|
31
|
+
['4', undefined],
|
|
32
|
+
['', undefined],
|
|
33
|
+
[null, undefined],
|
|
34
|
+
[undefined, undefined],
|
|
35
|
+
] as Array<[string, any]>) {
|
|
36
|
+
let out = DivisionCode.parse(a);
|
|
37
|
+
expect(out).toMatchObject(b);
|
|
38
|
+
if (out) {
|
|
39
|
+
expect(DivisionCode.format(out)).toBe(String(a));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
const DivisionCodeLevels: Array<{ level: number; code: string; length: number; size: number; label: string }> = [
|
|
2
|
+
{ level: 1, code: 'Province', length: 2, size: 2, label: '省' },
|
|
3
|
+
{ level: 2, code: 'City', length: 4, size: 2, label: '市' },
|
|
4
|
+
{ level: 3, code: 'County', length: 6, size: 2, label: '区县' },
|
|
5
|
+
{ level: 4, code: 'Town', length: 9, size: 3, label: '乡镇' },
|
|
6
|
+
{ level: 5, code: 'Village', length: 12, size: 3, label: '村' },
|
|
7
|
+
] as const;
|
|
8
|
+
|
|
9
|
+
// String(Number.MAX_SAFE_INTEGER).length=16
|
|
10
|
+
// 12 is safe int
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Codes for the administrative divisions of the People's Republic of China
|
|
14
|
+
*
|
|
15
|
+
* @see https://zh.wikipedia.org/wiki/GB/T_2260 中华人民共和国行政区划代码
|
|
16
|
+
*/
|
|
17
|
+
export namespace DivisionCode {
|
|
18
|
+
enum DivisionCodeLevel {
|
|
19
|
+
Province = 1,
|
|
20
|
+
City = 2,
|
|
21
|
+
County = 3,
|
|
22
|
+
Town = 4,
|
|
23
|
+
Village = 5,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const levels = DivisionCodeLevels;
|
|
27
|
+
|
|
28
|
+
export const regex = /^(?<province>\d{2})(?<city>\d{2})?(?<county>\d{2})?(?<town>\d{3})?(?<village>\d{3})?$/;
|
|
29
|
+
|
|
30
|
+
const root: CodeValue[] = [
|
|
31
|
+
{ value: '11', label: '北京市' },
|
|
32
|
+
{ value: '12', label: '天津市' },
|
|
33
|
+
{ value: '13', label: '河北省' },
|
|
34
|
+
{ value: '14', label: '山西省' },
|
|
35
|
+
{ value: '15', label: '内蒙古自治区' },
|
|
36
|
+
{ value: '21', label: '辽宁省' },
|
|
37
|
+
{ value: '22', label: '吉林省' },
|
|
38
|
+
{ value: '23', label: '黑龙江省' },
|
|
39
|
+
{ value: '31', label: '上海市' },
|
|
40
|
+
{ value: '32', label: '江苏省' },
|
|
41
|
+
{ value: '33', label: '浙江省' },
|
|
42
|
+
{ value: '34', label: '安徽省' },
|
|
43
|
+
{ value: '35', label: '福建省' },
|
|
44
|
+
{ value: '36', label: '江西省' },
|
|
45
|
+
{ value: '37', label: '山东省' },
|
|
46
|
+
{ value: '41', label: '河南省' },
|
|
47
|
+
{ value: '42', label: '湖北省' },
|
|
48
|
+
{ value: '43', label: '湖南省' },
|
|
49
|
+
{ value: '44', label: '广东省' },
|
|
50
|
+
{ value: '45', label: '广西壮族自治区' },
|
|
51
|
+
{ value: '46', label: '海南省' },
|
|
52
|
+
{ value: '50', label: '重庆市' },
|
|
53
|
+
{ value: '51', label: '四川省' },
|
|
54
|
+
{ value: '52', label: '贵州省' },
|
|
55
|
+
{ value: '53', label: '云南省' },
|
|
56
|
+
{ value: '54', label: '西藏自治区' },
|
|
57
|
+
{ value: '61', label: '陕西省' },
|
|
58
|
+
{ value: '62', label: '甘肃省' },
|
|
59
|
+
{ value: '63', label: '青海省' },
|
|
60
|
+
{ value: '64', label: '宁夏回族自治区' },
|
|
61
|
+
{ value: '65', label: '新疆维吾尔自治区' },
|
|
62
|
+
{ value: '71', label: '台湾省' },
|
|
63
|
+
{ value: '81', label: '香港特别行政区' },
|
|
64
|
+
{ value: '82', label: '澳门特别行政区' },
|
|
65
|
+
// 9 国外
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
export type ParsedCode = {
|
|
69
|
+
province: string;
|
|
70
|
+
city?: string;
|
|
71
|
+
county?: string;
|
|
72
|
+
town?: string;
|
|
73
|
+
village?: string;
|
|
74
|
+
codes: string[];
|
|
75
|
+
level: DivisionCodeLevel;
|
|
76
|
+
labels: string[];
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export function parse(code: string | undefined | null | number): ParsedCode | undefined {
|
|
80
|
+
if (!code) return;
|
|
81
|
+
code = String(code);
|
|
82
|
+
const match = regex.exec(code);
|
|
83
|
+
if (!match) return;
|
|
84
|
+
const { province, city, county, town, village } = match.groups ?? {};
|
|
85
|
+
if (!province) return;
|
|
86
|
+
|
|
87
|
+
let codes = [province, city, county, town, village].filter(Boolean);
|
|
88
|
+
return { province, city, county, town, village, codes: codes, level: codes.length as DivisionCodeLevel };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function format({
|
|
92
|
+
province,
|
|
93
|
+
city,
|
|
94
|
+
county,
|
|
95
|
+
town,
|
|
96
|
+
village,
|
|
97
|
+
}: {
|
|
98
|
+
province: string | number;
|
|
99
|
+
city?: string | number;
|
|
100
|
+
county?: string | number;
|
|
101
|
+
town?: string | number;
|
|
102
|
+
village?: string | number;
|
|
103
|
+
}): string {
|
|
104
|
+
const codes: string[] = [];
|
|
105
|
+
for (let i = 0; i < [province, city, county, town, village].length; i++) {
|
|
106
|
+
let x = [province, city, county, town, village][i];
|
|
107
|
+
if (x === undefined || x === null || x === '') {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
let len = levels[i].size;
|
|
111
|
+
codes.push(String(x).padStart(len, '0').slice(0, len));
|
|
112
|
+
}
|
|
113
|
+
return codes.join('');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// export function random(level: DivisionCodeLevel = 'County'): string {
|
|
117
|
+
// const l = DivisionCodeLevels.find((v) => v.code === level) || DivisionCodeLevels[2];
|
|
118
|
+
// const l1 = randomPick(provinces);
|
|
119
|
+
// if (l.level === 1) {
|
|
120
|
+
// return String(l1[0]);
|
|
121
|
+
// }
|
|
122
|
+
// return l1 + String(Math.floor(Math.random() * parseFloat(`1e${l.length - 2}`) - 1));
|
|
123
|
+
// }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
interface DivisionTreeNode {
|
|
127
|
+
sub: string; // sub code
|
|
128
|
+
children?: Record<string, DivisionTreeNode>;
|
|
129
|
+
|
|
130
|
+
code: string; // full code
|
|
131
|
+
name?: string; // name of division
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// export type DivisionCodeLevel = 'Village' | 'Town' | 'County' | 'City' | 'Province';
|
|
135
|
+
|
|
136
|
+
// export interface ParsedDivisionCode {
|
|
137
|
+
// level: DivisionCodeLevel;
|
|
138
|
+
// code: string;
|
|
139
|
+
// name?: string;
|
|
140
|
+
// fullName?: string;
|
|
141
|
+
// names: string[];
|
|
142
|
+
// // 村级(村委会、居委会)
|
|
143
|
+
// // 12 位
|
|
144
|
+
// village?: CodeName;
|
|
145
|
+
// // 乡级(乡镇、街道)
|
|
146
|
+
// // 9 位
|
|
147
|
+
// town?: CodeName;
|
|
148
|
+
// // 县级(区县)
|
|
149
|
+
// // 6 位 - 常用 - 2985 个
|
|
150
|
+
// county?: CodeName;
|
|
151
|
+
// // 地级(城市)
|
|
152
|
+
// // 4 位 - 343 个
|
|
153
|
+
// city?: CodeName;
|
|
154
|
+
// // 省级(省份、直辖市、自治区)
|
|
155
|
+
// // 2 位 - 32 个
|
|
156
|
+
// province: CodeName;
|
|
157
|
+
//
|
|
158
|
+
// children?: Array<{ code: string; name?: string }>;
|
|
159
|
+
// }
|
|
160
|
+
|
|
161
|
+
// export interface CodeName {
|
|
162
|
+
// code: string;
|
|
163
|
+
// name: string;
|
|
164
|
+
// }
|
|
165
|
+
|
|
166
|
+
// export function getSimpleProvinceLabel(value: string) {
|
|
167
|
+
// if (!value) {
|
|
168
|
+
// return;
|
|
169
|
+
// }
|
|
170
|
+
// let label = value;
|
|
171
|
+
// if (/[0-9]/.test(label)) {
|
|
172
|
+
// label = label.slice(0, 2);
|
|
173
|
+
// label = options.find((v) => v.value === label)?.label || label;
|
|
174
|
+
// }
|
|
175
|
+
// return label.replace(/省|市|(回族|维吾尔|壮族)?自治区|特别行政区$/, '');
|
|
176
|
+
// }
|
|
177
|
+
|
|
178
|
+
export function randomPick<T>(s: T[]) {
|
|
179
|
+
return s[Math.floor(Math.random() * s.length)];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function lookup(opts: { values: string[]; root: CodeValue[] }): { found: CodeValue[] } {
|
|
183
|
+
const { values, root } = opts;
|
|
184
|
+
const found: CodeValue[] = [];
|
|
185
|
+
let currentLevel = root;
|
|
186
|
+
|
|
187
|
+
for (const v of values) {
|
|
188
|
+
const node = currentLevel.find((n) => n.value === v);
|
|
189
|
+
if (!node) {
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
found.push(node);
|
|
194
|
+
|
|
195
|
+
if (node.children) {
|
|
196
|
+
currentLevel = node.children;
|
|
197
|
+
} else {
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return { found };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface CodeValue {
|
|
206
|
+
value: string;
|
|
207
|
+
label: string;
|
|
208
|
+
children?: Array<CodeValue>;
|
|
209
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ISO 7064:1983, MOD 11-2.
|
|
3
|
+
*/
|
|
4
|
+
export class Mod11Checksum {
|
|
5
|
+
weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
|
|
6
|
+
|
|
7
|
+
validate(s: string) {
|
|
8
|
+
return s.at(-1) === this.compute(s.slice(0, s.length - 1));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
compute(s: string) {
|
|
12
|
+
const { weights } = this;
|
|
13
|
+
let sum = 0;
|
|
14
|
+
for (let i = 0; i < s.length; i++) {
|
|
15
|
+
sum += parseInt(s[i]) * weights[i];
|
|
16
|
+
}
|
|
17
|
+
const num = (12 - (sum % 11)) % 11;
|
|
18
|
+
if (num < 10) {
|
|
19
|
+
return num.toString();
|
|
20
|
+
} else {
|
|
21
|
+
return 'X';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GB/T 17710(采ISO 7064)的模31校验码
|
|
3
|
+
*
|
|
4
|
+
* Mod31-3
|
|
5
|
+
*/
|
|
6
|
+
export class Mod31Checksum {
|
|
7
|
+
weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
|
|
8
|
+
chars = '0123456789ABCDEFGHJKLMNPQRTUWXY';
|
|
9
|
+
numbers: Record<string, number> = this.chars.split('').reduce(
|
|
10
|
+
(acc, cur, i) => {
|
|
11
|
+
acc[cur] = i;
|
|
12
|
+
return acc;
|
|
13
|
+
},
|
|
14
|
+
{} as Record<string, number>,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
toChar(n: number) {
|
|
18
|
+
return this.chars[n];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
toNumber(c: string) {
|
|
22
|
+
return this.numbers[c];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
validate(s: string) {
|
|
26
|
+
return s.at(-1) === this.compute(s.slice(0, s.length - 1));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
compute(s: string) {
|
|
30
|
+
let sum = 0;
|
|
31
|
+
for (let i = 0; i < s.length; i++) {
|
|
32
|
+
sum += this.numbers[s[i]] * this.weights[i];
|
|
33
|
+
}
|
|
34
|
+
return this.toChar(31 - (sum % 31));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { ResidentIdentityCardNumber } from './ResidentIdentityCardNumber';
|
|
3
|
+
|
|
4
|
+
describe('ResidentIdentityCardNumber', () => {
|
|
5
|
+
it('should parse', () => {
|
|
6
|
+
for (const a of ['11010519491231002X']) {
|
|
7
|
+
let out = ResidentIdentityCardNumber.parse(a);
|
|
8
|
+
expect(ResidentIdentityCardNumber.format(out)).toBe(a);
|
|
9
|
+
expect(out).toMatchSnapshot();
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
it('should format with partial', () => {
|
|
13
|
+
expect(
|
|
14
|
+
ResidentIdentityCardNumber.format({ division: '110105', birthDate: new Date('1949-12-31'), sequence: 2 }),
|
|
15
|
+
).toBe('11010519491231002X');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { formatDate } from './formatDate';
|
|
2
|
+
import { Mod11Checksum } from './Mod11Checksum';
|
|
3
|
+
|
|
4
|
+
export namespace ResidentIdentityCardNumber {
|
|
5
|
+
export const Checksum = new Mod11Checksum();
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
export const length = 18;
|
|
9
|
+
export const pattern = /^\d{6}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/;
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export function parse(s: string): ParsedResidentIdentityCardNumber {
|
|
13
|
+
const division = s.slice(0, 6);
|
|
14
|
+
const birthDate = s.slice(6, 14);
|
|
15
|
+
const sequence = parseInt(s.slice(14, 17), 10);
|
|
16
|
+
const checksum = s.slice(17, 18);
|
|
17
|
+
const valid = Checksum.validate(s);
|
|
18
|
+
const sex = sequence % 2 === 1 ? 'Male' : 'Female';
|
|
19
|
+
return {
|
|
20
|
+
division,
|
|
21
|
+
birthDate,
|
|
22
|
+
sequence,
|
|
23
|
+
checksum,
|
|
24
|
+
valid,
|
|
25
|
+
sex,
|
|
26
|
+
male: sex === 'Male',
|
|
27
|
+
female: sex === 'Female',
|
|
28
|
+
age: new Date().getFullYear() - parseInt(birthDate.slice(0, 4), 10),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function format({
|
|
33
|
+
division,
|
|
34
|
+
birthDate,
|
|
35
|
+
sequence,
|
|
36
|
+
checksum,
|
|
37
|
+
}: {
|
|
38
|
+
division: string;
|
|
39
|
+
birthDate: string | Date;
|
|
40
|
+
sequence: number | string;
|
|
41
|
+
checksum?: string;
|
|
42
|
+
}) {
|
|
43
|
+
if (typeof birthDate !== 'string') {
|
|
44
|
+
birthDate = formatDate(birthDate, 'yyyyMMDD');
|
|
45
|
+
}
|
|
46
|
+
if (birthDate.includes('-')) {
|
|
47
|
+
birthDate = birthDate.replace(/-/g, '');
|
|
48
|
+
}
|
|
49
|
+
typeof sequence === 'number' && (sequence = sequence.toString());
|
|
50
|
+
sequence = sequence.padStart(3, '0');
|
|
51
|
+
const base = [division, birthDate, sequence].join('');
|
|
52
|
+
if (base.length !== 17) throw new Error('Invalid params');
|
|
53
|
+
checksum ||= Checksum.compute(base);
|
|
54
|
+
return base + checksum;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export interface ParsedResidentIdentityCardNumber {
|
|
58
|
+
/**
|
|
59
|
+
* @title 行政区划代码
|
|
60
|
+
*/
|
|
61
|
+
division: string;
|
|
62
|
+
/**
|
|
63
|
+
* @title 出生日期
|
|
64
|
+
* 格式 yyyyMMDD
|
|
65
|
+
*/
|
|
66
|
+
birthDate: string;
|
|
67
|
+
/**
|
|
68
|
+
* @title 顺序码
|
|
69
|
+
*/
|
|
70
|
+
sequence: number;
|
|
71
|
+
/**
|
|
72
|
+
* @title 校验位
|
|
73
|
+
*/
|
|
74
|
+
checksum: string;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @title 是否有效
|
|
78
|
+
*/
|
|
79
|
+
valid: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* @title 是否男性
|
|
82
|
+
*/
|
|
83
|
+
male: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* @title 是否女性
|
|
86
|
+
*/
|
|
87
|
+
female: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* @title 性别
|
|
90
|
+
*/
|
|
91
|
+
sex: 'Male' | 'Female';
|
|
92
|
+
/**
|
|
93
|
+
* @title 年龄
|
|
94
|
+
*/
|
|
95
|
+
age: number;
|
|
96
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { UnifiedSocialCreditCode } from './UnifiedSocialCreditCode';
|
|
3
|
+
|
|
4
|
+
describe('UnifiedSocialCreditCode', () => {
|
|
5
|
+
it('should parse', () => {
|
|
6
|
+
for (const a of [
|
|
7
|
+
//
|
|
8
|
+
'91330106673959654P',
|
|
9
|
+
'91330106MA2CFLDG4R',
|
|
10
|
+
]) {
|
|
11
|
+
let out = UnifiedSocialCreditCode.parse(a);
|
|
12
|
+
expect(UnifiedSocialCreditCode.format(out)).toBe(a);
|
|
13
|
+
expect(out).toMatchSnapshot();
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Mod31Checksum } from './Mod31Checksum';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 统一社会信用代码
|
|
5
|
+
*
|
|
6
|
+
* - GB 11714-1997 全国组织机构代码编制规则
|
|
7
|
+
*/
|
|
8
|
+
export namespace UnifiedSocialCreditCode {
|
|
9
|
+
interface CodeValue {
|
|
10
|
+
label: string;
|
|
11
|
+
children?: Record<string, CodeValue>;
|
|
12
|
+
}
|
|
13
|
+
|
|
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
|
+
},
|
|
23
|
+
},
|
|
24
|
+
5: {
|
|
25
|
+
label: '民政',
|
|
26
|
+
children: {
|
|
27
|
+
1: { label: '社会团体' },
|
|
28
|
+
2: { label: '民办非企业单位' },
|
|
29
|
+
3: { label: '基金会' },
|
|
30
|
+
9: { label: '其他' },
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
9: {
|
|
34
|
+
label: '工商',
|
|
35
|
+
children: {
|
|
36
|
+
1: { label: '企业' },
|
|
37
|
+
2: { label: '个体工商户' },
|
|
38
|
+
3: { label: '农民专业合作社' },
|
|
39
|
+
9: { label: '其他' },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
Y: { label: '其他', children: { 1: { label: '其他' } } },
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const pattern = /^([159][1239]|Y1)[0-9]{6}[0-9A-HJ-NP-RTUWXY]{10}$/; // 无 I O Z S V
|
|
46
|
+
|
|
47
|
+
export const Checksum = new Mod31Checksum();
|
|
48
|
+
|
|
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位,校验码
|
|
55
|
+
|
|
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);
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
bureau,
|
|
64
|
+
subjectType,
|
|
65
|
+
division,
|
|
66
|
+
subject,
|
|
67
|
+
checksum,
|
|
68
|
+
codes: [bureau, subjectType, division, subject],
|
|
69
|
+
labels,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
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
|
+
}
|
|
90
|
+
|
|
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
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return sp.map((v) => Checksum.chars[v]).join('');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 解析后的统一社会信用代码信息
|
|
109
|
+
*/
|
|
110
|
+
interface ParsedUnifiedSocialCreditCode {
|
|
111
|
+
/**
|
|
112
|
+
* @title 登记管理部门代码
|
|
113
|
+
* 对应统一社会信用代码的第1位字符,用于标识发证机构类别(登记管理部门)。
|
|
114
|
+
*/
|
|
115
|
+
bureau: string;
|
|
116
|
+
|
|
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;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @title 校验码
|
|
137
|
+
* 对应统一社会信用代码的最后一位字符,用特定算法计算,用于校验代码有效性。
|
|
138
|
+
*/
|
|
139
|
+
checksum: string;
|
|
140
|
+
|
|
141
|
+
codes: string[];
|
|
142
|
+
labels: string[];
|
|
143
|
+
}
|