@wener/common 2.0.5 → 2.0.6

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 (206) hide show
  1. package/lib/ai/qwen3vl/index.js +1 -1
  2. package/lib/ai/qwen3vl/utils.js +15 -15
  3. package/lib/ai/vision/DocLayoutElementTypeSchema.js +22 -22
  4. package/lib/ai/vision/ImageAnnotationSchema.js +63 -47
  5. package/lib/ai/vision/index.js +2 -2
  6. package/lib/ai/vision/resolveImageAnnotation.js +81 -95
  7. package/lib/cn/ChineseResidentIdNo.js +55 -41
  8. package/lib/cn/ChineseResidentIdNo.mod.js +6 -1
  9. package/lib/cn/ChineseResidentIdNo.test.js +22 -21
  10. package/lib/cn/DivisionCode.js +220 -235
  11. package/lib/cn/DivisionCode.mod.js +6 -1
  12. package/lib/cn/DivisionCode.test.js +92 -121
  13. package/lib/cn/Mod11.js +18 -37
  14. package/lib/cn/Mod31.js +23 -41
  15. package/lib/cn/UnifiedSocialCreditCode.js +143 -137
  16. package/lib/cn/UnifiedSocialCreditCode.mod.js +6 -1
  17. package/lib/cn/UnifiedSocialCreditCode.test.js +21 -15
  18. package/lib/cn/formatChineseAmount.js +46 -71
  19. package/lib/cn/index.js +6 -6
  20. package/lib/cn/mod.js +5 -3
  21. package/lib/cn/parseChineseNumber.js +81 -85
  22. package/lib/cn/parseChineseNumber.test.js +183 -261
  23. package/lib/cn/pinyin/cartesianProduct.js +19 -19
  24. package/lib/cn/pinyin/cartesianProduct.test.js +78 -178
  25. package/lib/cn/pinyin/loader.js +13 -11
  26. package/lib/cn/pinyin/preload.js +2 -1
  27. package/lib/cn/pinyin/toPinyin.test.js +149 -161
  28. package/lib/cn/pinyin/toPinyinPure.js +28 -23
  29. package/lib/cn/pinyin/transform.js +11 -11
  30. package/lib/cn/types.d.js +2 -2
  31. package/lib/consola/createStandardConsolaReporter.js +14 -15
  32. package/lib/consola/formatLogObject.js +149 -133
  33. package/lib/consola/formatLogObject.test.js +167 -178
  34. package/lib/consola/index.js +2 -2
  35. package/lib/data/formatSort.js +14 -12
  36. package/lib/data/formatSort.test.js +33 -33
  37. package/lib/data/index.js +3 -3
  38. package/lib/data/maybeNumber.js +23 -23
  39. package/lib/data/parseSort.js +75 -68
  40. package/lib/data/parseSort.test.js +196 -187
  41. package/lib/data/resolvePagination.js +38 -39
  42. package/lib/data/resolvePagination.test.js +228 -218
  43. package/lib/data/types.d.js +2 -2
  44. package/lib/dayjs/dayjs.js +20 -20
  45. package/lib/dayjs/formatDuration.js +56 -56
  46. package/lib/dayjs/formatDuration.test.js +63 -77
  47. package/lib/dayjs/index.js +4 -4
  48. package/lib/dayjs/parseDuration.js +21 -26
  49. package/lib/dayjs/parseRelativeTime.js +65 -66
  50. package/lib/dayjs/parseRelativeTime.test.js +227 -243
  51. package/lib/dayjs/resolveRelativeTime.js +73 -72
  52. package/lib/dayjs/resolveRelativeTime.test.js +296 -307
  53. package/lib/decimal/index.js +1 -1
  54. package/lib/decimal/parseDecimal.js +12 -12
  55. package/lib/drain3/Drain.js +303 -338
  56. package/lib/drain3/LogCluster.js +25 -25
  57. package/lib/drain3/Node.js +24 -24
  58. package/lib/drain3/TemplateMiner.js +197 -196
  59. package/lib/drain3/index.js +5 -5
  60. package/lib/drain3/persistence/FilePersistence.js +19 -19
  61. package/lib/drain3/persistence/MemoryPersistence.js +8 -8
  62. package/lib/drain3/persistence/PersistenceHandler.js +2 -2
  63. package/lib/drain3/types.js +2 -2
  64. package/lib/emittery/emitter.js +7 -7
  65. package/lib/emittery/index.js +1 -1
  66. package/lib/foundation/schema/SexType.js +15 -12
  67. package/lib/foundation/schema/index.js +1 -1
  68. package/lib/foundation/schema/parseSexType.js +15 -16
  69. package/lib/foundation/schema/types.js +8 -6
  70. package/lib/fs/FileSystemError.js +18 -18
  71. package/lib/fs/IFileSystem.d.js +2 -2
  72. package/lib/fs/MemoryFileSystem.test.js +172 -181
  73. package/lib/fs/createBrowserFileSystem.js +222 -235
  74. package/lib/fs/createMemoryFileSystem.js +472 -510
  75. package/lib/fs/createSandboxFileSystem.js +102 -101
  76. package/lib/fs/createWebDavFileSystem.js +162 -149
  77. package/lib/fs/createWebFileSystem.js +197 -220
  78. package/lib/fs/findMimeType.js +14 -14
  79. package/lib/fs/index.js +7 -7
  80. package/lib/fs/minio/createMinioFileSystem.js +959 -956
  81. package/lib/fs/minio/index.js +1 -1
  82. package/lib/fs/orpc/FileSystemContract.js +57 -57
  83. package/lib/fs/orpc/createContractClientFileSystem.js +88 -88
  84. package/lib/fs/orpc/index.js +2 -2
  85. package/lib/fs/orpc/server/createFileSystemContractImpl.js +62 -60
  86. package/lib/fs/orpc/server/index.js +1 -1
  87. package/lib/fs/s3/createS3MiniFileSystem.js +756 -737
  88. package/lib/fs/s3/index.js +1 -1
  89. package/lib/fs/s3/s3mini.test.js +524 -553
  90. package/lib/fs/scandir.js +56 -56
  91. package/lib/fs/server/createDatabaseFileSystem.js +834 -741
  92. package/lib/fs/server/createNodeFileSystem.js +407 -405
  93. package/lib/fs/server/dbfs.test.js +201 -214
  94. package/lib/fs/server/index.js +1 -1
  95. package/lib/fs/server/loadTestDatabase.js +40 -43
  96. package/lib/fs/tests/runFileSystemTest.js +352 -316
  97. package/lib/fs/types.js +17 -20
  98. package/lib/fs/utils/getFileUrl.js +24 -30
  99. package/lib/fs/utils.js +17 -17
  100. package/lib/fs/webdav/index.js +1 -1
  101. package/lib/index.js +2 -2
  102. package/lib/jsonschema/JsonSchema.js +216 -155
  103. package/lib/jsonschema/JsonSchema.test.js +123 -124
  104. package/lib/jsonschema/forEachJsonSchema.js +41 -41
  105. package/lib/jsonschema/index.js +2 -2
  106. package/lib/jsonschema/types.d.js +2 -2
  107. package/lib/meta/defineFileType.js +32 -38
  108. package/lib/meta/defineInit.js +39 -35
  109. package/lib/meta/defineMetadata.js +37 -34
  110. package/lib/meta/defineMetadata.test.js +13 -12
  111. package/lib/meta/index.js +3 -3
  112. package/lib/orpc/createOpenApiContractClient.js +26 -24
  113. package/lib/orpc/createRpcContractClient.js +37 -31
  114. package/lib/orpc/index.js +2 -2
  115. package/lib/orpc/resolveLinkPlugins.js +25 -25
  116. package/lib/password/PHC.js +187 -189
  117. package/lib/password/PHC.test.js +517 -535
  118. package/lib/password/Password.js +85 -80
  119. package/lib/password/Password.test.js +330 -364
  120. package/lib/password/createArgon2PasswordAlgorithm.js +50 -51
  121. package/lib/password/createBase64PasswordAlgorithm.js +11 -11
  122. package/lib/password/createBcryptPasswordAlgorithm.js +20 -18
  123. package/lib/password/createPBKDF2PasswordAlgorithm.js +65 -52
  124. package/lib/password/createScryptPasswordAlgorithm.js +74 -63
  125. package/lib/password/index.js +5 -5
  126. package/lib/password/server/index.js +1 -1
  127. package/lib/resource/Identifiable.js +2 -2
  128. package/lib/resource/ListQuery.js +42 -42
  129. package/lib/resource/getTitleOfResource.js +5 -5
  130. package/lib/resource/index.js +2 -2
  131. package/lib/resource/schema/AnyResourceSchema.js +91 -89
  132. package/lib/resource/schema/BaseResourceSchema.js +26 -26
  133. package/lib/resource/schema/ResourceActionType.js +117 -115
  134. package/lib/resource/schema/ResourceStatus.js +94 -92
  135. package/lib/resource/schema/ResourceType.js +25 -23
  136. package/lib/resource/schema/index.js +5 -5
  137. package/lib/resource/schema/types.js +86 -55
  138. package/lib/resource/schema/types.test.js +16 -13
  139. package/lib/s3/formatS3Url.js +60 -60
  140. package/lib/s3/formatS3Url.test.js +238 -261
  141. package/lib/s3/index.js +2 -2
  142. package/lib/s3/parseS3Url.js +61 -60
  143. package/lib/s3/parseS3Url.test.js +270 -269
  144. package/lib/schema/SchemaRegistry.js +41 -42
  145. package/lib/schema/SchemaRegistry.mod.js +1 -1
  146. package/lib/schema/TypeSchema.d.js +2 -2
  147. package/lib/schema/createSchemaData.js +113 -67
  148. package/lib/schema/findJsonSchemaByPath.js +28 -23
  149. package/lib/schema/formatZodError.js +112 -131
  150. package/lib/schema/formatZodError.test.js +192 -195
  151. package/lib/schema/getSchemaCache.js +7 -7
  152. package/lib/schema/getSchemaOptions.js +17 -16
  153. package/lib/schema/index.js +6 -6
  154. package/lib/schema/toJsonSchema.js +195 -189
  155. package/lib/schema/toJsonSchema.test.js +34 -26
  156. package/lib/schema/validate.js +105 -96
  157. package/lib/tools/generateSchema.js +40 -40
  158. package/lib/tools/renderJsonSchemaToMarkdownDoc.js +74 -74
  159. package/lib/utils/buildBaseUrl.js +8 -8
  160. package/lib/utils/buildRedactorFormSchema.js +54 -53
  161. package/lib/utils/getEstimateProcessTime.js +24 -19
  162. package/lib/utils/index.js +3 -3
  163. package/lib/utils/resolveFeatureOptions.js +9 -9
  164. package/package.json +14 -14
  165. package/src/ai/vision/index.ts +2 -2
  166. package/src/cn/index.ts +1 -2
  167. package/src/consola/index.ts +1 -1
  168. package/src/data/index.ts +3 -4
  169. package/src/data/resolvePagination.ts +2 -2
  170. package/src/dayjs/formatDuration.ts +8 -9
  171. package/src/dayjs/index.ts +1 -1
  172. package/src/dayjs/parseRelativeTime.ts +1 -1
  173. package/src/dayjs/resolveRelativeTime.ts +1 -1
  174. package/src/drain3/Drain.test.ts +2 -2
  175. package/src/drain3/index.ts +2 -4
  176. package/src/fs/createWebDavFileSystem.ts +2 -7
  177. package/src/fs/createWebFileSystem.ts +1 -1
  178. package/src/fs/index.ts +4 -4
  179. package/src/fs/minio/createMinioFileSystem.ts +2 -2
  180. package/src/fs/minio/index.ts +1 -1
  181. package/src/fs/s3/createS3MiniFileSystem.ts +1 -1
  182. package/src/fs/server/createDatabaseFileSystem.ts +84 -120
  183. package/src/fs/server/dbfs.test.ts +14 -10
  184. package/src/fs/server/index.ts +1 -0
  185. package/src/fs/server/loadTestDatabase.ts +8 -119
  186. package/src/jsonschema/index.ts +1 -1
  187. package/src/meta/index.ts +2 -3
  188. package/src/orm/createSqliteDialect.ts +17 -0
  189. package/src/orm/index.ts +1 -0
  190. package/src/orpc/createOpenApiContractClient.ts +1 -1
  191. package/src/orpc/index.ts +1 -1
  192. package/src/password/createArgon2PasswordAlgorithm.ts +1 -1
  193. package/src/password/index.ts +2 -2
  194. package/src/resource/index.ts +3 -3
  195. package/src/resource/schema/index.ts +4 -4
  196. package/src/s3/index.ts +1 -1
  197. package/src/schema/SchemaRegistry.ts +1 -1
  198. package/src/schema/createSchemaData.ts +1 -1
  199. package/src/schema/findJsonSchemaByPath.ts +1 -1
  200. package/src/schema/index.ts +5 -5
  201. package/src/schema/validate.ts +1 -1
  202. package/src/utils/buildRedactorFormSchema.ts +1 -1
  203. package/src/utils/formatNumber.ts +18 -0
  204. package/src/utils/formatPercent.ts +17 -0
  205. package/src/utils/index.ts +3 -3
  206. package/src/utils/resolveFeatureOptions.ts +1 -1
