@wener/common 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/lib/cn/ChineseResidentIdNo.js +41 -0
  2. package/lib/cn/ChineseResidentIdNo.mod.js +1 -0
  3. package/lib/cn/{ResidentIdentityCardNumber.test.js → ChineseResidentIdNo.test.js} +7 -6
  4. package/lib/cn/DivisionCode.js +211 -300
  5. package/lib/cn/DivisionCode.mod.js +1 -0
  6. package/lib/cn/DivisionCode.test.js +9 -15
  7. package/lib/cn/{Mod11Checksum.js → Mod11.js} +1 -0
  8. package/lib/cn/{Mod31Checksum.js → Mod31.js} +1 -0
  9. package/lib/cn/UnifiedSocialCreditCode.js +130 -115
  10. package/lib/cn/UnifiedSocialCreditCode.mod.js +1 -0
  11. package/lib/cn/UnifiedSocialCreditCode.test.js +1 -1
  12. package/lib/cn/index.js +1 -3
  13. package/lib/cn/mod.js +6 -0
  14. package/lib/consola/formatLogObject.js +18 -6
  15. package/lib/dayjs/dayjs.js +38 -0
  16. package/lib/dayjs/formatDuration.js +58 -0
  17. package/lib/dayjs/formatDuration.test.js +90 -0
  18. package/lib/dayjs/index.js +3 -0
  19. package/lib/dayjs/parseDuration.js +32 -0
  20. package/lib/decimal/index.js +1 -0
  21. package/lib/decimal/parseDecimal.js +13 -0
  22. package/lib/{resource → foundation}/schema/SexType.js +5 -1
  23. package/lib/foundation/schema/index.js +1 -0
  24. package/lib/foundation/schema/parseSexType.js +18 -0
  25. package/lib/foundation/schema/types.js +5 -0
  26. package/lib/password/Password.js +10 -7
  27. package/lib/resource/ListQuery.js +119 -0
  28. package/lib/resource/index.js +1 -0
  29. package/lib/resource/schema/AnyResourceSchema.js +1 -1
  30. package/lib/resource/schema/index.js +5 -0
  31. package/lib/{resource/schema → schema}/SchemaRegistry.js +12 -5
  32. package/lib/schema/SchemaRegistry.mod.js +2 -0
  33. package/lib/schema/createSchemaData.js +1 -1
  34. package/lib/schema/getSchemaOptions.js +2 -2
  35. package/lib/schema/index.js +1 -0
  36. package/lib/utils/getEstimateProcessTime.js +20 -0
  37. package/lib/utils/index.js +1 -0
  38. package/package.json +23 -14
  39. package/src/cn/ChineseResidentIdNo.mod.ts +7 -0
  40. package/src/cn/ChineseResidentIdNo.test.ts +18 -0
  41. package/src/cn/ChineseResidentIdNo.ts +66 -0
  42. package/src/cn/DivisionCode.mod.ts +7 -0
  43. package/src/cn/DivisionCode.test.ts +3 -13
  44. package/src/cn/DivisionCode.ts +132 -195
  45. package/src/cn/{Mod11Checksum.ts → Mod11.ts} +3 -1
  46. package/src/cn/{Mod31Checksum.ts → Mod31.ts} +2 -0
  47. package/src/cn/UnifiedSocialCreditCode.mod.ts +7 -0
  48. package/src/cn/UnifiedSocialCreditCode.test.ts +2 -2
  49. package/src/cn/UnifiedSocialCreditCode.ts +105 -125
  50. package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +14 -0
  51. package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +18 -12
  52. package/src/cn/index.ts +1 -3
  53. package/src/cn/mod.ts +3 -0
  54. package/src/consola/formatLogObject.ts +12 -4
  55. package/src/dayjs/dayjs.ts +40 -0
  56. package/src/dayjs/formatDuration.test.ts +14 -0
  57. package/src/dayjs/formatDuration.ts +86 -0
  58. package/src/dayjs/index.ts +3 -0
  59. package/src/dayjs/parseDuration.ts +40 -0
  60. package/src/decimal/index.ts +1 -0
  61. package/src/decimal/parseDecimal.ts +16 -0
  62. package/src/foundation/schema/SexType.ts +21 -0
  63. package/src/foundation/schema/index.ts +1 -0
  64. package/src/foundation/schema/parseSexType.ts +19 -0
  65. package/src/foundation/schema/types.ts +8 -0
  66. package/src/password/Password.ts +2 -2
  67. package/src/resource/ListQuery.ts +53 -0
  68. package/src/resource/index.ts +1 -0
  69. package/src/resource/schema/AnyResourceSchema.ts +1 -1
  70. package/src/resource/schema/index.ts +5 -0
  71. package/src/schema/SchemaRegistry.mod.ts +1 -0
  72. package/src/{resource/schema → schema}/SchemaRegistry.ts +12 -8
  73. package/src/schema/createSchemaData.ts +1 -1
  74. package/src/schema/getSchemaOptions.ts +2 -2
  75. package/src/schema/index.ts +1 -0
  76. package/src/utils/getEstimateProcessTime.ts +36 -0
  77. package/src/utils/index.ts +1 -0
  78. package/lib/cn/ResidentIdentityCardNumber.js +0 -50
  79. package/lib/cn/formatDate.js +0 -13
  80. package/lib/cn/parseSex.js +0 -20
  81. package/lib/search/AdvanceSearch.js +0 -9
  82. package/lib/search/AdvanceSearch.test.js +0 -435
  83. package/lib/search/formatAdvanceSearch.js +0 -78
  84. package/lib/search/index.js +0 -1
  85. package/lib/search/optimizeAdvanceSearch.js +0 -143
  86. package/lib/search/parseAdvanceSearch.js +0 -20
  87. package/lib/search/parser.d.js +0 -1
  88. package/lib/search/parser.js +0 -3088
  89. package/lib/search/types.d.js +0 -1
  90. package/src/cn/ResidentIdentityCardNumber.test.ts +0 -17
  91. package/src/cn/ResidentIdentityCardNumber.ts +0 -96
  92. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +0 -15
  93. package/src/cn/formatDate.ts +0 -12
  94. package/src/cn/parseSex.ts +0 -13
  95. package/src/resource/schema/SexType.ts +0 -13
  96. package/src/search/AdvanceSearch.test.ts +0 -149
  97. package/src/search/AdvanceSearch.ts +0 -14
  98. package/src/search/Makefile +0 -2
  99. package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +0 -675
  100. package/src/search/formatAdvanceSearch.ts +0 -52
  101. package/src/search/index.ts +0 -1
  102. package/src/search/optimizeAdvanceSearch.ts +0 -77
  103. package/src/search/parseAdvanceSearch.ts +0 -23
  104. package/src/search/parser.d.ts +0 -8
  105. package/src/search/parser.js +0 -2794
  106. package/src/search/parser.peggy +0 -237
  107. package/src/search/types.d.ts +0 -45
