feathers-utils 2.0.0-8 → 2.0.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.
Files changed (156) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -1
  3. package/dist/index.cjs +918 -0
  4. package/dist/index.d.ts +255 -5
  5. package/dist/index.mjs +892 -0
  6. package/package.json +34 -38
  7. package/src/filters/object.ts +1 -1
  8. package/src/hooks/forEach.ts +47 -0
  9. package/src/hooks/index.ts +3 -0
  10. package/src/hooks/makeSequelizeQuery.ts_ +4 -4
  11. package/src/hooks/parseFields.ts +27 -0
  12. package/src/hooks/runPerItem.ts +1 -2
  13. package/src/hooks/setData.ts +1 -1
  14. package/src/index.ts +1 -0
  15. package/src/typesInternal.ts +7 -0
  16. package/src/utility-types/index.ts +116 -0
  17. package/src/utils/filterQuery.ts +0 -2
  18. package/src/utils/getItemsIsArray.ts +29 -13
  19. package/src/utils/getPaginate.ts +1 -1
  20. package/src/utils/isPaginated.ts +1 -1
  21. package/src/utils/shouldSkip.ts +5 -17
  22. package/dist/esm/filters/array.d.ts +0 -2
  23. package/dist/esm/filters/array.js +0 -17
  24. package/dist/esm/filters/index.d.ts +0 -2
  25. package/dist/esm/filters/index.js +0 -2
  26. package/dist/esm/filters/object.d.ts +0 -2
  27. package/dist/esm/filters/object.js +0 -15
  28. package/dist/esm/hooks/checkMulti.d.ts +0 -5
  29. package/dist/esm/hooks/checkMulti.js +0 -20
  30. package/dist/esm/hooks/createRelated.d.ts +0 -12
  31. package/dist/esm/hooks/createRelated.js +0 -31
  32. package/dist/esm/hooks/index.d.ts +0 -6
  33. package/dist/esm/hooks/index.js +0 -6
  34. package/dist/esm/hooks/onDelete.d.ts +0 -12
  35. package/dist/esm/hooks/onDelete.js +0 -47
  36. package/dist/esm/hooks/removeRelated.d.ts +0 -11
  37. package/dist/esm/hooks/removeRelated.js +0 -37
  38. package/dist/esm/hooks/runPerItem.d.ts +0 -11
  39. package/dist/esm/hooks/runPerItem.js +0 -30
  40. package/dist/esm/hooks/setData.d.ts +0 -11
  41. package/dist/esm/hooks/setData.js +0 -46
  42. package/dist/esm/index.d.ts +0 -5
  43. package/dist/esm/index.js +0 -5
  44. package/dist/esm/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
  45. package/dist/esm/mixins/debounce-mixin/DebouncedStore.js +0 -46
  46. package/dist/esm/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
  47. package/dist/esm/mixins/debounce-mixin/debounceMixin.js +0 -19
  48. package/dist/esm/mixins/debounce-mixin/index.d.ts +0 -3
  49. package/dist/esm/mixins/debounce-mixin/index.js +0 -3
  50. package/dist/esm/mixins/debounce-mixin/types.d.ts +0 -13
  51. package/dist/esm/mixins/debounce-mixin/types.js +0 -1
  52. package/dist/esm/mixins/index.d.ts +0 -1
  53. package/dist/esm/mixins/index.js +0 -1
  54. package/dist/esm/types.d.ts +0 -3
  55. package/dist/esm/types.js +0 -1
  56. package/dist/esm/typesInternal.d.ts +0 -3
  57. package/dist/esm/typesInternal.js +0 -3
  58. package/dist/esm/utils/filterQuery.d.ts +0 -8
  59. package/dist/esm/utils/filterQuery.js +0 -32
  60. package/dist/esm/utils/getItemsIsArray.d.ts +0 -10
  61. package/dist/esm/utils/getItemsIsArray.js +0 -16
  62. package/dist/esm/utils/getPaginate.d.ts +0 -9
  63. package/dist/esm/utils/getPaginate.js +0 -20
  64. package/dist/esm/utils/index.d.ts +0 -11
  65. package/dist/esm/utils/index.js +0 -11
  66. package/dist/esm/utils/isMulti.d.ts +0 -11
  67. package/dist/esm/utils/isMulti.js +0 -26
  68. package/dist/esm/utils/isPaginated.d.ts +0 -5
  69. package/dist/esm/utils/isPaginated.js +0 -11
  70. package/dist/esm/utils/markHookForSkip.d.ts +0 -7
  71. package/dist/esm/utils/markHookForSkip.js +0 -18
  72. package/dist/esm/utils/mergeQuery/index.d.ts +0 -3
  73. package/dist/esm/utils/mergeQuery/index.js +0 -3
  74. package/dist/esm/utils/mergeQuery/mergeArrays.d.ts +0 -3
  75. package/dist/esm/utils/mergeQuery/mergeArrays.js +0 -37
  76. package/dist/esm/utils/mergeQuery/mergeQuery.d.ts +0 -3
  77. package/dist/esm/utils/mergeQuery/mergeQuery.js +0 -70
  78. package/dist/esm/utils/mergeQuery/types.d.ts +0 -13
  79. package/dist/esm/utils/mergeQuery/types.js +0 -1
  80. package/dist/esm/utils/mergeQuery/utils.d.ts +0 -11
  81. package/dist/esm/utils/mergeQuery/utils.js +0 -272
  82. package/dist/esm/utils/pushSet.d.ts +0 -8
  83. package/dist/esm/utils/pushSet.js +0 -22
  84. package/dist/esm/utils/setResultEmpty.d.ts +0 -5
  85. package/dist/esm/utils/setResultEmpty.js +0 -28
  86. package/dist/esm/utils/shouldSkip.d.ts +0 -8
  87. package/dist/esm/utils/shouldSkip.js +0 -32
  88. package/dist/esm/utils/validateQueryProperty.d.ts +0 -5
  89. package/dist/esm/utils/validateQueryProperty.js +0 -23
  90. package/dist/filters/array.d.ts +0 -2
  91. package/dist/filters/array.js +0 -21
  92. package/dist/filters/index.d.ts +0 -2
  93. package/dist/filters/index.js +0 -18
  94. package/dist/filters/object.d.ts +0 -2
  95. package/dist/filters/object.js +0 -22
  96. package/dist/hooks/checkMulti.d.ts +0 -5
  97. package/dist/hooks/checkMulti.js +0 -24
  98. package/dist/hooks/createRelated.d.ts +0 -12
  99. package/dist/hooks/createRelated.js +0 -44
  100. package/dist/hooks/index.d.ts +0 -6
  101. package/dist/hooks/index.js +0 -22
  102. package/dist/hooks/onDelete.d.ts +0 -12
  103. package/dist/hooks/onDelete.js +0 -60
  104. package/dist/hooks/removeRelated.d.ts +0 -11
  105. package/dist/hooks/removeRelated.js +0 -50
  106. package/dist/hooks/runPerItem.d.ts +0 -11
  107. package/dist/hooks/runPerItem.js +0 -43
  108. package/dist/hooks/setData.d.ts +0 -11
  109. package/dist/hooks/setData.js +0 -54
  110. package/dist/index.js +0 -21
  111. package/dist/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
  112. package/dist/mixins/debounce-mixin/DebouncedStore.js +0 -65
  113. package/dist/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
  114. package/dist/mixins/debounce-mixin/debounceMixin.js +0 -23
  115. package/dist/mixins/debounce-mixin/index.d.ts +0 -3
  116. package/dist/mixins/debounce-mixin/index.js +0 -19
  117. package/dist/mixins/debounce-mixin/types.d.ts +0 -13
  118. package/dist/mixins/debounce-mixin/types.js +0 -2
  119. package/dist/mixins/index.d.ts +0 -1
  120. package/dist/mixins/index.js +0 -17
  121. package/dist/types.d.ts +0 -3
  122. package/dist/types.js +0 -2
  123. package/dist/typesInternal.d.ts +0 -3
  124. package/dist/typesInternal.js +0 -4
  125. package/dist/utils/filterQuery.d.ts +0 -8
  126. package/dist/utils/filterQuery.js +0 -48
  127. package/dist/utils/getItemsIsArray.d.ts +0 -10
  128. package/dist/utils/getItemsIsArray.js +0 -20
  129. package/dist/utils/getPaginate.d.ts +0 -9
  130. package/dist/utils/getPaginate.js +0 -21
  131. package/dist/utils/index.d.ts +0 -11
  132. package/dist/utils/index.js +0 -27
  133. package/dist/utils/isMulti.d.ts +0 -11
  134. package/dist/utils/isMulti.js +0 -30
  135. package/dist/utils/isPaginated.d.ts +0 -5
  136. package/dist/utils/isPaginated.js +0 -15
  137. package/dist/utils/markHookForSkip.d.ts +0 -7
  138. package/dist/utils/markHookForSkip.js +0 -22
  139. package/dist/utils/mergeQuery/index.d.ts +0 -3
  140. package/dist/utils/mergeQuery/index.js +0 -19
  141. package/dist/utils/mergeQuery/mergeArrays.d.ts +0 -3
  142. package/dist/utils/mergeQuery/mergeArrays.js +0 -41
  143. package/dist/utils/mergeQuery/mergeQuery.d.ts +0 -3
  144. package/dist/utils/mergeQuery/mergeQuery.js +0 -77
  145. package/dist/utils/mergeQuery/types.d.ts +0 -13
  146. package/dist/utils/mergeQuery/types.js +0 -2
  147. package/dist/utils/mergeQuery/utils.d.ts +0 -11
  148. package/dist/utils/mergeQuery/utils.js +0 -287
  149. package/dist/utils/pushSet.d.ts +0 -8
  150. package/dist/utils/pushSet.js +0 -29
  151. package/dist/utils/setResultEmpty.d.ts +0 -5
  152. package/dist/utils/setResultEmpty.js +0 -32
  153. package/dist/utils/shouldSkip.d.ts +0 -8
  154. package/dist/utils/shouldSkip.js +0 -36
  155. package/dist/utils/validateQueryProperty.d.ts +0 -5
  156. 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.0.0-8",
