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,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.arrayWithoutDuplicates = exports.cleanAnd = exports.cleanOr = exports.getParentProp = exports.moveProperty = exports.makeDefaultOptions = exports.handleCircular = exports.handleArray = exports.hasOwnProperty = void 0;
|
|
7
|
+
const errors_1 = require("@feathersjs/errors");
|
|
8
|
+
const get_js_1 = __importDefault(require("lodash/get.js"));
|
|
9
|
+
const has_js_1 = __importDefault(require("lodash/has.js"));
|
|
10
|
+
const isEmpty_js_1 = __importDefault(require("lodash/isEmpty.js"));
|
|
11
|
+
const isEqual_js_1 = __importDefault(require("lodash/isEqual.js"));
|
|
12
|
+
const set_js_1 = __importDefault(require("lodash/set.js"));
|
|
13
|
+
const uniqWith_js_1 = __importDefault(require("lodash/uniqWith.js"));
|
|
14
|
+
const mergeArrays_1 = require("./mergeArrays");
|
|
15
|
+
const hasOwnProperty = (obj, key) => {
|
|
16
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
17
|
+
};
|
|
18
|
+
exports.hasOwnProperty = hasOwnProperty;
|
|
19
|
+
function handleArray(target, source, key, options) {
|
|
20
|
+
const targetVal = (0, get_js_1.default)(target, key);
|
|
21
|
+
const sourceVal = (0, get_js_1.default)(source, key);
|
|
22
|
+
if (!sourceVal && !targetVal) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const handle = (0, get_js_1.default)(options, ["handle", ...key], options.defaultHandle);
|
|
26
|
+
const arr = (0, mergeArrays_1.mergeArrays)(targetVal, sourceVal, handle, key, options.actionOnEmptyIntersect);
|
|
27
|
+
(0, set_js_1.default)(target, key, arr);
|
|
28
|
+
}
|
|
29
|
+
exports.handleArray = handleArray;
|
|
30
|
+
function handleCircular(target, source, prependKey, options) {
|
|
31
|
+
if (target === null || target === void 0 ? void 0 : target.$or) {
|
|
32
|
+
target.$or = cleanOr(target.$or);
|
|
33
|
+
if (!target.$or) {
|
|
34
|
+
delete target.$or;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (source === null || source === void 0 ? void 0 : source.$or) {
|
|
38
|
+
source.$or = cleanOr(source.$or);
|
|
39
|
+
if (!source.$or) {
|
|
40
|
+
delete source.$or;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (target === null || target === void 0 ? void 0 : target.$and) {
|
|
44
|
+
target.$and = cleanAnd(target.$and);
|
|
45
|
+
if (!target.$and) {
|
|
46
|
+
delete target.$and;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (source === null || source === void 0 ? void 0 : source.$and) {
|
|
50
|
+
source.$and = cleanAnd(source.$and);
|
|
51
|
+
if (!source.$and) {
|
|
52
|
+
delete source.$and;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!(0, has_js_1.default)(source, prependKey)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (!(0, has_js_1.default)(target, prependKey)) {
|
|
59
|
+
(0, set_js_1.default)(target, prependKey, (0, get_js_1.default)(source, prependKey));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const { defaultHandle, actionOnEmptyIntersect } = options;
|
|
63
|
+
if (defaultHandle === "target") {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const getTargetVal = () => {
|
|
67
|
+
return prependKey.length > 0 ? (0, get_js_1.default)(target, prependKey) : target;
|
|
68
|
+
};
|
|
69
|
+
const getSourceVal = () => {
|
|
70
|
+
return prependKey.length > 0 ? (0, get_js_1.default)(source, prependKey) : source;
|
|
71
|
+
};
|
|
72
|
+
const targetVal = getTargetVal();
|
|
73
|
+
const sourceVal = getSourceVal();
|
|
74
|
+
if ((0, isEqual_js_1.default)(targetVal, sourceVal)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (defaultHandle === "source") {
|
|
78
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (targetVal === null || sourceVal === null) {
|
|
82
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const typeOfTargetVal = typeof targetVal;
|
|
86
|
+
if (["boolean"].includes(typeOfTargetVal)) {
|
|
87
|
+
if (defaultHandle === "intersect") {
|
|
88
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
89
|
+
}
|
|
90
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const typeOfSourceVal = typeof sourceVal;
|
|
94
|
+
const isTargetSimple = ["string", "number"].includes(typeOfTargetVal);
|
|
95
|
+
const isSourceSimple = ["string", "number"].includes(typeOfSourceVal);
|
|
96
|
+
if (isTargetSimple || isSourceSimple) {
|
|
97
|
+
if (isTargetSimple && isSourceSimple) {
|
|
98
|
+
if (defaultHandle === "combine") {
|
|
99
|
+
(0, set_js_1.default)(target, prependKey, { $in: [...new Set([targetVal, sourceVal])] });
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
else if (defaultHandle === "intersect") {
|
|
103
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
throw new Error("should not reach here");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if ((0, exports.hasOwnProperty)(targetVal, "$in") ||
|
|
110
|
+
(0, exports.hasOwnProperty)(sourceVal, "$in")) {
|
|
111
|
+
const targetHasIn = (0, exports.hasOwnProperty)(targetVal, "$in");
|
|
112
|
+
const $in = targetHasIn ? targetVal["$in"] : sourceVal["$in"];
|
|
113
|
+
const otherVal = isTargetSimple ? targetVal : sourceVal;
|
|
114
|
+
if ($in.length === 1 && (0, isEqual_js_1.default)($in[0], otherVal)) {
|
|
115
|
+
(0, set_js_1.default)(target, prependKey, otherVal);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
else if (defaultHandle === "combine") {
|
|
119
|
+
if (!$in.some((x) => (0, isEqual_js_1.default)(x, otherVal))) {
|
|
120
|
+
$in.push(otherVal);
|
|
121
|
+
}
|
|
122
|
+
(0, set_js_1.default)(target, `${prependKey}.$in`, $in);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
else if (defaultHandle === "intersect") {
|
|
126
|
+
if ($in.some((x) => (0, isEqual_js_1.default)(x, otherVal))) {
|
|
127
|
+
(0, set_js_1.default)(target, prependKey, otherVal);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const isTargetArray = Array.isArray(targetVal);
|
|
138
|
+
const isSourceArray = Array.isArray(sourceVal);
|
|
139
|
+
if (isTargetArray && isSourceArray) {
|
|
140
|
+
const key = prependKey[prependKey.length - 1];
|
|
141
|
+
if (key === "$or") {
|
|
142
|
+
if (defaultHandle === "combine") {
|
|
143
|
+
const newVals = sourceVal.filter((x) => !targetVal.some((y) => (0, isEqual_js_1.default)(x, y)));
|
|
144
|
+
targetVal.push(...newVals);
|
|
145
|
+
}
|
|
146
|
+
else if (defaultHandle === "intersect") {
|
|
147
|
+
// combine into "$and"
|
|
148
|
+
const targetParent = getParentProp(target, prependKey);
|
|
149
|
+
const sourceParent = getParentProp(source, prependKey);
|
|
150
|
+
targetParent.$and = targetParent.$and || [];
|
|
151
|
+
targetParent.$and.push({ $or: targetVal }, { $or: sourceVal });
|
|
152
|
+
targetParent.$and = cleanAnd(targetParent.$and);
|
|
153
|
+
if (!targetParent.$and) {
|
|
154
|
+
delete targetParent.$and;
|
|
155
|
+
}
|
|
156
|
+
delete targetParent.$or;
|
|
157
|
+
delete sourceParent.$or;
|
|
158
|
+
handleCircular(target, source, [...prependKey, "$and"], options);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
else if (key === "$and") {
|
|
164
|
+
if (defaultHandle === "combine") {
|
|
165
|
+
// combine into "$or"
|
|
166
|
+
const targetParent = getParentProp(target, prependKey);
|
|
167
|
+
const sourceParent = getParentProp(source, prependKey);
|
|
168
|
+
targetParent.$or = targetParent.$or || [];
|
|
169
|
+
targetParent.$or.push({ $and: targetVal }, { $and: sourceVal });
|
|
170
|
+
targetParent.$or = cleanOr(targetParent.$or);
|
|
171
|
+
if (!targetParent.$or) {
|
|
172
|
+
delete targetParent.$or;
|
|
173
|
+
}
|
|
174
|
+
delete targetParent.$and;
|
|
175
|
+
delete sourceParent.$and;
|
|
176
|
+
handleCircular(target, source, [...prependKey, "$or"], options);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
else if (defaultHandle === "intersect") {
|
|
180
|
+
const newVals = sourceVal.filter((x) => !targetVal.some((y) => (0, isEqual_js_1.default)(x, y)));
|
|
181
|
+
targetVal.push(...newVals);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else if (key === "$in") {
|
|
186
|
+
if (defaultHandle === "combine") {
|
|
187
|
+
let $in = targetVal.concat(sourceVal);
|
|
188
|
+
$in = [...new Set($in)];
|
|
189
|
+
(0, set_js_1.default)(target, prependKey, $in);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
else if (defaultHandle === "intersect") {
|
|
193
|
+
const $in = targetVal.filter((x) => sourceVal.some((y) => (0, isEqual_js_1.default)(x, y)));
|
|
194
|
+
if ($in.length === 0) {
|
|
195
|
+
actionOnEmptyIntersect(target, source, prependKey);
|
|
196
|
+
}
|
|
197
|
+
else if ($in.length === 1) {
|
|
198
|
+
(0, set_js_1.default)(target, prependKey.slice(0, -1), $in[0]);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
(0, set_js_1.default)(target, prependKey, $in);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (typeOfTargetVal !== "object" || typeOfSourceVal !== "object") {
|
|
211
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// both are objects
|
|
215
|
+
const sourceKeys = Object.keys(sourceVal);
|
|
216
|
+
for (let i = 0, n = sourceKeys.length; i < n; i++) {
|
|
217
|
+
const key = sourceKeys[i];
|
|
218
|
+
handleCircular(target, source, [...prependKey, key], options);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
exports.handleCircular = handleCircular;
|
|
222
|
+
function makeDefaultOptions(options) {
|
|
223
|
+
options = options || {};
|
|
224
|
+
options.defaultHandle = options.defaultHandle || "combine";
|
|
225
|
+
options.useLogicalConjunction = Object.prototype.hasOwnProperty.call(options, "useLogicalConjunction")
|
|
226
|
+
? options.useLogicalConjunction
|
|
227
|
+
: false;
|
|
228
|
+
options.actionOnEmptyIntersect =
|
|
229
|
+
options.actionOnEmptyIntersect ||
|
|
230
|
+
(() => {
|
|
231
|
+
throw new errors_1.Forbidden("You're not allowed to make this request");
|
|
232
|
+
});
|
|
233
|
+
options.handle = options.handle || {};
|
|
234
|
+
if (options.defaultHandle === "intersect") {
|
|
235
|
+
options.handle.$select = options.handle.$select || "intersectOrFull";
|
|
236
|
+
}
|
|
237
|
+
return options;
|
|
238
|
+
}
|
|
239
|
+
exports.makeDefaultOptions = makeDefaultOptions;
|
|
240
|
+
function moveProperty(source, target, key) {
|
|
241
|
+
if (!Object.prototype.hasOwnProperty.call(source, key)) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
target[key] = source[key];
|
|
245
|
+
delete source[key];
|
|
246
|
+
}
|
|
247
|
+
exports.moveProperty = moveProperty;
|
|
248
|
+
function getParentProp(target, path) {
|
|
249
|
+
if (path.length <= 1) {
|
|
250
|
+
return target;
|
|
251
|
+
}
|
|
252
|
+
const pathOneUp = path.slice(0, -1);
|
|
253
|
+
return (0, get_js_1.default)(target, pathOneUp);
|
|
254
|
+
}
|
|
255
|
+
exports.getParentProp = getParentProp;
|
|
256
|
+
function cleanOr(target) {
|
|
257
|
+
if (!target || !Array.isArray(target) || target.length <= 0) {
|
|
258
|
+
return target;
|
|
259
|
+
}
|
|
260
|
+
if (target.some((x) => (0, isEmpty_js_1.default)(x))) {
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
return arrayWithoutDuplicates(target);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
exports.cleanOr = cleanOr;
|
|
268
|
+
function cleanAnd(target) {
|
|
269
|
+
if (!target || !Array.isArray(target) || target.length <= 0) {
|
|
270
|
+
return target;
|
|
271
|
+
}
|
|
272
|
+
if (target.every((x) => (0, isEmpty_js_1.default)(x))) {
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
target = target.filter((x) => !(0, isEmpty_js_1.default)(x));
|
|
277
|
+
return arrayWithoutDuplicates(target);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
exports.cleanAnd = cleanAnd;
|
|
281
|
+
function arrayWithoutDuplicates(target) {
|
|
282
|
+
if (!target || !Array.isArray(target)) {
|
|
283
|
+
return target;
|
|
284
|
+
}
|
|
285
|
+
return (0, uniqWith_js_1.default)(target, isEqual_js_1.default);
|
|
286
|
+
}
|
|
287
|
+
exports.arrayWithoutDuplicates = arrayWithoutDuplicates;
|
package/dist/utils/pushSet.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
import type { Path
|
|
1
|
+
import type { Path } from "../typesInternal";
|
|
2
|
+
export interface PushSetOptions {
|
|
3
|
+
unique?: boolean;
|
|
4
|
+
}
|
|
2
5
|
export declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val: unknown, options?: PushSetOptions) => unknown[];
|
package/dist/utils/pushSet.js
CHANGED
|
@@ -16,7 +16,7 @@ const pushSet = (obj, path, val, options) => {
|
|
|
16
16
|
return arr;
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
19
|
-
if (options.unique && arr.some(x => (0, isEqual_js_1.default)(x, val))) {
|
|
19
|
+
if (options.unique && arr.some((x) => (0, isEqual_js_1.default)(x, val))) {
|
|
20
20
|
return arr;
|
|
21
21
|
}
|
|
22
22
|
arr.push(val);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
export declare const setResultEmpty: (context:
|
|
2
|
+
export declare const setResultEmpty: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any> = HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(context: H) => H;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
export declare const shouldSkip: (hookName: string, context:
|
|
2
|
+
export declare const shouldSkip: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any> = HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(hookName: string, context: H) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feathers-utils",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-4",
|
|
4
4
|
"description": "Some utils for projects using '@feathersjs/feathers'",
|
|
5
5
|
"author": "fratzinger",
|
|
6
6
|
"repository": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@feathersjs/adapter-commons": "5.0.0-pre.29",
|
|
46
46
|
"@feathersjs/errors": "5.0.0-pre.29",
|
|
47
47
|
"@feathersjs/feathers": "5.0.0-pre.29",
|
|
48
|
-
"feathers-hooks-common": "^
|
|
48
|
+
"feathers-hooks-common": "^7.0.0-pre.0",
|
|
49
49
|
"lodash": "^4.17.21",
|
|
50
50
|
"type-fest": "^2.19.0"
|
|
51
51
|
},
|
|
@@ -59,13 +59,16 @@
|
|
|
59
59
|
"@typescript-eslint/parser": "^5.37.0",
|
|
60
60
|
"cross-env": "^7.0.3",
|
|
61
61
|
"eslint": "^8.23.1",
|
|
62
|
+
"eslint-config-prettier": "^8.5.0",
|
|
62
63
|
"eslint-import-resolver-typescript": "^3.5.1",
|
|
63
64
|
"eslint-plugin-import": "^2.26.0",
|
|
65
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
64
66
|
"eslint-plugin-security": "^1.5.0",
|
|
65
67
|
"feathers-memory": "^4.1.0",
|
|
66
68
|
"mocha": "^10.0.0",
|
|
67
69
|
"np": "^7.6.2",
|
|
68
70
|
"nyc": "^15.1.0",
|
|
71
|
+
"prettier": "^2.7.1",
|
|
69
72
|
"shx": "^0.3.4",
|
|
70
73
|
"ts-node": "^10.9.1",
|
|
71
74
|
"typescript": "^4.8.3"
|
package/src/filters/array.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
|
|
2
2
|
import { validateQueryProperty } from "../utils/validateQueryProperty";
|
|
3
3
|
|
|
4
|
-
export const filterArray =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
export const filterArray =
|
|
5
|
+
(key: string) =>
|
|
6
|
+
(arr: any, { operators }: FilterQueryOptions) => {
|
|
7
|
+
if (arr && !Array.isArray(arr)) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`Invalid query parameter '${key}'. It has to be an array`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
if (Array.isArray(arr)) {
|
|
14
|
+
return arr.map((current) => validateQueryProperty(current, operators));
|
|
15
|
+
}
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
};
|
|
17
|
+
return arr;
|
|
18
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
|
|
2
|
+
import { validateQueryProperty } from "../utils/validateQueryProperty";
|
|
3
|
+
import _isObject from "lodash/isObject";
|
|
4
|
+
|
|
5
|
+
export const filterObject =
|
|
6
|
+
(key: string) =>
|
|
7
|
+
(obj: any, { operators }: FilterQueryOptions) => {
|
|
8
|
+
if (obj && !_isObject(obj)) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
`Invalid query parameter: '${key}'. It has to be an object`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return validateQueryProperty(obj, operators);
|
|
15
|
+
};
|
package/src/hooks/checkMulti.ts
CHANGED
|
@@ -3,14 +3,16 @@ import { shouldSkip } from "../utils/shouldSkip";
|
|
|
3
3
|
import { isMulti } from "../utils/isMulti";
|
|
4
4
|
|
|
5
5
|
import type { HookContext } from "@feathersjs/feathers";
|
|
6
|
-
import type { ReturnSyncHook } from "../types";
|
|
7
6
|
|
|
8
|
-
export function checkMulti(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
export function checkMulti<H extends HookContext = HookContext>() {
|
|
8
|
+
return (context: H) => {
|
|
9
|
+
if (shouldSkip("checkMulti", context)) {
|
|
10
|
+
return context;
|
|
11
|
+
}
|
|
12
12
|
const { service, method } = context;
|
|
13
|
-
if (!service.allowsMulti || !isMulti(context) || method === "find") {
|
|
13
|
+
if (!service.allowsMulti || !isMulti(context) || method === "find") {
|
|
14
|
+
return context;
|
|
15
|
+
}
|
|
14
16
|
|
|
15
17
|
if (!service.allowsMulti(method)) {
|
|
16
18
|
throw new MethodNotAllowed(`Can not ${method} multiple entries`);
|
|
@@ -1,40 +1,49 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
2
|
import { checkContext } from "feathers-hooks-common";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Promisable } from "../typesInternal";
|
|
4
4
|
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
5
5
|
|
|
6
|
-
export
|
|
6
|
+
export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
7
|
+
service: keyof S;
|
|
8
|
+
multi?: boolean;
|
|
9
|
+
data: (item: any, context: HookContext) => Promisable<Record<string, any>>;
|
|
10
|
+
createItemsInDataArraySeparately?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createRelated<
|
|
14
|
+
S = Record<string, any>,
|
|
15
|
+
H extends HookContext = HookContext
|
|
16
|
+
>({
|
|
7
17
|
service,
|
|
8
18
|
multi = true,
|
|
9
19
|
data,
|
|
10
|
-
createItemsInDataArraySeparately = true
|
|
20
|
+
createItemsInDataArraySeparately = true,
|
|
11
21
|
}: CreateRelatedOptions<S>) {
|
|
12
22
|
if (!service || !data) {
|
|
13
23
|
throw "initialize hook 'createRelated' completely!";
|
|
14
24
|
}
|
|
15
|
-
return async (context:
|
|
16
|
-
// @ts-expect-error wait for feathers-hooks-common to update
|
|
25
|
+
return async (context: H) => {
|
|
17
26
|
checkContext(context, "after", undefined, "createRelated");
|
|
18
27
|
|
|
19
28
|
const { items } = getItemsIsArray(context);
|
|
20
29
|
|
|
21
|
-
let dataToCreate = (
|
|
22
|
-
items.map(async item => data(item, context))
|
|
23
|
-
)
|
|
30
|
+
let dataToCreate = (
|
|
31
|
+
await Promise.all(items.map(async (item) => data(item, context)))
|
|
32
|
+
).filter((x) => !!x);
|
|
24
33
|
|
|
25
34
|
if (createItemsInDataArraySeparately) {
|
|
26
35
|
dataToCreate = dataToCreate.flat();
|
|
27
36
|
}
|
|
28
37
|
|
|
29
|
-
if (!dataToCreate || dataToCreate.length <= 0) {
|
|
30
|
-
return context;
|
|
38
|
+
if (!dataToCreate || dataToCreate.length <= 0) {
|
|
39
|
+
return context;
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
if (multi) {
|
|
34
43
|
await context.app.service(service as string).create(dataToCreate);
|
|
35
44
|
} else {
|
|
36
45
|
await Promise.all(
|
|
37
|
-
dataToCreate.map(async item =>
|
|
46
|
+
dataToCreate.map(async (item) =>
|
|
38
47
|
context.app.service(service as string).create(item)
|
|
39
48
|
)
|
|
40
49
|
);
|
|
@@ -42,4 +51,4 @@ export function createRelated<S = Record<string, any>>({
|
|
|
42
51
|
|
|
43
52
|
return context;
|
|
44
53
|
};
|
|
45
|
-
}
|
|
54
|
+
}
|
package/src/hooks/onDelete.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
2
|
import { checkContext } from "feathers-hooks-common";
|
|
3
|
-
import type { OnDeleteOptions } from "../types";
|
|
4
3
|
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
5
4
|
|
|
6
|
-
export
|
|
5
|
+
export type OnDeleteAction = "cascade" | "set null";
|
|
6
|
+
|
|
7
|
+
export interface OnDeleteOptions {
|
|
8
|
+
keyThere: string;
|
|
9
|
+
keyHere: string;
|
|
10
|
+
onDelete: OnDeleteAction;
|
|
11
|
+
blocking?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function onDelete<
|
|
15
|
+
S = Record<string, any>,
|
|
16
|
+
H extends HookContext = HookContext
|
|
17
|
+
>(
|
|
7
18
|
service: keyof S,
|
|
8
19
|
{
|
|
9
20
|
keyThere,
|
|
10
21
|
keyHere = "id",
|
|
11
22
|
onDelete = "cascade",
|
|
12
|
-
blocking = true
|
|
13
|
-
}: OnDeleteOptions
|
|
23
|
+
blocking = true,
|
|
24
|
+
}: OnDeleteOptions
|
|
25
|
+
) {
|
|
14
26
|
if (!service || !keyThere) {
|
|
15
27
|
throw "initialize hook 'removeRelated' completely!";
|
|
16
28
|
}
|
|
@@ -18,24 +30,25 @@ export function onDelete<S = Record<string, any>>(
|
|
|
18
30
|
throw "onDelete must be 'cascade' or 'set null'";
|
|
19
31
|
}
|
|
20
32
|
|
|
21
|
-
return async (context:
|
|
22
|
-
// @ts-expect-error wait for feathers-hooks-common to update
|
|
33
|
+
return async (context: H) => {
|
|
23
34
|
checkContext(context, "after", "remove", "onDelete");
|
|
24
35
|
|
|
25
36
|
const { items } = getItemsIsArray(context);
|
|
26
37
|
|
|
27
|
-
let ids = items.map(x => x[keyHere]).filter(x => !!x);
|
|
38
|
+
let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
|
|
28
39
|
ids = [...new Set(ids)];
|
|
29
40
|
|
|
30
|
-
if (!ids || ids.length <= 0) {
|
|
41
|
+
if (!ids || ids.length <= 0) {
|
|
42
|
+
return context;
|
|
43
|
+
}
|
|
31
44
|
|
|
32
45
|
const params = {
|
|
33
46
|
query: {
|
|
34
47
|
[keyThere]: {
|
|
35
|
-
$in: ids
|
|
36
|
-
}
|
|
48
|
+
$in: ids,
|
|
49
|
+
},
|
|
37
50
|
},
|
|
38
|
-
paginate: false
|
|
51
|
+
paginate: false,
|
|
39
52
|
};
|
|
40
53
|
|
|
41
54
|
let promise;
|
|
@@ -44,7 +57,9 @@ export function onDelete<S = Record<string, any>>(
|
|
|
44
57
|
promise = context.app.service(service as string).remove(null, params);
|
|
45
58
|
} else if (onDelete === "set null") {
|
|
46
59
|
const data = { [keyThere]: null };
|
|
47
|
-
promise = context.app
|
|
60
|
+
promise = context.app
|
|
61
|
+
.service(service as string)
|
|
62
|
+
.patch(null, data, params);
|
|
48
63
|
}
|
|
49
64
|
|
|
50
65
|
if (blocking) {
|
|
@@ -53,4 +68,4 @@ export function onDelete<S = Record<string, any>>(
|
|
|
53
68
|
|
|
54
69
|
return context;
|
|
55
70
|
};
|
|
56
|
-
}
|
|
71
|
+
}
|
|
@@ -1,37 +1,49 @@
|
|
|
1
1
|
import type { HookContext, Params, Query } from "@feathersjs/feathers";
|
|
2
2
|
import { checkContext } from "feathers-hooks-common";
|
|
3
|
-
import type { RemoveRelatedOptions } from "../types";
|
|
4
3
|
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
5
4
|
|
|
6
|
-
export
|
|
5
|
+
export interface RemoveRelatedOptions<S = Record<string, any>> {
|
|
6
|
+
service: keyof S;
|
|
7
|
+
keyThere: string;
|
|
8
|
+
keyHere: string;
|
|
9
|
+
blocking?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function removeRelated<
|
|
13
|
+
S = Record<string, any>,
|
|
14
|
+
H extends HookContext = HookContext
|
|
15
|
+
>({
|
|
7
16
|
service,
|
|
8
17
|
keyThere,
|
|
9
18
|
keyHere = "id",
|
|
10
|
-
blocking = true
|
|
19
|
+
blocking = true,
|
|
11
20
|
}: RemoveRelatedOptions<S>) {
|
|
12
21
|
if (!service || !keyThere) {
|
|
13
22
|
throw "initialize hook 'removeRelated' completely!";
|
|
14
23
|
}
|
|
15
|
-
return async (context:
|
|
16
|
-
// @ts-expect-error wait for feathers-hooks-common to update
|
|
24
|
+
return async (context: H) => {
|
|
17
25
|
checkContext(context, "after", "remove", "removeRelated");
|
|
18
26
|
|
|
19
27
|
const { items } = getItemsIsArray(context);
|
|
20
28
|
|
|
21
|
-
let ids = items.map(x => x[keyHere]).filter(x => !!x);
|
|
29
|
+
let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
|
|
22
30
|
ids = [...new Set(ids)];
|
|
23
31
|
|
|
24
|
-
if (!ids || ids.length <= 0) {
|
|
32
|
+
if (!ids || ids.length <= 0) {
|
|
33
|
+
return context;
|
|
34
|
+
}
|
|
25
35
|
|
|
26
36
|
// feathers does not accept `paginate: false` for remove, but some adapters need it to work properly
|
|
27
|
-
const promise: Promise<any> = context.app
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
const promise: Promise<any> = context.app
|
|
38
|
+
.service(service as string)
|
|
39
|
+
.remove(null, {
|
|
40
|
+
query: {
|
|
41
|
+
[keyThere]: {
|
|
42
|
+
$in: ids,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
paginate: false,
|
|
46
|
+
} as Params<Query>);
|
|
35
47
|
|
|
36
48
|
if (blocking) {
|
|
37
49
|
await promise;
|
|
@@ -39,4 +51,4 @@ export function removeRelated<S = Record<string, any>>({
|
|
|
39
51
|
|
|
40
52
|
return context;
|
|
41
53
|
};
|
|
42
|
-
}
|
|
54
|
+
}
|