@wener/common 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cn/DivisionCode.js.map +1 -1
- package/lib/cn/Mod11Checksum.js.map +1 -1
- package/lib/cn/Mod31Checksum.js.map +1 -1
- package/lib/cn/ResidentIdentityCardNumber.js.map +1 -1
- package/lib/cn/UnifiedSocialCreditCode.js.map +1 -1
- package/lib/cn/formatDate.js.map +1 -1
- package/lib/cn/parseSex.js.map +1 -1
- package/lib/cn/types.d.js.map +1 -1
- package/lib/consola/createStandardConsolaReporter.js +18 -0
- package/lib/consola/createStandardConsolaReporter.js.map +1 -0
- package/lib/consola/formatLogObject.js +125 -0
- package/lib/consola/formatLogObject.js.map +1 -0
- package/lib/consola/index.js +3 -0
- package/lib/consola/index.js.map +1 -0
- package/lib/data/formatSort.js +15 -0
- package/lib/data/formatSort.js.map +1 -0
- package/lib/data/index.js +4 -0
- package/lib/data/index.js.map +1 -0
- package/lib/data/maybeNumber.js +22 -0
- package/lib/data/maybeNumber.js.map +1 -0
- package/lib/data/parseSort.js +95 -0
- package/lib/data/parseSort.js.map +1 -0
- package/lib/data/resolvePagination.js +36 -0
- package/lib/data/resolvePagination.js.map +1 -0
- package/lib/data/types.d.js +3 -0
- package/lib/data/types.d.js.map +1 -0
- package/lib/index.js +6 -2
- package/lib/index.js.map +1 -1
- package/lib/jsonschema/JsonSchema.js +6 -6
- package/lib/jsonschema/JsonSchema.js.map +1 -1
- package/lib/jsonschema/types.d.js.map +1 -1
- package/lib/meta/defineFileType.js.map +1 -1
- package/lib/meta/defineInit.js.map +1 -1
- package/lib/meta/defineMetadata.js.map +1 -1
- package/lib/password/PHC.js +8 -8
- package/lib/password/PHC.js.map +1 -1
- package/lib/password/Password.js.map +1 -1
- package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
- package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
- package/lib/search/AdvanceSearch.js.map +1 -1
- package/lib/search/formatAdvanceSearch.js.map +1 -1
- package/lib/search/optimizeAdvanceSearch.js.map +1 -1
- package/lib/search/parseAdvanceSearch.js.map +1 -1
- package/lib/search/parser.d.js.map +1 -1
- package/lib/search/types.d.js.map +1 -1
- package/lib/tools/generateSchema.js +43 -0
- package/lib/tools/generateSchema.js.map +1 -0
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -1
- package/package.json +19 -5
- package/src/cn/DivisionCode.test.ts +38 -45
- package/src/cn/DivisionCode.ts +140 -184
- package/src/cn/Mod11Checksum.ts +17 -17
- package/src/cn/Mod31Checksum.ts +25 -25
- package/src/cn/ResidentIdentityCardNumber.test.ts +12 -16
- package/src/cn/ResidentIdentityCardNumber.ts +82 -82
- package/src/cn/UnifiedSocialCreditCode.test.ts +11 -11
- package/src/cn/UnifiedSocialCreditCode.ts +115 -120
- package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +1 -1
- package/src/cn/formatDate.ts +10 -10
- package/src/cn/parseSex.ts +11 -25
- package/src/cn/types.d.ts +43 -43
- package/src/consola/createStandardConsolaReporter.ts +31 -0
- package/src/consola/formatLogObject.ts +171 -0
- package/src/consola/index.ts +2 -0
- package/src/data/formatSort.test.ts +13 -0
- package/src/data/formatSort.ts +18 -0
- package/src/data/index.ts +5 -0
- package/src/data/maybeNumber.ts +23 -0
- package/src/data/parseSort.test.ts +67 -0
- package/src/data/parseSort.ts +108 -0
- package/src/data/resolvePagination.test.ts +58 -0
- package/src/data/resolvePagination.ts +60 -0
- package/src/data/types.d.ts +33 -0
- package/src/index.ts +8 -2
- package/src/jsonschema/JsonSchema.test.ts +13 -22
- package/src/jsonschema/JsonSchema.ts +146 -178
- package/src/jsonschema/types.d.ts +151 -161
- package/src/meta/defineFileType.tsx +54 -54
- package/src/meta/defineInit.ts +32 -53
- package/src/meta/defineMetadata.test.ts +5 -7
- package/src/meta/defineMetadata.ts +28 -46
- package/src/password/PHC.test.ts +186 -277
- package/src/password/PHC.ts +243 -243
- package/src/password/Password.test.ts +38 -50
- package/src/password/Password.ts +73 -95
- package/src/password/createArgon2PasswordAlgorithm.ts +65 -69
- package/src/password/createBase64PasswordAlgorithm.ts +9 -9
- package/src/password/createBcryptPasswordAlgorithm.ts +20 -22
- package/src/password/createPBKDF2PasswordAlgorithm.ts +49 -61
- package/src/password/createScryptPasswordAlgorithm.ts +48 -59
- package/src/search/AdvanceSearch.test.ts +136 -143
- package/src/search/AdvanceSearch.ts +6 -6
- package/src/search/formatAdvanceSearch.ts +44 -53
- package/src/search/optimizeAdvanceSearch.ts +70 -83
- package/src/search/parseAdvanceSearch.ts +16 -19
- package/src/search/parser.d.ts +3 -3
- package/src/search/types.d.ts +28 -54
- package/src/tools/generateSchema.ts +39 -0
- package/src/tools/renderJsonSchemaToMarkdownDoc.ts +69 -69
- package/lib/normalizePagination.js +0 -14
- package/lib/normalizePagination.js.map +0 -1
- package/lib/parseSort.js +0 -106
- package/lib/parseSort.js.map +0 -1
- package/src/normalizePagination.ts +0 -25
- package/src/parseSort.test.ts +0 -42
- package/src/parseSort.ts +0 -133
package/src/index.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated
|
|
3
|
+
*/
|
|
4
|
+
export { parseSort, type SortRule } from './data/parseSort';
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated
|
|
7
|
+
*/
|
|
8
|
+
export { resolvePagination as normalizePagination } from './data/resolvePagination';
|
|
@@ -2,26 +2,17 @@ import { describe, expect, it } from 'vitest';
|
|
|
2
2
|
import { JsonSchema } from './JsonSchema';
|
|
3
3
|
|
|
4
4
|
describe('jsonschema', () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
required: ['a'],
|
|
20
|
-
},
|
|
21
|
-
{ a: '' },
|
|
22
|
-
],
|
|
23
|
-
]) {
|
|
24
|
-
expect(JsonSchema.create(a)).toEqual(b);
|
|
25
|
-
}
|
|
26
|
-
});
|
|
5
|
+
it('should create from schema', () => {
|
|
6
|
+
for (const [a, b] of [
|
|
7
|
+
[{ type: 'string' }, ''],
|
|
8
|
+
[{ type: 'number' }, 0],
|
|
9
|
+
[{ type: 'number', default: 1 }, 1],
|
|
10
|
+
[{ type: 'integer' }, 0],
|
|
11
|
+
[{ type: 'array' }, []],
|
|
12
|
+
[{ type: 'object' }, {}],
|
|
13
|
+
[{ type: 'object', properties: { a: { type: 'string' } }, required: ['a'] }, { a: '' }],
|
|
14
|
+
]) {
|
|
15
|
+
expect(JsonSchema.create(a)).toEqual(b);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
27
18
|
});
|
|
@@ -1,197 +1,165 @@
|
|
|
1
1
|
import type { Static, TSchema } from '@sinclair/typebox';
|
|
2
2
|
import Ajv, { type ErrorObject, type Options } from 'ajv';
|
|
3
3
|
import addFormats from 'ajv-formats';
|
|
4
|
-
import localize from 'ajv-i18n/localize/zh';
|
|
4
|
+
// import localize from 'ajv-i18n/localize/zh';
|
|
5
5
|
import addKeywords from 'ajv-keywords';
|
|
6
6
|
import { isNil } from 'es-toolkit';
|
|
7
7
|
import { match, P } from 'ts-pattern';
|
|
8
8
|
import type { JsonSchemaDef } from './types';
|
|
9
9
|
|
|
10
10
|
function _createAjv(opt: Options) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const ajv = new Ajv(opt);
|
|
12
|
+
addKeywords(ajv);
|
|
13
|
+
addFormats(ajv);
|
|
14
|
+
return ajv;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
type ValidateOptions = {
|
|
18
|
-
mutate?: boolean;
|
|
19
|
-
clone?: boolean;
|
|
20
|
-
ajv?: Ajv;
|
|
21
|
-
};
|
|
17
|
+
type ValidateOptions = { mutate?: boolean; clone?: boolean; ajv?: Ajv };
|
|
22
18
|
|
|
23
19
|
type ValidateResult<T> =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
useDefaults: true,
|
|
56
|
-
coerceTypes: true,
|
|
57
|
-
allErrors: true,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (clone) {
|
|
62
|
-
data = structuredClone(data);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (!ajv) {
|
|
66
|
-
ajv = JsonSchema.createAjv(opts);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const validate = ajv.compile(schema);
|
|
70
|
-
|
|
71
|
-
// consider reusing validate instance
|
|
72
|
-
|
|
73
|
-
const valid = validate(data);
|
|
74
|
-
const errors = validate.errors;
|
|
75
|
-
localize(errors);
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
data,
|
|
79
|
-
success: valid,
|
|
80
|
-
message: ajv.errorsText(errors),
|
|
81
|
-
errors: errors,
|
|
82
|
-
};
|
|
20
|
+
| { data: T; success: true; message: undefined }
|
|
21
|
+
| { data: undefined; success: false; message: string; errors: ErrorObject[] };
|
|
22
|
+
|
|
23
|
+
function validate({ schema, data, mutate, clone, ajv }: ValidateOptions & { schema: any; data: any }) {
|
|
24
|
+
let opts: Options = {
|
|
25
|
+
// strict: 'log',
|
|
26
|
+
strict: true,
|
|
27
|
+
strictSchema: 'log', // skip unknown keywords in schema
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
if (mutate) {
|
|
31
|
+
Object.assign(opts, { removeAdditional: true, useDefaults: true, coerceTypes: true, allErrors: true });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (clone) {
|
|
35
|
+
data = structuredClone(data);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!ajv) {
|
|
39
|
+
ajv = JsonSchema.createAjv(opts);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const validate = ajv.compile(schema);
|
|
43
|
+
|
|
44
|
+
// consider reusing validate instance
|
|
45
|
+
|
|
46
|
+
const valid = validate(data);
|
|
47
|
+
const errors = validate.errors;
|
|
48
|
+
// localize(errors);
|
|
49
|
+
|
|
50
|
+
return { data, success: valid, message: ajv.errorsText(errors), errors: errors };
|
|
83
51
|
}
|
|
84
52
|
|
|
85
53
|
type TypeOfSchema<S> = S extends TSchema ? Static<S> : any;
|
|
86
54
|
|
|
87
55
|
export namespace JsonSchema {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
56
|
+
export let schemas: JsonSchemaDef[] = [];
|
|
57
|
+
|
|
58
|
+
export const createAjv = _createAjv;
|
|
59
|
+
|
|
60
|
+
export function addSchema(
|
|
61
|
+
schema: JsonSchemaDef,
|
|
62
|
+
{
|
|
63
|
+
onConflict = 'throw',
|
|
64
|
+
}: {
|
|
65
|
+
onConflict?: 'throw' | 'ignore' | 'replace' | ((old: JsonSchemaDef, neo: JsonSchemaDef) => JsonSchemaDef);
|
|
66
|
+
} = {},
|
|
67
|
+
) {
|
|
68
|
+
if (!schema.$id) throw new Error('Schema must have $id');
|
|
69
|
+
switch (onConflict) {
|
|
70
|
+
case 'ignore':
|
|
71
|
+
onConflict = (old) => old;
|
|
72
|
+
break;
|
|
73
|
+
case 'replace':
|
|
74
|
+
onConflict = (_, neo) => neo;
|
|
75
|
+
break;
|
|
76
|
+
case 'throw':
|
|
77
|
+
onConflict = (old, neo) => {
|
|
78
|
+
throw new Error(`Schema ${neo.$id} already exists`);
|
|
79
|
+
};
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
let idx = schemas.findIndex((s) => s.$id === schema.$id);
|
|
83
|
+
if (idx >= 0) {
|
|
84
|
+
schemas[idx] = onConflict(schemas[idx], schema);
|
|
85
|
+
} else {
|
|
86
|
+
schemas.push(schema);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Check data is valid, will not use default
|
|
92
|
+
*/
|
|
93
|
+
export function check<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {
|
|
94
|
+
return validate({ schema, data, mutate: false, clone: true }) as any;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Parse data with default value and coerceTypes
|
|
99
|
+
*/
|
|
100
|
+
export function safeParse<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {
|
|
101
|
+
return validate({ schema, data, mutate: true, clone: true }) as any;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function parse<S>(schema: S, data: any): TypeOfSchema<S> {
|
|
105
|
+
const { data: out, message, errors } = validate({ schema, data, mutate: true, clone: true });
|
|
106
|
+
if (errors) {
|
|
107
|
+
throw new Error(message);
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function create<S>(schema: S, data?: any): TypeOfSchema<S> {
|
|
113
|
+
// will not ensure value match the rule
|
|
114
|
+
return match(schema as JsonSchemaDef)
|
|
115
|
+
.returnType<any>()
|
|
116
|
+
.with({ const: P.select() }, (v) => v)
|
|
117
|
+
.with({ default: P.select() }, (v) => v)
|
|
118
|
+
.with({ anyOf: P.nonNullable }, (schema) => {
|
|
119
|
+
return create(schema.anyOf[0]);
|
|
120
|
+
})
|
|
121
|
+
.with({ oneOf: P.nonNullable }, (schema) => {
|
|
122
|
+
return create(schema.oneOf[0]);
|
|
123
|
+
})
|
|
124
|
+
.with({ type: 'string' }, (schema) => '')
|
|
125
|
+
.with({ type: P.union('number', 'integer') }, (schema) => 0)
|
|
126
|
+
.with({ type: 'object' }, (schema) => {
|
|
127
|
+
let out = validate({ schema, data: data ?? {}, mutate: true });
|
|
128
|
+
if (!out.success) {
|
|
129
|
+
// fallback
|
|
130
|
+
let obj = data || {};
|
|
131
|
+
schema.required?.forEach((key) => {
|
|
132
|
+
if (!(key in obj)) {
|
|
133
|
+
let last = obj[key];
|
|
134
|
+
let prop = schema.properties?.[key];
|
|
135
|
+
if (prop && isNil(last)) obj[key] = JsonSchema.create(prop, last);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
out = validate({ schema, data: obj, mutate: true });
|
|
139
|
+
if (!out.success) {
|
|
140
|
+
console.warn(`Failed to create object with schema: ${out.message}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return out.data;
|
|
144
|
+
})
|
|
145
|
+
.with({ type: 'null' }, () => null)
|
|
146
|
+
.with({ type: 'boolean' }, (schema) => false)
|
|
147
|
+
.with({ type: 'array' }, (schema) => [])
|
|
148
|
+
.otherwise(() => {
|
|
149
|
+
return undefined;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function isPrimitiveType(schema: any): boolean {
|
|
154
|
+
return match(schema as JsonSchemaDef)
|
|
155
|
+
.returnType<boolean>()
|
|
156
|
+
.with({ type: P.union('number', 'integer', 'string', 'boolean') }, () => true)
|
|
157
|
+
.with({ anyOf: P.nonNullable }, (schema) => {
|
|
158
|
+
return isPrimitiveType(schema.anyOf[0]);
|
|
159
|
+
})
|
|
160
|
+
.with({ oneOf: P.nonNullable }, (schema) => {
|
|
161
|
+
return isPrimitiveType(schema.oneOf[0]);
|
|
162
|
+
})
|
|
163
|
+
.otherwise(() => false);
|
|
164
|
+
}
|
|
197
165
|
}
|