3
+ "version": "2.0.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": ">= 14"
11
+ "node": ">= 16"
12
12
  },
13
13
  "homepage": "https://github.com/fratzinger/feathers-utils",
14
14
  "license": "MIT",
15
- "main": "dist/index.js",
16
- "module": "dist/esm/index.js",
17
- "types": "dist/index.d.ts",
15
+ "type": "module",
18
16
  "exports": {
19
17
  ".": {
20
- "import": "./dist/esm/index.js",
21
- "require": "./dist/index.js",
22
- "types": "./dist/index.d.ts"
18
+ "import": "./dist/index.mjs",
19
+ "require": "./dist/index.cjs"
23
20
  }
24
21
  },
25
- "directories": {
26
- "dist": "dist"
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,44 @@
34
30
  "dist/**"
35
31
  ],
36
32
  "scripts": {
37
- "build": "shx rm -rf dist/ && npm run tsc",
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": "cross-env NODE_ENV=test TS_NODE_PROJECT='tsconfig.test.json' mocha --require ts-node/register 'test/**/*.test.ts' --timeout 5000",
42
- "coverage": "nyc npm run test",
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-pre.29",
47
- "@feathersjs/errors": "5.0.0-pre.29",
48
- "@feathersjs/feathers": "5.0.0-pre.29",
49
- "feathers-hooks-common": "^7.0.0-pre.0",
50
- "lodash": "^4.17.21",
51
- "type-fest": "^2.19.0"
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
+ "feathers-hooks-common": "^7.0.0",
47
+ "lodash": "^4.17.21"
52
48
  },
