feathers-utils 1.6.0 → 1.7.2
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/hooks/checkMulti.d.ts +2 -0
- package/dist/esm/hooks/checkMulti.js +18 -0
- package/dist/esm/hooks/runPerItem.d.ts +4 -0
- package/dist/esm/hooks/runPerItem.js +25 -0
- package/dist/esm/hooks/setData.d.ts +4 -0
- package/dist/esm/hooks/setData.js +33 -0
- package/dist/esm/index.d.ts +30 -0
- package/dist/esm/index.js +31 -0
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.d.ts +15 -0
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.js +46 -0
- package/dist/esm/mixins/debounce-mixin/index.d.ts +5 -0
- package/dist/esm/mixins/debounce-mixin/index.js +20 -0
- package/dist/esm/types.d.ts +59 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/utils/addHook.d.ts +3 -0
- package/dist/esm/utils/addHook.js +36 -0
- package/dist/esm/utils/filterQuery.d.ts +3 -0
- package/dist/esm/utils/filterQuery.js +28 -0
- package/dist/esm/utils/getPaginate.d.ts +2 -0
- package/dist/esm/utils/getPaginate.js +14 -0
- package/dist/esm/utils/isMulti.d.ts +2 -0
- package/dist/esm/utils/isMulti.js +17 -0
- package/dist/esm/utils/isPaginated.d.ts +2 -0
- package/dist/esm/utils/isPaginated.js +8 -0
- package/dist/esm/utils/markHookForSkip.d.ts +3 -0
- package/dist/esm/utils/markHookForSkip.js +14 -0
- package/dist/esm/utils/mergeQuery/index.d.ts +3 -0
- package/dist/esm/utils/mergeQuery/index.js +327 -0
- package/dist/esm/utils/mergeQuery/mergeArrays.d.ts +2 -0
- package/dist/esm/utils/mergeQuery/mergeArrays.js +37 -0
- package/dist/esm/utils/pushSet.d.ts +2 -0
- package/dist/esm/utils/pushSet.js +19 -0
- package/dist/esm/utils/setResultEmpty.d.ts +2 -0
- package/dist/esm/utils/setResultEmpty.js +25 -0
- package/dist/esm/utils/shouldSkip.d.ts +2 -0
- package/dist/esm/utils/shouldSkip.js +29 -0
- package/dist/hooks/runPerItem.d.ts +2 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +7 -1
- package/dist/mixins/debounce-mixin/DebouncedStore.d.ts +2 -2
- package/dist/utils/getPaginate.d.ts +2 -0
- package/dist/utils/getPaginate.js +15 -0
- package/dist/utils/isMulti.js +2 -3
- package/dist/utils/isPaginated.d.ts +2 -0
- package/dist/utils/isPaginated.js +12 -0
- package/dist/utils/setResultEmpty.d.ts +2 -0
- package/dist/utils/setResultEmpty.js +29 -0
- package/package.json +15 -9
- package/src/hooks/runPerItem.ts +2 -1
- package/src/index.ts +3 -0
- package/src/mixins/debounce-mixin/DebouncedStore.ts +2 -2
- package/src/utils/getPaginate.ts +18 -0
- package/src/utils/isMulti.ts +2 -3
- package/src/utils/isPaginated.ts +12 -0
- package/src/utils/setResultEmpty.ts +28 -0
- package/tsconfig-esm.json +9 -0
- package/.github/workflows/node.js.yml +0 -45
- package/.vscode/launch.json +0 -29
- package/.vscode/settings.json +0 -14
- package/test/hooks/checkMulti.test.ts +0 -121
- package/test/hooks/setData.test.ts +0 -333
- package/test/mixins/debounce-mixin.test.ts +0 -174
- package/test/utils/addHook.test.ts +0 -307
- package/test/utils/isMulti.test.ts +0 -53
- package/test/utils/markHookForSkip.test.ts +0 -292
- package/test/utils/mergeQuery.test.ts +0 -407
- package/test/utils/pushSet.test.ts +0 -66
- package/test/utils/shouldSkip.test.ts +0 -67
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MethodNotAllowed } from "@feathersjs/errors";
|
|
2
|
+
import { shouldSkip } from "../utils/shouldSkip";
|
|
3
|
+
import { isMulti } from "../utils/isMulti";
|
|
4
|
+
export function checkMulti() {
|
|
5
|
+
return (context) => {
|
|
6
|
+
if (shouldSkip("checkMulti", context)) {
|
|
7
|
+
return context;
|
|
8
|
+
}
|
|
9
|
+
const { service, method } = context;
|
|
10
|
+
if (!service.allowsMulti || !isMulti(context) || method === "find") {
|
|
11
|
+
return context;
|
|
12
|
+
}
|
|
13
|
+
if (!service.allowsMulti(method)) {
|
|
14
|
+
throw new MethodNotAllowed(`Can not ${method} multiple entries`);
|
|
15
|
+
}
|
|
16
|
+
return context;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HookRunPerItemOptions } from "../types";
|
|
2
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
3
|
+
import type { Promisable } from "type-fest";
|
|
4
|
+
export declare const runPerItem: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, options: HookRunPerItemOptions) => (context: HookContext) => Promise<HookContext>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getItems } from "feathers-hooks-common";
|
|
2
|
+
import { shouldSkip } from "../utils/shouldSkip";
|
|
3
|
+
const makeOptions = (options) => {
|
|
4
|
+
options = options || {};
|
|
5
|
+
return Object.assign({
|
|
6
|
+
wait: true
|
|
7
|
+
}, options);
|
|
8
|
+
};
|
|
9
|
+
export const runPerItem = (actionPerItem, options) => {
|
|
10
|
+
options = makeOptions(options);
|
|
11
|
+
return async (context) => {
|
|
12
|
+
if (shouldSkip("runForItems", context)) {
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
let items = getItems(context);
|
|
16
|
+
items = (Array.isArray(items)) ? items : [items];
|
|
17
|
+
const promises = items.map(async (item) => {
|
|
18
|
+
await actionPerItem(item, context);
|
|
19
|
+
});
|
|
20
|
+
if (options.wait) {
|
|
21
|
+
await Promise.all(promises);
|
|
22
|
+
}
|
|
23
|
+
return context;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import type { HookSetDataOptions } from "../types";
|
|
3
|
+
import type { PropertyPath } from "lodash";
|
|
4
|
+
export declare function setData(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): ((context: HookContext) => HookContext);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import _get from "lodash/get";
|
|
2
|
+
import _set from "lodash/set";
|
|
3
|
+
import _has from "lodash/has";
|
|
4
|
+
import { getItems } from "feathers-hooks-common";
|
|
5
|
+
import { Forbidden } from "@feathersjs/errors";
|
|
6
|
+
const defaultOptions = {
|
|
7
|
+
allowUndefined: false,
|
|
8
|
+
overwrite: true
|
|
9
|
+
};
|
|
10
|
+
export function setData(from, to, _options) {
|
|
11
|
+
const options = Object.assign({}, defaultOptions, _options);
|
|
12
|
+
return (context) => {
|
|
13
|
+
let items = getItems(context);
|
|
14
|
+
items = (Array.isArray(items)) ? items : [items];
|
|
15
|
+
if (!_has(context, from)) {
|
|
16
|
+
if (!context.params?.provider || options.allowUndefined === true) {
|
|
17
|
+
return context;
|
|
18
|
+
}
|
|
19
|
+
if (!options.overwrite && items.every((item) => _has(item, to))) {
|
|
20
|
+
return context;
|
|
21
|
+
}
|
|
22
|
+
throw new Forbidden(`Expected field ${from.toString()} not available`);
|
|
23
|
+
}
|
|
24
|
+
const val = _get(context, from);
|
|
25
|
+
items.forEach((item) => {
|
|
26
|
+
if (!options.overwrite && _has(item, to)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
_set(item, to, val);
|
|
30
|
+
});
|
|
31
|
+
return context;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { checkMulti } from "./hooks/checkMulti";
|
|
2
|
+
import { setData } from "./hooks/setData";
|
|
3
|
+
import { runPerItem } from "./hooks/runPerItem";
|
|
4
|
+
export declare const hooks: {
|
|
5
|
+
checkMulti: typeof checkMulti;
|
|
6
|
+
setData: typeof setData;
|
|
7
|
+
runPerItem: (actionPerItem: (item: any, context: import("@feathersjs/feathers").HookContext<any, import("@feathersjs/feathers").Service<any>>) => any, options: import("./types").HookRunPerItemOptions) => (context: import("@feathersjs/feathers").HookContext<any, import("@feathersjs/feathers").Service<any>>) => Promise<import("@feathersjs/feathers").HookContext<any, import("@feathersjs/feathers").Service<any>>>;
|
|
8
|
+
};
|
|
9
|
+
export { checkMulti };
|
|
10
|
+
export { setData };
|
|
11
|
+
export { runPerItem };
|
|
12
|
+
import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
|
|
13
|
+
export declare const mixins: {
|
|
14
|
+
debounceMixin: typeof debounceMixin;
|
|
15
|
+
DebouncedStore: typeof DebouncedStore;
|
|
16
|
+
};
|
|
17
|
+
export { debounceMixin };
|
|
18
|
+
export { DebouncedStore };
|
|
19
|
+
export { addHook } from "./utils/addHook";
|
|
20
|
+
export { getPaginate } from "./utils/getPaginate";
|
|
21
|
+
export { isMulti } from "./utils/isMulti";
|
|
22
|
+
export { isPaginated } from "./utils/isPaginated";
|
|
23
|
+
export { mergeQuery } from "./utils/mergeQuery/index";
|
|
24
|
+
export { mergeArrays } from "./utils/mergeQuery/mergeArrays";
|
|
25
|
+
export { pushSet } from "./utils/pushSet";
|
|
26
|
+
export { setResultEmpty } from "./utils/setResultEmpty";
|
|
27
|
+
export { markHookForSkip } from "./utils/markHookForSkip";
|
|
28
|
+
export { shouldSkip } from "./utils/shouldSkip";
|
|
29
|
+
export { filterQuery } from "./utils/filterQuery";
|
|
30
|
+
export * from "./types";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// hooks
|
|
2
|
+
import { checkMulti } from "./hooks/checkMulti";
|
|
3
|
+
import { setData } from "./hooks/setData";
|
|
4
|
+
import { runPerItem } from "./hooks/runPerItem";
|
|
5
|
+
export const hooks = {
|
|
6
|
+
checkMulti,
|
|
7
|
+
setData,
|
|
8
|
+
runPerItem
|
|
9
|
+
};
|
|
10
|
+
export { checkMulti };
|
|
11
|
+
export { setData };
|
|
12
|
+
export { runPerItem };
|
|
13
|
+
import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
|
|
14
|
+
export const mixins = {
|
|
15
|
+
debounceMixin,
|
|
16
|
+
DebouncedStore
|
|
17
|
+
};
|
|
18
|
+
export { debounceMixin };
|
|
19
|
+
export { DebouncedStore };
|
|
20
|
+
export { addHook } from "./utils/addHook";
|
|
21
|
+
export { getPaginate } from "./utils/getPaginate";
|
|
22
|
+
export { isMulti } from "./utils/isMulti";
|
|
23
|
+
export { isPaginated } from "./utils/isPaginated";
|
|
24
|
+
export { mergeQuery } from "./utils/mergeQuery/index";
|
|
25
|
+
export { mergeArrays } from "./utils/mergeQuery/mergeArrays";
|
|
26
|
+
export { pushSet } from "./utils/pushSet";
|
|
27
|
+
export { setResultEmpty } from "./utils/setResultEmpty";
|
|
28
|
+
export { markHookForSkip } from "./utils/markHookForSkip";
|
|
29
|
+
export { shouldSkip } from "./utils/shouldSkip";
|
|
30
|
+
export { filterQuery } from "./utils/filterQuery";
|
|
31
|
+
export * from "./types";
|
|
@@ -0,0 +1,15 @@
|
|
|
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 declare class DebouncedStore {
|
|
6
|
+
private _app;
|
|
7
|
+
private _options;
|
|
8
|
+
private _isRunningById;
|
|
9
|
+
_queueById: Record<string, DebouncedFunc<((id: Id, action: DebouncedFunctionApp) => void | Promise<void>)>>;
|
|
10
|
+
add: (id: Id, action: (app?: Application<{}> | undefined) => void | Promise<void>) => void | Promise<void> | undefined;
|
|
11
|
+
constructor(app: Application, options?: Partial<DebouncedStoreOptions>);
|
|
12
|
+
private unbounced;
|
|
13
|
+
private debounceById;
|
|
14
|
+
cancel(id: Id): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import _debounce from "lodash/debounce";
|
|
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
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DebouncedStore } from "./DebouncedStore";
|
|
2
|
+
import type { Application } from "@feathersjs/feathers";
|
|
3
|
+
import type { InitDebounceMixinOptions } from "../../types";
|
|
4
|
+
export declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): ((app: Application) => void);
|
|
5
|
+
export { DebouncedStore };
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
}
|
|
20
|
+
export { DebouncedStore };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Application, Service } from "@feathersjs/feathers";
|
|
2
|
+
export declare type Path = Array<string | number>;
|
|
3
|
+
export declare type HookType = "before" | "after" | "error";
|
|
4
|
+
export declare type ServiceMethodName = "find" | "get" | "create" | "update" | "patch" | "remove";
|
|
5
|
+
export declare type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
|
|
6
|
+
export declare type FirstLast = "first" | "last";
|
|
7
|
+
export interface HookSetDataOptions {
|
|
8
|
+
allowUndefined?: boolean;
|
|
9
|
+
overwrite?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface AddHookOptions {
|
|
12
|
+
types: HookType[];
|
|
13
|
+
methods: ServiceMethodName[];
|
|
14
|
+
orderByType: Record<HookType, FirstLast>;
|
|
15
|
+
whitelist?: string[];
|
|
16
|
+
blacklist?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface HookRunPerItemOptions {
|
|
19
|
+
wait?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface InitDebounceMixinOptions {
|
|
22
|
+
default: Partial<DebouncedStoreOptions>;
|
|
23
|
+
blacklist: string[];
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
export declare type DebouncedFunctionApp = (app?: Application) => void | Promise<void>;
|
|
27
|
+
export interface DebouncedStoreOptions {
|
|
28
|
+
leading: boolean;
|
|
29
|
+
maxWait: number | undefined;
|
|
30
|
+
trailing: boolean;
|
|
31
|
+
wait: number;
|
|
32
|
+
}
|
|
33
|
+
export interface PushSetOptions {
|
|
34
|
+
unique?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
|
|
37
|
+
export interface MergeQueryOptions<T> extends FilterQueryOptions<T> {
|
|
38
|
+
defaultHandle: Handle;
|
|
39
|
+
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
40
|
+
useLogicalConjunction: boolean;
|
|
41
|
+
handle?: {
|
|
42
|
+
[key: string]: Handle;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface FilterQueryOptions<T> {
|
|
46
|
+
service?: Service<T>;
|
|
47
|
+
operators?: string[];
|
|
48
|
+
filters?: string[];
|
|
49
|
+
}
|
|
50
|
+
export interface PlainFilterQueryOptions {
|
|
51
|
+
operators?: string[];
|
|
52
|
+
filters?: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface FilterQueryResult {
|
|
55
|
+
filters: Record<string, unknown>;
|
|
56
|
+
query: Record<string, unknown>;
|
|
57
|
+
paginate?: unknown;
|
|
58
|
+
[key: string]: unknown;
|
|
59
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const defaultOptions = () => {
|
|
2
|
+
return {
|
|
3
|
+
whitelist: ["*"],
|
|
4
|
+
blacklist: []
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
export const addHook = (app, hook, options) => {
|
|
8
|
+
options = Object.assign(defaultOptions(), options);
|
|
9
|
+
const { types, methods, whitelist, blacklist, orderByType } = options;
|
|
10
|
+
if (types.some(x => !(Object.keys(orderByType).includes(x)))) {
|
|
11
|
+
throw new Error("'feathers-utils/addHook': some types in 'orderByType' are undefined");
|
|
12
|
+
}
|
|
13
|
+
if (Object.keys(orderByType).some(type => !((["first", "last"]).includes(orderByType[type])))) {
|
|
14
|
+
throw new Error("'feathers-utils/addHook': only allowed values for 'orderByType' are 'first' or 'last'");
|
|
15
|
+
}
|
|
16
|
+
const allServices = app.services;
|
|
17
|
+
for (const servicePath in allServices) {
|
|
18
|
+
if (!Object.prototype.hasOwnProperty.call(allServices, servicePath)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const service = app.service(servicePath);
|
|
22
|
+
if (blacklist && blacklist.includes(servicePath)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (whitelist && !whitelist.includes("*") && !whitelist.includes(servicePath)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
types.forEach(type => {
|
|
29
|
+
const order = orderByType[type];
|
|
30
|
+
const unshiftOrPush = (order === "first") ? "unshift" : "push";
|
|
31
|
+
methods.forEach(method => {
|
|
32
|
+
service.__hooks[type][method][unshiftOrPush](hook);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { filterQuery as plainFilterQuery } from "@feathersjs/adapter-commons";
|
|
2
|
+
export function filterQuery(query, options) {
|
|
3
|
+
query = query || {};
|
|
4
|
+
options = options || {};
|
|
5
|
+
if (options?.service) {
|
|
6
|
+
const { service } = options;
|
|
7
|
+
const operators = options.operators
|
|
8
|
+
? options.operators
|
|
9
|
+
: service.options?.whitelist;
|
|
10
|
+
const filters = options.filters
|
|
11
|
+
? options.filters
|
|
12
|
+
: service.options?.filters;
|
|
13
|
+
const optionsForFilterQuery = {};
|
|
14
|
+
if (operators) {
|
|
15
|
+
optionsForFilterQuery.operators = operators;
|
|
16
|
+
}
|
|
17
|
+
if (filters) {
|
|
18
|
+
optionsForFilterQuery.filters = filters;
|
|
19
|
+
}
|
|
20
|
+
if (typeof service?.filterQuery === "function") {
|
|
21
|
+
return service.filterQuery({ query }, optionsForFilterQuery);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
return plainFilterQuery(query, optionsForFilterQuery);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return plainFilterQuery(query, options);
|
|
28
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const getPaginate = (context) => {
|
|
2
|
+
if (Object.prototype.hasOwnProperty.call(context.params, "paginate")) {
|
|
3
|
+
return context.params.paginate || undefined;
|
|
4
|
+
}
|
|
5
|
+
if (context.params.paginate === false) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
let options = context.service.options || {};
|
|
9
|
+
options = {
|
|
10
|
+
...options,
|
|
11
|
+
...context.params.adapter
|
|
12
|
+
};
|
|
13
|
+
return options.paginate || undefined;
|
|
14
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const isMulti = (context) => {
|
|
2
|
+
const { method } = context;
|
|
3
|
+
if (method === "find") {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
else if (["patch", "remove"].includes(method)) {
|
|
7
|
+
return context.id == null;
|
|
8
|
+
}
|
|
9
|
+
else if (method === "create") {
|
|
10
|
+
const items = context.type === "before" ? context.data : context.result;
|
|
11
|
+
return Array.isArray(items);
|
|
12
|
+
}
|
|
13
|
+
else if (["get", "update"].includes(method)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import type { HookType } from "feathers-hooks-common/types";
|
|
3
|
+
export declare function markHookForSkip<T>(hookName: string, type: "all" | HookType | HookType[], context?: Partial<HookContext<T>>): Partial<HookContext<T>>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { pushSet } from "./pushSet";
|
|
2
|
+
export function markHookForSkip(hookName, type, context) {
|
|
3
|
+
context = context || {};
|
|
4
|
+
const params = context.params || {};
|
|
5
|
+
const types = (Array.isArray(type)) ? type : [type];
|
|
6
|
+
types.forEach(t => {
|
|
7
|
+
const combinedName = (t === "all")
|
|
8
|
+
? hookName
|
|
9
|
+
: `${type}:${hookName}`;
|
|
10
|
+
pushSet(params, ["skipHooks"], combinedName, { unique: true });
|
|
11
|
+
});
|
|
12
|
+
context.params = params;
|
|
13
|
+
return context;
|
|
14
|
+
}
|