@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.
Files changed (109) hide show
  1. package/lib/cn/DivisionCode.js.map +1 -1
  2. package/lib/cn/Mod11Checksum.js.map +1 -1
  3. package/lib/cn/Mod31Checksum.js.map +1 -1
  4. package/lib/cn/ResidentIdentityCardNumber.js.map +1 -1
  5. package/lib/cn/UnifiedSocialCreditCode.js.map +1 -1
  6. package/lib/cn/formatDate.js.map +1 -1
  7. package/lib/cn/parseSex.js.map +1 -1
  8. package/lib/cn/types.d.js.map +1 -1
  9. package/lib/consola/createStandardConsolaReporter.js +18 -0
  10. package/lib/consola/createStandardConsolaReporter.js.map +1 -0
  11. package/lib/consola/formatLogObject.js +125 -0
  12. package/lib/consola/formatLogObject.js.map +1 -0
  13. package/lib/consola/index.js +3 -0
  14. package/lib/consola/index.js.map +1 -0
  15. package/lib/data/formatSort.js +15 -0
  16. package/lib/data/formatSort.js.map +1 -0
  17. package/lib/data/index.js +4 -0
  18. package/lib/data/index.js.map +1 -0
  19. package/lib/data/maybeNumber.js +22 -0
  20. package/lib/data/maybeNumber.js.map +1 -0
  21. package/lib/data/parseSort.js +95 -0
  22. package/lib/data/parseSort.js.map +1 -0
  23. package/lib/data/resolvePagination.js +36 -0
  24. package/lib/data/resolvePagination.js.map +1 -0
  25. package/lib/data/types.d.js +3 -0
  26. package/lib/data/types.d.js.map +1 -0
  27. package/lib/index.js +6 -2
  28. package/lib/index.js.map +1 -1
  29. package/lib/jsonschema/JsonSchema.js +6 -6
  30. package/lib/jsonschema/JsonSchema.js.map +1 -1
  31. package/lib/jsonschema/types.d.js.map +1 -1
  32. package/lib/meta/defineFileType.js.map +1 -1
  33. package/lib/meta/defineInit.js.map +1 -1
  34. package/lib/meta/defineMetadata.js.map +1 -1
  35. package/lib/password/PHC.js +8 -8
  36. package/lib/password/PHC.js.map +1 -1
  37. package/lib/password/Password.js.map +1 -1
  38. package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
  39. package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
  40. package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
  41. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
  42. package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
  43. package/lib/search/AdvanceSearch.js.map +1 -1
  44. package/lib/search/formatAdvanceSearch.js.map +1 -1
  45. package/lib/search/optimizeAdvanceSearch.js.map +1 -1
  46. package/lib/search/parseAdvanceSearch.js.map +1 -1
  47. package/lib/search/parser.d.js.map +1 -1
  48. package/lib/search/types.d.js.map +1 -1
  49. package/lib/tools/generateSchema.js +43 -0
  50. package/lib/tools/generateSchema.js.map +1 -0
  51. package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -1
  52. package/package.json +19 -5
  53. package/src/cn/DivisionCode.test.ts +38 -45
  54. package/src/cn/DivisionCode.ts +140 -184
  55. package/src/cn/Mod11Checksum.ts +17 -17
  56. package/src/cn/Mod31Checksum.ts +25 -25
  57. package/src/cn/ResidentIdentityCardNumber.test.ts +12 -16
  58. package/src/cn/ResidentIdentityCardNumber.ts +82 -82
  59. package/src/cn/UnifiedSocialCreditCode.test.ts +11 -11
  60. package/src/cn/UnifiedSocialCreditCode.ts +115 -120
  61. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +1 -1
  62. package/src/cn/formatDate.ts +10 -10
  63. package/src/cn/parseSex.ts +11 -25
  64. package/src/cn/types.d.ts +43 -43
  65. package/src/consola/createStandardConsolaReporter.ts +31 -0
  66. package/src/consola/formatLogObject.ts +171 -0
  67. package/src/consola/index.ts +2 -0
  68. package/src/data/formatSort.test.ts +13 -0
  69. package/src/data/formatSort.ts +18 -0
  70. package/src/data/index.ts +5 -0
  71. package/src/data/maybeNumber.ts +23 -0
  72. package/src/data/parseSort.test.ts +67 -0
  73. package/src/data/parseSort.ts +108 -0
  74. package/src/data/resolvePagination.test.ts +58 -0
  75. package/src/data/resolvePagination.ts +60 -0
  76. package/src/data/types.d.ts +33 -0
  77. package/src/index.ts +8 -2
  78. package/src/jsonschema/JsonSchema.test.ts +13 -22
  79. package/src/jsonschema/JsonSchema.ts +146 -178
  80. package/src/jsonschema/types.d.ts +151 -161
  81. package/src/meta/defineFileType.tsx +54 -54
  82. package/src/meta/defineInit.ts +32 -53
  83. package/src/meta/defineMetadata.test.ts +5 -7
  84. package/src/meta/defineMetadata.ts +28 -46
  85. package/src/password/PHC.test.ts +186 -277
  86. package/src/password/PHC.ts +243 -243
  87. package/src/password/Password.test.ts +38 -50
  88. package/src/password/Password.ts +73 -95
  89. package/src/password/createArgon2PasswordAlgorithm.ts +65 -69
  90. package/src/password/createBase64PasswordAlgorithm.ts +9 -9
  91. package/src/password/createBcryptPasswordAlgorithm.ts +20 -22
  92. package/src/password/createPBKDF2PasswordAlgorithm.ts +49 -61
  93. package/src/password/createScryptPasswordAlgorithm.ts +48 -59
  94. package/src/search/AdvanceSearch.test.ts +136 -143
  95. package/src/search/AdvanceSearch.ts +6 -6
  96. package/src/search/formatAdvanceSearch.ts +44 -53
  97. package/src/search/optimizeAdvanceSearch.ts +70 -83
  98. package/src/search/parseAdvanceSearch.ts +16 -19
  99. package/src/search/parser.d.ts +3 -3
  100. package/src/search/types.d.ts +28 -54
  101. package/src/tools/generateSchema.ts +39 -0
  102. package/src/tools/renderJsonSchemaToMarkdownDoc.ts +69 -69
  103. package/lib/normalizePagination.js +0 -14
  104. package/lib/normalizePagination.js.map +0 -1
  105. package/lib/parseSort.js +0 -106
  106. package/lib/parseSort.js.map +0 -1
  107. package/src/normalizePagination.ts +0 -25
  108. package/src/parseSort.test.ts +0 -42
  109. package/src/parseSort.ts +0 -133