53
49
  "devDependencies": {
54
- "@feathersjs/memory": "^5.0.0-pre.20",
50
+ "@feathersjs/memory": "^5.0.0",
55
51
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
56
- "@types/lodash": "^4.14.185",
57
- "@types/mocha": "^9.1.1",
58
- "@types/node": "^18.7.18",
59
- "@typescript-eslint/eslint-plugin": "^5.37.0",
60
- "@typescript-eslint/parser": "^5.37.0",
52
+ "@types/lodash": "^4.14.191",
53
+ "@types/mocha": "^10.0.1",
54
+ "@types/node": "^18.14.1",
55
+ "@typescript-eslint/eslint-plugin": "^5.53.0",
56
+ "@typescript-eslint/parser": "^5.53.0",
57
+ "@vitest/coverage-c8": "^0.29.1",
61
58
  "cross-env": "^7.0.3",
62
- "eslint": "^8.23.1",
63
- "eslint-config-prettier": "^8.5.0",
64
- "eslint-import-resolver-typescript": "^3.5.1",
65
- "eslint-plugin-import": "^2.26.0",
59
+ "eslint": "^8.34.0",
60
+ "eslint-config-prettier": "^8.6.0",
61
+ "eslint-import-resolver-typescript": "^3.5.3",
62
+ "eslint-plugin-import": "^2.27.5",
66
63
  "eslint-plugin-prettier": "^4.2.1",
67
- "eslint-plugin-security": "^1.5.0",
68
- "feathers-memory": "^4.1.0",
69
- "mocha": "^10.0.0",
70
- "np": "^7.6.2",
64
+ "eslint-plugin-security": "^1.7.1",
65
+ "np": "^7.6.3",
71
66
  "nyc": "^15.1.0",
72
- "prettier": "^2.7.1",
67
+ "prettier": "^2.8.4",
73
68
  "shx": "^0.3.4",
74
- "ts-node": "^10.9.1",
75
- "typescript": "^4.8.3"
69
+ "typescript": "^4.9.5",
70
+ "unbuild": "^1.1.2",
71
+ "vitest": "^0.29.1"
76
72
  }
