quetch 0.30.0 → 0.31.0

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 (164) hide show
  1. package/dist/tools/comparatorFieldValues.d.ts +8 -0
  2. package/dist/tools/comparatorFieldValues.js +26 -0
  3. package/dist/tools/comparatorFieldValues.js.map +1 -0
  4. package/dist/tools/get.d.ts +4 -4
  5. package/dist/tools/get.js +6 -2
  6. package/dist/tools/get.js.map +1 -1
  7. package/dist/tools/querySettings.d.ts +8 -0
  8. package/dist/tools/querySettings.js +16 -0
  9. package/dist/tools/querySettings.js.map +1 -0
  10. package/dist/tools/sortItemList.d.ts +4 -4
  11. package/dist/tools/sortItemList.js +17 -24
  12. package/dist/tools/sortItemList.js.map +1 -1
  13. package/dist/tools/transformerFilterChildren.d.ts +2 -22
  14. package/dist/tools/transformerFilterChildren.js +1 -4
  15. package/dist/tools/transformerFilterChildren.js.map +1 -1
  16. package/dist/tools.d.ts +2 -0
  17. package/dist/tools.js +2 -0
  18. package/dist/tools.js.map +1 -1
  19. package/dist/types/CombineUnion.d.ts +1 -1
  20. package/dist/types/Decrement.d.ts +4 -0
  21. package/dist/types/Decrement.js +1 -0
  22. package/dist/types/Decrement.js.map +1 -0
  23. package/dist/types/DepthLimit.d.ts +1 -0
  24. package/dist/types/DepthLimit.js +1 -0
  25. package/dist/types/DepthLimit.js.map +1 -0
  26. package/dist/types/FieldKey.d.ts +2 -1
  27. package/dist/types/Get.d.ts +3 -1
  28. package/dist/types/KeyFiltered.d.ts +1 -1
  29. package/dist/types/NormalizedPathFieldSettings.d.ts +24 -0
  30. package/dist/types/NormalizedPathFieldSettings.js +1 -0
  31. package/dist/types/NormalizedPathFieldSettings.js.map +1 -0
  32. package/dist/types/Path.d.ts +4 -3
  33. package/dist/types/PathFiltered.d.ts +4 -3
  34. package/dist/types/QuerySettings.d.ts +12 -17
  35. package/dist/types.d.ts +3 -1
  36. package/doc/README.md +5 -1
  37. package/doc/classes/RequestError.md +5 -5
  38. package/doc/functions/aggregate.md +1 -1
  39. package/doc/functions/branch.md +1 -1
  40. package/doc/functions/cache.md +1 -1
  41. package/doc/functions/combine.md +1 -1
  42. package/doc/functions/comparatorFieldValues.md +33 -0
  43. package/doc/functions/cork.md +1 -1
  44. package/doc/functions/defineCheckQuery.md +1 -1
  45. package/doc/functions/defineCustomFetch.md +1 -1
  46. package/doc/functions/defineGenericFetch.md +1 -1
  47. package/doc/functions/escapeRegex.md +1 -1
  48. package/doc/functions/fetchExternal.md +1 -1
  49. package/doc/functions/fetchLocal.md +1 -1
  50. package/doc/functions/fieldListFromFilter.md +1 -1
  51. package/doc/functions/filterChildren.md +1 -1
  52. package/doc/functions/filterFromValue.md +1 -1
  53. package/doc/functions/get.md +2 -2
  54. package/doc/functions/groupFilters.md +1 -1
  55. package/doc/functions/identity.md +1 -1
  56. package/doc/functions/intrinsicFilter.md +1 -1
  57. package/doc/functions/isFilterGroup.md +1 -1
  58. package/doc/functions/log.md +1 -1
  59. package/doc/functions/normalizeOrder.md +1 -1
  60. package/doc/functions/queryItemList.md +1 -1
  61. package/doc/functions/querySettings.md +33 -0
  62. package/doc/functions/retry.md +1 -1
  63. package/doc/functions/reverseOrder.md +1 -1
  64. package/doc/functions/sameField.md +1 -1
  65. package/doc/functions/sortItemList.md +2 -2
  66. package/doc/functions/splitPath.md +2 -2
  67. package/doc/functions/testFilter.md +1 -1
  68. package/doc/functions/transformerFilterChildren.md +2 -2
  69. package/doc/interfaces/CustomFetch.md +1 -1
  70. package/doc/type-aliases/AggregateFunction.md +1 -1
  71. package/doc/type-aliases/AggregateFunctionOperator.md +1 -1
  72. package/doc/type-aliases/CombineUnion.md +2 -2
  73. package/doc/type-aliases/Context.md +1 -1
  74. package/doc/type-aliases/CustomFieldAggregateMap.md +1 -1
  75. package/doc/type-aliases/CustomFieldMap.md +1 -1
  76. package/doc/type-aliases/Decrement.md +17 -0
  77. package/doc/type-aliases/DepthLimit.md +13 -0
  78. package/doc/type-aliases/Field.md +1 -1
  79. package/doc/type-aliases/FieldFiltered.md +1 -1
  80. package/doc/type-aliases/FieldFunction.md +1 -1
  81. package/doc/type-aliases/FieldFunctionCustom.md +1 -1
  82. package/doc/type-aliases/FieldFunctionFormatDate.md +1 -1
  83. package/doc/type-aliases/FieldFunctionReturn.md +1 -1
  84. package/doc/type-aliases/FieldKey.md +2 -2
  85. package/doc/type-aliases/FieldMap.md +1 -1
  86. package/doc/type-aliases/Filter.md +1 -1
  87. package/doc/type-aliases/FilterArray.md +1 -1
  88. package/doc/type-aliases/FilterBoolean.md +1 -1
  89. package/doc/type-aliases/FilterChildren.md +1 -1
  90. package/doc/type-aliases/FilterCustom.md +1 -1
  91. package/doc/type-aliases/FilterField.md +1 -1
  92. package/doc/type-aliases/FilterGroup.md +1 -1
  93. package/doc/type-aliases/FilterNumber.md +1 -1
  94. package/doc/type-aliases/FilterOperator.md +1 -1
  95. package/doc/type-aliases/FilterString.md +1 -1
  96. package/doc/type-aliases/FilterStringIntersect.md +1 -1
  97. package/doc/type-aliases/FilterStringMatch.md +1 -1
  98. package/doc/type-aliases/Get.md +5 -3
  99. package/doc/type-aliases/Group.md +1 -1
  100. package/doc/type-aliases/Handler.md +1 -1
  101. package/doc/type-aliases/Immutable.md +1 -1
  102. package/doc/type-aliases/InjectCustomFields.md +1 -1
  103. package/doc/type-aliases/IntersectUnion.md +1 -1
  104. package/doc/type-aliases/IntrinsicFilter.md +1 -1
  105. package/doc/type-aliases/Item.md +1 -1
  106. package/doc/type-aliases/Join.md +1 -1
  107. package/doc/type-aliases/Key.md +1 -1
  108. package/doc/type-aliases/KeyFiltered.md +2 -2
  109. package/doc/type-aliases/KeyFromUnion.md +1 -1
  110. package/doc/type-aliases/Locale.md +1 -1
  111. package/doc/type-aliases/NextHandler.md +1 -1
  112. package/doc/type-aliases/NormalizedPathFieldSettings.md +57 -0
  113. package/doc/type-aliases/Order.md +1 -1
  114. package/doc/type-aliases/OrderNormalized.md +1 -1
  115. package/doc/type-aliases/Parameters.md +1 -1
  116. package/doc/type-aliases/Path.md +3 -3
  117. package/doc/type-aliases/PathFiltered.md +3 -3
  118. package/doc/type-aliases/Primitive.md +1 -1
  119. package/doc/type-aliases/PrimitiveObject.md +1 -1
  120. package/doc/type-aliases/Query.md +1 -1
  121. package/doc/type-aliases/QueryAggregate.md +1 -1
  122. package/doc/type-aliases/QueryCreate.md +1 -1
  123. package/doc/type-aliases/QueryCreateMultiple.md +1 -1
  124. package/doc/type-aliases/QueryDelete.md +1 -1
  125. package/doc/type-aliases/QueryDeleteMultiple.md +1 -1
  126. package/doc/type-aliases/QueryMethod.md +1 -1
  127. package/doc/type-aliases/QueryRead.md +1 -1
  128. package/doc/type-aliases/QueryReadMultiple.md +1 -1
  129. package/doc/type-aliases/QuerySettings.md +36 -30
  130. package/doc/type-aliases/QueryUpdate.md +1 -1
  131. package/doc/type-aliases/QueryUpdateMultiple.md +1 -1
  132. package/doc/type-aliases/Result.md +1 -1
  133. package/doc/type-aliases/Store.md +1 -1
  134. package/doc/type-aliases/Value.md +1 -1
  135. package/doc/type-aliases/ValueMap.md +1 -1
  136. package/doc/variables/CACHE.md +1 -1
  137. package/doc/variables/FILTER_ANY.md +1 -1
  138. package/doc/variables/FILTER_NONE.md +1 -1
  139. package/doc/variables/SELF.md +1 -1
  140. package/lib/tools/comparatorFieldValues.ts +46 -0
  141. package/lib/tools/get.ts +9 -4
  142. package/lib/tools/querySettings.ts +20 -0
  143. package/lib/tools/sortItemList.test.ts +31 -8
  144. package/lib/tools/sortItemList.ts +21 -41
  145. package/lib/tools/testFilter.test.ts +35 -12
  146. package/lib/tools/transformerFilterChildren.ts +3 -26
  147. package/lib/tools.ts +2 -0
  148. package/lib/types/CombineUnion.ts +12 -10
  149. package/lib/types/Decrement.ts +5 -0
  150. package/lib/types/DepthLimit.ts +1 -0
  151. package/lib/types/FieldKey.ts +6 -1
  152. package/lib/types/Get.ts +17 -9
  153. package/lib/types/KeyFiltered.ts +14 -10
  154. package/lib/types/NormalizedPathFieldSettings.ts +25 -0
  155. package/lib/types/Path.ts +18 -15
  156. package/lib/types/PathFiltered.ts +20 -17
  157. package/lib/types/QuerySettings.ts +16 -17
  158. package/lib/types.ts +3 -1
  159. package/package.json +2 -2
  160. package/dist/types/Increment.d.ts +0 -4
  161. package/dist/types/Increment.js +0 -1
  162. package/dist/types/Increment.js.map +0 -1
  163. package/doc/type-aliases/Increment.md +0 -17
  164. package/lib/types/Increment.ts +0 -5
