feathers-utils 1.11.0 → 1.13.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/README.md CHANGED
@@ -21,6 +21,7 @@ npm i feathers-utils
21
21
 
22
22
  - `checkMulti`: throws if the request is **multi** data, but the service has `allowsMulti(method)` returns `false`
23
23
  - `createRelated`: simply create related items from a hook.
24
+ - `onDelete`: simply remove/set null related items from a hook.
24
25
  - `removeRelated`: simple remove related items from a hook. Basically `cascade` at feathers level.
25
26
  - `runPerItem`: run a function for every item. Meant for `multi:true`.
26
27
  - `setData`: map properties from `context` to `data`. Something like `userId: context.params.user.id`
@@ -0,0 +1,8 @@
1
+ import type { ReturnAsyncHook, Promisable } from "../types";
2
+ import type { HookContext } from "@feathersjs/feathers";
3
+ import type { GetItemsIsArrayOptions } from "../utils/getItemsIsArray";
4
+ export interface HookForEachOptions {
5
+ wait?: "sequential" | "parallel" | false;
6
+ items?: GetItemsIsArrayOptions["from"];
7
+ }
8
+ export declare const forEach: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookForEachOptions) => ReturnAsyncHook;
@@ -0,0 +1,31 @@
1
+ import { shouldSkip } from "../utils/shouldSkip";
2
+ import { getItemsIsArray } from "../utils/getItemsIsArray";
3
+ export const forEach = (
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ actionPerItem, _options) => {
6
+ const options = {
7
+ wait: "parallel",
8
+ items: "automatic",
9
+ ..._options
10
+ };
11
+ return async (context) => {
12
+ if (shouldSkip("runForItems", context)) {
13
+ return context;
14
+ }
15
+ const { items } = getItemsIsArray(context, { from: options.items });
16
+ const promises = [];
17
+ for (const item of items) {
18
+ const promise = actionPerItem(item, context);
19
+ if (options.wait === "sequential") {
20
+ await promise;
21
+ }
22
+ else {
23
+ promises.push(promise);
24
+ }
25
+ }
26
+ if (options.wait === "parallel") {
27
+ await Promise.all(promises);
28
+ }
29
+ return context;
30
+ };
31
+ };
@@ -0,0 +1,8 @@
1
+ import type { HookContext } from "@feathersjs/feathers";
2
+ /**
3
+ * Parse fields to date or number
4
+ * skips undefined fields
5
+ */
6
+ export declare const parseFields: (type: "date" | "number", options: {
7
+ fields: string[];
8
+ }) => (context: HookContext) => HookContext<any, import("@feathersjs/feathers").Service<any>>;
@@ -0,0 +1,23 @@
1
+ import { getItemsIsArray } from "../utils/getItemsIsArray";
2
+ /**
3
+ * Parse fields to date or number
4
+ * skips undefined fields
5
+ */
6
+ export const parseFields = (type, options) => (context) => {
7
+ const { items } = getItemsIsArray(context);
8
+ items.forEach(item => {
9
+ options.fields.forEach(field => {
10
+ // ignore undefined fields
11
+ if (!(field in item)) {
12
+ return;
13
+ }
14
+ if (type === "date") {
15
+ item[field] = new Date(item[field]);
16
+ }
17
+ else if (type === "number") {
18
+ item[field] = Number(item[field]);
19
+ }
20
+ });
21
+ });
22
+ return context;
23
+ };
@@ -11,6 +11,8 @@ export { createRelated } from "./hooks/createRelated";
11
11
  export { setData };
12
12
  export { removeRelated } from "./hooks/removeRelated";
13
13
  export { runPerItem };
14
+ export * from "./hooks/forEach";
15
+ export * from "./hooks/parseFields";
14
16
  import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
