feathers-utils 1.10.0 → 1.12.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/onDelete.d.ts +3 -0
- package/dist/esm/hooks/onDelete.js +39 -0
- package/dist/esm/hooks/runPerItem.d.ts +1 -1
- package/dist/esm/hooks/setData.js +3 -3
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +4 -2
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.d.ts +1 -1
- package/dist/esm/mixins/debounce-mixin/DebouncedStore.js +1 -1
- package/dist/esm/types.d.ts +7 -0
- 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/mergeQuery/index.js +7 -7
- package/dist/esm/utils/pushSet.d.ts +1 -1
- package/dist/esm/utils/pushSet.js +3 -3
- package/dist/hooks/onDelete.d.ts +3 -0
- package/dist/hooks/onDelete.js +52 -0
- package/dist/hooks/runPerItem.d.ts +1 -1
- package/dist/hooks/setData.js +8 -8
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -3
- package/dist/mixins/debounce-mixin/DebouncedStore.d.ts +1 -1
- package/dist/mixins/debounce-mixin/DebouncedStore.js +2 -2
- package/dist/types.d.ts +7 -0
- package/dist/utility-types/utility-types.d.ts +33 -0
- package/dist/utility-types/utility-types.js +2 -0
- package/dist/utils/mergeQuery/index.js +42 -42
- package/dist/utils/pushSet.d.ts +1 -1
- package/dist/utils/pushSet.js +6 -6
- package/package.json +18 -18
- package/src/hooks/onDelete.ts +55 -0
- package/src/hooks/setData.ts +3 -3
- package/src/index.ts +5 -4
- package/src/mixins/debounce-mixin/DebouncedStore.ts +1 -1
- package/src/types.ts +9 -0
- package/src/utility-types/utility-types.ts +69 -0
- package/src/utils/mergeQuery/index.ts +7 -7
- package/src/utils/pushSet.ts +3 -3
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,3 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import type { OnDeleteOptions } from "../types";
|
|
3
|
+
export declare function onDelete<S = Record<string, any>>(service: keyof S, { keyThere, keyHere, onDelete, blocking }: OnDeleteOptions): (context: HookContext) => Promise<HookContext>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { checkContext } from "feathers-hooks-common";
|
|
2
|
+
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
3
|
+
export function onDelete(service, { keyThere, keyHere = "id", onDelete = "cascade", blocking = true }) {
|
|
4
|
+
if (!service || !keyThere) {
|
|
5
|
+
throw "initialize hook 'removeRelated' completely!";
|
|
6
|
+
}
|
|
7
|
+
if (!["cascade", "set null"].includes(onDelete)) {
|
|
8
|
+
throw "onDelete must be 'cascade' or 'set null'";
|
|
9
|
+
}
|
|
10
|
+
return async (context) => {
|
|
11
|
+
checkContext(context, "after", "remove", "onDelete");
|
|
12
|
+
const { items } = getItemsIsArray(context);
|
|
13
|
+
let ids = items.map(x => x[keyHere]).filter(x => !!x);
|
|
14
|
+
ids = [...new Set(ids)];
|
|
15
|
+
if (!ids || ids.length <= 0) {
|
|
16
|
+
return context;
|
|
17
|
+
}
|
|
18
|
+
const params = {
|
|
19
|
+
query: {
|
|
20
|
+
[keyThere]: {
|
|
21
|
+
$in: ids
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
paginate: false
|
|
25
|
+
};
|
|
26
|
+
let promise;
|
|
27
|
+
if (onDelete === "cascade") {
|
|
28
|
+
promise = context.app.service(service).remove(null, params);
|
|
29
|
+
}
|
|
30
|
+
else if (onDelete === "set null") {
|
|
31
|
+
const data = { [keyThere]: null };
|
|
32
|
+
promise = context.app.service(service).patch(null, data, params);
|
|
33
|
+
}
|
|
34
|
+
if (blocking) {
|
|
35
|
+
await promise;
|
|
36
|
+
}
|
|
37
|
+
return context;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { HookRunPerItemOptions, ReturnAsyncHook, Promisable } from "../types";
|
|
2
2
|
import type { HookContext } from "@feathersjs/feathers";
|
|
3
|
-
export declare const runPerItem: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookRunPerItemOptions
|
|
3
|
+
export declare const runPerItem: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookRunPerItemOptions) => ReturnAsyncHook;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import _get from "lodash/get";
|
|
2
|
-
import _set from "lodash/set";
|
|
3
|
-
import _has from "lodash/has";
|
|
1
|
+
import _get from "lodash/get.js";
|
|
2
|
+
import _set from "lodash/set.js";
|
|
3
|
+
import _has from "lodash/has.js";
|
|
4
4
|
import { Forbidden } from "@feathersjs/errors";
|
|
5
5
|
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
6
6
|
const defaultOptions = {
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -29,5 +29,7 @@ export { setResultEmpty } from "./utils/setResultEmpty";
|
|
|
29
29
|
export { markHookForSkip } from "./utils/markHookForSkip";
|
|
30
30
|
export { filterQuery } from "./utils/filterQuery";
|
|
31
31
|
export { getItemsIsArray } from "./utils/getItemsIsArray";
|
|
32
|
+
export { onDelete } from "./hooks/onDelete";
|
|
32
33
|
export { shouldSkip } from "./utils/shouldSkip";
|
|
33
34
|
export * from "./types";
|
|
35
|
+
export * from "./utility-types/utility-types";
|
package/dist/esm/index.js
CHANGED
|
@@ -5,7 +5,7 @@ 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";
|
|
@@ -15,7 +15,7 @@ export { runPerItem };
|
|
|
15
15
|
import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
|
|
16
16
|
export const mixins = {
|
|
17
17
|
debounceMixin,
|
|
18
|
-
DebouncedStore
|
|
18
|
+
DebouncedStore,
|
|
19
19
|
};
|
|
20
20
|
export { debounceMixin };
|
|
21
21
|
export { DebouncedStore };
|
|
@@ -30,5 +30,7 @@ export { setResultEmpty } from "./utils/setResultEmpty";
|
|
|
30
30
|
export { markHookForSkip } from "./utils/markHookForSkip";
|
|
31
31
|
export { filterQuery } from "./utils/filterQuery";
|
|
32
32
|
export { getItemsIsArray } from "./utils/getItemsIsArray";
|
|
33
|
+
export { onDelete } from "./hooks/onDelete";
|
|
33
34
|
export { shouldSkip } from "./utils/shouldSkip";
|
|
34
35
|
export * from "./types";
|
|
36
|
+
export * from "./utility-types/utility-types";
|
|
@@ -7,7 +7,7 @@ export declare class DebouncedStore {
|
|
|
7
7
|
private _options;
|
|
8
8
|
private _isRunningById;
|
|
9
9
|
_queueById: Record<string, DebouncedFunc<((id: Id, action: DebouncedFunctionApp) => void | Promise<void>)>>;
|
|
10
|
-
add: (id: Id, action: (app?: Application
|
|
10
|
+
add: (id: Id, action: (app?: Application) => void | Promise<void>) => void | Promise<void> | undefined;
|
|
11
11
|
constructor(app: Application, options?: Partial<DebouncedStoreOptions>);
|
|
12
12
|
private unbounced;
|
|
13
13
|
private debounceById;
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -36,6 +36,13 @@ export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
36
36
|
data: (item: any, context: HookContext) => Promisable<Record<string, any>>;
|
|
37
37
|
createItemsInDataArraySeparately?: boolean;
|
|
38
38
|
}
|
|
39
|
+
export declare type OnDeleteAction = "cascade" | "set null";
|
|
40
|
+
export interface OnDeleteOptions {
|
|
41
|
+
keyThere: string;
|
|
42
|
+
keyHere: string;
|
|
43
|
+
onDelete: OnDeleteAction;
|
|
44
|
+
blocking?: boolean;
|
|
45
|
+
}
|
|
39
46
|
export interface InitDebounceMixinOptions {
|
|
40
47
|
default: Partial<DebouncedStoreOptions>;
|
|
41
48
|
blacklist: string[];
|
|
@@ -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,10 +1,10 @@
|
|
|
1
|
-
import _get from "lodash/get";
|
|
2
|
-
import _has from "lodash/has";
|
|
3
|
-
import _isEmpty from "lodash/isEmpty";
|
|
4
|
-
import _isEqual from "lodash/isEqual";
|
|
5
|
-
import _merge from "lodash/merge";
|
|
6
|
-
import _set from "lodash/set";
|
|
7
|
-
import _uniqWith from "lodash/uniqWith";
|
|
1
|
+
import _get from "lodash/get.js";
|
|
2
|
+
import _has from "lodash/has.js";
|
|
3
|
+
import _isEmpty from "lodash/isEmpty.js";
|
|
4
|
+
import _isEqual from "lodash/isEqual.js";
|
|
5
|
+
import _merge from "lodash/merge.js";
|
|
6
|
+
import _set from "lodash/set.js";
|
|
7
|
+
import _uniqWith from "lodash/uniqWith.js";
|
|
8
8
|
import { mergeArrays } from "./mergeArrays";
|
|
9
9
|
import { filterQuery } from "../filterQuery";
|
|
10
10
|
import { Forbidden } from "@feathersjs/errors";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Path, PushSetOptions } from "../types";
|
|
2
|
-
export declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val: unknown, options?: PushSetOptions
|
|
2
|
+
export declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val: unknown, options?: PushSetOptions) => unknown[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import _isEqual from "lodash/isEqual";
|
|
2
|
-
import _get from "lodash/get";
|
|
3
|
-
import _set from "lodash/set";
|
|
1
|
+
import _isEqual from "lodash/isEqual.js";
|
|
2
|
+
import _get from "lodash/get.js";
|
|
3
|
+
import _set from "lodash/set.js";
|
|
4
4
|
export const pushSet = (obj, path, val, options) => {
|
|
5
5
|
options = options || {};
|
|
6
6
|
let arr = _get(obj, path);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import type { OnDeleteOptions } from "../types";
|
|
3
|
+
export declare function onDelete<S = Record<string, any>>(service: keyof S, { keyThere, keyHere, onDelete, blocking }: OnDeleteOptions): (context: HookContext) => Promise<HookContext>;
|
|
@@ -0,0 +1,52 @@
|
|
|
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.onDelete = void 0;
|
|
13
|
+
const feathers_hooks_common_1 = require("feathers-hooks-common");
|
|
14
|
+
const getItemsIsArray_1 = require("../utils/getItemsIsArray");
|
|
15
|
+
function onDelete(service, { keyThere, keyHere = "id", onDelete = "cascade", blocking = true }) {
|
|
16
|
+
if (!service || !keyThere) {
|
|
17
|
+
throw "initialize hook 'removeRelated' completely!";
|
|
18
|
+
}
|
|
19
|
+
if (!["cascade", "set null"].includes(onDelete)) {
|
|
20
|
+
throw "onDelete must be 'cascade' or 'set null'";
|
|
21
|
+
}
|
|
22
|
+
return (context) => __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
(0, feathers_hooks_common_1.checkContext)(context, "after", "remove", "onDelete");
|
|
24
|
+
const { items } = (0, getItemsIsArray_1.getItemsIsArray)(context);
|
|
25
|
+
let ids = items.map(x => x[keyHere]).filter(x => !!x);
|
|
26
|
+
ids = [...new Set(ids)];
|
|
27
|
+
if (!ids || ids.length <= 0) {
|
|
28
|
+
return context;
|
|
29
|
+
}
|
|
30
|
+
const params = {
|
|
31
|
+
query: {
|
|
32
|
+
[keyThere]: {
|
|
33
|
+
$in: ids
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
paginate: false
|
|
37
|
+
};
|
|
38
|
+
let promise;
|
|
39
|
+
if (onDelete === "cascade") {
|
|
40
|
+
promise = context.app.service(service).remove(null, params);
|
|
41
|
+
}
|
|
42
|
+
else if (onDelete === "set null") {
|
|
43
|
+
const data = { [keyThere]: null };
|
|
44
|
+
promise = context.app.service(service).patch(null, data, params);
|
|
45
|
+
}
|
|
46
|
+
if (blocking) {
|
|
47
|
+
yield promise;
|
|
48
|
+
}
|
|
49
|
+
return context;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
exports.onDelete = onDelete;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { HookRunPerItemOptions, ReturnAsyncHook, Promisable } from "../types";
|
|
2
2
|
import type { HookContext } from "@feathersjs/feathers";
|
|
3
|
-
export declare const runPerItem: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookRunPerItemOptions
|
|
3
|
+
export declare const runPerItem: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookRunPerItemOptions) => ReturnAsyncHook;
|
package/dist/hooks/setData.js
CHANGED
|
@@ -4,9 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.setData = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
7
|
+
const get_js_1 = __importDefault(require("lodash/get.js"));
|
|
8
|
+
const set_js_1 = __importDefault(require("lodash/set.js"));
|
|
9
|
+
const has_js_1 = __importDefault(require("lodash/has.js"));
|
|
10
10
|
const errors_1 = require("@feathersjs/errors");
|
|
11
11
|
const getItemsIsArray_1 = require("../utils/getItemsIsArray");
|
|
12
12
|
const defaultOptions = {
|
|
@@ -18,16 +18,16 @@ function setData(from, to, _options) {
|
|
|
18
18
|
return (context) => {
|
|
19
19
|
var _a;
|
|
20
20
|
const { items } = (0, getItemsIsArray_1.getItemsIsArray)(context);
|
|
21
|
-
if (!(0,
|
|
21
|
+
if (!(0, has_js_1.default)(context, from)) {
|
|
22
22
|
if (!((_a = context.params) === null || _a === void 0 ? void 0 : _a.provider) || options.allowUndefined === true) {
|
|
23
23
|
return context;
|
|
24
24
|
}
|
|
25
|
-
if (!options.overwrite && items.every((item) => (0,
|
|
25
|
+
if (!options.overwrite && items.every((item) => (0, has_js_1.default)(item, to))) {
|
|
26
26
|
return context;
|
|
27
27
|
}
|
|
28
28
|
throw new errors_1.Forbidden(`Expected field ${from.toString()} not available`);
|
|
29
29
|
}
|
|
30
|
-
const val = (0,
|
|
30
|
+
const val = (0, get_js_1.default)(context, from);
|
|
31
31
|
items.forEach((item) => {
|
|
32
32
|
let overwrite;
|
|
33
33
|
if (typeof options.overwrite === "function") {
|
|
@@ -36,10 +36,10 @@ function setData(from, to, _options) {
|
|
|
36
36
|
else {
|
|
37
37
|
overwrite = options.overwrite;
|
|
38
38
|
}
|
|
39
|
-
if (!overwrite && (0,
|
|
39
|
+
if (!overwrite && (0, has_js_1.default)(item, to)) {
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
(0,
|
|
42
|
+
(0, set_js_1.default)(item, to, val);
|
|
43
43
|
});
|
|
44
44
|
return context;
|
|
45
45
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -29,5 +29,7 @@ export { setResultEmpty } from "./utils/setResultEmpty";
|
|
|
29
29
|
export { markHookForSkip } from "./utils/markHookForSkip";
|
|
30
30
|
export { filterQuery } from "./utils/filterQuery";
|
|
31
31
|
export { getItemsIsArray } from "./utils/getItemsIsArray";
|
|
32
|
+
export { onDelete } from "./hooks/onDelete";
|
|
32
33
|
export { shouldSkip } from "./utils/shouldSkip";
|
|
33
34
|
export * from "./types";
|
|
35
|
+
export * from "./utility-types/utility-types";
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.shouldSkip = exports.getItemsIsArray = exports.filterQuery = exports.markHookForSkip = exports.setResultEmpty = exports.pushSet = exports.mergeArrays = exports.mergeQuery = exports.isPaginated = exports.isMulti = exports.getPaginate = exports.addHook = exports.DebouncedStore = exports.debounceMixin = exports.mixins = exports.runPerItem = exports.removeRelated = exports.setData = exports.createRelated = exports.checkMulti = exports.hooks = void 0;
|
|
17
|
+
exports.shouldSkip = exports.onDelete = exports.getItemsIsArray = exports.filterQuery = exports.markHookForSkip = exports.setResultEmpty = exports.pushSet = exports.mergeArrays = exports.mergeQuery = exports.isPaginated = exports.isMulti = exports.getPaginate = exports.addHook = exports.DebouncedStore = exports.debounceMixin = exports.mixins = exports.runPerItem = exports.removeRelated = exports.setData = exports.createRelated = exports.checkMulti = exports.hooks = void 0;
|
|
18
18
|
// hooks
|
|
19
19
|
const checkMulti_1 = require("./hooks/checkMulti");
|
|
20
20
|
Object.defineProperty(exports, "checkMulti", { enumerable: true, get: function () { return checkMulti_1.checkMulti; } });
|
|
@@ -25,7 +25,7 @@ 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; } });
|
|
@@ -36,7 +36,7 @@ Object.defineProperty(exports, "debounceMixin", { enumerable: true, get: functio
|
|
|
36
36
|
Object.defineProperty(exports, "DebouncedStore", { enumerable: true, get: function () { return debounce_mixin_1.DebouncedStore; } });
|
|
37
37
|
exports.mixins = {
|
|
38
38
|
debounceMixin: debounce_mixin_1.debounceMixin,
|
|
39
|
-
DebouncedStore: debounce_mixin_1.DebouncedStore
|
|
39
|
+
DebouncedStore: debounce_mixin_1.DebouncedStore,
|
|
40
40
|
};
|
|
41
41
|
var addHook_1 = require("./utils/addHook");
|
|
42
42
|
Object.defineProperty(exports, "addHook", { enumerable: true, get: function () { return addHook_1.addHook; } });
|
|
@@ -60,6 +60,9 @@ var filterQuery_1 = require("./utils/filterQuery");
|
|
|
60
60
|
Object.defineProperty(exports, "filterQuery", { enumerable: true, get: function () { return filterQuery_1.filterQuery; } });
|
|
61
61
|
var getItemsIsArray_1 = require("./utils/getItemsIsArray");
|
|
62
62
|
Object.defineProperty(exports, "getItemsIsArray", { enumerable: true, get: function () { return getItemsIsArray_1.getItemsIsArray; } });
|
|
63
|
+
var onDelete_1 = require("./hooks/onDelete");
|
|
64
|
+
Object.defineProperty(exports, "onDelete", { enumerable: true, get: function () { return onDelete_1.onDelete; } });
|
|
63
65
|
var shouldSkip_1 = require("./utils/shouldSkip");
|
|
64
66
|
Object.defineProperty(exports, "shouldSkip", { enumerable: true, get: function () { return shouldSkip_1.shouldSkip; } });
|
|
65
67
|
__exportStar(require("./types"), exports);
|
|
68
|
+
__exportStar(require("./utility-types/utility-types"), exports);
|
|
@@ -7,7 +7,7 @@ export declare class DebouncedStore {
|
|
|
7
7
|
private _options;
|
|
8
8
|
private _isRunningById;
|
|
9
9
|
_queueById: Record<string, DebouncedFunc<((id: Id, action: DebouncedFunctionApp) => void | Promise<void>)>>;
|
|
10
|
-
add: (id: Id, action: (app?: Application
|
|
10
|
+
add: (id: Id, action: (app?: Application) => void | Promise<void>) => void | Promise<void> | undefined;
|
|
11
11
|
constructor(app: Application, options?: Partial<DebouncedStoreOptions>);
|
|
12
12
|
private unbounced;
|
|
13
13
|
private debounceById;
|
|
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.DebouncedStore = exports.makeDefaultOptions = void 0;
|
|
16
|
-
const
|
|
16
|
+
const debounce_js_1 = __importDefault(require("lodash/debounce.js"));
|
|
17
17
|
const makeDefaultOptions = () => {
|
|
18
18
|
return {
|
|
19
19
|
leading: false,
|
|
@@ -52,7 +52,7 @@ class DebouncedStore {
|
|
|
52
52
|
if (typeof this._queueById[id] === "function") {
|
|
53
53
|
return this._queueById[id](id, action);
|
|
54
54
|
}
|
|
55
|
-
this._queueById[id] = (0,
|
|
55
|
+
this._queueById[id] = (0, debounce_js_1.default)((id, action) => {
|
|
56
56
|
this.unbounced(id, action);
|
|
57
57
|
}, wait, Object.assign(Object.assign({}, options), { leading: false })); // leading required for return promise
|
|
58
58
|
return this._queueById[id](id, action);
|
package/dist/types.d.ts
CHANGED
|
@@ -36,6 +36,13 @@ export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
36
36
|
data: (item: any, context: HookContext) => Promisable<Record<string, any>>;
|
|
37
37
|
createItemsInDataArraySeparately?: boolean;
|
|
38
38
|
}
|
|
39
|
+
export declare type OnDeleteAction = "cascade" | "set null";
|
|
40
|
+
export interface OnDeleteOptions {
|
|
41
|
+
keyThere: string;
|
|
42
|
+
keyHere: string;
|
|
43
|
+
onDelete: OnDeleteAction;
|
|
44
|
+
blocking?: boolean;
|
|
45
|
+
}
|
|
39
46
|
export interface InitDebounceMixinOptions {
|
|
40
47
|
default: Partial<DebouncedStoreOptions>;
|
|
41
48
|
blacklist: string[];
|
|
@@ -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;
|
|
@@ -4,13 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.mergeQuery = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
7
|
+
const get_js_1 = __importDefault(require("lodash/get.js"));
|
|
8
|
+
const has_js_1 = __importDefault(require("lodash/has.js"));
|
|
9
|
+
const isEmpty_js_1 = __importDefault(require("lodash/isEmpty.js"));
|
|
10
|
+
const isEqual_js_1 = __importDefault(require("lodash/isEqual.js"));
|
|
11
|
+
const merge_js_1 = __importDefault(require("lodash/merge.js"));
|
|
12
|
+
const set_js_1 = __importDefault(require("lodash/set.js"));
|
|
13
|
+
const uniqWith_js_1 = __importDefault(require("lodash/uniqWith.js"));
|
|
14
14
|
const mergeArrays_1 = require("./mergeArrays");
|
|
15
15
|
const filterQuery_1 = require("../filterQuery");
|
|
16
16
|
const errors_1 = require("@feathersjs/errors");
|
|
@@ -18,14 +18,14 @@ const hasOwnProperty = (obj, key) => {
|
|
|
18
18
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
19
19
|
};
|
|
20
20
|
function handleArray(target, source, key, options) {
|
|
21
|
-
const targetVal = (0,
|
|
22
|
-
const sourceVal = (0,
|
|
21
|
+
const targetVal = (0, get_js_1.default)(target, key);
|
|
22
|
+
const sourceVal = (0, get_js_1.default)(source, key);
|
|
23
23
|
if (!sourceVal && !targetVal) {
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
-
const handle = (0,
|
|
26
|
+
const handle = (0, get_js_1.default)(options, ["handle", ...key], options.defaultHandle);
|
|
27
27
|
const arr = (0, mergeArrays_1.mergeArrays)(targetVal, sourceVal, handle, key, options.actionOnEmptyIntersect);
|
|
28
|
-
(0,
|
|
28
|
+
(0, set_js_1.default)(target, key, arr);
|
|
29
29
|
}
|
|
30
30
|
function handleCircular(target, source, prependKey, options) {
|
|
31
31
|
if (target === null || target === void 0 ? void 0 : target.$or) {
|
|
@@ -52,11 +52,11 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
52
52
|
delete source.$and;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
if (!(0,
|
|
55
|
+
if (!(0, has_js_1.default)(source, prependKey)) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
if (!(0,
|
|
59
|
-
(0,
|
|
58
|
+
if (!(0, has_js_1.default)(target, prependKey)) {
|
|
59
|
+
(0, set_js_1.default)(target, prependKey, (0, get_js_1.default)(source, prependKey));
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
const { defaultHandle, actionOnEmptyIntersect } = options;
|
|
@@ -64,22 +64,22 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
const getTargetVal = () => {
|
|
67
|
-
return (prependKey.length > 0) ? (0,
|
|
67
|
+
return (prependKey.length > 0) ? (0, get_js_1.default)(target, prependKey) : target;
|
|
68
68
|
};
|
|
69
69
|
const getSourceVal = () => {
|
|
70
|
-
return (prependKey.length > 0) ? (0,
|
|
70
|
+
return (prependKey.length > 0) ? (0, get_js_1.default)(source, prependKey) : source;
|
|
71
71
|
};
|
|
72
72
|
const targetVal = getTargetVal();
|
|
73
73
|
const sourceVal = getSourceVal();
|
|
74
|
-
if ((0,
|
|
74
|
+
if ((0, isEqual_js_1.default)(targetVal, sourceVal)) {
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
77
|
if (defaultHandle === "source") {
|
|
78
|
-
(0,
|
|
78
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
if (targetVal === null || sourceVal === null) {
|
|
82
|
-
(0,
|
|
82
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
85
|
const typeOfTargetVal = typeof targetVal;
|
|
@@ -87,7 +87,7 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
87
87
|
if (defaultHandle === "intersect") {
|
|
88
88
|
actionOnEmptyIntersect(target, source, prependKey);
|
|
89
89
|
}
|
|
90
|
-
(0,
|
|
90
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
const typeOfSourceVal = typeof sourceVal;
|
|
@@ -96,7 +96,7 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
96
96
|
if (isTargetSimple || isSourceSimple) {
|
|
97
97
|
if (isTargetSimple && isSourceSimple) {
|
|
98
98
|
if (defaultHandle === "combine") {
|
|
99
|
-
(0,
|
|
99
|
+
(0, set_js_1.default)(target, prependKey, { $in: [...new Set([targetVal, sourceVal])] });
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
102
|
else if (defaultHandle === "intersect") {
|
|
@@ -110,20 +110,20 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
110
110
|
const targetHasIn = hasOwnProperty(targetVal, "$in");
|
|
111
111
|
const $in = (targetHasIn) ? targetVal["$in"] : sourceVal["$in"];
|
|
112
112
|
const otherVal = (isTargetSimple) ? targetVal : sourceVal;
|
|
113
|
-
if ($in.length === 1 && (0,
|
|
114
|
-
(0,
|
|
113
|
+
if ($in.length === 1 && (0, isEqual_js_1.default)($in[0], otherVal)) {
|
|
114
|
+
(0, set_js_1.default)(target, prependKey, otherVal);
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
else if (defaultHandle === "combine") {
|
|
118
|
-
if (!$in.some((x) => (0,
|
|
118
|
+
if (!$in.some((x) => (0, isEqual_js_1.default)(x, otherVal))) {
|
|
119
119
|
$in.push(otherVal);
|
|
120
120
|
}
|
|
121
|
-
(0,
|
|
121
|
+
(0, set_js_1.default)(target, `${prependKey}.$in`, $in);
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
124
|
else if (defaultHandle === "intersect") {
|
|
125
|
-
if ($in.some((x) => (0,
|
|
126
|
-
(0,
|
|
125
|
+
if ($in.some((x) => (0, isEqual_js_1.default)(x, otherVal))) {
|
|
126
|
+
(0, set_js_1.default)(target, prependKey, otherVal);
|
|
127
127
|
}
|
|
128
128
|
else {
|
|
129
129
|
actionOnEmptyIntersect(target, source, prependKey);
|
|
@@ -139,7 +139,7 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
139
139
|
const key = prependKey[prependKey.length - 1];
|
|
140
140
|
if (key === "$or") {
|
|
141
141
|
if (defaultHandle === "combine") {
|
|
142
|
-
const newVals = sourceVal.filter((x) => !targetVal.some((y) => (0,
|
|
142
|
+
const newVals = sourceVal.filter((x) => !targetVal.some((y) => (0, isEqual_js_1.default)(x, y)));
|
|
143
143
|
targetVal.push(...newVals);
|
|
144
144
|
}
|
|
145
145
|
else if (defaultHandle === "intersect") {
|
|
@@ -176,7 +176,7 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
178
|
else if (defaultHandle === "intersect") {
|
|
179
|
-
const newVals = sourceVal.filter((x) => !targetVal.some((y) => (0,
|
|
179
|
+
const newVals = sourceVal.filter((x) => !targetVal.some((y) => (0, isEqual_js_1.default)(x, y)));
|
|
180
180
|
targetVal.push(...newVals);
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
@@ -185,29 +185,29 @@ function handleCircular(target, source, prependKey, options) {
|
|
|
185
185
|
if (defaultHandle === "combine") {
|
|
186
186
|
let $in = targetVal.concat(sourceVal);
|
|
187
187
|
$in = [...new Set($in)];
|
|
188
|
-
(0,
|
|
188
|
+
(0, set_js_1.default)(target, prependKey, $in);
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
191
|
else if (defaultHandle === "intersect") {
|
|
192
|
-
const $in = targetVal.filter((x) => sourceVal.some((y) => (0,
|
|
192
|
+
const $in = targetVal.filter((x) => sourceVal.some((y) => (0, isEqual_js_1.default)(x, y)));
|
|
193
193
|
if ($in.length === 0) {
|
|
194
194
|
actionOnEmptyIntersect(target, source, prependKey);
|
|
195
195
|
}
|
|
196
196
|
else if ($in.length === 1) {
|
|
197
|
-
(0,
|
|
197
|
+
(0, set_js_1.default)(target, prependKey.slice(0, -1), $in[0]);
|
|
198
198
|
return;
|
|
199
199
|
}
|
|
200
200
|
else {
|
|
201
|
-
(0,
|
|
201
|
+
(0, set_js_1.default)(target, prependKey, $in);
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
return;
|
|
205
205
|
}
|
|
206
|
-
(0,
|
|
206
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
209
|
if (typeOfTargetVal !== "object" || typeOfSourceVal !== "object") {
|
|
210
|
-
(0,
|
|
210
|
+
(0, set_js_1.default)(target, prependKey, sourceVal);
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
213
|
// both are objects
|
|
@@ -265,13 +265,13 @@ function mergeQuery(target, source, options) {
|
|
|
265
265
|
handleArray(targetFilters, sourceFilters, ["$select"], fullOptions);
|
|
266
266
|
// remaining filters
|
|
267
267
|
delete sourceFilters["$select"];
|
|
268
|
-
(0,
|
|
268
|
+
(0, merge_js_1.default)(targetFilters, sourceFilters);
|
|
269
269
|
//#endregion
|
|
270
270
|
//#region '$or' / '$and'
|
|
271
271
|
if ((options === null || options === void 0 ? void 0 : options.useLogicalConjunction) &&
|
|
272
272
|
(options.defaultHandle === "combine" ||
|
|
273
273
|
options.defaultHandle === "intersect") &&
|
|
274
|
-
!(0,
|
|
274
|
+
!(0, isEmpty_js_1.default)(targetQuery)) {
|
|
275
275
|
const logicalOp = (options.defaultHandle === "combine")
|
|
276
276
|
? "$or"
|
|
277
277
|
: "$and";
|
|
@@ -301,13 +301,13 @@ function getParentProp(target, path) {
|
|
|
301
301
|
return target;
|
|
302
302
|
}
|
|
303
303
|
const pathOneUp = path.slice(0, -1);
|
|
304
|
-
return (0,
|
|
304
|
+
return (0, get_js_1.default)(target, pathOneUp);
|
|
305
305
|
}
|
|
306
306
|
function cleanOr(target) {
|
|
307
307
|
if (!target || !Array.isArray(target) || target.length <= 0) {
|
|
308
308
|
return target;
|
|
309
309
|
}
|
|
310
|
-
if (target.some(x => (0,
|
|
310
|
+
if (target.some(x => (0, isEmpty_js_1.default)(x))) {
|
|
311
311
|
return undefined;
|
|
312
312
|
}
|
|
313
313
|
else {
|
|
@@ -318,11 +318,11 @@ function cleanAnd(target) {
|
|
|
318
318
|
if (!target || !Array.isArray(target) || target.length <= 0) {
|
|
319
319
|
return target;
|
|
320
320
|
}
|
|
321
|
-
if (target.every(x => (0,
|
|
321
|
+
if (target.every(x => (0, isEmpty_js_1.default)(x))) {
|
|
322
322
|
return undefined;
|
|
323
323
|
}
|
|
324
324
|
else {
|
|
325
|
-
target = target.filter(x => !(0,
|
|
325
|
+
target = target.filter(x => !(0, isEmpty_js_1.default)(x));
|
|
326
326
|
return arrayWithoutDuplicates(target);
|
|
327
327
|
}
|
|
328
328
|
}
|
|
@@ -330,5 +330,5 @@ function arrayWithoutDuplicates(target) {
|
|
|
330
330
|
if (!target || !Array.isArray(target)) {
|
|
331
331
|
return target;
|
|
332
332
|
}
|
|
333
|
-
return (0,
|
|
333
|
+
return (0, uniqWith_js_1.default)(target, isEqual_js_1.default);
|
|
334
334
|
}
|
package/dist/utils/pushSet.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Path, PushSetOptions } from "../types";
|
|
2
|
-
export declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val: unknown, options?: PushSetOptions
|
|
2
|
+
export declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val: unknown, options?: PushSetOptions) => unknown[];
|
package/dist/utils/pushSet.js
CHANGED
|
@@ -4,19 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.pushSet = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
7
|
+
const isEqual_js_1 = __importDefault(require("lodash/isEqual.js"));
|
|
8
|
+
const get_js_1 = __importDefault(require("lodash/get.js"));
|
|
9
|
+
const set_js_1 = __importDefault(require("lodash/set.js"));
|
|
10
10
|
const pushSet = (obj, path, val, options) => {
|
|
11
11
|
options = options || {};
|
|
12
|
-
let arr = (0,
|
|
12
|
+
let arr = (0, get_js_1.default)(obj, path);
|
|
13
13
|
if (!arr || !Array.isArray(arr)) {
|
|
14
14
|
arr = [val];
|
|
15
|
-
(0,
|
|
15
|
+
(0, set_js_1.default)(obj, path, arr);
|
|
16
16
|
return arr;
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
19
|
-
if (options.unique && arr.some(x => (0,
|
|
19
|
+
if (options.unique && arr.some(x => (0, isEqual_js_1.default)(x, val))) {
|
|
20
20
|
return arr;
|
|
21
21
|
}
|
|
22
22
|
arr.push(val);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feathers-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Some utils for projects using '@feathersjs/feathers'",
|
|
5
5
|
"author": "fratzinger",
|
|
6
6
|
"repository": {
|
|
@@ -39,30 +39,30 @@
|
|
|
39
39
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@feathersjs/adapter-commons": "^4.5.
|
|
43
|
-
"@feathersjs/errors": "^4.5.
|
|
44
|
-
"@feathersjs/feathers": "^4.5.
|
|
45
|
-
"feathers-hooks-common": "^
|
|
42
|
+
"@feathersjs/adapter-commons": "^4.5.15",
|
|
43
|
+
"@feathersjs/errors": "^4.5.15",
|
|
44
|
+
"@feathersjs/feathers": "^4.5.15",
|
|
45
|
+
"feathers-hooks-common": "^6.1.5",
|
|
46
46
|
"lodash": "^4.17.21"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
50
|
-
"@types/lodash": "^4.14.
|
|
51
|
-
"@types/mocha": "^9.1.
|
|
52
|
-
"@types/node": "^
|
|
53
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
54
|
-
"@typescript-eslint/parser": "^5.
|
|
50
|
+
"@types/lodash": "^4.14.184",
|
|
51
|
+
"@types/mocha": "^9.1.1",
|
|
52
|
+
"@types/node": "^18.7.14",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^5.36.0",
|
|
54
|
+
"@typescript-eslint/parser": "^5.36.0",
|
|
55
55
|
"cross-env": "^7.0.3",
|
|
56
|
-
"eslint": "^8.
|
|
57
|
-
"eslint-import-resolver-typescript": "^
|
|
58
|
-
"eslint-plugin-import": "^2.
|
|
59
|
-
"eslint-plugin-security": "^1.
|
|
56
|
+
"eslint": "^8.23.0",
|
|
57
|
+
"eslint-import-resolver-typescript": "^3.5.0",
|
|
58
|
+
"eslint-plugin-import": "^2.26.0",
|
|
59
|
+
"eslint-plugin-security": "^1.5.0",
|
|
60
60
|
"feathers-memory": "^4.1.0",
|
|
61
|
-
"mocha": "^
|
|
62
|
-
"np": "^7.6.
|
|
61
|
+
"mocha": "^10.0.0",
|
|
62
|
+
"np": "^7.6.2",
|
|
63
63
|
"nyc": "^15.1.0",
|
|
64
64
|
"shx": "^0.3.4",
|
|
65
|
-
"ts-node": "^10.
|
|
66
|
-
"typescript": "^4.
|
|
65
|
+
"ts-node": "^10.9.1",
|
|
66
|
+
"typescript": "^4.8.2"
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import { checkContext } from "feathers-hooks-common";
|
|
3
|
+
import type { OnDeleteOptions } from "../types";
|
|
4
|
+
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
|
5
|
+
|
|
6
|
+
export function onDelete<S = Record<string, any>>(
|
|
7
|
+
service: keyof S,
|
|
8
|
+
{
|
|
9
|
+
keyThere,
|
|
10
|
+
keyHere = "id",
|
|
11
|
+
onDelete = "cascade",
|
|
12
|
+
blocking = true
|
|
13
|
+
}: OnDeleteOptions) {
|
|
14
|
+
if (!service || !keyThere) {
|
|
15
|
+
throw "initialize hook 'removeRelated' completely!";
|
|
16
|
+
}
|
|
17
|
+
if (!["cascade", "set null"].includes(onDelete)) {
|
|
18
|
+
throw "onDelete must be 'cascade' or 'set null'";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return async (context: HookContext): Promise<HookContext> => {
|
|
22
|
+
checkContext(context, "after", "remove", "onDelete");
|
|
23
|
+
|
|
24
|
+
const { items } = getItemsIsArray(context);
|
|
25
|
+
|
|
26
|
+
let ids = items.map(x => x[keyHere]).filter(x => !!x);
|
|
27
|
+
ids = [...new Set(ids)];
|
|
28
|
+
|
|
29
|
+
if (!ids || ids.length <= 0) { return context; }
|
|
30
|
+
|
|
31
|
+
const params = {
|
|
32
|
+
query: {
|
|
33
|
+
[keyThere]: {
|
|
34
|
+
$in: ids
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
paginate: false
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let promise;
|
|
41
|
+
|
|
42
|
+
if (onDelete === "cascade") {
|
|
43
|
+
promise = context.app.service(service as string).remove(null, params);
|
|
44
|
+
} else if (onDelete === "set null") {
|
|
45
|
+
const data = { [keyThere]: null };
|
|
46
|
+
promise = context.app.service(service as string).patch(null, data, params);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (blocking) {
|
|
50
|
+
await promise;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return context;
|
|
54
|
+
};
|
|
55
|
+
}
|
package/src/hooks/setData.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import _get from "lodash/get";
|
|
2
|
-
import _set from "lodash/set";
|
|
3
|
-
import _has from "lodash/has";
|
|
1
|
+
import _get from "lodash/get.js";
|
|
2
|
+
import _set from "lodash/set.js";
|
|
3
|
+
import _has from "lodash/has.js";
|
|
4
4
|
|
|
5
5
|
import { Forbidden } from "@feathersjs/errors";
|
|
6
6
|
import { getItemsIsArray } from "../utils/getItemsIsArray";
|
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 };
|
|
@@ -20,7 +20,7 @@ import { debounceMixin, DebouncedStore } from "./mixins/debounce-mixin";
|
|
|
20
20
|
|
|
21
21
|
export const mixins = {
|
|
22
22
|
debounceMixin,
|
|
23
|
-
DebouncedStore
|
|
23
|
+
DebouncedStore,
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export { debounceMixin };
|
|
@@ -38,7 +38,8 @@ export { setResultEmpty } from "./utils/setResultEmpty";
|
|
|
38
38
|
export { markHookForSkip } from "./utils/markHookForSkip";
|
|
39
39
|
export { filterQuery } from "./utils/filterQuery";
|
|
40
40
|
export { getItemsIsArray } from "./utils/getItemsIsArray";
|
|
41
|
+
export { onDelete } from "./hooks/onDelete";
|
|
41
42
|
export { shouldSkip } from "./utils/shouldSkip";
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
export * from "./types";
|
|
44
|
+
export * from "./types";
|
|
45
|
+
export * from "./utility-types/utility-types";
|
package/src/types.ts
CHANGED
|
@@ -50,6 +50,15 @@ export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
50
50
|
createItemsInDataArraySeparately?: boolean
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
export type OnDeleteAction = "cascade" | "set null";
|
|
54
|
+
|
|
55
|
+
export interface OnDeleteOptions {
|
|
56
|
+
keyThere: string
|
|
57
|
+
keyHere: string
|
|
58
|
+
onDelete: OnDeleteAction
|
|
59
|
+
blocking?: boolean
|
|
60
|
+
}
|
|
61
|
+
|
|
53
62
|
//#endregion
|
|
54
63
|
|
|
55
64
|
//#region mixins
|
|
@@ -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,10 +1,10 @@
|
|
|
1
|
-
import _get from "lodash/get";
|
|
2
|
-
import _has from "lodash/has";
|
|
3
|
-
import _isEmpty from "lodash/isEmpty";
|
|
4
|
-
import _isEqual from "lodash/isEqual";
|
|
5
|
-
import _merge from "lodash/merge";
|
|
6
|
-
import _set from "lodash/set";
|
|
7
|
-
import _uniqWith from "lodash/uniqWith";
|
|
1
|
+
import _get from "lodash/get.js";
|
|
2
|
+
import _has from "lodash/has.js";
|
|
3
|
+
import _isEmpty from "lodash/isEmpty.js";
|
|
4
|
+
import _isEqual from "lodash/isEqual.js";
|
|
5
|
+
import _merge from "lodash/merge.js";
|
|
6
|
+
import _set from "lodash/set.js";
|
|
7
|
+
import _uniqWith from "lodash/uniqWith.js";
|
|
8
8
|
|
|
9
9
|
import { mergeArrays } from "./mergeArrays";
|
|
10
10
|
import { filterQuery } from "../filterQuery";
|
package/src/utils/pushSet.ts
CHANGED