@@ -1,73 +1,53 @@
1
+ import { EMPTY_OBJECT } from "unchangeable";
2
+
1
3
  import type { Order, QuerySettings } from "../types";
2
4
 
3
- import { escapeRegex } from "./escapeRegex.js";
4
5
  import { get } from "./get.js";
5
6
  import { normalizeOrder } from "./normalizeOrder.js";
6
- import { sameField } from "./sameField.js";
7
7
 
8
8
  /**
9
9
  * Sorts provided `value` array according to the `orderList`.
10
10
  *
11
- * @param orderList The order to use for sorting.
12
- * @param value The array to sort.
13
- * @param settings Optional query settings.
11
+ * @param orderList - The order to use for sorting.
12
+ * @param value - The array to sort.
13
+ * @param settings - Optional query settings.
14
14
  * @returns A new sorted array.
15
15
  */
16
16
  export function sortItemList<T>(
17
- orderList: readonly Order<T>[] | undefined,
17
+ orderList: NoInfer<readonly Order<T>[]> | undefined,
18
18
  value: readonly T[],
19
19
  settings?: QuerySettings<T>,
20
20
  ) {
21
- const {
22
- pathField,
23
- pathFieldSeparator = "/",
24
- pathFieldSeparatorEscape,
25
- } = settings ?? {};
26
21
  if (orderList === undefined || orderList.length === 0) {
27
22
  return value;
28
23
  }
24
+ const { compareFieldValues } = settings ?? EMPTY_OBJECT;
29
25
  const normalizedOrder = orderList.map(normalizeOrder);
30
- const fieldSeparatorRegexp =
31
- pathField == null || pathFieldSeparator == null
32
- ? null
33
- : new RegExp(
34
- !pathFieldSeparatorEscape
35
- ? escapeRegex(pathFieldSeparator)
36
- : `(?<!${escapeRegex(pathFieldSeparatorEscape)})${escapeRegex(pathFieldSeparator)}`,
37
- "g",
38
- );
39
26
  return value.toSorted((a, b) => {
40
27
  for (let index = 0; index < normalizedOrder.length; index++) {
41
28
  const { field, descending } = normalizedOrder[index]!;
42
- const valueA = get(a, field as any);
43
- const valueB = get(b, field as any);
29
+ const valueA = get(a, field);
30
+ const valueB = get(b, field);
44
31
  if (valueA === valueB) {
45
32
  continue;
46
33
  }
47
- if (fieldSeparatorRegexp != null && sameField(field, pathField!)) {
48
- if (valueA == null) {
49
- return valueB == null ? 0 : descending ? 1 : -1;
50
- }
51
- if (valueB == null) {
52
- return descending ? -1 : 1;
53
- }
54
- const normalizedA = (valueA as string).replaceAll(
55
- fieldSeparatorRegexp,
56
- "\x00",
57
- );
58
- const normalizedB = (valueB as string).replaceAll(
59
- fieldSeparatorRegexp,
60
- "\x00",
61
- );
62
- if (normalizedA > normalizedB) {
34
+ if (valueA == null) {
35
+ return valueB == null ? 0 : descending ? 1 : -1;
36
+ }
37
+ if (valueB == null) {
38
+ return descending ? -1 : 1;
39
+ }
40
+ const comparison = compareFieldValues?.(field, valueA, valueB);
41
+ if (comparison === undefined) {
42
+ if (valueA > valueB) {
63
43
  return descending ? -1 : 1;
64
44
  }
65
45
  return descending ? 1 : -1;
66
46
  }
67
- if (valueA > valueB) {
68
- return descending ? -1 : 1;
47
+ if (comparison === 0) {
48
+ continue;
69
49
  }
70
- return descending ? 1 : -1;
50
+ return descending ? -comparison : comparison;
71
51
  }
72
52
  return 0;
73
53
  });
@@ -5,6 +5,7 @@ import { SELF } from "../constants.js";
5
5
  import type { FilterChildren } from "../types.js";
6
6
 
7
7
  import { filterFromValue } from "./filterFromValue.js";
8
+ import { querySettings } from "./querySettings.js";
8
9
  import { testFilter } from "./testFilter.js";
9
10
 
10
11
  test("tests filter lists", () => {
@@ -360,27 +361,37 @@ test("tests filter with children predicates", () => {
360
361
  { id: "a" },
361
362
  ),
362
363
  ).toBe(true);
364
+
365
+ // Always true if `transformFilterChildren` is not provided, to avoid false negatives
363
366
  expect(
364
367
  testFilter({ operator: "notChildren", value: { id: "a" } }, { id: "a/b" }),
368
+ ).toBe(true);
369
+ expect(
370
+ testFilter(
371
+ { operator: "notChildren", value: { id: "a" } },
372
+ { id: "a/b" },
373
+ querySettings({ pathField: "id" }),
374
+ ),
365
375
  ).toBe(false);
376
+
366
377
  expect(
367
378
  testFilter(
368
379
  { operator: "children", value: { path: ".a" } },
369
380
  { path: ".a.b" },
370
- {
381
+ querySettings({
371
382
  pathField: "path",
372
383
  pathFieldSeparator: ".",
373
- },
384
+ }),
374
385
  ),
375
386
  ).toBe(true);
376
387
  expect(
377
388
  testFilter(
378
389
  { operator: "notChildren", value: { path: ".a" } },
379
390
  { path: ".a.b" },
380
- {
391
+ querySettings({
381
392
  pathField: "path",
382
393
  pathFieldSeparator: ".",
383
- },
394
+ }),
384
395
  ),
385
396
  ).toBe(false);
386
397
  const filterChildren: FilterChildren<{ path: string }> = {
@@ -397,7 +408,7 @@ test("tests filter with children predicates", () => {
397
408
  field: "path",
398
409
  operator: "startWith",
399
410
  value: `.${filter.value?.path}.`,
400
- };
411
+ } as const;
401
412
  },
402
413
  },
403
414
  ),
@@ -415,36 +426,48 @@ test("tests filter with children predicates", () => {
415
426
  field: "path",
416
427
  operator: "startWith",
417
428
  value: `.${filter.value?.path}.`,
418
- };
429
+ } as const;
419
430
  },
420
431
  },
421
432
  ),
422
433
  ).toBe(true);
