@wener/common 1.0.3 → 1.0.4

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 (97) 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/data/formatSort.js +15 -0
  10. package/lib/data/formatSort.js.map +1 -0
  11. package/lib/data/index.js +4 -0
  12. package/lib/data/index.js.map +1 -0
  13. package/lib/data/maybeNumber.js +22 -0
  14. package/lib/data/maybeNumber.js.map +1 -0
  15. package/lib/data/parseSort.js +95 -0
  16. package/lib/data/parseSort.js.map +1 -0
  17. package/lib/data/resolvePagination.js +36 -0
  18. package/lib/data/resolvePagination.js.map +1 -0
  19. package/lib/data/types.d.js +3 -0
  20. package/lib/data/types.d.js.map +1 -0
  21. package/lib/index.js +6 -2
  22. package/lib/index.js.map +1 -1
  23. package/lib/jsonschema/JsonSchema.js +4 -4
  24. package/lib/jsonschema/JsonSchema.js.map +1 -1
  25. package/lib/jsonschema/types.d.js.map +1 -1
  26. package/lib/meta/defineFileType.js.map +1 -1
  27. package/lib/meta/defineInit.js.map +1 -1
  28. package/lib/meta/defineMetadata.js.map +1 -1
  29. package/lib/password/PHC.js +8 -8
  30. package/lib/password/PHC.js.map +1 -1
  31. package/lib/password/Password.js.map +1 -1
  32. package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
  33. package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
  34. package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
  35. package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
  36. package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
  37. package/lib/search/AdvanceSearch.js.map +1 -1
  38. package/lib/search/formatAdvanceSearch.js.map +1 -1
  39. package/lib/search/optimizeAdvanceSearch.js.map +1 -1
  40. package/lib/search/parseAdvanceSearch.js.map +1 -1
  41. package/lib/search/parser.d.js.map +1 -1
  42. package/lib/search/types.d.js.map +1 -1
  43. package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -1
  44. package/package.json +10 -5
  45. package/src/cn/DivisionCode.test.ts +38 -45
  46. package/src/cn/DivisionCode.ts +140 -184
  47. package/src/cn/Mod11Checksum.ts +17 -17
  48. package/src/cn/Mod31Checksum.ts +25 -25
  49. package/src/cn/ResidentIdentityCardNumber.test.ts +12 -16
  50. package/src/cn/ResidentIdentityCardNumber.ts +82 -82
  51. package/src/cn/UnifiedSocialCreditCode.test.ts +11 -11
  52. package/src/cn/UnifiedSocialCreditCode.ts +115 -120
  53. package/src/cn/__snapshots__/ResidentIdentityCardNumber.test.ts.snap +1 -1
  54. package/src/cn/formatDate.ts +10 -10
  55. package/src/cn/parseSex.ts +11 -25
  56. package/src/cn/types.d.ts +43 -43
  57. package/src/data/formatSort.test.ts +13 -0
  58. package/src/data/formatSort.ts +18 -0
  59. package/src/data/index.ts +5 -0
  60. package/src/data/maybeNumber.ts +23 -0
  61. package/src/data/parseSort.test.ts +67 -0
  62. package/src/data/parseSort.ts +108 -0
  63. package/src/data/resolvePagination.test.ts +58 -0
  64. package/src/data/resolvePagination.ts +60 -0
  65. package/src/data/types.d.ts +33 -0
  66. package/src/index.ts +8 -2
  67. package/src/jsonschema/JsonSchema.test.ts +13 -22
  68. package/src/jsonschema/JsonSchema.ts +145 -177
  69. package/src/jsonschema/types.d.ts +151 -161
  70. package/src/meta/defineFileType.tsx +54 -54
  71. package/src/meta/defineInit.ts +32 -53
  72. package/src/meta/defineMetadata.test.ts +5 -7
  73. package/src/meta/defineMetadata.ts +28 -46
  74. package/src/password/PHC.test.ts +186 -277
  75. package/src/password/PHC.ts +243 -243
  76. package/src/password/Password.test.ts +38 -50
  77. package/src/password/Password.ts +73 -95
  78. package/src/password/createArgon2PasswordAlgorithm.ts +65 -69
  79. package/src/password/createBase64PasswordAlgorithm.ts +9 -9
  80. package/src/password/createBcryptPasswordAlgorithm.ts +20 -22
  81. package/src/password/createPBKDF2PasswordAlgorithm.ts +49 -61
  82. package/src/password/createScryptPasswordAlgorithm.ts +48 -59
  83. package/src/search/AdvanceSearch.test.ts +136 -143
  84. package/src/search/AdvanceSearch.ts +6 -6
  85. package/src/search/formatAdvanceSearch.ts +44 -53
  86. package/src/search/optimizeAdvanceSearch.ts +70 -83
  87. package/src/search/parseAdvanceSearch.ts +16 -19
  88. package/src/search/parser.d.ts +3 -3
  89. package/src/search/types.d.ts +28 -54
  90. package/src/tools/renderJsonSchemaToMarkdownDoc.ts +69 -69
  91. package/lib/normalizePagination.js +0 -14
  92. package/lib/normalizePagination.js.map +0 -1
  93. package/lib/parseSort.js +0 -106
  94. package/lib/parseSort.js.map +0 -1
  95. package/src/normalizePagination.ts +0 -25
  96. package/src/parseSort.test.ts +0 -42
  97. 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
  };
@@ -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
- }