@@ -1,4 +1,4 @@
1
- import { arrayOfMaybeArray } from "@wener/utils";
1
+ import { arrayOfMaybeArray } from '@wener/utils';
2
2
  /**
3
3
  * Parses various format of sort specifications into standardized SortRule objects
4
4
  *
@@ -14,82 +14,89 @@ import { arrayOfMaybeArray } from "@wener/utils";
14
14
  * parseSort('name asc nulls last') // [{ field: 'name', order: 'asc', nulls: 'last' }]
15
15
  * parseSort([{ field: 'name' }]) // [{ field: 'name', order: 'asc' }]
16
16
  */ export function parseSort(order) {
17
- if (!order) {
18
- return [];
19
- }
20
- return arrayOfMaybeArray(order).flatMap((v)=>{
21
- if (!v) return [];
22
- if (typeof v === 'object') {
23
- if (!v.field) {
24
- return [];
25
- }
26
- const rule = {
27
- field: v.field,
28
- order: normalizeOrder(v.order)
29
- };
30
- if (v.nulls) {
31
- rule.nulls = normalizeNulls(v.nulls);
32
- }
33
- return rule;
34
- }
35
- return v.split(',').map((v)=>v.trim()).filter(Boolean).map(_parse);
36
- });
17
+ if (!order) {
18
+ return [];
19
+ }
20
+ return arrayOfMaybeArray(order).flatMap((v) => {
21
+ if (!v) return [];
22
+ if (typeof v === 'object') {
23
+ if (!v.field) {
24
+ return [];
25
+ }
26
+ const rule = {
27
+ field: v.field,
28
+ order: normalizeOrder(v.order),
29
+ };
30
+ if (v.nulls) {
31
+ rule.nulls = normalizeNulls(v.nulls);
32
+ }
33
+ return rule;
34
+ }
35
+ return v
36
+ .split(',')
37
+ .map((v) => v.trim())
38
+ .filter(Boolean)
39
+ .map(_parse);
40
+ });
37
41
  }
