feathers-utils 2.0.0-9 → 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 (150) 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/index.ts +1 -0
  13. package/src/typesInternal.ts +7 -0
  14. package/src/utility-types/index.ts +116 -0
  15. package/src/utils/getItemsIsArray.ts +27 -11
  16. package/dist/esm/filters/array.d.ts +0 -2
  17. package/dist/esm/filters/array.js +0 -17
  18. package/dist/esm/filters/index.d.ts +0 -2
  19. package/dist/esm/filters/index.js +0 -2
  20. package/dist/esm/filters/object.d.ts +0 -2
  21. package/dist/esm/filters/object.js +0 -15
  22. package/dist/esm/hooks/checkMulti.d.ts +0 -5
  23. package/dist/esm/hooks/checkMulti.js +0 -20
  24. package/dist/esm/hooks/createRelated.d.ts +0 -12
  25. package/dist/esm/hooks/createRelated.js +0 -31
  26. package/dist/esm/hooks/index.d.ts +0 -6
  27. package/dist/esm/hooks/index.js +0 -6
  28. package/dist/esm/hooks/onDelete.d.ts +0 -12
  29. package/dist/esm/hooks/onDelete.js +0 -47
  30. package/dist/esm/hooks/removeRelated.d.ts +0 -11
  31. package/dist/esm/hooks/removeRelated.js +0 -37
  32. package/dist/esm/hooks/runPerItem.d.ts +0 -10
  33. package/dist/esm/hooks/runPerItem.js +0 -29
  34. package/dist/esm/hooks/setData.d.ts +0 -11
  35. package/dist/esm/hooks/setData.js +0 -46
  36. package/dist/esm/index.d.ts +0 -5
  37. package/dist/esm/index.js +0 -5
  38. package/dist/esm/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
  39. package/dist/esm/mixins/debounce-mixin/DebouncedStore.js +0 -46
  40. package/dist/esm/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
  41. package/dist/esm/mixins/debounce-mixin/debounceMixin.js +0 -19
  42. package/dist/esm/mixins/debounce-mixin/index.d.ts +0 -3
  43. package/dist/esm/mixins/debounce-mixin/index.js +0 -3
  44. package/dist/esm/mixins/debounce-mixin/types.d.ts +0 -13
  45. package/dist/esm/mixins/debounce-mixin/types.js +0 -1
  46. package/dist/esm/mixins/index.d.ts +0 -1
  47. package/dist/esm/mixins/index.js +0 -1
  48. package/dist/esm/types.d.ts +0 -3
  49. package/dist/esm/types.js +0 -1
  50. package/dist/esm/typesInternal.d.ts +0 -3
  51. package/dist/esm/typesInternal.js +0 -3
  52. package/dist/esm/utils/filterQuery.d.ts +0 -8
  53. package/dist/esm/utils/filterQuery.js +0 -30
  54. package/dist/esm/utils/getItemsIsArray.d.ts +0 -10
  55. package/dist/esm/utils/getItemsIsArray.js +0 -16
  56. package/dist/esm/utils/getPaginate.d.ts +0 -9
  57. package/dist/esm/utils/getPaginate.js +0 -20
  58. package/dist/esm/utils/index.d.ts +0 -11
  59. package/dist/esm/utils/index.js +0 -11
  60. package/dist/esm/utils/isMulti.d.ts +0 -11
  61. package/dist/esm/utils/isMulti.js +0 -26
  62. package/dist/esm/utils/isPaginated.d.ts +0 -5
  63. package/dist/esm/utils/isPaginated.js +0 -11
  64. package/dist/esm/utils/markHookForSkip.d.ts +0 -7
  65. package/dist/esm/utils/markHookForSkip.js +0 -18
  66. package/dist/esm/utils/mergeQuery/index.d.ts +0 -3
  67. package/dist/esm/utils/mergeQuery/index.js +0 -3
  68. package/dist/esm/utils/mergeQuery/mergeArrays.d.ts +0 -3
  69. package/dist/esm/utils/mergeQuery/mergeArrays.js +0 -37
  70. package/dist/esm/utils/mergeQuery/mergeQuery.d.ts +0 -3
  71. package/dist/esm/utils/mergeQuery/mergeQuery.js +0 -70
  72. package/dist/esm/utils/mergeQuery/types.d.ts +0 -13
  73. package/dist/esm/utils/mergeQuery/types.js +0 -1
  74. package/dist/esm/utils/mergeQuery/utils.d.ts +0 -11
  75. package/dist/esm/utils/mergeQuery/utils.js +0 -272
  76. package/dist/esm/utils/pushSet.d.ts +0 -8
  77. package/dist/esm/utils/pushSet.js +0 -22
  78. package/dist/esm/utils/setResultEmpty.d.ts +0 -5
  79. package/dist/esm/utils/setResultEmpty.js +0 -28
  80. package/dist/esm/utils/shouldSkip.d.ts +0 -8
  81. package/dist/esm/utils/shouldSkip.js +0 -29
  82. package/dist/esm/utils/validateQueryProperty.d.ts +0 -5
  83. package/dist/esm/utils/validateQueryProperty.js +0 -23
  84. package/dist/filters/array.d.ts +0 -2
  85. package/dist/filters/array.js +0 -21
  86. package/dist/filters/index.d.ts +0 -2
  87. package/dist/filters/index.js +0 -18
  88. package/dist/filters/object.d.ts +0 -2
  89. package/dist/filters/object.js +0 -22
  90. package/dist/hooks/checkMulti.d.ts +0 -5
  91. package/dist/hooks/checkMulti.js +0 -24
  92. package/dist/hooks/createRelated.d.ts +0 -12
  93. package/dist/hooks/createRelated.js +0 -44
  94. package/dist/hooks/index.d.ts +0 -6
  95. package/dist/hooks/index.js +0 -22
  96. package/dist/hooks/onDelete.d.ts +0 -12
  97. package/dist/hooks/onDelete.js +0 -60
  98. package/dist/hooks/removeRelated.d.ts +0 -11
  99. package/dist/hooks/removeRelated.js +0 -50
  100. package/dist/hooks/runPerItem.d.ts +0 -10
  101. package/dist/hooks/runPerItem.js +0 -42
  102. package/dist/hooks/setData.d.ts +0 -11
  103. package/dist/hooks/setData.js +0 -54
  104. package/dist/index.js +0 -21
  105. package/dist/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
  106. package/dist/mixins/debounce-mixin/DebouncedStore.js +0 -65
  107. package/dist/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
  108. package/dist/mixins/debounce-mixin/debounceMixin.js +0 -23
  109. package/dist/mixins/debounce-mixin/index.d.ts +0 -3
  110. package/dist/mixins/debounce-mixin/index.js +0 -19
  111. package/dist/mixins/debounce-mixin/types.d.ts +0 -13
  112. package/dist/mixins/debounce-mixin/types.js +0 -2
  113. package/dist/mixins/index.d.ts +0 -1
  114. package/dist/mixins/index.js +0 -17
  115. package/dist/types.d.ts +0 -3
  116. package/dist/types.js +0 -2
  117. package/dist/typesInternal.d.ts +0 -3
  118. package/dist/typesInternal.js +0 -4
  119. package/dist/utils/filterQuery.d.ts +0 -8
  120. package/dist/utils/filterQuery.js +0 -46
  121. package/dist/utils/getItemsIsArray.d.ts +0 -10
  122. package/dist/utils/getItemsIsArray.js +0 -20
  123. package/dist/utils/getPaginate.d.ts +0 -9
  124. package/dist/utils/getPaginate.js +0 -22
  125. package/dist/utils/index.d.ts +0 -11
  126. package/dist/utils/index.js +0 -27
  127. package/dist/utils/isMulti.d.ts +0 -11
  128. package/dist/utils/isMulti.js +0 -30
  129. package/dist/utils/isPaginated.d.ts +0 -5
  130. package/dist/utils/isPaginated.js +0 -15
  131. package/dist/utils/markHookForSkip.d.ts +0 -7
  132. package/dist/utils/markHookForSkip.js +0 -22
  133. package/dist/utils/mergeQuery/index.d.ts +0 -3
  134. package/dist/utils/mergeQuery/index.js +0 -19
  135. package/dist/utils/mergeQuery/mergeArrays.d.ts +0 -3
  136. package/dist/utils/mergeQuery/mergeArrays.js +0 -41
  137. package/dist/utils/mergeQuery/mergeQuery.d.ts +0 -3
  138. package/dist/utils/mergeQuery/mergeQuery.js +0 -77
  139. package/dist/utils/mergeQuery/types.d.ts +0 -13
  140. package/dist/utils/mergeQuery/types.js +0 -2
  141. package/dist/utils/mergeQuery/utils.d.ts +0 -11
  142. package/dist/utils/mergeQuery/utils.js +0 -287
  143. package/dist/utils/pushSet.d.ts +0 -8
  144. package/dist/utils/pushSet.js +0 -29
  145. package/dist/utils/setResultEmpty.d.ts +0 -5
  146. package/dist/utils/setResultEmpty.js +0 -32
  147. package/dist/utils/shouldSkip.d.ts +0 -8
  148. package/dist/utils/shouldSkip.js +0 -33
  149. package/dist/utils/validateQueryProperty.d.ts +0 -5
  150. 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-9",
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.33",
47
- "@feathersjs/errors": "5.0.0-pre.33",
48
- "@feathersjs/feathers": "5.0.0-pre.33",
49
- "feathers-hooks-common": "^7.0.0-pre.1",
50
- "lodash": "^4.17.21",
51
- "type-fest": "^3.2.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.33",
50
+ "@feathersjs/memory": "^5.0.0",
55
51
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
56
- "@types/lodash": "^4.14.189",
57
- "@types/mocha": "^10.0.0",
58
- "@types/node": "^18.11.9",
59
- "@typescript-eslint/eslint-plugin": "^5.44.0",
60
- "@typescript-eslint/parser": "^5.44.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.28.0",
63
- "eslint-config-prettier": "^8.5.0",
64
- "eslint-import-resolver-typescript": "^3.5.2",
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.1.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.8.0",
67
+ "prettier": "^2.8.4",
73
68
  "shx": "^0.3.4",
