quetch 0.29.0 → 0.30.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 (129) hide show
  1. package/dist/tools/intrinsicFilter.d.ts +9 -0
  2. package/dist/tools/intrinsicFilter.js +24 -0
  3. package/dist/tools/intrinsicFilter.js.map +1 -0
  4. package/dist/tools/queryItemList.js +2 -2
  5. package/dist/tools/queryItemList.js.map +1 -1
  6. package/dist/tools/testFilter.d.ts +1 -1
  7. package/dist/tools/testFilter.js +6 -9
  8. package/dist/tools/testFilter.js.map +1 -1
  9. package/dist/tools/transformerFilterChildren.d.ts +28 -0
  10. package/dist/tools/transformerFilterChildren.js +20 -0
  11. package/dist/tools/transformerFilterChildren.js.map +1 -0
  12. package/dist/tools.d.ts +2 -0
  13. package/dist/tools.js +2 -0
  14. package/dist/tools.js.map +1 -1
  15. package/dist/types/AggregateFunction.d.ts +1 -1
  16. package/dist/types/Context.d.ts +8 -0
  17. package/dist/types/FilterChildren.d.ts +1 -2
  18. package/dist/types/FilterGroup.d.ts +2 -2
  19. package/doc/README.md +2 -0
  20. package/doc/classes/RequestError.md +5 -5
  21. package/doc/functions/aggregate.md +1 -1
  22. package/doc/functions/branch.md +1 -1
  23. package/doc/functions/cache.md +1 -1
  24. package/doc/functions/combine.md +1 -1
  25. package/doc/functions/cork.md +1 -1
  26. package/doc/functions/defineCheckQuery.md +1 -1
  27. package/doc/functions/defineCustomFetch.md +1 -1
  28. package/doc/functions/defineGenericFetch.md +1 -1
  29. package/doc/functions/escapeRegex.md +1 -1
  30. package/doc/functions/fetchExternal.md +1 -1
  31. package/doc/functions/fetchLocal.md +1 -1
  32. package/doc/functions/fieldListFromFilter.md +1 -1
  33. package/doc/functions/filterChildren.md +1 -1
  34. package/doc/functions/filterFromValue.md +1 -1
  35. package/doc/functions/get.md +1 -1
  36. package/doc/functions/groupFilters.md +1 -1
  37. package/doc/functions/identity.md +1 -1
  38. package/doc/functions/intrinsicFilter.md +39 -0
  39. package/doc/functions/isFilterGroup.md +1 -1
  40. package/doc/functions/log.md +1 -1
  41. package/doc/functions/normalizeOrder.md +1 -1
  42. package/doc/functions/queryItemList.md +1 -1
  43. package/doc/functions/retry.md +1 -1
  44. package/doc/functions/reverseOrder.md +1 -1
  45. package/doc/functions/sameField.md +1 -1
  46. package/doc/functions/sortItemList.md +1 -1
  47. package/doc/functions/splitPath.md +2 -2
  48. package/doc/functions/testFilter.md +2 -2
  49. package/doc/functions/transformerFilterChildren.md +43 -0
  50. package/doc/interfaces/CustomFetch.md +1 -1
  51. package/doc/type-aliases/AggregateFunction.md +2 -2
  52. package/doc/type-aliases/AggregateFunctionOperator.md +1 -1
  53. package/doc/type-aliases/CombineUnion.md +1 -1
  54. package/doc/type-aliases/Context.md +8 -1
  55. package/doc/type-aliases/CustomFieldAggregateMap.md +1 -1
  56. package/doc/type-aliases/CustomFieldMap.md +1 -1
  57. package/doc/type-aliases/Field.md +1 -1
  58. package/doc/type-aliases/FieldFiltered.md +1 -1
  59. package/doc/type-aliases/FieldFunction.md +1 -1
  60. package/doc/type-aliases/FieldFunctionCustom.md +1 -1
  61. package/doc/type-aliases/FieldFunctionFormatDate.md +1 -1
  62. package/doc/type-aliases/FieldFunctionReturn.md +1 -1
  63. package/doc/type-aliases/FieldKey.md +1 -1
  64. package/doc/type-aliases/FieldMap.md +1 -1
  65. package/doc/type-aliases/Filter.md +1 -1
  66. package/doc/type-aliases/FilterArray.md +1 -1
  67. package/doc/type-aliases/FilterBoolean.md +1 -1
  68. package/doc/type-aliases/FilterChildren.md +2 -2
  69. package/doc/type-aliases/FilterCustom.md +1 -1
  70. package/doc/type-aliases/FilterField.md +1 -1
  71. package/doc/type-aliases/FilterGroup.md +7 -7
  72. package/doc/type-aliases/FilterNumber.md +1 -1
  73. package/doc/type-aliases/FilterOperator.md +1 -1
  74. package/doc/type-aliases/FilterString.md +1 -1
  75. package/doc/type-aliases/FilterStringIntersect.md +1 -1
  76. package/doc/type-aliases/FilterStringMatch.md +1 -1
  77. package/doc/type-aliases/Get.md +1 -1
  78. package/doc/type-aliases/Group.md +1 -1
  79. package/doc/type-aliases/Handler.md +1 -1
  80. package/doc/type-aliases/Immutable.md +1 -1
  81. package/doc/type-aliases/Increment.md +1 -1
  82. package/doc/type-aliases/InjectCustomFields.md +1 -1
  83. package/doc/type-aliases/IntersectUnion.md +1 -1
  84. package/doc/type-aliases/IntrinsicFilter.md +1 -1
  85. package/doc/type-aliases/Item.md +1 -1
  86. package/doc/type-aliases/Join.md +1 -1
  87. package/doc/type-aliases/Key.md +1 -1
  88. package/doc/type-aliases/KeyFiltered.md +1 -1
  89. package/doc/type-aliases/KeyFromUnion.md +1 -1
  90. package/doc/type-aliases/Locale.md +1 -1
  91. package/doc/type-aliases/NextHandler.md +1 -1
  92. package/doc/type-aliases/Order.md +1 -1
  93. package/doc/type-aliases/OrderNormalized.md +1 -1
  94. package/doc/type-aliases/Parameters.md +1 -1
  95. package/doc/type-aliases/Path.md +1 -1
  96. package/doc/type-aliases/PathFiltered.md +1 -1
  97. package/doc/type-aliases/Primitive.md +1 -1
  98. package/doc/type-aliases/PrimitiveObject.md +1 -1
  99. package/doc/type-aliases/Query.md +1 -1
  100. package/doc/type-aliases/QueryAggregate.md +1 -1
  101. package/doc/type-aliases/QueryCreate.md +1 -1
  102. package/doc/type-aliases/QueryCreateMultiple.md +1 -1
  103. package/doc/type-aliases/QueryDelete.md +1 -1
  104. package/doc/type-aliases/QueryDeleteMultiple.md +1 -1
  105. package/doc/type-aliases/QueryMethod.md +1 -1
  106. package/doc/type-aliases/QueryRead.md +1 -1
  107. package/doc/type-aliases/QueryReadMultiple.md +1 -1
  108. package/doc/type-aliases/QuerySettings.md +1 -1
  109. package/doc/type-aliases/QueryUpdate.md +1 -1
  110. package/doc/type-aliases/QueryUpdateMultiple.md +1 -1
  111. package/doc/type-aliases/Result.md +1 -1
  112. package/doc/type-aliases/Store.md +1 -1
  113. package/doc/type-aliases/Value.md +1 -1
  114. package/doc/type-aliases/ValueMap.md +1 -1
  115. package/doc/variables/CACHE.md +1 -1
  116. package/doc/variables/FILTER_ANY.md +1 -1
  117. package/doc/variables/FILTER_NONE.md +1 -1
  118. package/doc/variables/SELF.md +1 -1
  119. package/lib/tools/intrinsicFilter.ts +30 -0
  120. package/lib/tools/queryItemList.ts +2 -2
  121. package/lib/tools/testFilter.test.ts +5 -5
  122. package/lib/tools/testFilter.ts +8 -25
  123. package/lib/tools/transformerFilterChildren.ts +57 -0
  124. package/lib/tools.ts +2 -0
  125. package/lib/types/AggregateFunction.ts +2 -2
  126. package/lib/types/Context.ts +8 -0
  127. package/lib/types/FilterChildren.ts +1 -2
  128. package/lib/types/FilterGroup.ts +2 -2
  129. package/package.json +1 -1