38
42
  /**
39
43
  * Normalizes order values to 'asc' or 'desc'
40
44
  */ function normalizeOrder(order) {
41
- return order?.toLowerCase() === 'asc' ? 'asc' : 'desc';
45
+ return order?.toLowerCase() === 'asc' ? 'asc' : 'desc';
42
46
  }
43
47
  /**
44
48
  * Normalizes nulls values to 'last' or 'first'
45
49
  */ function normalizeNulls(nulls) {
46
- return nulls?.toLowerCase() === 'last' ? 'last' : 'first';
50
+ return nulls?.toLowerCase() === 'last' ? 'last' : 'first';
47
51
  }
48
52
  function _parse(v) {
49
- const sp = v.split(/\s+/);
50
- let field = '';
51
- let order;
52
- let nulls;
53
- // Handle first token which should be the field name (possibly with +/- prefix)
54
- const f = sp.shift();
55
- if (!f) return {
56
- field: '',
57
- order: 'asc'
58
- }; // Defensive programming
59
- if (f.startsWith('-') || f.startsWith('+')) {
60
- field = f.slice(1).trim();
61
- order = f.startsWith('-') ? 'desc' : 'asc';
62
- } else {
63
- field = f.trim();
64
- }
65
- // Process remaining tokens
66
- while(sp.length > 0){
67
- const token = sp.shift()?.trim()?.toLowerCase();
68
- if (!token) continue;
69
- switch(token){
70
- case 'asc':
71
- case 'desc':
72
- order = token;
73
- break;
74
- case 'nulls':
75
- nulls = sp.shift()?.trim()?.toLowerCase() === 'last' ? 'last' : 'first';
76
- break;
77
- case 'last':
78
- case 'first':
79
- nulls = token;
80
- break;
81
- }
82
- }
83
- order ||= 'asc';
84
- // Only include nulls if specified
85
- return nulls ? {
86
- field,
87
- order,
88
- nulls
89
- } : {
90
- field,
91
- order
92
- };
53
+ const sp = v.split(/\s+/);
54
+ let field = '';
55
+ let order;
56
+ let nulls;
57
+ // Handle first token which should be the field name (possibly with +/- prefix)
58
+ const f = sp.shift();
59
+ if (!f)
60
+ return {
61
+ field: '',
62
+ order: 'asc',
63
+ }; // Defensive programming
64
+ if (f.startsWith('-') || f.startsWith('+')) {
65
+ field = f.slice(1).trim();
66
+ order = f.startsWith('-') ? 'desc' : 'asc';
67
+ } else {
68
+ field = f.trim();
69
+ }
70
+ // Process remaining tokens
71
+ while (sp.length > 0) {
72
+ const token = sp.shift()?.trim()?.toLowerCase();
73
+ if (!token) continue;
74
+ switch (token) {
75
+ case 'asc':
76
+ case 'desc':
77
+ order = token;
78
+ break;
79
+ case 'nulls':
80
+ nulls = sp.shift()?.trim()?.toLowerCase() === 'last' ? 'last' : 'first';
81
+ break;
82
+ case 'last':
83
+ case 'first':
84
+ nulls = token;
85
+ break;
86
+ }
87
+ }
88
+ order ||= 'asc';
89
+ // Only include nulls if specified
90
+ return nulls
91
+ ? {
92
+ field,
93
+ order,
94
+ nulls,
95
+ }
96
+ : {
97
+ field,
98
+ order,
99
+ };
93
100
  }
