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 +1 -0
- package/dist/esm/hooks/forEach.d.ts +8 -0
- package/dist/esm/hooks/forEach.js +31 -0
- package/dist/esm/hooks/parseFields.d.ts +8 -0
- package/dist/esm/hooks/parseFields.js +23 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +5 -2
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/utility-types/utility-types.d.ts +33 -0
- package/dist/esm/utility-types/utility-types.js +1 -0
- package/dist/esm/utils/getItemsIsArray.d.ts +5 -2
- package/dist/esm/utils/getItemsIsArray.js +17 -7
- package/dist/hooks/forEach.d.ts +8 -0
- package/dist/hooks/forEach.js +40 -0
- package/dist/hooks/parseFields.d.ts +8 -0
- package/dist/hooks/parseFields.js +27 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +5 -2
- package/dist/types.d.ts +1 -1
- package/dist/utility-types/utility-types.d.ts +33 -0
- package/dist/utility-types/utility-types.js +2 -0
- package/dist/utils/getItemsIsArray.d.ts +5 -2
- package/dist/utils/getItemsIsArray.js +17 -7
- package/package.json +1 -1
- package/src/hooks/forEach.ts +47 -0
- package/src/hooks/parseFields.ts +27 -0
- package/src/index.ts +6 -4
- package/src/types.ts +1 -1
- package/src/utility-types/utility-types.ts +69 -0
- package/src/utils/getItemsIsArray.ts +27 -9
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
|
+
};
|
package/dist/esm/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/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";
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -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 {
|
|
3
|
-
export declare
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
@@ -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;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
-
import type {
|
|
3
|
-
export declare
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
@@ -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
|
|
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 {
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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)
|