423
434
  expect(filterChildren[CACHE]).toBeDefined();
424
435
  expect(
425
- testFilter({ operator: "children", value: { id: "b" } }, { id: "a/b" }),
436
+ testFilter(
437
+ { operator: "children", value: { id: "b" } },
438
+ { id: "a/b" },
439
+ querySettings({
440
+ pathField: "id",
441
+ }),
442
+ ),
426
443
  ).toBe(false);
427
444
  expect(
428
- testFilter({ operator: "notChildren", value: { id: "b" } }, { id: "a/b" }),
445
+ testFilter(
446
+ { operator: "notChildren", value: { id: "b" } },
447
+ { id: "a/b" },
448
+ querySettings({
449
+ pathField: "id",
450
+ }),
451
+ ),
429
452
  ).toBe(true);
430
453
  expect(
431
454
  testFilter(
432
455
  { operator: "children", value: { path: "ba" } },
433
456
  { path: ".a.b" },
434
- {
457
+ querySettings({
435
458
  pathField: "path",
436
459
  pathFieldSeparator: ".",
437
- },
460
+ }),
438
461
  ),
439
462
  ).toBe(false);
440
463
  expect(
441
464
  testFilter(
442
465
  { operator: "notChildren", value: { path: "ba" } },
443
466
  { path: ".a.b" },
444
- {
467
+ querySettings({
445
468
  pathField: "path",
446
469
  pathFieldSeparator: ".",
447
- },
470
+ }),
448
471
  ),
449
472
  ).toBe(true);
