feathers-utils 5.0.1 → 5.1.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 +2 -0
- package/dist/index.cjs +78 -0
- package/dist/index.d.cts +14 -1
- package/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.mjs +75 -1
- package/package.json +1 -1
- package/src/hooks/forEach.ts +5 -0
- package/src/hooks/from-client-for-server/common.ts +1 -0
- package/src/hooks/from-client-for-server/index.ts +2 -0
- package/src/hooks/from-client-for-server/paramsForServer.ts +100 -0
- package/src/hooks/from-client-for-server/paramsFromClient.ts +105 -0
- package/src/hooks/index.ts +1 -0
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ npm i feathers-utils
|
|
|
25
25
|
- `createRelated`: simply create related items from a hook.
|
|
26
26
|
- `forEach`
|
|
27
27
|
- `onDelete`: simply remove/set null related items from a hook.
|
|
28
|
+
- `paramsForServer`
|
|
29
|
+
- `paramsFromClient`
|
|
28
30
|
- `parseFields`
|
|
29
31
|
- `removeRelated`: simple remove related items from a hook. Basically `cascade` at feathers level.
|
|
30
32
|
- `runPerItem`: run a function for every item. Meant for `multi:true`.
|
package/dist/index.cjs
CHANGED
|
@@ -688,6 +688,9 @@ const forEach = (actionPerItem, options) => {
|
|
|
688
688
|
if (shouldSkip("forEach", context)) {
|
|
689
689
|
return context;
|
|
690
690
|
}
|
|
691
|
+
if (options?.skip && await options.skip(context)) {
|
|
692
|
+
return context;
|
|
693
|
+
}
|
|
691
694
|
const { items } = getItemsIsArray(context, { from });
|
|
692
695
|
const forAll = options?.forAll ? await options.forAll(items, context) : {};
|
|
693
696
|
const promises = [];
|
|
@@ -874,6 +877,77 @@ function setData(from, to, _options) {
|
|
|
874
877
|
};
|
|
875
878
|
}
|
|
876
879
|
|
|
880
|
+
const FROM_CLIENT_FOR_SERVER_DEFAULT_KEY = "_$client";
|
|
881
|
+
|
|
882
|
+
function defineParamsForServer(keyToHide) {
|
|
883
|
+
return function paramsForServer2(...whitelist) {
|
|
884
|
+
return (context) => {
|
|
885
|
+
let clonedParams;
|
|
886
|
+
Object.keys(context.params).forEach((key) => {
|
|
887
|
+
if (key === "query") {
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
if (whitelist.includes(key)) {
|
|
891
|
+
if (!clonedParams) {
|
|
892
|
+
clonedParams = {
|
|
893
|
+
...context.params,
|
|
894
|
+
query: {
|
|
895
|
+
...context.params.query
|
|
896
|
+
}
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
if (!clonedParams.query[keyToHide]) {
|
|
900
|
+
clonedParams.query[keyToHide] = {};
|
|
901
|
+
}
|
|
902
|
+
clonedParams.query[keyToHide][key] = clonedParams[key];
|
|
903
|
+
delete clonedParams[key];
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
if (clonedParams) {
|
|
907
|
+
context.params = clonedParams;
|
|
908
|
+
}
|
|
909
|
+
return context;
|
|
910
|
+
};
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
const paramsForServer = defineParamsForServer(
|
|
914
|
+
FROM_CLIENT_FOR_SERVER_DEFAULT_KEY
|
|
915
|
+
);
|
|
916
|
+
|
|
917
|
+
function defineParamsFromClient(keyToHide) {
|
|
918
|
+
return function paramsFromClient2(...whitelist) {
|
|
919
|
+
return (context) => {
|
|
920
|
+
if (!context.params?.query?.[keyToHide] || typeof context.params.query[keyToHide] !== "object") {
|
|
921
|
+
return context;
|
|
922
|
+
}
|
|
923
|
+
const params = {
|
|
924
|
+
...context.params,
|
|
925
|
+
query: {
|
|
926
|
+
...context.params.query,
|
|
927
|
+
[keyToHide]: {
|
|
928
|
+
...context.params.query[keyToHide]
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
const client = params.query[keyToHide];
|
|
933
|
+
whitelist.forEach((key) => {
|
|
934
|
+
if (key in client) {
|
|
935
|
+
params[key] = client[key];
|
|
936
|
+
delete client[key];
|
|
937
|
+
}
|
|
938
|
+
});
|
|
939
|
+
if (Object.keys(client).length === 0) {
|
|
940
|
+
delete params.query[keyToHide];
|
|
941
|
+
}
|
|
942
|
+
context.params = params;
|
|
943
|
+
return context;
|
|
944
|
+
};
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
const paramsFromClient = defineParamsFromClient(
|
|
948
|
+
FROM_CLIENT_FOR_SERVER_DEFAULT_KEY
|
|
949
|
+
);
|
|
950
|
+
|
|
877
951
|
var __defProp = Object.defineProperty;
|
|
878
952
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
879
953
|
var __publicField = (obj, key, value) => {
|
|
@@ -1000,6 +1074,8 @@ exports.checkMulti = checkMulti;
|
|
|
1000
1074
|
exports.createRelated = createRelated;
|
|
1001
1075
|
exports.debounceMixin = debounceMixin;
|
|
1002
1076
|
exports.defineHooks = defineHooks;
|
|
1077
|
+
exports.defineParamsForServer = defineParamsForServer;
|
|
1078
|
+
exports.defineParamsFromClient = defineParamsFromClient;
|
|
1003
1079
|
exports.filterArray = filterArray;
|
|
1004
1080
|
exports.filterObject = filterObject;
|
|
1005
1081
|
exports.filterQuery = filterQuery;
|
|
@@ -1014,6 +1090,8 @@ exports.mergeArrays = mergeArrays;
|
|
|
1014
1090
|
exports.mergeQuery = mergeQuery;
|
|
1015
1091
|
exports.onDelete = onDelete;
|
|
1016
1092
|
exports.optimizeBatchPatch = optimizeBatchPatch;
|
|
1093
|
+
exports.paramsForServer = paramsForServer;
|
|
1094
|
+
exports.paramsFromClient = paramsFromClient;
|
|
1017
1095
|
exports.parseFields = parseFields;
|
|
1018
1096
|
exports.pushSet = pushSet;
|
|
1019
1097
|
exports.removeRelated = removeRelated;
|
package/dist/index.d.cts
CHANGED
|
@@ -40,6 +40,7 @@ type HookForEachOptions<T = any, H = HookContext, R = any> = {
|
|
|
40
40
|
wait?: "sequential" | "parallel" | false;
|
|
41
41
|
items?: GetItemsIsArrayOptions["from"];
|
|
42
42
|
forAll?: (items: T[], context: H) => Promisable<R>;
|
|
43
|
+
skip?: (context: H) => Promisable<boolean>;
|
|
43
44
|
};
|
|
44
45
|
type ActionPerItem<T, H, R> = (item: T, options: {
|
|
45
46
|
context: H;
|
|
@@ -101,6 +102,18 @@ interface HookSetDataOptions {
|
|
|
101
102
|
*/
|
|
102
103
|
declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
|
|
103
104
|
|
|
105
|
+
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
106
|
+
/**
|
|
107
|
+
* a hook to move params to query._$client
|
|
108
|
+
* the server only receives 'query' from params. All other params are ignored.
|
|
109
|
+
* So, to use `$populateParams` on the server, we need to move the params to query._$client
|
|
110
|
+
* the server will move them back to params
|
|
111
|
+
*/
|
|
112
|
+
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
113
|
+
|
|
114
|
+
declare function defineParamsFromClient(keyToHide: string): (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
115
|
+
declare const paramsFromClient: (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
116
|
+
|
|
104
117
|
interface InitDebounceMixinOptions {
|
|
105
118
|
default: Partial<DebouncedStoreOptions>;
|
|
106
119
|
blacklist: string[];
|
|
@@ -297,4 +310,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
297
310
|
type InferDataFromPath<App extends Application, Path extends string, Method extends "create" | "update" | "patch"> = Method extends "create" ? InferCreateDataFromPath<App, Path> : Method extends "update" ? InferUpdateDataFromPath<App, Path> : Method extends "patch" ? InferPatchDataFromPath<App, Path> : never;
|
|
298
311
|
type InferResultFromPath<App extends Application, Path extends string, Method extends "get" | "find" | "create" | "update" | "patch" | "remove"> = Method extends "get" ? InferGetResultFromPath<App, Path> : Method extends "find" ? InferFindResultFromPath<App, Path> : Method extends "create" ? InferCreateResultFromPath<App, Path> : Method extends "update" ? InferUpdateResultFromPath<App, Path> : Method extends "patch" ? InferPatchResultFromPath<App, Path> : Method extends "remove" ? InferRemoveResultFromPath<App, Path> : never;
|
|
299
312
|
|
|
300
|
-
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type OptimizeBatchPatchOptions, type OptimizeBatchPatchResultItem, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, defineHooks, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
|
313
|
+
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type OptimizeBatchPatchOptions, type OptimizeBatchPatchResultItem, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, defineHooks, defineParamsForServer, defineParamsFromClient, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, paramsForServer, paramsFromClient, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
package/dist/index.d.mts
CHANGED
|
@@ -40,6 +40,7 @@ type HookForEachOptions<T = any, H = HookContext, R = any> = {
|
|
|
40
40
|
wait?: "sequential" | "parallel" | false;
|
|
41
41
|
items?: GetItemsIsArrayOptions["from"];
|
|
42
42
|
forAll?: (items: T[], context: H) => Promisable<R>;
|
|
43
|
+
skip?: (context: H) => Promisable<boolean>;
|
|
43
44
|
};
|
|
44
45
|
type ActionPerItem<T, H, R> = (item: T, options: {
|
|
45
46
|
context: H;
|
|
@@ -101,6 +102,18 @@ interface HookSetDataOptions {
|
|
|
101
102
|
*/
|
|
102
103
|
declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
|
|
103
104
|
|
|
105
|
+
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
106
|
+
/**
|
|
107
|
+
* a hook to move params to query._$client
|
|
108
|
+
* the server only receives 'query' from params. All other params are ignored.
|
|
109
|
+
* So, to use `$populateParams` on the server, we need to move the params to query._$client
|
|
110
|
+
* the server will move them back to params
|
|
111
|
+
*/
|
|
112
|
+
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
113
|
+
|
|
114
|
+
declare function defineParamsFromClient(keyToHide: string): (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
115
|
+
declare const paramsFromClient: (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
116
|
+
|
|
104
117
|
interface InitDebounceMixinOptions {
|
|
105
118
|
default: Partial<DebouncedStoreOptions>;
|
|
106
119
|
blacklist: string[];
|
|
@@ -297,4 +310,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
297
310
|
type InferDataFromPath<App extends Application, Path extends string, Method extends "create" | "update" | "patch"> = Method extends "create" ? InferCreateDataFromPath<App, Path> : Method extends "update" ? InferUpdateDataFromPath<App, Path> : Method extends "patch" ? InferPatchDataFromPath<App, Path> : never;
|
|
298
311
|
type InferResultFromPath<App extends Application, Path extends string, Method extends "get" | "find" | "create" | "update" | "patch" | "remove"> = Method extends "get" ? InferGetResultFromPath<App, Path> : Method extends "find" ? InferFindResultFromPath<App, Path> : Method extends "create" ? InferCreateResultFromPath<App, Path> : Method extends "update" ? InferUpdateResultFromPath<App, Path> : Method extends "patch" ? InferPatchResultFromPath<App, Path> : Method extends "remove" ? InferRemoveResultFromPath<App, Path> : never;
|
|
299
312
|
|
|
300
|
-
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type OptimizeBatchPatchOptions, type OptimizeBatchPatchResultItem, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, defineHooks, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
|
313
|
+
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type OptimizeBatchPatchOptions, type OptimizeBatchPatchResultItem, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, defineHooks, defineParamsForServer, defineParamsFromClient, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, paramsForServer, paramsFromClient, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ type HookForEachOptions<T = any, H = HookContext, R = any> = {
|
|
|
40
40
|
wait?: "sequential" | "parallel" | false;
|
|
41
41
|
items?: GetItemsIsArrayOptions["from"];
|
|
42
42
|
forAll?: (items: T[], context: H) => Promisable<R>;
|
|
43
|
+
skip?: (context: H) => Promisable<boolean>;
|
|
43
44
|
};
|
|
44
45
|
type ActionPerItem<T, H, R> = (item: T, options: {
|
|
45
46
|
context: H;
|
|
@@ -101,6 +102,18 @@ interface HookSetDataOptions {
|
|
|
101
102
|
*/
|
|
102
103
|
declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
|
|
103
104
|
|
|
105
|
+
declare function defineParamsForServer(keyToHide: string): (...whitelist: string[]) => <H extends HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
106
|
+
/**
|
|
107
|
+
* a hook to move params to query._$client
|
|
108
|
+
* the server only receives 'query' from params. All other params are ignored.
|
|
109
|
+
* So, to use `$populateParams` on the server, we need to move the params to query._$client
|
|
110
|
+
* the server will move them back to params
|
|
111
|
+
*/
|
|
112
|
+
declare const paramsForServer: (...whitelist: string[]) => <H extends HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
|
|
113
|
+
|
|
114
|
+
declare function defineParamsFromClient(keyToHide: string): (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
115
|
+
declare const paramsFromClient: (...whitelist: string[]) => (context: HookContext) => HookContext;
|
|
116
|
+
|
|
104
117
|
interface InitDebounceMixinOptions {
|
|
105
118
|
default: Partial<DebouncedStoreOptions>;
|
|
106
119
|
blacklist: string[];
|
|
@@ -297,4 +310,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
297
310
|
type InferDataFromPath<App extends Application, Path extends string, Method extends "create" | "update" | "patch"> = Method extends "create" ? InferCreateDataFromPath<App, Path> : Method extends "update" ? InferUpdateDataFromPath<App, Path> : Method extends "patch" ? InferPatchDataFromPath<App, Path> : never;
|
|
298
311
|
type InferResultFromPath<App extends Application, Path extends string, Method extends "get" | "find" | "create" | "update" | "patch" | "remove"> = Method extends "get" ? InferGetResultFromPath<App, Path> : Method extends "find" ? InferFindResultFromPath<App, Path> : Method extends "create" ? InferCreateResultFromPath<App, Path> : Method extends "update" ? InferUpdateResultFromPath<App, Path> : Method extends "patch" ? InferPatchResultFromPath<App, Path> : Method extends "remove" ? InferRemoveResultFromPath<App, Path> : never;
|
|
299
312
|
|
|
300
|
-
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type OptimizeBatchPatchOptions, type OptimizeBatchPatchResultItem, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, defineHooks, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
|
313
|
+
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type OptimizeBatchPatchOptions, type OptimizeBatchPatchResultItem, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, defineHooks, defineParamsForServer, defineParamsFromClient, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, paramsForServer, paramsFromClient, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
package/dist/index.mjs
CHANGED
|
@@ -674,6 +674,9 @@ const forEach = (actionPerItem, options) => {
|
|
|
674
674
|
if (shouldSkip("forEach", context)) {
|
|
675
675
|
return context;
|
|
676
676
|
}
|
|
677
|
+
if (options?.skip && await options.skip(context)) {
|
|
678
|
+
return context;
|
|
679
|
+
}
|
|
677
680
|
const { items } = getItemsIsArray(context, { from });
|
|
678
681
|
const forAll = options?.forAll ? await options.forAll(items, context) : {};
|
|
679
682
|
const promises = [];
|
|
@@ -860,6 +863,77 @@ function setData(from, to, _options) {
|
|
|
860
863
|
};
|
|
861
864
|
}
|
|
862
865
|
|
|
866
|
+
const FROM_CLIENT_FOR_SERVER_DEFAULT_KEY = "_$client";
|
|
867
|
+
|
|
868
|
+
function defineParamsForServer(keyToHide) {
|
|
869
|
+
return function paramsForServer2(...whitelist) {
|
|
870
|
+
return (context) => {
|
|
871
|
+
let clonedParams;
|
|
872
|
+
Object.keys(context.params).forEach((key) => {
|
|
873
|
+
if (key === "query") {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
if (whitelist.includes(key)) {
|
|
877
|
+
if (!clonedParams) {
|
|
878
|
+
clonedParams = {
|
|
879
|
+
...context.params,
|
|
880
|
+
query: {
|
|
881
|
+
...context.params.query
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
if (!clonedParams.query[keyToHide]) {
|
|
886
|
+
clonedParams.query[keyToHide] = {};
|
|
887
|
+
}
|
|
888
|
+
clonedParams.query[keyToHide][key] = clonedParams[key];
|
|
889
|
+
delete clonedParams[key];
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
if (clonedParams) {
|
|
893
|
+
context.params = clonedParams;
|
|
894
|
+
}
|
|
895
|
+
return context;
|
|
896
|
+
};
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
const paramsForServer = defineParamsForServer(
|
|
900
|
+
FROM_CLIENT_FOR_SERVER_DEFAULT_KEY
|
|
901
|
+
);
|
|
902
|
+
|
|
903
|
+
function defineParamsFromClient(keyToHide) {
|
|
904
|
+
return function paramsFromClient2(...whitelist) {
|
|
905
|
+
return (context) => {
|
|
906
|
+
if (!context.params?.query?.[keyToHide] || typeof context.params.query[keyToHide] !== "object") {
|
|
907
|
+
return context;
|
|
908
|
+
}
|
|
909
|
+
const params = {
|
|
910
|
+
...context.params,
|
|
911
|
+
query: {
|
|
912
|
+
...context.params.query,
|
|
913
|
+
[keyToHide]: {
|
|
914
|
+
...context.params.query[keyToHide]
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
const client = params.query[keyToHide];
|
|
919
|
+
whitelist.forEach((key) => {
|
|
920
|
+
if (key in client) {
|
|
921
|
+
params[key] = client[key];
|
|
922
|
+
delete client[key];
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
if (Object.keys(client).length === 0) {
|
|
926
|
+
delete params.query[keyToHide];
|
|
927
|
+
}
|
|
928
|
+
context.params = params;
|
|
929
|
+
return context;
|
|
930
|
+
};
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
const paramsFromClient = defineParamsFromClient(
|
|
934
|
+
FROM_CLIENT_FOR_SERVER_DEFAULT_KEY
|
|
935
|
+
);
|
|
936
|
+
|
|
863
937
|
var __defProp = Object.defineProperty;
|
|
864
938
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
865
939
|
var __publicField = (obj, key, value) => {
|
|
@@ -981,4 +1055,4 @@ const filterObject = (...keys) => {
|
|
|
981
1055
|
return result;
|
|
982
1056
|
};
|
|
983
1057
|
|
|
984
|
-
export { DebouncedStore, checkMulti, createRelated, debounceMixin, defineHooks, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
|
1058
|
+
export { DebouncedStore, checkMulti, createRelated, debounceMixin, defineHooks, defineParamsForServer, defineParamsFromClient, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, paramsForServer, paramsFromClient, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
package/package.json
CHANGED
package/src/hooks/forEach.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type HookForEachOptions<T = any, H = HookContext, R = any> = {
|
|
|
9
9
|
wait?: "sequential" | "parallel" | false;
|
|
10
10
|
items?: GetItemsIsArrayOptions["from"];
|
|
11
11
|
forAll?: (items: T[], context: H) => Promisable<R>;
|
|
12
|
+
skip?: (context: H) => Promisable<boolean>;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
type ActionPerItem<T, H, R> = (
|
|
@@ -31,6 +32,10 @@ export const forEach = <H extends HookContext = HookContext, T = any, R = any>(
|
|
|
31
32
|
return context;
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
if (options?.skip && (await options.skip(context))) {
|
|
36
|
+
return context;
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
const { items } = getItemsIsArray(context, { from });
|
|
35
40
|
|
|
36
41
|
const forAll = options?.forAll
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const FROM_CLIENT_FOR_SERVER_DEFAULT_KEY = "_$client" as const;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import { FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } from "./common";
|
|
3
|
+
|
|
4
|
+
export function defineParamsForServer(keyToHide: string) {
|
|
5
|
+
return function paramsForServer(...whitelist: string[]) {
|
|
6
|
+
return <H extends HookContext>(context: H) => {
|
|
7
|
+
// clone params on demand
|
|
8
|
+
let clonedParams;
|
|
9
|
+
|
|
10
|
+
Object.keys(context.params).forEach((key) => {
|
|
11
|
+
if (key === "query") {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (whitelist.includes(key)) {
|
|
16
|
+
if (!clonedParams) {
|
|
17
|
+
clonedParams = {
|
|
18
|
+
...context.params,
|
|
19
|
+
query: {
|
|
20
|
+
...context.params.query,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!clonedParams.query[keyToHide]) {
|
|
26
|
+
clonedParams.query[keyToHide] = {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
clonedParams.query[keyToHide][key] = clonedParams[key];
|
|
30
|
+
delete clonedParams[key];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (clonedParams) {
|
|
35
|
+
context.params = clonedParams;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return context;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* a hook to move params to query._$client
|
|
45
|
+
* the server only receives 'query' from params. All other params are ignored.
|
|
46
|
+
* So, to use `$populateParams` on the server, we need to move the params to query._$client
|
|
47
|
+
* the server will move them back to params
|
|
48
|
+
*/
|
|
49
|
+
export const paramsForServer = defineParamsForServer(
|
|
50
|
+
FROM_CLIENT_FOR_SERVER_DEFAULT_KEY,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (import.meta.vitest) {
|
|
54
|
+
const { it, expect } = import.meta.vitest;
|
|
55
|
+
|
|
56
|
+
it("should move params to query._$client", () => {
|
|
57
|
+
expect(
|
|
58
|
+
paramsForServer(
|
|
59
|
+
"a",
|
|
60
|
+
"b",
|
|
61
|
+
)({
|
|
62
|
+
params: {
|
|
63
|
+
a: 1,
|
|
64
|
+
b: 2,
|
|
65
|
+
query: {},
|
|
66
|
+
},
|
|
67
|
+
} as HookContext),
|
|
68
|
+
).toEqual({
|
|
69
|
+
params: {
|
|
70
|
+
query: {
|
|
71
|
+
_$client: {
|
|
72
|
+
a: 1,
|
|
73
|
+
b: 2,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("should move params to query._$client and leave remaining", () => {
|
|
81
|
+
expect(
|
|
82
|
+
paramsForServer("a")({
|
|
83
|
+
params: {
|
|
84
|
+
a: 1,
|
|
85
|
+
b: 2,
|
|
86
|
+
query: {},
|
|
87
|
+
},
|
|
88
|
+
} as HookContext),
|
|
89
|
+
).toEqual({
|
|
90
|
+
params: {
|
|
91
|
+
b: 2,
|
|
92
|
+
query: {
|
|
93
|
+
_$client: {
|
|
94
|
+
a: 1,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { HookContext } from "@feathersjs/feathers";
|
|
2
|
+
import { FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } from "./common";
|
|
3
|
+
|
|
4
|
+
export function defineParamsFromClient(keyToHide: string) {
|
|
5
|
+
return function paramsFromClient(
|
|
6
|
+
...whitelist: string[]
|
|
7
|
+
): (context: HookContext) => HookContext {
|
|
8
|
+
return (context: HookContext): HookContext => {
|
|
9
|
+
if (
|
|
10
|
+
!context.params?.query?.[keyToHide] ||
|
|
11
|
+
typeof context.params.query[keyToHide] !== "object"
|
|
12
|
+
) {
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const params = {
|
|
17
|
+
...context.params,
|
|
18
|
+
query: {
|
|
19
|
+
...context.params.query,
|
|
20
|
+
[keyToHide]: {
|
|
21
|
+
...context.params.query[keyToHide],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const client = params.query[keyToHide];
|
|
27
|
+
|
|
28
|
+
whitelist.forEach((key) => {
|
|
29
|
+
if (key in client) {
|
|
30
|
+
params[key] = client[key];
|
|
31
|
+
delete client[key];
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (Object.keys(client).length === 0) {
|
|
36
|
+
delete params.query[keyToHide];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
context.params = params;
|
|
40
|
+
|
|
41
|
+
return context;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const paramsFromClient = defineParamsFromClient(
|
|
47
|
+
FROM_CLIENT_FOR_SERVER_DEFAULT_KEY,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
if (import.meta.vitest) {
|
|
51
|
+
const { it, expect } = import.meta.vitest;
|
|
52
|
+
|
|
53
|
+
it("should move params to query._$client", () => {
|
|
54
|
+
expect(
|
|
55
|
+
paramsFromClient(
|
|
56
|
+
"a",
|
|
57
|
+
"b",
|
|
58
|
+
)({
|
|
59
|
+
params: {
|
|
60
|
+
query: {
|
|
61
|
+
_$client: {
|
|
62
|
+
a: 1,
|
|
63
|
+
b: 2,
|
|
64
|
+
},
|
|
65
|
+
c: 3,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
} as HookContext),
|
|
69
|
+
).toEqual({
|
|
70
|
+
params: {
|
|
71
|
+
a: 1,
|
|
72
|
+
b: 2,
|
|
73
|
+
query: {
|
|
74
|
+
c: 3,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("should move params to query._$client and leave remaining", () => {
|
|
81
|
+
expect(
|
|
82
|
+
paramsFromClient("a")({
|
|
83
|
+
params: {
|
|
84
|
+
query: {
|
|
85
|
+
_$client: {
|
|
86
|
+
a: 1,
|
|
87
|
+
b: 2,
|
|
88
|
+
},
|
|
89
|
+
c: 3,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
} as HookContext),
|
|
93
|
+
).toEqual({
|
|
94
|
+
params: {
|
|
95
|
+
a: 1,
|
|
96
|
+
query: {
|
|
97
|
+
_$client: {
|
|
98
|
+
b: 2,
|
|
99
|
+
},
|
|
100
|
+
c: 3,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
package/src/hooks/index.ts
CHANGED