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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feathers-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Some utils for projects using '@feathersjs/feathers'",
|
|
5
5
|
"author": "fratzinger",
|
|
6
6
|
"repository": {
|
|
@@ -8,23 +8,19 @@
|
|
|
8
8
|
"url": "https://github.com/fratzinger/feathers-utils"
|
|
9
9
|
},
|
|
10
10
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
11
|
+
"node": ">= 16"
|
|
12
12
|
},
|
|
13
13
|
"homepage": "https://github.com/fratzinger/feathers-utils",
|
|
14
14
|
"license": "MIT",
|
|
15
|
-
"
|
|
16
|
-
"module": "dist/esm/index.js",
|
|
17
|
-
"types": "dist/index.d.ts",
|
|
15
|
+
"type": "module",
|
|
18
16
|
"exports": {
|
|
19
17
|
".": {
|
|
20
|
-
"import": "./dist/
|
|
21
|
-
"require": "./dist/index.
|
|
22
|
-
"types": "./dist/index.d.ts"
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
23
20
|
}
|
|
24
21
|
},
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
},
|
|
22
|
+
"main": "./dist/index.cjs",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
28
24
|
"files": [
|
|
29
25
|
"CHANGELOG.md",
|
|
30
26
|
"LICENSE",
|
|
@@ -34,44 +30,45 @@
|
|
|
34
30
|
"dist/**"
|
|
35
31
|
],
|
|
36
32
|
"scripts": {
|
|
37
|
-
"build": "
|
|
38
|
-
"tsc": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json",
|
|
33
|
+
"build": "unbuild",
|
|
39
34
|
"version": "npm run build",
|
|
40
35
|
"release": "np",
|
|
41
|
-
"test": "
|
|
42
|
-
"
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"vitest": "vitest",
|
|
38
|
+
"coverage": "vitest run --coverage",
|
|
43
39
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
|
|
44
40
|
},
|
|
45
41
|
"dependencies": {
|
|
46
|
-
"@feathersjs/adapter-commons": "5.0.0
|
|
47
|
-
"@feathersjs/
|
|
48
|
-
"@feathersjs/
|
|
49
|
-
"feathers
|
|
50
|
-
"
|
|
51
|
-
"
|
|
42
|
+
"@feathersjs/adapter-commons": "5.0.0",
|
|
43
|
+
"@feathersjs/commons": "^5.0.0",
|
|
44
|
+
"@feathersjs/errors": "5.0.0",
|
|
45
|
+
"@feathersjs/feathers": "5.0.0",
|
|
46
|
+
"fast-equals": "^5.0.1",
|
|
47
|
+
"feathers-hooks-common": "^7.0.0",
|
|
48
|
+
"lodash": "^4.17.21"
|
|
52
49
|
},
|
|
53
50
|
"devDependencies": {
|
|
54
|
-
"@feathersjs/memory": "^5.0.0
|
|
51
|
+
"@feathersjs/memory": "^5.0.0",
|
|
55
52
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
56
|
-
"@types/lodash": "^4.14.
|
|
57
|
-
"@types/mocha": "^10.0.
|
|
58
|
-
"@types/node": "^18.
|
|
59
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
60
|
-
"@typescript-eslint/parser": "^5.
|
|
53
|
+
"@types/lodash": "^4.14.191",
|
|
54
|
+
"@types/mocha": "^10.0.1",
|
|
55
|
+
"@types/node": "^18.14.1",
|
|
56
|
+
"@typescript-eslint/eslint-plugin": "^5.53.0",
|
|
57
|
+
"@typescript-eslint/parser": "^5.53.0",
|
|
58
|
+
"@vitest/coverage-c8": "^0.29.1",
|
|
61
59
|
"cross-env": "^7.0.3",
|
|
62
|
-
"eslint": "^8.
|
|
63
|
-
"eslint-config-prettier": "^8.
|
|
64
|
-
"eslint-import-resolver-typescript": "^3.5.
|
|
65
|
-
"eslint-plugin-import": "^2.
|
|
60
|
+
"eslint": "^8.34.0",
|
|
61
|
+
"eslint-config-prettier": "^8.6.0",
|
|
62
|
+
"eslint-import-resolver-typescript": "^3.5.3",
|
|
63
|
+
"eslint-plugin-import": "^2.27.5",
|
|
66
64
|
"eslint-plugin-prettier": "^4.2.1",
|
|
67
|
-
"eslint-plugin-security": "^1.
|
|
68
|
-
"
|
|
69
|
-
"mocha": "^10.1.0",
|
|
70
|
-
"np": "^7.6.2",
|
|
65
|
+
"eslint-plugin-security": "^1.7.1",
|
|
66
|
+
"np": "^7.6.3",
|
|
71
67
|
"nyc": "^15.1.0",
|
|
72
|
-
"prettier": "^2.8.
|
|
68
|
+
"prettier": "^2.8.4",
|
|
73
69
|
"shx": "^0.3.4",
|
|
74
|
-
"
|
|
75
|
-
"
|
|
70
|
+
"typescript": "^4.9.5",
|
|
71
|
+
"unbuild": "^1.1.2",
|
|
72
|
+
"vitest": "^0.29.1"
|
|
76
73
|
}
|
|
77
74
|
}
|
package/src/filters/object.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
|
|
2
2
|
import { validateQueryProperty } from "../utils/validateQueryProperty";
|
|
3
|
-
import _isObject from "lodash/isObject";
|
|
3
|
+
import _isObject from "lodash/isObject.js";
|
|
4
4
|
|
|
5
5
|
const filterQueryObject =
|
|
6
6
|
(key: string) =>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { shouldSkip } from "../utils/shouldSkip";
|
|
2
|
+
|
|
3
|
+
import type { ReturnAsyncHook, Promisable } from "../typesInternal";
|
|
4
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
5
|
+
import type { GetItemsIsArrayOptions } from "../utils/getItemsIsArray";
|
|
6
|
+
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
7
|
+
|
|
8
|
+
export interface HookForEachOptions {
|
|
9
|
+
wait?: "sequential" | "parallel" | false
|
|
10
|
+
items?: GetItemsIsArrayOptions["from"]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const forEach = (
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
actionPerItem: (item: any, context: HookContext) => Promisable<any>,
|
|
16
|
+
_options?: HookForEachOptions
|
|
17
|
+
): ReturnAsyncHook => {
|
|
18
|
+
const options: Required<HookForEachOptions> = {
|
|
19
|
+
wait: "parallel",
|
|
20
|
+
items: "automatic",
|
|
21
|
+
..._options
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return async (context: HookContext): Promise<HookContext> => {
|
|
25
|
+
if (shouldSkip("runForItems", context)) { return context; }
|
|
26
|
+
|
|
27
|
+
const { items } = getItemsIsArray(context, { from: options.items });
|
|
28
|
+
|
|
29
|
+
const promises: Promise<any>[] = [];
|
|
30
|
+
|
|
31
|
+
for (const item of items) {
|
|
32
|
+
const promise = actionPerItem(item, context);
|
|
33
|
+
|
|
34
|
+
if (options.wait === "sequential") {
|
|
35
|
+
await promise;
|
|
36
|
+
} else {
|
|
37
|
+
promises.push(promise);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (options.wait === "parallel") {
|
|
42
|
+
await Promise.all(promises);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return context;
|
|
46
|
+
};
|
|
47
|
+
};
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import _get from "lodash/get";
|
|
2
|
-
import _isObject from "lodash/isObject";
|
|
3
|
-
import _transform from "lodash/transform";
|
|
4
|
-
import _intersection from "lodash/intersection";
|
|
1
|
+
import _get from "lodash/get.js";
|
|
2
|
+
import _isObject from "lodash/isObject.js";
|
|
3
|
+
import _transform from "lodash/transform.js";
|
|
4
|
+
import _intersection from "lodash/intersection.js";
|
|
5
5
|
import { HookContext, Query } from "@feathersjs/feathers";
|
|
6
6
|
|
|
7
7
|
import { Model } from "sequelize";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parse fields to date or number
|
|
6
|
+
* skips undefined fields
|
|
7
|
+
*/
|
|
8
|
+
export const parseFields = (type: "date" | "number", options: { fields: string[] }) => (context: HookContext) => {
|
|
9
|
+
const { items } = getItemsIsArray(context);
|
|
10
|
+
|
|
11
|
+
items.forEach(item => {
|
|
12
|
+
options.fields.forEach(field => {
|
|
13
|
+
// ignore undefined fields
|
|
14
|
+
if (!(field in item)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (type === "date") {
|
|
19
|
+
item[field] = new Date(item[field]);
|
|
20
|
+
} else if (type === "number") {
|
|
21
|
+
item[field] = Number(item[field]);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return context;
|
|
27
|
+
};
|
package/src/hooks/runPerItem.ts
CHANGED
|
@@ -11,12 +11,10 @@ const makeOptions = (
|
|
|
11
11
|
options?: HookRunPerItemOptions
|
|
12
12
|
): Required<HookRunPerItemOptions> => {
|
|
13
13
|
options = options || {};
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
options
|
|
19
|
-
);
|
|
14
|
+
return {
|
|
15
|
+
wait: true,
|
|
16
|
+
...options,
|
|
17
|
+
};
|
|
20
18
|
};
|
|
21
19
|
|
|
22
20
|
/**
|
package/src/hooks/setData.ts
CHANGED
|
@@ -27,11 +27,10 @@ export function setData<H extends HookContext = HookContext>(
|
|
|
27
27
|
to: PropertyPath,
|
|
28
28
|
_options?: HookSetDataOptions
|
|
29
29
|
) {
|
|
30
|
-
const options: Required<HookSetDataOptions> =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
);
|
|
30
|
+
const options: Required<HookSetDataOptions> = {
|
|
31
|
+
...defaultOptions,
|
|
32
|
+
..._options,
|
|
33
|
+
};
|
|
35
34
|
return (context: H) => {
|
|
36
35
|
if (shouldSkip("setData", context)) {
|
|
37
36
|
return context;
|
package/src/index.ts
CHANGED
package/src/typesInternal.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// here are types that are not meant to be exported!
|
|
2
2
|
// just for internal use of this package
|
|
3
3
|
|
|
4
|
+
import { HookContext } from "@feathersjs/feathers/lib";
|
|
5
|
+
|
|
4
6
|
export type MaybeArray<T> = T | T[];
|
|
5
7
|
export type Promisable<T> = T | Promise<T>;
|
|
6
8
|
export type Path = Array<string | number>;
|
|
9
|
+
|
|
10
|
+
export type HookType = "before" | "after" | "error";
|
|
11
|
+
export type ServiceMethodName = "find" | "get" | "create" | "update" | "patch" | "remove";
|
|
12
|
+
export type ReturnSyncHook = (context: HookContext) => HookContext
|
|
13
|
+
export type ReturnAsyncHook = (context: HookContext) => Promise<HookContext>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { Application, Id } from "@feathersjs/feathers";
|
|
2
|
+
|
|
3
|
+
type Single<T> = T extends Array<infer U> ? U : T;
|
|
4
|
+
type AsArray<T> = T extends any[] ? T : [T];
|
|
5
|
+
|
|
6
|
+
export type InferCreateData<S> = S extends {
|
|
7
|
+
create: (data: infer D, params: any) => any;
|
|
8
|
+
}
|
|
9
|
+
? D
|
|
10
|
+
: never;
|
|
11
|
+
|
|
12
|
+
export type InferCreateDataSingle<S> = Single<InferCreateData<S>>;
|
|
13
|
+
|
|
14
|
+
export type InferUpdateData<S> = S extends {
|
|
15
|
+
update: (id: any, data: infer D, params: any) => any;
|
|
16
|
+
}
|
|
17
|
+
? D
|
|
18
|
+
: never;
|
|
19
|
+
|
|
20
|
+
export type InferPatchData<S> = S extends {
|
|
21
|
+
patch: (id: any, data: infer D, params: any) => any;
|
|
22
|
+
}
|
|
23
|
+
? D
|
|
24
|
+
: never;
|
|
25
|
+
|
|
26
|
+
export type InferGetResult<S> = S extends {
|
|
27
|
+
get: (id: any, params: any) => infer R;
|
|
28
|
+
}
|
|
29
|
+
? Awaited<R>
|
|
30
|
+
: never;
|
|
31
|
+
|
|
32
|
+
export type InferFindResult<S> = S extends {
|
|
33
|
+
find: (params: any) => infer R;
|
|
34
|
+
}
|
|
35
|
+
? Awaited<R>
|
|
36
|
+
: never;
|
|
37
|
+
|
|
38
|
+
export type InferCreateResult<S, D = unknown> = S extends {
|
|
39
|
+
create: (data: any, params: any) => infer R;
|
|
40
|
+
}
|
|
41
|
+
? D extends any[]
|
|
42
|
+
? AsArray<Awaited<R>>
|
|
43
|
+
: D extends InferCreateDataSingle<S>
|
|
44
|
+
? Single<Awaited<R>>
|
|
45
|
+
: Awaited<R>
|
|
46
|
+
: never;
|
|
47
|
+
|
|
48
|
+
export type InferCreateResultSingle<S> = Single<InferCreateResult<S>>;
|
|
49
|
+
|
|
50
|
+
export type InferUpdateResult<S> = S extends {
|
|
51
|
+
update: (id: any, data: any, params: any) => infer R;
|
|
52
|
+
}
|
|
53
|
+
? Awaited<R>
|
|
54
|
+
: never;
|
|
55
|
+
|
|
56
|
+
export type InferPatchResult<S, IdOrNullable = any> = S extends {
|
|
57
|
+
patch: (id: Id, data: any, params: any) => infer R;
|
|
58
|
+
}
|
|
59
|
+
? IdOrNullable extends Id
|
|
60
|
+
? Single<Awaited<R>>
|
|
61
|
+
: IdOrNullable extends null
|
|
62
|
+
? AsArray<Awaited<R>>
|
|
63
|
+
: Awaited<R>
|
|
64
|
+
: never;
|
|
65
|
+
|
|
66
|
+
export type InferRemoveResult<S, IdOrNullable = any> = S extends {
|
|
67
|
+
remove: (id: IdOrNullable, params: any) => infer R;
|
|
68
|
+
}
|
|
69
|
+
? IdOrNullable extends Id
|
|
70
|
+
? Single<Awaited<R>>
|
|
71
|
+
: IdOrNullable extends null
|
|
72
|
+
? AsArray<Awaited<R>>
|
|
73
|
+
: Awaited<R>
|
|
74
|
+
: never;
|
|
75
|
+
|
|
76
|
+
export type GetService<App extends Application, Path extends string> = App["services"][Path];
|
|
77
|
+
|
|
78
|
+
export type InferGetResultFromPath<App extends Application, Path extends string> = InferGetResult<GetService<App, Path>>;
|
|
79
|
+
export type InferFindResultFromPath<App extends Application, Path extends string> = InferFindResult<GetService<App, Path>>;
|
|
80
|
+
|
|
81
|
+
export type InferCreateDataFromPath<App extends Application, Path extends string> = InferCreateData<GetService<App, Path>>
|
|
82
|
+
export type InferCreateDataSingleFromPath<App extends Application, Path extends string> = InferCreateDataSingle<GetService<App, Path>>;
|
|
83
|
+
|
|
84
|
+
export type InferCreateResultFromPath<App extends Application, Path extends string, D = unknown> = InferCreateResult<GetService<App, Path>, D>;
|
|
85
|
+
export type InferCreateResultSingleFromPath<App extends Application, Path extends string> = InferCreateResultSingle<GetService<App, Path>>;
|
|
86
|
+
|
|
87
|
+
export type InferUpdateDataFromPath<App extends Application, Path extends string> = InferUpdateData<GetService<App, Path>>
|
|
88
|
+
export type InferPatchDataFromPath<App extends Application, Path extends string> = InferPatchData<GetService<App, Path>>
|
|
89
|
+
|
|
90
|
+
export type InferUpdateResultFromPath<App extends Application, Path extends string> = InferUpdateResult<GetService<App, Path>>;
|
|
91
|
+
export type InferPatchResultFromPath<App extends Application, Path extends string, IdOrNullable = any> = InferPatchResult<GetService<App, Path>, IdOrNullable>;
|
|
92
|
+
|
|
93
|
+
export type InferRemoveResultFromPath<App extends Application, Path extends string, IdOrNullable = any> = InferRemoveResult<GetService<App, Path>, IdOrNullable>;
|
|
94
|
+
|
|
95
|
+
export type InferDataFromPath<App extends Application, Path extends string, Method extends "create" | "update" | "patch"> = Method extends "create"
|
|
96
|
+
? InferCreateDataFromPath<App, Path>
|
|
97
|
+
: Method extends "update"
|
|
98
|
+
? InferUpdateDataFromPath<App, Path>
|
|
99
|
+
: Method extends "patch"
|
|
100
|
+
? InferPatchDataFromPath<App, Path>
|
|
101
|
+
: never;
|
|
102
|
+
|
|
103
|
+
export type InferResultFromPath<App extends Application, Path extends string, Method extends "get" | "find" | "create" | "update" | "patch" | "remove"> = Method extends "get"
|
|
104
|
+
? InferGetResultFromPath<App, Path>
|
|
105
|
+
: Method extends "find"
|
|
106
|
+
? InferFindResultFromPath<App, Path>
|
|
107
|
+
: Method extends "create"
|
|
108
|
+
? InferCreateResultFromPath<App, Path>
|
|
109
|
+
: Method extends "update"
|
|
110
|
+
? InferUpdateResultFromPath<App, Path>
|
|
111
|
+
: Method extends "patch"
|
|
112
|
+
? InferPatchResultFromPath<App, Path>
|
|
113
|
+
: Method extends "remove"
|
|
114
|
+
? InferRemoveResultFromPath<App, Path>
|
|
115
|
+
: never;
|
|
116
|
+
|
|
@@ -1,22 +1,38 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
2
|
|
|
3
|
+
export type GetItemsIsArrayOptions = {
|
|
4
|
+
from: "data" | "result" | "automatic"
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
export interface GetItemsIsArrayResult<T = any> {
|
|
4
|
-
items: T[]
|
|
5
|
-
isArray: boolean
|
|
8
|
+
items: T[]
|
|
9
|
+
isArray: boolean
|
|
6
10
|
}
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
* util to get items from context, return it as an array, no matter if it is an array or not
|
|
10
|
-
* uses `context.result` if existent. uses `context.data` otherwise
|
|
11
|
-
*/
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
13
|
export const getItemsIsArray = <T = any, H extends HookContext = HookContext>(
|
|
13
|
-
context: H
|
|
14
|
+
context: H,
|
|
15
|
+
options?: GetItemsIsArrayOptions
|
|
14
16
|
): GetItemsIsArrayResult<T> => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const {
|
|
18
|
+
from = "automatic"
|
|
19
|
+
} = options || {};
|
|
20
|
+
|
|
21
|
+
let itemOrItems;
|
|
22
|
+
|
|
23
|
+
if (from === "automatic") {
|
|
24
|
+
itemOrItems = context.type === "before"
|
|
25
|
+
? context.data
|
|
26
|
+
: context.result;
|
|
27
|
+
itemOrItems = itemOrItems && context.method === "find"
|
|
28
|
+
? (itemOrItems.data || itemOrItems)
|
|
19
29
|
: itemOrItems;
|
|
30
|
+
} else if (from === "data") {
|
|
31
|
+
itemOrItems = context.data;
|
|
32
|
+
} else if (from === "result") {
|
|
33
|
+
itemOrItems = context.result;
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
const isArray = Array.isArray(itemOrItems);
|
|
21
37
|
return {
|
|
22
38
|
items: isArray ? itemOrItems : itemOrItems != null ? [itemOrItems] : [],
|
package/src/utils/getPaginate.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PaginationOptions } from "@feathersjs/adapter-commons";
|
|
2
2
|
import type { HookContext } from "@feathersjs/feathers";
|
|
3
|
+
import { hasOwnProperty } from "./internal.utils";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* util to get paginate options from context
|
|
@@ -10,7 +11,7 @@ import type { HookContext } from "@feathersjs/feathers";
|
|
|
10
11
|
export const getPaginate = <H extends HookContext = HookContext>(
|
|
11
12
|
context: H
|
|
12
13
|
): PaginationOptions | undefined => {
|
|
13
|
-
if (
|
|
14
|
+
if (hasOwnProperty(context.params, "paginate")) {
|
|
14
15
|
return (context.params.paginate as PaginationOptions) || undefined;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -2,30 +2,39 @@ import _merge from "lodash/merge.js";
|
|
|
2
2
|
import _isEmpty from "lodash/isEmpty.js";
|
|
3
3
|
import type { Query } from "@feathersjs/feathers";
|
|
4
4
|
import {
|
|
5
|
+
areQueriesOverlapping,
|
|
5
6
|
handleArray,
|
|
6
7
|
handleCircular,
|
|
8
|
+
isQueryMoreExplicitThanQuery,
|
|
7
9
|
makeDefaultOptions,
|
|
8
10
|
moveProperty,
|
|
9
11
|
} from "./utils";
|
|
10
12
|
import type { MergeQueryOptions } from "./types";
|
|
11
13
|
import { filterQuery } from "../filterQuery";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
import { hasOwnProperty } from "../internal.utils";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Merges two queries into one.
|
|
18
|
+
* @param target Query to be merged into
|
|
19
|
+
* @param source Query to be merged from
|
|
20
|
+
* @param _options
|
|
21
|
+
* @returns Query
|
|
22
|
+
*/
|
|
23
|
+
export function mergeQuery<T = any>(
|
|
14
24
|
target: Query,
|
|
15
25
|
source: Query,
|
|
16
|
-
|
|
26
|
+
_options?: Partial<MergeQueryOptions<T>>
|
|
17
27
|
): Query {
|
|
18
|
-
const
|
|
28
|
+
const options = makeDefaultOptions(_options);
|
|
19
29
|
const { filters: targetFilters, query: targetQuery } = filterQuery(target, {
|
|
20
|
-
operators:
|
|
21
|
-
filters:
|
|
22
|
-
service:
|
|
30
|
+
operators: options.operators,
|
|
31
|
+
filters: options.filters,
|
|
32
|
+
service: options.service,
|
|
23
33
|
});
|
|
24
34
|
|
|
25
|
-
moveProperty(targetFilters, targetQuery, "$or");
|
|
26
|
-
moveProperty(targetFilters, targetQuery, "$and");
|
|
35
|
+
moveProperty(targetFilters, targetQuery, "$or", "$and");
|
|
27
36
|
|
|
28
|
-
if (target
|
|
37
|
+
if ("$limit" in target) {
|
|
29
38
|
targetFilters.$limit = target.$limit;
|
|
30
39
|
}
|
|
31
40
|
|
|
@@ -34,13 +43,12 @@ export function mergeQuery<T>(
|
|
|
34
43
|
filters: sourceFilters,
|
|
35
44
|
query: sourceQuery,
|
|
36
45
|
} = filterQuery(source, {
|
|
37
|
-
operators:
|
|
38
|
-
filters:
|
|
39
|
-
service:
|
|
46
|
+
operators: options.operators,
|
|
47
|
+
filters: options.filters,
|
|
48
|
+
service: options.service,
|
|
40
49
|
});
|
|
41
50
|
|
|
42
|
-
moveProperty(sourceFilters, sourceQuery, "$or");
|
|
43
|
-
moveProperty(sourceFilters, sourceQuery, "$and");
|
|
51
|
+
moveProperty(sourceFilters, sourceQuery, "$or", "$and");
|
|
44
52
|
|
|
45
53
|
if (source.$limit) {
|
|
46
54
|
sourceFilters.$limit = source.$limit;
|
|
@@ -50,37 +58,64 @@ export function mergeQuery<T>(
|
|
|
50
58
|
|
|
51
59
|
if (
|
|
52
60
|
target &&
|
|
53
|
-
!
|
|
54
|
-
|
|
61
|
+
!hasOwnProperty(target, "$limit") &&
|
|
62
|
+
hasOwnProperty(targetFilters, "$limit")
|
|
55
63
|
) {
|
|
56
64
|
delete targetFilters.$limit;
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
if (
|
|
60
68
|
source &&
|
|
61
|
-
!
|
|
62
|
-
|
|
69
|
+
!hasOwnProperty(source, "$limit") &&
|
|
70
|
+
hasOwnProperty(sourceFilters, "$limit")
|
|
63
71
|
) {
|
|
64
72
|
delete sourceFilters.$limit;
|
|
65
73
|
}
|
|
66
74
|
|
|
67
|
-
handleArray(targetFilters, sourceFilters, ["$select"],
|
|
75
|
+
handleArray(targetFilters, sourceFilters, ["$select"], options);
|
|
68
76
|
// remaining filters
|
|
69
77
|
delete sourceFilters["$select"];
|
|
70
78
|
_merge(targetFilters, sourceFilters);
|
|
71
79
|
|
|
72
80
|
//#endregion
|
|
73
81
|
|
|
82
|
+
const subsetQuery = isQueryMoreExplicitThanQuery(targetQuery, sourceQuery);
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
options.defaultHandle === "intersect" &&
|
|
86
|
+
!!subsetQuery &&
|
|
87
|
+
!hasOwnProperty(targetQuery, "$or", "$and") &&
|
|
88
|
+
!hasOwnProperty(sourceQuery, "$or", "$and")
|
|
89
|
+
) {
|
|
90
|
+
return {
|
|
91
|
+
...targetFilters,
|
|
92
|
+
...subsetQuery,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (
|
|
97
|
+
options.defaultHandle === "intersect" &&
|
|
98
|
+
!areQueriesOverlapping(targetQuery, sourceQuery) &&
|
|
99
|
+
!hasOwnProperty(targetQuery, "$or", "$and") &&
|
|
100
|
+
!hasOwnProperty(sourceQuery, "$or", "$and")
|
|
101
|
+
) {
|
|
102
|
+
return {
|
|
103
|
+
...targetFilters,
|
|
104
|
+
...targetQuery,
|
|
105
|
+
...sourceQuery,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
74
109
|
//#region '$or' / '$and'
|
|
75
110
|
|
|
76
111
|
if (
|
|
77
|
-
options
|
|
112
|
+
options.useLogicalConjunction &&
|
|
78
113
|
(options.defaultHandle === "combine" ||
|
|
79
114
|
options.defaultHandle === "intersect") &&
|
|
80
115
|
!_isEmpty(targetQuery)
|
|
81
116
|
) {
|
|
82
117
|
const logicalOp = options.defaultHandle === "combine" ? "$or" : "$and";
|
|
83
|
-
if (
|
|
118
|
+
if (hasOwnProperty(sourceQuery, logicalOp)) {
|
|
84
119
|
// omit '$or'/'$and' and put all other props into '$or'/'$and'
|
|
85
120
|
const andOr = sourceQuery[logicalOp] as unknown[];
|
|
86
121
|
delete sourceQuery[logicalOp];
|
|
@@ -96,9 +131,11 @@ export function mergeQuery<T>(
|
|
|
96
131
|
const keys = Object.keys(sourceQuery);
|
|
97
132
|
for (let i = 0, n = keys.length; i < n; i++) {
|
|
98
133
|
const key = keys[i];
|
|
99
|
-
handleCircular(targetQuery, sourceQuery, [key],
|
|
134
|
+
handleCircular(targetQuery, sourceQuery, [key], options);
|
|
100
135
|
}
|
|
101
|
-
const result = Object.assign({}, targetFilters, targetQuery) as Query;
|
|
102
136
|
|
|
103
|
-
return
|
|
137
|
+
return {
|
|
138
|
+
...targetFilters,
|
|
139
|
+
...targetQuery,
|
|
140
|
+
};
|
|
104
141
|
}
|