450
473
  });
@@ -4,32 +4,12 @@ import type {
4
4
  FieldFiltered,
5
5
  FilterChildren,
6
6
  FilterStringMatch,
7
+ NormalizedPathFieldSettings,
7
8
  } from "../types";
8
9
 
9
10
  import { filterChildren } from "./filterChildren.js";
10
11
  import { get } from "./get.js";
11
12
 
12
- export type TransformerFilterChildrenOptions<T> = {
13
- /**
14
- * Path to the field that contains the path value of an item, used for displaying items in a tree.
15
- *
16
- * @default "path"
17
- */
18
- pathField?: FieldFiltered<T, string>;
19
- /**
20
- * String used to escape the separator.
21
- *
22
- * @default "\\"
23
- */
24
- pathFieldSeparatorEscape?: string;
25
- /**
26
- * Maps path fields to a string used to separate the path nodes of a field value.
27
- *
28
- * @default "/"
29
- */
30
- pathFieldSeparator?: string;
31
- };
32
-
33
13
  /**
34
14
  * Returns a function that transforms a `FilterChildren` into a `FilterStringMatch`.
35
15
  *
@@ -39,13 +19,10 @@ export type TransformerFilterChildrenOptions<T> = {
39
19
  export function transformerFilterChildren<T>({
40
20
  pathField = "path" as FieldFiltered<T, string>,
41
21
  pathFieldSeparator = "/",
42
- }: TransformerFilterChildrenOptions<T> = EMPTY_OBJECT) {
22
+ }: NormalizedPathFieldSettings<T> = EMPTY_OBJECT) {
43
23
  return (filter: FilterChildren<T>): FilterStringMatch<T> => {
44
24
  const { value, minDepth = 1, maxDepth = Infinity } = filter;
45
- if (value === undefined) {
46
- throw new Error("FilterChildren must have a value");
47
- }
48
- const parentPath = get(value, pathField as any) as string;
25
+ const parentPath = (get(value, pathField as any) ?? "") as string;
49
26
  return filterChildren(
50
27
  parentPath,
51
28
  pathField,
package/lib/tools.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  // File automatically generated by `vite-plugin-module-list`
2
+ export { comparatorFieldValues } from "./tools/comparatorFieldValues.js";
2
3
  export { cork } from "./tools/cork.js";
3
4
  export { defineCheckQuery } from "./tools/defineCheckQuery.js";
4
5
  export { defineCustomFetch } from "./tools/defineCustomFetch.js";
@@ -13,6 +14,7 @@ export { intrinsicFilter } from "./tools/intrinsicFilter.js";
13
14
  export { isFilterGroup } from "./tools/isFilterGroup.js";
14
15
  export { normalizeOrder } from "./tools/normalizeOrder.js";
15
16
  export { queryItemList } from "./tools/queryItemList.js";
17
+ export { querySettings } from "./tools/querySettings.js";
16
18
  export { reverseOrder } from "./tools/reverseOrder.js";
17
19
  export { sameField } from "./tools/sameField.js";
18
20
  export { sortItemList } from "./tools/sortItemList.js";
@@ -1,17 +1,19 @@
1
1
  import type { KeyFromUnion } from "./KeyFromUnion";
2
2
  import type { Primitive } from "./Primitive";
3
3
 
4
- export type CombineUnion<U> = [0] extends [1 & U]
5
- ? any
6
- : [U] extends [Function | readonly Function[]]
7
- ? undefined
8
- : [U] extends [Primitive]
9
- ? U
10
- : [U] extends readonly [Array<any>]
4
+ export type CombineUnion<U> = [unknown] extends [U]
5
+ ? unknown
6
+ : [0] extends [1 & U]
7
+ ? any
8
+ : [U] extends [Function | readonly Function[]]
9
+ ? undefined
10
+ : [U] extends [Primitive]
11
11
  ? U
12
- : {
13
- [K in KeyFromUnion<U>]: Continue<Combine<U, K>>;
14
- };
12
+ : [U] extends readonly [Array<any>]
13
+ ? U
14
+ : {
15
+ [K in KeyFromUnion<U>]: Continue<Combine<U, K>>;
16
+ };
15
17
 
16
18
  type Combine<U, K extends string | number | symbol> = Exclude<
17
19
  Extract<U, { [k in K]?: any }>[K],
@@ -0,0 +1,5 @@
1
+ type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
2
+
3
+ type NextDigit = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
4
+
5
+ export type Decrement<D> = D extends Digit ? NextDigit[D] : -1;
@@ -0,0 +1 @@
1
+ export type DepthLimit = 4;
@@ -1,5 +1,10 @@
1
1
  import type { SELF } from "../constants/SELF.ts";
2
2
 
3
+ import type { Key } from "./Key.ts";
3
4
  import type { Primitive } from "./Primitive";
4
5
 
5
- export type FieldKey<T> = T extends Primitive ? typeof SELF : keyof T;
6
+ export type FieldKey<T> = T extends Primitive
7
+ ? typeof SELF
8
+ : [unknown] extends [T]
9
+ ? Key
10
+ : keyof T;
package/lib/types/Get.ts CHANGED
@@ -1,14 +1,22 @@
1
+ import type { Decrement } from "./Decrement";
2
+ import type { DepthLimit } from "./DepthLimit";
1
3
  import type { Path } from "./Path";
2
4
 
3
5
  /**
4
6
  * Returns the type of the property at the specified `P` path.
5
7
  */