74
- "ts-node": "^10.9.1",
75
- "typescript": "^4.9.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
+ };
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
+
@@ -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
- let itemOrItems = context.result !== undefined ? context.result : context.data;
16
- itemOrItems =
17
- itemOrItems && context.method === "find"
18
- ? itemOrItems.data || itemOrItems
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] : [],
@@ -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 type OnDeleteAction = "cascade" | "set null";
3
- export interface OnDeleteOptions {
4
- keyThere: string;
5
- keyHere: string;
6
- onDelete: OnDeleteAction;
7
- blocking?: boolean;
8
- }
9
- /**
10
- * hook to manipulate related items on delete
11
- */
12
- export declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(service: keyof S, { keyThere, keyHere, onDelete, blocking, }: OnDeleteOptions): (context: H) => Promise<H>;
@@ -1,47 +0,0 @@
1
- import { checkContext } from "feathers-hooks-common";
2
- import { getItemsIsArray, shouldSkip } from "../utils";
3
- /**
4
- * hook to manipulate related items on delete
5
- */
6
- export function onDelete(service, { keyThere, keyHere = "id", onDelete = "cascade", blocking = true, }) {
7
- if (!service || !keyThere) {
8
- throw "initialize hook 'removeRelated' completely!";
9
- }
10
- if (!["cascade", "set null"].includes(onDelete)) {
11
- throw "onDelete must be 'cascade' or 'set null'";
12
- }
13
- return async (context) => {
14
- if (shouldSkip("onDelete", context)) {
15
- return context;
16
- }
17
- checkContext(context, "after", "remove", "onDelete");
18
- const { items } = getItemsIsArray(context);
19
- let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
20
- ids = [...new Set(ids)];
21
- if (!ids || ids.length <= 0) {
22
- return context;
23
- }
24
- const params = {
25
- query: {
26
- [keyThere]: {
27
- $in: ids,
28
- },
29
- },
30
- paginate: false,
31
- };
32
- let promise;
33
- if (onDelete === "cascade") {
34
- promise = context.app.service(service).remove(null, params);
35
- }
36
- else if (onDelete === "set null") {
37
- const data = { [keyThere]: null };
38
- promise = context.app
39
- .service(service)
40
- .patch(null, data, params);
41
- }
42
- if (blocking) {
43
- await promise;
44
- }
45
- return context;
46
- };
47
- }
@@ -1,11 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- export interface RemoveRelatedOptions<S = Record<string, any>> {
3
- service: keyof S;
4
- keyThere: string;
5
- keyHere: string;
6
- blocking?: boolean;
7
- }
8
- /**
9
- * hook to remove related items
10
- */
11
- export declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
@@ -1,37 +0,0 @@
1
- import { checkContext } from "feathers-hooks-common";
2
- import { getItemsIsArray, shouldSkip } from "../utils";
3
- /**
4
- * hook to remove related items
5
- */
6
- export function removeRelated({ service, keyThere, keyHere = "id", blocking = true, }) {
7
- if (!service || !keyThere) {
8
- throw "initialize hook 'removeRelated' completely!";
9
- }
10
- return async (context) => {
11
- if (shouldSkip("removeRelated", context)) {
12
- return context;
13
- }
14
- checkContext(context, "after", "remove", "removeRelated");
15
- const { items } = getItemsIsArray(context);
16
- let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
17
- ids = [...new Set(ids)];
18
- if (!ids || ids.length <= 0) {
19
- return context;
20
- }
21
- // feathers does not accept `paginate: false` for remove, but some adapters need it to work properly
22
- const promise = context.app
23
- .service(service)
24
- .remove(null, {
25
- query: {
26
- [keyThere]: {
27
- $in: ids,
28
- },
29
- },
30
- paginate: false,
31
- });
32
- if (blocking) {
33
- await promise;
34
- }
35
- return context;
36
- };
37
- }