@wener/utils 1.1.37 → 1.1.38
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/browsers/download.js +20 -11
- package/lib/browsers/download.js.map +1 -1
- package/lib/cn/division/DivisionCode.js +204 -0
- package/lib/cn/division/DivisionCode.js.map +1 -0
- package/lib/cn/id/Mod11Checksum.js +46 -0
- package/lib/cn/id/Mod11Checksum.js.map +1 -0
- package/lib/cn/id/ResidentIdNumber.js +89 -0
- package/lib/cn/id/ResidentIdNumber.js.map +1 -0
- package/lib/cn/id/types.js +8 -0
- package/lib/cn/id/types.js.map +1 -0
- package/lib/cn/index.js +9 -1
- package/lib/cn/index.js.map +1 -1
- package/lib/cn/uscc/Mod31Checksum.js +52 -0
- package/lib/cn/uscc/Mod31Checksum.js.map +1 -0
- package/lib/cn/uscc/USCC.js +97 -0
- package/lib/cn/uscc/USCC.js.map +1 -0
- package/lib/cn/uscc/isUSCC.js +8 -0
- package/lib/cn/uscc/isUSCC.js.map +1 -0
- package/lib/crypto/getRandomValues.js +1 -1
- package/lib/crypto/getRandomValues.js.map +1 -1
- package/lib/crypto/randomUUID.js +1 -1
- package/lib/crypto/randomUUID.js.map +1 -1
- package/lib/crypto/randomUUIDv7.js +3 -0
- package/lib/crypto/randomUUIDv7.js.map +1 -0
- package/lib/errors/Errors.js +1 -1
- package/lib/errors/Errors.js.map +1 -1
- package/lib/fetch/HttpStatus.js.map +1 -0
- package/lib/fetch/createFetchWith.js +1 -1
- package/lib/fetch/createFetchWith.js.map +1 -1
- package/lib/fetch/createFetchWithRetry.js +1 -1
- package/lib/fetch/createFetchWithRetry.js.map +1 -1
- package/lib/index.js +7 -5
- package/lib/index.js.map +1 -1
- package/lib/io/ArrayBuffers.js +58 -4
- package/lib/io/ArrayBuffers.js.map +1 -1
- package/lib/io/isTransferable.js +1 -1
- package/lib/io/isTransferable.js.map +1 -1
- package/lib/io/parseDataUri.js +57 -0
- package/lib/io/parseDataUri.js.map +1 -0
- package/lib/objects/computeIfAbsent.js +14 -0
- package/lib/objects/computeIfAbsent.js.map +1 -0
- package/lib/runtime/AsyncCloser.js.map +1 -0
- package/lib/runtime/Closer.js.map +1 -0
- package/lib/runtime/getGlobalThis.js.map +1 -0
- package/lib/runtime/structuredClone.js.map +1 -0
- package/lib/server/fetch/createFetchWithProxyByNodeFetch.js +1 -1
- package/lib/server/fetch/createFetchWithProxyByNodeFetch.js.map +1 -1
- package/lib/server/fetch/createFetchWithProxyByUndici.js +1 -1
- package/lib/server/fetch/createFetchWithProxyByUndici.js.map +1 -1
- package/lib/server/getPackageDir.js +5 -4
- package/lib/server/getPackageDir.js.map +1 -1
- package/lib/server/polyfill/polyfillCrypto.js +1 -1
- package/lib/server/polyfill/polyfillCrypto.js.map +1 -1
- package/lib/server/polyfill/polyfillJsDom.js +1 -1
- package/lib/server/polyfill/polyfillJsDom.js.map +1 -1
- package/lib/server/polyfill/polyfillWebSocket.js +1 -1
- package/lib/server/polyfill/polyfillWebSocket.js.map +1 -1
- package/package.json +18 -15
- package/src/browsers/download.ts +20 -13
- package/src/cn/division/DivisionCode.ts +109 -0
- package/src/cn/id/Mod11Checksum.ts +29 -0
- package/src/cn/id/ResidentIdNumber.ts +102 -0
- package/src/cn/id/id.test.ts +20 -0
- package/src/cn/id/types.ts +26 -0
- package/src/cn/index.ts +13 -0
- package/src/cn/uscc/Mod31Checksum.ts +42 -0
- package/src/cn/uscc/USCC.ts +98 -0
- package/src/cn/uscc/isUSCC.ts +8 -0
- package/src/cn/uscc/uscc.test.ts +16 -0
- package/src/crypto/getRandomValues.ts +1 -1
- package/src/crypto/randomUUID.ts +1 -1
- package/src/crypto/randomUUIDv7.ts +1 -0
- package/src/errors/Errors.ts +1 -1
- package/src/fetch/createFetchWith.ts +1 -1
- package/src/fetch/createFetchWithRetry.ts +1 -1
- package/src/index.ts +7 -5
- package/src/io/ArrayBuffers.base64.test.ts +24 -0
- package/src/io/ArrayBuffers.ts +106 -4
- package/src/io/isTransferable.ts +1 -1
- package/src/io/parseDataUri.test.ts +34 -0
- package/src/io/parseDataUri.ts +66 -0
- package/src/objects/computeIfAbsent.ts +15 -0
- package/src/schema/typebox/gen/README.md +2 -0
- package/src/server/fetch/createFetchWithProxyByNodeFetch.ts +1 -1
- package/src/server/fetch/createFetchWithProxyByUndici.ts +1 -1
- package/src/server/getPackageDir.ts +6 -4
- package/src/server/polyfill/polyfillCrypto.ts +1 -1
- package/src/server/polyfill/polyfillJsDom.ts +1 -1
- package/src/server/polyfill/polyfillWebSocket.ts +1 -1
- package/lib/http/HttpStatus.js.map +0 -1
- package/lib/io/Bytes.js +0 -51
- package/lib/io/Bytes.js.map +0 -1
- package/lib/isomorphics/getGlobalThis.js.map +0 -1
- package/lib/isomorphics/structuredClone.js.map +0 -1
- package/lib/langs/AsyncCloser.js.map +0 -1
- package/lib/langs/Closer.js.map +0 -1
- package/src/io/Bytes.ts +0 -64
- /package/lib/{http → fetch}/HttpStatus.js +0 -0
- /package/lib/{langs → runtime}/AsyncCloser.js +0 -0
- /package/lib/{langs → runtime}/Closer.js +0 -0
- /package/lib/{isomorphics → runtime}/getGlobalThis.js +0 -0
- /package/lib/{isomorphics → runtime}/structuredClone.js +0 -0
- /package/src/{http → fetch}/HttpStatus.ts +0 -0
- /package/src/{langs → runtime}/AsyncCloser.ts +0 -0
- /package/src/{langs → runtime}/Closer.ts +0 -0
- /package/src/{isomorphics → runtime}/getGlobalThis.ts +0 -0
- /package/src/{isomorphics → runtime}/structuredClone.test.ts +0 -0
- /package/src/{isomorphics → runtime}/structuredClone.ts +0 -0
package/lib/browsers/download.js
CHANGED
|
@@ -4,15 +4,22 @@
|
|
|
4
4
|
* @param data data or url to download
|
|
5
5
|
* @param type content type
|
|
6
6
|
* @param raw if true, data is treated as raw data, not url
|
|
7
|
-
*/ export function download(filename, data, { type = 'application/octet-stream', raw = false } = {}) {
|
|
7
|
+
*/ export async function download(filename, data, { type = 'application/octet-stream', raw = false } = {}) {
|
|
8
8
|
const a = document.createElement('a');
|
|
9
9
|
let closer = ()=>null;
|
|
10
10
|
try {
|
|
11
11
|
a.download = filename;
|
|
12
|
-
// console.info(`downloading ${name}`, data);
|
|
13
12
|
// url or data url
|
|
14
13
|
if (typeof data === 'string' && /^(https?:|data:)/.test(data) && !raw) {
|
|
15
14
|
a.href = data;
|
|
15
|
+
// 只有 same-origin 才能 download
|
|
16
|
+
if (/^https?:/.test(data)) {
|
|
17
|
+
if (new URL(data).origin !== location.origin) {
|
|
18
|
+
// 非同源
|
|
19
|
+
a.href = '';
|
|
20
|
+
data = await fetch(data).then((res)=>res.blob());
|
|
21
|
+
}
|
|
22
|
+
}
|
|
16
23
|
} else if (typeof data === 'string') {
|
|
17
24
|
data = new TextEncoder().encode(data);
|
|
18
25
|
}
|
|
@@ -23,16 +30,18 @@
|
|
|
23
30
|
type
|
|
24
31
|
});
|
|
25
32
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
{
|
|
34
|
+
if (data instanceof File || data instanceof Blob || data instanceof MediaSource) {
|
|
35
|
+
a.href = URL.createObjectURL(data);
|
|
36
|
+
closer = ()=>{
|
|
37
|
+
URL.revokeObjectURL(a.href);
|
|
38
|
+
};
|
|
39
|
+
} else {
|
|
40
|
+
console.error(`invalid download data`, data);
|
|
41
|
+
throw new Error(`can not download ${data && Object.getPrototypeOf(data)}`);
|
|
42
|
+
}
|
|
43
|
+
a.click();
|
|
34
44
|
}
|
|
35
|
-
a.click();
|
|
36
45
|
} finally{
|
|
37
46
|
closer();
|
|
38
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/browsers/download.ts"],"sourcesContent":["/**\n * Trigger browser download\n * @param filename download as filename\n * @param data data or url to download\n * @param type content type\n * @param raw if true, data is treated as raw data, not url\n */\nexport function download(filename: string, data: any, { type = 'application/octet-stream', raw = false } = {}) {\n const a = document.createElement('a');\n let closer: () => void = () => null;\n try {\n a.download = filename;\n\n //
|
|
1
|
+
{"version":3,"sources":["../../src/browsers/download.ts"],"sourcesContent":["/**\n * Trigger browser download\n * @param filename download as filename\n * @param data data or url to download\n * @param type content type\n * @param raw if true, data is treated as raw data, not url\n */\nexport async function download(filename: string, data: any, { type = 'application/octet-stream', raw = false } = {}) {\n const a = document.createElement('a');\n let closer: () => void = () => null;\n try {\n a.download = filename;\n\n // url or data url\n if (typeof data === 'string' && /^(https?:|data:)/.test(data) && !raw) {\n a.href = data;\n // 只有 same-origin 才能 download\n if (/^https?:/.test(data)) {\n if (new URL(data).origin !== location.origin) {\n // 非同源\n a.href = '';\n data = await fetch(data).then((res) => res.blob());\n }\n }\n } else if (typeof data === 'string') {\n data = new TextEncoder().encode(data);\n }\n\n if (data instanceof Uint8Array) {\n data = new Blob([data], { type });\n }\n {\n if (data instanceof File || data instanceof Blob || data instanceof MediaSource) {\n a.href = URL.createObjectURL(data);\n closer = () => {\n URL.revokeObjectURL(a.href);\n };\n } else {\n console.error(`invalid download data`, data);\n throw new Error(`can not download ${data && Object.getPrototypeOf(data)}`);\n }\n a.click();\n }\n } finally {\n closer();\n }\n}\n"],"names":["download","filename","data","type","raw","a","document","createElement","closer","test","href","URL","origin","location","fetch","then","res","blob","TextEncoder","encode","Uint8Array","Blob","File","MediaSource","createObjectURL","revokeObjectURL","console","error","Error","Object","getPrototypeOf","click"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,eAAeA,SAASC,QAAgB,EAAEC,IAAS,EAAE,EAAEC,OAAO,0BAA0B,EAAEC,MAAM,KAAK,EAAE,GAAG,CAAC,CAAC;IACjH,MAAMC,IAAIC,SAASC,aAAa,CAAC;IACjC,IAAIC,SAAqB,IAAM;IAC/B,IAAI;QACFH,EAAEL,QAAQ,GAAGC;QAEb,kBAAkB;QAClB,IAAI,OAAOC,SAAS,YAAY,mBAAmBO,IAAI,CAACP,SAAS,CAACE,KAAK;YACrEC,EAAEK,IAAI,GAAGR;YACT,6BAA6B;YAC7B,IAAI,WAAWO,IAAI,CAACP,OAAO;gBACzB,IAAI,IAAIS,IAAIT,MAAMU,MAAM,KAAKC,SAASD,MAAM,EAAE;oBAC5C,MAAM;oBACNP,EAAEK,IAAI,GAAG;oBACTR,OAAO,MAAMY,MAAMZ,MAAMa,IAAI,CAAC,CAACC,MAAQA,IAAIC,IAAI;gBACjD;YACF;QACF,OAAO,IAAI,OAAOf,SAAS,UAAU;YACnCA,OAAO,IAAIgB,cAAcC,MAAM,CAACjB;QAClC;QAEA,IAAIA,gBAAgBkB,YAAY;YAC9BlB,OAAO,IAAImB,KAAK;gBAACnB;aAAK,EAAE;gBAAEC;YAAK;QACjC;QACA;YACE,IAAID,gBAAgBoB,QAAQpB,gBAAgBmB,QAAQnB,gBAAgBqB,aAAa;gBAC/ElB,EAAEK,IAAI,GAAGC,IAAIa,eAAe,CAACtB;gBAC7BM,SAAS;oBACPG,IAAIc,eAAe,CAACpB,EAAEK,IAAI;gBAC5B;YACF,OAAO;gBACLgB,QAAQC,KAAK,CAAC,CAAC,qBAAqB,CAAC,EAAEzB;gBACvC,MAAM,IAAI0B,MAAM,CAAC,iBAAiB,EAAE1B,QAAQ2B,OAAOC,cAAc,CAAC5B,MAAM,CAAC;YAC3E;YACAG,EAAE0B,KAAK;QACT;IACF,SAAU;QACRvB;IACF;AACF"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codes for the administrative divisions of the People's Republic of China
|
|
3
|
+
*
|
|
4
|
+
* @see https://zh.wikipedia.org/wiki/GB/T_2260 中华人民共和国行政区划代码
|
|
5
|
+
*/ export class DivisionCode {
|
|
6
|
+
static Levels = {
|
|
7
|
+
Province: {
|
|
8
|
+
level: 1,
|
|
9
|
+
code: 'Province',
|
|
10
|
+
length: 2
|
|
11
|
+
},
|
|
12
|
+
City: {
|
|
13
|
+
level: 2,
|
|
14
|
+
code: 'City',
|
|
15
|
+
length: 4
|
|
16
|
+
},
|
|
17
|
+
County: {
|
|
18
|
+
level: 3,
|
|
19
|
+
code: 'County',
|
|
20
|
+
length: 6
|
|
21
|
+
},
|
|
22
|
+
Town: {
|
|
23
|
+
level: 4,
|
|
24
|
+
code: 'Town',
|
|
25
|
+
length: 9
|
|
26
|
+
},
|
|
27
|
+
Village: {
|
|
28
|
+
level: 5,
|
|
29
|
+
code: 'Village',
|
|
30
|
+
length: 12
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
static instance;
|
|
34
|
+
static get() {
|
|
35
|
+
return this.instance || (this.instance = new DivisionCode());
|
|
36
|
+
}
|
|
37
|
+
regex = /^(?<province>\d{2})(?<city>\d{2})?(?<county>\d{2})?(?<town>\d{3})?(?<village>\d{3})?$/;
|
|
38
|
+
provinces = [
|
|
39
|
+
[
|
|
40
|
+
11,
|
|
41
|
+
'北京市'
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
12,
|
|
45
|
+
'天津市'
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
13,
|
|
49
|
+
'河北省'
|
|
50
|
+
],
|
|
51
|
+
[
|
|
52
|
+
14,
|
|
53
|
+
'山西省'
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
15,
|
|
57
|
+
'内蒙古自治区'
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
21,
|
|
61
|
+
'辽宁省'
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
22,
|
|
65
|
+
'吉林省'
|
|
66
|
+
],
|
|
67
|
+
[
|
|
68
|
+
23,
|
|
69
|
+
'黑龙江省'
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
31,
|
|
73
|
+
'上海市'
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
32,
|
|
77
|
+
'江苏省'
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
33,
|
|
81
|
+
'浙江省'
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
34,
|
|
85
|
+
'安徽省'
|
|
86
|
+
],
|
|
87
|
+
[
|
|
88
|
+
35,
|
|
89
|
+
'福建省'
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
36,
|
|
93
|
+
'江西省'
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
37,
|
|
97
|
+
'山东省'
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
41,
|
|
101
|
+
'河南省'
|
|
102
|
+
],
|
|
103
|
+
[
|
|
104
|
+
42,
|
|
105
|
+
'湖北省'
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
43,
|
|
109
|
+
'湖南省'
|
|
110
|
+
],
|
|
111
|
+
[
|
|
112
|
+
44,
|
|
113
|
+
'广东省'
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
45,
|
|
117
|
+
'广西壮族自治区'
|
|
118
|
+
],
|
|
119
|
+
[
|
|
120
|
+
46,
|
|
121
|
+
'海南省'
|
|
122
|
+
],
|
|
123
|
+
[
|
|
124
|
+
50,
|
|
125
|
+
'重庆市'
|
|
126
|
+
],
|
|
127
|
+
[
|
|
128
|
+
51,
|
|
129
|
+
'四川省'
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
52,
|
|
133
|
+
'贵州省'
|
|
134
|
+
],
|
|
135
|
+
[
|
|
136
|
+
53,
|
|
137
|
+
'云南省'
|
|
138
|
+
],
|
|
139
|
+
[
|
|
140
|
+
54,
|
|
141
|
+
'西藏自治区'
|
|
142
|
+
],
|
|
143
|
+
[
|
|
144
|
+
61,
|
|
145
|
+
'陕西省'
|
|
146
|
+
],
|
|
147
|
+
[
|
|
148
|
+
62,
|
|
149
|
+
'甘肃省'
|
|
150
|
+
],
|
|
151
|
+
[
|
|
152
|
+
63,
|
|
153
|
+
'青海省'
|
|
154
|
+
],
|
|
155
|
+
[
|
|
156
|
+
64,
|
|
157
|
+
'宁夏回族自治区'
|
|
158
|
+
],
|
|
159
|
+
[
|
|
160
|
+
65,
|
|
161
|
+
'新疆维吾尔自治区'
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
71,
|
|
165
|
+
'台湾省'
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
81,
|
|
169
|
+
'香港特别行政区'
|
|
170
|
+
],
|
|
171
|
+
[
|
|
172
|
+
82,
|
|
173
|
+
'澳门特别行政区'
|
|
174
|
+
]
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
export function binarySearch(arr, value, compare) {
|
|
178
|
+
let low = 0;
|
|
179
|
+
let high = arr.length - 1;
|
|
180
|
+
while(low <= high){
|
|
181
|
+
const mid = low + high >> 1;
|
|
182
|
+
const cmp = compare(arr[mid], value);
|
|
183
|
+
if (cmp < 0) {
|
|
184
|
+
low = mid + 1;
|
|
185
|
+
} else if (cmp > 0) {
|
|
186
|
+
high = mid - 1;
|
|
187
|
+
} else {
|
|
188
|
+
return mid;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return -1;
|
|
192
|
+
} // export function getSimpleProvinceLabel(value: string) {
|
|
193
|
+
// if (!value) {
|
|
194
|
+
// return;
|
|
195
|
+
// }
|
|
196
|
+
// let label = value;
|
|
197
|
+
// if (/[0-9]/.test(label)) {
|
|
198
|
+
// label = label.slice(0, 2);
|
|
199
|
+
// label = options.find((v) => v.value === label)?.label || label;
|
|
200
|
+
// }
|
|
201
|
+
// return label.replace(/省|市|(回族|维吾尔|壮族)?自治区|特别行政区$/, '');
|
|
202
|
+
// }
|
|
203
|
+
|
|
204
|
+
//# sourceMappingURL=DivisionCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cn/division/DivisionCode.ts"],"sourcesContent":["/**\n * Codes for the administrative divisions of the People's Republic of China\n *\n * @see https://zh.wikipedia.org/wiki/GB/T_2260 中华人民共和国行政区划代码\n */\nexport class DivisionCode {\n static Levels = {\n Province: {\n level: 1,\n code: 'Province',\n length: 2,\n },\n City: {\n level: 2,\n code: 'City',\n length: 4,\n },\n County: {\n level: 3,\n code: 'County',\n length: 6,\n },\n Town: {\n level: 4,\n code: 'Town',\n length: 9,\n },\n Village: {\n level: 5,\n code: 'Village',\n length: 12,\n },\n } as const;\n\n private static instance: DivisionCode;\n\n static get() {\n return this.instance || (this.instance = new DivisionCode());\n }\n\n regex = /^(?<province>\\d{2})(?<city>\\d{2})?(?<county>\\d{2})?(?<town>\\d{3})?(?<village>\\d{3})?$/;\n\n provinces: Array<[number, string]> = [\n [11, '北京市'],\n [12, '天津市'],\n [13, '河北省'],\n [14, '山西省'],\n [15, '内蒙古自治区'],\n [21, '辽宁省'],\n [22, '吉林省'],\n [23, '黑龙江省'],\n [31, '上海市'],\n [32, '江苏省'],\n [33, '浙江省'],\n [34, '安徽省'],\n [35, '福建省'],\n [36, '江西省'],\n [37, '山东省'],\n [41, '河南省'],\n [42, '湖北省'],\n [43, '湖南省'],\n [44, '广东省'],\n [45, '广西壮族自治区'],\n [46, '海南省'],\n [50, '重庆市'],\n [51, '四川省'],\n [52, '贵州省'],\n [53, '云南省'],\n [54, '西藏自治区'],\n [61, '陕西省'],\n [62, '甘肃省'],\n [63, '青海省'],\n [64, '宁夏回族自治区'],\n [65, '新疆维吾尔自治区'],\n [71, '台湾省'],\n [81, '香港特别行政区'],\n [82, '澳门特别行政区'],\n // 9 国外\n ];\n}\n\nexport function binarySearch<T, S = number>(arr: T[], value: S, compare: (a: T, b: S) => number) {\n let low = 0;\n let high = arr.length - 1;\n while (low <= high) {\n const mid = (low + high) >> 1;\n const cmp = compare(arr[mid], value);\n if (cmp < 0) {\n low = mid + 1;\n } else if (cmp > 0) {\n high = mid - 1;\n } else {\n return mid;\n }\n }\n return -1;\n}\n\n// export function getSimpleProvinceLabel(value: string) {\n// if (!value) {\n// return;\n// }\n// let label = value;\n// if (/[0-9]/.test(label)) {\n// label = label.slice(0, 2);\n// label = options.find((v) => v.value === label)?.label || label;\n// }\n// return label.replace(/省|市|(回族|维吾尔|壮族)?自治区|特别行政区$/, '');\n// }\n"],"names":["DivisionCode","Levels","Province","level","code","length","City","County","Town","Village","instance","get","regex","provinces","binarySearch","arr","value","compare","low","high","mid","cmp"],"mappings":"AAAA;;;;CAIC,GACD,OAAO,MAAMA;IACX,OAAOC,SAAS;QACdC,UAAU;YACRC,OAAO;YACPC,MAAM;YACNC,QAAQ;QACV;QACAC,MAAM;YACJH,OAAO;YACPC,MAAM;YACNC,QAAQ;QACV;QACAE,QAAQ;YACNJ,OAAO;YACPC,MAAM;YACNC,QAAQ;QACV;QACAG,MAAM;YACJL,OAAO;YACPC,MAAM;YACNC,QAAQ;QACV;QACAI,SAAS;YACPN,OAAO;YACPC,MAAM;YACNC,QAAQ;QACV;IACF,EAAW;IAEX,OAAeK,SAAuB;IAEtC,OAAOC,MAAM;QACX,OAAO,IAAI,CAACD,QAAQ,IAAK,CAAA,IAAI,CAACA,QAAQ,GAAG,IAAIV,cAAa;IAC5D;IAEAY,QAAQ,wFAAwF;IAEhGC,YAAqC;QACnC;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAS;QACd;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAO;QACZ;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAU;QACf;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAQ;QACb;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAU;QACf;YAAC;YAAI;SAAW;QAChB;YAAC;YAAI;SAAM;QACX;YAAC;YAAI;SAAU;QACf;YAAC;YAAI;SAAU;KAEhB,CAAC;AACJ;AAEA,OAAO,SAASC,aAA4BC,GAAQ,EAAEC,KAAQ,EAAEC,OAA+B;IAC7F,IAAIC,MAAM;IACV,IAAIC,OAAOJ,IAAIV,MAAM,GAAG;IACxB,MAAOa,OAAOC,KAAM;QAClB,MAAMC,MAAM,AAACF,MAAMC,QAAS;QAC5B,MAAME,MAAMJ,QAAQF,GAAG,CAACK,IAAI,EAAEJ;QAC9B,IAAIK,MAAM,GAAG;YACXH,MAAME,MAAM;QACd,OAAO,IAAIC,MAAM,GAAG;YAClBF,OAAOC,MAAM;QACf,OAAO;YACL,OAAOA;QACT;IACF;IACA,OAAO,CAAC;AACV,EAEA,0DAA0D;CAC1D,kBAAkB;CAClB,cAAc;CACd,MAAM;CACN,uBAAuB;CACvB,+BAA+B;CAC/B,iCAAiC;CACjC,sEAAsE;CACtE,MAAM;CACN,4DAA4D;CAC5D,IAAI"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ISO 7064:1983, MOD 11-2.
|
|
3
|
+
*/ export class Mod11Checksum {
|
|
4
|
+
weights = [
|
|
5
|
+
7,
|
|
6
|
+
9,
|
|
7
|
+
10,
|
|
8
|
+
5,
|
|
9
|
+
8,
|
|
10
|
+
4,
|
|
11
|
+
2,
|
|
12
|
+
1,
|
|
13
|
+
6,
|
|
14
|
+
3,
|
|
15
|
+
7,
|
|
16
|
+
9,
|
|
17
|
+
10,
|
|
18
|
+
5,
|
|
19
|
+
8,
|
|
20
|
+
4,
|
|
21
|
+
2,
|
|
22
|
+
1
|
|
23
|
+
];
|
|
24
|
+
static instance;
|
|
25
|
+
static get() {
|
|
26
|
+
return this.instance || (this.instance = new Mod11Checksum());
|
|
27
|
+
}
|
|
28
|
+
verify(s) {
|
|
29
|
+
return s.at(-1) === this.generate(s.slice(0, s.length - 1));
|
|
30
|
+
}
|
|
31
|
+
generate(s) {
|
|
32
|
+
const { weights } = this;
|
|
33
|
+
let sum = 0;
|
|
34
|
+
for(let i = 0; i < s.length; i++){
|
|
35
|
+
sum += parseInt(s[i]) * weights[i];
|
|
36
|
+
}
|
|
37
|
+
const num = (12 - sum % 11) % 11;
|
|
38
|
+
if (num < 10) {
|
|
39
|
+
return num.toString();
|
|
40
|
+
} else {
|
|
41
|
+
return 'X';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=Mod11Checksum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cn/id/Mod11Checksum.ts"],"sourcesContent":["/**\n * ISO 7064:1983, MOD 11-2.\n */\nexport class Mod11Checksum {\n weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];\n private static instance: Mod11Checksum;\n\n static get() {\n return this.instance || (this.instance = new Mod11Checksum());\n }\n\n verify(s: string) {\n return s.at(-1) === this.generate(s.slice(0, s.length - 1));\n }\n\n generate(s: string) {\n const { weights } = this;\n let sum = 0;\n for (let i = 0; i < s.length; i++) {\n sum += parseInt(s[i]) * weights[i];\n }\n const num = (12 - (sum % 11)) % 11;\n if (num < 10) {\n return num.toString();\n } else {\n return 'X';\n }\n }\n}\n"],"names":["Mod11Checksum","weights","instance","get","verify","s","at","generate","slice","length","sum","i","parseInt","num","toString"],"mappings":"AAAA;;CAEC,GACD,OAAO,MAAMA;IACXC,UAAU;QAAC;QAAG;QAAG;QAAI;QAAG;QAAG;QAAG;QAAG;QAAG;QAAG;QAAG;QAAG;QAAG;QAAI;QAAG;QAAG;QAAG;QAAG;KAAE,CAAC;IACnE,OAAeC,SAAwB;IAEvC,OAAOC,MAAM;QACX,OAAO,IAAI,CAACD,QAAQ,IAAK,CAAA,IAAI,CAACA,QAAQ,GAAG,IAAIF,eAAc;IAC7D;IAEAI,OAAOC,CAAS,EAAE;QAChB,OAAOA,EAAEC,EAAE,CAAC,CAAC,OAAO,IAAI,CAACC,QAAQ,CAACF,EAAEG,KAAK,CAAC,GAAGH,EAAEI,MAAM,GAAG;IAC1D;IAEAF,SAASF,CAAS,EAAE;QAClB,MAAM,EAAEJ,OAAO,EAAE,GAAG,IAAI;QACxB,IAAIS,MAAM;QACV,IAAK,IAAIC,IAAI,GAAGA,IAAIN,EAAEI,MAAM,EAAEE,IAAK;YACjCD,OAAOE,SAASP,CAAC,CAACM,EAAE,IAAIV,OAAO,CAACU,EAAE;QACpC;QACA,MAAME,MAAM,AAAC,CAAA,KAAMH,MAAM,EAAE,IAAK;QAChC,IAAIG,MAAM,IAAI;YACZ,OAAOA,IAAIC,QAAQ;QACrB,OAAO;YACL,OAAO;QACT;IACF;AACF"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Mod11Checksum } from './Mod11Checksum.js';
|
|
2
|
+
export class ResidentIdNumber {
|
|
3
|
+
checksum = Mod11Checksum.get();
|
|
4
|
+
// 9 https://zh.wikipedia.org/wiki/中华人民共和国外国人永久居留身份证
|
|
5
|
+
// 9 标识码
|
|
6
|
+
// 申领地代码 - 2 位行政区划
|
|
7
|
+
// 国籍国代码 - 3 位数字 https://zh.wikipedia.org/wiki/ISO_3166-1数字代码
|
|
8
|
+
regex = /^(?<division>[1-9]\d{5})(?<year>18|19|20)\d{2}(?<month>0[1-9]|1[0-2])(?<day>0[1-9]|[12]\d|3[01])(?<sequence>\d{3})(?<checksum>[0-9Xx])$/;
|
|
9
|
+
static instance;
|
|
10
|
+
static get() {
|
|
11
|
+
return this.instance ||= new ResidentIdNumber();
|
|
12
|
+
}
|
|
13
|
+
verify(s) {
|
|
14
|
+
if (!s) return false;
|
|
15
|
+
return this.regex.test(s) && this.checksum.verify(s.toUpperCase());
|
|
16
|
+
}
|
|
17
|
+
parse(s) {
|
|
18
|
+
if (!this.verify(s)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
let date = s.slice(6, 14);
|
|
22
|
+
let y = parseInt(date.slice(0, 4));
|
|
23
|
+
let m = parseInt(date.slice(4, 6));
|
|
24
|
+
let d = parseInt(date.slice(6));
|
|
25
|
+
return new IdNumber(s.slice(0, 6), new Date(`${y}-${m}-${d}`), // new Date(y, m - 1, d, 0, 0, 0, 0), // 有时区问题
|
|
26
|
+
parseInt(s.slice(14, 17)), s.slice(17, 18).toUpperCase());
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
let IdNumber = class IdNumber {
|
|
30
|
+
division;
|
|
31
|
+
date;
|
|
32
|
+
sequence;
|
|
33
|
+
checksum;
|
|
34
|
+
constructor(division, date, sequence, checksum){
|
|
35
|
+
this.division = division;
|
|
36
|
+
this.date = date;
|
|
37
|
+
this.sequence = sequence;
|
|
38
|
+
this.checksum = checksum;
|
|
39
|
+
}
|
|
40
|
+
toString() {
|
|
41
|
+
return this.subject + this.checksum;
|
|
42
|
+
}
|
|
43
|
+
toJSON() {
|
|
44
|
+
return this.toString();
|
|
45
|
+
}
|
|
46
|
+
toObject() {
|
|
47
|
+
const { division, date, sequence, checksum } = this;
|
|
48
|
+
return {
|
|
49
|
+
division,
|
|
50
|
+
date,
|
|
51
|
+
sequence,
|
|
52
|
+
checksum
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
get male() {
|
|
56
|
+
return this.sequence % 2 === 1;
|
|
57
|
+
}
|
|
58
|
+
get female() {
|
|
59
|
+
return this.sequence % 2 === 0;
|
|
60
|
+
}
|
|
61
|
+
get age() {
|
|
62
|
+
return new Date().getFullYear() - this.date.getFullYear();
|
|
63
|
+
}
|
|
64
|
+
get gender() {
|
|
65
|
+
return this.sequence % 2 === 1 ? 'male' : 'female';
|
|
66
|
+
}
|
|
67
|
+
get subject() {
|
|
68
|
+
return [
|
|
69
|
+
this.division,
|
|
70
|
+
formatDate(this.date, 'YYYYMMDD'),
|
|
71
|
+
this.sequence.toString().padStart(3, '0')
|
|
72
|
+
].join('');
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
function formatDate(date, format = 'YYYYMMDD') {
|
|
76
|
+
switch(format){
|
|
77
|
+
case 'YYYYMMDD':
|
|
78
|
+
{
|
|
79
|
+
const year = date.getFullYear();
|
|
80
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
81
|
+
const day = date.getDate().toString().padStart(2, '0');
|
|
82
|
+
return `${year}${month}${day}`;
|
|
83
|
+
}
|
|
84
|
+
default:
|
|
85
|
+
throw new Error(`Invalid format`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=ResidentIdNumber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cn/id/ResidentIdNumber.ts"],"sourcesContent":["import { Mod11Checksum } from './Mod11Checksum';\n\nexport class ResidentIdNumber {\n checksum = Mod11Checksum.get();\n\n // 9 https://zh.wikipedia.org/wiki/中华人民共和国外国人永久居留身份证\n // 9 标识码\n // 申领地代码 - 2 位行政区划\n // 国籍国代码 - 3 位数字 https://zh.wikipedia.org/wiki/ISO_3166-1数字代码\n\n regex =\n /^(?<division>[1-9]\\d{5})(?<year>18|19|20)\\d{2}(?<month>0[1-9]|1[0-2])(?<day>0[1-9]|[12]\\d|3[01])(?<sequence>\\d{3})(?<checksum>[0-9Xx])$/;\n\n private static instance: ResidentIdNumber;\n\n static get() {\n return (this.instance ||= new ResidentIdNumber());\n }\n\n verify(s: string) {\n if (!s) return false;\n return this.regex.test(s) && this.checksum.verify(s.toUpperCase());\n }\n\n parse(s: string): IdNumber | undefined {\n if (!this.verify(s)) {\n return;\n }\n\n let date = s.slice(6, 14);\n let y = parseInt(date.slice(0, 4));\n let m = parseInt(date.slice(4, 6));\n let d = parseInt(date.slice(6));\n return new IdNumber(\n s.slice(0, 6),\n new Date(`${y}-${m}-${d}`), // YYYYMMDD\n // new Date(y, m - 1, d, 0, 0, 0, 0), // 有时区问题\n parseInt(s.slice(14, 17)),\n s.slice(17, 18).toUpperCase(),\n );\n }\n}\n\nclass IdNumber {\n constructor(\n public division: string,\n public date: Date,\n public sequence: number,\n public checksum: string,\n ) {}\n\n toString() {\n return this.subject + this.checksum;\n }\n\n toJSON() {\n return this.toString();\n }\n\n toObject() {\n const { division, date, sequence, checksum } = this;\n return {\n division,\n date,\n sequence,\n checksum,\n };\n }\n\n get male() {\n return this.sequence % 2 === 1;\n }\n\n get female() {\n return this.sequence % 2 === 0;\n }\n\n get age() {\n return new Date().getFullYear() - this.date.getFullYear();\n }\n\n get gender(): 'male' | 'female' {\n return this.sequence % 2 === 1 ? 'male' : 'female';\n }\n\n get subject() {\n return [this.division, formatDate(this.date, 'YYYYMMDD'), this.sequence.toString().padStart(3, '0')].join('');\n }\n}\n\nfunction formatDate(date: Date, format = 'YYYYMMDD') {\n switch (format) {\n case 'YYYYMMDD': {\n const year = date.getFullYear();\n const month = (date.getMonth() + 1).toString().padStart(2, '0');\n const day = date.getDate().toString().padStart(2, '0');\n return `${year}${month}${day}`;\n }\n default:\n throw new Error(`Invalid format`);\n }\n}\n"],"names":["Mod11Checksum","ResidentIdNumber","checksum","get","regex","instance","verify","s","test","toUpperCase","parse","date","slice","y","parseInt","m","d","IdNumber","Date","constructor","division","sequence","toString","subject","toJSON","toObject","male","female","age","getFullYear","gender","formatDate","padStart","join","format","year","month","getMonth","day","getDate","Error"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cn/id/types.ts"],"sourcesContent":["/**\n * 居民身份证\n *\n * @see https://en.wikipedia.org/wiki/Resident_Identity_Card\n * @see https://en.wikipedia.org/wiki/Foreign_Permanent_Resident_ID_Card\n */\nexport interface ResidentIdentityCard {\n // 姓名\n name: string;\n // 性别\n gender: string;\n // 民族\n ethnicity: string;\n // 出生日期\n birthDate: Date;\n // 地址\n domicile: string;\n // 身份证号\n idNumber: string;\n // 签发机关\n issuingAuthority: string;\n // 有效期开始日期\n validStartDate: Date;\n // 有效期结束日期\n validEndDate?: Date;\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GACD,WAmBC"}
|
package/lib/cn/index.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* China related utilities.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/ export { parseChineseNumber } from './parseChineseNumber.js';
|
|
6
|
+
export { isUSCC } from './uscc/isUSCC.js';
|
|
7
|
+
export { USCC } from './uscc/USCC.js';
|
|
8
|
+
export { ResidentIdNumber } from './id/ResidentIdNumber.js';
|
|
9
|
+
export { DivisionCode } from './division/DivisionCode.js';
|
|
2
10
|
|
|
3
11
|
//# sourceMappingURL=index.js.map
|
package/lib/cn/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cn/index.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../src/cn/index.ts"],"sourcesContent":["/**\n * China related utilities.\n *\n * @packageDocumentation\n */\n\nexport { parseChineseNumber } from './parseChineseNumber';\n\nexport { isUSCC } from './uscc/isUSCC';\nexport { USCC } from './uscc/USCC';\n\nexport { ResidentIdNumber } from './id/ResidentIdNumber';\n\nexport { DivisionCode } from './division/DivisionCode';\n"],"names":["parseChineseNumber","isUSCC","USCC","ResidentIdNumber","DivisionCode"],"mappings":"AAAA;;;;CAIC,GAED,SAASA,kBAAkB,QAAQ,uBAAuB;AAE1D,SAASC,MAAM,QAAQ,gBAAgB;AACvC,SAASC,IAAI,QAAQ,cAAc;AAEnC,SAASC,gBAAgB,QAAQ,wBAAwB;AAEzD,SAASC,YAAY,QAAQ,0BAA0B"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GB/T 17710(采ISO 7064)的模31校验码
|
|
3
|
+
*
|
|
4
|
+
* Mod31-3
|
|
5
|
+
*/ export class Mod31Checksum {
|
|
6
|
+
weights = [
|
|
7
|
+
1,
|
|
8
|
+
3,
|
|
9
|
+
9,
|
|
10
|
+
27,
|
|
11
|
+
19,
|
|
12
|
+
26,
|
|
13
|
+
16,
|
|
14
|
+
17,
|
|
15
|
+
20,
|
|
16
|
+
29,
|
|
17
|
+
25,
|
|
18
|
+
13,
|
|
19
|
+
8,
|
|
20
|
+
24,
|
|
21
|
+
10,
|
|
22
|
+
30,
|
|
23
|
+
28
|
|
24
|
+
];
|
|
25
|
+
chars = '0123456789ABCDEFGHJKLMNPQRTUWXY';
|
|
26
|
+
numbers = this.chars.split('').reduce((acc, cur, i)=>{
|
|
27
|
+
acc[cur] = i;
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
|
30
|
+
static instance;
|
|
31
|
+
static get() {
|
|
32
|
+
return this.instance || (this.instance = new Mod31Checksum());
|
|
33
|
+
}
|
|
34
|
+
toChar(n) {
|
|
35
|
+
return this.chars[n];
|
|
36
|
+
}
|
|
37
|
+
toNumber(c) {
|
|
38
|
+
return this.numbers[c];
|
|
39
|
+
}
|
|
40
|
+
verify(s) {
|
|
41
|
+
return s.at(-1) === this.generate(s.slice(0, s.length - 1));
|
|
42
|
+
}
|
|
43
|
+
generate(s) {
|
|
44
|
+
let sum = 0;
|
|
45
|
+
for(let i = 0; i < s.length; i++){
|
|
46
|
+
sum += this.numbers[s[i]] * this.weights[i];
|
|
47
|
+
}
|
|
48
|
+
return this.toChar(31 - sum % 31);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=Mod31Checksum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cn/uscc/Mod31Checksum.ts"],"sourcesContent":["/**\n * GB/T 17710(采ISO 7064)的模31校验码\n *\n * Mod31-3\n */\nexport class Mod31Checksum {\n weights = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];\n chars = '0123456789ABCDEFGHJKLMNPQRTUWXY';\n numbers: Record<string, number> = this.chars.split('').reduce(\n (acc, cur, i) => {\n acc[cur] = i;\n return acc;\n },\n {} as Record<string, number>,\n );\n\n private static instance: Mod31Checksum;\n\n static get() {\n return this.instance || (this.instance = new Mod31Checksum());\n }\n\n toChar(n: number) {\n return this.chars[n];\n }\n\n toNumber(c: string) {\n return this.numbers[c];\n }\n\n verify(s: string) {\n return s.at(-1) === this.generate(s.slice(0, s.length - 1));\n }\n\n generate(s: string) {\n let sum = 0;\n for (let i = 0; i < s.length; i++) {\n sum += this.numbers[s[i]] * this.weights[i];\n }\n return this.toChar(31 - (sum % 31));\n }\n}\n"],"names":["Mod31Checksum","weights","chars","numbers","split","reduce","acc","cur","i","instance","get","toChar","n","toNumber","c","verify","s","at","generate","slice","length","sum"],"mappings":"AAAA;;;;CAIC,GACD,OAAO,MAAMA;IACXC,UAAU;QAAC;QAAG;QAAG;QAAG;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QAAG;QAAI;QAAI;QAAI;KAAG,CAAC;IAC3EC,QAAQ,kCAAkC;IAC1CC,UAAkC,IAAI,CAACD,KAAK,CAACE,KAAK,CAAC,IAAIC,MAAM,CAC3D,CAACC,KAAKC,KAAKC;QACTF,GAAG,CAACC,IAAI,GAAGC;QACX,OAAOF;IACT,GACA,CAAC,GACD;IAEF,OAAeG,SAAwB;IAEvC,OAAOC,MAAM;QACX,OAAO,IAAI,CAACD,QAAQ,IAAK,CAAA,IAAI,CAACA,QAAQ,GAAG,IAAIT,eAAc;IAC7D;IAEAW,OAAOC,CAAS,EAAE;QAChB,OAAO,IAAI,CAACV,KAAK,CAACU,EAAE;IACtB;IAEAC,SAASC,CAAS,EAAE;QAClB,OAAO,IAAI,CAACX,OAAO,CAACW,EAAE;IACxB;IAEAC,OAAOC,CAAS,EAAE;QAChB,OAAOA,EAAEC,EAAE,CAAC,CAAC,OAAO,IAAI,CAACC,QAAQ,CAACF,EAAEG,KAAK,CAAC,GAAGH,EAAEI,MAAM,GAAG;IAC1D;IAEAF,SAASF,CAAS,EAAE;QAClB,IAAIK,MAAM;QACV,IAAK,IAAIb,IAAI,GAAGA,IAAIQ,EAAEI,MAAM,EAAEZ,IAAK;YACjCa,OAAO,IAAI,CAAClB,OAAO,CAACa,CAAC,CAACR,EAAE,CAAC,GAAG,IAAI,CAACP,OAAO,CAACO,EAAE;QAC7C;QACA,OAAO,IAAI,CAACG,MAAM,CAAC,KAAMU,MAAM;IACjC;AACF"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Mod31Checksum } from './Mod31Checksum.js';
|
|
2
|
+
/**
|
|
3
|
+
* - GB 32100-2015 法人和其他组织统一社会信用代码编码规则
|
|
4
|
+
* - USCI -> UnifiedSocialCreditIdentifier
|
|
5
|
+
* - USCC -> Unified Social Credit Code - 官方叫法
|
|
6
|
+
* - Business License
|
|
7
|
+
*
|
|
8
|
+
* @see https://en.wikipedia.org/wiki/Unified_Social_Credit_Identifier
|
|
9
|
+
*/ export class USCC {
|
|
10
|
+
registryCodeLabels = {
|
|
11
|
+
1: {
|
|
12
|
+
label: '机构编制',
|
|
13
|
+
children: {
|
|
14
|
+
1: {
|
|
15
|
+
label: '机关'
|
|
16
|
+
},
|
|
17
|
+
2: {
|
|
18
|
+
label: '事业单位'
|
|
19
|
+
},
|
|
20
|
+
3: {
|
|
21
|
+
label: '中央编办直接管理机构编制的群众团体'
|
|
22
|
+
},
|
|
23
|
+
9: {
|
|
24
|
+
label: '其他'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
5: {
|
|
29
|
+
label: '民政',
|
|
30
|
+
children: {
|
|
31
|
+
1: {
|
|
32
|
+
label: '社会团体'
|
|
33
|
+
},
|
|
34
|
+
2: {
|
|
35
|
+
label: '民办非企业单位'
|
|
36
|
+
},
|
|
37
|
+
3: {
|
|
38
|
+
label: '基金会'
|
|
39
|
+
},
|
|
40
|
+
9: {
|
|
41
|
+
label: '其他'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
9: {
|
|
46
|
+
label: '工商',
|
|
47
|
+
children: {
|
|
48
|
+
1: {
|
|
49
|
+
label: '企业'
|
|
50
|
+
},
|
|
51
|
+
2: {
|
|
52
|
+
label: '个体工商户'
|
|
53
|
+
},
|
|
54
|
+
3: {
|
|
55
|
+
label: '农民专业合作社'
|
|
56
|
+
},
|
|
57
|
+
9: {
|
|
58
|
+
label: '其他'
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
Y: {
|
|
63
|
+
label: '其他',
|
|
64
|
+
children: {
|
|
65
|
+
1: {
|
|
66
|
+
label: '其他'
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
/* 16 位 */ regex = /^([159][1239]|Y1)[0-9]{6}[0-9A-HJ-NP-RTUWXY]{10}$/;
|
|
72
|
+
checksum = Mod31Checksum.get();
|
|
73
|
+
static instance;
|
|
74
|
+
static get() {
|
|
75
|
+
return this.instance ||= new USCC();
|
|
76
|
+
}
|
|
77
|
+
parse(s) {
|
|
78
|
+
let registryCode = s[0];
|
|
79
|
+
let l1 = this.registryCodeLabels[registryCode];
|
|
80
|
+
let organizationTypeCode = s[1];
|
|
81
|
+
return {
|
|
82
|
+
registryAuthorityCode: registryCode,
|
|
83
|
+
registryAuthorityCodeLabel: l1?.label,
|
|
84
|
+
organizationTypeCode,
|
|
85
|
+
organizationTypeLabel: l1?.children?.[organizationTypeCode]?.label,
|
|
86
|
+
registryDivisionCode: s.slice(3, 6),
|
|
87
|
+
// GB 11714-1997 全国组织机构代码编制规则
|
|
88
|
+
subject: s.slice(6, 15),
|
|
89
|
+
checksum: s.slice(17, 18)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
verify(s) {
|
|
93
|
+
return this.regex.test(s) && this.checksum.verify(s);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=USCC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cn/uscc/USCC.ts"],"sourcesContent":["import { Mod31Checksum } from './Mod31Checksum';\n\n/**\n * - GB 32100-2015 法人和其他组织统一社会信用代码编码规则\n * - USCI -> UnifiedSocialCreditIdentifier\n * - USCC -> Unified Social Credit Code - 官方叫法\n * - Business License\n *\n * @see https://en.wikipedia.org/wiki/Unified_Social_Credit_Identifier\n */\nexport class USCC {\n registryCodeLabels: Record<string, Code> = {\n 1: {\n label: '机构编制',\n children: {\n 1: { label: '机关' },\n 2: { label: '事业单位' },\n 3: { label: '中央编办直接管理机构编制的群众团体' },\n 9: { label: '其他' },\n },\n },\n 5: {\n label: '民政',\n children: {\n 1: { label: '社会团体' },\n 2: { label: '民办非企业单位' },\n 3: { label: '基金会' },\n 9: { label: '其他' },\n },\n },\n 9: {\n label: '工商',\n children: {\n 1: { label: '企业' },\n 2: { label: '个体工商户' },\n 3: { label: '农民专业合作社' },\n 9: { label: '其他' },\n },\n },\n Y: {\n label: '其他',\n children: {\n 1: { label: '其他' },\n },\n },\n };\n\n /* 16 位 */\n regex = /^([159][1239]|Y1)[0-9]{6}[0-9A-HJ-NP-RTUWXY]{10}$/; // 无 I O Z S V\n checksum = Mod31Checksum.get();\n\n static instance: USCC;\n\n static get() {\n return (this.instance ||= new USCC());\n }\n\n parse(s: string): ParsedUSCC {\n let registryCode = s[0];\n let l1 = this.registryCodeLabels[registryCode];\n let organizationTypeCode = s[1];\n return {\n registryAuthorityCode: registryCode,\n registryAuthorityCodeLabel: l1?.label,\n organizationTypeCode,\n organizationTypeLabel: l1?.children?.[organizationTypeCode]?.label,\n registryDivisionCode: s.slice(3, 6),\n // GB 11714-1997 全国组织机构代码编制规则\n subject: s.slice(6, 15),\n checksum: s.slice(17, 18),\n };\n }\n\n verify(s: string) {\n return this.regex.test(s) && this.checksum.verify(s);\n }\n}\n\ninterface Code {\n label: string;\n children?: Record<string, Code>;\n}\n\ninterface ParsedUSCC {\n // 登记管理部门码\n registryAuthorityCode: string;\n registryAuthorityCodeLabel?: string;\n // 机构类别代码\n organizationTypeCode: string;\n organizationTypeLabel?: string;\n // 登记管理机关行政区划代码\n registryDivisionCode: string;\n registryDivisionLabel?: string;\n // 主体标识码\n subject: string;\n // 校验码\n checksum: string;\n}\n"],"names":["Mod31Checksum","USCC","registryCodeLabels","label","children","Y","regex","checksum","get","instance","parse","s","registryCode","l1","organizationTypeCode","registryAuthorityCode","registryAuthorityCodeLabel","organizationTypeLabel","registryDivisionCode","slice","subject","verify","test"],"mappings":"AAAA,SAASA,aAAa,QAAQ,kBAAkB;AAEhD;;;;;;;CAOC,GACD,OAAO,MAAMC;IACXC,qBAA2C;QACzC,GAAG;YACDC,OAAO;YACPC,UAAU;gBACR,GAAG;oBAAED,OAAO;gBAAK;gBACjB,GAAG;oBAAEA,OAAO;gBAAO;gBACnB,GAAG;oBAAEA,OAAO;gBAAoB;gBAChC,GAAG;oBAAEA,OAAO;gBAAK;YACnB;QACF;QACA,GAAG;YACDA,OAAO;YACPC,UAAU;gBACR,GAAG;oBAAED,OAAO;gBAAO;gBACnB,GAAG;oBAAEA,OAAO;gBAAU;gBACtB,GAAG;oBAAEA,OAAO;gBAAM;gBAClB,GAAG;oBAAEA,OAAO;gBAAK;YACnB;QACF;QACA,GAAG;YACDA,OAAO;YACPC,UAAU;gBACR,GAAG;oBAAED,OAAO;gBAAK;gBACjB,GAAG;oBAAEA,OAAO;gBAAQ;gBACpB,GAAG;oBAAEA,OAAO;gBAAU;gBACtB,GAAG;oBAAEA,OAAO;gBAAK;YACnB;QACF;QACAE,GAAG;YACDF,OAAO;YACPC,UAAU;gBACR,GAAG;oBAAED,OAAO;gBAAK;YACnB;QACF;IACF,EAAE;IAEF,QAAQ,GACRG,QAAQ,oDAAoD;IAC5DC,WAAWP,cAAcQ,GAAG,GAAG;IAE/B,OAAOC,SAAe;IAEtB,OAAOD,MAAM;QACX,OAAQ,IAAI,CAACC,QAAQ,KAAK,IAAIR;IAChC;IAEAS,MAAMC,CAAS,EAAc;QAC3B,IAAIC,eAAeD,CAAC,CAAC,EAAE;QACvB,IAAIE,KAAK,IAAI,CAACX,kBAAkB,CAACU,aAAa;QAC9C,IAAIE,uBAAuBH,CAAC,CAAC,EAAE;QAC/B,OAAO;YACLI,uBAAuBH;YACvBI,4BAA4BH,IAAIV;YAChCW;YACAG,uBAAuBJ,IAAIT,UAAU,CAACU,qBAAqB,EAAEX;YAC7De,sBAAsBP,EAAEQ,KAAK,CAAC,GAAG;YACjC,6BAA6B;YAC7BC,SAAST,EAAEQ,KAAK,CAAC,GAAG;YACpBZ,UAAUI,EAAEQ,KAAK,CAAC,IAAI;QACxB;IACF;IAEAE,OAAOV,CAAS,EAAE;QAChB,OAAO,IAAI,CAACL,KAAK,CAACgB,IAAI,CAACX,MAAM,IAAI,CAACJ,QAAQ,CAACc,MAAM,CAACV;IACpD;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cn/uscc/isUSCC.ts"],"sourcesContent":["import { USCC } from './USCC';\n\n/**\n * USCC - 统一社会信用代码\n */\nexport function isUSCC(s: string) {\n return USCC.get().verify(s);\n}\n"],"names":["USCC","isUSCC","s","get","verify"],"mappings":"AAAA,SAASA,IAAI,QAAQ,SAAS;AAE9B;;CAEC,GACD,OAAO,SAASC,OAAOC,CAAS;IAC9B,OAAOF,KAAKG,GAAG,GAAGC,MAAM,CAACF;AAC3B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
2
|
-
import { getGlobalThis } from '../
|
|
2
|
+
import { getGlobalThis } from '../runtime/getGlobalThis.js';
|
|
3
3
|
import { getNodeCrypto } from './getNodeCrypto.js';
|
|
4
4
|
const globalThis = getGlobalThis();
|
|
5
5
|
export let getRandomValues = globalThis.crypto?.getRandomValues?.bind(globalThis.crypto) || globalThis.msCrypto?.getRandomValues?.bind(globalThis.msCrypto) || _getRandomValues;
|