6
- export type Get<T, P> = [P] extends [readonly [infer K, ...infer R]]
7
- ? K extends keyof T
8
- ? R extends Path<T[K]>
9
- ? Get<T[K], R>
10
- : T[K]
11
- : never
12
- : [P] extends [keyof T]
13
- ? T[P]
14
- : T;
8
+ export type Get<T, P, D = DepthLimit> = [unknown] extends [T]
9
+ ? unknown
10
+ : [0] extends [1 & T]
11
+ ? any
12
+ : D extends -1
13
+ ? any
14
+ : [P] extends [readonly [infer K, ...infer R]]
15
+ ? K extends keyof T
16
+ ? R extends Path<T[K]>
17
+ ? Get<T[K], R, Decrement<D>>
18
+ : T[K]
19
+ : never
20
+ : [P] extends [keyof T]
21
+ ? T[P]
22
+ : T;
@@ -7,14 +7,18 @@ type SymbolSelf = typeof SELF;
7
7
  /**
8
8
  * Returns union of keys whose mapped value extend the provided `P` type.
9
9
  */
10
- export type KeyFiltered<T, P> = [0] extends [1 & T]
10
+ export type KeyFiltered<T, P> = [unknown] extends [T]
11
11
  ? Key | SymbolSelf
12
- : T extends string | number | boolean | bigint | symbol
13
- ? T extends P
14
- ? SymbolSelf
15
- : never
16
- : T extends object
17
- ? keyof {
18
- [K in keyof T as Extract<T[K], P> extends never ? never : K]-?: T[K];
19
- }
20
- : never;
12
+ : [0] extends [1 & T]
13
+ ? Key | SymbolSelf
14
+ : T extends string | number | boolean | bigint | symbol
15
+ ? T extends P
16
+ ? SymbolSelf
17
+ : never
18
+ : T extends object
19
+ ? keyof {
20
+ [K in keyof T as Extract<T[K], P> extends never
21
+ ? never
22
+ : K]-?: T[K];
23
+ }
24
+ : never;
@@ -0,0 +1,25 @@
1
+ import type { FieldFiltered } from "./FieldFiltered";
2
+
3
+ /**
4
+ * Settings for fields that contain path values of items, used for displaying items in a tree.
5
+ */
6
+ export type NormalizedPathFieldSettings<T> = {
7
+ /**
8
+ * Path to the field that contains the path value of an item, used for displaying items in a tree.
9
+ *
10
+ * @default "path"
11
+ */
12
+ pathField?: FieldFiltered<T, string>;
13
+ /**
14
+ * String used to escape the separator.
15
+ *
16
+ * @default "\\"
17
+ */
18
+ pathFieldSeparatorEscape?: string;
19
+ /**
20
+ * Maps path fields to a string used to separate the path nodes of a field value.
21
+ *
22
+ * @default "/"
23
+ */
24
+ pathFieldSeparator?: string;
25
+ };
package/lib/types/Path.ts CHANGED
@@ -1,19 +1,22 @@
1
- import type { Increment } from "./Increment";
1
+ import type { Decrement } from "./Decrement";
2
+ import type { DepthLimit } from "./DepthLimit";
2
3
  import type { Key } from "./Key";
