@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.
- package/lib/cn/ChineseResidentIdNo.js +41 -0
- package/lib/cn/ChineseResidentIdNo.mod.js +1 -0
- package/lib/cn/{ResidentIdentityCardNumber.test.js → ChineseResidentIdNo.test.js} +7 -6
- package/lib/cn/DivisionCode.js +211 -300
- package/lib/cn/DivisionCode.mod.js +1 -0
- package/lib/cn/DivisionCode.test.js +9 -15
- package/lib/cn/{Mod11Checksum.js → Mod11.js} +1 -0
- package/lib/cn/{Mod31Checksum.js → Mod31.js} +1 -0
- package/lib/cn/UnifiedSocialCreditCode.js +130 -115
- package/lib/cn/UnifiedSocialCreditCode.mod.js +1 -0
- package/lib/cn/UnifiedSocialCreditCode.test.js +1 -1
- package/lib/cn/index.js +1 -3
- package/lib/cn/mod.js +6 -0
- package/lib/consola/formatLogObject.js +18 -6
- package/lib/dayjs/dayjs.js +38 -0
- package/lib/dayjs/formatDuration.js +58 -0
- package/lib/dayjs/formatDuration.test.js +90 -0
- package/lib/dayjs/index.js +3 -0
- package/lib/dayjs/parseDuration.js +32 -0
- package/lib/decimal/index.js +1 -0
- package/lib/decimal/parseDecimal.js +13 -0
- package/lib/{resource → foundation}/schema/SexType.js +5 -1
- package/lib/foundation/schema/index.js +1 -0
- package/lib/foundation/schema/parseSexType.js +18 -0
- package/lib/foundation/schema/types.js +5 -0
- package/lib/password/Password.js +10 -7
- package/lib/resource/ListQuery.js +119 -0
- package/lib/resource/index.js +1 -0
- package/lib/resource/schema/AnyResourceSchema.js +1 -1
- package/lib/resource/schema/index.js +5 -0
- package/lib/{resource/schema → schema}/SchemaRegistry.js +12 -5
- package/lib/schema/SchemaRegistry.mod.js +2 -0
- package/lib/schema/createSchemaData.js +1 -1
- package/lib/schema/getSchemaOptions.js +2 -2
- package/lib/schema/index.js +1 -0
- package/lib/utils/getEstimateProcessTime.js +20 -0
- package/lib/utils/index.js +1 -0
- package/package.json +23 -14
- package/src/cn/ChineseResidentIdNo.mod.ts +7 -0
- package/src/cn/ChineseResidentIdNo.test.ts +18 -0
- package/src/cn/ChineseResidentIdNo.ts +66 -0
- package/src/cn/DivisionCode.mod.ts +7 -0
- package/src/cn/DivisionCode.test.ts +3 -13
- package/src/cn/DivisionCode.ts +132 -195
- package/src/cn/{Mod11Checksum.ts → Mod11.ts} +3 -1
- package/src/cn/{Mod31Checksum.ts → Mod31.ts} +2 -0
- package/src/cn/UnifiedSocialCreditCode.mod.ts +7 -0
- package/src/cn/UnifiedSocialCreditCode.test.ts +2 -2
- package/src/cn/UnifiedSocialCreditCode.ts +105 -125
- package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +14 -0
- package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +18 -12
- package/src/cn/index.ts +1 -3
- package/src/cn/mod.ts +3 -0
- package/src/consola/formatLogObject.ts +12 -4
- package/src/dayjs/dayjs.ts +40 -0
- package/src/dayjs/formatDuration.test.ts +14 -0
- package/src/dayjs/formatDuration.ts +86 -0
- package/src/dayjs/index.ts +3 -0
- package/src/dayjs/parseDuration.ts +40 -0
- package/src/decimal/index.ts +1 -0
- package/src/decimal/parseDecimal.ts +16 -0
- package/src/foundation/schema/SexType.ts +21 -0
- package/src/foundation/schema/index.ts +1 -0
- package/src/foundation/schema/parseSexType.ts +19 -0
- package/src/foundation/schema/types.ts +8 -0
- package/src/password/Password.ts +2 -2
- package/src/resource/ListQuery.ts +53 -0
- package/src/resource/index.ts +1 -0
- package/src/resource/schema/AnyResourceSchema.ts +1 -1
- package/src/resource/schema/index.ts +5 -0
- package/src/schema/SchemaRegistry.mod.ts +1 -0
- package/src/{resource/schema → schema}/SchemaRegistry.ts +12 -8
- package/src/schema/createSchemaData.ts +1 -1
- package/src/schema/getSchemaOptions.ts +2 -2
- package/src/schema/index.ts +1 -0
- package/src/utils/getEstimateProcessTime.ts +36 -0
- package/src/utils/index.ts +1 -0
- package/lib/cn/ResidentIdentityCardNumber.js +0 -50
- package/lib/cn/formatDate.js +0 -13
- package/lib/cn/parseSex.js +0 -20
- package/lib/search/AdvanceSearch.js +0 -9
- package/lib/search/AdvanceSearch.test.js +0 -435
- package/lib/search/formatAdvanceSearch.js +0 -78
- package/lib/search/index.js +0 -1
- package/lib/search/optimizeAdvanceSearch.js +0 -143
- package/lib/search/parseAdvanceSearch.js +0 -20
- package/lib/search/parser.d.js +0 -1
- package/lib/search/parser.js +0 -3088
- package/lib/search/types.d.js +0 -1
- package/src/cn/ResidentIdentityCardNumber.test.ts +0 -17
- package/src/cn/ResidentIdentityCardNumber.ts +0 -96
- package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +0 -15
- package/src/cn/formatDate.ts +0 -12
- package/src/cn/parseSex.ts +0 -13
- package/src/resource/schema/SexType.ts +0 -13
- package/src/search/AdvanceSearch.test.ts +0 -149
- package/src/search/AdvanceSearch.ts +0 -14
- package/src/search/Makefile +0 -2
- package/src/search/__snapshots__/AdvanceSearch.test.ts.snap +0 -675
- package/src/search/formatAdvanceSearch.ts +0 -52
- package/src/search/index.ts +0 -1
- package/src/search/optimizeAdvanceSearch.ts +0 -77
- package/src/search/parseAdvanceSearch.ts +0 -23
- package/src/search/parser.d.ts +0 -8
- package/src/search/parser.js +0 -2794
- package/src/search/parser.peggy +0 -237
- package/src/search/types.d.ts +0 -45
|
@@ -2,40 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`UnifiedSocialCreditCode > should parse 1`] = `
|
|
4
4
|
{
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"adminDivisionCode": "330106",
|
|
6
|
+
"checkDigit": "P",
|
|
7
7
|
"codes": [
|
|
8
8
|
"9",
|
|
9
9
|
"1",
|
|
10
10
|
"330106",
|
|
11
11
|
"673959654",
|
|
12
|
+
"P",
|
|
12
13
|
],
|
|
13
|
-
"
|
|
14
|
-
"
|
|
14
|
+
"entityCategoryCode": "1",
|
|
15
|
+
"names": [
|
|
15
16
|
"工商",
|
|
16
17
|
"企业",
|
|
17
18
|
],
|
|
18
|
-
"
|
|
19
|
-
"
|
|
19
|
+
"organizationCode": "673959654",
|
|
20
|
+
"raw": "91330106673959654P",
|
|
21
|
+
"registrationAuthorityCode": "9",
|
|
22
|
+
"valid": true,
|
|
20
23
|
}
|
|
21
24
|
`;
|
|
22
25
|
|
|
23
26
|
exports[`UnifiedSocialCreditCode > should parse 2`] = `
|
|
24
27
|
{
|
|
25
|
-
"
|
|
26
|
-
"
|
|
28
|
+
"adminDivisionCode": "330106",
|
|
29
|
+
"checkDigit": "R",
|
|
27
30
|
"codes": [
|
|
28
31
|
"9",
|
|
29
32
|
"1",
|
|
30
33
|
"330106",
|
|
31
34
|
"MA2CFLDG4",
|
|
35
|
+
"R",
|
|
32
36
|
],
|
|
33
|
-
"
|
|
34
|
-
"
|
|
37
|
+
"entityCategoryCode": "1",
|
|
38
|
+
"names": [
|
|
35
39
|
"工商",
|
|
36
40
|
"企业",
|
|
37
41
|
],
|
|
38
|
-
"
|
|
39
|
-
"
|
|
42
|
+
"organizationCode": "MA2CFLDG4",
|
|
43
|
+
"raw": "91330106MA2CFLDG4R",
|
|
44
|
+
"registrationAuthorityCode": "9",
|
|
45
|
+
"valid": true,
|
|
40
46
|
}
|
|
41
47
|
`;
|
package/src/cn/index.ts
CHANGED
|
@@ -1,3 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { DivisionCode } from './DivisionCode';
|
|
3
|
-
export { UnifiedSocialCreditCode } from './UnifiedSocialCreditCode';
|
|
1
|
+
export { ChineseResidentIdNo, UnifiedSocialCreditCode, DivisionCode } from './mod';
|
package/src/cn/mod.ts
ADDED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import colors from 'chalk';
|
|
1
|
+
import colors, { Chalk, type ChalkInstance } from 'chalk';
|
|
2
2
|
import type { ConsolaOptions, FormatOptions, LogObject, LogType } from 'consola/core';
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import { isDevelopment } from 'std-env';
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const LevelColors: Record<LogType, (str: string) => string> = {
|
|
7
7
|
trace: colors.gray,
|
|
8
8
|
debug: colors.cyan,
|
|
9
9
|
info: colors.blueBright,
|
|
@@ -38,16 +38,24 @@ const levelShort: Record<LogType, string> = {
|
|
|
38
38
|
};
|
|
39
39
|
const start = Date.now();
|
|
40
40
|
|
|
41
|
+
const Colors: ChalkInstance = colors;
|
|
42
|
+
const NoColors = new Chalk({ level: 0 });
|
|
43
|
+
|
|
41
44
|
export function formatLogObject(
|
|
42
45
|
o: LogObject,
|
|
43
46
|
ctx: {
|
|
44
47
|
options: ConsolaOptions;
|
|
45
48
|
},
|
|
46
49
|
) {
|
|
50
|
+
const shouldColor = Boolean(ctx.options?.formatOptions?.colors);
|
|
51
|
+
|
|
47
52
|
let { date, type, tag } = o;
|
|
48
53
|
type = type === 'log' ? 'info' : type;
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
const colors = shouldColor ? Colors : NoColors;
|
|
55
|
+
let color = LevelColors[type] || colors.white;
|
|
56
|
+
if (!shouldColor) {
|
|
57
|
+
color = (v) => v;
|
|
58
|
+
}
|
|
51
59
|
const levelText = levelShort[type] || type.toUpperCase().slice(0, 4); // Get first 4 chars, consistent uppercase
|
|
52
60
|
|
|
53
61
|
let line = '';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
|
3
|
+
import dayOfYear from 'dayjs/plugin/dayOfYear';
|
|
4
|
+
import duration from 'dayjs/plugin/duration';
|
|
5
|
+
import isBetween from 'dayjs/plugin/isBetween';
|
|
6
|
+
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
|
|
7
|
+
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
|
|
8
|
+
import isToday from 'dayjs/plugin/isToday';
|
|
9
|
+
import isTomorrow from 'dayjs/plugin/isTomorrow';
|
|
10
|
+
import isYesterday from 'dayjs/plugin/isYesterday';
|
|
11
|
+
import localeData from 'dayjs/plugin/localeData';
|
|
12
|
+
import objectSupport from 'dayjs/plugin/objectSupport';
|
|
13
|
+
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
|
|
14
|
+
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
15
|
+
import timezone from 'dayjs/plugin/timezone';
|
|
16
|
+
import toObject from 'dayjs/plugin/toObject';
|
|
17
|
+
import utc from 'dayjs/plugin/utc';
|
|
18
|
+
import 'dayjs/locale/zh-cn';
|
|
19
|
+
import 'dayjs/locale/zh';
|
|
20
|
+
|
|
21
|
+
dayjs.extend(advancedFormat);
|
|
22
|
+
dayjs.extend(dayOfYear);
|
|
23
|
+
dayjs.extend(duration);
|
|
24
|
+
dayjs.extend(isBetween);
|
|
25
|
+
dayjs.extend(isSameOrAfter);
|
|
26
|
+
dayjs.extend(isSameOrBefore);
|
|
27
|
+
dayjs.extend(isToday);
|
|
28
|
+
dayjs.extend(isTomorrow);
|
|
29
|
+
dayjs.extend(isYesterday);
|
|
30
|
+
dayjs.extend(localeData);
|
|
31
|
+
dayjs.extend(objectSupport);
|
|
32
|
+
dayjs.extend(quarterOfYear);
|
|
33
|
+
dayjs.extend(relativeTime);
|
|
34
|
+
dayjs.extend(timezone);
|
|
35
|
+
dayjs.extend(toObject);
|
|
36
|
+
dayjs.extend(utc);
|
|
37
|
+
dayjs.locale('zh-cn');
|
|
38
|
+
dayjs.tz.setDefault('Asia/Shanghai');
|
|
39
|
+
|
|
40
|
+
export { dayjs };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { expect, test } from 'vitest';
|
|
2
|
+
import { formatDuration } from './formatDuration';
|
|
3
|
+
|
|
4
|
+
test('formatDuration', () => {
|
|
5
|
+
for (const [a, b] of [
|
|
6
|
+
[0, '0ms'],
|
|
7
|
+
[1000, '1s'],
|
|
8
|
+
[1000 * 60, '1m'],
|
|
9
|
+
[1000 * 60 + 1000, '1m1s'],
|
|
10
|
+
[1000 * 60 + 1000 + 1, '1m1s1ms'],
|
|
11
|
+
]) {
|
|
12
|
+
expect(formatDuration(a)).toBe(b);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type OpUnitType, type UnitTypeLongPlural } from 'dayjs';
|
|
2
|
+
import { type Duration } from 'dayjs/plugin/duration';
|
|
3
|
+
import { parseDuration } from './parseDuration';
|
|
4
|
+
|
|
5
|
+
type FormatDurationOptions = {
|
|
6
|
+
humanize?: boolean;
|
|
7
|
+
format?: string | 'human' | 'humanize' | 'iso' | 'auto';
|
|
8
|
+
iso?: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type MaybeDuration =
|
|
12
|
+
| number
|
|
13
|
+
| string
|
|
14
|
+
| Duration
|
|
15
|
+
| Partial<{
|
|
16
|
+
[unit in Exclude<UnitTypeLongPlural, 'dates'> | 'weeks']: number;
|
|
17
|
+
}>
|
|
18
|
+
| {
|
|
19
|
+
value: number;
|
|
20
|
+
unit?: Exclude<OpUnitType, 'date' | 'dates'>;
|
|
21
|
+
}
|
|
22
|
+
| undefined
|
|
23
|
+
| null;
|
|
24
|
+
|
|
25
|
+
export function formatDuration(value: MaybeDuration, o?: FormatDurationOptions): string | undefined {
|
|
26
|
+
const v = parseDuration(value);
|
|
27
|
+
if (v === undefined || v === null) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let { format, humanize, iso } = o || {};
|
|
32
|
+
// Use local variables instead of modifying o directly
|
|
33
|
+
switch (format) {
|
|
34
|
+
case 'human':
|
|
35
|
+
case 'humanize':
|
|
36
|
+
humanize = true;
|
|
37
|
+
format = undefined;
|
|
38
|
+
break;
|
|
39
|
+
case 'iso':
|
|
40
|
+
iso = true;
|
|
41
|
+
format = undefined;
|
|
42
|
+
break;
|
|
43
|
+
case 'auto':
|
|
44
|
+
format = undefined;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (humanize) {
|
|
49
|
+
return v.humanize();
|
|
50
|
+
}
|
|
51
|
+
if (iso) {
|
|
52
|
+
return v.toISOString();
|
|
53
|
+
}
|
|
54
|
+
if (format) {
|
|
55
|
+
return v.format(format);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// auto format
|
|
59
|
+
// 1h2m3s
|
|
60
|
+
if (v.asDays() > 1) {
|
|
61
|
+
let s = v.toISOString();
|
|
62
|
+
return s.replace('P', '').replace('T', '').toLowerCase();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
let parts: string[] = [];
|
|
67
|
+
let h = v.hours();
|
|
68
|
+
let m = v.minutes();
|
|
69
|
+
let s = v.seconds();
|
|
70
|
+
let ms = v.milliseconds();
|
|
71
|
+
|
|
72
|
+
if (h > 0) {
|
|
73
|
+
parts.push(`${h}h`);
|
|
74
|
+
}
|
|
75
|
+
if (m > 0) {
|
|
76
|
+
parts.push(`${m}m`);
|
|
77
|
+
}
|
|
78
|
+
if (s > 0) {
|
|
79
|
+
parts.push(`${s}s`);
|
|
80
|
+
}
|
|
81
|
+
if (ms > 0 || (h === 0 && m === 0 && s === 0)) {
|
|
82
|
+
parts.push(`${ms}ms`);
|
|
83
|
+
}
|
|
84
|
+
return parts.join('');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { OpUnitType, UnitTypeLongPlural } from 'dayjs';
|
|
2
|
+
import type { Duration } from 'dayjs/plugin/duration';
|
|
3
|
+
import { dayjs } from './dayjs';
|
|
4
|
+
|
|
5
|
+
export type MaybeDuration =
|
|
6
|
+
| number
|
|
7
|
+
| string
|
|
8
|
+
| Duration
|
|
9
|
+
| Partial<{
|
|
10
|
+
[unit in Exclude<UnitTypeLongPlural, 'dates'> | 'weeks']: number;
|
|
11
|
+
}>
|
|
12
|
+
| {
|
|
13
|
+
value: number;
|
|
14
|
+
unit?: Exclude<OpUnitType, 'date' | 'dates'>;
|
|
15
|
+
}
|
|
16
|
+
| undefined
|
|
17
|
+
| null;
|
|
18
|
+
|
|
19
|
+
export function parseDuration(value: MaybeDuration): Duration | undefined {
|
|
20
|
+
if (!value && value !== 0) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
let duration: Duration;
|
|
24
|
+
if (typeof value === 'number') {
|
|
25
|
+
duration = dayjs.duration(value);
|
|
26
|
+
} else if (typeof value === 'string' && value.startsWith('P')) {
|
|
27
|
+
// PT0S
|
|
28
|
+
duration = dayjs.duration(value);
|
|
29
|
+
} else if (typeof value === 'object' && 'value' in value) {
|
|
30
|
+
duration = dayjs.duration(value.value, value.unit);
|
|
31
|
+
} else if (dayjs.isDuration(value)) {
|
|
32
|
+
duration = value;
|
|
33
|
+
} else if (typeof value === 'object') {
|
|
34
|
+
duration = dayjs.duration(value);
|
|
35
|
+
} else {
|
|
36
|
+
console.warn(`Invalid duration value:`, value);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
return duration;
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parseDecimal } from './parseDecimal';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Decimal from 'decimal.js';
|
|
2
|
+
|
|
3
|
+
export function parseDecimal(v: string | number | Decimal): Decimal;
|
|
4
|
+
export function parseDecimal(v: string | number | Decimal | undefined | null): Decimal | undefined;
|
|
5
|
+
export function parseDecimal(v: string | number | Decimal | undefined | null): Decimal | undefined {
|
|
6
|
+
switch (v) {
|
|
7
|
+
case '':
|
|
8
|
+
case undefined:
|
|
9
|
+
case null:
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
if (Decimal.isDecimal(v)) {
|
|
13
|
+
return v;
|
|
14
|
+
}
|
|
15
|
+
return new Decimal(v);
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import type { EnumValues } from '../../resource/schema';
|
|
3
|
+
|
|
4
|
+
// Sex 指的是生理性别/生物性别,通常由出生时的生物特征决定
|
|
5
|
+
export const SexType = Object.freeze({
|
|
6
|
+
__proto__: null,
|
|
7
|
+
Male: 'Male',
|
|
8
|
+
Female: 'Female',
|
|
9
|
+
});
|
|
10
|
+
export type SexType = EnumValues<typeof SexType>;
|
|
11
|
+
|
|
12
|
+
export const SexTypeSchema = z
|
|
13
|
+
.union([
|
|
14
|
+
//
|
|
15
|
+
z.literal(SexType.Male).describe('男'),
|
|
16
|
+
z.literal(SexType.Female).describe('女'),
|
|
17
|
+
])
|
|
18
|
+
.describe('性别')
|
|
19
|
+
.meta({
|
|
20
|
+
title: 'SexType',
|
|
21
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SexType, SexTypeSchema } from './SexType';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SexType } from './SexType';
|
|
2
|
+
|
|
3
|
+
export function parseSexType(s: string | null | undefined): undefined | SexType {
|
|
4
|
+
if (!s) return undefined;
|
|
5
|
+
|
|
6
|
+
switch (s.toLowerCase()) {
|
|
7
|
+
case '♂':
|
|
8
|
+
case '男':
|
|
9
|
+
case 'male':
|
|
10
|
+
case 'man':
|
|
11
|
+
return SexType.Male;
|
|
12
|
+
case '♀':
|
|
13
|
+
case '女':
|
|
14
|
+
case 'female':
|
|
15
|
+
case 'woman':
|
|
16
|
+
return SexType.Female;
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
package/src/password/Password.ts
CHANGED
|
@@ -68,10 +68,10 @@ export namespace Password {
|
|
|
68
68
|
return f;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
export async function
|
|
71
|
+
export async function validate(password: string, hash: string) {
|
|
72
72
|
let res = await parse(hash);
|
|
73
73
|
let f = resolveAlgorithm(res.id);
|
|
74
|
-
return { result: f.verify(password, hash, res), parsed: res };
|
|
74
|
+
return { result: await f.verify(password, hash, res), parsed: res };
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export async function verify(password: string, hash: string) {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
export type ListQueryInput = z.input<typeof ListQuerySchema>;
|
|
4
|
+
export type ListQuery = z.infer<typeof ListQuerySchema>;
|
|
5
|
+
const IntLikeSchema = z.coerce
|
|
6
|
+
.number()
|
|
7
|
+
.multipleOf(1)
|
|
8
|
+
.min(0)
|
|
9
|
+
.optional()
|
|
10
|
+
.overwrite((v) => v || undefined);
|
|
11
|
+
export const ListQuerySchema = z.object({
|
|
12
|
+
id: z.coerce.string().optional(),
|
|
13
|
+
ids: z.array(z.coerce.string()).optional(),
|
|
14
|
+
filter: z.string().optional().describe('sql-like filter string'),
|
|
15
|
+
filters: z.array(z.any()).optional().describe('sql-like filter string'),
|
|
16
|
+
where: z.record(z.string(), z.any()).optional().describe('document query filter'),
|
|
17
|
+
search: z.string().optional(),
|
|
18
|
+
limit: IntLikeSchema,
|
|
19
|
+
offset: IntLikeSchema,
|
|
20
|
+
order: z.array(z.string()).optional().describe('order like "a,-b,c desc null last"'),
|
|
21
|
+
pageIndex: IntLikeSchema.describe('0-based page index'),
|
|
22
|
+
pageNumber: IntLikeSchema.describe('1-based page number'),
|
|
23
|
+
pageSize: IntLikeSchema,
|
|
24
|
+
cursor: z.string().optional(),
|
|
25
|
+
deleted: z.coerce.boolean().optional(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
type ListQueryOverride = ListQueryInput | undefined | ((input: ListQueryInput) => ListQueryInput | undefined | void);
|
|
29
|
+
|
|
30
|
+
export function resolveListQuery(target: ListQueryInput | undefined, ...args: ListQueryOverride[]): ListQuery {
|
|
31
|
+
let out = args.reduce((a: ListQueryInput, source) => {
|
|
32
|
+
if (typeof source === 'function') {
|
|
33
|
+
const result = source(a);
|
|
34
|
+
// do not use the result as merge source
|
|
35
|
+
return result || a;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let b: ListQueryInput | undefined = source;
|
|
39
|
+
if (!b) return a;
|
|
40
|
+
|
|
41
|
+
// do not resolve id to ids
|
|
42
|
+
let ids = [...(a.ids || []), ...(b.ids || [])];
|
|
43
|
+
return {
|
|
44
|
+
...a,
|
|
45
|
+
...b,
|
|
46
|
+
ids: ids,
|
|
47
|
+
filters: [...(a.filters || []), ...(b.filters || [])],
|
|
48
|
+
search: b.search || a.search,
|
|
49
|
+
// NOTE maybe should merge where ?
|
|
50
|
+
};
|
|
51
|
+
}, target || {});
|
|
52
|
+
return ListQuerySchema.parse(out);
|
|
53
|
+
}
|
package/src/resource/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { type AnyResource } from './schema/AnyResourceSchema';
|
|
2
2
|
export { type Identifiable } from './Identifiable';
|
|
3
3
|
export { getTitleOfResource } from './getTitleOfResource';
|
|
4
|
+
export { type ListQueryInput, type ListQuery, resolveListQuery, ListQuerySchema } from './ListQuery';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ResourceStatus, ResourceStatusSchema } from './ResourceStatus';
|
|
2
|
+
export { ResourceActionType, ResourceActionTypeSchema, ResourceActionDataSchema } from './ResourceActionType';
|
|
3
|
+
export { AnyResourceSchema, type AnyResource } from './AnyResourceSchema';
|
|
4
|
+
export { rz, type EnumValues } from './types';
|
|
5
|
+
export { BaseResourceSchema } from './BaseResourceSchema';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as SchemaRegistry from './SchemaRegistry';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getGlobalStates } from '@wener/utils';
|
|
2
|
-
import type { JsonSchemaDef } from '
|
|
3
|
-
import { toJsonSchema, type SchemaOutput, type TypeSchema } from '
|
|
2
|
+
import type { JsonSchemaDef } from '../jsonschema';
|
|
3
|
+
import { toJsonSchema, type SchemaOutput, type TypeSchema } from './index';
|
|
4
4
|
|
|
5
5
|
const types = getGlobalStates('@wener/common/resource/schema/SchemaRegistry', () => new Map<string, JsonSchemaDef>());
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ export function get(needle: TypeSchema | string) {
|
|
|
12
12
|
if (found) {
|
|
13
13
|
return found;
|
|
14
14
|
} else {
|
|
15
|
-
if (typeof needle !== 'string') {
|
|
15
|
+
if (needle && typeof needle !== 'string') {
|
|
16
16
|
return toJsonSchema(needle);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -33,10 +33,14 @@ function getKey(s: TypeSchema | string) {
|
|
|
33
33
|
return key;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
export function set(key: TypeSchema | string, def: TypeSchema): void;
|
|
37
|
+
export function set(key: TypeSchema, def?: TypeSchema): void;
|
|
38
|
+
export function set(key: TypeSchema | string, def?: TypeSchema) {
|
|
39
|
+
if (!def) {
|
|
40
|
+
def = key as TypeSchema;
|
|
41
|
+
if (!def || typeof def !== 'object') {
|
|
42
|
+
throw new Error(`Invalid schema definition for: ${getKey(key)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
41
45
|
types.set(getKey(key), toJsonSchema(def));
|
|
42
46
|
}
|
|
@@ -59,7 +59,7 @@ function _create(schema: JsonSchemaDef, options: CreateOptions, ctx: { required:
|
|
|
59
59
|
.with({ type: 'object' }, () => {
|
|
60
60
|
const out: Record<string, any> = {};
|
|
61
61
|
|
|
62
|
-
let required = schema.required
|
|
62
|
+
let required = Array.isArray(schema.required) ? schema.required : [];
|
|
63
63
|
for (const [k, v] of Object.entries(schema.properties || {}) as [string, JsonSchemaDef][]) {
|
|
64
64
|
const value = _create(v, options, {
|
|
65
65
|
required: required.includes(k),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { deepFreeze } from '@wener/utils';
|
|
2
2
|
import { getSchemaCache } from './getSchemaCache';
|
|
3
|
-
import {
|
|
3
|
+
import { SchemaRegistry } from './SchemaRegistry.mod';
|
|
4
4
|
import type { TypeSchema } from './TypeSchema';
|
|
5
5
|
|
|
6
6
|
export function getSchemaOptions(s: TypeSchema): Array<{ value: string; label: string }> {
|
|
7
|
-
let js =
|
|
7
|
+
let js = SchemaRegistry.get(s);
|
|
8
8
|
return getSchemaCache(s, 'options', () => {
|
|
9
9
|
let out =
|
|
10
10
|
(js.anyOf || js.oneOf)?.map((v) => {
|
package/src/schema/index.ts
CHANGED
|
@@ -4,3 +4,4 @@ export { getSchemaOptions, getSchemaOptionLabel } from './getSchemaOptions';
|
|
|
4
4
|
export { toJsonSchema } from './toJsonSchema';
|
|
5
5
|
export { findJsonSchemaByPath } from './findJsonSchemaByPath';
|
|
6
6
|
export { createSchemaData } from './createSchemaData';
|
|
7
|
+
export { SchemaRegistry } from './SchemaRegistry.mod';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
type EstimateProcessTimeResult = {
|
|
2
|
+
eta: number; // estimated time of arrival in seconds
|
|
3
|
+
elapsed: number; // in seconds
|
|
4
|
+
endTime: Date; // estimated end time
|
|
5
|
+
rate: number; // rate of processing in items per second
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function getEstimateProcessTime({
|
|
9
|
+
total,
|
|
10
|
+
processed,
|
|
11
|
+
startTime,
|
|
12
|
+
elapsed = startTime ? (Date.now() - startTime.getTime()) / 1000 : undefined,
|
|
13
|
+
}: {
|
|
14
|
+
total?: number;
|
|
15
|
+
processed?: number;
|
|
16
|
+
startTime?: Date;
|
|
17
|
+
elapsed?: number; // in seconds
|
|
18
|
+
}): EstimateProcessTimeResult | undefined {
|
|
19
|
+
if (typeof total !== 'number' || typeof processed !== 'number' || !elapsed || processed === 0 || processed >= total) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const now = new Date();
|
|
23
|
+
const rate = processed / elapsed;
|
|
24
|
+
if (rate === 0) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const remaining = total - processed;
|
|
28
|
+
const eta = Math.round(remaining / rate);
|
|
29
|
+
const endTime = new Date(now.getTime() + eta * 1000);
|
|
30
|
+
return {
|
|
31
|
+
eta,
|
|
32
|
+
elapsed,
|
|
33
|
+
endTime,
|
|
34
|
+
rate,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getEstimateProcessTime } from './getEstimateProcessTime';
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { formatDate } from "./formatDate.js";
|
|
2
|
-
import { Mod11Checksum } from "./Mod11Checksum.js";
|
|
3
|
-
(function (ResidentIdentityCardNumber) {
|
|
4
|
-
ResidentIdentityCardNumber.Checksum = new Mod11Checksum();
|
|
5
|
-
function parse(s) {
|
|
6
|
-
var division = s.slice(0, 6);
|
|
7
|
-
var birthDate = s.slice(6, 14);
|
|
8
|
-
var sequence = parseInt(s.slice(14, 17), 10);
|
|
9
|
-
var checksum = s.slice(17, 18);
|
|
10
|
-
var valid = ResidentIdentityCardNumber.Checksum.validate(s);
|
|
11
|
-
var sex = sequence % 2 === 1 ? "Male" : "Female";
|
|
12
|
-
return {
|
|
13
|
-
division: division,
|
|
14
|
-
birthDate: birthDate,
|
|
15
|
-
sequence: sequence,
|
|
16
|
-
checksum: checksum,
|
|
17
|
-
valid: valid,
|
|
18
|
-
sex: sex,
|
|
19
|
-
male: sex === "Male",
|
|
20
|
-
female: sex === "Female",
|
|
21
|
-
age: new Date().getFullYear() - parseInt(birthDate.slice(0, 4), 10)
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
/*
|
|
25
|
-
export const length = 18;
|
|
26
|
-
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]$/;
|
|
27
|
-
*/ ResidentIdentityCardNumber.parse = parse;
|
|
28
|
-
function format(param) {
|
|
29
|
-
var division = param.division, birthDate = param.birthDate, sequence = param.sequence, checksum = param.checksum;
|
|
30
|
-
if (typeof birthDate !== "string") {
|
|
31
|
-
birthDate = formatDate(birthDate, "yyyyMMDD");
|
|
32
|
-
}
|
|
33
|
-
if (birthDate.includes("-")) {
|
|
34
|
-
birthDate = birthDate.replace(/-/g, "");
|
|
35
|
-
}
|
|
36
|
-
typeof sequence === "number" && (sequence = sequence.toString());
|
|
37
|
-
sequence = sequence.padStart(3, "0");
|
|
38
|
-
var base = [
|
|
39
|
-
division,
|
|
40
|
-
birthDate,
|
|
41
|
-
sequence
|
|
42
|
-
].join("");
|
|
43
|
-
if (base.length !== 17)
|
|
44
|
-
throw new Error("Invalid params");
|
|
45
|
-
checksum || (checksum = ResidentIdentityCardNumber.Checksum.compute(base));
|
|
46
|
-
return base + checksum;
|
|
47
|
-
}
|
|
48
|
-
ResidentIdentityCardNumber.format = format;
|
|
49
|
-
})(ResidentIdentityCardNumber || (ResidentIdentityCardNumber = {}));
|
|
50
|
-
export var ResidentIdentityCardNumber;
|
package/lib/cn/formatDate.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export function formatDate(date, format) {
|
|
2
|
-
switch(format){
|
|
3
|
-
case 'yyyyMMDD':
|
|
4
|
-
{
|
|
5
|
-
var year = date.getFullYear();
|
|
6
|
-
var month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
7
|
-
var day = date.getDate().toString().padStart(2, '0');
|
|
8
|
-
return "".concat(year).concat(month).concat(day);
|
|
9
|
-
}
|
|
10
|
-
default:
|
|
11
|
-
throw new Error("Invalid format");
|
|
12
|
-
}
|
|
13
|
-
}
|
package/lib/cn/parseSex.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export function parseSex(s) {
|
|
2
|
-
if (!s) return undefined;
|
|
3
|
-
switch(s.toLowerCase()){
|
|
4
|
-
case '男':
|
|
5
|
-
case 'male':
|
|
6
|
-
return {
|
|
7
|
-
sex: 'Male',
|
|
8
|
-
male: true,
|
|
9
|
-
female: false
|
|
10
|
-
};
|
|
11
|
-
case '女':
|
|
12
|
-
case 'female':
|
|
13
|
-
return {
|
|
14
|
-
sex: 'Female',
|
|
15
|
-
male: false,
|
|
16
|
-
female: true
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|