feathers-utils 6.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +54 -58
- package/dist/index.d.cts +16 -13
- package/dist/index.d.mts +16 -13
- package/dist/index.d.ts +16 -13
- package/dist/index.mjs +54 -58
- package/package.json +24 -24
- package/src/.DS_Store +0 -0
- package/src/hooks/.DS_Store +0 -0
- package/src/hooks/createRelated.ts +32 -31
- package/src/hooks/onDelete.ts +40 -41
- package/src/hooks/removeRelated.ts +2 -0
package/dist/index.cjs
CHANGED
|
@@ -729,37 +729,35 @@ function checkMulti() {
|
|
|
729
729
|
};
|
|
730
730
|
}
|
|
731
731
|
|
|
732
|
-
function createRelated({
|
|
733
|
-
service,
|
|
734
|
-
multi = true,
|
|
735
|
-
data,
|
|
736
|
-
createItemsInDataArraySeparately = true
|
|
737
|
-
}) {
|
|
738
|
-
if (!service || !data) {
|
|
739
|
-
throw "initialize hook 'createRelated' completely!";
|
|
740
|
-
}
|
|
732
|
+
function createRelated(options) {
|
|
741
733
|
return async (context) => {
|
|
742
734
|
if (shouldSkip("createRelated", context)) {
|
|
743
735
|
return context;
|
|
744
736
|
}
|
|
745
737
|
feathersHooksCommon.checkContext(context, "after", void 0, "createRelated");
|
|
746
738
|
const { items } = getItemsIsArray(context);
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
739
|
+
const entries = Array.isArray(options) ? options : [options];
|
|
740
|
+
await Promise.all(
|
|
741
|
+
entries.map(async (entry) => {
|
|
742
|
+
const { data, service, createItemsInDataArraySeparately, multi } = entry;
|
|
743
|
+
let dataToCreate = (await Promise.all(items.map(async (item) => data(item, context)))).filter((x) => !!x);
|
|
744
|
+
if (createItemsInDataArraySeparately) {
|
|
745
|
+
dataToCreate = dataToCreate.flat();
|
|
746
|
+
}
|
|
747
|
+
if (!dataToCreate || dataToCreate.length <= 0) {
|
|
748
|
+
return context;
|
|
749
|
+
}
|
|
750
|
+
if (multi) {
|
|
751
|
+
await context.app.service(service).create(dataToCreate);
|
|
752
|
+
} else {
|
|
753
|
+
await Promise.all(
|
|
754
|
+
dataToCreate.map(
|
|
755
|
+
async (item) => context.app.service(service).create(item)
|
|
756
|
+
)
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
})
|
|
760
|
+
);
|
|
763
761
|
return context;
|
|
764
762
|
};
|
|
765
763
|
}
|
|
@@ -797,46 +795,44 @@ const forEach = (actionPerItem, options) => {
|
|
|
797
795
|
};
|
|
798
796
|
};
|
|
799
797
|
|
|
800
|
-
function onDelete(
|
|
801
|
-
keyThere,
|
|
802
|
-
keyHere = "id",
|
|
803
|
-
onDelete: onDelete2 = "cascade",
|
|
804
|
-
blocking = true
|
|
805
|
-
}) {
|
|
806
|
-
if (!service || !keyThere) {
|
|
807
|
-
throw "initialize hook 'removeRelated' completely!";
|
|
808
|
-
}
|
|
809
|
-
if (!["cascade", "set null"].includes(onDelete2)) {
|
|
810
|
-
throw "onDelete must be 'cascade' or 'set null'";
|
|
811
|
-
}
|
|
798
|
+
function onDelete(options) {
|
|
812
799
|
return async (context) => {
|
|
813
800
|
if (shouldSkip("onDelete", context)) {
|
|
814
801
|
return context;
|
|
815
802
|
}
|
|
816
803
|
feathersHooksCommon.checkContext(context, "after", "remove", "onDelete");
|
|
817
804
|
const { items } = getItemsIsArray(context);
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
$in: ids
|
|
805
|
+
const entries = Array.isArray(options) ? options : [options];
|
|
806
|
+
const promises = [];
|
|
807
|
+
entries.forEach(
|
|
808
|
+
async ({ keyHere, keyThere, onDelete: onDelete2, service, blocking }) => {
|
|
809
|
+
let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
|
|
810
|
+
ids = [...new Set(ids)];
|
|
811
|
+
if (!ids || ids.length <= 0) {
|
|
812
|
+
return context;
|
|
827
813
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
814
|
+
const params = {
|
|
815
|
+
query: {
|
|
816
|
+
[keyThere]: {
|
|
817
|
+
$in: ids
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
paginate: false
|
|
821
|
+
};
|
|
822
|
+
let promise = void 0;
|
|
823
|
+
if (onDelete2 === "cascade") {
|
|
824
|
+
promise = context.app.service(service).remove(null, params);
|
|
825
|
+
} else if (onDelete2 === "set null") {
|
|
826
|
+
const data = { [keyThere]: null };
|
|
827
|
+
promise = context.app.service(service).patch(null, data, params);
|
|
828
|
+
}
|
|
829
|
+
if (blocking) {
|
|
830
|
+
promises.push(promise);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
);
|
|
834
|
+
if (promises.length) {
|
|
835
|
+
await Promise.all(promises);
|
|
840
836
|
}
|
|
841
837
|
return context;
|
|
842
838
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -25,7 +25,7 @@ interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
25
25
|
/**
|
|
26
26
|
* hook to create related items
|
|
27
27
|
*/
|
|
28
|
-
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>(
|
|
28
|
+
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>(options: MaybeArray<CreateRelatedOptions<S>>): (context: H) => Promise<H>;
|
|
29
29
|
|
|
30
30
|
type GetItemsIsArrayFrom = "data" | "result" | "automatic";
|
|
31
31
|
type GetItemsIsArrayOptions = {
|
|
@@ -35,7 +35,7 @@ interface GetItemsIsArrayResult<T = any> {
|
|
|
35
35
|
items: T[];
|
|
36
36
|
isArray: boolean;
|
|
37
37
|
}
|
|
38
|
-
declare const getItemsIsArray: <T = any, H extends HookContext
|
|
38
|
+
declare const getItemsIsArray: <T = any, H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H, options?: GetItemsIsArrayOptions) => GetItemsIsArrayResult<T>;
|
|
39
39
|
|
|
40
40
|
type HookForEachOptions<T = any, H = HookContext, R = any> = {
|
|
41
41
|
wait?: "sequential" | "parallel" | false;
|
|
@@ -49,10 +49,11 @@ type ActionPerItem<T, H, R> = (item: T, options: {
|
|
|
49
49
|
} & (undefined extends R ? {} : {
|
|
50
50
|
fromAll: R;
|
|
51
51
|
})) => Promisable<any>;
|
|
52
|
-
declare const forEach: <H extends HookContext
|
|
52
|
+
declare const forEach: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>, T = any, R = any>(actionPerItem: ActionPerItem<T, H, R>, options?: HookForEachOptions<T, H, R>) => ReturnAsyncHook<H>;
|
|
53
53
|
|
|
54
54
|
type OnDeleteAction = "cascade" | "set null";
|
|
55
|
-
interface OnDeleteOptions {
|
|
55
|
+
interface OnDeleteOptions<Path extends string = string> {
|
|
56
|
+
service: Path;
|
|
56
57
|
keyThere: string;
|
|
57
58
|
keyHere: string;
|
|
58
59
|
onDelete: OnDeleteAction;
|
|
@@ -61,7 +62,7 @@ interface OnDeleteOptions {
|
|
|
61
62
|
/**
|
|
62
63
|
* hook to manipulate related items on delete
|
|
63
64
|
*/
|
|
64
|
-
declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(
|
|
65
|
+
declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(options: MaybeArray<OnDeleteOptions<KeyOf<S>>>): (context: H) => Promise<H>;
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
68
|
* Parse fields to date or number
|
|
@@ -79,6 +80,8 @@ interface RemoveRelatedOptions<S = Record<string, any>> {
|
|
|
79
80
|
}
|
|
80
81
|
/**
|
|
81
82
|
* hook to remove related items
|
|
83
|
+
*
|
|
84
|
+
* @deprecated use 'onDelete' instead
|
|
82
85
|
*/
|
|
83
86
|
declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
|
|
84
87
|
|
|
@@ -89,7 +92,7 @@ interface HookRunPerItemOptions {
|
|
|
89
92
|
* hook to run a hook for each item in the context
|
|
90
93
|
* uses `context.result` if it is existent. otherwise uses context.data
|
|
91
94
|
*/
|
|
92
|
-
declare const runPerItem: <H extends HookContext
|
|
95
|
+
declare const runPerItem: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>, T = any>(actionPerItem: (item: T, context: H) => Promisable<any>, _options?: HookRunPerItemOptions) => (context: H) => Promise<H>;
|
|
93
96
|
|
|
94
97
|
type Predicate<T = any> = (item: T) => boolean;
|
|
95
98
|
type PredicateWithContext<T = any> = (item: T, context: HookContext) => boolean;
|
|
@@ -103,14 +106,14 @@ interface HookSetDataOptions {
|
|
|
103
106
|
*/
|
|
104
107
|
declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
|
|
105
108
|
|
|
106
|
-
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext
|
|
109
|
+
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext>(context: H) => H;
|
|
107
110
|
/**
|
|
108
111
|
* a hook to move params to query._$client
|
|
109
112
|
* the server only receives 'query' from params. All other params are ignored.
|
|
110
113
|
* So, to use `$populateParams` on the server, we need to move the params to query._$client
|
|
111
114
|
* the server will move them back to params
|
|
112
115
|
*/
|
|
113
|
-
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext
|
|
116
|
+
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext>(context: H) => H;
|
|
114
117
|
|
|
115
118
|
declare function defineParamsFromClient(keyToHide: string): (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
116
119
|
declare const paramsFromClient: (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
@@ -176,7 +179,7 @@ declare function reassembleQuery(query: FilterQueryResult): Query;
|
|
|
176
179
|
* 2. it uses `service.options.paginate` if it exists
|
|
177
180
|
* 3. it uses `context.params.adapter` if it exists
|
|
178
181
|
*/
|
|
179
|
-
declare const getPaginate: <H extends HookContext
|
|
182
|
+
declare const getPaginate: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => PaginationOptions | undefined;
|
|
180
183
|
|
|
181
184
|
/**
|
|
182
185
|
* util to check if a hook is a multi hook:
|
|
@@ -187,12 +190,12 @@ declare const getPaginate: <H extends HookContext<_feathersjs_feathers.Applicati
|
|
|
187
190
|
* - patch: `context.id == null`
|
|
188
191
|
* - remove: `context.id == null`
|
|
189
192
|
*/
|
|
190
|
-
declare const isMulti: <H extends HookContext
|
|
193
|
+
declare const isMulti: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
|
|
191
194
|
|
|
192
195
|
/**
|
|
193
196
|
* util to check if a hook is a paginated hook using `getPaginate`
|
|
194
197
|
*/
|
|
195
|
-
declare const isPaginated: <H extends HookContext
|
|
198
|
+
declare const isPaginated: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
|
|
196
199
|
|
|
197
200
|
/**
|
|
198
201
|
* util to mark a hook for skip, has to be used with `shouldSkip`
|
|
@@ -237,7 +240,7 @@ declare const setQueryKeySafely: (params: Params, key: string, value: any, opera
|
|
|
237
240
|
/**
|
|
238
241
|
* util to set `context.result` to an empty array or object, depending on the hook type
|
|
239
242
|
*/
|
|
240
|
-
declare const setResultEmpty: <H extends HookContext
|
|
243
|
+
declare const setResultEmpty: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
241
244
|
|
|
242
245
|
type ShouldSkipOptions = {
|
|
243
246
|
notSkippable?: boolean;
|
|
@@ -245,7 +248,7 @@ type ShouldSkipOptions = {
|
|
|
245
248
|
/**
|
|
246
249
|
* util to detect if a hook should be skipped
|
|
247
250
|
*/
|
|
248
|
-
declare const shouldSkip: <H extends HookContext
|
|
251
|
+
declare const shouldSkip: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(hookName: string, context: H, options?: ShouldSkipOptions) => boolean;
|
|
249
252
|
|
|
250
253
|
declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers.Application<any, any>, any>;
|
|
251
254
|
|
package/dist/index.d.mts
CHANGED
|
@@ -25,7 +25,7 @@ interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
25
25
|
/**
|
|
26
26
|
* hook to create related items
|
|
27
27
|
*/
|
|
28
|
-
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>(
|
|
28
|
+
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>(options: MaybeArray<CreateRelatedOptions<S>>): (context: H) => Promise<H>;
|
|
29
29
|
|
|
30
30
|
type GetItemsIsArrayFrom = "data" | "result" | "automatic";
|
|
31
31
|
type GetItemsIsArrayOptions = {
|
|
@@ -35,7 +35,7 @@ interface GetItemsIsArrayResult<T = any> {
|
|
|
35
35
|
items: T[];
|
|
36
36
|
isArray: boolean;
|
|
37
37
|
}
|
|
38
|
-
declare const getItemsIsArray: <T = any, H extends HookContext
|
|
38
|
+
declare const getItemsIsArray: <T = any, H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H, options?: GetItemsIsArrayOptions) => GetItemsIsArrayResult<T>;
|
|
39
39
|
|
|
40
40
|
type HookForEachOptions<T = any, H = HookContext, R = any> = {
|
|
41
41
|
wait?: "sequential" | "parallel" | false;
|
|
@@ -49,10 +49,11 @@ type ActionPerItem<T, H, R> = (item: T, options: {
|
|
|
49
49
|
} & (undefined extends R ? {} : {
|
|
50
50
|
fromAll: R;
|
|
51
51
|
})) => Promisable<any>;
|
|
52
|
-
declare const forEach: <H extends HookContext
|
|
52
|
+
declare const forEach: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>, T = any, R = any>(actionPerItem: ActionPerItem<T, H, R>, options?: HookForEachOptions<T, H, R>) => ReturnAsyncHook<H>;
|
|
53
53
|
|
|
54
54
|
type OnDeleteAction = "cascade" | "set null";
|
|
55
|
-
interface OnDeleteOptions {
|
|
55
|
+
interface OnDeleteOptions<Path extends string = string> {
|
|
56
|
+
service: Path;
|
|
56
57
|
keyThere: string;
|
|
57
58
|
keyHere: string;
|
|
58
59
|
onDelete: OnDeleteAction;
|
|
@@ -61,7 +62,7 @@ interface OnDeleteOptions {
|
|
|
61
62
|
/**
|
|
62
63
|
* hook to manipulate related items on delete
|
|
63
64
|
*/
|
|
64
|
-
declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(
|
|
65
|
+
declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(options: MaybeArray<OnDeleteOptions<KeyOf<S>>>): (context: H) => Promise<H>;
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
68
|
* Parse fields to date or number
|
|
@@ -79,6 +80,8 @@ interface RemoveRelatedOptions<S = Record<string, any>> {
|
|
|
79
80
|
}
|
|
80
81
|
/**
|
|
81
82
|
* hook to remove related items
|
|
83
|
+
*
|
|
84
|
+
* @deprecated use 'onDelete' instead
|
|
82
85
|
*/
|
|
83
86
|
declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
|
|
84
87
|
|
|
@@ -89,7 +92,7 @@ interface HookRunPerItemOptions {
|
|
|
89
92
|
* hook to run a hook for each item in the context
|
|
90
93
|
* uses `context.result` if it is existent. otherwise uses context.data
|
|
91
94
|
*/
|
|
92
|
-
declare const runPerItem: <H extends HookContext
|
|
95
|
+
declare const runPerItem: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>, T = any>(actionPerItem: (item: T, context: H) => Promisable<any>, _options?: HookRunPerItemOptions) => (context: H) => Promise<H>;
|
|
93
96
|
|
|
94
97
|
type Predicate<T = any> = (item: T) => boolean;
|
|
95
98
|
type PredicateWithContext<T = any> = (item: T, context: HookContext) => boolean;
|
|
@@ -103,14 +106,14 @@ interface HookSetDataOptions {
|
|
|
103
106
|
*/
|
|
104
107
|
declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
|
|
105
108
|
|
|
106
|
-
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext
|
|
109
|
+
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext>(context: H) => H;
|
|
107
110
|
/**
|
|
108
111
|
* a hook to move params to query._$client
|
|
109
112
|
* the server only receives 'query' from params. All other params are ignored.
|
|
110
113
|
* So, to use `$populateParams` on the server, we need to move the params to query._$client
|
|
111
114
|
* the server will move them back to params
|
|
112
115
|
*/
|
|
113
|
-
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext
|
|
116
|
+
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext>(context: H) => H;
|
|
114
117
|
|
|
115
118
|
declare function defineParamsFromClient(keyToHide: string): (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
116
119
|
declare const paramsFromClient: (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
@@ -176,7 +179,7 @@ declare function reassembleQuery(query: FilterQueryResult): Query;
|
|
|
176
179
|
* 2. it uses `service.options.paginate` if it exists
|
|
177
180
|
* 3. it uses `context.params.adapter` if it exists
|
|
178
181
|
*/
|
|
179
|
-
declare const getPaginate: <H extends HookContext
|
|
182
|
+
declare const getPaginate: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => PaginationOptions | undefined;
|
|
180
183
|
|
|
181
184
|
/**
|
|
182
185
|
* util to check if a hook is a multi hook:
|
|
@@ -187,12 +190,12 @@ declare const getPaginate: <H extends HookContext<_feathersjs_feathers.Applicati
|
|
|
187
190
|
* - patch: `context.id == null`
|
|
188
191
|
* - remove: `context.id == null`
|
|
189
192
|
*/
|
|
190
|
-
declare const isMulti: <H extends HookContext
|
|
193
|
+
declare const isMulti: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
|
|
191
194
|
|
|
192
195
|
/**
|
|
193
196
|
* util to check if a hook is a paginated hook using `getPaginate`
|
|
194
197
|
*/
|
|
195
|
-
declare const isPaginated: <H extends HookContext
|
|
198
|
+
declare const isPaginated: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
|
|
196
199
|
|
|
197
200
|
/**
|
|
198
201
|
* util to mark a hook for skip, has to be used with `shouldSkip`
|
|
@@ -237,7 +240,7 @@ declare const setQueryKeySafely: (params: Params, key: string, value: any, opera
|
|
|
237
240
|
/**
|
|
238
241
|
* util to set `context.result` to an empty array or object, depending on the hook type
|
|
239
242
|
*/
|
|
240
|
-
declare const setResultEmpty: <H extends HookContext
|
|
243
|
+
declare const setResultEmpty: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
241
244
|
|
|
242
245
|
type ShouldSkipOptions = {
|
|
243
246
|
notSkippable?: boolean;
|
|
@@ -245,7 +248,7 @@ type ShouldSkipOptions = {
|
|
|
245
248
|
/**
|
|
246
249
|
* util to detect if a hook should be skipped
|
|
247
250
|
*/
|
|
248
|
-
declare const shouldSkip: <H extends HookContext
|
|
251
|
+
declare const shouldSkip: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(hookName: string, context: H, options?: ShouldSkipOptions) => boolean;
|
|
249
252
|
|
|
250
253
|
declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers.Application<any, any>, any>;
|
|
251
254
|
|
package/dist/index.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
25
25
|
/**
|
|
26
26
|
* hook to create related items
|
|
27
27
|
*/
|
|
28
|
-
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>(
|
|
28
|
+
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>(options: MaybeArray<CreateRelatedOptions<S>>): (context: H) => Promise<H>;
|
|
29
29
|
|
|
30
30
|
type GetItemsIsArrayFrom = "data" | "result" | "automatic";
|
|
31
31
|
type GetItemsIsArrayOptions = {
|
|
@@ -35,7 +35,7 @@ interface GetItemsIsArrayResult<T = any> {
|
|
|
35
35
|
items: T[];
|
|
36
36
|
isArray: boolean;
|
|
37
37
|
}
|
|
38
|
-
declare const getItemsIsArray: <T = any, H extends HookContext
|
|
38
|
+
declare const getItemsIsArray: <T = any, H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H, options?: GetItemsIsArrayOptions) => GetItemsIsArrayResult<T>;
|
|
39
39
|
|
|
40
40
|
type HookForEachOptions<T = any, H = HookContext, R = any> = {
|
|
41
41
|
wait?: "sequential" | "parallel" | false;
|
|
@@ -49,10 +49,11 @@ type ActionPerItem<T, H, R> = (item: T, options: {
|
|
|
49
49
|
} & (undefined extends R ? {} : {
|
|
50
50
|
fromAll: R;
|
|
51
51
|
})) => Promisable<any>;
|
|
52
|
-
declare const forEach: <H extends HookContext
|
|
52
|
+
declare const forEach: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>, T = any, R = any>(actionPerItem: ActionPerItem<T, H, R>, options?: HookForEachOptions<T, H, R>) => ReturnAsyncHook<H>;
|
|
53
53
|
|
|
54
54
|
type OnDeleteAction = "cascade" | "set null";
|
|
55
|
-
interface OnDeleteOptions {
|
|
55
|
+
interface OnDeleteOptions<Path extends string = string> {
|
|
56
|
+
service: Path;
|
|
56
57
|
keyThere: string;
|
|
57
58
|
keyHere: string;
|
|
58
59
|
onDelete: OnDeleteAction;
|
|
@@ -61,7 +62,7 @@ interface OnDeleteOptions {
|
|
|
61
62
|
/**
|
|
62
63
|
* hook to manipulate related items on delete
|
|
63
64
|
*/
|
|
64
|
-
declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(
|
|
65
|
+
declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(options: MaybeArray<OnDeleteOptions<KeyOf<S>>>): (context: H) => Promise<H>;
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
68
|
* Parse fields to date or number
|
|
@@ -79,6 +80,8 @@ interface RemoveRelatedOptions<S = Record<string, any>> {
|
|
|
79
80
|
}
|
|
80
81
|
/**
|
|
81
82
|
* hook to remove related items
|
|
83
|
+
*
|
|
84
|
+
* @deprecated use 'onDelete' instead
|
|
82
85
|
*/
|
|
83
86
|
declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
|
|
84
87
|
|
|
@@ -89,7 +92,7 @@ interface HookRunPerItemOptions {
|
|
|
89
92
|
* hook to run a hook for each item in the context
|
|
90
93
|
* uses `context.result` if it is existent. otherwise uses context.data
|
|
91
94
|
*/
|
|
92
|
-
declare const runPerItem: <H extends HookContext
|
|
95
|
+
declare const runPerItem: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>, T = any>(actionPerItem: (item: T, context: H) => Promisable<any>, _options?: HookRunPerItemOptions) => (context: H) => Promise<H>;
|
|
93
96
|
|
|
94
97
|
type Predicate<T = any> = (item: T) => boolean;
|
|
95
98
|
type PredicateWithContext<T = any> = (item: T, context: HookContext) => boolean;
|
|
@@ -103,14 +106,14 @@ interface HookSetDataOptions {
|
|
|
103
106
|
*/
|
|
104
107
|
declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
|
|
105
108
|
|
|
106
|
-
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext
|
|
109
|
+
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext>(context: H) => H;
|
|
107
110
|
/**
|
|
108
111
|
* a hook to move params to query._$client
|
|
109
112
|
* the server only receives 'query' from params. All other params are ignored.
|
|
110
113
|
* So, to use `$populateParams` on the server, we need to move the params to query._$client
|
|
111
114
|
* the server will move them back to params
|
|
112
115
|
*/
|
|
113
|
-
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext
|
|
116
|
+
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext>(context: H) => H;
|
|
114
117
|
|
|
115
118
|
declare function defineParamsFromClient(keyToHide: string): (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
116
119
|
declare const paramsFromClient: (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
@@ -176,7 +179,7 @@ declare function reassembleQuery(query: FilterQueryResult): Query;
|
|
|
176
179
|
* 2. it uses `service.options.paginate` if it exists
|
|
177
180
|
* 3. it uses `context.params.adapter` if it exists
|
|
178
181
|
*/
|
|
179
|
-
declare const getPaginate: <H extends HookContext
|
|
182
|
+
declare const getPaginate: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => PaginationOptions | undefined;
|
|
180
183
|
|
|
181
184
|
/**
|
|
182
185
|
* util to check if a hook is a multi hook:
|
|
@@ -187,12 +190,12 @@ declare const getPaginate: <H extends HookContext<_feathersjs_feathers.Applicati
|
|
|
187
190
|
* - patch: `context.id == null`
|
|
188
191
|
* - remove: `context.id == null`
|
|
189
192
|
*/
|
|
190
|
-
declare const isMulti: <H extends HookContext
|
|
193
|
+
declare const isMulti: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
|
|
191
194
|
|
|
192
195
|
/**
|
|
193
196
|
* util to check if a hook is a paginated hook using `getPaginate`
|
|
194
197
|
*/
|
|
195
|
-
declare const isPaginated: <H extends HookContext
|
|
198
|
+
declare const isPaginated: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
|
|
196
199
|
|
|
197
200
|
/**
|
|
198
201
|
* util to mark a hook for skip, has to be used with `shouldSkip`
|
|
@@ -237,7 +240,7 @@ declare const setQueryKeySafely: (params: Params, key: string, value: any, opera
|
|
|
237
240
|
/**
|
|
238
241
|
* util to set `context.result` to an empty array or object, depending on the hook type
|
|
239
242
|
*/
|
|
240
|
-
declare const setResultEmpty: <H extends HookContext
|
|
243
|
+
declare const setResultEmpty: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
241
244
|
|
|
242
245
|
type ShouldSkipOptions = {
|
|
243
246
|
notSkippable?: boolean;
|
|
@@ -245,7 +248,7 @@ type ShouldSkipOptions = {
|
|
|
245
248
|
/**
|
|
246
249
|
* util to detect if a hook should be skipped
|
|
247
250
|
*/
|
|
248
|
-
declare const shouldSkip: <H extends HookContext
|
|
251
|
+
declare const shouldSkip: <H extends HookContext = HookContext<_feathersjs_feathers.Application<any, any>, any>>(hookName: string, context: H, options?: ShouldSkipOptions) => boolean;
|
|
249
252
|
|
|
250
253
|
declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers.Application<any, any>, any>;
|
|
251
254
|
|
package/dist/index.mjs
CHANGED
|
@@ -718,37 +718,35 @@ function checkMulti() {
|
|
|
718
718
|
};
|
|
719
719
|
}
|
|
720
720
|
|
|
721
|
-
function createRelated({
|
|
722
|
-
service,
|
|
723
|
-
multi = true,
|
|
724
|
-
data,
|
|
725
|
-
createItemsInDataArraySeparately = true
|
|
726
|
-
}) {
|
|
727
|
-
if (!service || !data) {
|
|
728
|
-
throw "initialize hook 'createRelated' completely!";
|
|
729
|
-
}
|
|
721
|
+
function createRelated(options) {
|
|
730
722
|
return async (context) => {
|
|
731
723
|
if (shouldSkip("createRelated", context)) {
|
|
732
724
|
return context;
|
|
733
725
|
}
|
|
734
726
|
checkContext(context, "after", void 0, "createRelated");
|
|
735
727
|
const { items } = getItemsIsArray(context);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
728
|
+
const entries = Array.isArray(options) ? options : [options];
|
|
729
|
+
await Promise.all(
|
|
730
|
+
entries.map(async (entry) => {
|
|
731
|
+
const { data, service, createItemsInDataArraySeparately, multi } = entry;
|
|
732
|
+
let dataToCreate = (await Promise.all(items.map(async (item) => data(item, context)))).filter((x) => !!x);
|
|
733
|
+
if (createItemsInDataArraySeparately) {
|
|
734
|
+
dataToCreate = dataToCreate.flat();
|
|
735
|
+
}
|
|
736
|
+
if (!dataToCreate || dataToCreate.length <= 0) {
|
|
737
|
+
return context;
|
|
738
|
+
}
|
|
739
|
+
if (multi) {
|
|
740
|
+
await context.app.service(service).create(dataToCreate);
|
|
741
|
+
} else {
|
|
742
|
+
await Promise.all(
|
|
743
|
+
dataToCreate.map(
|
|
744
|
+
async (item) => context.app.service(service).create(item)
|
|
745
|
+
)
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
})
|
|
749
|
+
);
|
|
752
750
|
return context;
|
|
753
751
|
};
|
|
754
752
|
}
|
|
@@ -786,46 +784,44 @@ const forEach = (actionPerItem, options) => {
|
|
|
786
784
|
};
|
|
787
785
|
};
|
|
788
786
|
|
|
789
|
-
function onDelete(
|
|
790
|
-
keyThere,
|
|
791
|
-
keyHere = "id",
|
|
792
|
-
onDelete: onDelete2 = "cascade",
|
|
793
|
-
blocking = true
|
|
794
|
-
}) {
|
|
795
|
-
if (!service || !keyThere) {
|
|
796
|
-
throw "initialize hook 'removeRelated' completely!";
|
|
797
|
-
}
|
|
798
|
-
if (!["cascade", "set null"].includes(onDelete2)) {
|
|
799
|
-
throw "onDelete must be 'cascade' or 'set null'";
|
|
800
|
-
}
|
|
787
|
+
function onDelete(options) {
|
|
801
788
|
return async (context) => {
|
|
802
789
|
if (shouldSkip("onDelete", context)) {
|
|
803
790
|
return context;
|
|
804
791
|
}
|
|
805
792
|
checkContext(context, "after", "remove", "onDelete");
|
|
806
793
|
const { items } = getItemsIsArray(context);
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
$in: ids
|
|
794
|
+
const entries = Array.isArray(options) ? options : [options];
|
|
795
|
+
const promises = [];
|
|
796
|
+
entries.forEach(
|
|
797
|
+
async ({ keyHere, keyThere, onDelete: onDelete2, service, blocking }) => {
|
|
798
|
+
let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
|
|
799
|
+
ids = [...new Set(ids)];
|
|
800
|
+
if (!ids || ids.length <= 0) {
|
|
801
|
+
return context;
|
|
816
802
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
803
|
+
const params = {
|
|
804
|
+
query: {
|
|
805
|
+
[keyThere]: {
|
|
806
|
+
$in: ids
|
|
807
|
+
}
|
|
808
|
+
},
|
|
809
|
+
paginate: false
|
|
810
|
+
};
|
|
811
|
+
let promise = void 0;
|
|
812
|
+
if (onDelete2 === "cascade") {
|
|
813
|
+
promise = context.app.service(service).remove(null, params);
|
|
814
|
+
} else if (onDelete2 === "set null") {
|
|
815
|
+
const data = { [keyThere]: null };
|
|
816
|
+
promise = context.app.service(service).patch(null, data, params);
|
|
817
|
+
}
|
|
818
|
+
if (blocking) {
|
|
819
|
+
promises.push(promise);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
);
|
|
823
|
+
if (promises.length) {
|
|
824
|
+
await Promise.all(promises);
|
|
829
825
|
}
|
|
830
826
|
return context;
|
|
831
827
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feathers-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Some utils for projects using '@feathersjs/feathers'",
|
|
5
5
|
"author": "fratzinger",
|
|
6
6
|
"repository": {
|
|
@@ -30,43 +30,43 @@
|
|
|
30
30
|
"lib/**",
|
|
31
31
|
"dist/**"
|
|
32
32
|
],
|
|
33
|
-
"scripts": {
|
|
34
|
-
"build": "unbuild",
|
|
35
|
-
"version": "npm run build",
|
|
36
|
-
"release": "np",
|
|
37
|
-
"test": "vitest run",
|
|
38
|
-
"vitest": "vitest",
|
|
39
|
-
"coverage": "vitest run --coverage",
|
|
40
|
-
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
|
|
41
|
-
},
|
|
42
33
|
"dependencies": {
|
|
43
|
-
"@feathersjs/adapter-commons": "^5.0.
|
|
44
|
-
"@feathersjs/errors": "^5.0.
|
|
45
|
-
"@feathersjs/feathers": "^5.0.
|
|
34
|
+
"@feathersjs/adapter-commons": "^5.0.31",
|
|
35
|
+
"@feathersjs/errors": "^5.0.31",
|
|
36
|
+
"@feathersjs/feathers": "^5.0.31",
|
|
46
37
|
"fast-equals": "^5.0.1",
|
|
47
|
-
"feathers-hooks-common": "^8.
|
|
38
|
+
"feathers-hooks-common": "^8.2.1",
|
|
48
39
|
"lodash": "^4.17.21"
|
|
49
40
|
},
|
|
50
41
|
"devDependencies": {
|
|
51
|
-
"@feathersjs/memory": "^5.0.
|
|
52
|
-
"@types/lodash": "^4.
|
|
53
|
-
"@types/node": "^
|
|
42
|
+
"@feathersjs/memory": "^5.0.31",
|
|
43
|
+
"@types/lodash": "^4.17.13",
|
|
44
|
+
"@types/node": "^22.10.1",
|
|
54
45
|
"@typescript-eslint/eslint-plugin": "^6.16.0",
|
|
55
46
|
"@typescript-eslint/parser": "^6.16.0",
|
|
56
|
-
"@vitest/coverage-v8": "^
|
|
47
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
57
48
|
"eslint": "^8.56.0",
|
|
58
49
|
"eslint-config-prettier": "^9.1.0",
|
|
59
|
-
"eslint-import-resolver-typescript": "^3.
|
|
50
|
+
"eslint-import-resolver-typescript": "^3.7.0",
|
|
60
51
|
"eslint-plugin-import": "^2.29.1",
|
|
61
52
|
"eslint-plugin-prettier": "^5.1.2",
|
|
62
|
-
"np": "^
|
|
63
|
-
"prettier": "^3.
|
|
53
|
+
"np": "^10.1.0",
|
|
54
|
+
"prettier": "^3.4.1",
|
|
64
55
|
"shx": "^0.3.4",
|
|
65
|
-
"typescript": "^5.
|
|
56
|
+
"typescript": "^5.7.2",
|
|
66
57
|
"unbuild": "^2.0.0",
|
|
67
|
-
"vitest": "^
|
|
58
|
+
"vitest": "^2.1.8"
|
|
68
59
|
},
|
|
69
60
|
"peerDependencies": {
|
|
70
61
|
"@feathersjs/feathers": "^5.0.0"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "unbuild",
|
|
65
|
+
"version": "npm run build",
|
|
66
|
+
"release": "np",
|
|
67
|
+
"test": "vitest run",
|
|
68
|
+
"vitest": "vitest",
|
|
69
|
+
"coverage": "vitest run --coverage",
|
|
70
|
+
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
|
|
71
71
|
}
|
|
72
|
-
}
|
|
72
|
+
}
|
package/src/.DS_Store
ADDED
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
2
|
import { checkContext } from "feathers-hooks-common";
|
|
3
|
-
import type { Promisable } from "../typesInternal";
|
|
3
|
+
import type { MaybeArray, Promisable } from "../typesInternal";
|
|
4
4
|
import { getItemsIsArray, shouldSkip } from "../utils";
|
|
5
5
|
|
|
6
6
|
export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
@@ -16,15 +16,7 @@ export interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
16
16
|
export function createRelated<
|
|
17
17
|
S = Record<string, any>,
|
|
18
18
|
H extends HookContext = HookContext,
|
|
19
|
-
>({
|
|
20
|
-
service,
|
|
21
|
-
multi = true,
|
|
22
|
-
data,
|
|
23
|
-
createItemsInDataArraySeparately = true,
|
|
24
|
-
}: CreateRelatedOptions<S>) {
|
|
25
|
-
if (!service || !data) {
|
|
26
|
-
throw "initialize hook 'createRelated' completely!";
|
|
27
|
-
}
|
|
19
|
+
>(options: MaybeArray<CreateRelatedOptions<S>>) {
|
|
28
20
|
return async (context: H) => {
|
|
29
21
|
if (shouldSkip("createRelated", context)) {
|
|
30
22
|
return context;
|
|
@@ -34,27 +26,36 @@ export function createRelated<
|
|
|
34
26
|
|
|
35
27
|
const { items } = getItemsIsArray(context);
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
29
|
+
const entries = Array.isArray(options) ? options : [options];
|
|
30
|
+
|
|
31
|
+
await Promise.all(
|
|
32
|
+
entries.map(async (entry) => {
|
|
33
|
+
const { data, service, createItemsInDataArraySeparately, multi } =
|
|
34
|
+
entry;
|
|
35
|
+
|
|
36
|
+
let dataToCreate = (
|
|
37
|
+
await Promise.all(items.map(async (item) => data(item, context)))
|
|
38
|
+
).filter((x) => !!x);
|
|
39
|
+
|
|
40
|
+
if (createItemsInDataArraySeparately) {
|
|
41
|
+
dataToCreate = dataToCreate.flat();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!dataToCreate || dataToCreate.length <= 0) {
|
|
45
|
+
return context;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (multi) {
|
|
49
|
+
await context.app.service(service as string).create(dataToCreate);
|
|
50
|
+
} else {
|
|
51
|
+
await Promise.all(
|
|
52
|
+
dataToCreate.map(async (item) =>
|
|
53
|
+
context.app.service(service as string).create(item),
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
58
59
|
|
|
59
60
|
return context;
|
|
60
61
|
};
|
package/src/hooks/onDelete.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
2
|
import { checkContext } from "feathers-hooks-common";
|
|
3
3
|
import { getItemsIsArray, shouldSkip } from "../utils";
|
|
4
|
+
import type { KeyOf, MaybeArray } from "../typesInternal";
|
|
4
5
|
|
|
5
6
|
export type OnDeleteAction = "cascade" | "set null";
|
|
6
7
|
|
|
7
|
-
export interface OnDeleteOptions {
|
|
8
|
+
export interface OnDeleteOptions<Path extends string = string> {
|
|
9
|
+
service: Path;
|
|
8
10
|
keyThere: string;
|
|
9
11
|
keyHere: string;
|
|
10
12
|
onDelete: OnDeleteAction;
|
|
@@ -17,22 +19,7 @@ export interface OnDeleteOptions {
|
|
|
17
19
|
export function onDelete<
|
|
18
20
|
S = Record<string, any>,
|
|
19
21
|
H extends HookContext = HookContext,
|
|
20
|
-
>(
|
|
21
|
-
service: keyof S,
|
|
22
|
-
{
|
|
23
|
-
keyThere,
|
|
24
|
-
keyHere = "id",
|
|
25
|
-
onDelete = "cascade",
|
|
26
|
-
blocking = true,
|
|
27
|
-
}: OnDeleteOptions,
|
|
28
|
-
) {
|
|
29
|
-
if (!service || !keyThere) {
|
|
30
|
-
throw "initialize hook 'removeRelated' completely!";
|
|
31
|
-
}
|
|
32
|
-
if (!["cascade", "set null"].includes(onDelete)) {
|
|
33
|
-
throw "onDelete must be 'cascade' or 'set null'";
|
|
34
|
-
}
|
|
35
|
-
|
|
22
|
+
>(options: MaybeArray<OnDeleteOptions<KeyOf<S>>>) {
|
|
36
23
|
return async (context: H) => {
|
|
37
24
|
if (shouldSkip("onDelete", context)) {
|
|
38
25
|
return context;
|
|
@@ -42,35 +29,47 @@ export function onDelete<
|
|
|
42
29
|
|
|
43
30
|
const { items } = getItemsIsArray(context);
|
|
44
31
|
|
|
45
|
-
|
|
46
|
-
ids = [...new Set(ids)];
|
|
32
|
+
const entries = Array.isArray(options) ? options : [options];
|
|
47
33
|
|
|
48
|
-
|
|
49
|
-
return context;
|
|
50
|
-
}
|
|
34
|
+
const promises: Promise<any>[] = [];
|
|
51
35
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
[
|
|
55
|
-
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
paginate: false,
|
|
59
|
-
};
|
|
36
|
+
entries.forEach(
|
|
37
|
+
async ({ keyHere, keyThere, onDelete, service, blocking }) => {
|
|
38
|
+
let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
|
|
39
|
+
ids = [...new Set(ids)];
|
|
60
40
|
|
|
61
|
-
|
|
41
|
+
if (!ids || ids.length <= 0) {
|
|
42
|
+
return context;
|
|
43
|
+
}
|
|
62
44
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
45
|
+
const params = {
|
|
46
|
+
query: {
|
|
47
|
+
[keyThere]: {
|
|
48
|
+
$in: ids,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
paginate: false,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
let promise: Promise<any> | undefined = undefined;
|
|
55
|
+
|
|
56
|
+
if (onDelete === "cascade") {
|
|
57
|
+
promise = context.app.service(service as string).remove(null, params);
|
|
58
|
+
} else if (onDelete === "set null") {
|
|
59
|
+
const data = { [keyThere]: null };
|
|
60
|
+
promise = context.app
|
|
61
|
+
.service(service as string)
|
|
62
|
+
.patch(null, data, params);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (blocking) {
|
|
66
|
+
promises.push(promise);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
);
|
|
71
70
|
|
|
72
|
-
if (
|
|
73
|
-
await
|
|
71
|
+
if (promises.length) {
|
|
72
|
+
await Promise.all(promises);
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
return context;
|