3
4
  import type { Primitive } from "./Primitive";
4
5
 
5
- export type Path<T, D = 7> = [0] extends [1 & T]
6
+ export type Path<T, D = DepthLimit> = [unknown] extends [T]
6
7
  ? readonly (Key | never)[]
7
- : D extends -1
8
- ? never
9
- : T extends Primitive
10
- ? readonly never[]
11
- : T extends Array<infer P>
12
- ? readonly [number] | readonly [number, ...Path<P, Increment<D>>]
13
- : T extends object
14
- ? {
15
- [K in keyof T]:
16
- | readonly [K]
17
- | readonly [K, ...Path<T[K], Increment<D>>];
18
- }[keyof T]
19
- : never;
8
+ : [0] extends [1 & T]
9
+ ? readonly (Key | never)[]
10
+ : D extends -1
11
+ ? never
12
+ : T extends Primitive
13
+ ? readonly never[]
14
+ : T extends Array<infer P>
15
+ ? readonly [number] | readonly [number, ...Path<P, Decrement<D>>]
16
+ : T extends object
17
+ ? {
18
+ [K in keyof T]:
19
+ | readonly [K]
20
+ | readonly [K, ...Path<T[K], Decrement<D>>];
21
+ }[keyof T]
22
+ : never;
@@ -1,20 +1,23 @@
1
- import type { Increment } from "./Increment";
1
+ import type { Decrement } from "./Decrement";
2
+ import type { DepthLimit } from "./DepthLimit";
2
3
  import type { Key } from "./Key";
