@wener/utils 1.1.39 → 1.1.41
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/README.md +24 -0
- package/lib/asyncs/createAsyncIterator.js.map +1 -1
- package/lib/asyncs/createLazyPromise.js.map +1 -1
- package/lib/asyncs/firstOfAsyncIterator.js.map +1 -1
- package/lib/asyncs/nextOfAsyncIterator.js.map +1 -1
- package/lib/cn/division/DivisionCode.js +35 -43
- package/lib/cn/division/DivisionCode.js.map +1 -1
- package/lib/cn/division/binarySearch.js +27 -0
- package/lib/cn/division/binarySearch.js.map +1 -0
- package/lib/cn/id/ResidentIdNumber.js +25 -14
- package/lib/cn/id/ResidentIdNumber.js.map +1 -1
- package/lib/cn/index.js +1 -0
- package/lib/cn/index.js.map +1 -1
- package/lib/cn/pinyin/cartesianProduct.js +22 -0
- package/lib/cn/pinyin/cartesianProduct.js.map +1 -0
- package/lib/cn/pinyin/data.json +413 -0
- package/lib/cn/pinyin/toPinyinPure.js +58 -0
- package/lib/cn/pinyin/toPinyinPure.js.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/langs/mixin.js +22 -0
- package/lib/langs/mixin.js.map +1 -0
- package/lib/logging/createChildLogger.js.map +1 -1
- package/lib/objects/get.js.map +1 -1
- package/lib/objects/set.js.map +1 -1
- package/lib/schema/typebox/gen/codegen/typescript/typescript-to-model.js +1 -1
- package/lib/schema/typebox/gen/codegen/typescript/typescript-to-model.js.map +1 -1
- package/lib/scripts/getGenerateContext.js +86 -0
- package/lib/scripts/getGenerateContext.js.map +1 -0
- package/lib/types.d.js.map +1 -1
- package/package.json +2 -1
- package/src/asyncs/createAsyncIterator.ts +1 -1
- package/src/asyncs/createLazyPromise.ts +1 -1
- package/src/asyncs/firstOfAsyncIterator.ts +1 -1
- package/src/asyncs/nextOfAsyncIterator.ts +1 -1
- package/src/cn/README.md +3 -0
- package/src/cn/division/DivisionCode.ts +37 -44
- package/src/cn/division/binarySearch.test.ts +64 -0
- package/src/cn/division/binarySearch.ts +25 -0
- package/src/cn/id/ResidentIdNumber.ts +38 -12
- package/src/cn/id/id.test.ts +1 -1
- package/src/cn/index.ts +2 -0
- package/src/cn/pinyin/cartesianProduct.test.ts +64 -0
- package/src/cn/pinyin/cartesianProduct.ts +24 -0
- package/src/cn/pinyin/data.json +413 -0
- package/src/cn/pinyin/toPinyin.test.ts +11 -0
- package/src/cn/pinyin/toPinyinPure.ts +68 -0
- package/src/cn/scripts/gen.test.ts +130 -0
- package/src/cn/uscc/uscc.test.ts +2 -2
- package/src/index.ts +3 -0
- package/src/io/ArrayBuffers.base64.test.ts +1 -1
- package/src/io/ArrayBuffers.test.ts +1 -1
- package/src/io/Buffer.test.ts +1 -1
- package/src/langs/README.md +4 -0
- package/src/langs/mixin.ts +82 -0
- package/src/logging/createChildLogger.ts +1 -1
- package/src/logging/logger.test.ts +1 -1
- package/src/modules/parseModuleId.test.ts +1 -1
- package/src/objects/get.ts +1 -2
- package/src/objects/parseObjectPath.test.ts +1 -1
- package/src/objects/set.test.ts +1 -1
- package/src/objects/set.ts +1 -2
- package/src/schema/typebox/gen/codegen/typescript/typescript-to-model.ts +1 -1
- package/src/scripts/getGenerateContext.ts +97 -0
- package/src/server/polyfill/polyfillBrowser.test.ts +1 -1
- package/src/types.d.ts +2 -2
- package/lib/langs/hashCode.ignored.js +0 -112
- package/lib/langs/hashCode.ignored.js.map +0 -1
- package/src/langs/hashCode.ignored.ts +0 -125
|
@@ -33,40 +33,62 @@ export class ResidentIdNumber {
|
|
|
33
33
|
let d = parseInt(date.slice(6));
|
|
34
34
|
return new IdNumber(
|
|
35
35
|
s.slice(0, 6),
|
|
36
|
-
new Date(`${y}-${m}-${d}`), // YYYYMMDD
|
|
37
|
-
|
|
36
|
+
// new Date(`${y}-${m}-${d}`), // YYYYMMDD
|
|
37
|
+
new Date(Date.UTC(y, m - 1, d)), // 避免时区问题
|
|
38
38
|
parseInt(s.slice(14, 17)),
|
|
39
39
|
s.slice(17, 18).toUpperCase(),
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
interface ParseResidentIdNumberResult {
|
|
45
|
+
division: string;
|
|
46
|
+
birthDate: Date;
|
|
47
|
+
sequence: number;
|
|
48
|
+
checksum: string;
|
|
49
|
+
|
|
50
|
+
valid: boolean;
|
|
51
|
+
male: boolean;
|
|
52
|
+
female: boolean;
|
|
53
|
+
sex: 'Male' | 'Female';
|
|
54
|
+
age: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
class IdNumber {
|
|
45
58
|
constructor(
|
|
46
59
|
public division: string,
|
|
47
|
-
public
|
|
60
|
+
public birthDate: Date,
|
|
48
61
|
public sequence: number,
|
|
49
62
|
public checksum: string,
|
|
50
63
|
) {}
|
|
51
64
|
|
|
52
65
|
toString() {
|
|
53
|
-
return this.
|
|
66
|
+
return this.base + this.checksum;
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
toJSON() {
|
|
57
70
|
return this.toString();
|
|
58
71
|
}
|
|
59
72
|
|
|
60
|
-
toObject() {
|
|
61
|
-
const { division,
|
|
73
|
+
toObject(): ParseResidentIdNumberResult {
|
|
74
|
+
const { division, birthDate, sequence, checksum, age, valid, male, female, sex } = this;
|
|
62
75
|
return {
|
|
63
76
|
division,
|
|
64
|
-
|
|
77
|
+
birthDate,
|
|
65
78
|
sequence,
|
|
66
79
|
checksum,
|
|
80
|
+
age,
|
|
81
|
+
valid,
|
|
82
|
+
male,
|
|
83
|
+
female,
|
|
84
|
+
sex,
|
|
67
85
|
};
|
|
68
86
|
}
|
|
69
87
|
|
|
88
|
+
get valid() {
|
|
89
|
+
return ResidentIdNumber.get().verify(this.toString());
|
|
90
|
+
}
|
|
91
|
+
|
|
70
92
|
get male() {
|
|
71
93
|
return this.sequence % 2 === 1;
|
|
72
94
|
}
|
|
@@ -76,15 +98,19 @@ class IdNumber {
|
|
|
76
98
|
}
|
|
77
99
|
|
|
78
100
|
get age() {
|
|
79
|
-
return new Date().getFullYear() - this.
|
|
101
|
+
return new Date().getFullYear() - this.birthDate.getFullYear();
|
|
80
102
|
}
|
|
81
103
|
|
|
82
|
-
get
|
|
83
|
-
return this.sequence % 2 === 1 ? '
|
|
104
|
+
get sex(): 'Male' | 'Female' {
|
|
105
|
+
return this.sequence % 2 === 1 ? 'Male' : 'Female';
|
|
84
106
|
}
|
|
85
107
|
|
|
86
|
-
|
|
87
|
-
|
|
108
|
+
/**
|
|
109
|
+
* base for checksum
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
private get base() {
|
|
113
|
+
return [this.division, formatDate(this.birthDate, 'YYYYMMDD'), this.sequence.toString().padStart(3, '0')].join('');
|
|
88
114
|
}
|
|
89
115
|
}
|
|
90
116
|
|
package/src/cn/id/id.test.ts
CHANGED
package/src/cn/index.ts
CHANGED
|
@@ -12,3 +12,5 @@ export { USCC } from './uscc/USCC';
|
|
|
12
12
|
export { ResidentIdNumber } from './id/ResidentIdNumber';
|
|
13
13
|
|
|
14
14
|
export { DivisionCode } from './division/DivisionCode';
|
|
15
|
+
|
|
16
|
+
export { toPinyinPure, toPinyinPureFirst, getCharToPinyinTable, loadCharToPinyinTable } from './pinyin/toPinyinPure';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { cartesianProduct } from './cartesianProduct';
|
|
3
|
+
|
|
4
|
+
describe('cartesianProduct', () => {
|
|
5
|
+
test('combines two arrays with multiple elements', () => {
|
|
6
|
+
expect(
|
|
7
|
+
cartesianProduct([
|
|
8
|
+
[1, 2],
|
|
9
|
+
[3, 4],
|
|
10
|
+
]),
|
|
11
|
+
).toEqual([
|
|
12
|
+
[1, 3],
|
|
13
|
+
[1, 4],
|
|
14
|
+
[2, 3],
|
|
15
|
+
[2, 4],
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('combines multiple arrays', () => {
|
|
20
|
+
expect(cartesianProduct([[1, 2], [3], [4, 5]])).toEqual([
|
|
21
|
+
[1, 3, 4],
|
|
22
|
+
[1, 3, 5],
|
|
23
|
+
[2, 3, 4],
|
|
24
|
+
[2, 3, 5],
|
|
25
|
+
]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('handles an empty array input correctly', () => {
|
|
29
|
+
expect(cartesianProduct([])).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('handles one array being empty', () => {
|
|
33
|
+
expect(cartesianProduct([[1, 2], [], [3]])).toEqual([]);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('works with arrays of different types', () => {
|
|
37
|
+
expect(
|
|
38
|
+
cartesianProduct<string | number>([
|
|
39
|
+
['a', 'b'],
|
|
40
|
+
[1, 2],
|
|
41
|
+
]),
|
|
42
|
+
).toEqual([
|
|
43
|
+
['a', 1],
|
|
44
|
+
['a', 2],
|
|
45
|
+
['b', 1],
|
|
46
|
+
['b', 2],
|
|
47
|
+
]);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('handles single-element arrays', () => {
|
|
51
|
+
expect(cartesianProduct([[1], [2], [3]])).toEqual([[1, 2, 3]]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('works with more complex objects', () => {
|
|
55
|
+
expect(cartesianProduct<any>([[{ id: 1 }, { id: 2 }], ['a']])).toEqual([
|
|
56
|
+
[{ id: 1 }, 'a'],
|
|
57
|
+
[{ id: 2 }, 'a'],
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('handles an array containing a single array', () => {
|
|
62
|
+
expect(cartesianProduct([[1, 2, 3]])).toEqual([[1], [2], [3]]);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function cartesianProduct<T>(args: T[][]): T[][] {
|
|
2
|
+
if (args.length === 0) return [];
|
|
3
|
+
|
|
4
|
+
const product: T[][] = [];
|
|
5
|
+
const counts = args.map((arr) => arr.length);
|
|
6
|
+
const counter = new Array(args.length).fill(0);
|
|
7
|
+
const total = counts.reduce((acc, val) => acc * val, 1);
|
|
8
|
+
|
|
9
|
+
for (let i = 0; i < total; i++) {
|
|
10
|
+
product.push(counter.map((count, index) => args[index][count]));
|
|
11
|
+
|
|
12
|
+
// Update the counter for the next row in the Cartesian product.
|
|
13
|
+
for (let j = args.length - 1; j >= 0; j--) {
|
|
14
|
+
if (counter[j] + 1 < counts[j]) {
|
|
15
|
+
counter[j]++;
|
|
16
|
+
break; // Stop as we've found a digit that can be incremented.
|
|
17
|
+
} else {
|
|
18
|
+
counter[j] = 0; // Reset this digit and increment the next digit in the next iteration.
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return product;
|
|
24
|
+
}
|