15
17
  export declare const mixins: {
16
18
  debounceMixin: typeof debounceMixin;
@@ -32,3 +34,4 @@ export { getItemsIsArray } from "./utils/getItemsIsArray";
32
34
  export { onDelete } from "./hooks/onDelete";
33
35
  export { shouldSkip } from "./utils/shouldSkip";
34
36
  export * from "./types";
37
+ export * from "./utility-types/utility-types";
package/dist/esm/index.js CHANGED
@@ -5,17 +5,19 @@ import { runPerItem } from "./hooks/runPerItem";
5
5
  export const hooks = {
6
6
  checkMulti,
7
7
  setData,
8
- runPerItem
8
+ runPerItem,
9
9
  };
10
10
  export { checkMulti };
11
11
  export { createRelated } from "./hooks/createRelated";
12
12
  export { setData };
13
13
  export { removeRelated } from "./hooks/removeRelated";
14
14
  export { runPerItem };
15
+ export * from "./hooks/forEach";
16
+ export * from "./hooks/parseFields";
15
17
  import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
16
18
  export const mixins = {
17
19
  debounceMixin,
18
- DebouncedStore
20
+ DebouncedStore,
19
21
  };
20
22
  export { debounceMixin };
21
23
  export { DebouncedStore };
@@ -33,3 +35,4 @@ export { getItemsIsArray } from "./utils/getItemsIsArray";
33
35
  export { onDelete } from "./hooks/onDelete";
34
36
  export { shouldSkip } from "./utils/shouldSkip";
35
37
  export * from "./types";
38
+ export * from "./utility-types/utility-types";
@@ -82,7 +82,7 @@ export interface FilterQueryResult {
82
82
  paginate?: unknown;
83
83
  [key: string]: unknown;
84
84
  }
85
- export interface GetItemsIsArrayOptions<T = any> {
85
+ export interface GetItemsIsArrayResult<T = any> {
86
86
  items: T[];
87
87
  isArray: boolean;
88
88
  }
@@ -0,0 +1,33 @@
1
+ export declare type InferCreateData<S> = S extends {
2
+ create: (data: infer D, params: any) => any;
3
+ } ? D : never;
4
+ export declare type InferCreateDataSingle<S> = S extends {
5
+ create: (data: infer D, params: any) => any;
6
+ } ? D extends Array<infer T> ? T : D : never;
7
+ export declare type InferUpdateData<S> = S extends {
8
+ update: (id: any, data: infer D, params: any) => any;
9
+ } ? D : never;
10
+ export declare type InferPatchData<S> = S extends {
11
+ patch: (id: any, data: infer D, params: any) => any;
12
+ } ? D : never;
13
+ export declare type InferGetResult<S> = S extends {
14
+ get: (id: any, params: any) => infer R;
15
+ } ? Awaited<R> : never;
16
+ export declare type InferFindResult<S> = S extends {
17
+ find: (params: any) => infer R;
18
+ } ? Awaited<R> : never;
19
+ export declare type InferCreateResult<S, D = any> = S extends {
20
+ create: (data: D, params: any) => infer R;
21
+ } ? Awaited<R> : never;
22
+ export declare type InferCreateResultSingle<S> = S extends {
23
+ create: (data: any, params: any) => infer R;
24
+ } ? Awaited<R> extends Array<infer T> ? T : Awaited<R> : never;
25
+ export declare type InferUpdateResult<S> = S extends {
26
+ update: (id: any, data: any, params: any) => infer R;
27
+ } ? Awaited<R> : never;
28
+ export declare type InferPatchResult<S, Id = any> = S extends {
29
+ patch: (id: Id, data: any, params: any) => infer R;
30
+ } ? Awaited<R> : never;
31
+ export declare type InferRemoveResult<S, Id = any> = S extends {
32
+ remove: (id: Id, params: any) => infer R;
33
+ } ? Awaited<R> : never;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,6 @@
1
1
  import type { HookContext } from "@feathersjs/feathers";
2
- import type { GetItemsIsArrayOptions } from "..";
3
- export declare const getItemsIsArray: <T = any>(context: HookContext) => GetItemsIsArrayOptions<T>;
2
+ import type { GetItemsIsArrayResult } from "..";
3
+ export declare type GetItemsIsArrayOptions = {
4
+ from: "data" | "result" | "automatic";
5
+ };
6
+ export declare const getItemsIsArray: <T = any>(context: HookContext, options?: GetItemsIsArrayOptions) => GetItemsIsArrayResult<T>;
@@ -1,11 +1,21 @@
1
1
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2
- export const getItemsIsArray = (context) => {
3
- let itemOrItems = context.type === "before"
4
- ? context.data
5
- : context.result;
6
- itemOrItems = itemOrItems && context.method === "find"
7
- ? (itemOrItems.data || itemOrItems)
8
- : itemOrItems;
2
+ export const getItemsIsArray = (context, options) => {
3
+ const { from = "automatic" } = options || {};
4
+ let itemOrItems;
5
+ if (from === "automatic") {
6
+ itemOrItems = context.type === "before"
7
+ ? context.data
8
+ : context.result;
9
+ itemOrItems = itemOrItems && context.method === "find"
10
+ ? (itemOrItems.data || itemOrItems)
11
+ : itemOrItems;
12
+ }
13
+ else if (from === "data") {
14
+ itemOrItems = context.data;
15
+ }
16
+ else if (from === "result") {
17
+ itemOrItems = context.result;
18
+ }
9
19
  const isArray = Array.isArray(itemOrItems);
10
20
  return {
11
21
  items: (isArray)
@@ -0,0 +1,8 @@
1
+ import type { ReturnAsyncHook, Promisable } from "../types";
2
+ import type { HookContext } from "@feathersjs/feathers";
3
+ import type { GetItemsIsArrayOptions } from "../utils/getItemsIsArray";
4
+ export interface HookForEachOptions {
5
+ wait?: "sequential" | "parallel" | false;
6
+ items?: GetItemsIsArrayOptions["from"];
7
+ }
8
+ export declare const forEach: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookForEachOptions) => ReturnAsyncHook;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.forEach = void 0;
13
+ const shouldSkip_1 = require("../utils/shouldSkip");
14
+ const getItemsIsArray_1 = require("../utils/getItemsIsArray");
15
+ const forEach = (
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ actionPerItem, _options) => {
18
+ const options = Object.assign({ wait: "parallel", items: "automatic" }, _options);
19
+ return (context) => __awaiter(void 0, void 0, void 0, function* () {
20
+ if ((0, shouldSkip_1.shouldSkip)("runForItems", context)) {
21
+ return context;
22
+ }
23
+ const { items } = (0, getItemsIsArray_1.getItemsIsArray)(context, { from: options.items });
24
+ const promises = [];
25
+ for (const item of items) {
26
+ const promise = actionPerItem(item, context);
27
+ if (options.wait === "sequential") {
28
+ yield promise;
29
+ }
30
+ else {
31
+ promises.push(promise);
32
+ }
33
+ }
34
+ if (options.wait === "parallel") {
35
+ yield Promise.all(promises);
36
+ }
37
+ return context;
38
+ });
39
+ };
40
+ exports.forEach = forEach;
@@ -0,0 +1,8 @@
1
+ import type { HookContext } from "@feathersjs/feathers";
2
+ /**
3
+ * Parse fields to date or number
4
+ * skips undefined fields
5
+ */
6
+ export declare const parseFields: (type: "date" | "number", options: {
7
+ fields: string[];
8
+ }) => (context: HookContext) => HookContext<any, import("@feathersjs/feathers").Service<any>>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFields = void 0;
4
+ const getItemsIsArray_1 = require("../utils/getItemsIsArray");
5
+ /**
6
+ * Parse fields to date or number
7
+ * skips undefined fields
8
+ */
9
+ const parseFields = (type, options) => (context) => {
10
+ const { items } = (0, getItemsIsArray_1.getItemsIsArray)(context);
11
+ items.forEach(item => {
12
+ options.fields.forEach(field => {
13
+ // ignore undefined fields
14
+ if (!(field in item)) {
15
+ return;
16
+ }
17
+ if (type === "date") {
18
+ item[field] = new Date(item[field]);
19
+ }
20
+ else if (type === "number") {
21
+ item[field] = Number(item[field]);
22
+ }
23
+ });
24
+ });
25
+ return context;
26
+ };
27
+ exports.parseFields = parseFields;
package/dist/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export { createRelated } from "./hooks/createRelated";
11
11
  export { setData };
12
12
  export { removeRelated } from "./hooks/removeRelated";
13
13
  export { runPerItem };
14
+ export * from "./hooks/forEach";
15
+ export * from "./hooks/parseFields";
14
16
  import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
15
17
  export declare const mixins: {
16
18
  debounceMixin: typeof debounceMixin;
@@ -32,3 +34,4 @@ export { getItemsIsArray } from "./utils/getItemsIsArray";
32
34
  export { onDelete } from "./hooks/onDelete";
33
35
  export { shouldSkip } from "./utils/shouldSkip";
34
36
  export * from "./types";
37
+ export * from "./utility-types/utility-types";
package/dist/index.js CHANGED
@@ -25,18 +25,20 @@ Object.defineProperty(exports, "runPerItem", { enumerable: true, get: function (
25
25
  exports.hooks = {
26
26
  checkMulti: checkMulti_1.checkMulti,
27
27
  setData: setData_1.setData,
28
- runPerItem: runPerItem_1.runPerItem
28
+ runPerItem: runPerItem_1.runPerItem,
29
29
  };
30
30
  var createRelated_1 = require("./hooks/createRelated");
31
31
  Object.defineProperty(exports, "createRelated", { enumerable: true, get: function () { return createRelated_1.createRelated; } });
32
32
  var removeRelated_1 = require("./hooks/removeRelated");
33
33
  Object.defineProperty(exports, "removeRelated", { enumerable: true, get: function () { return removeRelated_1.removeRelated; } });
34
+ __exportStar(require("./hooks/forEach"), exports);
35
+ __exportStar(require("./hooks/parseFields"), exports);
34
36
  const debounce_mixin_1 = require("./mixins/debounce-mixin");
35
37
  Object.defineProperty(exports, "debounceMixin", { enumerable: true, get: function () { return debounce_mixin_1.debounceMixin; } });
36
38
  Object.defineProperty(exports, "DebouncedStore", { enumerable: true, get: function () { return debounce_mixin_1.DebouncedStore; } });
37
39
  exports.mixins = {
38
40
  debounceMixin: debounce_mixin_1.debounceMixin,
39
- DebouncedStore: debounce_mixin_1.DebouncedStore
41
+ DebouncedStore: debounce_mixin_1.DebouncedStore,
40
42
  };
41
43
  var addHook_1 = require("./utils/addHook");
42
44
  Object.defineProperty(exports, "addHook", { enumerable: true, get: function () { return addHook_1.addHook; } });
@@ -65,3 +67,4 @@ Object.defineProperty(exports, "onDelete", { enumerable: true, get: function ()
65
67
  var shouldSkip_1 = require("./utils/shouldSkip");
66
68
  Object.defineProperty(exports, "shouldSkip", { enumerable: true, get: function () { return shouldSkip_1.shouldSkip; } });
67
69
  __exportStar(require("./types"), exports);
70
+ __exportStar(require("./utility-types/utility-types"), exports);
package/dist/types.d.ts CHANGED
@@ -82,7 +82,7 @@ export interface FilterQueryResult {
82
82
  paginate?: unknown;
83
83
  [key: string]: unknown;
84
84
  }
85
- export interface GetItemsIsArrayOptions<T = any> {
85
+ export interface GetItemsIsArrayResult<T = any> {
86
86
  items: T[];
87
87
  isArray: boolean;
88
88
  }
@@ -0,0 +1,33 @@
1
+ export declare type InferCreateData<S> = S extends {
2
+ create: (data: infer D, params: any) => any;
3
+ } ? D : never;
4
+ export declare type InferCreateDataSingle<S> = S extends {
5
+ create: (data: infer D, params: any) => any;
6
+ } ? D extends Array<infer T> ? T : D : never;
7
+ export declare type InferUpdateData<S> = S extends {
8
+ update: (id: any, data: infer D, params: any) => any;
9
+ } ? D : never;
10
+ export declare type InferPatchData<S> = S extends {
11
+ patch: (id: any, data: infer D, params: any) => any;
12
+ } ? D : never;
13
+ export declare type InferGetResult<S> = S extends {
14
+ get: (id: any, params: any) => infer R;
15
+ } ? Awaited<R> : never;
16
+ export declare type InferFindResult<S> = S extends {
17
+ find: (params: any) => infer R;
18
+ } ? Awaited<R> : never;
19
+ export declare type InferCreateResult<S, D = any> = S extends {
20
+ create: (data: D, params: any) => infer R;
21
+ } ? Awaited<R> : never;
22
+ export declare type InferCreateResultSingle<S> = S extends {
23
+ create: (data: any, params: any) => infer R;
24
+ } ? Awaited<R> extends Array<infer T> ? T : Awaited<R> : never;
25
+ export declare type InferUpdateResult<S> = S extends {
26
+ update: (id: any, data: any, params: any) => infer R;
27
+ } ? Awaited<R> : never;
28
+ export declare type InferPatchResult<S, Id = any> = S extends {
29
+ patch: (id: Id, data: any, params: any) => infer R;
30
+ } ? Awaited<R> : never;
31
+ export declare type InferRemoveResult<S, Id = any> = S extends {
32
+ remove: (id: Id, params: any) => infer R;
33
+ } ? Awaited<R> : never;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,6 @@
1
1
  import type { HookContext } from "@feathersjs/feathers";
2
- import type { GetItemsIsArrayOptions } from "..";
3
- export declare const getItemsIsArray: <T = any>(context: HookContext) => GetItemsIsArrayOptions<T>;
2
+ import type { GetItemsIsArrayResult } from "..";
3
+ export declare type GetItemsIsArrayOptions = {
4
+ from: "data" | "result" | "automatic";
5
+ };
6
+ export declare const getItemsIsArray: <T = any>(context: HookContext, options?: GetItemsIsArrayOptions) => GetItemsIsArrayResult<T>;
@@ -2,13 +2,23 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getItemsIsArray = void 0;
4
4
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
- const getItemsIsArray = (context) => {
6
- let itemOrItems = context.type === "before"
7
- ? context.data
8
- : context.result;
9
- itemOrItems = itemOrItems && context.method === "find"
10
- ? (itemOrItems.data || itemOrItems)
11
- : itemOrItems;
5
+ const getItemsIsArray = (context, options) => {
6
+ const { from = "automatic" } = options || {};
7
+ let itemOrItems;
8
+ if (from === "automatic") {
9
+ itemOrItems = context.type === "before"
10
+ ? context.data
11
+ : context.result;
12
+ itemOrItems = itemOrItems && context.method === "find"
13
+ ? (itemOrItems.data || itemOrItems)
14
+ : itemOrItems;
15
+ }
16
+ else if (from === "data") {
17
+ itemOrItems = context.data;
18
+ }
19
+ else if (from === "result") {
20
+ itemOrItems = context.result;
21
+ }
12
22
  const isArray = Array.isArray(itemOrItems);
13
23
  return {
14
24
  items: (isArray)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feathers-utils",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "description": "Some utils for projects using '@feathersjs/feathers'",
5
5
  "author": "fratzinger",
6
6
  "repository": {
@@ -0,0 +1,47 @@
1
+ import { shouldSkip } from "../utils/shouldSkip";
2
+
3
+ import type { ReturnAsyncHook, Promisable } from "../types";
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
+ };
@@ -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
@@ -7,7 +7,7 @@ import { runPerItem } from "./hooks/runPerItem";
7
7
  export const hooks = {
8
8
  checkMulti,
9
9
  setData,
10
- runPerItem
10
+ runPerItem,
11
11
  };
12
12
 
13
13
  export { checkMulti };
@@ -15,12 +15,14 @@ export { createRelated } from "./hooks/createRelated";
15
15
  export { setData };
16
16
  export { removeRelated } from "./hooks/removeRelated";
17
17
  export { runPerItem };
18
+ export * from "./hooks/forEach";
19
+ export * from "./hooks/parseFields";
18
20
 
19
21
  import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
20
22
 
21
23
  export const mixins = {
22
24
  debounceMixin,
23
- DebouncedStore
25
+ DebouncedStore,
24
26
  };
25
27
 
26
28
  export { debounceMixin };
@@ -41,5 +43,5 @@ export { getItemsIsArray } from "./utils/getItemsIsArray";
41
43
  export { onDelete } from "./hooks/onDelete";
42
44
  export { shouldSkip } from "./utils/shouldSkip";
43
45
 
44
-
45
- export * from "./types";
46
+ export * from "./types";
47
+ export * from "./utility-types/utility-types";
package/src/types.ts CHANGED
@@ -120,7 +120,7 @@ export interface FilterQueryResult {
120
120
  }
121
121
 
122
122
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
123
- export interface GetItemsIsArrayOptions<T = any> {
123
+ export interface GetItemsIsArrayResult<T = any> {
124
124
  items: T[]
125
125
  isArray: boolean
126
126
  }
@@ -0,0 +1,69 @@
1
+ export type InferCreateData<S> = S extends {
2
+ create: (data: infer D, params: any) => any;
3
+ }
4
+ ? D
5
+ : never;
6
+
7
+ export type InferCreateDataSingle<S> = S extends {
8
+ create: (data: infer D, params: any) => any;
9
+ }
10
+ ? D extends Array<infer T>
11
+ ? T
12
+ : D
13
+ : never;
14
+
15
+ export type InferUpdateData<S> = S extends {
16
+ update: (id: any, data: infer D, params: any) => any;
17
+ }
18
+ ? D
19
+ : never;
20
+
21
+ export type InferPatchData<S> = S extends {
22
+ patch: (id: any, data: infer D, params: any) => any;
23
+ }
24
+ ? D
25
+ : never;
26
+
27
+ export type InferGetResult<S> = S extends {
28
+ get: (id: any, params: any) => infer R;
29
+ }
30
+ ? Awaited<R>
31
+ : never;
32
+
33
+ export type InferFindResult<S> = S extends {
34
+ find: (params: any) => infer R;
35
+ }
36
+ ? Awaited<R>
37
+ : never;
38
+
39
+ export type InferCreateResult<S, D = any> = S extends {
40
+ create: (data: D, params: any) => infer R;
41
+ }
42
+ ? Awaited<R>
43
+ : never;
44
+
45
+ export type InferCreateResultSingle<S> = S extends {
46
+ create: (data: any, params: any) => infer R;
47
+ }
48
+ ? Awaited<R> extends Array<infer T>
49
+ ? T
50
+ : Awaited<R>
51
+ : never;
52
+
53
+ export type InferUpdateResult<S> = S extends {
54
+ update: (id: any, data: any, params: any) => infer R;
55
+ }
56
+ ? Awaited<R>
57
+ : never;
58
+
59
+ export type InferPatchResult<S, Id = any> = S extends {
60
+ patch: (id: Id, data: any, params: any) => infer R;
61
+ }
62
+ ? Awaited<R>
63
+ : never;
64
+
65
+ export type InferRemoveResult<S, Id = any> = S extends {
66
+ remove: (id: Id, params: any) => infer R;
67
+ }
68
+ ? Awaited<R>
69
+ : never;
@@ -1,16 +1,34 @@
1
1
  import type { HookContext } from "@feathersjs/feathers";
2
- import type { GetItemsIsArrayOptions } from "..";
2
+ import type { GetItemsIsArrayResult } from "..";
3
+
4
+ export type GetItemsIsArrayOptions = {
5
+ from: "data" | "result" | "automatic"
6
+ }
3
7
 
4
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
9
  export const getItemsIsArray = <T = any>(
6
- context: HookContext
7
- ): GetItemsIsArrayOptions<T> => {
8
- let itemOrItems = context.type === "before"
9
- ? context.data
10
- : context.result;
11
- itemOrItems = itemOrItems && context.method === "find"
12
- ? (itemOrItems.data || itemOrItems)
13
- : itemOrItems;
10
+ context: HookContext,
11
+ options?: GetItemsIsArrayOptions
12
+ ): GetItemsIsArrayResult<T> => {
13
+ const {
14
+ from = "automatic"
15
+ } = options || {};
16
+
17
+ let itemOrItems;
18
+
19
+ if (from === "automatic") {
20
+ itemOrItems = context.type === "before"
21
+ ? context.data
22
+ : context.result;
23
+ itemOrItems = itemOrItems && context.method === "find"
24
+ ? (itemOrItems.data || itemOrItems)
25
+ : itemOrItems;
26
+ } else if (from === "data") {
27
+ itemOrItems = context.data;
28
+ } else if (from === "result") {
29
+ itemOrItems = context.result;
30
+ }
31
+
14
32
  const isArray = Array.isArray(itemOrItems);
15
33
  return {
16
34
  items: (isArray)