3
4
 
4
- export type PathFiltered<T, P, D = 7> = [0] extends [1 & T]
5
+ export type PathFiltered<T, P, D = DepthLimit> = [unknown] extends [T]
5
6
  ? readonly (Key | never)[]
6
- : D extends -1
7
- ? never
8
- : T extends P
9
- ? readonly never[]
10
- : T extends ReadonlyArray<infer I>
11
- ? Extract<I, P> extends never
12
- ? readonly [number, ...PathFiltered<I, P, Increment<D>>]
13
- : readonly [number]
14
- : T extends object
15
- ? {
16
- [K in keyof T]: Extract<T[K], P> extends never
17
- ? readonly [K, ...PathFiltered<T[K], P, Increment<D>>]
18
- : readonly [K];
19
- }[keyof T]
20
- : never;
7
+ : [0] extends [1 & T]
8
+ ? readonly (Key | never)[]
9
+ : D extends -1
10
+ ? never
11
+ : T extends P
12
+ ? readonly never[]
13
+ : T extends ReadonlyArray<infer I>
14
+ ? Extract<I, P> extends never
15
+ ? readonly [number, ...PathFiltered<I, P, Decrement<D>>]
16
+ : readonly [number]
17
+ : T extends object
18
+ ? {
19
+ [K in keyof T]: Extract<T[K], P> extends never
20
+ ? readonly [K, ...PathFiltered<T[K], P, Decrement<D>>]
21
+ : readonly [K];
22
+ }[keyof T]
23
+ : never;
@@ -1,4 +1,4 @@
1
- import type { FieldFiltered } from "./FieldFiltered";
1
+ import type { Field } from "./Field";
2
2
  import type { FilterChildren } from "./FilterChildren";
3
3
  import type { IntrinsicFilter } from "./IntrinsicFilter";
4
4
 
@@ -6,22 +6,6 @@ import type { IntrinsicFilter } from "./IntrinsicFilter";
6
6
  * Settings to use when doing a query.
7
7
  */