@@ -1,71 +1,45 @@
1
1
  export type Exprs = Expr[];
2
2
  export type Expr =
3
- | CommentExpr
4
- | ParenthesesExpr
5
- | KeywordCondition
6
- | LogicalCondition
7
- | NotCondition
8
- | CompareCondition;
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
- type: 'compare';
40
- field: string;
41
- /**
42
- * mention value for eq, ne only
43
- * range require range value
44
- */
45
- operator: 'eq' | 'ne' | 'gt' | 'lt' | 'gte' | 'lte' | 'range' | 'match';
46
- negative?: boolean;
47
- mention?: boolean;
48
- value: Value;
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
- type: 'range';
67
- minimum: LiteralValue | undefined;
68
- maximum: LiteralValue | undefined;
69
- minimumExclusive: boolean;
70
- maximumExclusive: boolean;
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
- // markdown
5
- const out: string[] = [];
6
- const all = new Set();
7
- const pending: TSchema[] = [];
4
+ // markdown
5
+ const out: string[] = [];
6
+ const all = new Set();
7
+ const pending: TSchema[] = [];
8
8
 
9
- const addObject = (o: TSchema) => {
10
- if (all.has(o.$id)) {
11
- return;
12
- }
13
- all.add(o.$id);
14
- pending.push(o);
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
- 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;
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
- 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
- }
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
- out.push(`| ${prefix}${name} | ${typ} | ${schema.title || schema.description || ''} |`);
38
+ out.push(`| ${prefix}${name} | ${typ} | ${schema.title || schema.description || ''} |`);
39
39
 
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(`
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
- if (T.description) {
57
- out.push('');
58
- out.push(`> ${T.description}`);
59
- out.push('');
60
- }
56
+ if (T.description) {
57
+ out.push('');
58
+ out.push(`> ${T.description}`);
59
+ out.push('');
60
+ }
61
61
 
62
- out.push(`| 名字 | 类型 | 说明 |`);
63
- out.push(`| --- | --- | --- |`);
62
+ out.push(`| 名字 | 类型 | 说明 |`);
63
+ out.push(`| --- | --- | --- |`);
64
64
 
65
- writeObjectProps(T);
65
+ writeObjectProps(T);
66
66
 
67
- out.push('');
68
- };
67
+ out.push('');
68
+ };
69
69
 
70
- writeObject(rootSchema);
70
+ writeObject(rootSchema);
71
71
 
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(`
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
- 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
- }
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
- return out.join('\n');
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
@@ -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;
@@ -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
- }