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
package/src/hooks/runPerItem.ts
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
import { shouldSkip } from "../utils/shouldSkip";
|
|
2
2
|
|
|
3
|
-
import type { HookRunPerItemOptions, ReturnAsyncHook, Promisable } from "../types";
|
|
4
3
|
import type { HookContext } from "@feathersjs/feathers";
|
|
5
4
|
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
5
|
+
import type { Promisable } from "../typesInternal";
|
|
6
|
+
|
|
7
|
+
export interface HookRunPerItemOptions {
|
|
8
|
+
wait?: boolean;
|
|
9
|
+
}
|
|
6
10
|
|
|
7
11
|
const makeOptions = (
|
|
8
12
|
options?: HookRunPerItemOptions
|
|
9
13
|
): Required<HookRunPerItemOptions> => {
|
|
10
14
|
options = options || {};
|
|
11
|
-
return Object.assign(
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
return Object.assign(
|
|
16
|
+
{
|
|
17
|
+
wait: true,
|
|
18
|
+
},
|
|
19
|
+
options
|
|
20
|
+
);
|
|
14
21
|
};
|
|
15
22
|
|
|
16
|
-
export const runPerItem = (
|
|
23
|
+
export const runPerItem = <H extends HookContext = HookContext>(
|
|
17
24
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
-
actionPerItem: (item: any, context:
|
|
25
|
+
actionPerItem: (item: any, context: H) => Promisable<any>,
|
|
19
26
|
_options?: HookRunPerItemOptions
|
|
20
|
-
)
|
|
27
|
+
) => {
|
|
21
28
|
const options = makeOptions(_options);
|
|
22
|
-
return async (context:
|
|
23
|
-
if (shouldSkip("runForItems", context)) {
|
|
29
|
+
return async (context: H) => {
|
|
30
|
+
if (shouldSkip("runForItems", context)) {
|
|
31
|
+
return context;
|
|
32
|
+
}
|
|
24
33
|
|
|
25
34
|
const { items } = getItemsIsArray(context);
|
|
26
35
|
|
|
@@ -34,4 +43,4 @@ export const runPerItem = (
|
|
|
34
43
|
|
|
35
44
|
return context;
|
|
36
45
|
};
|
|
37
|
-
};
|
|
46
|
+
};
|
package/src/hooks/setData.ts
CHANGED
|
@@ -7,25 +7,29 @@ import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
|
7
7
|
|
|
8
8
|
import type { HookContext } from "@feathersjs/feathers";
|
|
9
9
|
import type { PropertyPath } from "lodash";
|
|
10
|
+
import type { PredicateWithContext } from "../types";
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
12
|
+
export interface HookSetDataOptions {
|
|
13
|
+
allowUndefined?: boolean;
|
|
14
|
+
overwrite?: boolean | PredicateWithContext;
|
|
15
|
+
}
|
|
15
16
|
|
|
16
17
|
const defaultOptions: Required<HookSetDataOptions> = {
|
|
17
18
|
allowUndefined: false,
|
|
18
|
-
overwrite: true
|
|
19
|
+
overwrite: true,
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
export function setData(
|
|
22
|
-
from: PropertyPath,
|
|
23
|
-
to: PropertyPath,
|
|
22
|
+
export function setData<H extends HookContext = HookContext>(
|
|
23
|
+
from: PropertyPath,
|
|
24
|
+
to: PropertyPath,
|
|
24
25
|
_options?: HookSetDataOptions
|
|
25
|
-
)
|
|
26
|
-
const options: Required<HookSetDataOptions> = Object.assign(
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
) {
|
|
27
|
+
const options: Required<HookSetDataOptions> = Object.assign(
|
|
28
|
+
{},
|
|
29
|
+
defaultOptions,
|
|
30
|
+
_options
|
|
31
|
+
);
|
|
32
|
+
return (context: H) => {
|
|
29
33
|
const { items } = getItemsIsArray(context);
|
|
30
34
|
|
|
31
35
|
if (!_has(context, from)) {
|
|
@@ -33,7 +37,10 @@ export function setData(
|
|
|
33
37
|
return context;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
if (
|
|
40
|
+
if (
|
|
41
|
+
!options.overwrite &&
|
|
42
|
+
items.every((item: Record<string, unknown>) => _has(item, to))
|
|
43
|
+
) {
|
|
37
44
|
return context;
|
|
38
45
|
}
|
|
39
46
|
|
|
@@ -50,11 +57,13 @@ export function setData(
|
|
|
50
57
|
overwrite = options.overwrite;
|
|
51
58
|
}
|
|
52
59
|
|
|
53
|
-
if (!overwrite && _has(item, to)) {
|
|
60
|
+
if (!overwrite && _has(item, to)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
54
63
|
|
|
55
64
|
_set(item, to, val);
|
|
56
65
|
});
|
|
57
66
|
|
|
58
67
|
return context;
|
|
59
68
|
};
|
|
60
|
-
}
|
|
69
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,50 +1,33 @@
|
|
|
1
1
|
// hooks
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
export * from "./hooks/checkMulti";
|
|
3
|
+
export * from "./hooks/createRelated";
|
|
4
|
+
export * from "./hooks/onDelete";
|
|
5
|
+
export * from "./hooks/removeRelated";
|
|
6
|
+
export * from "./hooks/runPerItem";
|
|
7
|
+
export * from "./hooks/setData";
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
// mixins
|
|
10
|
+
export * from "./mixins/debounce-mixin";
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
setData,
|
|
10
|
-
runPerItem
|
|
11
|
-
};
|
|
12
|
+
// utils
|
|
13
|
+
export * from "./utils/isMulti";
|
|
12
14
|
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export { setData };
|
|
16
|
-
export { removeRelated } from "./hooks/removeRelated";
|
|
17
|
-
export { runPerItem };
|
|
15
|
+
export * from "./utils/getPaginate";
|
|
16
|
+
export * from "./utils/isPaginated";
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
export * from "./utils/mergeQuery";
|
|
19
|
+
export * from "./utils/pushSet";
|
|
20
|
+
export * from "./utils/setResultEmpty";
|
|
21
|
+
export * from "./utils/filterQuery";
|
|
22
|
+
export * from "./utils/getItemsIsArray";
|
|
20
23
|
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
DebouncedStore
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export { debounceMixin };
|
|
27
|
-
export { DebouncedService };
|
|
28
|
-
export { DebouncedStore };
|
|
29
|
-
|
|
30
|
-
export { getPaginate } from "./utils/getPaginate";
|
|
31
|
-
export { isMulti } from "./utils/isMulti";
|
|
32
|
-
export { isPaginated } from "./utils/isPaginated";
|
|
33
|
-
export { mergeQuery } from "./utils/mergeQuery/index";
|
|
34
|
-
export { mergeArrays } from "./utils/mergeQuery/mergeArrays";
|
|
35
|
-
export { pushSet } from "./utils/pushSet";
|
|
36
|
-
export { setResultEmpty } from "./utils/setResultEmpty";
|
|
37
|
-
|
|
38
|
-
export { markHookForSkip } from "./utils/markHookForSkip";
|
|
39
|
-
export { filterQuery } from "./utils/filterQuery";
|
|
40
|
-
export { getItemsIsArray } from "./utils/getItemsIsArray";
|
|
41
|
-
export { onDelete } from "./hooks/onDelete";
|
|
42
|
-
export { shouldSkip } from "./utils/shouldSkip";
|
|
43
|
-
|
|
44
|
-
export { validateQueryProperty } from "./utils/validateQueryProperty";
|
|
24
|
+
export * from "./utils/shouldSkip";
|
|
25
|
+
export * from "./utils/markHookForSkip";
|
|
45
26
|
|
|
27
|
+
export * from "./utils/validateQueryProperty";
|
|
46
28
|
|
|
47
29
|
// query filters
|
|
48
30
|
export { filterArray } from "./filters/array";
|
|
31
|
+
export { filterObject } from "./filters/object";
|
|
49
32
|
|
|
50
33
|
export * from "./types";
|
|
@@ -2,26 +2,31 @@ import _debounce from "lodash/debounce.js";
|
|
|
2
2
|
|
|
3
3
|
import type { DebouncedFunc } from "lodash";
|
|
4
4
|
import type { Application, Id } from "@feathersjs/feathers";
|
|
5
|
-
|
|
6
|
-
import type {
|
|
7
|
-
DebouncedFunctionApp,
|
|
8
|
-
DebouncedStoreOptions
|
|
9
|
-
} from "../../types";
|
|
5
|
+
import type { DebouncedFunctionApp, DebouncedStoreOptions } from "./types";
|
|
10
6
|
|
|
11
7
|
export const makeDefaultOptions = (): DebouncedStoreOptions => {
|
|
12
8
|
return {
|
|
13
9
|
leading: false,
|
|
14
10
|
maxWait: undefined,
|
|
15
11
|
trailing: true,
|
|
16
|
-
wait: 100
|
|
12
|
+
wait: 100,
|
|
17
13
|
};
|
|
18
14
|
};
|
|
19
15
|
|
|
16
|
+
export type DebouncedService<T = any> = T & {
|
|
17
|
+
debouncedStore: DebouncedStore;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
20
|
export class DebouncedStore {
|
|
21
21
|
private _app: Application;
|
|
22
22
|
private _options: DebouncedStoreOptions;
|
|
23
23
|
private _isRunningById: Record<string, unknown>;
|
|
24
|
-
_queueById: Record<
|
|
24
|
+
_queueById: Record<
|
|
25
|
+
string,
|
|
26
|
+
DebouncedFunc<
|
|
27
|
+
(id: Id, action: DebouncedFunctionApp) => void | Promise<void>
|
|
28
|
+
>
|
|
29
|
+
>;
|
|
25
30
|
//_waitingById: Record<string, WaitingObject>;
|
|
26
31
|
add;
|
|
27
32
|
constructor(app: Application, options?: Partial<DebouncedStoreOptions>) {
|
|
@@ -31,15 +36,11 @@ export class DebouncedStore {
|
|
|
31
36
|
this._isRunningById = {};
|
|
32
37
|
//this._waitingById = {};
|
|
33
38
|
|
|
34
|
-
this.add = this.debounceById(
|
|
35
|
-
this.
|
|
36
|
-
this._options.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
maxWait: this._options.maxWait,
|
|
40
|
-
trailing: this._options.trailing
|
|
41
|
-
}
|
|
42
|
-
);
|
|
39
|
+
this.add = this.debounceById(this.unbounced, this._options.wait, {
|
|
40
|
+
leading: this._options.leading,
|
|
41
|
+
maxWait: this._options.maxWait,
|
|
42
|
+
trailing: this._options.trailing,
|
|
43
|
+
});
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
private async unbounced(id: Id, action: DebouncedFunctionApp): Promise<void> {
|
|
@@ -53,18 +54,22 @@ export class DebouncedStore {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
private debounceById(
|
|
56
|
-
func: (
|
|
57
|
-
wait: number,
|
|
57
|
+
func: (id: Id, action: DebouncedFunctionApp) => Promise<void>,
|
|
58
|
+
wait: number,
|
|
58
59
|
options?: Partial<DebouncedStoreOptions>
|
|
59
60
|
) {
|
|
60
|
-
return (id: Id, action: (
|
|
61
|
+
return (id: Id, action: (app?: Application) => void | Promise<void>) => {
|
|
61
62
|
if (typeof this._queueById[id] === "function") {
|
|
62
63
|
return this._queueById[id](id, action);
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
this._queueById[id] = _debounce(
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
|
|
66
|
+
this._queueById[id] = _debounce(
|
|
67
|
+
(id, action) => {
|
|
68
|
+
this.unbounced(id, action);
|
|
69
|
+
},
|
|
70
|
+
wait,
|
|
71
|
+
{ ...options, leading: false }
|
|
72
|
+
); // leading required for return promise
|
|
68
73
|
return this._queueById[id](id, action);
|
|
69
74
|
};
|
|
70
75
|
}
|
|
@@ -72,4 +77,4 @@ export class DebouncedStore {
|
|
|
72
77
|
cancel(id: Id): void {
|
|
73
78
|
delete this._queueById[id];
|
|
74
79
|
}
|
|
75
|
-
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Application } from "@feathersjs/feathers/lib";
|
|
2
|
+
import { DebouncedStore, makeDefaultOptions } from "./DebouncedStore";
|
|
3
|
+
import type { DebouncedStoreOptions, InitDebounceMixinOptions } from "./types";
|
|
4
|
+
|
|
5
|
+
export function debounceMixin(
|
|
6
|
+
options?: Partial<InitDebounceMixinOptions>
|
|
7
|
+
): (app: Application) => void {
|
|
8
|
+
return (app: Application): void => {
|
|
9
|
+
options = options || {};
|
|
10
|
+
const defaultOptions = Object.assign(
|
|
11
|
+
makeDefaultOptions(),
|
|
12
|
+
options?.default
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
app.mixins.push((service: any, path) => {
|
|
16
|
+
// if path is on blacklist, don't add debouncedStore to service
|
|
17
|
+
if (options?.blacklist && options.blacklist.includes(path)) return;
|
|
18
|
+
// if service already has registered something on `debouncedStore`
|
|
19
|
+
if (service.debouncedStore) {
|
|
20
|
+
console.warn(
|
|
21
|
+
`[feathers-utils] service: '${path}' already has a property 'debouncedStore'. Mixin will skip creating a new debouncedStore`
|
|
22
|
+
);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const serviceOptions = Object.assign({}, defaultOptions, options?.[path]);
|
|
27
|
+
service.debouncedStore = new DebouncedStore(
|
|
28
|
+
app,
|
|
29
|
+
serviceOptions as DebouncedStoreOptions
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "./DebouncedStore";
|
|
5
|
-
|
|
6
|
-
import type { Application, FeathersService } from "@feathersjs/feathers";
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
InitDebounceMixinOptions,
|
|
10
|
-
DebouncedStoreOptions,
|
|
11
|
-
} from "../../types";
|
|
12
|
-
|
|
13
|
-
export type DebouncedService = FeathersService & {
|
|
14
|
-
debouncedStore: DebouncedStore;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export function debounceMixin(
|
|
18
|
-
options?: Partial<InitDebounceMixinOptions>
|
|
19
|
-
): ((app: Application) => void) {
|
|
20
|
-
return (app: Application): void => {
|
|
21
|
-
options = options || {};
|
|
22
|
-
const defaultOptions = Object.assign(makeDefaultOptions(), options?.default);
|
|
23
|
-
|
|
24
|
-
app.mixins.push((service: any, path) => {
|
|
25
|
-
// if path is on blacklist, don't add debouncedStore to service
|
|
26
|
-
if (options?.blacklist && options.blacklist.includes(path)) return;
|
|
27
|
-
// if service already has registered something on `debouncedStore`
|
|
28
|
-
if (service.debouncedStore) {
|
|
29
|
-
console.warn(`[feathers-utils] service: '${path}' already has a property 'debouncedStore'. Mixin will skip creating a new debouncedStore`);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const serviceOptions = Object.assign({}, defaultOptions, options?.[path]);
|
|
34
|
-
service.debouncedStore = new DebouncedStore(app, serviceOptions as DebouncedStoreOptions);
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export { DebouncedStore };
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./DebouncedStore";
|
|
3
|
+
export * from "./debounceMixin";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Application } from "@feathersjs/feathers";
|
|
2
|
+
|
|
3
|
+
export interface InitDebounceMixinOptions {
|
|
4
|
+
default: Partial<DebouncedStoreOptions>;
|
|
5
|
+
blacklist: string[];
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type DebouncedFunctionApp = (app?: Application) => void | Promise<void>;
|
|
10
|
+
|
|
11
|
+
export interface DebouncedStoreOptions {
|
|
12
|
+
leading: boolean;
|
|
13
|
+
maxWait: number | undefined;
|
|
14
|
+
trailing: boolean;
|
|
15
|
+
wait: number;
|
|
16
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,120 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
AdapterBase,
|
|
4
|
-
FilterQueryOptions as PlainFilterQueryOptions
|
|
5
|
-
} from "@feathersjs/adapter-commons";
|
|
6
|
-
|
|
7
|
-
export type Path = Array<string|number>;
|
|
8
|
-
export type MaybeArray<T> = T | T[]
|
|
9
|
-
export type Promisable<T> = T | Promise<T>
|
|
10
|
-
|
|
11
|
-
export type HookType = "before" | "after" | "error";
|
|
12
|
-
export type ServiceMethodName = "find" | "get" | "create" | "update" | "patch" | "remove";
|
|
13
|
-
export type ReturnSyncHook = (context: HookContext) => HookContext
|
|
14
|
-
export type ReturnAsyncHook = (context: HookContext) => Promise<HookContext>
|
|
15
|
-
|
|
16
|
-
export type Handle = "target" | "source" | "combine" | "intersect"| "intersectOrFull";
|
|
17
|
-
export type FirstLast = "first" | "last";
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
18
2
|
|
|
19
3
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
-
export type Predicate<T = any> = (item: T) => boolean
|
|
4
|
+
export type Predicate<T = any> = (item: T) => boolean;
|
|
21
5
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
export type PredicateWithContext<T = any> = (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export interface HookSetDataOptions {
|
|
27
|
-
allowUndefined?: boolean
|
|
28
|
-
overwrite?: boolean | PredicateWithContext
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface AddHookOptions {
|
|
32
|
-
types: HookType[],
|
|
33
|
-
methods: ServiceMethodName[],
|
|
34
|
-
orderByType: Record<HookType, FirstLast>
|
|
35
|
-
whitelist?: string[],
|
|
36
|
-
blacklist?: string[],
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface HookRunPerItemOptions {
|
|
40
|
-
wait?: boolean
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface RemoveRelatedOptions<S = Record<string, any>> {
|
|
44
|
-
service: keyof S
|
|
45
|
-
keyThere: string
|
|
46
|
-
keyHere: string
|
|
47
|
-
blocking?: boolean
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
51
|
-
service: keyof S
|
|
52
|
-
multi?: boolean
|
|
53
|
-
data: (item: any, context: HookContext) => Promisable<Record<string, any>>
|
|
54
|
-
createItemsInDataArraySeparately?: boolean
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export type OnDeleteAction = "cascade" | "set null";
|
|
58
|
-
|
|
59
|
-
export interface OnDeleteOptions {
|
|
60
|
-
keyThere: string
|
|
61
|
-
keyHere: string
|
|
62
|
-
onDelete: OnDeleteAction
|
|
63
|
-
blocking?: boolean
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
//#endregion
|
|
67
|
-
|
|
68
|
-
//#region mixins
|
|
69
|
-
|
|
70
|
-
export interface InitDebounceMixinOptions {
|
|
71
|
-
default: Partial<DebouncedStoreOptions>
|
|
72
|
-
blacklist: string[]
|
|
73
|
-
[key: string]: unknown
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export type DebouncedFunctionApp = (app?: Application) => void | Promise<void>;
|
|
77
|
-
|
|
78
|
-
export interface DebouncedStoreOptions {
|
|
79
|
-
leading: boolean
|
|
80
|
-
maxWait: number | undefined
|
|
81
|
-
trailing: boolean
|
|
82
|
-
wait: number
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/*interface WaitingObject {
|
|
86
|
-
id: Id,
|
|
87
|
-
action: FunctionApp
|
|
88
|
-
}*/
|
|
89
|
-
|
|
90
|
-
//#endregion
|
|
91
|
-
|
|
92
|
-
//#region utils
|
|
93
|
-
export interface PushSetOptions {
|
|
94
|
-
unique?: boolean
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void
|
|
98
|
-
|
|
99
|
-
export interface MergeQueryOptions<T> extends FilterQueryOptions<T> {
|
|
100
|
-
defaultHandle: Handle,
|
|
101
|
-
actionOnEmptyIntersect: ActionOnEmptyIntersect
|
|
102
|
-
useLogicalConjunction: boolean
|
|
103
|
-
handle?: {
|
|
104
|
-
[key: string]: Handle
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface FilterQueryOptions<T> {
|
|
109
|
-
service?: AdapterBase<T>
|
|
110
|
-
operators?: PlainFilterQueryOptions["operators"],
|
|
111
|
-
filters?: PlainFilterQueryOptions["filters"],
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
-
export interface GetItemsIsArrayOptions<T = any> {
|
|
116
|
-
items: T[]
|
|
117
|
-
isArray: boolean
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
//#endregion
|
|
6
|
+
export type PredicateWithContext<T = any> = (
|
|
7
|
+
item: T,
|
|
8
|
+
context: HookContext
|
|
9
|
+
) => boolean;
|
package/src/utils/filterQuery.ts
CHANGED
|
@@ -1,30 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
filterQuery as plainFilterQuery,
|
|
3
|
-
} from "@feathersjs/adapter-commons";
|
|
1
|
+
import { filterQuery as plainFilterQuery } from "@feathersjs/adapter-commons";
|
|
4
2
|
|
|
5
3
|
import type {
|
|
6
4
|
FilterQueryOptions as PlainFilterQueryOptions,
|
|
5
|
+
AdapterBase,
|
|
7
6
|
} from "@feathersjs/adapter-commons";
|
|
8
7
|
|
|
9
8
|
import type { Query } from "@feathersjs/feathers";
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
export interface FilterQueryOptions<T> {
|
|
11
|
+
service?: AdapterBase<T>;
|
|
12
|
+
operators?: PlainFilterQueryOptions["operators"];
|
|
13
|
+
filters?: PlainFilterQueryOptions["filters"];
|
|
14
|
+
}
|
|
11
15
|
|
|
12
16
|
export function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>) {
|
|
13
17
|
query = query || {};
|
|
14
18
|
_options = _options || {};
|
|
15
19
|
const { service, ...options } = _options;
|
|
16
20
|
if (service) {
|
|
17
|
-
const operators = options.operators
|
|
21
|
+
const operators = options.operators
|
|
18
22
|
? options.operators
|
|
19
23
|
: service.options?.operators;
|
|
20
24
|
const filters = options.filters
|
|
21
25
|
? options.filters
|
|
22
26
|
: service.options?.filters;
|
|
23
|
-
const optionsForFilterQuery: PlainFilterQueryOptions = {};
|
|
24
|
-
if (operators) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (
|
|
27
|
+
const optionsForFilterQuery: PlainFilterQueryOptions = {};
|
|
28
|
+
if (operators) {
|
|
29
|
+
optionsForFilterQuery.operators = operators;
|
|
30
|
+
}
|
|
31
|
+
if (filters) {
|
|
32
|
+
optionsForFilterQuery.filters = filters;
|
|
33
|
+
}
|
|
34
|
+
if (
|
|
35
|
+
service &&
|
|
36
|
+
"filterQuery" in service &&
|
|
37
|
+
// @ts-expect-error service is of type 'never'
|
|
38
|
+
typeof service.filterQuery === "function"
|
|
39
|
+
) {
|
|
28
40
|
// @ts-expect-error service has no filterQuery method
|
|
29
41
|
return service.filterQuery({ query }, optionsForFilterQuery);
|
|
30
42
|
} else {
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
export interface GetItemsIsArrayOptions<T = any> {
|
|
4
|
+
items: T[];
|
|
5
|
+
isArray: boolean;
|
|
6
|
+
}
|
|
3
7
|
|
|
4
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
-
export const getItemsIsArray = <T = any>(
|
|
6
|
-
context:
|
|
9
|
+
export const getItemsIsArray = <T = any, H extends HookContext = HookContext>(
|
|
10
|
+
context: H
|
|
7
11
|
): GetItemsIsArrayOptions<T> => {
|
|
8
|
-
let itemOrItems = context.type === "before"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
: itemOrItems;
|
|
12
|
+
let itemOrItems = context.type === "before" ? context.data : context.result;
|
|
13
|
+
itemOrItems =
|
|
14
|
+
itemOrItems && context.method === "find"
|
|
15
|
+
? itemOrItems.data || itemOrItems
|
|
16
|
+
: itemOrItems;
|
|
14
17
|
const isArray = Array.isArray(itemOrItems);
|
|
15
18
|
return {
|
|
16
|
-
items:
|
|
17
|
-
|
|
18
|
-
: (itemOrItems != null)
|
|
19
|
-
? [itemOrItems]
|
|
20
|
-
: [],
|
|
21
|
-
isArray
|
|
19
|
+
items: isArray ? itemOrItems : itemOrItems != null ? [itemOrItems] : [],
|
|
20
|
+
isArray,
|
|
22
21
|
};
|
|
23
|
-
};
|
|
22
|
+
};
|
package/src/utils/getPaginate.ts
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
+
import type { PaginationOptions } from "@feathersjs/adapter-commons";
|
|
1
2
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
default: number;
|
|
6
|
-
max: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const getPaginate = (
|
|
10
|
-
context: HookContext
|
|
4
|
+
export const getPaginate = <H extends HookContext = HookContext>(
|
|
5
|
+
context: H
|
|
11
6
|
): PaginationOptions | undefined => {
|
|
12
7
|
if (Object.prototype.hasOwnProperty.call(context.params, "paginate")) {
|
|
13
|
-
return context.params.paginate as PaginationOptions || undefined;
|
|
8
|
+
return (context.params.paginate as PaginationOptions) || undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (context.params.paginate === false) {
|
|
12
|
+
return undefined;
|
|
14
13
|
}
|
|
15
|
-
|
|
16
|
-
if (context.params.paginate === false) { return undefined; }
|
|
17
14
|
let options = context.service.options || {};
|
|
18
|
-
|
|
15
|
+
|
|
19
16
|
options = {
|
|
20
17
|
...options,
|
|
21
|
-
...context.params.adapter
|
|
18
|
+
...context.params.adapter,
|
|
22
19
|
};
|
|
23
|
-
|
|
20
|
+
|
|
24
21
|
return options.paginate || undefined;
|
|
25
22
|
};
|
package/src/utils/isMulti.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
2
|
|
|
3
|
-
export const isMulti = (
|
|
4
|
-
context:
|
|
3
|
+
export const isMulti = <H extends HookContext = HookContext>(
|
|
4
|
+
context: H
|
|
5
5
|
): boolean => {
|
|
6
6
|
const { method } = context;
|
|
7
7
|
if (method === "find") {
|
|
@@ -15,4 +15,4 @@ export const isMulti = (
|
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
return false;
|
|
18
|
-
};
|
|
18
|
+
};
|