8
8
  export type QuerySettings<T> = {
9
- /**
10
- * Path to the field that contains the path value of an item, used for displaying items in a tree.
11
- */
12
- pathField?: FieldFiltered<T, string>;
13
- /**
14
- * String used to escape the separator.
15
- *
16
- * @default "\\"
17
- */
18
- pathFieldSeparatorEscape?: string;
19
- /**
20
- * Maps path fields to a string used to separate the path nodes of a field value.
21
- *
22
- * @default "/"
23
- */
24
- pathFieldSeparator?: string;
25
9
  /**
26
10
  * Returns a filter that captures the items expressed by the provided `FilterChildren`. The return filter cannot use filters of type `FilterChildren` or `FilterContext`.
27
11
  *
@@ -29,6 +13,21 @@ export type QuerySettings<T> = {
29
13
  * @returns A filter that captures the items expressed by the provided `FilterChildren`.
30
14
  */
31
15
  transformFilterChildren?: (filter: FilterChildren<T>) => IntrinsicFilter<T>;
16
+ /**
17
+ * Compares two values of a field for sorting purposes. If not provided, values are compared using the default comparison operators (`>`, `<`, `===`).
18
+ *
19
+ * This function is called only when both `a` and `b` are defined and different. If it returns `undefined`, the default comparison operators are used as a fallback.
20
+ *
21
+ * @param a - The first value to compare.
22
+ * @param b - The second value to compare.
23
+ * @param field - The field for which the values are compared.
24
+ * @returns `-1` if `a` should be sorted before `b`, `1` if `a` should be sorted after `b`, `0` if they are considered equal, or `undefined` to use the default comparison operators.
25
+ */
26
+ compareFieldValues?<T>(
27
+ field: Field<T>,
28
+ a: NonNullable<any>,
29
+ b: NonNullable<any>,
30
+ ): -1 | 0 | 1 | undefined;
32
31
  /**
33
32
  * Abort signal to abort the query.
34
33
  */
package/lib/types.ts CHANGED
@@ -6,6 +6,8 @@ export type { Context } from "./types/Context";
6
6
  export type { CustomFetch } from "./types/CustomFetch";
7
7
  export type { CustomFieldAggregateMap } from "./types/CustomFieldAggregateMap";
8
8
  export type { CustomFieldMap } from "./types/CustomFieldMap";
9
+ export type { Decrement } from "./types/Decrement";
10
+ export type { DepthLimit } from "./types/DepthLimit";
9
11
  export type { Field } from "./types/Field";
10
12
  export type { FieldFiltered } from "./types/FieldFiltered";
11
13
  export type { FieldFunction } from "./types/FieldFunction";
@@ -30,7 +32,6 @@ export type { Get } from "./types/Get";
30
32
  export type { Group } from "./types/Group";
31
33
  export type { Handler } from "./types/Handler";
32
34
  export type { Immutable } from "./types/Immutable";
33
- export type { Increment } from "./types/Increment";
34
35
  export type { InjectCustomFields } from "./types/InjectCustomFields";
35
36
  export type { IntersectUnion } from "./types/IntersectUnion";
36
37
  export type { IntrinsicFilter } from "./types/IntrinsicFilter";
@@ -41,6 +42,7 @@ export type { KeyFiltered } from "./types/KeyFiltered";
41
42
  export type { KeyFromUnion } from "./types/KeyFromUnion";
42
43
  export type { Locale } from "./types/Locale";
43
44
  export type { NextHandler } from "./types/NextHandler";
45
+ export type { NormalizedPathFieldSettings } from "./types/NormalizedPathFieldSettings";
44
46
  export type { Order } from "./types/Order";
45
47
  export type { OrderNormalized } from "./types/OrderNormalized";
46
48
  export type { Parameters } from "./types/Parameters";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quetch",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "type": "module",
5
5
  "main": "./dist/main.js",
6
6
  "exports": {
@@ -39,7 +39,7 @@
39
39
  "lint": "npm run lint:ts",
40
40
  "lint:fix": "npm run lint:ts:fix",
41
41
  "lint:ts": "eslint . && tsc --project tsconfig.package.json --noEmit",
42
- "lint:types": "tsc --project tsconfig.package.json --noEmit",
42
+ "lint:types:trace": "tsc --project tsconfig.package.json --noEmit --generateTrace ./trace",
43
43
  "lint:ts:fix": "eslint --fix .",
44
44
  "release:init": "npm publish --access=public",
45
45
  "release:patch": "npm version patch && git push origin --follow-tags && npm publish",
@@ -1,4 +0,0 @@
1
- type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
2
- type NextDigit = [1, 2, 3, 4, 5, 6, 7, 8, 9, -1];
3
- export type Increment<D> = D extends Digit ? NextDigit[D] : -1;
4
- export {};
@@ -1 +0,0 @@
1
- //# sourceMappingURL=Increment.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Increment.js","sourceRoot":"","sources":["../../lib/types/Increment.ts"],"names":[],"mappings":""}
@@ -1,17 +0,0 @@
1
- [**quetch**](../README.md)
2
-
3
- ***
4
-
5
- [quetch](../README.md) / Increment
6
-
7
- # Type Alias: Increment\<D\>
8
-
9
- > **Increment**\<`D`\>: `D` *extends* `Digit` ? `NextDigit`\[`D`\] : `-1`
10
-
11
- ## Type Parameters
12
-
13
- • **D**
14
-
15
- ## Defined in
16
-
17
- [lib/types/Increment.ts:5](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/types/Increment.ts#L5)
@@ -1,5 +0,0 @@
1
- type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
2
-
3
- type NextDigit = [1, 2, 3, 4, 5, 6, 7, 8, 9, -1];
4
-
5
- export type Increment<D> = D extends Digit ? NextDigit[D] : -1;