feathers-utils 2.0.0-9 → 2.1.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.
- package/LICENSE +1 -1
- package/README.md +3 -1
- package/dist/index.cjs +964 -0
- package/dist/index.d.ts +262 -5
- package/dist/index.mjs +938 -0
- package/package.json +35 -38
- package/src/filters/object.ts +1 -1
- package/src/hooks/forEach.ts +47 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/makeSequelizeQuery.ts_ +4 -4
- package/src/hooks/parseFields.ts +27 -0
- package/src/hooks/runPerItem.ts +4 -6
- package/src/hooks/setData.ts +4 -5
- package/src/index.ts +1 -0
- package/src/typesInternal.ts +7 -0
- package/src/utility-types/index.ts +116 -0
- package/src/utils/getItemsIsArray.ts +27 -11
- package/src/utils/getPaginate.ts +2 -1
- package/src/utils/internal.utils.ts +6 -0
- package/src/utils/mergeQuery/mergeQuery.ts +62 -25
- package/src/utils/mergeQuery/utils.ts +82 -29
- package/dist/esm/filters/array.d.ts +0 -2
- package/dist/esm/filters/array.js +0 -17
- package/dist/esm/filters/index.d.ts +0 -2
- package/dist/esm/filters/index.js +0 -2
- package/dist/esm/filters/object.d.ts +0 -2
- package/dist/esm/filters/object.js +0 -15
- package/dist/esm/hooks/checkMulti.d.ts +0 -5
- package/dist/esm/hooks/checkMulti.js +0 -20
- package/dist/esm/hooks/createRelated.d.ts +0 -12
- package/dist/esm/hooks/createRelated.js +0 -31
- package/dist/esm/hooks/index.d.ts +0 -6
- package/dist/esm/hooks/index.js +0 -6
- package/dist/esm/hooks/onDelete.d.ts +0 -12
- package/dist/esm/hooks/onDelete.js +0 -47
- package/dist/esm/hooks/removeRelated.d.ts +0 -11
- package/dist/esm/hooks/removeRelated.js +0 -37
- package/dist/esm/hooks/runPerItem.d.ts +0 -10
- package/dist/esm/hooks/runPerItem.js +0 -29
- package/dist/esm/hooks/setData.d.ts +0 -11
- package/dist/esm/hooks/setData.js +0 -46
- package/dist/esm/index.d.ts +0 -5
- package/dist/esm/index.js +0 -5
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.js +0 -46
- package/dist/esm/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
- package/dist/esm/mixins/debounce-mixin/debounceMixin.js +0 -19
- package/dist/esm/mixins/debounce-mixin/index.d.ts +0 -3
- package/dist/esm/mixins/debounce-mixin/index.js +0 -3
- package/dist/esm/mixins/debounce-mixin/types.d.ts +0 -13
- package/dist/esm/mixins/debounce-mixin/types.js +0 -1
- package/dist/esm/mixins/index.d.ts +0 -1
- package/dist/esm/mixins/index.js +0 -1
- package/dist/esm/types.d.ts +0 -3
- package/dist/esm/types.js +0 -1
- package/dist/esm/typesInternal.d.ts +0 -3
- package/dist/esm/typesInternal.js +0 -3
- package/dist/esm/utils/filterQuery.d.ts +0 -8
- package/dist/esm/utils/filterQuery.js +0 -30
- package/dist/esm/utils/getItemsIsArray.d.ts +0 -10
- package/dist/esm/utils/getItemsIsArray.js +0 -16
- package/dist/esm/utils/getPaginate.d.ts +0 -9
- package/dist/esm/utils/getPaginate.js +0 -20
- package/dist/esm/utils/index.d.ts +0 -11
- package/dist/esm/utils/index.js +0 -11
- package/dist/esm/utils/isMulti.d.ts +0 -11
- package/dist/esm/utils/isMulti.js +0 -26
- package/dist/esm/utils/isPaginated.d.ts +0 -5
- package/dist/esm/utils/isPaginated.js +0 -11
- package/dist/esm/utils/markHookForSkip.d.ts +0 -7
- package/dist/esm/utils/markHookForSkip.js +0 -18
- package/dist/esm/utils/mergeQuery/index.d.ts +0 -3
- package/dist/esm/utils/mergeQuery/index.js +0 -3
- package/dist/esm/utils/mergeQuery/mergeArrays.d.ts +0 -3
- package/dist/esm/utils/mergeQuery/mergeArrays.js +0 -37
- package/dist/esm/utils/mergeQuery/mergeQuery.d.ts +0 -3
- package/dist/esm/utils/mergeQuery/mergeQuery.js +0 -70
- package/dist/esm/utils/mergeQuery/types.d.ts +0 -13
- package/dist/esm/utils/mergeQuery/types.js +0 -1
- package/dist/esm/utils/mergeQuery/utils.d.ts +0 -11
- package/dist/esm/utils/mergeQuery/utils.js +0 -272
- package/dist/esm/utils/pushSet.d.ts +0 -8
- package/dist/esm/utils/pushSet.js +0 -22
- package/dist/esm/utils/setResultEmpty.d.ts +0 -5
- package/dist/esm/utils/setResultEmpty.js +0 -28
- package/dist/esm/utils/shouldSkip.d.ts +0 -8
- package/dist/esm/utils/shouldSkip.js +0 -29
- package/dist/esm/utils/validateQueryProperty.d.ts +0 -5
- package/dist/esm/utils/validateQueryProperty.js +0 -23
- package/dist/filters/array.d.ts +0 -2
- package/dist/filters/array.js +0 -21
- package/dist/filters/index.d.ts +0 -2
- package/dist/filters/index.js +0 -18
- package/dist/filters/object.d.ts +0 -2
- package/dist/filters/object.js +0 -22
- package/dist/hooks/checkMulti.d.ts +0 -5
- package/dist/hooks/checkMulti.js +0 -24
- package/dist/hooks/createRelated.d.ts +0 -12
- package/dist/hooks/createRelated.js +0 -44
- package/dist/hooks/index.d.ts +0 -6
- package/dist/hooks/index.js +0 -22
- package/dist/hooks/onDelete.d.ts +0 -12
- package/dist/hooks/onDelete.js +0 -60
- package/dist/hooks/removeRelated.d.ts +0 -11
- package/dist/hooks/removeRelated.js +0 -50
- package/dist/hooks/runPerItem.d.ts +0 -10
- package/dist/hooks/runPerItem.js +0 -42
- package/dist/hooks/setData.d.ts +0 -11
- package/dist/hooks/setData.js +0 -54
- package/dist/index.js +0 -21
- package/dist/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
- package/dist/mixins/debounce-mixin/DebouncedStore.js +0 -65
- package/dist/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
- package/dist/mixins/debounce-mixin/debounceMixin.js +0 -23
- package/dist/mixins/debounce-mixin/index.d.ts +0 -3
- package/dist/mixins/debounce-mixin/index.js +0 -19
- package/dist/mixins/debounce-mixin/types.d.ts +0 -13
- package/dist/mixins/debounce-mixin/types.js +0 -2
- package/dist/mixins/index.d.ts +0 -1
- package/dist/mixins/index.js +0 -17
- package/dist/types.d.ts +0 -3
- package/dist/types.js +0 -2
- package/dist/typesInternal.d.ts +0 -3
- package/dist/typesInternal.js +0 -4
- package/dist/utils/filterQuery.d.ts +0 -8
- package/dist/utils/filterQuery.js +0 -46
- package/dist/utils/getItemsIsArray.d.ts +0 -10
- package/dist/utils/getItemsIsArray.js +0 -20
- package/dist/utils/getPaginate.d.ts +0 -9
- package/dist/utils/getPaginate.js +0 -22
- package/dist/utils/index.d.ts +0 -11
- package/dist/utils/index.js +0 -27
- package/dist/utils/isMulti.d.ts +0 -11
- package/dist/utils/isMulti.js +0 -30
- package/dist/utils/isPaginated.d.ts +0 -5
- package/dist/utils/isPaginated.js +0 -15
- package/dist/utils/markHookForSkip.d.ts +0 -7
- package/dist/utils/markHookForSkip.js +0 -22
- package/dist/utils/mergeQuery/index.d.ts +0 -3
- package/dist/utils/mergeQuery/index.js +0 -19
- package/dist/utils/mergeQuery/mergeArrays.d.ts +0 -3
- package/dist/utils/mergeQuery/mergeArrays.js +0 -41
- package/dist/utils/mergeQuery/mergeQuery.d.ts +0 -3
- package/dist/utils/mergeQuery/mergeQuery.js +0 -77
- package/dist/utils/mergeQuery/types.d.ts +0 -13
- package/dist/utils/mergeQuery/types.js +0 -2
- package/dist/utils/mergeQuery/utils.d.ts +0 -11
- package/dist/utils/mergeQuery/utils.js +0 -287
- package/dist/utils/pushSet.d.ts +0 -8
- package/dist/utils/pushSet.js +0 -29
- package/dist/utils/setResultEmpty.d.ts +0 -5
- package/dist/utils/setResultEmpty.js +0 -32
- package/dist/utils/shouldSkip.d.ts +0 -8
- package/dist/utils/shouldSkip.js +0 -33
- package/dist/utils/validateQueryProperty.d.ts +0 -5
- package/dist/utils/validateQueryProperty.js +0 -25
|
@@ -2,20 +2,15 @@ import { Forbidden } from "@feathersjs/errors";
|
|
|
2
2
|
import _get from "lodash/get.js";
|
|
3
3
|
import _has from "lodash/has.js";
|
|
4
4
|
import _isEmpty from "lodash/isEmpty.js";
|
|
5
|
-
import _isEqual from "lodash/isEqual.js";
|
|
6
5
|
|
|
7
6
|
import _set from "lodash/set.js";
|
|
8
7
|
import _uniqWith from "lodash/uniqWith.js";
|
|
9
8
|
import type { Path } from "../../typesInternal";
|
|
10
9
|
import { mergeArrays } from "./mergeArrays";
|
|
11
10
|
import type { Handle, MergeQueryOptions } from "./types";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
key: string
|
|
16
|
-
): boolean => {
|
|
17
|
-
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
18
|
-
};
|
|
11
|
+
import { deepEqual as _isEqual } from "fast-equals";
|
|
12
|
+
import type { Query } from "@feathersjs/feathers";
|
|
13
|
+
import { hasOwnProperty } from "../internal.utils";
|
|
19
14
|
|
|
20
15
|
export function handleArray<T>(
|
|
21
16
|
target: Record<string, unknown>,
|
|
@@ -265,19 +260,12 @@ export function handleCircular<T>(
|
|
|
265
260
|
export function makeDefaultOptions<T>(
|
|
266
261
|
options?: Partial<MergeQueryOptions<T>>
|
|
267
262
|
): MergeQueryOptions<T> {
|
|
268
|
-
options
|
|
269
|
-
options.defaultHandle
|
|
270
|
-
options.useLogicalConjunction
|
|
271
|
-
|
|
272
|
-
"
|
|
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
|
-
});
|
|
263
|
+
options ??= {} as MergeQueryOptions<T>;
|
|
264
|
+
options.defaultHandle ??= "combine";
|
|
265
|
+
options.useLogicalConjunction ??= false;
|
|
266
|
+
options.actionOnEmptyIntersect ??= () => {
|
|
267
|
+
throw new Forbidden("You're not allowed to make this request");
|
|
268
|
+
};
|
|
281
269
|
options.handle = options.handle || {};
|
|
282
270
|
if (options.defaultHandle === "intersect") {
|
|
283
271
|
options.handle.$select = options.handle.$select || "intersectOrFull";
|
|
@@ -286,15 +274,17 @@ export function makeDefaultOptions<T>(
|
|
|
286
274
|
}
|
|
287
275
|
|
|
288
276
|
export function moveProperty(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
277
|
+
from: Record<string, any>,
|
|
278
|
+
to: Record<string, any>,
|
|
279
|
+
...keys: string[]
|
|
292
280
|
): void {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
281
|
+
keys.forEach((key) => {
|
|
282
|
+
if (!hasOwnProperty(from, key)) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
to[key] = from[key];
|
|
286
|
+
delete from[key];
|
|
287
|
+
});
|
|
298
288
|
}
|
|
299
289
|
|
|
300
290
|
export function getParentProp(target: Record<string, unknown>, path: Path) {
|
|
@@ -338,5 +328,68 @@ export function arrayWithoutDuplicates<T>(target: T[]): T[] {
|
|
|
338
328
|
if (!target || !Array.isArray(target)) {
|
|
339
329
|
return target;
|
|
340
330
|
}
|
|
331
|
+
|
|
341
332
|
return _uniqWith(target, _isEqual);
|
|
342
333
|
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Checks if one query is a superset of the target query
|
|
337
|
+
* @param target The target query
|
|
338
|
+
* @param source The source query
|
|
339
|
+
* @returns The query that is the superset of the other query, returns undefined otherwise
|
|
340
|
+
*/
|
|
341
|
+
export function isQueryMoreExplicitThanQuery(
|
|
342
|
+
target: Query,
|
|
343
|
+
source: Query
|
|
344
|
+
): Query | undefined {
|
|
345
|
+
if (!target || !source) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const targetKeys = Object.keys(target);
|
|
350
|
+
const sourceKeys = Object.keys(source);
|
|
351
|
+
|
|
352
|
+
// sourceQuery: {}; targetQuery: { something }
|
|
353
|
+
if (!sourceKeys.length) {
|
|
354
|
+
return target;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// sourceQuery: { something }; targetQuery: {}
|
|
358
|
+
if (!targetKeys.length) {
|
|
359
|
+
return source;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (targetKeys.every((key) => _isEqual(target[key], source[key]))) {
|
|
363
|
+
// every property of target is exactly in source
|
|
364
|
+
return source;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (sourceKeys.every((key) => _isEqual(target[key], source[key]))) {
|
|
368
|
+
// every property of source is exactly in target
|
|
369
|
+
return target;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export function areQueriesOverlapping(target: Query, source: Query): boolean {
|
|
376
|
+
if (!target || !source) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const targetKeys = Object.keys(target);
|
|
381
|
+
const sourceKeys = Object.keys(source);
|
|
382
|
+
|
|
383
|
+
if (!sourceKeys.length || !targetKeys.length) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (
|
|
388
|
+
targetKeys.some((x) => sourceKeys.includes(x)) ||
|
|
389
|
+
sourceKeys.some((x) => targetKeys.includes(x))
|
|
390
|
+
) {
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { validateQueryProperty } from "../utils/validateQueryProperty";
|
|
2
|
-
const filterQueryArray = (key) => (arr, { operators }) => {
|
|
3
|
-
if (arr && !Array.isArray(arr)) {
|
|
4
|
-
throw new Error(`Invalid query parameter '${key}'. It has to be an array`);
|
|
5
|
-
}
|
|
6
|
-
if (Array.isArray(arr)) {
|
|
7
|
-
return arr.map((current) => validateQueryProperty(current, operators));
|
|
8
|
-
}
|
|
9
|
-
return arr;
|
|
10
|
-
};
|
|
11
|
-
export const filterArray = (...keys) => {
|
|
12
|
-
const result = {};
|
|
13
|
-
for (const key of keys) {
|
|
14
|
-
result[key] = filterQueryArray(key);
|
|
15
|
-
}
|
|
16
|
-
return result;
|
|
17
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { validateQueryProperty } from "../utils/validateQueryProperty";
|
|
2
|
-
import _isObject from "lodash/isObject";
|
|
3
|
-
const filterQueryObject = (key) => (obj, { operators }) => {
|
|
4
|
-
if (obj && !_isObject(obj)) {
|
|
5
|
-
throw new Error(`Invalid query parameter: '${key}'. It has to be an object`);
|
|
6
|
-
}
|
|
7
|
-
return validateQueryProperty(obj, operators);
|
|
8
|
-
};
|
|
9
|
-
export const filterObject = (...keys) => {
|
|
10
|
-
const result = {};
|
|
11
|
-
for (const key of keys) {
|
|
12
|
-
result[key] = filterQueryObject(key);
|
|
13
|
-
}
|
|
14
|
-
return result;
|
|
15
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { MethodNotAllowed } from "@feathersjs/errors";
|
|
2
|
-
import { shouldSkip, isMulti } from "../utils";
|
|
3
|
-
/**
|
|
4
|
-
* hook to check if context is multi patch/remove and if the service allows it
|
|
5
|
-
*/
|
|
6
|
-
export function checkMulti() {
|
|
7
|
-
return (context) => {
|
|
8
|
-
if (shouldSkip("checkMulti", context)) {
|
|
9
|
-
return context;
|
|
10
|
-
}
|
|
11
|
-
const { service, method } = context;
|
|
12
|
-
if (!service.allowsMulti || !isMulti(context) || method === "find") {
|
|
13
|
-
return context;
|
|
14
|
-
}
|
|
15
|
-
if (!service.allowsMulti(method)) {
|
|
16
|
-
throw new MethodNotAllowed(`Can not ${method} multiple entries`);
|
|
17
|
-
}
|
|
18
|
-
return context;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
import type { Promisable } from "../typesInternal";
|
|
3
|
-
export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
4
|
-
service: keyof S;
|
|
5
|
-
multi?: boolean;
|
|
6
|
-
data: (item: any, context: HookContext) => Promisable<Record<string, any>>;
|
|
7
|
-
createItemsInDataArraySeparately?: boolean;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* hook to create related items
|
|
11
|
-
*/
|
|
12
|
-
export declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, multi, data, createItemsInDataArraySeparately, }: CreateRelatedOptions<S>): (context: H) => Promise<H>;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { checkContext } from "feathers-hooks-common";
|
|
2
|
-
import { getItemsIsArray, shouldSkip } from "../utils";
|
|
3
|
-
/**
|
|
4
|
-
* hook to create related items
|
|
5
|
-
*/
|
|
6
|
-
export function createRelated({ service, multi = true, data, createItemsInDataArraySeparately = true, }) {
|
|
7
|
-
if (!service || !data) {
|
|
8
|
-
throw "initialize hook 'createRelated' completely!";
|
|
9
|
-
}
|
|
10
|
-
return async (context) => {
|
|
11
|
-
if (shouldSkip("createRelated", context)) {
|
|
12
|
-
return context;
|
|
13
|
-
}
|
|
14
|
-
checkContext(context, "after", undefined, "createRelated");
|
|
15
|
-
const { items } = getItemsIsArray(context);
|
|
16
|
-
let dataToCreate = (await Promise.all(items.map(async (item) => data(item, context)))).filter((x) => !!x);
|
|
17
|
-
if (createItemsInDataArraySeparately) {
|
|
18
|
-
dataToCreate = dataToCreate.flat();
|
|
19
|
-
}
|
|
20
|
-
if (!dataToCreate || dataToCreate.length <= 0) {
|
|
21
|
-
return context;
|
|
22
|
-
}
|
|
23
|
-
if (multi) {
|
|
24
|
-
await context.app.service(service).create(dataToCreate);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
await Promise.all(dataToCreate.map(async (item) => context.app.service(service).create(item)));
|
|
28
|
-
}
|
|
29
|
-
return context;
|
|
30
|
-
};
|
|
31
|
-
}
|
package/dist/esm/hooks/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
export type OnDeleteAction = "cascade" | "set null";
|
|
3
|
-
export interface OnDeleteOptions {
|
|
4
|
-
keyThere: string;
|
|
5
|
-
keyHere: string;
|
|
6
|
-
onDelete: OnDeleteAction;
|
|
7
|
-
blocking?: boolean;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* hook to manipulate related items on delete
|
|
11
|
-
*/
|
|
12
|
-
export declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(service: keyof S, { keyThere, keyHere, onDelete, blocking, }: OnDeleteOptions): (context: H) => Promise<H>;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { checkContext } from "feathers-hooks-common";
|
|
2
|
-
import { getItemsIsArray, shouldSkip } from "../utils";
|
|
3
|
-
/**
|
|
4
|
-
* hook to manipulate related items on delete
|
|
5
|
-
*/
|
|
6
|
-
export function onDelete(service, { keyThere, keyHere = "id", onDelete = "cascade", blocking = true, }) {
|
|
7
|
-
if (!service || !keyThere) {
|
|
8
|
-
throw "initialize hook 'removeRelated' completely!";
|
|
9
|
-
}
|
|
10
|
-
if (!["cascade", "set null"].includes(onDelete)) {
|
|
11
|
-
throw "onDelete must be 'cascade' or 'set null'";
|
|
12
|
-
}
|
|
13
|
-
return async (context) => {
|
|
14
|
-
if (shouldSkip("onDelete", context)) {
|
|
15
|
-
return context;
|
|
16
|
-
}
|
|
17
|
-
checkContext(context, "after", "remove", "onDelete");
|
|
18
|
-
const { items } = getItemsIsArray(context);
|
|
19
|
-
let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
|
|
20
|
-
ids = [...new Set(ids)];
|
|
21
|
-
if (!ids || ids.length <= 0) {
|
|
22
|
-
return context;
|
|
23
|
-
}
|
|
24
|
-
const params = {
|
|
25
|
-
query: {
|
|
26
|
-
[keyThere]: {
|
|
27
|
-
$in: ids,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
paginate: false,
|
|
31
|
-
};
|
|
32
|
-
let promise;
|
|
33
|
-
if (onDelete === "cascade") {
|
|
34
|
-
promise = context.app.service(service).remove(null, params);
|
|
35
|
-
}
|
|
36
|
-
else if (onDelete === "set null") {
|
|
37
|
-
const data = { [keyThere]: null };
|
|
38
|
-
promise = context.app
|
|
39
|
-
.service(service)
|
|
40
|
-
.patch(null, data, params);
|
|
41
|
-
}
|
|
42
|
-
if (blocking) {
|
|
43
|
-
await promise;
|
|
44
|
-
}
|
|
45
|
-
return context;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
export interface RemoveRelatedOptions<S = Record<string, any>> {
|
|
3
|
-
service: keyof S;
|
|
4
|
-
keyThere: string;
|
|
5
|
-
keyHere: string;
|
|
6
|
-
blocking?: boolean;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* hook to remove related items
|
|
10
|
-
*/
|
|
11
|
-
export declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { checkContext } from "feathers-hooks-common";
|
|
2
|
-
import { getItemsIsArray, shouldSkip } from "../utils";
|
|
3
|
-
/**
|
|
4
|
-
* hook to remove related items
|
|
5
|
-
*/
|
|
6
|
-
export function removeRelated({ service, keyThere, keyHere = "id", blocking = true, }) {
|
|
7
|
-
if (!service || !keyThere) {
|
|
8
|
-
throw "initialize hook 'removeRelated' completely!";
|
|
9
|
-
}
|
|
10
|
-
return async (context) => {
|
|
11
|
-
if (shouldSkip("removeRelated", context)) {
|
|
12
|
-
return context;
|
|
13
|
-
}
|
|
14
|
-
checkContext(context, "after", "remove", "removeRelated");
|
|
15
|
-
const { items } = getItemsIsArray(context);
|
|
16
|
-
let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
|
|
17
|
-
ids = [...new Set(ids)];
|
|
18
|
-
if (!ids || ids.length <= 0) {
|
|
19
|
-
return context;
|
|
20
|
-
}
|
|
21
|
-
// feathers does not accept `paginate: false` for remove, but some adapters need it to work properly
|
|
22
|
-
const promise = context.app
|
|
23
|
-
.service(service)
|
|
24
|
-
.remove(null, {
|
|
25
|
-
query: {
|
|
26
|
-
[keyThere]: {
|
|
27
|
-
$in: ids,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
paginate: false,
|
|
31
|
-
});
|
|
32
|
-
if (blocking) {
|
|
33
|
-
await promise;
|
|
34
|
-
}
|
|
35
|
-
return context;
|
|
36
|
-
};
|
|
37
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
import type { Promisable } from "../typesInternal";
|
|
3
|
-
export interface HookRunPerItemOptions {
|
|
4
|
-
wait?: boolean;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* hook to run a hook for each item in the context
|
|
8
|
-
* uses `context.result` if it is existent. otherwise uses context.data
|
|
9
|
-
*/
|
|
10
|
-
export declare const runPerItem: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any> = HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(actionPerItem: (item: any, context: H) => Promisable<any>, _options?: HookRunPerItemOptions) => (context: H) => Promise<H>;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { shouldSkip, getItemsIsArray } from "../utils";
|
|
2
|
-
const makeOptions = (options) => {
|
|
3
|
-
options = options || {};
|
|
4
|
-
return Object.assign({
|
|
5
|
-
wait: true,
|
|
6
|
-
}, options);
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* hook to run a hook for each item in the context
|
|
10
|
-
* uses `context.result` if it is existent. otherwise uses context.data
|
|
11
|
-
*/
|
|
12
|
-
export const runPerItem = (
|
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
-
actionPerItem, _options) => {
|
|
15
|
-
const options = makeOptions(_options);
|
|
16
|
-
return async (context) => {
|
|
17
|
-
if (shouldSkip("runForItems", context)) {
|
|
18
|
-
return context;
|
|
19
|
-
}
|
|
20
|
-
const { items } = getItemsIsArray(context);
|
|
21
|
-
const promises = items.map(async (item) => {
|
|
22
|
-
await actionPerItem(item, context);
|
|
23
|
-
});
|
|
24
|
-
if (options.wait) {
|
|
25
|
-
await Promise.all(promises);
|
|
26
|
-
}
|
|
27
|
-
return context;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
import type { PropertyPath } from "lodash";
|
|
3
|
-
import type { PredicateWithContext } from "../types";
|
|
4
|
-
export interface HookSetDataOptions {
|
|
5
|
-
allowUndefined?: boolean;
|
|
6
|
-
overwrite?: boolean | PredicateWithContext;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* hook to set properties on `context.result` (if existent) or `context.data` (otherwise)
|
|
10
|
-
*/
|
|
11
|
-
export declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import _get from "lodash/get.js";
|
|
2
|
-
import _set from "lodash/set.js";
|
|
3
|
-
import _has from "lodash/has.js";
|
|
4
|
-
import { Forbidden } from "@feathersjs/errors";
|
|
5
|
-
import { getItemsIsArray, shouldSkip } from "../utils";
|
|
6
|
-
const defaultOptions = {
|
|
7
|
-
allowUndefined: false,
|
|
8
|
-
overwrite: true,
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* hook to set properties on `context.result` (if existent) or `context.data` (otherwise)
|
|
12
|
-
*/
|
|
13
|
-
export function setData(from, to, _options) {
|
|
14
|
-
const options = Object.assign({}, defaultOptions, _options);
|
|
15
|
-
return (context) => {
|
|
16
|
-
if (shouldSkip("setData", context)) {
|
|
17
|
-
return context;
|
|
18
|
-
}
|
|
19
|
-
const { items } = getItemsIsArray(context);
|
|
20
|
-
if (!_has(context, from)) {
|
|
21
|
-
if (!context.params?.provider || options.allowUndefined === true) {
|
|
22
|
-
return context;
|
|
23
|
-
}
|
|
24
|
-
if (!options.overwrite &&
|
|
25
|
-
items.every((item) => _has(item, to))) {
|
|
26
|
-
return context;
|
|
27
|
-
}
|
|
28
|
-
throw new Forbidden(`Expected field ${from.toString()} not available`);
|
|
29
|
-
}
|
|
30
|
-
const val = _get(context, from);
|
|
31
|
-
items.forEach((item) => {
|
|
32
|
-
let overwrite;
|
|
33
|
-
if (typeof options.overwrite === "function") {
|
|
34
|
-
overwrite = options.overwrite(item, context);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
overwrite = options.overwrite;
|
|
38
|
-
}
|
|
39
|
-
if (!overwrite && _has(item, to)) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
_set(item, to, val);
|
|
43
|
-
});
|
|
44
|
-
return context;
|
|
45
|
-
};
|
|
46
|
-
}
|
package/dist/esm/index.d.ts
DELETED
package/dist/esm/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { DebouncedFunc } from "lodash";
|
|
2
|
-
import type { Application, Id } from "@feathersjs/feathers";
|
|
3
|
-
import type { DebouncedFunctionApp, DebouncedStoreOptions } from "./types";
|
|
4
|
-
export declare const makeDefaultOptions: () => DebouncedStoreOptions;
|
|
5
|
-
export type DebouncedService<T = any> = T & {
|
|
6
|
-
debouncedStore: DebouncedStore;
|
|
7
|
-
};
|
|
8
|
-
export declare class DebouncedStore {
|
|
9
|
-
private _app;
|
|
10
|
-
private _options;
|
|
11
|
-
private _isRunningById;
|
|
12
|
-
_queueById: Record<string, DebouncedFunc<(id: Id, action: DebouncedFunctionApp) => void | Promise<void>>>;
|
|
13
|
-
add: (id: Id, action: (app?: Application) => void | Promise<void>) => void | Promise<void> | undefined;
|
|
14
|
-
constructor(app: Application, options?: Partial<DebouncedStoreOptions>);
|
|
15
|
-
private unbounced;
|
|
16
|
-
private debounceById;
|
|
17
|
-
cancel(id: Id): void;
|
|
18
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import _debounce from "lodash/debounce.js";
|
|
2
|
-
export const makeDefaultOptions = () => {
|
|
3
|
-
return {
|
|
4
|
-
leading: false,
|
|
5
|
-
maxWait: undefined,
|
|
6
|
-
trailing: true,
|
|
7
|
-
wait: 100,
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
export class DebouncedStore {
|
|
11
|
-
constructor(app, options) {
|
|
12
|
-
this._app = app;
|
|
13
|
-
this._options = Object.assign(makeDefaultOptions(), options);
|
|
14
|
-
this._queueById = {};
|
|
15
|
-
this._isRunningById = {};
|
|
16
|
-
//this._waitingById = {};
|
|
17
|
-
this.add = this.debounceById(this.unbounced, this._options.wait, {
|
|
18
|
-
leading: this._options.leading,
|
|
19
|
-
maxWait: this._options.maxWait,
|
|
20
|
-
trailing: this._options.trailing,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
async unbounced(id, action) {
|
|
24
|
-
if (this._queueById[id] === undefined) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
delete this._queueById[id];
|
|
28
|
-
this._isRunningById[id] = true;
|
|
29
|
-
await action(this._app);
|
|
30
|
-
delete this._isRunningById[id];
|
|
31
|
-
}
|
|
32
|
-
debounceById(func, wait, options) {
|
|
33
|
-
return (id, action) => {
|
|
34
|
-
if (typeof this._queueById[id] === "function") {
|
|
35
|
-
return this._queueById[id](id, action);
|
|
36
|
-
}
|
|
37
|
-
this._queueById[id] = _debounce((id, action) => {
|
|
38
|
-
this.unbounced(id, action);
|
|
39
|
-
}, wait, { ...options, leading: false }); // leading required for return promise
|
|
40
|
-
return this._queueById[id](id, action);
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
cancel(id) {
|
|
44
|
-
delete this._queueById[id];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { DebouncedStore, makeDefaultOptions } from "./DebouncedStore";
|
|
2
|
-
export function debounceMixin(options) {
|
|
3
|
-
return (app) => {
|
|
4
|
-
options = options || {};
|
|
5
|
-
const defaultOptions = Object.assign(makeDefaultOptions(), options?.default);
|
|
6
|
-
app.mixins.push((service, path) => {
|
|
7
|
-
// if path is on blacklist, don't add debouncedStore to service
|
|
8
|
-
if (options?.blacklist && options.blacklist.includes(path))
|
|
9
|
-
return;
|
|
10
|
-
// if service already has registered something on `debouncedStore`
|
|
11
|
-
if (service.debouncedStore) {
|
|
12
|
-
console.warn(`[feathers-utils] service: '${path}' already has a property 'debouncedStore'. Mixin will skip creating a new debouncedStore`);
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const serviceOptions = Object.assign({}, defaultOptions, options?.[path]);
|
|
16
|
-
service.debouncedStore = new DebouncedStore(app, serviceOptions);
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Application } from "@feathersjs/feathers";
|
|
2
|
-
export interface InitDebounceMixinOptions {
|
|
3
|
-
default: Partial<DebouncedStoreOptions>;
|
|
4
|
-
blacklist: string[];
|
|
5
|
-
[key: string]: unknown;
|
|
6
|
-
}
|
|
7
|
-
export type DebouncedFunctionApp = (app?: Application) => void | Promise<void>;
|
|
8
|
-
export interface DebouncedStoreOptions {
|
|
9
|
-
leading: boolean;
|
|
10
|
-
maxWait: number | undefined;
|
|
11
|
-
trailing: boolean;
|
|
12
|
-
wait: number;
|
|
13
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./debounce-mixin";
|
package/dist/esm/mixins/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./debounce-mixin";
|
package/dist/esm/types.d.ts
DELETED
package/dist/esm/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|