feathers-utils 2.0.0-2 → 2.0.0-4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/filters/array.d.ts +1 -1
- package/dist/esm/filters/array.js +2 -2
- package/dist/esm/filters/object.d.ts +2 -0
- package/dist/esm/filters/object.js +8 -0
- package/dist/esm/hooks/checkMulti.d.ts +2 -2
- package/dist/esm/hooks/createRelated.d.ts +8 -2
- package/dist/esm/hooks/createRelated.js +2 -3
- package/dist/esm/hooks/onDelete.d.ts +8 -2
- package/dist/esm/hooks/onDelete.js +8 -7
- package/dist/esm/hooks/removeRelated.d.ts +7 -2
- package/dist/esm/hooks/removeRelated.js +8 -7
- package/dist/esm/hooks/runPerItem.d.ts +5 -2
- package/dist/esm/hooks/runPerItem.js +1 -1
- package/dist/esm/hooks/setData.d.ts +7 -2
- package/dist/esm/hooks/setData.js +3 -2
- package/dist/esm/index.d.ts +19 -34
- package/dist/esm/index.js +21 -33
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.d.ts +5 -2
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.js +2 -2
- package/dist/esm/mixins/debounce-mixin/debounceMixin.d.ts +3 -0
- package/dist/esm/mixins/debounce-mixin/debounceMixin.js +19 -0
- package/dist/esm/mixins/debounce-mixin/index.d.ts +3 -8
- package/dist/esm/mixins/debounce-mixin/index.js +3 -20
- package/dist/esm/mixins/debounce-mixin/types.d.ts +13 -0
- package/dist/esm/mixins/debounce-mixin/types.js +1 -0
- package/dist/esm/types.d.ts +1 -77
- package/dist/esm/types.js +0 -1
- package/dist/esm/typesInternal.d.ts +3 -0
- package/dist/esm/typesInternal.js +3 -0
- package/dist/esm/utils/filterQuery.d.ts +6 -1
- package/dist/esm/utils/filterQuery.js +5 -3
- package/dist/esm/utils/getItemsIsArray.d.ts +5 -2
- package/dist/esm/utils/getItemsIsArray.js +7 -12
- package/dist/esm/utils/getPaginate.d.ts +2 -6
- package/dist/esm/utils/getPaginate.js +1 -1
- package/dist/esm/utils/isMulti.d.ts +1 -1
- package/dist/esm/utils/isPaginated.d.ts +1 -1
- package/dist/esm/utils/markHookForSkip.d.ts +3 -2
- package/dist/esm/utils/markHookForSkip.js +6 -5
- package/dist/esm/utils/mergeQuery/index.d.ts +3 -3
- package/dist/esm/utils/mergeQuery/index.js +3 -338
- package/dist/esm/utils/mergeQuery/mergeArrays.d.ts +2 -1
- package/dist/esm/utils/mergeQuery/mergeArrays.js +2 -2
- package/dist/esm/utils/mergeQuery/mergeQuery.d.ts +3 -0
- package/dist/esm/utils/mergeQuery/mergeQuery.js +68 -0
- package/dist/esm/utils/mergeQuery/types.d.ts +13 -0
- package/dist/esm/utils/mergeQuery/types.js +1 -0
- package/dist/esm/utils/mergeQuery/utils.d.ts +11 -0
- package/dist/esm/utils/mergeQuery/utils.js +272 -0
- package/dist/esm/utils/pushSet.d.ts +4 -1
- package/dist/esm/utils/pushSet.js +1 -1
- package/dist/esm/utils/setResultEmpty.d.ts +1 -1
- package/dist/esm/utils/setResultEmpty.js +1 -1
- package/dist/esm/utils/shouldSkip.d.ts +1 -1
- package/dist/esm/utils/validateQueryProperty.js +1 -1
- package/dist/filters/array.d.ts +1 -1
- package/dist/filters/array.js +2 -2
- package/dist/filters/object.d.ts +2 -0
- package/dist/filters/object.js +15 -0
- package/dist/hooks/checkMulti.d.ts +2 -2
- package/dist/hooks/createRelated.d.ts +8 -2
- package/dist/hooks/createRelated.js +2 -3
- package/dist/hooks/onDelete.d.ts +8 -2
- package/dist/hooks/onDelete.js +8 -7
- package/dist/hooks/removeRelated.d.ts +7 -2
- package/dist/hooks/removeRelated.js +8 -7
- package/dist/hooks/runPerItem.d.ts +5 -2
- package/dist/hooks/runPerItem.js +1 -1
- package/dist/hooks/setData.d.ts +7 -2
- package/dist/hooks/setData.js +3 -2
- package/dist/index.d.ts +19 -34
- package/dist/index.js +23 -49
- package/dist/mixins/debounce-mixin/DebouncedStore.d.ts +5 -2
- package/dist/mixins/debounce-mixin/DebouncedStore.js +2 -2
- package/dist/mixins/debounce-mixin/debounceMixin.d.ts +3 -0
- package/dist/mixins/debounce-mixin/debounceMixin.js +23 -0
- package/dist/mixins/debounce-mixin/index.d.ts +3 -8
- package/dist/mixins/debounce-mixin/index.js +17 -22
- package/dist/mixins/debounce-mixin/types.d.ts +13 -0
- package/dist/mixins/debounce-mixin/types.js +2 -0
- package/dist/types.d.ts +1 -77
- package/dist/types.js +0 -1
- package/dist/typesInternal.d.ts +3 -0
- package/dist/typesInternal.js +4 -0
- package/dist/utils/filterQuery.d.ts +6 -1
- package/dist/utils/filterQuery.js +4 -2
- package/dist/utils/getItemsIsArray.d.ts +5 -2
- package/dist/utils/getItemsIsArray.js +7 -12
- package/dist/utils/getPaginate.d.ts +2 -6
- package/dist/utils/isMulti.d.ts +1 -1
- package/dist/utils/isPaginated.d.ts +1 -1
- package/dist/utils/markHookForSkip.d.ts +3 -2
- package/dist/utils/markHookForSkip.js +6 -5
- package/dist/utils/mergeQuery/index.d.ts +3 -3
- package/dist/utils/mergeQuery/index.js +16 -342
- package/dist/utils/mergeQuery/mergeArrays.d.ts +2 -1
- package/dist/utils/mergeQuery/mergeArrays.js +2 -2
- package/dist/utils/mergeQuery/mergeQuery.d.ts +3 -0
- package/dist/utils/mergeQuery/mergeQuery.js +75 -0
- package/dist/utils/mergeQuery/types.d.ts +13 -0
- package/dist/utils/mergeQuery/types.js +2 -0
- package/dist/utils/mergeQuery/utils.d.ts +11 -0
- package/dist/utils/mergeQuery/utils.js +287 -0
- package/dist/utils/pushSet.d.ts +4 -1
- package/dist/utils/pushSet.js +1 -1
- package/dist/utils/setResultEmpty.d.ts +1 -1
- package/dist/utils/setResultEmpty.js +1 -1
- package/dist/utils/shouldSkip.d.ts +1 -1
- package/package.json +5 -2
- package/src/filters/array.ts +13 -9
- package/src/filters/object.ts +15 -0
- package/src/hooks/checkMulti.ts +8 -6
- package/src/hooks/createRelated.ts +21 -12
- package/src/hooks/onDelete.ts +28 -13
- package/src/hooks/removeRelated.ts +28 -16
- package/src/hooks/runPerItem.ts +19 -10
- package/src/hooks/setData.ts +24 -15
- package/src/index.ts +21 -38
- package/src/mixins/debounce-mixin/DebouncedStore.ts +29 -24
- package/src/mixins/debounce-mixin/debounceMixin.ts +33 -0
- package/src/mixins/debounce-mixin/index.ts +3 -39
- package/src/mixins/debounce-mixin/types.ts +16 -0
- package/src/types.ts +6 -117
- package/src/typesInternal.ts +6 -0
- package/src/utils/filterQuery.ts +22 -10
- package/src/utils/getItemsIsArray.ts +15 -16
- package/src/utils/getPaginate.ts +11 -14
- package/src/utils/isMulti.ts +3 -3
- package/src/utils/isPaginated.ts +6 -4
- package/src/utils/markHookForSkip.ts +18 -16
- package/src/utils/mergeQuery/index.ts +3 -379
- package/src/utils/mergeQuery/mergeArrays.ts +25 -18
- package/src/utils/mergeQuery/mergeQuery.ts +102 -0
- package/src/utils/mergeQuery/types.ts +25 -0
- package/src/utils/mergeQuery/utils.ts +342 -0
- package/src/utils/pushSet.ts +14 -7
- package/src/utils/setResultEmpty.ts +8 -6
- package/src/utils/shouldSkip.ts +4 -4
- package/src/utils/validateQueryProperty.ts +8 -4
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { Forbidden } from "@feathersjs/errors";
|
|
2
|
+
import _get from "lodash/get.js";
|
|
3
|
+
import _has from "lodash/has.js";
|
|
4
|
+
import _isEmpty from "lodash/isEmpty.js";
|
|
5
|
+
import _isEqual from "lodash/isEqual.js";
|
|
6
|
+
|
|
7
|
+
import _set from "lodash/set.js";
|
|
8
|
+
import _uniqWith from "lodash/uniqWith.js";
|
|
9
|
+
import type { Path } from "../../typesInternal";
|
|
10
|
+
import { mergeArrays } from "./mergeArrays";
|
|
11
|
+
import type { Handle, MergeQueryOptions } from "./types";
|
|
12
|
+
|
|
13
|
+
export const hasOwnProperty = (
|
|
14
|
+
obj: Record<string, unknown>,
|
|
15
|
+
key: string
|
|
16
|
+
): boolean => {
|
|
17
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function handleArray<T>(
|
|
21
|
+
target: Record<string, unknown>,
|
|
22
|
+
source: Record<string, unknown>,
|
|
23
|
+
key: Path,
|
|
24
|
+
options: MergeQueryOptions<T>
|
|
25
|
+
): void {
|
|
26
|
+
const targetVal = _get(target, key);
|
|
27
|
+
const sourceVal = _get(source, key);
|
|
28
|
+
if (!sourceVal && !targetVal) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const handle: Handle = _get(
|
|
32
|
+
options,
|
|
33
|
+
["handle", ...key],
|
|
34
|
+
options.defaultHandle
|
|
35
|
+
);
|
|
36
|
+
const arr = mergeArrays(
|
|
37
|
+
targetVal,
|
|
38
|
+
sourceVal,
|
|
39
|
+
handle,
|
|
40
|
+
key,
|
|
41
|
+
options.actionOnEmptyIntersect
|
|
42
|
+
);
|
|
43
|
+
_set(target, key, arr);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function handleCircular<T>(
|
|
47
|
+
target: Record<string, unknown>,
|
|
48
|
+
source: Record<string, unknown>,
|
|
49
|
+
prependKey: Path,
|
|
50
|
+
options: MergeQueryOptions<T>
|
|
51
|
+
): void {
|
|
52
|
+
if (target?.$or) {
|
|
53
|
+
target.$or = cleanOr(target.$or as Record<string, unknown>[]);
|
|
54
|
+
if (!target.$or) {
|
|
55
|
+
delete target.$or;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (source?.$or) {
|
|
59
|
+
source.$or = cleanOr(source.$or as Record<string, unknown>[]);
|
|
60
|
+
if (!source.$or) {
|
|
61
|
+
delete source.$or;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (target?.$and) {
|
|
66
|
+
target.$and = cleanAnd(target.$and as Record<string, unknown>[]);
|
|
67
|
+
if (!target.$and) {
|
|
68
|
+
delete target.$and;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (source?.$and) {
|
|
73
|
+
source.$and = cleanAnd(source.$and as Record<string, unknown>[]);
|
|
74
|
+
if (!source.$and) {
|
|
75
|
+
delete source.$and;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!_has(source, prependKey)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!_has(target, prependKey)) {
|
|
84
|
+
_set(target, prependKey, _get(source, prependKey));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const { defaultHandle, actionOnEmptyIntersect } = options;
|
|
89
|
+
|
|
90
|
+
if (defaultHandle === "target") {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const getTargetVal = () => {
|
|
95
|
+
return prependKey.length > 0 ? _get(target, prependKey) : target;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const getSourceVal = () => {
|
|
99
|
+
return prependKey.length > 0 ? _get(source, prependKey) : source;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const targetVal = getTargetVal();
|
|
103
|
+
const sourceVal = getSourceVal();
|
|
104
|
+
|
|
105
|
+
if (_isEqual(targetVal, sourceVal)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (defaultHandle === "source") {
|
|
110
|
+
_set(target, prependKey, sourceVal);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (targetVal === null || sourceVal === null) {
|
|
115
|
+
_set(target, prependKey, sourceVal);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const typeOfTargetVal = typeof targetVal;
|
|
120
|
+
|
|
121
|
+
if (["boolean"].includes(typeOfTargetVal)) {
|
|
122
|
+
if (defaultHandle === "intersect") {
|
|
123
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
124
|
+
}
|
|
125
|
+
_set(target, prependKey, sourceVal);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const typeOfSourceVal = typeof sourceVal;
|
|
130
|
+
|
|
131
|
+
const isTargetSimple = ["string", "number"].includes(typeOfTargetVal);
|
|
132
|
+
const isSourceSimple = ["string", "number"].includes(typeOfSourceVal);
|
|
133
|
+
|
|
134
|
+
if (isTargetSimple || isSourceSimple) {
|
|
135
|
+
if (isTargetSimple && isSourceSimple) {
|
|
136
|
+
if (defaultHandle === "combine") {
|
|
137
|
+
_set(target, prependKey, { $in: [...new Set([targetVal, sourceVal])] });
|
|
138
|
+
return;
|
|
139
|
+
} else if (defaultHandle === "intersect") {
|
|
140
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
141
|
+
} else {
|
|
142
|
+
throw new Error("should not reach here");
|
|
143
|
+
}
|
|
144
|
+
} else if (
|
|
145
|
+
hasOwnProperty(targetVal, "$in") ||
|
|
146
|
+
hasOwnProperty(sourceVal, "$in")
|
|
147
|
+
) {
|
|
148
|
+
const targetHasIn = hasOwnProperty(targetVal, "$in");
|
|
149
|
+
|
|
150
|
+
const $in = targetHasIn ? targetVal["$in"] : sourceVal["$in"];
|
|
151
|
+
const otherVal = isTargetSimple ? targetVal : sourceVal;
|
|
152
|
+
if ($in.length === 1 && _isEqual($in[0], otherVal)) {
|
|
153
|
+
_set(target, prependKey, otherVal);
|
|
154
|
+
return;
|
|
155
|
+
} else if (defaultHandle === "combine") {
|
|
156
|
+
if (!$in.some((x: unknown) => _isEqual(x, otherVal))) {
|
|
157
|
+
$in.push(otherVal);
|
|
158
|
+
}
|
|
159
|
+
_set(target, `${prependKey}.$in`, $in);
|
|
160
|
+
return;
|
|
161
|
+
} else if (defaultHandle === "intersect") {
|
|
162
|
+
if ($in.some((x: unknown) => _isEqual(x, otherVal))) {
|
|
163
|
+
_set(target, prependKey, otherVal);
|
|
164
|
+
} else {
|
|
165
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const isTargetArray = Array.isArray(targetVal);
|
|
174
|
+
const isSourceArray = Array.isArray(sourceVal);
|
|
175
|
+
|
|
176
|
+
if (isTargetArray && isSourceArray) {
|
|
177
|
+
const key = prependKey[prependKey.length - 1];
|
|
178
|
+
if (key === "$or") {
|
|
179
|
+
if (defaultHandle === "combine") {
|
|
180
|
+
const newVals = sourceVal.filter(
|
|
181
|
+
(x: unknown) => !targetVal.some((y: unknown) => _isEqual(x, y))
|
|
182
|
+
);
|
|
183
|
+
targetVal.push(...newVals);
|
|
184
|
+
} else if (defaultHandle === "intersect") {
|
|
185
|
+
// combine into "$and"
|
|
186
|
+
const targetParent = getParentProp(target, prependKey);
|
|
187
|
+
const sourceParent = getParentProp(source, prependKey);
|
|
188
|
+
targetParent.$and = targetParent.$and || [];
|
|
189
|
+
|
|
190
|
+
targetParent.$and.push({ $or: targetVal }, { $or: sourceVal });
|
|
191
|
+
|
|
192
|
+
targetParent.$and = cleanAnd(targetParent.$and);
|
|
193
|
+
if (!targetParent.$and) {
|
|
194
|
+
delete targetParent.$and;
|
|
195
|
+
}
|
|
196
|
+
delete targetParent.$or;
|
|
197
|
+
delete sourceParent.$or;
|
|
198
|
+
handleCircular(target, source, [...prependKey, "$and"], options);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
} else if (key === "$and") {
|
|
203
|
+
if (defaultHandle === "combine") {
|
|
204
|
+
// combine into "$or"
|
|
205
|
+
const targetParent = getParentProp(target, prependKey);
|
|
206
|
+
const sourceParent = getParentProp(source, prependKey);
|
|
207
|
+
|
|
208
|
+
targetParent.$or = targetParent.$or || [];
|
|
209
|
+
targetParent.$or.push({ $and: targetVal }, { $and: sourceVal });
|
|
210
|
+
targetParent.$or = cleanOr(targetParent.$or);
|
|
211
|
+
if (!targetParent.$or) {
|
|
212
|
+
delete targetParent.$or;
|
|
213
|
+
}
|
|
214
|
+
delete targetParent.$and;
|
|
215
|
+
delete sourceParent.$and;
|
|
216
|
+
handleCircular(target, source, [...prependKey, "$or"], options);
|
|
217
|
+
return;
|
|
218
|
+
} else if (defaultHandle === "intersect") {
|
|
219
|
+
const newVals = sourceVal.filter(
|
|
220
|
+
(x: unknown) => !targetVal.some((y: unknown) => _isEqual(x, y))
|
|
221
|
+
);
|
|
222
|
+
targetVal.push(...newVals);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
} else if (key === "$in") {
|
|
226
|
+
if (defaultHandle === "combine") {
|
|
227
|
+
let $in: unknown[] = targetVal.concat(sourceVal);
|
|
228
|
+
$in = [...new Set($in)];
|
|
229
|
+
_set(target, prependKey, $in);
|
|
230
|
+
return;
|
|
231
|
+
} else if (defaultHandle === "intersect") {
|
|
232
|
+
const $in = targetVal.filter((x: unknown) =>
|
|
233
|
+
sourceVal.some((y: unknown) => _isEqual(x, y))
|
|
234
|
+
);
|
|
235
|
+
if ($in.length === 0) {
|
|
236
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
237
|
+
} else if ($in.length === 1) {
|
|
238
|
+
_set(target, prependKey.slice(0, -1), $in[0]);
|
|
239
|
+
return;
|
|
240
|
+
} else {
|
|
241
|
+
_set(target, prependKey, $in);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
_set(target, prependKey, sourceVal);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (typeOfTargetVal !== "object" || typeOfSourceVal !== "object") {
|
|
252
|
+
_set(target, prependKey, sourceVal);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// both are objects
|
|
257
|
+
const sourceKeys = Object.keys(sourceVal);
|
|
258
|
+
|
|
259
|
+
for (let i = 0, n = sourceKeys.length; i < n; i++) {
|
|
260
|
+
const key = sourceKeys[i];
|
|
261
|
+
handleCircular(target, source, [...prependKey, key], options);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function makeDefaultOptions<T>(
|
|
266
|
+
options?: Partial<MergeQueryOptions<T>>
|
|
267
|
+
): MergeQueryOptions<T> {
|
|
268
|
+
options = options || ({} as MergeQueryOptions<T>);
|
|
269
|
+
options.defaultHandle = options.defaultHandle || "combine";
|
|
270
|
+
options.useLogicalConjunction = Object.prototype.hasOwnProperty.call(
|
|
271
|
+
options,
|
|
272
|
+
"useLogicalConjunction"
|
|
273
|
+
)
|
|
274
|
+
? options.useLogicalConjunction
|
|
275
|
+
: false;
|
|
276
|
+
options.actionOnEmptyIntersect =
|
|
277
|
+
options.actionOnEmptyIntersect ||
|
|
278
|
+
(() => {
|
|
279
|
+
throw new Forbidden("You're not allowed to make this request");
|
|
280
|
+
});
|
|
281
|
+
options.handle = options.handle || {};
|
|
282
|
+
if (options.defaultHandle === "intersect") {
|
|
283
|
+
options.handle.$select = options.handle.$select || "intersectOrFull";
|
|
284
|
+
}
|
|
285
|
+
return options as MergeQueryOptions<T>;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function moveProperty(
|
|
289
|
+
source: Record<string, any>,
|
|
290
|
+
target: Record<string, any>,
|
|
291
|
+
key: string
|
|
292
|
+
): void {
|
|
293
|
+
if (!Object.prototype.hasOwnProperty.call(source, key)) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
target[key] = source[key];
|
|
297
|
+
delete source[key];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function getParentProp(target: Record<string, unknown>, path: Path) {
|
|
301
|
+
if (path.length <= 1) {
|
|
302
|
+
return target;
|
|
303
|
+
}
|
|
304
|
+
const pathOneUp = path.slice(0, -1);
|
|
305
|
+
return _get(target, pathOneUp);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export function cleanOr(
|
|
309
|
+
target: Record<string, unknown>[]
|
|
310
|
+
): Record<string, unknown>[] | undefined {
|
|
311
|
+
if (!target || !Array.isArray(target) || target.length <= 0) {
|
|
312
|
+
return target;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (target.some((x) => _isEmpty(x))) {
|
|
316
|
+
return undefined;
|
|
317
|
+
} else {
|
|
318
|
+
return arrayWithoutDuplicates(target);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function cleanAnd(
|
|
323
|
+
target: Record<string, unknown>[]
|
|
324
|
+
): Record<string, unknown>[] | undefined {
|
|
325
|
+
if (!target || !Array.isArray(target) || target.length <= 0) {
|
|
326
|
+
return target;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (target.every((x) => _isEmpty(x))) {
|
|
330
|
+
return undefined;
|
|
331
|
+
} else {
|
|
332
|
+
target = target.filter((x) => !_isEmpty(x));
|
|
333
|
+
return arrayWithoutDuplicates(target);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export function arrayWithoutDuplicates<T>(target: T[]): T[] {
|
|
338
|
+
if (!target || !Array.isArray(target)) {
|
|
339
|
+
return target;
|
|
340
|
+
}
|
|
341
|
+
return _uniqWith(target, _isEqual);
|
|
342
|
+
}
|
package/src/utils/pushSet.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import _isEqual from "lodash/isEqual.js";
|
|
2
2
|
import _get from "lodash/get.js";
|
|
3
3
|
import _set from "lodash/set.js";
|
|
4
|
+
import type { Path } from "../typesInternal";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "../types";
|
|
6
|
+
export interface PushSetOptions {
|
|
7
|
+
unique?: boolean;
|
|
8
|
+
}
|
|
9
9
|
|
|
10
|
-
export const pushSet = (
|
|
10
|
+
export const pushSet = (
|
|
11
|
+
obj: Record<string, unknown>,
|
|
12
|
+
path: string | Path,
|
|
13
|
+
val: unknown,
|
|
14
|
+
options?: PushSetOptions
|
|
15
|
+
): unknown[] => {
|
|
11
16
|
options = options || {};
|
|
12
17
|
let arr = _get(obj, path);
|
|
13
18
|
if (!arr || !Array.isArray(arr)) {
|
|
@@ -15,8 +20,10 @@ export const pushSet = (obj: Record<string, unknown>, path: string | Path, val:
|
|
|
15
20
|
_set(obj, path, arr);
|
|
16
21
|
return arr;
|
|
17
22
|
} else {
|
|
18
|
-
if (options.unique && arr.some(x => _isEqual(x, val))) {
|
|
23
|
+
if (options.unique && arr.some((x) => _isEqual(x, val))) {
|
|
24
|
+
return arr;
|
|
25
|
+
}
|
|
19
26
|
arr.push(val);
|
|
20
27
|
return arr;
|
|
21
28
|
}
|
|
22
|
-
};
|
|
29
|
+
};
|
|
@@ -2,10 +2,12 @@ import type { HookContext } from "@feathersjs/feathers";
|
|
|
2
2
|
import { isMulti } from "..";
|
|
3
3
|
import { isPaginated } from "./isPaginated";
|
|
4
4
|
|
|
5
|
-
export const setResultEmpty = (
|
|
6
|
-
context:
|
|
7
|
-
)
|
|
8
|
-
if (context.result) {
|
|
5
|
+
export const setResultEmpty = <H extends HookContext = HookContext>(
|
|
6
|
+
context: H
|
|
7
|
+
) => {
|
|
8
|
+
if (context.result) {
|
|
9
|
+
return context;
|
|
10
|
+
}
|
|
9
11
|
|
|
10
12
|
const multi = isMulti(context);
|
|
11
13
|
|
|
@@ -15,7 +17,7 @@ export const setResultEmpty = (
|
|
|
15
17
|
total: 0,
|
|
16
18
|
skip: 0,
|
|
17
19
|
limit: 0,
|
|
18
|
-
data: []
|
|
20
|
+
data: [],
|
|
19
21
|
};
|
|
20
22
|
} else {
|
|
21
23
|
context.result = [];
|
|
@@ -25,4 +27,4 @@ export const setResultEmpty = (
|
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
return context;
|
|
28
|
-
};
|
|
30
|
+
};
|
package/src/utils/shouldSkip.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { GeneralError } from "@feathersjs/errors";
|
|
|
5
5
|
|
|
6
6
|
import type { HookContext } from "@feathersjs/feathers";
|
|
7
7
|
|
|
8
|
-
export const shouldSkip = (
|
|
9
|
-
hookName: string,
|
|
10
|
-
context:
|
|
8
|
+
export const shouldSkip = <H extends HookContext = HookContext>(
|
|
9
|
+
hookName: string,
|
|
10
|
+
context: H
|
|
11
11
|
): boolean => {
|
|
12
12
|
if (!context.params || !context.params.skipHooks) {
|
|
13
13
|
return false;
|
|
@@ -41,4 +41,4 @@ export const shouldSkip = (
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
return false;
|
|
44
|
-
};
|
|
44
|
+
};
|
|
@@ -2,9 +2,13 @@ import { _ } from "@feathersjs/commons";
|
|
|
2
2
|
import { BadRequest } from "@feathersjs/errors";
|
|
3
3
|
import type { Query } from "@feathersjs/feathers";
|
|
4
4
|
|
|
5
|
-
const isPlainObject = (value: any) =>
|
|
5
|
+
const isPlainObject = (value: any) =>
|
|
6
|
+
_.isObject(value) && value.constructor === {}.constructor;
|
|
6
7
|
|
|
7
|
-
export const validateQueryProperty = (
|
|
8
|
+
export const validateQueryProperty = (
|
|
9
|
+
query: any,
|
|
10
|
+
operators: string[] = []
|
|
11
|
+
): Query => {
|
|
8
12
|
if (!isPlainObject(query)) {
|
|
9
13
|
return query;
|
|
10
14
|
}
|
|
@@ -22,6 +26,6 @@ export const validateQueryProperty = (query: any, operators: string[] = []): Que
|
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
return {
|
|
25
|
-
...query
|
|
29
|
+
...query,
|
|
26
30
|
};
|
|
27
|
-
};
|
|
31
|
+
};
|