feathers-utils 3.0.3 → 3.1.1

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.
Files changed (38) hide show
  1. package/README.md +3 -0
  2. package/dist/index.cjs +49 -3
  3. package/dist/index.d.cts +269 -0
  4. package/dist/index.d.mts +269 -0
  5. package/dist/index.d.ts +7 -2
  6. package/dist/index.mjs +49 -4
  7. package/package.json +23 -27
  8. package/src/filters/array.ts +1 -1
  9. package/src/filters/object.ts +1 -1
  10. package/src/hooks/createRelated.ts +3 -3
  11. package/src/hooks/forEach.ts +10 -8
  12. package/src/hooks/index.ts +0 -1
  13. package/src/hooks/onDelete.ts +2 -2
  14. package/src/hooks/parseFields.ts +20 -18
  15. package/src/hooks/removeRelated.ts +1 -1
  16. package/src/hooks/runPerItem.ts +2 -2
  17. package/src/hooks/setData.ts +1 -1
  18. package/src/mixins/debounce-mixin/DebouncedStore.ts +2 -2
  19. package/src/mixins/debounce-mixin/debounceMixin.ts +4 -4
  20. package/src/types.ts +1 -1
  21. package/src/typesInternal.ts +10 -4
  22. package/src/utility-types/index.ts +88 -42
  23. package/src/utils/getItemsIsArray.ts +12 -15
  24. package/src/utils/getPaginate.ts +1 -1
  25. package/src/utils/index.ts +1 -0
  26. package/src/utils/internal.utils.ts +3 -0
  27. package/src/utils/isMulti.ts +1 -1
  28. package/src/utils/isPaginated.ts +1 -1
  29. package/src/utils/markHookForSkip.ts +1 -1
  30. package/src/utils/mergeQuery/mergeArrays.ts +2 -2
  31. package/src/utils/mergeQuery/mergeQuery.ts +1 -1
  32. package/src/utils/mergeQuery/types.ts +1 -1
  33. package/src/utils/mergeQuery/utils.ts +11 -11
  34. package/src/utils/pushSet.ts +1 -1
  35. package/src/utils/setQueryKeySafely.ts +56 -0
  36. package/src/utils/setResultEmpty.ts +1 -1
  37. package/src/utils/shouldSkip.ts +1 -1
  38. package/src/utils/validateQueryProperty.ts +1 -1
package/README.md CHANGED
@@ -23,7 +23,9 @@ npm i feathers-utils
23
23
 
24
24
  - `checkMulti`: throws if the request is **multi** data, but the services `allowsMulti(method)` returns `false`
25
25
  - `createRelated`: simply create related items from a hook.
26
+ - `forEach`
26
27
  - `onDelete`: simply remove/set null related items from a hook.
28
+ - `parseFields`
27
29
  - `removeRelated`: simple remove related items from a hook. Basically `cascade` at feathers level.
28
30
  - `runPerItem`: run a function for every item. Meant for `multi:true`.
29
31
  - `setData`: map properties from `context` to `data`. Something like `userId: context.params.user.id`
@@ -43,5 +45,6 @@ npm i feathers-utils
43
45
  - `mergeQuery`: deeply merges queries
44
46
  - `mergeArrays`: merges arrays with intersection options
45
47
  - `pushSet`: if existing array: *push*, else *set*
48
+ - `setQueryKeySafely`
46
49
  - `setResultEmpty`
47
50
  - `shouldSkip`: checks `context.params.skipHooks` for `'all' | '${hookName}' | '${type}:${hookName}'` - also see `markHookForSkip`