@@ -68,4 +68,4 @@
68
68
 
69
69
  ## Defined in
70
70
 
71
- [lib/types/Store.ts:2](https://github.com/nevoland/quetch/blob/439120295bc3ab3895611a5a04d7281d9d40fc45/lib/types/Store.ts#L2)
71
+ [lib/types/Store.ts:2](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/types/Store.ts#L2)
@@ -36,4 +36,4 @@ Path leading to the value.
36
36
 
37
37
  ## Defined in
38
38
 
39
- [lib/types/Value.ts:6](https://github.com/nevoland/quetch/blob/439120295bc3ab3895611a5a04d7281d9d40fc45/lib/types/Value.ts#L6)
39
+ [lib/types/Value.ts:6](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/types/Value.ts#L6)
@@ -18,4 +18,4 @@ Maps the properties of the provided value `T` to a specific value `V`.
18
18
 
19
19
  ## Defined in
20
20
 
21
- [lib/types/ValueMap.ts:6](https://github.com/nevoland/quetch/blob/439120295bc3ab3895611a5a04d7281d9d40fc45/lib/types/ValueMap.ts#L6)
21
+ [lib/types/ValueMap.ts:6](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/types/ValueMap.ts#L6)
@@ -10,4 +10,4 @@
10
10
 
11
11
  ## Defined in
12
12
 
13
- [lib/constants/CACHE.ts:1](https://github.com/nevoland/quetch/blob/439120295bc3ab3895611a5a04d7281d9d40fc45/lib/constants/CACHE.ts#L1)
13
+ [lib/constants/CACHE.ts:1](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/constants/CACHE.ts#L1)
@@ -16,4 +16,4 @@
16
16
 
17
17
  ## Defined in
18
18
 
19
- [lib/constants/FILTER\_ANY.ts:1](https://github.com/nevoland/quetch/blob/439120295bc3ab3895611a5a04d7281d9d40fc45/lib/constants/FILTER_ANY.ts#L1)
19
+ [lib/constants/FILTER\_ANY.ts:1](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/constants/FILTER_ANY.ts#L1)
@@ -16,4 +16,4 @@
16
16
 
17
17
  ## Defined in
18
18
 
19
- [lib/constants/FILTER\_NONE.ts:1](https://github.com/nevoland/quetch/blob/439120295bc3ab3895611a5a04d7281d9d40fc45/lib/constants/FILTER_NONE.ts#L1)
19
+ [lib/constants/FILTER\_NONE.ts:1](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/constants/FILTER_NONE.ts#L1)
@@ -10,4 +10,4 @@
10
10
 
11
11
  ## Defined in
12
12
 
13
- [lib/constants/SELF.ts:1](https://github.com/nevoland/quetch/blob/439120295bc3ab3895611a5a04d7281d9d40fc45/lib/constants/SELF.ts#L1)
13
+ [lib/constants/SELF.ts:1](https://github.com/nevoland/quetch/blob/94f546831241bf41f83cf97787b7e923c8cf7824/lib/constants/SELF.ts#L1)
@@ -0,0 +1,30 @@
1
+ import type { Filter, IntrinsicFilter, QuerySettings } from "../types";
2
+
3
+ /**
4
+ * Transforms a filter into an intrinsic filter by replacing `children` and `notChildren` filters with their transformed versions from the query settings.
5
+ *
6
+ * @param filter - The filter to transform.
7
+ * @param settings - The query settings that may contain a `transformFilterChildren` function to transform `children` and `notChildren` filters.
8
+ * @returns The transformed intrinsic filter.
9
+ */
10
+ export function intrinsicFilter<T>(
11
+ settings: Required<Pick<QuerySettings<T>, "transformFilterChildren">>,
12
+ filter: Filter<T>,
13
+ ): IntrinsicFilter<T> {
14
+ switch (filter.operator) {
15
+ case "any":
16
+ case "all":
17
+ case "none":
18
+ return {
19
+ ...filter,
20
+ value: filter.value?.map((filter) =>
21
+ intrinsicFilter(settings, filter),
22
+ ) as readonly Filter<T>[],
23
+ };
24
+ case "children":
25
+ case "notChildren":
26
+ return settings.transformFilterChildren(filter)!;
27
+ default:
28
+ return filter;
29
+ }
30
+ }
@@ -83,7 +83,7 @@ export function queryItemList<T, const Q extends Query<T>>(
83
83
  );
84
84
  }
85
85
  // Sort
86
- result = sortItemList(order, result, query.settings);
86
+ result = sortItemList(order, result, settings);
87
87
  // Slice
88
88
  if (offset !== 0 || limit !== Infinity) {
89
89
  result = result.slice(offset, offset + limit);
@@ -125,7 +125,7 @@ export function queryItemList<T, const Q extends Query<T>>(
125
125
  );
126
126
  }
127
127
  // Sort
128
- result = sortItemList(order, result, query.settings);
128
+ result = sortItemList(order, result, settings);
129
129
  // Slice
130
130
  if (offset !== 0 || limit !== Infinity) {
131
131
  result = result.slice(offset, offset + limit);
@@ -2,7 +2,7 @@ import { expect, test } from "vitest";
2
2
 
3
3
  import { CACHE } from "../constants/CACHE.js";
4
4
  import { SELF } from "../constants.js";
5
- import type { FilterChildren, FilterContext } from "../types.js";
5
+ import type { FilterChildren } from "../types.js";
6
6
 
7
7
  import { filterFromValue } from "./filterFromValue.js";
8
8
  import { testFilter } from "./testFilter.js";
@@ -77,7 +77,7 @@ test("tests filter lists", () => {
77
77
  { field: "a", operator: "equal", value: "foo" },
78
78
  { field: "c", operator: "equal", value: "baz" },
79
79
  ],
80
- minimum: 2,
80
+ min: 2,
81
81
  },
82
82
  { a: "foo", b: "bar", c: "baz" },
83
83
  ),
@@ -90,8 +90,8 @@ test("tests filter lists", () => {
90
90
  { field: "a", operator: "equal", value: "foo" },
91
91
  { field: "c", operator: "equal", value: "baz" },
92
92
  ],
93
- minimum: 1,
94
- maximum: 2,
93
+ min: 1,
94
+ max: 2,
95
95
  },
96
96
  { a: "foo", b: "bar", c: "baz" },
97
97
  ),
@@ -104,7 +104,7 @@ test("tests filter lists", () => {
104
104
  { field: "a", operator: "equal", value: "foo" },
105
105
  { field: "c", operator: "equal", value: "baz" },
106
106
  ],
107
- maximum: 1,
107
+ max: 1,
108
108
  },
109
109
  { a: "foo", b: "bar", c: "baz" },
110
110
  ),
@@ -1,16 +1,7 @@
1
- import { EMPTY_OBJECT } from "unchangeable";
2
-
3
1
  import { CACHE } from "../constants/CACHE.js";
4
2
  import type { QuerySettings } from "../types/QuerySettings.js";
5
- import type {
6
- Context,
7
- FieldFiltered,
8
- Filter,
9
- FilterString,
10
- IntrinsicFilter,
11
- } from "../types.js";
3
+ import type { Filter, FilterString } from "../types.js";
12
4
 
13
- import { filterChildren } from "./filterChildren.js";
14
5
  import { get } from "./get.js";
15
6
 
16
7
  const { isArray } = Array;
@@ -32,7 +23,7 @@ function valueFromFilter<T>(value: T, filter: Filter<T>): any {
32
23
  * @returns `true` if the `value` matches the `filter` and `false` otherwise.
33
24
  */
34
25
  export function testFilter<T>(
35
- filter: Filter<T> | undefined,
26
+ filter: NoInfer<Filter<T>> | undefined,
36
27
  value: T | undefined,
37
28
  settings?: QuerySettings<T>,
38
29
  ): boolean {
@@ -49,12 +40,12 @@ export function testFilter<T>(
49
40
  );
50
41
  case "any": {
51
42
  const length = filter.value?.length ?? 0;
52
- const minimum = filter.minimum ?? (length > 0 ? 1 : 0);
53
- const maximum = filter.maximum ?? Infinity;
43
+ const min = filter.min ?? (length > 0 ? 1 : 0);
44
+ const max = filter.max ?? Infinity;
54
45
  if (filter.value === undefined || filter.value.length === 0) {
55
46
  return true;
56
47
  }
57
- if (minimum === 1 && maximum >= length) {
48
+ if (min === 1 && max >= length) {
58
49
  return filter.value.some((filter) =>
59
50
  testFilter(filter, value, settings),
60
51
  );
@@ -64,7 +55,7 @@ export function testFilter<T>(
64
55
  count + (testFilter(filter, value, settings) ? 1 : 0),
65
56
  0,
66
57
  );
67
- return matched >= minimum && matched <= maximum;
58
+ return matched >= min && matched <= max;
68
59
  }
69
60
  case "none": {
70
61
  if (filter.value === undefined || filter.value.length === 0) {
@@ -137,16 +128,8 @@ export function testFilter<T>(
137
128
  filter[CACHE] = settings.transformFilterChildren(filter);
138
129
  break;
139
130
  default: {
140
- const { pathField = "id", pathFieldSeparator } =
141
- settings || EMPTY_OBJECT;
142
- pathField;
143
- filter[CACHE] = filterChildren<Context<T>>(
144
- (get(filter.value, pathField as any) as string) ?? "",
145
- pathField as FieldFiltered<Context<T>, string>,
146
- filter.minDepth,
147
- filter.maxDepth,
148
- pathFieldSeparator,
149
- ) as IntrinsicFilter<T>;
131
+ // Opt-out if no filter transformation is provided
132
+ return true;
150
133
  }
151
134
  }
152
135
  }
@@ -0,0 +1,57 @@
1
+ import { EMPTY_OBJECT } from "unchangeable";
2
+
3
+ import type {
4
+ FieldFiltered,
5
+ FilterChildren,
6
+ FilterStringMatch,
7
+ } from "../types";
8
+
9
+ import { filterChildren } from "./filterChildren.js";
10
+ import { get } from "./get.js";
11
+
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
+ /**
34
+ * Returns a function that transforms a `FilterChildren` into a `FilterStringMatch`.
35
+ *
36
+ * @param options - Options for the transformer.
37
+ * @returns A function that takes a `FilterChildren` and returns a `FilterStringMatch` that matches the paths of the children of the item specified in the `FilterChildren`.
38
+ */
39
+ export function transformerFilterChildren<T>({
40
+ pathField = "path" as FieldFiltered<T, string>,
41
+ pathFieldSeparator = "/",
42
+ }: TransformerFilterChildrenOptions<T> = EMPTY_OBJECT) {
43
+ return (filter: FilterChildren<T>): FilterStringMatch<T> => {
44
+ 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;
49
+ return filterChildren(
50
+ parentPath,
51
+ pathField,
52
+ minDepth,
53
+ maxDepth,
54
+ pathFieldSeparator,
55
+ );
56
+ };
57
+ }
package/lib/tools.ts CHANGED
@@ -9,6 +9,7 @@ export { filterChildren } from "./tools/filterChildren.js";
9
9
  export { filterFromValue } from "./tools/filterFromValue.js";
10
10
  export { get } from "./tools/get.js";
11
11
  export { groupFilters } from "./tools/groupFilters.js";
12
+ export { intrinsicFilter } from "./tools/intrinsicFilter.js";
12
13
  export { isFilterGroup } from "./tools/isFilterGroup.js";
13
14
  export { normalizeOrder } from "./tools/normalizeOrder.js";
14
15
  export { queryItemList } from "./tools/queryItemList.js";
@@ -17,3 +18,4 @@ export { sameField } from "./tools/sameField.js";
17
18
  export { sortItemList } from "./tools/sortItemList.js";
18
19
  export { splitPath } from "./tools/splitPath.js";
19
20
  export { testFilter } from "./tools/testFilter.js";
21
+ export { transformerFilterChildren } from "./tools/transformerFilterChildren.js";
@@ -13,8 +13,8 @@ export type AggregateFunction<T> =
13
13
  | "median"
14
14
  | "standardDeviation"
15
15
  | "mean"
16
- | "minimum"
17
- | "maximum"
16
+ | "min"
17
+ | "max"
18
18
  | "variance"
19
19
  | "mode";
20
20
  field: Field<T>;
@@ -2,6 +2,14 @@ import type { SELF } from "../constants/SELF.js";
2
2
 
3
3
  import type { Primitive } from "./Primitive.js";
4
4
 
5
+ /**
6
+ * Describes the entity so that it can be identified or selected in a filter.
7
+ *
8
+ * The context of a single item (`query.multiple` is `false`) is typically its identifier.
9
+ * The context of a list of items (`query.multiple` is `true`) typically consists of common properties that reference the parent entity.
10
+ *
11
+ * It can be a partial object of the type `T` or a primitive value wrapped in an object with the `SELF` key.
12
+ */
5
13
  export type Context<T> = [0] extends [1 & T]
6
14
  ? any
7
15
  : T extends Primitive
@@ -1,6 +1,5 @@
1
1
  import type { CACHE } from "../constants/CACHE.js";
2
2
 
3
- import type { Context } from "./Context";
4
3
  import type { IntrinsicFilter } from "./IntrinsicFilter.js";
5
4
 
6
5
  /**
@@ -8,7 +7,7 @@ import type { IntrinsicFilter } from "./IntrinsicFilter.js";
8
7
  */
9
8
  export type FilterChildren<T> = {
10
9
  operator: "children" | "notChildren";
11
- value?: Context<T>;
10
+ value?: T;
12
11
  /**
13
12
  * Minimum depth of the children to match. If `0`, matches the parent. If `1`, matches the direct children, if `2`, the grandchildren, and so on.
14
13
  *
@@ -29,13 +29,13 @@ export type FilterGroup<T> =
29
29
  *
30
30
  * @default `1` if filters are provided, `0` otherwise
31
31
  */
32
- minimum?: number;
32
+ min?: number;
33
33
  /**
34
34
  * Maximum number of filters that can match.
35
35
  *
36
36
  * @default Infinity
37
37
  */
38
- maximum?: number;
38
+ max?: number;
39
39
  }
40
40
  | {
41
41
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quetch",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "type": "module",
5
5
  "main": "./dist/main.js",
6
6
  "exports": {