77
73
  }
@@ -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
+ };
@@ -1,6 +1,9 @@
1
1
  export * from "./checkMulti";
2
2
  export * from "./createRelated";
3
+ export * from "./forEach";
3
4
  export * from "./onDelete";
5
+ export * from "./parseFields";
4
6
  export * from "./removeRelated";
5
7
  export * from "./runPerItem";
6
8
  export * from "./setData";
9
+
@@ -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
+ };
@@ -21,8 +21,7 @@ const makeOptions = (
21
21
 
22
22
  /**
23
23
  * hook to run a hook for each item in the context
24
- * uses `context.data` in a before hook
25
- * uses `context.result` in an after hook
24
+ * uses `context.result` if it is existent. otherwise uses context.data
26
25
  */
27
26
  export const runPerItem = <H extends HookContext = HookContext>(
28
27
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -20,7 +20,7 @@ const defaultOptions: Required<HookSetDataOptions> = {
20
20
  };
21
21
 
22
22
  /**
23
- * hook to set properties on `context.data` (before-hook) or `context.result` (after-hook)
23
+ * hook to set properties on `context.result` (if existent) or `context.data` (otherwise)
24
24
  */
25
25
  export function setData<H extends HookContext = HookContext>(
26
26
  from: PropertyPath,
package/src/index.ts CHANGED
@@ -5,3 +5,4 @@ export * from "./utils";
5
5
  export * from "./filters";
6
6
 
7
7
  export * from "./types";
8
+ export * from "./utility-types";
@@ -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
+
@@ -34,10 +34,8 @@ export function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>) {
34
34
  if (
35
35
  service &&
36
36
  "filterQuery" in service &&
37
- // @ts-expect-error service is of type 'never'
38
37
  typeof service.filterQuery === "function"
39
38
  ) {
40
- // @ts-expect-error service has no filterQuery method
41
39
  return service.filterQuery({ query }, optionsForFilterQuery);
42
40
  } else {
43
41
  return plainFilterQuery(query, optionsForFilterQuery);
@@ -1,22 +1,38 @@
1
1
  import type { HookContext } from "@feathersjs/feathers";
2
2
 
3
- export interface GetItemsIsArrayOptions<T = any> {
4
- items: T[];
5
- isArray: boolean;
3
+ export type GetItemsIsArrayOptions = {
4
+ from: "data" | "result" | "automatic"
6
5
  }
7
6
 
8
- /**
9
- * util to get items from context, return it as an array, no matter if it is an array or not
10
- * in a before hook, it uses `context.data`. in an after hook, it uses `context.result`
11
- */
7
+ export interface GetItemsIsArrayResult<T = any> {
8
+ items: T[]
9
+ isArray: boolean
10
+ }
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
- ): GetItemsIsArrayOptions<T> => {
15
- let itemOrItems = context.type === "before" ? context.data : context.result;
16
- itemOrItems =
17
- itemOrItems && context.method === "find"
18
- ? itemOrItems.data || itemOrItems
14
+ context: H,
15
+ options?: GetItemsIsArrayOptions
16
+ ): GetItemsIsArrayResult<T> => {
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] : [],
@@ -17,7 +17,7 @@ export const getPaginate = <H extends HookContext = HookContext>(
17
17
  if (context.params.paginate === false) {
18
18
  return undefined;
19
19
  }
20
- let options = context.service.options || {};
20
+ let options = context.service?.options || {};
21
21
 
22
22
  options = {
23
23
  ...options,
@@ -7,7 +7,7 @@ import { getPaginate } from "./getPaginate";
7
7
  export const isPaginated = <H extends HookContext = HookContext>(
8
8
  context: H
9
9
  ): boolean => {
10
- if (context.params.paginate === false) {
10
+ if (context.params.paginate === false || context.method !== "find") {
11
11
  return false;
12
12
  }
13
13
 
@@ -31,24 +31,12 @@ export const shouldSkip = <
31
31
  const { type } = context;
32
32
  if (skipHooks.includes(hookName)) {
33
33
  return true;
34
- }
35
- if (skipHooks.includes("all")) {
34
+ } else if (skipHooks.includes("all")) {
35
+ return true;
36
+ } else if (skipHooks.includes(type)) {
37
+ return true;
38
+ } else if (skipHooks.includes(`${type}:${hookName}`)) {
36
39
  return true;
37
- }
38
- if (type === "before") {
39
- return (
40
- skipHooks.includes(`before:${hookName}`) || skipHooks.includes("before")
41
- );
42
- }
43
- if (type === "after") {
44
- return (
45
- skipHooks.includes(`after:${hookName}`) || skipHooks.includes("after")
46
- );
47
- }
48
- if (type === "error") {
49
- return (
50
- skipHooks.includes(`error:${hookName}`) || skipHooks.includes("error")
51
- );
52
40
  }
53
41
 
54
42
  return false;
@@ -1,2 +0,0 @@
1
- import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
2
- export declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
@@ -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,2 +0,0 @@
1
- export * from "./array";
2
- export * from "./object";
@@ -1,2 +0,0 @@
1
- export * from "./array";
2
- export * from "./object";
@@ -1,2 +0,0 @@
1
- import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
2
- export declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
@@ -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,5 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- /**
3
- * hook to check if context is multi patch/remove and if the service allows it
4
- */
5
- export declare function checkMulti<H extends HookContext = HookContext>(): (context: H) => H;
@@ -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
- }
@@ -1,6 +0,0 @@
1
- export * from "./checkMulti";
2
- export * from "./createRelated";
3
- export * from "./onDelete";
4
- export * from "./removeRelated";
5
- export * from "./runPerItem";
6
- export * from "./setData";
@@ -1,6 +0,0 @@
1
- export * from "./checkMulti";
2
- export * from "./createRelated";
3
- export * from "./onDelete";
4
- export * from "./removeRelated";
5
- export * from "./runPerItem";
6
- export * from "./setData";
@@ -1,12 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- export declare 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>;