@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/search/types.d.ts
CHANGED
|
@@ -1,71 +1,45 @@
|
|
|
1
1
|
export type Exprs = Expr[];
|
|
2
2
|
export type Expr =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
| CommentExpr
|
|
4
|
+
| ParenthesesExpr
|
|
5
|
+
| KeywordCondition
|
|
6
|
+
| LogicalCondition
|
|
7
|
+
| NotCondition
|
|
8
|
+
| CompareCondition;
|
|
9
9
|
|
|
10
|
-
export type CommentExpr = {
|
|
11
|
-
type: 'comment';
|
|
12
|
-
value: string;
|
|
13
|
-
};
|
|
10
|
+
export type CommentExpr = { type: 'comment'; value: string };
|
|
14
11
|
|
|
15
|
-
export type ParenthesesExpr = {
|
|
16
|
-
type: 'parentheses';
|
|
17
|
-
value: Expr[];
|
|
18
|
-
};
|
|
12
|
+
export type ParenthesesExpr = { type: 'parentheses'; value: Expr[] };
|
|
19
13
|
|
|
20
|
-
export type KeywordCondition = {
|
|
21
|
-
type: 'keyword';
|
|
22
|
-
value: string;
|
|
23
|
-
negative?: boolean;
|
|
24
|
-
exact?: boolean;
|
|
25
|
-
};
|
|
14
|
+
export type KeywordCondition = { type: 'keyword'; value: string; negative?: boolean; exact?: boolean };
|
|
26
15
|
|
|
27
|
-
export type LogicalCondition = {
|
|
28
|
-
type: 'logical';
|
|
29
|
-
operator: 'and' | 'or';
|
|
30
|
-
value: Expr[];
|
|
31
|
-
};
|
|
16
|
+
export type LogicalCondition = { type: 'logical'; operator: 'and' | 'or'; value: Expr[] };
|
|
32
17
|
|
|
33
|
-
export type NotCondition = {
|
|
34
|
-
type: 'not';
|
|
35
|
-
value: Expr;
|
|
36
|
-
};
|
|
18
|
+
export type NotCondition = { type: 'not'; value: Expr };
|
|
37
19
|
|
|
38
20
|
export type CompareCondition = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
21
|
+
type: 'compare';
|
|
22
|
+
field: string;
|
|
23
|
+
/**
|
|
24
|
+
* mention value for eq, ne only
|
|
25
|
+
* range require range value
|
|
26
|
+
*/
|
|
27
|
+
operator: 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte' | 'range' | 'match';
|
|
28
|
+
negative?: boolean;
|
|
29
|
+
mention?: boolean;
|
|
30
|
+
value: Value;
|
|
49
31
|
};
|
|
50
32
|
|
|
51
33
|
export type Value = LiteralValue | RangeValue | MentionValue;
|
|
52
34
|
|
|
53
|
-
export type LiteralValue = {
|
|
54
|
-
type?: 'literal';
|
|
55
|
-
format?: 'date' | 'date-time';
|
|
56
|
-
value: string | number | null;
|
|
57
|
-
};
|
|
35
|
+
export type LiteralValue = { type?: 'literal'; format?: 'date' | 'date-time'; value: string | number | null };
|
|
58
36
|
|
|
59
|
-
export type MentionValue = {
|
|
60
|
-
type?: 'literal';
|
|
61
|
-
format: 'mention';
|
|
62
|
-
value: string;
|
|
63
|
-
};
|
|
37
|
+
export type MentionValue = { type?: 'literal'; format: 'mention'; value: string };
|
|
64
38
|
|
|
65
39
|
export type RangeValue = {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
40
|
+
type: 'range';
|
|
41
|
+
minimum: LiteralValue | undefined;
|
|
42
|
+
maximum: LiteralValue | undefined;
|
|
43
|
+
minimumExclusive: boolean;
|
|
44
|
+
maximumExclusive: boolean;
|
|
71
45
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import * as Codegen from '@sinclair/typebox-codegen';
|
|
5
|
+
|
|
6
|
+
export async function generateSchema({ file, dir = path.dirname(file) }: { file: string; dir?: string }) {
|
|
7
|
+
const fn = path.basename(file).replace(/\.d\.ts$/, '.ts');
|
|
8
|
+
const types = await fs.readFile(file, 'utf-8');
|
|
9
|
+
|
|
10
|
+
const typeboxDir = path.join(dir, 'typebox');
|
|
11
|
+
const zodDir = path.join(dir, 'zod');
|
|
12
|
+
|
|
13
|
+
await fs.mkdir(typeboxDir, { recursive: true });
|
|
14
|
+
await fs.mkdir(zodDir, { recursive: true });
|
|
15
|
+
|
|
16
|
+
const typeBoxFile = path.join(typeboxDir, fn);
|
|
17
|
+
const zodFile = path.join(zodDir, fn);
|
|
18
|
+
{
|
|
19
|
+
// avoid import type error
|
|
20
|
+
let out = Codegen.TypeScriptToTypeBox.Generate(types);
|
|
21
|
+
out = out.replace(/^import \{ Type, Static\b/, `import { Type, type Static`);
|
|
22
|
+
await fs.writeFile(typeBoxFile, out);
|
|
23
|
+
}
|
|
24
|
+
const model = Codegen.TypeScriptToModel.Generate(types);
|
|
25
|
+
await fs.writeFile(zodFile, Codegen.ModelToZod.Generate(model));
|
|
26
|
+
|
|
27
|
+
await new Promise((resolve, reject) => {
|
|
28
|
+
exec(`pnpm prettier --write "${dir}/{typebox,zod}/*.ts"`, (error, stdout, stderr) => {
|
|
29
|
+
if (error) {
|
|
30
|
+
console.error(`exec error: ${error}`);
|
|
31
|
+
reject(error);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
resolve({ stderr, stdout });
|
|
35
|
+
stdout && console.log(`prettier:stdout: ${stdout}`);
|
|
36
|
+
stderr && console.error(`prettier:stderr: ${stderr}`);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -1,93 +1,93 @@
|
|
|
1
1
|
import type { TObject, TSchema } from '@sinclair/typebox';
|
|
2
2
|
|
|
3
3
|
export function renderJsonSchemaToMarkdownDoc(rootSchema: any) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
// markdown
|
|
5
|
+
const out: string[] = [];
|
|
6
|
+
const all = new Set();
|
|
7
|
+
const pending: TSchema[] = [];
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
const addObject = (o: TSchema) => {
|
|
10
|
+
if (all.has(o.$id)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
all.add(o.$id);
|
|
14
|
+
pending.push(o);
|
|
15
|
+
};
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
const writeObjectProps = (T: TObject, { prefix = '' }: { prefix?: string } = {}) => {
|
|
18
|
+
if (!T?.properties) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const [name, schema] of Object.entries(T.properties)) {
|
|
22
|
+
let typ = schema.$id || schema.type;
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
24
|
+
if (typ === 'array') {
|
|
25
|
+
typ = `${schema.items.$id || schema.items.type}[]`;
|
|
26
|
+
if (schema.items.$id) {
|
|
27
|
+
addObject(schema.items);
|
|
28
|
+
}
|
|
29
|
+
} else if (schema.$id) {
|
|
30
|
+
addObject(schema);
|
|
31
|
+
}
|
|
32
|
+
if (!typ) {
|
|
33
|
+
if ('anyOf' in schema) {
|
|
34
|
+
typ = 'enum';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
out.push(`| ${prefix}${name} | ${typ} | ${schema.title || schema.description || ''} |`);
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
if (typ === 'object') {
|
|
41
|
+
writeObjectProps(schema as TObject, { prefix: `${prefix}${name}.` });
|
|
42
|
+
} else if (schema.type === 'array') {
|
|
43
|
+
if (schema.items.type === 'object' && !schema.items.$id) {
|
|
44
|
+
writeObjectProps(schema.items as TObject, { prefix: `${prefix}${name}[].` });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const writeObject = (T: TObject) => {
|
|
50
|
+
out.push(`### ${T.title || T.$id}`);
|
|
51
|
+
out.push(`
|
|
52
52
|
| $id | 名字 |
|
|
53
53
|
| --- | --- |
|
|
54
54
|
| ${T.$id || ''} | ${T.title || ''} |
|
|
55
55
|
`);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
if (T.description) {
|
|
57
|
+
out.push('');
|
|
58
|
+
out.push(`> ${T.description}`);
|
|
59
|
+
out.push('');
|
|
60
|
+
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
out.push(`| 名字 | 类型 | 说明 |`);
|
|
63
|
+
out.push(`| --- | --- | --- |`);
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
writeObjectProps(T);
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
out.push('');
|
|
68
|
+
};
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
writeObject(rootSchema);
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
for (const schema of pending) {
|
|
73
|
+
if (schema.type === 'object') {
|
|
74
|
+
writeObject(schema as TObject);
|
|
75
|
+
} else if ('anyOf' in schema) {
|
|
76
|
+
out.push(`### ${schema.$id || schema.title}`);
|
|
77
|
+
out.push(`
|
|
78
78
|
| $id | 名字 |
|
|
79
79
|
| --- | --- |
|
|
80
80
|
| ${schema.$id || ''} | ${schema.title || ''} |
|
|
81
81
|
`);
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
out.push(`| 值 | 说明 |`);
|
|
84
|
+
out.push(`| --- | --- |`);
|
|
85
|
+
for (const item of schema.anyOf) {
|
|
86
|
+
out.push(`| ${item.const} | ${item.title || item.description || ''} |`);
|
|
87
|
+
}
|
|
88
|
+
out.push('');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
return out.join('\n');
|
|
93
93
|
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export function normalizePagination(page) {
|
|
2
|
-
let { pageSize = normalizePagination.defaultPageSize, pageNumber = 1, pageIndex = pageNumber - 1, limit, offset } = page;
|
|
3
|
-
if (normalizePagination.maxPageSize) {
|
|
4
|
-
pageSize = Math.min(pageSize, normalizePagination.maxPageSize);
|
|
5
|
-
}
|
|
6
|
-
return {
|
|
7
|
-
limit: limit || pageSize,
|
|
8
|
-
offset: Math.min(0, offset ?? pageIndex * pageSize)
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
normalizePagination.defaultPageSize = 20;
|
|
12
|
-
normalizePagination.maxPageSize = undefined;
|
|
13
|
-
|
|
14
|
-
//# sourceMappingURL=normalizePagination.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/normalizePagination.ts"],"sourcesContent":["export function normalizePagination(page: {\n pageSize?: number;\n pageIndex?: number;\n pageNumber?: number;\n limit?: number;\n offset?: number;\n}) {\n let {\n pageSize = normalizePagination.defaultPageSize,\n pageNumber = 1,\n pageIndex = pageNumber - 1,\n limit,\n offset,\n } = page;\n if (normalizePagination.maxPageSize) {\n pageSize = Math.min(pageSize, normalizePagination.maxPageSize);\n }\n return {\n limit: limit || pageSize,\n offset: Math.min(0, offset ?? pageIndex * pageSize),\n };\n}\n\nnormalizePagination.defaultPageSize = 20;\nnormalizePagination.maxPageSize = undefined as number | undefined;\n"],"names":["normalizePagination","page","pageSize","defaultPageSize","pageNumber","pageIndex","limit","offset","maxPageSize","Math","min","undefined"],"mappings":"AAAA,OAAO,SAASA,oBAAoBC,IAMnC;IACC,IAAI,EACFC,WAAWF,oBAAoBG,eAAe,EAC9CC,aAAa,CAAC,EACdC,YAAYD,aAAa,CAAC,EAC1BE,KAAK,EACLC,MAAM,EACP,GAAGN;IACJ,IAAID,oBAAoBQ,WAAW,EAAE;QACnCN,WAAWO,KAAKC,GAAG,CAACR,UAAUF,oBAAoBQ,WAAW;IAC/D;IACA,OAAO;QACLF,OAAOA,SAASJ;QAChBK,QAAQE,KAAKC,GAAG,CAAC,GAAGH,UAAUF,YAAYH;IAC5C;AACF;AAEAF,oBAAoBG,eAAe,GAAG;AACtCH,oBAAoBQ,WAAW,GAAGG"}
|
package/lib/parseSort.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { arrayOfMaybeArray } from "@wener/utils";
|
|
2
|
-
/**
|
|
3
|
-
* parsing order string
|
|
4
|
-
*
|
|
5
|
-
* e.g.
|
|
6
|
-
* ```
|
|
7
|
-
* a desc
|
|
8
|
-
* +a,-b
|
|
9
|
-
* a asc nulls last
|
|
10
|
-
* a desc first
|
|
11
|
-
* ```
|
|
12
|
-
*/ export function parseSort(order) {
|
|
13
|
-
if (!order) {
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
return arrayOfMaybeArray(order).flatMap((v)=>{
|
|
17
|
-
if (!v) return [];
|
|
18
|
-
if (typeof v === 'object') {
|
|
19
|
-
// invalid
|
|
20
|
-
if (!v.field) {
|
|
21
|
-
return [];
|
|
22
|
-
}
|
|
23
|
-
let rule = {
|
|
24
|
-
field: v.field,
|
|
25
|
-
order: v.order?.toLowerCase() === 'asc' ? 'asc' : 'desc'
|
|
26
|
-
};
|
|
27
|
-
if (v.nulls) {
|
|
28
|
-
rule.nulls = v.nulls.toLowerCase() === 'last' ? 'last' : 'first';
|
|
29
|
-
}
|
|
30
|
-
return rule;
|
|
31
|
-
}
|
|
32
|
-
return v.split(',').map((v)=>v.trim()).filter(Boolean).map(_parse);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
function _parse(v) {
|
|
36
|
-
// const sp = v.match(/^(?<field>[a-z0-9_]+)(\s+(?<order>asc|desc))?(\s+(?<nulls>nulls\s+(?<nulls_order>last|first)))?$/i);
|
|
37
|
-
const sp = v.split(/\s+/);
|
|
38
|
-
let field = '';
|
|
39
|
-
let order;
|
|
40
|
-
let nulls;
|
|
41
|
-
const f = sp.shift();
|
|
42
|
-
if (f.startsWith('-') || f.startsWith('+')) {
|
|
43
|
-
// (order = f.slice(1).trim()), f.startsWith('-') ? 'desc' : 'asc';
|
|
44
|
-
field = f.slice(1).trim();
|
|
45
|
-
order = f.startsWith('-') ? 'desc' : 'asc';
|
|
46
|
-
} else {
|
|
47
|
-
field = f.trim();
|
|
48
|
-
}
|
|
49
|
-
while(true){
|
|
50
|
-
const v = sp.shift()?.trim()?.toLowerCase();
|
|
51
|
-
if (!v) {
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
switch(v){
|
|
55
|
-
case 'asc':
|
|
56
|
-
case 'desc':
|
|
57
|
-
{
|
|
58
|
-
order = v;
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
case 'nulls':
|
|
62
|
-
{
|
|
63
|
-
nulls = sp.shift()?.trim()?.toLowerCase() === 'last' ? 'last' : 'first';
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
case 'last':
|
|
67
|
-
case 'first':
|
|
68
|
-
{
|
|
69
|
-
nulls = v;
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
order ||= 'asc';
|
|
75
|
-
// avoid undefined
|
|
76
|
-
// NOTE pg default nulls first for desc, last for asc
|
|
77
|
-
// https://www.postgresql.org/docs/current/queries-order.html
|
|
78
|
-
if (!nulls) {
|
|
79
|
-
return {
|
|
80
|
-
field,
|
|
81
|
-
order
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
field,
|
|
86
|
-
order,
|
|
87
|
-
nulls
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
export function formatSort(s) {
|
|
91
|
-
return s.map(({ field, order, nulls })=>{
|
|
92
|
-
if (field) {
|
|
93
|
-
let r = field;
|
|
94
|
-
if (order) {
|
|
95
|
-
r += ` ${order}`;
|
|
96
|
-
}
|
|
97
|
-
if (nulls) {
|
|
98
|
-
r += ` nulls ${nulls}`;
|
|
99
|
-
}
|
|
100
|
-
return r;
|
|
101
|
-
}
|
|
102
|
-
return '';
|
|
103
|
-
}).filter(Boolean);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
//# sourceMappingURL=parseSort.js.map
|
package/lib/parseSort.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parseSort.ts"],"sourcesContent":["import { arrayOfMaybeArray, type MaybeArray } from '@wener/utils';\n\nexport type SortRule = {\n field: string;\n order: 'asc' | 'desc';\n nulls?: 'last' | 'first';\n};\n\n/**\n * parsing order string\n *\n * e.g.\n * ```\n * a desc\n * +a,-b\n * a asc nulls last\n * a desc first\n * ```\n */\nexport function parseSort(\n order:\n | MaybeArray<\n | {\n field?: string;\n order?: string;\n nulls?: string;\n }\n | string\n >\n | undefined\n | null,\n): SortRule[] {\n if (!order) {\n return [];\n }\n\n return arrayOfMaybeArray(order).flatMap((v): MaybeArray<SortRule> => {\n if (!v) return [];\n if (typeof v === 'object') {\n // invalid\n if (!v.field) {\n return [];\n }\n let rule: SortRule = {\n field: v.field,\n order: v.order?.toLowerCase() === 'asc' ? 'asc' : 'desc',\n };\n if (v.nulls) {\n rule.nulls = v.nulls.toLowerCase() === 'last' ? 'last' : 'first';\n }\n return rule;\n }\n return v\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean)\n .map(_parse);\n });\n}\n\nfunction _parse(v: string) {\n // const sp = v.match(/^(?<field>[a-z0-9_]+)(\\s+(?<order>asc|desc))?(\\s+(?<nulls>nulls\\s+(?<nulls_order>last|first)))?$/i);\n const sp = v.split(/\\s+/);\n let field = '';\n let order: SortRule['order'];\n let nulls: SortRule['nulls'];\n\n const f = sp.shift()!;\n if (f.startsWith('-') || f.startsWith('+')) {\n // (order = f.slice(1).trim()), f.startsWith('-') ? 'desc' : 'asc';\n field = f.slice(1).trim();\n order = f.startsWith('-') ? 'desc' : 'asc';\n } else {\n field = f.trim();\n }\n\n while (true) {\n const v = sp.shift()?.trim()?.toLowerCase();\n if (!v) {\n break;\n }\n\n switch (v) {\n case 'asc':\n case 'desc': {\n order = v;\n break;\n }\n\n case 'nulls': {\n nulls = sp.shift()?.trim()?.toLowerCase() === 'last' ? 'last' : 'first';\n break;\n }\n\n case 'last':\n case 'first': {\n nulls = v;\n break;\n }\n }\n }\n\n order ||= 'asc';\n // avoid undefined\n // NOTE pg default nulls first for desc, last for asc\n // https://www.postgresql.org/docs/current/queries-order.html\n if (!nulls) {\n return { field, order };\n }\n return {\n field,\n order,\n nulls,\n };\n}\n\nexport function formatSort(s: SortRule[]): string[] {\n return s\n .map(({ field, order, nulls }) => {\n if (field) {\n let r = field;\n if (order) {\n r += ` ${order}`;\n }\n if (nulls) {\n r += ` nulls ${nulls}`;\n }\n return r;\n }\n return '';\n })\n .filter(Boolean);\n}\n"],"names":["arrayOfMaybeArray","parseSort","order","flatMap","v","field","rule","toLowerCase","nulls","split","map","trim","filter","Boolean","_parse","sp","f","shift","startsWith","slice","formatSort","s","r"],"mappings":"AAAA,SAASA,iBAAiB,QAAyB,eAAe;AAQlE;;;;;;;;;;CAUC,GACD,OAAO,SAASC,UACdC,KAUQ;IAER,IAAI,CAACA,OAAO;QACV,OAAO,EAAE;IACX;IAEA,OAAOF,kBAAkBE,OAAOC,OAAO,CAAC,CAACC;QACvC,IAAI,CAACA,GAAG,OAAO,EAAE;QACjB,IAAI,OAAOA,MAAM,UAAU;YACzB,UAAU;YACV,IAAI,CAACA,EAAEC,KAAK,EAAE;gBACZ,OAAO,EAAE;YACX;YACA,IAAIC,OAAiB;gBACnBD,OAAOD,EAAEC,KAAK;gBACdH,OAAOE,EAAEF,KAAK,EAAEK,kBAAkB,QAAQ,QAAQ;YACpD;YACA,IAAIH,EAAEI,KAAK,EAAE;gBACXF,KAAKE,KAAK,GAAGJ,EAAEI,KAAK,CAACD,WAAW,OAAO,SAAS,SAAS;YAC3D;YACA,OAAOD;QACT;QACA,OAAOF,EACJK,KAAK,CAAC,KACNC,GAAG,CAAC,CAACN,IAAMA,EAAEO,IAAI,IACjBC,MAAM,CAACC,SACPH,GAAG,CAACI;IACT;AACF;AAEA,SAASA,OAAOV,CAAS;IACvB,2HAA2H;IAC3H,MAAMW,KAAKX,EAAEK,KAAK,CAAC;IACnB,IAAIJ,QAAQ;IACZ,IAAIH;IACJ,IAAIM;IAEJ,MAAMQ,IAAID,GAAGE,KAAK;IAClB,IAAID,EAAEE,UAAU,CAAC,QAAQF,EAAEE,UAAU,CAAC,MAAM;QAC1C,mEAAmE;QACnEb,QAAQW,EAAEG,KAAK,CAAC,GAAGR,IAAI;QACvBT,QAAQc,EAAEE,UAAU,CAAC,OAAO,SAAS;IACvC,OAAO;QACLb,QAAQW,EAAEL,IAAI;IAChB;IAEA,MAAO,KAAM;QACX,MAAMP,IAAIW,GAAGE,KAAK,IAAIN,QAAQJ;QAC9B,IAAI,CAACH,GAAG;YACN;QACF;QAEA,OAAQA;YACN,KAAK;YACL,KAAK;gBAAQ;oBACXF,QAAQE;oBACR;gBACF;YAEA,KAAK;gBAAS;oBACZI,QAAQO,GAAGE,KAAK,IAAIN,QAAQJ,kBAAkB,SAAS,SAAS;oBAChE;gBACF;YAEA,KAAK;YACL,KAAK;gBAAS;oBACZC,QAAQJ;oBACR;gBACF;QACF;IACF;IAEAF,UAAU;IACV,kBAAkB;IAClB,qDAAqD;IACrD,6DAA6D;IAC7D,IAAI,CAACM,OAAO;QACV,OAAO;YAAEH;YAAOH;QAAM;IACxB;IACA,OAAO;QACLG;QACAH;QACAM;IACF;AACF;AAEA,OAAO,SAASY,WAAWC,CAAa;IACtC,OAAOA,EACJX,GAAG,CAAC,CAAC,EAAEL,KAAK,EAAEH,KAAK,EAAEM,KAAK,EAAE;QAC3B,IAAIH,OAAO;YACT,IAAIiB,IAAIjB;YACR,IAAIH,OAAO;gBACToB,KAAK,CAAC,CAAC,EAAEpB,OAAO;YAClB;YACA,IAAIM,OAAO;gBACTc,KAAK,CAAC,OAAO,EAAEd,OAAO;YACxB;YACA,OAAOc;QACT;QACA,OAAO;IACT,GACCV,MAAM,CAACC;AACZ"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export function normalizePagination(page: {
|
|
2
|
-
pageSize?: number;
|
|
3
|
-
pageIndex?: number;
|
|
4
|
-
pageNumber?: number;
|
|
5
|
-
limit?: number;
|
|
6
|
-
offset?: number;
|
|
7
|
-
}) {
|
|
8
|
-
let {
|
|
9
|
-
pageSize = normalizePagination.defaultPageSize,
|
|
10
|
-
pageNumber = 1,
|
|
11
|
-
pageIndex = pageNumber - 1,
|
|
12
|
-
limit,
|
|
13
|
-
offset,
|
|
14
|
-
} = page;
|
|
15
|
-
if (normalizePagination.maxPageSize) {
|
|
16
|
-
pageSize = Math.min(pageSize, normalizePagination.maxPageSize);
|
|
17
|
-
}
|
|
18
|
-
return {
|
|
19
|
-
limit: limit || pageSize,
|
|
20
|
-
offset: Math.min(0, offset ?? pageIndex * pageSize),
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
normalizePagination.defaultPageSize = 20;
|
|
25
|
-
normalizePagination.maxPageSize = undefined as number | undefined;
|
package/src/parseSort.test.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { assert, test } from 'vitest';
|
|
2
|
-
import { parseSort } from './parseSort';
|
|
3
|
-
|
|
4
|
-
test('parseSort', () => {
|
|
5
|
-
for (const [o, e] of [
|
|
6
|
-
//
|
|
7
|
-
['', []],
|
|
8
|
-
[[], []],
|
|
9
|
-
[null, []],
|
|
10
|
-
// invalid
|
|
11
|
-
[[{ order: 'asc' }], []],
|
|
12
|
-
// partial invalid
|
|
13
|
-
[['a,,', { field: '', order: 'asc' }], [{ field: 'a', order: 'asc' }]],
|
|
14
|
-
[[',,', { field: 'a', order: 'asc' }], [{ field: 'a', order: 'asc' }]],
|
|
15
|
-
//
|
|
16
|
-
['a', [{ field: 'a', order: 'asc' }]],
|
|
17
|
-
[['a'], [{ field: 'a', order: 'asc' }]],
|
|
18
|
-
[[{ field: 'a', order: 'asc' }], [{ field: 'a', order: 'asc' }]],
|
|
19
|
-
[[{ field: 'a', order: 'asc', nulls: 'last' }], [{ field: 'a', order: 'asc', nulls: 'last' }]],
|
|
20
|
-
[
|
|
21
|
-
'-a,+b',
|
|
22
|
-
[
|
|
23
|
-
{ field: 'a', order: 'desc' },
|
|
24
|
-
{ field: 'b', order: 'asc' },
|
|
25
|
-
],
|
|
26
|
-
],
|
|
27
|
-
['a asc', [{ field: 'a', order: 'asc' }]],
|
|
28
|
-
['a desc', [{ field: 'a', order: 'desc' }]],
|
|
29
|
-
['a asc last', [{ field: 'a', order: 'asc', nulls: 'last' }]],
|
|
30
|
-
['a asc nulls last', [{ field: 'a', order: 'asc', nulls: 'last' }]],
|
|
31
|
-
['a asc nulls first', [{ field: 'a', order: 'asc', nulls: 'first' }]],
|
|
32
|
-
['a asc first', [{ field: 'a', order: 'asc', nulls: 'first' }]],
|
|
33
|
-
['a desc nulls last', [{ field: 'a', order: 'desc', nulls: 'last' }]],
|
|
34
|
-
['a desc nulls first', [{ field: 'a', order: 'desc', nulls: 'first' }]],
|
|
35
|
-
['a nulls first', [{ field: 'a', order: 'asc', nulls: 'first' }]],
|
|
36
|
-
['-a nulls first', [{ field: 'a', order: 'desc', nulls: 'first' }]],
|
|
37
|
-
['a.b', [{ field: 'a.b', order: 'asc' }]],
|
|
38
|
-
['-a asc', [{ field: 'a', order: 'asc' }]], // asc 优先级高
|
|
39
|
-
]) {
|
|
40
|
-
assert.deepEqual(parseSort(o as any), e as any, `parseOrder: ${JSON.stringify(o)}`);
|
|
41
|
-
}
|
|
42
|
-
});
|
package/src/parseSort.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { arrayOfMaybeArray, type MaybeArray } from '@wener/utils';
|
|
2
|
-
|
|
3
|
-
export type SortRule = {
|
|
4
|
-
field: string;
|
|
5
|
-
order: 'asc' | 'desc';
|
|
6
|
-
nulls?: 'last' | 'first';
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* parsing order string
|
|
11
|
-
*
|
|
12
|
-
* e.g.
|
|
13
|
-
* ```
|
|
14
|
-
* a desc
|
|
15
|
-
* +a,-b
|
|
16
|
-
* a asc nulls last
|
|
17
|
-
* a desc first
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export function parseSort(
|
|
21
|
-
order:
|
|
22
|
-
| MaybeArray<
|
|
23
|
-
| {
|
|
24
|
-
field?: string;
|
|
25
|
-
order?: string;
|
|
26
|
-
nulls?: string;
|
|
27
|
-
}
|
|
28
|
-
| string
|
|
29
|
-
>
|
|
30
|
-
| undefined
|
|
31
|
-
| null,
|
|
32
|
-
): SortRule[] {
|
|
33
|
-
if (!order) {
|
|
34
|
-
return [];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return arrayOfMaybeArray(order).flatMap((v): MaybeArray<SortRule> => {
|
|
38
|
-
if (!v) return [];
|
|
39
|
-
if (typeof v === 'object') {
|
|
40
|
-
// invalid
|
|
41
|
-
if (!v.field) {
|
|
42
|
-
return [];
|
|
43
|
-
}
|
|
44
|
-
let rule: SortRule = {
|
|
45
|
-
field: v.field,
|
|
46
|
-
order: v.order?.toLowerCase() === 'asc' ? 'asc' : 'desc',
|
|
47
|
-
};
|
|
48
|
-
if (v.nulls) {
|
|
49
|
-
rule.nulls = v.nulls.toLowerCase() === 'last' ? 'last' : 'first';
|
|
50
|
-
}
|
|
51
|
-
return rule;
|
|
52
|
-
}
|
|
53
|
-
return v
|
|
54
|
-
.split(',')
|
|
55
|
-
.map((v) => v.trim())
|
|
56
|
-
.filter(Boolean)
|
|
57
|
-
.map(_parse);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function _parse(v: string) {
|
|
62
|
-
// const sp = v.match(/^(?<field>[a-z0-9_]+)(\s+(?<order>asc|desc))?(\s+(?<nulls>nulls\s+(?<nulls_order>last|first)))?$/i);
|
|
63
|
-
const sp = v.split(/\s+/);
|
|
64
|
-
let field = '';
|
|
65
|
-
let order: SortRule['order'];
|
|
66
|
-
let nulls: SortRule['nulls'];
|
|
67
|
-
|
|
68
|
-
const f = sp.shift()!;
|
|
69
|
-
if (f.startsWith('-') || f.startsWith('+')) {
|
|
70
|
-
// (order = f.slice(1).trim()), f.startsWith('-') ? 'desc' : 'asc';
|
|
71
|
-
field = f.slice(1).trim();
|
|
72
|
-
order = f.startsWith('-') ? 'desc' : 'asc';
|
|
73
|
-
} else {
|
|
74
|
-
field = f.trim();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
while (true) {
|
|
78
|
-
const v = sp.shift()?.trim()?.toLowerCase();
|
|
79
|
-
if (!v) {
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
switch (v) {
|
|
84
|
-
case 'asc':
|
|
85
|
-
case 'desc': {
|
|
86
|
-
order = v;
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
case 'nulls': {
|
|
91
|
-
nulls = sp.shift()?.trim()?.toLowerCase() === 'last' ? 'last' : 'first';
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
case 'last':
|
|
96
|
-
case 'first': {
|
|
97
|
-
nulls = v;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
order ||= 'asc';
|
|
104
|
-
// avoid undefined
|
|
105
|
-
// NOTE pg default nulls first for desc, last for asc
|
|
106
|
-
// https://www.postgresql.org/docs/current/queries-order.html
|
|
107
|
-
if (!nulls) {
|
|
108
|
-
return { field, order };
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
field,
|
|
112
|
-
order,
|
|
113
|
-
nulls,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function formatSort(s: SortRule[]): string[] {
|
|
118
|
-
return s
|
|
119
|
-
.map(({ field, order, nulls }) => {
|
|
120
|
-
if (field) {
|
|
121
|
-
let r = field;
|
|
122
|
-
if (order) {
|
|
123
|
-
r += ` ${order}`;
|
|
124
|
-
}
|
|
125
|
-
if (nulls) {
|
|
126
|
-
r += ` nulls ${nulls}`;
|
|
127
|
-
}
|
|
128
|
-
return r;
|
|
129
|
-
}
|
|
130
|
-
return '';
|
|
131
|
-
})
|
|
132
|
-
.filter(Boolean);
|
|
133
|
-
}
|