94
101
 
95
- //# sourceMappingURL=parseSort.js.map
102
+ //# sourceMappingURL=parseSort.js.map
@@ -1,188 +1,197 @@
1
- import { describe, expect, test } from "vitest";
2
- import { parseSort } from "./parseSort.js";
3
- describe("parseSort", function () {
4
- describe("basic parsing", function () {
5
- test("handles empty inputs", function () {
6
- expect(parseSort("")).toEqual([]);
7
- expect(parseSort([])).toEqual([]);
8
- expect(parseSort(null)).toEqual([]);
9
- expect(parseSort(undefined)).toEqual([]);
10
- });
11
- test("handles simple field names", function () {
12
- expect(parseSort("a")).toEqual([
13
- {
14
- field: "a",
15
- order: "asc"
16
- }
17
- ]);
18
- expect(parseSort([
19
- "a"
20
- ])).toEqual([
21
- {
22
- field: "a",
23
- order: "asc"
24
- }
25
- ]);
26
- expect(parseSort("a.b")).toEqual([
27
- {
28
- field: "a.b",
29
- order: "asc"
30
- }
31
- ]);
32
- });
33
- test("handles prefix notation", function () {
34
- expect(parseSort("-a")).toEqual([
35
- {
36
- field: "a",
37
- order: "desc"
38
- }
39
- ]);
40
- expect(parseSort("+b")).toEqual([
41
- {
42
- field: "b",
43
- order: "asc"
44
- }
45
- ]);
46
- expect(parseSort("-a,+b")).toEqual([
47
- {
48
- field: "a",
49
- order: "desc"
50
- },
51
- {
52
- field: "b",
53
- order: "asc"
54
- }
55
- ]);
56
- });
57
- });
58
- describe("explicit ordering", function () {
59
- test("handles explicit order keywords", function () {
60
- expect(parseSort("a asc")).toEqual([
61
- {
62
- field: "a",
63
- order: "asc"
64
- }
65
- ]);
66
- expect(parseSort("a desc")).toEqual([
67
- {
68
- field: "a",
69
- order: "desc"
70
- }
71
- ]);
72
- expect(parseSort("-a asc")).toEqual([
73
- {
74
- field: "a",
75
- order: "asc"
76
- }
77
- ]); // explicit order overrides prefix
78
- });
79
- });
80
- describe("nulls handling", function () {
81
- test("handles nulls specification", function () {
82
- expect(parseSort("a asc nulls last")).toEqual([
83
- {
84
- field: "a",
85
- order: "asc",
86
- nulls: "last"
87
- }
88
- ]);
89
- expect(parseSort("a asc nulls first")).toEqual([
90
- {
91
- field: "a",
92
- order: "asc",
93
- nulls: "first"
94
- }
95
- ]);
96
- expect(parseSort("a desc nulls last")).toEqual([
97
- {
98
- field: "a",
99
- order: "desc",
100
- nulls: "last"
101
- }
102
- ]);
103
- expect(parseSort("a nulls first")).toEqual([
104
- {
105
- field: "a",
106
- order: "asc",
107
- nulls: "first"
108
- }
109
- ]);
110
- expect(parseSort("-a nulls first")).toEqual([
111
- {
112
- field: "a",
113
- order: "desc",
114
- nulls: "first"
115
- }
116
- ]);
117
- // Alternative syntax
118
- expect(parseSort("a asc last")).toEqual([
119
- {
120
- field: "a",
121
- order: "asc",
122
- nulls: "last"
123
- }
124
- ]);
125
- });
126
- });
127
- describe("object notation", function () {
128
- test("handles object input", function () {
129
- expect(parseSort([
130
- {
131
- field: "a",
132
- order: "asc"
133
- }
134
- ])).toEqual([
135
- {
136
- field: "a",
137
- order: "asc"
138
- }
139
- ]);
140
- expect(parseSort([
141
- {
142
- field: "a",
143
- order: "asc",
144
- nulls: "last"
145
- }
146
- ])).toEqual([
147
- {
148
- field: "a",
149
- order: "asc",
150
- nulls: "last"
151
- }
152
- ]);
153
- });
154
- });
155
- describe("invalid inputs", function () {
156
- test("handles invalid inputs gracefully", function () {
157
- expect(parseSort([
158
- {
159
- order: "asc"
160
- }
161
- ])).toEqual([]);
162
- expect(parseSort([
163
- "a,,",
164
- {
165
- field: "",
166
- order: "asc"
167
- }
168
- ])).toEqual([
169
- {
170
- field: "a",
171
- order: "asc"
172
- }
173
- ]);
174
- expect(parseSort([
175
- ",,",
176
- {
177
- field: "a",
178
- order: "asc"
179
- }
180
- ])).toEqual([
181
- {
182
- field: "a",
183
- order: "asc"
184
- }
185
- ]);
186
- });
187
- });
1
+ import { describe, expect, test } from 'vitest';
2
+ import { parseSort } from './parseSort.js';
3
+
4
+ describe('parseSort', () => {
5
+ describe('basic parsing', () => {
6
+ test('handles empty inputs', () => {
7
+ expect(parseSort('')).toEqual([]);
8
+ expect(parseSort([])).toEqual([]);
9
+ expect(parseSort(null)).toEqual([]);
10
+ expect(parseSort(undefined)).toEqual([]);
11
+ });
12
+ test('handles simple field names', () => {
13
+ expect(parseSort('a')).toEqual([
14
+ {
15
+ field: 'a',
16
+ order: 'asc',
17
+ },
18
+ ]);
19
+ expect(parseSort(['a'])).toEqual([
20
+ {
21
+ field: 'a',
22
+ order: 'asc',
23
+ },
24
+ ]);
25
+ expect(parseSort('a.b')).toEqual([
26
+ {
27
+ field: 'a.b',
28
+ order: 'asc',
29
+ },
30
+ ]);
31
+ });
32
+ test('handles prefix notation', () => {
33
+ expect(parseSort('-a')).toEqual([
34
+ {
35
+ field: 'a',
36
+ order: 'desc',
37
+ },
38
+ ]);
39
+ expect(parseSort('+b')).toEqual([
40
+ {
41
+ field: 'b',
42
+ order: 'asc',
43
+ },
44
+ ]);
45
+ expect(parseSort('-a,+b')).toEqual([
46
+ {
47
+ field: 'a',
48
+ order: 'desc',
49
+ },
50
+ {
51
+ field: 'b',
52
+ order: 'asc',
53
+ },
54
+ ]);
55
+ });
56
+ });
57
+ describe('explicit ordering', () => {
58
+ test('handles explicit order keywords', () => {
59
+ expect(parseSort('a asc')).toEqual([
60
+ {
61
+ field: 'a',
62
+ order: 'asc',
63
+ },
64
+ ]);
65
+ expect(parseSort('a desc')).toEqual([
66
+ {
67
+ field: 'a',
68
+ order: 'desc',
69
+ },
70
+ ]);
71
+ expect(parseSort('-a asc')).toEqual([
72
+ {
73
+ field: 'a',
74
+ order: 'asc',
75
+ },
76
+ ]); // explicit order overrides prefix
77
+ });
78
+ });
79
+ describe('nulls handling', () => {
80
+ test('handles nulls specification', () => {
81
+ expect(parseSort('a asc nulls last')).toEqual([
82
+ {
83
+ field: 'a',
84
+ order: 'asc',
85
+ nulls: 'last',
86
+ },
87
+ ]);
88
+ expect(parseSort('a asc nulls first')).toEqual([
89
+ {
90
+ field: 'a',
91
+ order: 'asc',
92
+ nulls: 'first',
93
+ },
94
+ ]);
95
+ expect(parseSort('a desc nulls last')).toEqual([
96
+ {
97
+ field: 'a',
98
+ order: 'desc',
99
+ nulls: 'last',
100
+ },
101
+ ]);
102
+ expect(parseSort('a nulls first')).toEqual([
103
+ {
104
+ field: 'a',
105
+ order: 'asc',
106
+ nulls: 'first',
107
+ },
108
+ ]);
109
+ expect(parseSort('-a nulls first')).toEqual([
110
+ {
111
+ field: 'a',
112
+ order: 'desc',
113
+ nulls: 'first',
114
+ },
115
+ ]);
116
+ // Alternative syntax
117
+ expect(parseSort('a asc last')).toEqual([
118
+ {
119
+ field: 'a',
120
+ order: 'asc',
121
+ nulls: 'last',
122
+ },
123
+ ]);
124
+ });
125
+ });
126
+ describe('object notation', () => {
127
+ test('handles object input', () => {
128
+ expect(
129
+ parseSort([
130
+ {
131
+ field: 'a',
132
+ order: 'asc',
133
+ },
134
+ ]),
135
+ ).toEqual([
136
+ {
137
+ field: 'a',
138
+ order: 'asc',
139
+ },
140
+ ]);
141
+ expect(
142
+ parseSort([
143
+ {
144
+ field: 'a',
145
+ order: 'asc',
146
+ nulls: 'last',
147
+ },
148
+ ]),
149
+ ).toEqual([
150
+ {
151
+ field: 'a',
152
+ order: 'asc',
153
+ nulls: 'last',
154
+ },
155
+ ]);
156
+ });
157
+ });
158
+ describe('invalid inputs', () => {
159
+ test('handles invalid inputs gracefully', () => {
160
+ expect(
161
+ parseSort([
162
+ {
163
+ order: 'asc',
164
+ },
165
+ ]),
166
+ ).toEqual([]);
167
+ expect(
168
+ parseSort([
169
+ 'a,,',
170
+ {
171
+ field: '',
172
+ order: 'asc',
173
+ },
174
+ ]),
175
+ ).toEqual([
176
+ {
177
+ field: 'a',
178
+ order: 'asc',
179
+ },
180
+ ]);
181
+ expect(
182
+ parseSort([
183
+ ',,',
184
+ {
185
+ field: 'a',
186
+ order: 'asc',
187
+ },
188
+ ]),
189
+ ).toEqual([
190
+ {
191
+ field: 'a',
192
+ order: 'asc',
193
+ },
194
+ ]);
195
+ });
196
+ });
188
197
  });
@@ -1,43 +1,42 @@
1
- import { maybeFunction } from "@wener/utils";
2
- import { mapValues, omitBy, pick } from "es-toolkit";
3
- import { maybeNumber } from "./maybeNumber.js";
1
+ import { maybeFunction } from '@wener/utils';
2
+ import { mapValues, omitBy, pick } from 'es-toolkit';
3
+ import { maybeNumber } from './maybeNumber.js';
4
4
  export function resolvePagination(page, options = {}) {
5
- let out = omitBy(mapValues(//
6
- pick(page, [
7
- "limit",
8
- "offset",
9
- "pageSize",
10
- "pageNumber",
11
- "pageIndex"
12
- ]), // to Number
13
- (v) => maybeNumber(v)), (v) => v === undefined || v === null);
14
- let { pageSize } = out;
15
- if (options.pageSize) {
16
- pageSize = maybeFunction(options.pageSize, pageSize);
17
- }
18
- pageSize ??= resolvePagination.pageSize;
19
- let { pageNumber = 1, pageIndex } = out;
20
- // page index over page number
21
- pageNumber = Math.max(pageNumber, 1);
22
- pageIndex = Math.max(pageIndex ?? pageNumber - 1, 0);
23
- let { limit = pageSize, offset = pageSize * pageIndex } = out;
24
- limit = Math.max(1, limit);
25
- offset = Math.max(0, offset);
26
- if (options.maxLimit) {
27
- limit = Math.min(limit, options.maxLimit);
28
- }
29
- if (options.maxOffset) {
30
- offset = Math.min(offset, options.maxOffset);
31
- }
32
- pageSize = limit;
33
- pageIndex = Math.floor(offset / pageSize);
34
- return {
35
- limit,
36
- offset,
37
- pageSize,
38
- pageNumber: pageIndex + 1,
39
- pageIndex
40
- };
5
+ let out = omitBy(
6
+ mapValues(
7
+ //
8
+ pick(page, ['limit', 'offset', 'pageSize', 'pageNumber', 'pageIndex']), // to Number
9
+ (v) => maybeNumber(v),
10
+ ),
11
+ (v) => v === undefined || v === null,
12
+ );
13
+ let { pageSize } = out;
14
+ if (options.pageSize) {
15
+ pageSize = maybeFunction(options.pageSize, pageSize);
16
+ }
17
+ pageSize ??= resolvePagination.pageSize;
18
+ let { pageNumber = 1, pageIndex } = out;
19
+ // page index over page number
20
+ pageNumber = Math.max(pageNumber, 1);
21
+ pageIndex = Math.max(pageIndex ?? pageNumber - 1, 0);
22
+ let { limit = pageSize, offset = pageSize * pageIndex } = out;
23
+ limit = Math.max(1, limit);
24
+ offset = Math.max(0, offset);
25
+ if (options.maxLimit) {
26
+ limit = Math.min(limit, options.maxLimit);
27
+ }
28
+ if (options.maxOffset) {
29
+ offset = Math.min(offset, options.maxOffset);
30
+ }
31
+ pageSize = limit;
32
+ pageIndex = Math.floor(offset / pageSize);
33
+ return {
34
+ limit,
35
+ offset,
36
+ pageSize,
37
+ pageNumber: pageIndex + 1,
38
+ pageIndex,
39
+ };
41
40
  }
42
41
  resolvePagination.pageSize = 20;
43
42
  //# sourceMappingURL=resolvePagination.js.map