@@ -1 +0,0 @@
1
- export { };
@@ -1,17 +0,0 @@
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
- });
@@ -1,96 +0,0 @@
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
- }
@@ -1,15 +0,0 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
-
3
- exports[`ResidentIdentityCardNumber > should parse 1`] = `
4
- {
5
- "age": 76,
6
- "birthDate": "19491231",
7
- "checksum": "X",
8
- "division": "110105",
9
- "female": true,
10
- "male": false,
11
- "sequence": 2,
12
- "sex": "Female",
13
- "valid": true,
14
- }
15
- `;
@@ -1,12 +0,0 @@
1
- export function formatDate(date: Date, format: 'yyyyMMDD') {
2
- switch (format) {
3
- case 'yyyyMMDD': {
4
- const year = date.getFullYear();
5
- const month = (date.getMonth() + 1).toString().padStart(2, '0');
6
- const day = date.getDate().toString().padStart(2, '0');
7
- return `${year}${month}${day}`;
8
- }
9
- default:
10
- throw new Error(`Invalid format`);
11
- }
12
- }
@@ -1,13 +0,0 @@
1
- export function parseSex(s: string): undefined | { sex: 'Male' | 'Female'; male: boolean; female: boolean } {
2
- if (!s) return undefined;
3
-
4
- switch (s.toLowerCase()) {
5
- case '男':
6
- case 'male':
7
- return { sex: 'Male', male: true, female: false };
8
- case '女':
9
- case 'female':
10
- return { sex: 'Female', male: false, female: true };
11
- }
12
- return undefined;
13
- }
@@ -1,13 +0,0 @@
1
- import { z } from 'zod/v4';
2
- import type { EnumValues } from './types';
3
-
4
- export const SexType = Object.freeze({
5
- __proto__: null,
6
- Male: 'Male',
7
- Female: 'Female',
8
- // Intersex
9
- } as const);
10
- export type SexType = EnumValues<typeof SexType>;
11
- export const SexTypeSchema = z
12
- .union([z.literal(SexType.Male).describe('男'), z.literal(SexType.Female).describe('女')])
13
- .describe('性别');
@@ -1,149 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { AdvanceSearch } from './AdvanceSearch';
3
-
4
- describe('AdvanceSearch', () => {
5
- it('should parse', () => {
6
- for (const input of [
7
- //
8
- '-a',
9
- 'a',
10
- 'a b',
11
- 'a -b',
12
- 'a-b',
13
- 'a"b',
14
- 'a&b',
15
- 'NOT a',
16
- 'NOT -a',
17
- 'HELLO -WORLD',
18
- '(a)',
19
- '( a OR B )',
20
- 'A OR B',
21
- 'a:[1,2]',
22
- 'a:*..1',
23
- 'a:ok a:=1 a:>1 a:<1 a:>=1 a:<=1 a:!=1 a:1..2 a:*..1 a:1..* a:[1,2] a:(1,2) a:[1,2) a:(1,2]',
24
- 'NOT (A B) AND (a:ok AND size:>1)',
25
- 'NOT -a',
26
- 'NOT (NOT -a)',
27
- 'owner:@me owner:=@me owner:!=@me',
28
- '@AI:"Where is my car"',
29
- '/**/ a',
30
- '/* Hint */ a',
31
- '/* a */ a /* b */',
32
- ]) {
33
- let out = AdvanceSearch.parse(input);
34
- let formated = AdvanceSearch.format(out);
35
- expect(formated, `reformat`).toMatchSnapshot();
36
- let optimized = AdvanceSearch.format(AdvanceSearch.optimize(out));
37
- expect(optimized, `optimized`).toMatchSnapshot();
38
- expect(out, `parsed`).toMatchSnapshot();
39
- expect(AdvanceSearch.parse(formated), `reformat match original`).toMatchObject(out);
40
- }
41
- });
42
- it('should parse as expected', () => {
43
- type Case = [string | null | undefined, AdvanceSearch.Expr[]];
44
-
45
- const cases: Case[] = [
46
- [null, []],
47
- [undefined, []],
48
- ['', []],
49
- // fast path
50
- ['a', [{ type: 'keyword', value: 'a' }]],
51
- ['a-b', [{ type: 'keyword', value: 'a-b' }]],
52
- ['a"b', [{ type: 'keyword', value: 'a"b' }]],
53
- [
54
- 'hello world',
55
- [
56
- { type: 'keyword', value: 'hello' },
57
- { type: 'keyword', value: 'world' },
58
- ],
59
- ],
60
- // advance
61
- ['-a', [{ type: 'keyword', value: 'a', negative: true }]],
62
- [
63
- '/*Hi*/ hello -world',
64
- [
65
- { type: 'comment', value: 'Hi' },
66
- { type: 'keyword', value: 'hello', negative: false },
67
- { type: 'keyword', value: 'world', negative: true },
68
- ],
69
- ],
70
- ['"Hello"', [{ type: 'keyword', value: 'Hello', exact: true }]],
71
- ['-"Hello"', [{ type: 'keyword', value: 'Hello', exact: true, negative: true }]],
72
- ['is:ok', [{ type: 'compare', field: 'is', operator: 'match', value: { value: 'ok' } }]],
73
- ['-is:ok', [{ type: 'compare', field: 'is', negative: true, operator: 'match', value: { value: 'ok' } }]],
74
- ];
75
-
76
- for (const [input, expected] of cases) {
77
- let out = AdvanceSearch.parse(input);
78
- expect(out).toMatchObject(expected);
79
- expect(AdvanceSearch.parse(AdvanceSearch.format(out)), 'reformat should match').toMatchObject(expected);
80
- }
81
- });
82
-
83
- it('should optimize simple', () => {
84
- type Case = { input: AdvanceSearch.Expr[]; expected: AdvanceSearch.Expr[] };
85
- const cases: Case[] = [
86
- // rm empty comment
87
- {
88
- input: [
89
- { type: 'comment', value: '' },
90
- { type: 'keyword', value: 'a' },
91
- ],
92
- expected: [{ type: 'keyword', value: 'a' }],
93
- },
94
- // unwrap parentheses
95
- {
96
- input: [
97
- { type: 'parentheses', value: [{ type: 'keyword', value: 'a' }] },
98
- { type: 'keyword', value: 'b' },
99
- ],
100
- expected: [
101
- { type: 'keyword', value: 'a' },
102
- { type: 'keyword', value: 'b' },
103
- ],
104
- },
105
- // not not
106
- {
107
- input: [{ type: 'not', value: { type: 'not', value: { type: 'keyword', value: 'a' } } }],
108
- expected: [{ type: 'keyword', value: 'a', negative: false }],
109
- },
110
- // not to negative
111
- {
112
- input: [{ type: 'not', value: { type: 'keyword', value: 'a' } }],
113
- expected: [{ type: 'keyword', value: 'a', negative: true }],
114
- },
115
- ];
116
-
117
- for (let i = 0; i < cases.length; i++) {
118
- const { input, expected } = cases[i];
119
- let out = AdvanceSearch.optimize(input);
120
- expect(out, `case #${i}`).toEqual(expected);
121
- }
122
- });
123
-
124
- it('should optimize by formated', () => {
125
- type Case = [string, string];
126
-
127
- const cases: Case[] = [
128
- ['( a )', 'a'],
129
- ['NOT a', '-a'],
130
- ['NOT -a', 'a'],
131
- ['NOT is:ok', '-is:ok'],
132
- ['NOT -is:ok', 'is:ok'],
133
- ['NOT -is:=ok', 'is:=ok'],
134
- ['NOT is:=ok', 'is:!=ok'],
135
- ['NOT (NOT -a)', '-a'],
136
- ];
137
-
138
- for (const [input, expected] of cases) {
139
- let out = AdvanceSearch.optimize(AdvanceSearch.parse(input));
140
- expect(AdvanceSearch.format(out), `${input} -> ${expected}: ${JSON.stringify(out)}`).toEqual(expected);
141
- }
142
- });
143
-
144
- it.fails('should parse parentheses', () => {
145
- let out = AdvanceSearch.parse('(a)');
146
- console.log(out);
147
- expect(out).toEqual([{ type: 'parentheses', value: [{ type: 'keyword', value: 'a' }] }]);
148
- });
149
- });
@@ -1,14 +0,0 @@
1
- import { formatAdvanceSearch } from './formatAdvanceSearch';
2
- import { optimizeAdvanceSearch } from './optimizeAdvanceSearch';
3
- import { parseAdvanceSearch } from './parseAdvanceSearch';
4
- import type * as types from './types';
5
-
6
- export namespace AdvanceSearch {
7
- export type Exprs = types.Exprs;
8
- export type Expr = types.Expr;
9
- export type Value = types.Value;
10
-
11
- export const parse = parseAdvanceSearch;
12
- export const format = formatAdvanceSearch;
13
- export const optimize = optimizeAdvanceSearch;
14
- }
@@ -1,2 +0,0 @@
1
- gen:
2
- pnpm dlx peggy@latest $(PWD)/parser.peggy --format es