package/dist/index.cjs CHANGED
@@ -69,6 +69,7 @@ function mergeArrays(targetArr, sourceArr, handle, prependKey, actionOnEmptyInte
69
69
  const hasOwnProperty = (obj, ...keys) => {
70
70
  return keys.some((x) => Object.prototype.hasOwnProperty.call(obj, x));
71
71
  };
72
+ const isPlainObject$1 = (value) => value && [void 0, Object].includes(value.constructor);
72
73
 
73
74
  function handleArray(target, source, key, options) {
74
75
  const targetVal = _get__default(target, key);
@@ -454,9 +455,7 @@ function mergeQuery(target, source, _options) {
454
455
  }
455
456
 
456
457
  const getItemsIsArray = (context, options) => {
457
- const {
458
- from = "automatic"
459
- } = options || {};
458
+ const { from = "automatic" } = options || {};
460
459
  let itemOrItems;
461
460
  if (from === "automatic") {
462
461
  itemOrItems = context.type === "before" ? context.data : context.result;
@@ -608,6 +607,40 @@ const toJSON = (context) => {
608
607
  return context;
609
608
  };
610
609
 
610
+ const setQueryKeySafely = (params, key, value, operator = "$eq", options) => {
611
+ var _a;
612
+ const { mutate = false } = options || {};
613
+ if (!mutate) {
614
+ params = structuredClone(params);
615
+ }
616
+ if (!params.query) {
617
+ params.query = {};
618
+ }
619
+ if (!(key in params.query)) {
620
+ if (operator === "$eq") {
621
+ params.query[key] = value;
622
+ } else {
623
+ params.query[key] = {
624
+ [operator]: value
625
+ };
626
+ }
627
+ return params;
628
+ }
629
+ if (isPlainObject$1(params.query[key]) && !(operator in params.query[key])) {
630
+ params.query[key][operator] = value;
631
+ } else {
632
+ (_a = params.query).$and ?? (_a.$and = []);
633
+ params.query.$and.push(
634
+ operator === "$eq" ? { [key]: value } : {
635
+ [key]: {
636
+ [operator]: value
637
+ }
638
+ }
639
+ );
640
+ }
641
+ return params;
642
+ };
643
+
611
644
  function checkMulti() {
612
645
  return (context) => {
613
646
  if (shouldSkip("checkMulti", context)) {
@@ -848,6 +881,12 @@ function setData(from, to, _options) {
848
881
  };
849
882
  }
850
883
 
884
+ var __defProp = Object.defineProperty;
885
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
886
+ var __publicField = (obj, key, value) => {
887
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
888
+ return value;
889
+ };
851
890
  const makeDefaultOptions = () => {
852
891
  return {
853
892
  leading: false,
@@ -858,6 +897,12 @@ const makeDefaultOptions = () => {
858
897
  };
859
898
  class DebouncedStore {
860
899
  constructor(app, options) {
900
+ __publicField(this, "_app");
901
+ __publicField(this, "_options");
902
+ __publicField(this, "_isRunningById");
903
+ __publicField(this, "_queueById");
904
+ //_waitingById: Record<string, WaitingObject>;
905
+ __publicField(this, "add");
861
906
  this._app = app;
862
907
  this._options = Object.assign(makeDefaultOptions(), options);
863
908
  this._queueById = {};
@@ -979,6 +1024,7 @@ exports.pushSet = pushSet;
979
1024
  exports.removeRelated = removeRelated;
980
1025
  exports.runPerItem = runPerItem;
981
1026
  exports.setData = setData;
1027
+ exports.setQueryKeySafely = setQueryKeySafely;
982
1028
  exports.setResultEmpty = setResultEmpty;
983
1029
  exports.shouldSkip = shouldSkip;
984
1030
  exports.toJSON = toJSON;
@@ -0,0 +1,269 @@
1
+ import * as _feathersjs_feathers from '@feathersjs/feathers';
2
+ import { HookContext, Application, Id, Query, Params } from '@feathersjs/feathers';
3
+ import { HookContext as HookContext$1, Application as Application$1 } from '@feathersjs/feathers/lib';
4
+ import { PropertyPath, DebouncedFunc } from 'lodash';
5
+ import { AdapterBase, FilterQueryOptions as FilterQueryOptions$1, PaginationOptions } from '@feathersjs/adapter-commons';
6
+ import { HookType } from 'feathers-hooks-common';
7
+
8
+ /**
9
+ * hook to check if context is multi patch/remove and if the service allows it
10
+ */
11
+ declare function checkMulti<H extends HookContext = HookContext>(): (context: H) => H;
12
+
13
+ type MaybeArray<T> = T | T[];
14
+ type Promisable<T> = T | Promise<T>;
15
+ type Path = Array<string | number>;
16
+ type ReturnAsyncHook = (context: HookContext$1) => Promise<HookContext$1>;
17
+
18
+ interface CreateRelatedOptions<S = Record<string, any>> {
19
+ service: keyof S;
20
+ multi?: boolean;
21
+ data: (item: any, context: HookContext) => Promisable<Record<string, any>>;
22
+ createItemsInDataArraySeparately?: boolean;
23
+ }
24
+ /**
25
+ * hook to create related items
26
+ */
27
+ declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, multi, data, createItemsInDataArraySeparately, }: CreateRelatedOptions<S>): (context: H) => Promise<H>;
28
+
29
+ type GetItemsIsArrayOptions = {
30
+ from: "data" | "result" | "automatic";
31
+ };
32
+ interface GetItemsIsArrayResult<T = any> {
33
+ items: T[];
34
+ isArray: boolean;
35
+ }
36
+ declare const getItemsIsArray: <T = any, H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H, options?: GetItemsIsArrayOptions) => GetItemsIsArrayResult<T>;
37
+
38
+ interface HookForEachOptions {
39
+ wait?: "sequential" | "parallel" | false;
40
+ items?: GetItemsIsArrayOptions["from"];
41
+ }
42
+ declare const forEach: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookForEachOptions) => ReturnAsyncHook;
43
+
44
+ type OnDeleteAction = "cascade" | "set null";
45
+ interface OnDeleteOptions {
46
+ keyThere: string;
47
+ keyHere: string;
48
+ onDelete: OnDeleteAction;
49
+ blocking?: boolean;
50
+ }
51
+ /**
52
+ * hook to manipulate related items on delete
53
+ */
54
+ declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(service: keyof S, { keyThere, keyHere, onDelete, blocking, }: OnDeleteOptions): (context: H) => Promise<H>;
55
+
56
+ /**
57
+ * Parse fields to date or number
58
+ * skips undefined fields
59
+ */
60
+ declare const parseFields: (type: "date" | "number", options: {
61
+ fields: string[];
62
+ }) => (context: HookContext) => HookContext<_feathersjs_feathers.Application<any, any>, any>;
63
+
64
+ interface RemoveRelatedOptions<S = Record<string, any>> {
65
+ service: keyof S;
66
+ keyThere: string;
67
+ keyHere: string;
68
+ blocking?: boolean;
69
+ }
70
+ /**
71
+ * hook to remove related items
72
+ */
73
+ declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
74
+
75
+ interface HookRunPerItemOptions {
76
+ wait?: boolean;
77
+ }
78
+ /**
79
+ * hook to run a hook for each item in the context
80
+ * uses `context.result` if it is existent. otherwise uses context.data
81
+ */
82
+ declare const runPerItem: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(actionPerItem: (item: any, context: H) => Promisable<any>, _options?: HookRunPerItemOptions) => (context: H) => Promise<H>;
83
+
84
+ type Predicate<T = any> = (item: T) => boolean;
85
+ type PredicateWithContext<T = any> = (item: T, context: HookContext) => boolean;
86
+
87
+ interface HookSetDataOptions {
88
+ allowUndefined?: boolean;
89
+ overwrite?: boolean | PredicateWithContext;
90
+ }
91
+ /**
92
+ * hook to set properties on `context.result` (if existent) or `context.data` (otherwise)
93
+ */
94
+ declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
95
+
96
+ interface InitDebounceMixinOptions {
97
+ default: Partial<DebouncedStoreOptions>;
98
+ blacklist: string[];
99
+ [key: string]: unknown;
100
+ }
101
+ type DebouncedFunctionApp = (app?: Application) => void | Promise<void>;
102
+ interface DebouncedStoreOptions {
103
+ leading: boolean;
104
+ maxWait: number | undefined;
105
+ trailing: boolean;
106
+ wait: number;
107
+ }
108
+
109
+ declare const makeDefaultOptions: () => DebouncedStoreOptions;
110
+ type DebouncedService<T = any> = T & {
111
+ debouncedStore: DebouncedStore;
112
+ };
113
+ declare class DebouncedStore {
114
+ private _app;
115
+ private _options;
116
+ private _isRunningById;
117
+ _queueById: Record<string, DebouncedFunc<(id: Id, action: DebouncedFunctionApp) => void | Promise<void>>>;
118
+ add: any;
119
+ constructor(app: Application, options?: Partial<DebouncedStoreOptions>);
120
+ private unbounced;
121
+ private debounceById;
122
+ cancel(id: Id): void;
123
+ }
124
+
125
+ declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
126
+
127
+ interface FilterQueryOptions<T> {
128
+ service?: AdapterBase<T>;
129
+ operators?: FilterQueryOptions$1["operators"];
130
+ filters?: FilterQueryOptions$1["filters"];
131
+ }
132
+ declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
133
+
134
+ type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
135
+ type FirstLast = "first" | "last";
136
+ type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
137
+ interface MergeQueryOptions<T> extends FilterQueryOptions<T> {
138
+ defaultHandle: Handle;
139
+ actionOnEmptyIntersect: ActionOnEmptyIntersect;
140
+ useLogicalConjunction: boolean;
141
+ handle?: {
142
+ [key: string]: Handle;
143
+ };
144
+ }
145
+
146
+ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | undefined, handle: Handle, prependKey?: Path, actionOnEmptyIntersect?: ActionOnEmptyIntersect): T[] | undefined;
147
+
148
+ /**
149
+ * Merges two queries into one.
150
+ * @param target Query to be merged into
151
+ * @param source Query to be merged from
152
+ * @param _options
153
+ * @returns Query
154
+ */
155
+ declare function mergeQuery<T = any>(target: Query, source: Query, _options?: Partial<MergeQueryOptions<T>>): Query;
156
+
157
+ /**
158
+ * util to get paginate options from context
159
+ * 1. it uses `context.params.paginate` if it exists
160
+ * 2. it uses `service.options.paginate` if it exists
161
+ * 3. it uses `context.params.adapter` if it exists
162
+ */
163
+ declare const getPaginate: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => PaginationOptions | undefined;
164
+
165
+ /**
166
+ * util to check if a hook is a multi hook:
167
+ * - find: true
168
+ * - get: false
169
+ * - create: `context.data` is an array
170
+ * - update: false
171
+ * - patch: `context.id == null`
172
+ * - remove: `context.id == null`
173
+ */
174
+ declare const isMulti: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
175
+
176
+ /**
177
+ * util to check if a hook is a paginated hook using `getPaginate`
178
+ */
179
+ declare const isPaginated: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
180
+
181
+ /**
182
+ * util to mark a hook for skip, has to be used with `shouldSkip`
183
+ */
184
+ declare function markHookForSkip<H extends HookContext = HookContext>(hookName: string, type: "all" | MaybeArray<HookType>, context?: H): H;
185
+
186
+ interface PushSetOptions {
187
+ unique?: boolean;
188
+ }
189
+ /**
190
+ * util to push a value to an array at a given path in an object
191
+ */
192
+ declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val: unknown, options?: PushSetOptions) => unknown[];
193
+
194
+ /**
195
+ * util to set `context.result` to an empty array or object, depending on the hook type
196
+ */
197
+ declare const setResultEmpty: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
198
+
199
+ type ShouldSkipOptions = {
200
+ notSkippable?: boolean;
201
+ };
202
+ /**
203
+ * util to detect if a hook should be skipped
204
+ */
205
+ declare const shouldSkip: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(hookName: string, context: H, options?: ShouldSkipOptions) => boolean;
206
+
207
+ /**
208
+ * util to validate a query for operators
209
+ */
210
+ declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
211
+
212
+ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers.Application<any, any>, any>;
213
+
214
+ type SetQueryKeySafelyOptions = {
215
+ mutate?: boolean;
216
+ };
217
+ declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
218
+
219
+ declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions$1) => any; };
220
+
221
+ declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions$1) => any; };
222
+
223
+ type Single<T> = T extends Array<infer U> ? U : T;
224
+ type AsArray<T> = T extends any[] ? T : [T];
225
+ type InferCreateData<S> = S extends {
226
+ create: (data: infer D, params: any) => any;
227
+ } ? D : never;
228
+ type InferCreateDataSingle<S> = Single<InferCreateData<S>>;
229
+ type InferUpdateData<S> = S extends {
230
+ update: (id: any, data: infer D, params: any) => any;
231
+ } ? D : never;
232
+ type InferPatchData<S> = S extends {
233
+ patch: (id: any, data: infer D, params: any) => any;
234
+ } ? D : never;
235
+ type InferGetResult<S> = S extends {
236
+ get: (id: any, params: any) => infer R;
237
+ } ? Awaited<R> : never;
238
+ type InferFindResult<S> = S extends {
239
+ find: (params: any) => infer R;
240
+ } ? Awaited<R> : never;
241
+ type InferCreateResult<S, D = unknown> = S extends {
242
+ create: (data: any, params: any) => infer R;
243
+ } ? D extends any[] ? AsArray<Awaited<R>> : D extends InferCreateDataSingle<S> ? Single<Awaited<R>> : Awaited<R> : never;
244
+ type InferCreateResultSingle<S> = Single<InferCreateResult<S>>;
245
+ type InferUpdateResult<S> = S extends {
246
+ update: (id: any, data: any, params: any) => infer R;
247
+ } ? Awaited<R> : never;
248
+ type InferPatchResult<S, IdOrNullable = any> = S extends {
249
+ patch: (id: Id, data: any, params: any) => infer R;
250
+ } ? IdOrNullable extends Id ? Single<Awaited<R>> : IdOrNullable extends null ? AsArray<Awaited<R>> : Awaited<R> : never;
251
+ type InferRemoveResult<S, IdOrNullable = any> = S extends {
252
+ remove: (id: IdOrNullable, params: any) => infer R;
253
+ } ? IdOrNullable extends Id ? Single<Awaited<R>> : IdOrNullable extends null ? AsArray<Awaited<R>> : Awaited<R> : never;
254
+ type GetService<App extends Application, Path extends string> = App["services"][Path];
255
+ type InferGetResultFromPath<App extends Application, Path extends string> = InferGetResult<GetService<App, Path>>;
256
+ type InferFindResultFromPath<App extends Application, Path extends string> = InferFindResult<GetService<App, Path>>;
257
+ type InferCreateDataFromPath<App extends Application, Path extends string> = InferCreateData<GetService<App, Path>>;
258
+ type InferCreateDataSingleFromPath<App extends Application, Path extends string> = InferCreateDataSingle<GetService<App, Path>>;
259
+ type InferCreateResultFromPath<App extends Application, Path extends string, D = unknown> = InferCreateResult<GetService<App, Path>, D>;
260
+ type InferCreateResultSingleFromPath<App extends Application, Path extends string> = InferCreateResultSingle<GetService<App, Path>>;
261
+ type InferUpdateDataFromPath<App extends Application, Path extends string> = InferUpdateData<GetService<App, Path>>;
262
+ type InferPatchDataFromPath<App extends Application, Path extends string> = InferPatchData<GetService<App, Path>>;
263
+ type InferUpdateResultFromPath<App extends Application, Path extends string> = InferUpdateResult<GetService<App, Path>>;
264
+ type InferPatchResultFromPath<App extends Application, Path extends string, IdOrNullable = any> = InferPatchResult<GetService<App, Path>, IdOrNullable>;
265
+ type InferRemoveResultFromPath<App extends Application, Path extends string, IdOrNullable = any> = InferRemoveResult<GetService<App, Path>, IdOrNullable>;
266
+ 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;
267
+ 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;
268
+
269
+ export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FilterQueryOptions, type FirstLast, 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 Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
@@ -0,0 +1,269 @@
1
+ import * as _feathersjs_feathers from '@feathersjs/feathers';
2
+ import { HookContext, Application, Id, Query, Params } from '@feathersjs/feathers';
3
+ import { HookContext as HookContext$1, Application as Application$1 } from '@feathersjs/feathers/lib';
4
+ import { PropertyPath, DebouncedFunc } from 'lodash';
5
+ import { AdapterBase, FilterQueryOptions as FilterQueryOptions$1, PaginationOptions } from '@feathersjs/adapter-commons';
6
+ import { HookType } from 'feathers-hooks-common';
7
+
8
+ /**
9
+ * hook to check if context is multi patch/remove and if the service allows it
10
+ */
11
+ declare function checkMulti<H extends HookContext = HookContext>(): (context: H) => H;
12
+
13
+ type MaybeArray<T> = T | T[];
14
+ type Promisable<T> = T | Promise<T>;
15
+ type Path = Array<string | number>;
16
+ type ReturnAsyncHook = (context: HookContext$1) => Promise<HookContext$1>;
17
+
18
+ interface CreateRelatedOptions<S = Record<string, any>> {
19
+ service: keyof S;
20
+ multi?: boolean;
21
+ data: (item: any, context: HookContext) => Promisable<Record<string, any>>;
22
+ createItemsInDataArraySeparately?: boolean;
23
+ }
24
+ /**
25
+ * hook to create related items
26
+ */
27
+ declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, multi, data, createItemsInDataArraySeparately, }: CreateRelatedOptions<S>): (context: H) => Promise<H>;
28
+
29
+ type GetItemsIsArrayOptions = {
30
+ from: "data" | "result" | "automatic";
31
+ };
32
+ interface GetItemsIsArrayResult<T = any> {
33
+ items: T[];
34
+ isArray: boolean;
35
+ }
36
+ declare const getItemsIsArray: <T = any, H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H, options?: GetItemsIsArrayOptions) => GetItemsIsArrayResult<T>;
37
+
38
+ interface HookForEachOptions {
39
+ wait?: "sequential" | "parallel" | false;
40
+ items?: GetItemsIsArrayOptions["from"];
41
+ }
42
+ declare const forEach: (actionPerItem: (item: any, context: HookContext) => Promisable<any>, _options?: HookForEachOptions) => ReturnAsyncHook;
43
+
44
+ type OnDeleteAction = "cascade" | "set null";
45
+ interface OnDeleteOptions {
46
+ keyThere: string;
47
+ keyHere: string;
48
+ onDelete: OnDeleteAction;
49
+ blocking?: boolean;
50
+ }
51
+ /**
52
+ * hook to manipulate related items on delete
53
+ */
54
+ declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(service: keyof S, { keyThere, keyHere, onDelete, blocking, }: OnDeleteOptions): (context: H) => Promise<H>;
55
+
56
+ /**
57
+ * Parse fields to date or number
58
+ * skips undefined fields
59
+ */
60
+ declare const parseFields: (type: "date" | "number", options: {
61
+ fields: string[];
62
+ }) => (context: HookContext) => HookContext<_feathersjs_feathers.Application<any, any>, any>;
63
+
64
+ interface RemoveRelatedOptions<S = Record<string, any>> {
65
+ service: keyof S;
66
+ keyThere: string;
67
+ keyHere: string;
68
+ blocking?: boolean;
69
+ }
70
+ /**
71
+ * hook to remove related items
72
+ */
73
+ declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
74
+
75
+ interface HookRunPerItemOptions {
76
+ wait?: boolean;
77
+ }
78
+ /**
79
+ * hook to run a hook for each item in the context
80
+ * uses `context.result` if it is existent. otherwise uses context.data
81
+ */
82
+ declare const runPerItem: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(actionPerItem: (item: any, context: H) => Promisable<any>, _options?: HookRunPerItemOptions) => (context: H) => Promise<H>;
83
+
84
+ type Predicate<T = any> = (item: T) => boolean;
85
+ type PredicateWithContext<T = any> = (item: T, context: HookContext) => boolean;
86
+
87
+ interface HookSetDataOptions {
88
+ allowUndefined?: boolean;
89
+ overwrite?: boolean | PredicateWithContext;
90
+ }
91
+ /**
92
+ * hook to set properties on `context.result` (if existent) or `context.data` (otherwise)
93
+ */
94
+ declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
95
+
96
+ interface InitDebounceMixinOptions {
97
+ default: Partial<DebouncedStoreOptions>;
98
+ blacklist: string[];
99
+ [key: string]: unknown;
100
+ }
101
+ type DebouncedFunctionApp = (app?: Application) => void | Promise<void>;
102
+ interface DebouncedStoreOptions {
103
+ leading: boolean;
104
+ maxWait: number | undefined;
105
+ trailing: boolean;
106
+ wait: number;
107
+ }
108
+
109
+ declare const makeDefaultOptions: () => DebouncedStoreOptions;
110
+ type DebouncedService<T = any> = T & {
111
+ debouncedStore: DebouncedStore;
112
+ };
113
+ declare class DebouncedStore {
114
+ private _app;
115
+ private _options;
116
+ private _isRunningById;
117
+ _queueById: Record<string, DebouncedFunc<(id: Id, action: DebouncedFunctionApp) => void | Promise<void>>>;
118
+ add: any;
119
+ constructor(app: Application, options?: Partial<DebouncedStoreOptions>);
120
+ private unbounced;
121
+ private debounceById;
122
+ cancel(id: Id): void;
123
+ }
124
+
125
+ declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
126
+
127
+ interface FilterQueryOptions<T> {
128
+ service?: AdapterBase<T>;
129
+ operators?: FilterQueryOptions$1["operators"];
130
+ filters?: FilterQueryOptions$1["filters"];
131
+ }
132
+ declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
133
+
134
+ type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
135
+ type FirstLast = "first" | "last";
136
+ type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
137
+ interface MergeQueryOptions<T> extends FilterQueryOptions<T> {
138
+ defaultHandle: Handle;
139
+ actionOnEmptyIntersect: ActionOnEmptyIntersect;
140
+ useLogicalConjunction: boolean;
141
+ handle?: {
142
+ [key: string]: Handle;
143
+ };
144
+ }
145
+
146
+ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | undefined, handle: Handle, prependKey?: Path, actionOnEmptyIntersect?: ActionOnEmptyIntersect): T[] | undefined;
147
+
148
+ /**
149
+ * Merges two queries into one.
150
+ * @param target Query to be merged into
151
+ * @param source Query to be merged from
152
+ * @param _options
153
+ * @returns Query
154
+ */
155
+ declare function mergeQuery<T = any>(target: Query, source: Query, _options?: Partial<MergeQueryOptions<T>>): Query;
156
+
157
+ /**
158
+ * util to get paginate options from context
159
+ * 1. it uses `context.params.paginate` if it exists
160
+ * 2. it uses `service.options.paginate` if it exists
161
+ * 3. it uses `context.params.adapter` if it exists
162
+ */
163
+ declare const getPaginate: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => PaginationOptions | undefined;
164
+
165
+ /**
166
+ * util to check if a hook is a multi hook:
167
+ * - find: true
168
+ * - get: false
169
+ * - create: `context.data` is an array
170
+ * - update: false
171
+ * - patch: `context.id == null`
172
+ * - remove: `context.id == null`
173
+ */
174
+ declare const isMulti: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
175
+
176
+ /**
177
+ * util to check if a hook is a paginated hook using `getPaginate`
178
+ */
179
+ declare const isPaginated: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => boolean;
180
+
181
+ /**
182
+ * util to mark a hook for skip, has to be used with `shouldSkip`
183
+ */
184
+ declare function markHookForSkip<H extends HookContext = HookContext>(hookName: string, type: "all" | MaybeArray<HookType>, context?: H): H;
185
+
186
+ interface PushSetOptions {
187
+ unique?: boolean;
188
+ }
189
+ /**
190
+ * util to push a value to an array at a given path in an object
191
+ */
192
+ declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val: unknown, options?: PushSetOptions) => unknown[];
193
+
194
+ /**
195
+ * util to set `context.result` to an empty array or object, depending on the hook type
196
+ */
197
+ declare const setResultEmpty: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(context: H) => H;
198
+
199
+ type ShouldSkipOptions = {
200
+ notSkippable?: boolean;
201
+ };
202
+ /**
203
+ * util to detect if a hook should be skipped
204
+ */
205
+ declare const shouldSkip: <H extends HookContext<_feathersjs_feathers.Application<any, any>, any> = HookContext<_feathersjs_feathers.Application<any, any>, any>>(hookName: string, context: H, options?: ShouldSkipOptions) => boolean;
206
+
207
+ /**
208
+ * util to validate a query for operators
209
+ */
210
+ declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
211
+
212
+ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers.Application<any, any>, any>;
213
+
214
+ type SetQueryKeySafelyOptions = {
215
+ mutate?: boolean;
216
+ };
217
+ declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
218
+
219
+ declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions$1) => any; };
220
+
221
+ declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions$1) => any; };
222
+
223
+ type Single<T> = T extends Array<infer U> ? U : T;
224
+ type AsArray<T> = T extends any[] ? T : [T];
225
+ type InferCreateData<S> = S extends {
226
+ create: (data: infer D, params: any) => any;
227
+ } ? D : never;
228
+ type InferCreateDataSingle<S> = Single<InferCreateData<S>>;
229
+ type InferUpdateData<S> = S extends {
230
+ update: (id: any, data: infer D, params: any) => any;
231
+ } ? D : never;
232
+ type InferPatchData<S> = S extends {
233
+ patch: (id: any, data: infer D, params: any) => any;
234
+ } ? D : never;
235
+ type InferGetResult<S> = S extends {
236
+ get: (id: any, params: any) => infer R;
237
+ } ? Awaited<R> : never;
238
+ type InferFindResult<S> = S extends {
239
+ find: (params: any) => infer R;
240
+ } ? Awaited<R> : never;
241
+ type InferCreateResult<S, D = unknown> = S extends {
242
+ create: (data: any, params: any) => infer R;
243
+ } ? D extends any[] ? AsArray<Awaited<R>> : D extends InferCreateDataSingle<S> ? Single<Awaited<R>> : Awaited<R> : never;
244
+ type InferCreateResultSingle<S> = Single<InferCreateResult<S>>;
245
+ type InferUpdateResult<S> = S extends {
246
+ update: (id: any, data: any, params: any) => infer R;
247
+ } ? Awaited<R> : never;
248
+ type InferPatchResult<S, IdOrNullable = any> = S extends {
249
+ patch: (id: Id, data: any, params: any) => infer R;
250
+ } ? IdOrNullable extends Id ? Single<Awaited<R>> : IdOrNullable extends null ? AsArray<Awaited<R>> : Awaited<R> : never;
251
+ type InferRemoveResult<S, IdOrNullable = any> = S extends {
252
+ remove: (id: IdOrNullable, params: any) => infer R;
253
+ } ? IdOrNullable extends Id ? Single<Awaited<R>> : IdOrNullable extends null ? AsArray<Awaited<R>> : Awaited<R> : never;
254
+ type GetService<App extends Application, Path extends string> = App["services"][Path];
255
+ type InferGetResultFromPath<App extends Application, Path extends string> = InferGetResult<GetService<App, Path>>;
256
+ type InferFindResultFromPath<App extends Application, Path extends string> = InferFindResult<GetService<App, Path>>;
257
+ type InferCreateDataFromPath<App extends Application, Path extends string> = InferCreateData<GetService<App, Path>>;
258
+ type InferCreateDataSingleFromPath<App extends Application, Path extends string> = InferCreateDataSingle<GetService<App, Path>>;
259
+ type InferCreateResultFromPath<App extends Application, Path extends string, D = unknown> = InferCreateResult<GetService<App, Path>, D>;
260
+ type InferCreateResultSingleFromPath<App extends Application, Path extends string> = InferCreateResultSingle<GetService<App, Path>>;
261
+ type InferUpdateDataFromPath<App extends Application, Path extends string> = InferUpdateData<GetService<App, Path>>;
262
+ type InferPatchDataFromPath<App extends Application, Path extends string> = InferPatchData<GetService<App, Path>>;
263
+ type InferUpdateResultFromPath<App extends Application, Path extends string> = InferUpdateResult<GetService<App, Path>>;
264
+ type InferPatchResultFromPath<App extends Application, Path extends string, IdOrNullable = any> = InferPatchResult<GetService<App, Path>, IdOrNullable>;
265
+ type InferRemoveResultFromPath<App extends Application, Path extends string, IdOrNullable = any> = InferRemoveResult<GetService<App, Path>, IdOrNullable>;
266
+ 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;
267
+ 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;
268
+
269
+ export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FilterQueryOptions, type FirstLast, 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 Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };