@nestia/e2e 7.3.3 → 8.0.0-dev.20250829
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/LICENSE +21 -21
- package/README.md +93 -93
- package/lib/ArrayUtil.d.ts +47 -43
- package/lib/ArrayUtil.js +122 -134
- package/lib/ArrayUtil.js.map +1 -1
- package/lib/GaffComparator.d.ts +19 -12
- package/lib/GaffComparator.js +19 -12
- package/lib/GaffComparator.js.map +1 -1
- package/lib/MapUtil.d.ts +79 -0
- package/lib/MapUtil.js +92 -0
- package/lib/MapUtil.js.map +1 -0
- package/lib/RandomGenerator.d.ts +107 -71
- package/lib/RandomGenerator.js +124 -109
- package/lib/RandomGenerator.js.map +1 -1
- package/lib/TestValidator.d.ts +107 -145
- package/lib/TestValidator.js +308 -351
- package/lib/TestValidator.js.map +1 -1
- package/lib/module.d.ts +2 -1
- package/lib/module.js +2 -1
- package/lib/module.js.map +1 -1
- package/package.json +1 -1
- package/src/ArrayUtil.ts +87 -88
- package/src/GaffComparator.ts +19 -12
- package/src/MapUtil.ts +86 -0
- package/src/RandomGenerator.ts +138 -101
- package/src/TestValidator.ts +251 -294
- package/src/module.ts +3 -1
package/lib/ArrayUtil.js
CHANGED
|
@@ -53,15 +53,15 @@ exports.ArrayUtil = void 0;
|
|
|
53
53
|
*
|
|
54
54
|
* This namespace contains utility functions for array operations including
|
|
55
55
|
* asynchronous processing, filtering, mapping, and repetition tasks implemented
|
|
56
|
-
* in functional programming style.
|
|
57
|
-
*
|
|
56
|
+
* in functional programming style. Functions use direct parameter passing for
|
|
57
|
+
* simplicity while maintaining functional programming principles.
|
|
58
58
|
*
|
|
59
59
|
* @author Jeongho Nam - https://github.com/samchon
|
|
60
60
|
* @example
|
|
61
61
|
* ```typescript
|
|
62
62
|
* // Asynchronous filtering example
|
|
63
63
|
* const numbers = [1, 2, 3, 4, 5];
|
|
64
|
-
* const evenNumbers = await ArrayUtil.asyncFilter(numbers
|
|
64
|
+
* const evenNumbers = await ArrayUtil.asyncFilter(numbers,
|
|
65
65
|
* async (num) => num % 2 === 0
|
|
66
66
|
* );
|
|
67
67
|
* console.log(evenNumbers); // [2, 4]
|
|
@@ -74,9 +74,9 @@ var ArrayUtil;
|
|
|
74
74
|
* Filters an array by applying an asynchronous predicate function to each
|
|
75
75
|
* element.
|
|
76
76
|
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
77
|
+
* Elements are processed sequentially, ensuring order is maintained. The
|
|
78
|
+
* predicate function receives the element, index, and the full array as
|
|
79
|
+
* parameters.
|
|
80
80
|
*
|
|
81
81
|
* @example
|
|
82
82
|
* ```typescript
|
|
@@ -86,7 +86,7 @@ var ArrayUtil;
|
|
|
86
86
|
* { id: 3, name: 'Charlie', active: true }
|
|
87
87
|
* ];
|
|
88
88
|
*
|
|
89
|
-
* const activeUsers = await ArrayUtil.asyncFilter(users
|
|
89
|
+
* const activeUsers = await ArrayUtil.asyncFilter(users,
|
|
90
90
|
* async (user) => {
|
|
91
91
|
* // Async validation logic (e.g., API call)
|
|
92
92
|
* await new Promise(resolve => setTimeout(resolve, 100));
|
|
@@ -98,37 +98,35 @@ var ArrayUtil;
|
|
|
98
98
|
*
|
|
99
99
|
* @template Input - The type of elements in the input array
|
|
100
100
|
* @param elements - The readonly array to filter
|
|
101
|
-
* @
|
|
102
|
-
*
|
|
101
|
+
* @param pred - The asynchronous predicate function to test each element
|
|
102
|
+
* @returns A Promise resolving to the filtered array
|
|
103
103
|
*/
|
|
104
|
-
ArrayUtil.asyncFilter = function (elements) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}); };
|
|
131
|
-
};
|
|
104
|
+
ArrayUtil.asyncFilter = function (elements, pred) { return __awaiter(_this, void 0, void 0, function () {
|
|
105
|
+
var ret;
|
|
106
|
+
var _this = this;
|
|
107
|
+
return __generator(this, function (_a) {
|
|
108
|
+
switch (_a.label) {
|
|
109
|
+
case 0:
|
|
110
|
+
ret = [];
|
|
111
|
+
return [4 /*yield*/, ArrayUtil.asyncForEach(elements, function (elem, index, array) { return __awaiter(_this, void 0, void 0, function () {
|
|
112
|
+
var flag;
|
|
113
|
+
return __generator(this, function (_a) {
|
|
114
|
+
switch (_a.label) {
|
|
115
|
+
case 0: return [4 /*yield*/, pred(elem, index, array)];
|
|
116
|
+
case 1:
|
|
117
|
+
flag = _a.sent();
|
|
118
|
+
if (flag === true)
|
|
119
|
+
ret.push(elem);
|
|
120
|
+
return [2 /*return*/];
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}); })];
|
|
124
|
+
case 1:
|
|
125
|
+
_a.sent();
|
|
126
|
+
return [2 /*return*/, ret];
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}); };
|
|
132
130
|
/**
|
|
133
131
|
* Executes an asynchronous function for each element in an array
|
|
134
132
|
* sequentially.
|
|
@@ -142,57 +140,56 @@ var ArrayUtil;
|
|
|
142
140
|
* ```typescript
|
|
143
141
|
* const urls = ['url1', 'url2', 'url3'];
|
|
144
142
|
*
|
|
145
|
-
* await ArrayUtil.asyncForEach(urls
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
143
|
+
* await ArrayUtil.asyncForEach(urls, async (url, index) => {
|
|
144
|
+
* console.log(`Processing ${index}: ${url}`);
|
|
145
|
+
* const data = await fetch(url);
|
|
146
|
+
* await processData(data);
|
|
147
|
+
* console.log(`Completed ${index}: ${url}`);
|
|
150
148
|
* });
|
|
151
149
|
* console.log('All URLs processed sequentially');
|
|
152
150
|
* ```
|
|
153
151
|
*
|
|
154
152
|
* @template Input - The type of elements in the input array
|
|
155
153
|
* @param elements - The readonly array to process
|
|
156
|
-
* @
|
|
154
|
+
* @param closure - The asynchronous function to execute for each element
|
|
155
|
+
* @returns A Promise<void> that resolves when all operations complete
|
|
157
156
|
*/
|
|
158
|
-
ArrayUtil.asyncForEach = function (elements) {
|
|
159
|
-
return
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}); };
|
|
171
|
-
};
|
|
157
|
+
ArrayUtil.asyncForEach = function (elements, closure) { return __awaiter(_this, void 0, void 0, function () {
|
|
158
|
+
return __generator(this, function (_a) {
|
|
159
|
+
switch (_a.label) {
|
|
160
|
+
case 0: return [4 /*yield*/, ArrayUtil.asyncRepeat(elements.length, function (index) {
|
|
161
|
+
return closure(elements[index], index, elements);
|
|
162
|
+
})];
|
|
163
|
+
case 1:
|
|
164
|
+
_a.sent();
|
|
165
|
+
return [2 /*return*/];
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}); };
|
|
172
169
|
/**
|
|
173
170
|
* Transforms each element of an array using an asynchronous function to
|
|
174
171
|
* create a new array.
|
|
175
172
|
*
|
|
176
173
|
* Similar to JavaScript's native map but processes asynchronous functions
|
|
177
174
|
* sequentially. Each element's transformation is completed before proceeding
|
|
178
|
-
* to the next element, ensuring order is maintained.
|
|
175
|
+
* to the next element, ensuring order is maintained. This function still
|
|
176
|
+
* maintains the currying pattern for composition.
|
|
179
177
|
*
|
|
180
178
|
* @example
|
|
181
179
|
* ```typescript
|
|
182
180
|
* const userIds = [1, 2, 3, 4, 5];
|
|
183
181
|
*
|
|
184
182
|
* const userDetails = await ArrayUtil.asyncMap(userIds)(
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
183
|
+
* async (id, index) => {
|
|
184
|
+
* console.log(`Fetching user ${id} (${index + 1}/${userIds.length})`);
|
|
185
|
+
* const response = await fetch(`/api/users/${id}`);
|
|
186
|
+
* return await response.json();
|
|
187
|
+
* }
|
|
190
188
|
* );
|
|
191
189
|
* console.log('All users fetched:', userDetails);
|
|
192
190
|
* ```
|
|
193
191
|
*
|
|
194
192
|
* @template Input - The type of elements in the input array
|
|
195
|
-
* @template Output - The type of elements in the output array
|
|
196
193
|
* @param elements - The readonly array to transform
|
|
197
194
|
* @returns A function that takes a transformation function and returns a
|
|
198
195
|
* Promise resolving to the transformed array
|
|
@@ -205,7 +202,7 @@ var ArrayUtil;
|
|
|
205
202
|
switch (_a.label) {
|
|
206
203
|
case 0:
|
|
207
204
|
ret = [];
|
|
208
|
-
return [4 /*yield*/, ArrayUtil.asyncForEach(elements
|
|
205
|
+
return [4 /*yield*/, ArrayUtil.asyncForEach(elements, function (elem, index, array) { return __awaiter(_this, void 0, void 0, function () {
|
|
209
206
|
var output;
|
|
210
207
|
return __generator(this, function (_a) {
|
|
211
208
|
switch (_a.label) {
|
|
@@ -234,7 +231,7 @@ var ArrayUtil;
|
|
|
234
231
|
* @example
|
|
235
232
|
* ```typescript
|
|
236
233
|
* // Generate random data 5 times
|
|
237
|
-
* const randomData = await ArrayUtil.asyncRepeat(5
|
|
234
|
+
* const randomData = await ArrayUtil.asyncRepeat(5, async (index) => {
|
|
238
235
|
* await new Promise(resolve => setTimeout(resolve, 100)); // Wait 0.1 seconds
|
|
239
236
|
* return {
|
|
240
237
|
* id: index,
|
|
@@ -245,59 +242,55 @@ var ArrayUtil;
|
|
|
245
242
|
* console.log('Generated data:', randomData);
|
|
246
243
|
* ```;
|
|
247
244
|
*
|
|
245
|
+
* @template T - The type of the result from each execution
|
|
248
246
|
* @param count - The number of times to repeat (non-negative integer)
|
|
249
|
-
* @
|
|
250
|
-
*
|
|
247
|
+
* @param closure - The asynchronous function to execute repeatedly
|
|
248
|
+
* @returns A Promise resolving to an array of results
|
|
251
249
|
*/
|
|
252
|
-
ArrayUtil.asyncRepeat = function (count) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
}); };
|
|
294
|
-
};
|
|
250
|
+
ArrayUtil.asyncRepeat = function (count, closure) { return __awaiter(_this, void 0, void 0, function () {
|
|
251
|
+
var indexes, output, indexes_1, indexes_1_1, index, _a, _b, e_1_1;
|
|
252
|
+
var e_1, _c;
|
|
253
|
+
return __generator(this, function (_d) {
|
|
254
|
+
switch (_d.label) {
|
|
255
|
+
case 0:
|
|
256
|
+
indexes = new Array(count).fill(1).map(function (_, index) { return index; });
|
|
257
|
+
output = [];
|
|
258
|
+
_d.label = 1;
|
|
259
|
+
case 1:
|
|
260
|
+
_d.trys.push([1, 6, 7, 8]);
|
|
261
|
+
indexes_1 = __values(indexes), indexes_1_1 = indexes_1.next();
|
|
262
|
+
_d.label = 2;
|
|
263
|
+
case 2:
|
|
264
|
+
if (!!indexes_1_1.done) return [3 /*break*/, 5];
|
|
265
|
+
index = indexes_1_1.value;
|
|
266
|
+
_b = (_a = output).push;
|
|
267
|
+
return [4 /*yield*/, closure(index)];
|
|
268
|
+
case 3:
|
|
269
|
+
_b.apply(_a, [_d.sent()]);
|
|
270
|
+
_d.label = 4;
|
|
271
|
+
case 4:
|
|
272
|
+
indexes_1_1 = indexes_1.next();
|
|
273
|
+
return [3 /*break*/, 2];
|
|
274
|
+
case 5: return [3 /*break*/, 8];
|
|
275
|
+
case 6:
|
|
276
|
+
e_1_1 = _d.sent();
|
|
277
|
+
e_1 = { error: e_1_1 };
|
|
278
|
+
return [3 /*break*/, 8];
|
|
279
|
+
case 7:
|
|
280
|
+
try {
|
|
281
|
+
if (indexes_1_1 && !indexes_1_1.done && (_c = indexes_1.return)) _c.call(indexes_1);
|
|
282
|
+
}
|
|
283
|
+
finally { if (e_1) throw e_1.error; }
|
|
284
|
+
return [7 /*endfinally*/];
|
|
285
|
+
case 8: return [2 /*return*/, output];
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}); };
|
|
295
289
|
/**
|
|
296
290
|
* Checks if at least one element in the array satisfies the given condition.
|
|
297
291
|
*
|
|
298
|
-
* Similar to JavaScript's native some() method
|
|
299
|
-
*
|
|
300
|
-
* true immediately when the first element satisfying the condition is found.
|
|
292
|
+
* Similar to JavaScript's native some() method. Returns true immediately
|
|
293
|
+
* when the first element satisfying the condition is found.
|
|
301
294
|
*
|
|
302
295
|
* @example
|
|
303
296
|
* ```typescript
|
|
@@ -308,25 +301,22 @@ var ArrayUtil;
|
|
|
308
301
|
* { name: 'Orange', price: 80, inStock: true }
|
|
309
302
|
* ];
|
|
310
303
|
*
|
|
311
|
-
* const hasEvenNumber = ArrayUtil.has(numbers
|
|
304
|
+
* const hasEvenNumber = ArrayUtil.has(numbers, num => num % 2 === 0);
|
|
312
305
|
* console.log(hasEvenNumber); // true (8 exists)
|
|
313
306
|
*
|
|
314
|
-
* const hasExpensiveItem = ArrayUtil.has(products
|
|
307
|
+
* const hasExpensiveItem = ArrayUtil.has(products, product => product.price > 90);
|
|
315
308
|
* console.log(hasExpensiveItem); // true (Apple costs 100)
|
|
316
309
|
*
|
|
317
|
-
* const hasOutOfStock = ArrayUtil.has(products
|
|
310
|
+
* const hasOutOfStock = ArrayUtil.has(products, product => !product.inStock);
|
|
318
311
|
* console.log(hasOutOfStock); // true (Banana is out of stock)
|
|
319
312
|
* ```;
|
|
320
313
|
*
|
|
321
314
|
* @template T - The type of elements in the array
|
|
322
315
|
* @param elements - The readonly array to check
|
|
323
|
-
* @
|
|
316
|
+
* @param pred - The predicate function to test elements
|
|
317
|
+
* @returns Boolean indicating if any element satisfies the condition
|
|
324
318
|
*/
|
|
325
|
-
ArrayUtil.has = function (elements) {
|
|
326
|
-
return function (pred) {
|
|
327
|
-
return elements.find(pred) !== undefined;
|
|
328
|
-
};
|
|
329
|
-
};
|
|
319
|
+
ArrayUtil.has = function (elements, pred) { return elements.find(pred) !== undefined; };
|
|
330
320
|
/**
|
|
331
321
|
* Executes a function a specified number of times and collects the results
|
|
332
322
|
* into an array.
|
|
@@ -337,14 +327,14 @@ var ArrayUtil;
|
|
|
337
327
|
* @example
|
|
338
328
|
* ```typescript
|
|
339
329
|
* // Generate an array of squares from 1 to 5
|
|
340
|
-
* const squares = ArrayUtil.repeat(5
|
|
330
|
+
* const squares = ArrayUtil.repeat(5, index => (index + 1) ** 2);
|
|
341
331
|
* console.log(squares); // [1, 4, 9, 16, 25]
|
|
342
332
|
*
|
|
343
333
|
* // Generate an array of default user objects
|
|
344
|
-
* const users = ArrayUtil.repeat(3
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
334
|
+
* const users = ArrayUtil.repeat(3, index => ({
|
|
335
|
+
* id: index + 1,
|
|
336
|
+
* name: `User${index + 1}`,
|
|
337
|
+
* email: `user${index + 1}@example.com`
|
|
348
338
|
* }));
|
|
349
339
|
* console.log(users);
|
|
350
340
|
* // [
|
|
@@ -354,14 +344,12 @@ var ArrayUtil;
|
|
|
354
344
|
* // ]
|
|
355
345
|
* ```
|
|
356
346
|
*
|
|
347
|
+
* @template T - The type of the result from each execution
|
|
357
348
|
* @param count - The number of times to repeat (non-negative integer)
|
|
358
|
-
* @
|
|
349
|
+
* @param closure - The function to execute repeatedly
|
|
350
|
+
* @returns An array of results
|
|
359
351
|
*/
|
|
360
|
-
ArrayUtil.repeat = function (count) {
|
|
361
|
-
return function (closure) {
|
|
362
|
-
return new Array(count).fill("").map(function (_, index) { return closure(index); });
|
|
363
|
-
};
|
|
364
|
-
};
|
|
352
|
+
ArrayUtil.repeat = function (count, closure) { return new Array(count).fill("").map(function (_, index) { return closure(index); }); };
|
|
365
353
|
/**
|
|
366
354
|
* Generates all possible subsets of a given array.
|
|
367
355
|
*
|
package/lib/ArrayUtil.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayUtil.js","sourceRoot":"","sources":["../src/ArrayUtil.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,IAAiB,SAAS,
|
|
1
|
+
{"version":3,"file":"ArrayUtil.js","sourceRoot":"","sources":["../src/ArrayUtil.ts"],"names":[],"mappings":"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"}
|
package/lib/GaffComparator.d.ts
CHANGED
|
@@ -34,12 +34,14 @@
|
|
|
34
34
|
* users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
|
|
35
35
|
* events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
|
|
36
36
|
*
|
|
37
|
-
* // Integration with TestValidator
|
|
38
|
-
*
|
|
37
|
+
* // Integration with TestValidator's currying pattern
|
|
38
|
+
* const validator = TestValidator.sort("user sorting",
|
|
39
39
|
* (sortable) => api.getUsers({ sort: sortable })
|
|
40
40
|
* )("name", "email")(
|
|
41
41
|
* GaffComparator.strings(user => [user.name, user.email])
|
|
42
|
-
* )
|
|
42
|
+
* );
|
|
43
|
+
* await validator("+"); // ascending
|
|
44
|
+
* await validator("-"); // descending
|
|
43
45
|
* ```;
|
|
44
46
|
*/
|
|
45
47
|
export declare namespace GaffComparator {
|
|
@@ -87,12 +89,14 @@ export declare namespace GaffComparator {
|
|
|
87
89
|
* // Complex multi-field: status, then last name, then first name
|
|
88
90
|
* users.sort(GaffComparator.strings(user => [user.status, user.lastName, user.firstName]));
|
|
89
91
|
*
|
|
90
|
-
* // Integration with
|
|
91
|
-
*
|
|
92
|
+
* // Integration with TestValidator sorting validation
|
|
93
|
+
* const sortValidator = TestValidator.sort("user name sorting",
|
|
92
94
|
* (sortFields) => userApi.getUsers({ sort: sortFields })
|
|
93
95
|
* )("lastName", "firstName")(
|
|
94
96
|
* GaffComparator.strings(user => [user.lastName, user.firstName])
|
|
95
|
-
* )
|
|
97
|
+
* );
|
|
98
|
+
* await sortValidator("+"); // test ascending order
|
|
99
|
+
* await sortValidator("-"); // test descending order
|
|
96
100
|
* ```;
|
|
97
101
|
*
|
|
98
102
|
* @template T - The type of objects being compared
|
|
@@ -156,12 +160,13 @@ export declare namespace GaffComparator {
|
|
|
156
160
|
* // Sort by modification history: created date, then updated date
|
|
157
161
|
* events.sort(GaffComparator.dates(event => [event.createdAt, event.updatedAt]));
|
|
158
162
|
*
|
|
159
|
-
* // Validate API date sorting
|
|
160
|
-
*
|
|
163
|
+
* // Validate API date sorting with TestValidator
|
|
164
|
+
* const dateValidator = TestValidator.sort("event chronological sorting",
|
|
161
165
|
* (sortFields) => eventApi.getEvents({ sort: sortFields })
|
|
162
166
|
* )("startDate")(
|
|
163
167
|
* GaffComparator.dates(event => event.startDate)
|
|
164
|
-
* )
|
|
168
|
+
* );
|
|
169
|
+
* await dateValidator("+", true); // ascending with trace logging
|
|
165
170
|
*
|
|
166
171
|
* // Test complex date-based sorting
|
|
167
172
|
* const sortByEventSchedule = GaffComparator.dates(event => [
|
|
@@ -225,12 +230,14 @@ export declare namespace GaffComparator {
|
|
|
225
230
|
* // Sort by inventory priority: low stock first, then by sales
|
|
226
231
|
* products.sort(GaffComparator.numbers(product => [product.stock, -product.salesCount]));
|
|
227
232
|
*
|
|
228
|
-
* // Validate API numerical sorting
|
|
229
|
-
*
|
|
233
|
+
* // Validate API numerical sorting with TestValidator
|
|
234
|
+
* const priceValidator = TestValidator.sort("product price sorting",
|
|
230
235
|
* (sortFields) => productApi.getProducts({ sort: sortFields })
|
|
231
236
|
* )("price")(
|
|
232
237
|
* GaffComparator.numbers(product => product.price)
|
|
233
|
-
* )
|
|
238
|
+
* );
|
|
239
|
+
* await priceValidator("+"); // test ascending order
|
|
240
|
+
* await priceValidator("-"); // test descending order
|
|
234
241
|
*
|
|
235
242
|
* // Test multi-criteria sorting
|
|
236
243
|
* const sortByBusinessValue = GaffComparator.numbers(product => [
|
package/lib/GaffComparator.js
CHANGED
|
@@ -37,12 +37,14 @@ exports.GaffComparator = void 0;
|
|
|
37
37
|
* users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
|
|
38
38
|
* events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
|
|
39
39
|
*
|
|
40
|
-
* // Integration with TestValidator
|
|
41
|
-
*
|
|
40
|
+
* // Integration with TestValidator's currying pattern
|
|
41
|
+
* const validator = TestValidator.sort("user sorting",
|
|
42
42
|
* (sortable) => api.getUsers({ sort: sortable })
|
|
43
43
|
* )("name", "email")(
|
|
44
44
|
* GaffComparator.strings(user => [user.name, user.email])
|
|
45
|
-
* )
|
|
45
|
+
* );
|
|
46
|
+
* await validator("+"); // ascending
|
|
47
|
+
* await validator("-"); // descending
|
|
46
48
|
* ```;
|
|
47
49
|
*/
|
|
48
50
|
var GaffComparator;
|
|
@@ -91,12 +93,14 @@ var GaffComparator;
|
|
|
91
93
|
* // Complex multi-field: status, then last name, then first name
|
|
92
94
|
* users.sort(GaffComparator.strings(user => [user.status, user.lastName, user.firstName]));
|
|
93
95
|
*
|
|
94
|
-
* // Integration with
|
|
95
|
-
*
|
|
96
|
+
* // Integration with TestValidator sorting validation
|
|
97
|
+
* const sortValidator = TestValidator.sort("user name sorting",
|
|
96
98
|
* (sortFields) => userApi.getUsers({ sort: sortFields })
|
|
97
99
|
* )("lastName", "firstName")(
|
|
98
100
|
* GaffComparator.strings(user => [user.lastName, user.firstName])
|
|
99
|
-
* )
|
|
101
|
+
* );
|
|
102
|
+
* await sortValidator("+"); // test ascending order
|
|
103
|
+
* await sortValidator("-"); // test descending order
|
|
100
104
|
* ```;
|
|
101
105
|
*
|
|
102
106
|
* @template T - The type of objects being compared
|
|
@@ -167,12 +171,13 @@ var GaffComparator;
|
|
|
167
171
|
* // Sort by modification history: created date, then updated date
|
|
168
172
|
* events.sort(GaffComparator.dates(event => [event.createdAt, event.updatedAt]));
|
|
169
173
|
*
|
|
170
|
-
* // Validate API date sorting
|
|
171
|
-
*
|
|
174
|
+
* // Validate API date sorting with TestValidator
|
|
175
|
+
* const dateValidator = TestValidator.sort("event chronological sorting",
|
|
172
176
|
* (sortFields) => eventApi.getEvents({ sort: sortFields })
|
|
173
177
|
* )("startDate")(
|
|
174
178
|
* GaffComparator.dates(event => event.startDate)
|
|
175
|
-
* )
|
|
179
|
+
* );
|
|
180
|
+
* await dateValidator("+", true); // ascending with trace logging
|
|
176
181
|
*
|
|
177
182
|
* // Test complex date-based sorting
|
|
178
183
|
* const sortByEventSchedule = GaffComparator.dates(event => [
|
|
@@ -246,12 +251,14 @@ var GaffComparator;
|
|
|
246
251
|
* // Sort by inventory priority: low stock first, then by sales
|
|
247
252
|
* products.sort(GaffComparator.numbers(product => [product.stock, -product.salesCount]));
|
|
248
253
|
*
|
|
249
|
-
* // Validate API numerical sorting
|
|
250
|
-
*
|
|
254
|
+
* // Validate API numerical sorting with TestValidator
|
|
255
|
+
* const priceValidator = TestValidator.sort("product price sorting",
|
|
251
256
|
* (sortFields) => productApi.getProducts({ sort: sortFields })
|
|
252
257
|
* )("price")(
|
|
253
258
|
* GaffComparator.numbers(product => product.price)
|
|
254
|
-
* )
|
|
259
|
+
* );
|
|
260
|
+
* await priceValidator("+"); // test ascending order
|
|
261
|
+
* await priceValidator("-"); // test descending order
|
|
255
262
|
*
|
|
256
263
|
* // Test multi-criteria sorting
|
|
257
264
|
* const sortByBusinessValue = GaffComparator.numbers(product => [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GaffComparator.js","sourceRoot":"","sources":["../src/GaffComparator.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"GaffComparator.js","sourceRoot":"","sources":["../src/GaffComparator.ts"],"names":[],"mappings":"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"}
|
package/lib/MapUtil.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A namespace providing utility functions for Map manipulation.
|
|
3
|
+
*
|
|
4
|
+
* This namespace contains helper functions for working with JavaScript Map
|
|
5
|
+
* objects, providing convenient methods for common Map operations like
|
|
6
|
+
* retrieving values with lazy initialization.
|
|
7
|
+
*
|
|
8
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Create a cache with lazy initialization
|
|
12
|
+
* const cache = new Map<string, ExpensiveObject>();
|
|
13
|
+
*
|
|
14
|
+
* const obj = MapUtil.take(cache, "key1", () => {
|
|
15
|
+
* console.log("Creating expensive object...");
|
|
16
|
+
* return new ExpensiveObject();
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Subsequent calls return cached value without re-creating
|
|
20
|
+
* const sameObj = MapUtil.take(cache, "key1", () => new ExpensiveObject());
|
|
21
|
+
* console.log(obj === sameObj); // true
|
|
22
|
+
* ```;
|
|
23
|
+
*/
|
|
24
|
+
export declare namespace MapUtil {
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves a value from a Map or creates it using a lazy initialization
|
|
27
|
+
* function.
|
|
28
|
+
*
|
|
29
|
+
* This function implements the "get or create" pattern for Maps. If the key
|
|
30
|
+
* exists in the Map, it returns the existing value. Otherwise, it calls the
|
|
31
|
+
* provided factory function to create a new value, stores it in the Map, and
|
|
32
|
+
* returns it. The factory function is only called when the key doesn't exist,
|
|
33
|
+
* enabling lazy initialization and caching patterns.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Simple caching example
|
|
38
|
+
* const userCache = new Map<number, User>();
|
|
39
|
+
*
|
|
40
|
+
* const user = MapUtil.take(userCache, userId, () => {
|
|
41
|
+
* // This expensive operation only runs if userId is not cached
|
|
42
|
+
* return fetchUserFromDatabase(userId);
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // Configuration object caching
|
|
46
|
+
* const configs = new Map<string, Config>();
|
|
47
|
+
*
|
|
48
|
+
* const dbConfig = MapUtil.take(configs, "database", () => ({
|
|
49
|
+
* host: "localhost",
|
|
50
|
+
* port: 5432,
|
|
51
|
+
* database: "myapp"
|
|
52
|
+
* }));
|
|
53
|
+
*
|
|
54
|
+
* // Lazy computation results
|
|
55
|
+
* const computationCache = new Map<string, number>();
|
|
56
|
+
*
|
|
57
|
+
* const result = MapUtil.take(computationCache, "fibonacci-40", () => {
|
|
58
|
+
* console.log("Computing fibonacci(40)...");
|
|
59
|
+
* return fibonacci(40); // Only computed once
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Using with complex keys
|
|
63
|
+
* const cache = new Map<[number, number], Matrix>();
|
|
64
|
+
* const key: [number, number] = [rows, cols];
|
|
65
|
+
*
|
|
66
|
+
* const matrix = MapUtil.take(cache, key, () =>
|
|
67
|
+
* generateIdentityMatrix(rows, cols)
|
|
68
|
+
* );
|
|
69
|
+
* ```;
|
|
70
|
+
*
|
|
71
|
+
* @template K - The type of keys in the Map
|
|
72
|
+
* @template V - The type of values in the Map
|
|
73
|
+
* @param map - The Map to retrieve from or update
|
|
74
|
+
* @param key - The key to look up in the Map
|
|
75
|
+
* @param value - A factory function that creates the value if key doesn't exist
|
|
76
|
+
* @returns The existing value if found, or the newly created value
|
|
77
|
+
*/
|
|
78
|
+
function take<K, V>(map: Map<K, V>, key: K, value: () => V): V;
|
|
79
|
+
}
|