feathers-utils 2.0.0-9 → 2.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.
Files changed (156) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -1
  3. package/dist/index.cjs +964 -0
  4. package/dist/index.d.ts +262 -5
  5. package/dist/index.mjs +938 -0
  6. package/package.json +35 -38
  7. package/src/filters/object.ts +1 -1
  8. package/src/hooks/forEach.ts +47 -0
  9. package/src/hooks/index.ts +3 -0
  10. package/src/hooks/makeSequelizeQuery.ts_ +4 -4
  11. package/src/hooks/parseFields.ts +27 -0
  12. package/src/hooks/runPerItem.ts +4 -6
  13. package/src/hooks/setData.ts +4 -5
  14. package/src/index.ts +1 -0
  15. package/src/typesInternal.ts +7 -0
  16. package/src/utility-types/index.ts +116 -0
  17. package/src/utils/getItemsIsArray.ts +27 -11
  18. package/src/utils/getPaginate.ts +2 -1
  19. package/src/utils/internal.utils.ts +6 -0
  20. package/src/utils/mergeQuery/mergeQuery.ts +62 -25
  21. package/src/utils/mergeQuery/utils.ts +82 -29
  22. package/dist/esm/filters/array.d.ts +0 -2
  23. package/dist/esm/filters/array.js +0 -17
  24. package/dist/esm/filters/index.d.ts +0 -2
  25. package/dist/esm/filters/index.js +0 -2
  26. package/dist/esm/filters/object.d.ts +0 -2
  27. package/dist/esm/filters/object.js +0 -15
  28. package/dist/esm/hooks/checkMulti.d.ts +0 -5
  29. package/dist/esm/hooks/checkMulti.js +0 -20
  30. package/dist/esm/hooks/createRelated.d.ts +0 -12
  31. package/dist/esm/hooks/createRelated.js +0 -31
  32. package/dist/esm/hooks/index.d.ts +0 -6
  33. package/dist/esm/hooks/index.js +0 -6
  34. package/dist/esm/hooks/onDelete.d.ts +0 -12
  35. package/dist/esm/hooks/onDelete.js +0 -47
  36. package/dist/esm/hooks/removeRelated.d.ts +0 -11
  37. package/dist/esm/hooks/removeRelated.js +0 -37
  38. package/dist/esm/hooks/runPerItem.d.ts +0 -10
  39. package/dist/esm/hooks/runPerItem.js +0 -29
  40. package/dist/esm/hooks/setData.d.ts +0 -11
  41. package/dist/esm/hooks/setData.js +0 -46
  42. package/dist/esm/index.d.ts +0 -5
  43. package/dist/esm/index.js +0 -5
  44. package/dist/esm/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
  45. package/dist/esm/mixins/debounce-mixin/DebouncedStore.js +0 -46
  46. package/dist/esm/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
  47. package/dist/esm/mixins/debounce-mixin/debounceMixin.js +0 -19
  48. package/dist/esm/mixins/debounce-mixin/index.d.ts +0 -3
  49. package/dist/esm/mixins/debounce-mixin/index.js +0 -3
  50. package/dist/esm/mixins/debounce-mixin/types.d.ts +0 -13
  51. package/dist/esm/mixins/debounce-mixin/types.js +0 -1
  52. package/dist/esm/mixins/index.d.ts +0 -1
  53. package/dist/esm/mixins/index.js +0 -1
  54. package/dist/esm/types.d.ts +0 -3
  55. package/dist/esm/types.js +0 -1
  56. package/dist/esm/typesInternal.d.ts +0 -3
  57. package/dist/esm/typesInternal.js +0 -3
  58. package/dist/esm/utils/filterQuery.d.ts +0 -8
  59. package/dist/esm/utils/filterQuery.js +0 -30
  60. package/dist/esm/utils/getItemsIsArray.d.ts +0 -10
  61. package/dist/esm/utils/getItemsIsArray.js +0 -16
  62. package/dist/esm/utils/getPaginate.d.ts +0 -9
  63. package/dist/esm/utils/getPaginate.js +0 -20
  64. package/dist/esm/utils/index.d.ts +0 -11
  65. package/dist/esm/utils/index.js +0 -11
  66. package/dist/esm/utils/isMulti.d.ts +0 -11
  67. package/dist/esm/utils/isMulti.js +0 -26
  68. package/dist/esm/utils/isPaginated.d.ts +0 -5
  69. package/dist/esm/utils/isPaginated.js +0 -11
  70. package/dist/esm/utils/markHookForSkip.d.ts +0 -7
  71. package/dist/esm/utils/markHookForSkip.js +0 -18
  72. package/dist/esm/utils/mergeQuery/index.d.ts +0 -3
  73. package/dist/esm/utils/mergeQuery/index.js +0 -3
  74. package/dist/esm/utils/mergeQuery/mergeArrays.d.ts +0 -3
  75. package/dist/esm/utils/mergeQuery/mergeArrays.js +0 -37
  76. package/dist/esm/utils/mergeQuery/mergeQuery.d.ts +0 -3
  77. package/dist/esm/utils/mergeQuery/mergeQuery.js +0 -70
  78. package/dist/esm/utils/mergeQuery/types.d.ts +0 -13
  79. package/dist/esm/utils/mergeQuery/types.js +0 -1
  80. package/dist/esm/utils/mergeQuery/utils.d.ts +0 -11
  81. package/dist/esm/utils/mergeQuery/utils.js +0 -272
  82. package/dist/esm/utils/pushSet.d.ts +0 -8
  83. package/dist/esm/utils/pushSet.js +0 -22
  84. package/dist/esm/utils/setResultEmpty.d.ts +0 -5
  85. package/dist/esm/utils/setResultEmpty.js +0 -28
  86. package/dist/esm/utils/shouldSkip.d.ts +0 -8
  87. package/dist/esm/utils/shouldSkip.js +0 -29
  88. package/dist/esm/utils/validateQueryProperty.d.ts +0 -5
  89. package/dist/esm/utils/validateQueryProperty.js +0 -23
  90. package/dist/filters/array.d.ts +0 -2
  91. package/dist/filters/array.js +0 -21
  92. package/dist/filters/index.d.ts +0 -2
  93. package/dist/filters/index.js +0 -18
  94. package/dist/filters/object.d.ts +0 -2
  95. package/dist/filters/object.js +0 -22
  96. package/dist/hooks/checkMulti.d.ts +0 -5
  97. package/dist/hooks/checkMulti.js +0 -24
  98. package/dist/hooks/createRelated.d.ts +0 -12
  99. package/dist/hooks/createRelated.js +0 -44
  100. package/dist/hooks/index.d.ts +0 -6
  101. package/dist/hooks/index.js +0 -22
  102. package/dist/hooks/onDelete.d.ts +0 -12
  103. package/dist/hooks/onDelete.js +0 -60
  104. package/dist/hooks/removeRelated.d.ts +0 -11
  105. package/dist/hooks/removeRelated.js +0 -50
  106. package/dist/hooks/runPerItem.d.ts +0 -10
  107. package/dist/hooks/runPerItem.js +0 -42
  108. package/dist/hooks/setData.d.ts +0 -11
  109. package/dist/hooks/setData.js +0 -54
  110. package/dist/index.js +0 -21
  111. package/dist/mixins/debounce-mixin/DebouncedStore.d.ts +0 -18
  112. package/dist/mixins/debounce-mixin/DebouncedStore.js +0 -65
  113. package/dist/mixins/debounce-mixin/debounceMixin.d.ts +0 -3
  114. package/dist/mixins/debounce-mixin/debounceMixin.js +0 -23
  115. package/dist/mixins/debounce-mixin/index.d.ts +0 -3
  116. package/dist/mixins/debounce-mixin/index.js +0 -19
  117. package/dist/mixins/debounce-mixin/types.d.ts +0 -13
  118. package/dist/mixins/debounce-mixin/types.js +0 -2
  119. package/dist/mixins/index.d.ts +0 -1
  120. package/dist/mixins/index.js +0 -17
  121. package/dist/types.d.ts +0 -3
  122. package/dist/types.js +0 -2
  123. package/dist/typesInternal.d.ts +0 -3
  124. package/dist/typesInternal.js +0 -4
  125. package/dist/utils/filterQuery.d.ts +0 -8
  126. package/dist/utils/filterQuery.js +0 -46
  127. package/dist/utils/getItemsIsArray.d.ts +0 -10
  128. package/dist/utils/getItemsIsArray.js +0 -20
  129. package/dist/utils/getPaginate.d.ts +0 -9
  130. package/dist/utils/getPaginate.js +0 -22
  131. package/dist/utils/index.d.ts +0 -11
  132. package/dist/utils/index.js +0 -27
  133. package/dist/utils/isMulti.d.ts +0 -11
  134. package/dist/utils/isMulti.js +0 -30
  135. package/dist/utils/isPaginated.d.ts +0 -5
  136. package/dist/utils/isPaginated.js +0 -15
  137. package/dist/utils/markHookForSkip.d.ts +0 -7
  138. package/dist/utils/markHookForSkip.js +0 -22
  139. package/dist/utils/mergeQuery/index.d.ts +0 -3
  140. package/dist/utils/mergeQuery/index.js +0 -19
  141. package/dist/utils/mergeQuery/mergeArrays.d.ts +0 -3
  142. package/dist/utils/mergeQuery/mergeArrays.js +0 -41
  143. package/dist/utils/mergeQuery/mergeQuery.d.ts +0 -3
  144. package/dist/utils/mergeQuery/mergeQuery.js +0 -77
  145. package/dist/utils/mergeQuery/types.d.ts +0 -13
  146. package/dist/utils/mergeQuery/types.js +0 -2
  147. package/dist/utils/mergeQuery/utils.d.ts +0 -11
  148. package/dist/utils/mergeQuery/utils.js +0 -287
  149. package/dist/utils/pushSet.d.ts +0 -8
  150. package/dist/utils/pushSet.js +0 -29
  151. package/dist/utils/setResultEmpty.d.ts +0 -5
  152. package/dist/utils/setResultEmpty.js +0 -32
  153. package/dist/utils/shouldSkip.d.ts +0 -8
  154. package/dist/utils/shouldSkip.js +0 -33
  155. package/dist/utils/validateQueryProperty.d.ts +0 -5
  156. package/dist/utils/validateQueryProperty.js +0 -25
@@ -2,20 +2,15 @@ import { Forbidden } from "@feathersjs/errors";
2
2
  import _get from "lodash/get.js";
3
3
  import _has from "lodash/has.js";
4
4
  import _isEmpty from "lodash/isEmpty.js";
5
- import _isEqual from "lodash/isEqual.js";
6
5
 
7
6
  import _set from "lodash/set.js";
8
7
  import _uniqWith from "lodash/uniqWith.js";
9
8
  import type { Path } from "../../typesInternal";
10
9
  import { mergeArrays } from "./mergeArrays";
11
10
  import type { Handle, MergeQueryOptions } from "./types";
12
-
13
- export const hasOwnProperty = (
14
- obj: Record<string, unknown>,
15
- key: string
16
- ): boolean => {
17
- return Object.prototype.hasOwnProperty.call(obj, key);
18
- };
11
+ import { deepEqual as _isEqual } from "fast-equals";
12
+ import type { Query } from "@feathersjs/feathers";
13
+ import { hasOwnProperty } from "../internal.utils";
19
14
 
20
15
  export function handleArray<T>(
21
16
  target: Record<string, unknown>,
@@ -265,19 +260,12 @@ export function handleCircular<T>(
265
260
  export function makeDefaultOptions<T>(
266
261
  options?: Partial<MergeQueryOptions<T>>
267
262
  ): MergeQueryOptions<T> {
268
- options = options || ({} as MergeQueryOptions<T>);
269
- options.defaultHandle = options.defaultHandle || "combine";
270
- options.useLogicalConjunction = Object.prototype.hasOwnProperty.call(
271
- options,
272
- "useLogicalConjunction"
273
- )
274
- ? options.useLogicalConjunction
275
- : false;
276
- options.actionOnEmptyIntersect =
277
- options.actionOnEmptyIntersect ||
278
- (() => {
279
- throw new Forbidden("You're not allowed to make this request");
280
- });
263
+ options ??= {} as MergeQueryOptions<T>;
264
+ options.defaultHandle ??= "combine";
265
+ options.useLogicalConjunction ??= false;
266
+ options.actionOnEmptyIntersect ??= () => {
267
+ throw new Forbidden("You're not allowed to make this request");
268
+ };
281
269
  options.handle = options.handle || {};
282
270
  if (options.defaultHandle === "intersect") {
283
271
  options.handle.$select = options.handle.$select || "intersectOrFull";
@@ -286,15 +274,17 @@ export function makeDefaultOptions<T>(
286
274
  }
287
275
 
288
276
  export function moveProperty(
289
- source: Record<string, any>,
290
- target: Record<string, any>,
291
- key: string
277
+ from: Record<string, any>,
278
+ to: Record<string, any>,
279
+ ...keys: string[]
292
280
  ): void {
293
- if (!Object.prototype.hasOwnProperty.call(source, key)) {
294
- return;
295
- }
296
- target[key] = source[key];
297
- delete source[key];
281
+ keys.forEach((key) => {
282
+ if (!hasOwnProperty(from, key)) {
283
+ return;
284
+ }
285
+ to[key] = from[key];
286
+ delete from[key];
287
+ });
298
288
  }
299
289
 
300
290
  export function getParentProp(target: Record<string, unknown>, path: Path) {
@@ -338,5 +328,68 @@ export function arrayWithoutDuplicates<T>(target: T[]): T[] {
338
328
  if (!target || !Array.isArray(target)) {
339
329
  return target;
340
330
  }
331
+
341
332
  return _uniqWith(target, _isEqual);
342
333
  }
334
+
335
+ /**
336
+ * Checks if one query is a superset of the target query
337
+ * @param target The target query
338
+ * @param source The source query
339
+ * @returns The query that is the superset of the other query, returns undefined otherwise
340
+ */
341
+ export function isQueryMoreExplicitThanQuery(
342
+ target: Query,
343
+ source: Query
344
+ ): Query | undefined {
345
+ if (!target || !source) {
346
+ return;
347
+ }
348
+
349
+ const targetKeys = Object.keys(target);
350
+ const sourceKeys = Object.keys(source);
351
+
352
+ // sourceQuery: {}; targetQuery: { something }
353
+ if (!sourceKeys.length) {
354
+ return target;
355
+ }
356
+
357
+ // sourceQuery: { something }; targetQuery: {}
358
+ if (!targetKeys.length) {
359
+ return source;
360
+ }
361
+
362
+ if (targetKeys.every((key) => _isEqual(target[key], source[key]))) {
363
+ // every property of target is exactly in source
364
+ return source;
365
+ }
366
+
367
+ if (sourceKeys.every((key) => _isEqual(target[key], source[key]))) {
368
+ // every property of source is exactly in target
369
+ return target;
370
+ }
371
+
372
+ return;
373
+ }
374
+
375
+ export function areQueriesOverlapping(target: Query, source: Query): boolean {
376
+ if (!target || !source) {
377
+ return false;
378
+ }
379
+
380
+ const targetKeys = Object.keys(target);
381
+ const sourceKeys = Object.keys(source);
382
+
383
+ if (!sourceKeys.length || !targetKeys.length) {
384
+ return false;
385
+ }
386
+
387
+ if (
388
+ targetKeys.some((x) => sourceKeys.includes(x)) ||
389
+ sourceKeys.some((x) => targetKeys.includes(x))
390
+ ) {
391
+ return true;
392
+ }
393
+
394
+ return false;
395
+ }
@@ -1,2 +0,0 @@
1
- import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
2
- export declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
@@ -1,17 +0,0 @@
1
- import { validateQueryProperty } from "../utils/validateQueryProperty";
2
- const filterQueryArray = (key) => (arr, { operators }) => {
3
- if (arr && !Array.isArray(arr)) {
4
- throw new Error(`Invalid query parameter '${key}'. It has to be an array`);
5
- }
6
- if (Array.isArray(arr)) {
7
- return arr.map((current) => validateQueryProperty(current, operators));
8
- }
9
- return arr;
10
- };
11
- export const filterArray = (...keys) => {
12
- const result = {};
13
- for (const key of keys) {
14
- result[key] = filterQueryArray(key);
15
- }
16
- return result;
17
- };
@@ -1,2 +0,0 @@
1
- export * from "./array";
2
- export * from "./object";
@@ -1,2 +0,0 @@
1
- export * from "./array";
2
- export * from "./object";
@@ -1,2 +0,0 @@
1
- import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
2
- export declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
@@ -1,15 +0,0 @@
1
- import { validateQueryProperty } from "../utils/validateQueryProperty";
2
- import _isObject from "lodash/isObject";
3
- const filterQueryObject = (key) => (obj, { operators }) => {
4
- if (obj && !_isObject(obj)) {
5
- throw new Error(`Invalid query parameter: '${key}'. It has to be an object`);
6
- }
7
- return validateQueryProperty(obj, operators);
8
- };
9
- export const filterObject = (...keys) => {
10
- const result = {};
11
- for (const key of keys) {
12
- result[key] = filterQueryObject(key);
13
- }
14
- return result;
15
- };
@@ -1,5 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- /**
3
- * hook to check if context is multi patch/remove and if the service allows it
4
- */
5
- export declare function checkMulti<H extends HookContext = HookContext>(): (context: H) => H;
@@ -1,20 +0,0 @@
1
- import { MethodNotAllowed } from "@feathersjs/errors";
2
- import { shouldSkip, isMulti } from "../utils";
3
- /**
4
- * hook to check if context is multi patch/remove and if the service allows it
5
- */
6
- export function checkMulti() {
7
- return (context) => {
8
- if (shouldSkip("checkMulti", context)) {
9
- return context;
10
- }
11
- const { service, method } = context;
12
- if (!service.allowsMulti || !isMulti(context) || method === "find") {
13
- return context;
14
- }
15
- if (!service.allowsMulti(method)) {
16
- throw new MethodNotAllowed(`Can not ${method} multiple entries`);
17
- }
18
- return context;
19
- };
20
- }
@@ -1,12 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- import type { Promisable } from "../typesInternal";
3
- export interface CreateRelatedOptions<S = Record<string, any>> {
4
- service: keyof S;
5
- multi?: boolean;
6
- data: (item: any, context: HookContext) => Promisable<Record<string, any>>;
7
- createItemsInDataArraySeparately?: boolean;
8
- }
9
- /**
10
- * hook to create related items
11
- */
12
- export declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, multi, data, createItemsInDataArraySeparately, }: CreateRelatedOptions<S>): (context: H) => Promise<H>;
@@ -1,31 +0,0 @@
1
- import { checkContext } from "feathers-hooks-common";
2
- import { getItemsIsArray, shouldSkip } from "../utils";
3
- /**
4
- * hook to create related items
5
- */
6
- export function createRelated({ service, multi = true, data, createItemsInDataArraySeparately = true, }) {
7
- if (!service || !data) {
8
- throw "initialize hook 'createRelated' completely!";
9
- }
10
- return async (context) => {
11
- if (shouldSkip("createRelated", context)) {
12
- return context;
13
- }
14
- checkContext(context, "after", undefined, "createRelated");
15
- const { items } = getItemsIsArray(context);
16
- let dataToCreate = (await Promise.all(items.map(async (item) => data(item, context)))).filter((x) => !!x);
17
- if (createItemsInDataArraySeparately) {
18
- dataToCreate = dataToCreate.flat();
19
- }
20
- if (!dataToCreate || dataToCreate.length <= 0) {
21
- return context;
22
- }
23
- if (multi) {
24
- await context.app.service(service).create(dataToCreate);
25
- }
26
- else {
27
- await Promise.all(dataToCreate.map(async (item) => context.app.service(service).create(item)));
28
- }
29
- return context;
30
- };
31
- }
@@ -1,6 +0,0 @@
1
- export * from "./checkMulti";
2
- export * from "./createRelated";
3
- export * from "./onDelete";
4
- export * from "./removeRelated";
5
- export * from "./runPerItem";
6
- export * from "./setData";
@@ -1,6 +0,0 @@
1
- export * from "./checkMulti";
2
- export * from "./createRelated";
3
- export * from "./onDelete";
4
- export * from "./removeRelated";
5
- export * from "./runPerItem";
6
- export * from "./setData";
@@ -1,12 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- export type OnDeleteAction = "cascade" | "set null";
3
- export interface OnDeleteOptions {
4
- keyThere: string;
5
- keyHere: string;
6
- onDelete: OnDeleteAction;
7
- blocking?: boolean;
8
- }
9
- /**
10
- * hook to manipulate related items on delete
11
- */
12
- export declare function onDelete<S = Record<string, any>, H extends HookContext = HookContext>(service: keyof S, { keyThere, keyHere, onDelete, blocking, }: OnDeleteOptions): (context: H) => Promise<H>;
@@ -1,47 +0,0 @@
1
- import { checkContext } from "feathers-hooks-common";
2
- import { getItemsIsArray, shouldSkip } from "../utils";
3
- /**
4
- * hook to manipulate related items on delete
5
- */
6
- export function onDelete(service, { keyThere, keyHere = "id", onDelete = "cascade", blocking = true, }) {
7
- if (!service || !keyThere) {
8
- throw "initialize hook 'removeRelated' completely!";
9
- }
10
- if (!["cascade", "set null"].includes(onDelete)) {
11
- throw "onDelete must be 'cascade' or 'set null'";
12
- }
13
- return async (context) => {
14
- if (shouldSkip("onDelete", context)) {
15
- return context;
16
- }
17
- checkContext(context, "after", "remove", "onDelete");
18
- const { items } = getItemsIsArray(context);
19
- let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
20
- ids = [...new Set(ids)];
21
- if (!ids || ids.length <= 0) {
22
- return context;
23
- }
24
- const params = {
25
- query: {
26
- [keyThere]: {
27
- $in: ids,
28
- },
29
- },
30
- paginate: false,
31
- };
32
- let promise;
33
- if (onDelete === "cascade") {
34
- promise = context.app.service(service).remove(null, params);
35
- }
36
- else if (onDelete === "set null") {
37
- const data = { [keyThere]: null };
38
- promise = context.app
39
- .service(service)
40
- .patch(null, data, params);
41
- }
42
- if (blocking) {
43
- await promise;
44
- }
45
- return context;
46
- };
47
- }
@@ -1,11 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- export interface RemoveRelatedOptions<S = Record<string, any>> {
3
- service: keyof S;
4
- keyThere: string;
5
- keyHere: string;
6
- blocking?: boolean;
7
- }
8
- /**
9
- * hook to remove related items
10
- */
11
- export declare function removeRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, keyThere, keyHere, blocking, }: RemoveRelatedOptions<S>): (context: H) => Promise<H>;
@@ -1,37 +0,0 @@
1
- import { checkContext } from "feathers-hooks-common";
2
- import { getItemsIsArray, shouldSkip } from "../utils";
3
- /**
4
- * hook to remove related items
5
- */
6
- export function removeRelated({ service, keyThere, keyHere = "id", blocking = true, }) {
7
- if (!service || !keyThere) {
8
- throw "initialize hook 'removeRelated' completely!";
9
- }
10
- return async (context) => {
11
- if (shouldSkip("removeRelated", context)) {
12
- return context;
13
- }
14
- checkContext(context, "after", "remove", "removeRelated");
15
- const { items } = getItemsIsArray(context);
16
- let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
17
- ids = [...new Set(ids)];
18
- if (!ids || ids.length <= 0) {
19
- return context;
20
- }
21
- // feathers does not accept `paginate: false` for remove, but some adapters need it to work properly
22
- const promise = context.app
23
- .service(service)
24
- .remove(null, {
25
- query: {
26
- [keyThere]: {
27
- $in: ids,
28
- },
29
- },
30
- paginate: false,
31
- });
32
- if (blocking) {
33
- await promise;
34
- }
35
- return context;
36
- };
37
- }
@@ -1,10 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- import type { Promisable } from "../typesInternal";
3
- export interface HookRunPerItemOptions {
4
- wait?: boolean;
5
- }
6
- /**
7
- * hook to run a hook for each item in the context
8
- * uses `context.result` if it is existent. otherwise uses context.data
9
- */
10
- export declare const runPerItem: <H extends HookContext<import("@feathersjs/feathers").Application<any, any>, any> = HookContext<import("@feathersjs/feathers").Application<any, any>, any>>(actionPerItem: (item: any, context: H) => Promisable<any>, _options?: HookRunPerItemOptions) => (context: H) => Promise<H>;
@@ -1,29 +0,0 @@
1
- import { shouldSkip, getItemsIsArray } from "../utils";
2
- const makeOptions = (options) => {
3
- options = options || {};
4
- return Object.assign({
5
- wait: true,
6
- }, options);
7
- };
8
- /**
9
- * hook to run a hook for each item in the context
10
- * uses `context.result` if it is existent. otherwise uses context.data
11
- */
12
- export const runPerItem = (
13
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- actionPerItem, _options) => {
15
- const options = makeOptions(_options);
16
- return async (context) => {
17
- if (shouldSkip("runForItems", context)) {
18
- return context;
19
- }
20
- const { items } = getItemsIsArray(context);
21
- const promises = items.map(async (item) => {
22
- await actionPerItem(item, context);
23
- });
24
- if (options.wait) {
25
- await Promise.all(promises);
26
- }
27
- return context;
28
- };
29
- };
@@ -1,11 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- import type { PropertyPath } from "lodash";
3
- import type { PredicateWithContext } from "../types";
4
- export interface HookSetDataOptions {
5
- allowUndefined?: boolean;
6
- overwrite?: boolean | PredicateWithContext;
7
- }
8
- /**
9
- * hook to set properties on `context.result` (if existent) or `context.data` (otherwise)
10
- */
11
- export declare function setData<H extends HookContext = HookContext>(from: PropertyPath, to: PropertyPath, _options?: HookSetDataOptions): (context: H) => H;
@@ -1,46 +0,0 @@
1
- import _get from "lodash/get.js";
2
- import _set from "lodash/set.js";
3
- import _has from "lodash/has.js";
4
- import { Forbidden } from "@feathersjs/errors";
5
- import { getItemsIsArray, shouldSkip } from "../utils";
6
- const defaultOptions = {
7
- allowUndefined: false,
8
- overwrite: true,
9
- };
10
- /**
11
- * hook to set properties on `context.result` (if existent) or `context.data` (otherwise)
12
- */
13
- export function setData(from, to, _options) {
14
- const options = Object.assign({}, defaultOptions, _options);
15
- return (context) => {
16
- if (shouldSkip("setData", context)) {
17
- return context;
18
- }
19
- const { items } = getItemsIsArray(context);
20
- if (!_has(context, from)) {
21
- if (!context.params?.provider || options.allowUndefined === true) {
22
- return context;
23
- }
24
- if (!options.overwrite &&
25
- items.every((item) => _has(item, to))) {
26
- return context;
27
- }
28
- throw new Forbidden(`Expected field ${from.toString()} not available`);
29
- }
30
- const val = _get(context, from);
31
- items.forEach((item) => {
32
- let overwrite;
33
- if (typeof options.overwrite === "function") {
34
- overwrite = options.overwrite(item, context);
35
- }
36
- else {
37
- overwrite = options.overwrite;
38
- }
39
- if (!overwrite && _has(item, to)) {
40
- return;
41
- }
42
- _set(item, to, val);
43
- });
44
- return context;
45
- };
46
- }
@@ -1,5 +0,0 @@
1
- export * from "./hooks";
2
- export * from "./mixins";
3
- export * from "./utils";
4
- export * from "./filters";
5
- export * from "./types";
package/dist/esm/index.js DELETED
@@ -1,5 +0,0 @@
1
- export * from "./hooks";
2
- export * from "./mixins";
3
- export * from "./utils";
4
- export * from "./filters";
5
- export * from "./types";
@@ -1,18 +0,0 @@
1
- import type { DebouncedFunc } from "lodash";
2
- import type { Application, Id } from "@feathersjs/feathers";
3
- import type { DebouncedFunctionApp, DebouncedStoreOptions } from "./types";
4
- export declare const makeDefaultOptions: () => DebouncedStoreOptions;
5
- export type DebouncedService<T = any> = T & {
6
- debouncedStore: DebouncedStore;
7
- };
8
- export declare class DebouncedStore {
9
- private _app;
10
- private _options;
11
- private _isRunningById;
12
- _queueById: Record<string, DebouncedFunc<(id: Id, action: DebouncedFunctionApp) => void | Promise<void>>>;
13
- add: (id: Id, action: (app?: Application) => void | Promise<void>) => void | Promise<void> | undefined;
14
- constructor(app: Application, options?: Partial<DebouncedStoreOptions>);
15
- private unbounced;
16
- private debounceById;
17
- cancel(id: Id): void;
18
- }
@@ -1,46 +0,0 @@
1
- import _debounce from "lodash/debounce.js";
2
- export const makeDefaultOptions = () => {
3
- return {
4
- leading: false,
5
- maxWait: undefined,
6
- trailing: true,
7
- wait: 100,
8
- };
9
- };
10
- export class DebouncedStore {
11
- constructor(app, options) {
12
- this._app = app;
13
- this._options = Object.assign(makeDefaultOptions(), options);
14
- this._queueById = {};
15
- this._isRunningById = {};
16
- //this._waitingById = {};
17
- this.add = this.debounceById(this.unbounced, this._options.wait, {
18
- leading: this._options.leading,
19
- maxWait: this._options.maxWait,
20
- trailing: this._options.trailing,
21
- });
22
- }
23
- async unbounced(id, action) {
24
- if (this._queueById[id] === undefined) {
25
- return;
26
- }
27
- delete this._queueById[id];
28
- this._isRunningById[id] = true;
29
- await action(this._app);
30
- delete this._isRunningById[id];
31
- }
32
- debounceById(func, wait, options) {
33
- return (id, action) => {
34
- if (typeof this._queueById[id] === "function") {
35
- return this._queueById[id](id, action);
36
- }
37
- this._queueById[id] = _debounce((id, action) => {
38
- this.unbounced(id, action);
39
- }, wait, { ...options, leading: false }); // leading required for return promise
40
- return this._queueById[id](id, action);
41
- };
42
- }
43
- cancel(id) {
44
- delete this._queueById[id];
45
- }
46
- }
@@ -1,3 +0,0 @@
1
- import type { Application } from "@feathersjs/feathers/lib";
2
- import type { InitDebounceMixinOptions } from "./types";
3
- export declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application) => void;
@@ -1,19 +0,0 @@
1
- import { DebouncedStore, makeDefaultOptions } from "./DebouncedStore";
2
- export function debounceMixin(options) {
3
- return (app) => {
4
- options = options || {};
5
- const defaultOptions = Object.assign(makeDefaultOptions(), options?.default);
6
- app.mixins.push((service, path) => {
7
- // if path is on blacklist, don't add debouncedStore to service
8
- if (options?.blacklist && options.blacklist.includes(path))
9
- return;
10
- // if service already has registered something on `debouncedStore`
11
- if (service.debouncedStore) {
12
- console.warn(`[feathers-utils] service: '${path}' already has a property 'debouncedStore'. Mixin will skip creating a new debouncedStore`);
13
- return;
14
- }
15
- const serviceOptions = Object.assign({}, defaultOptions, options?.[path]);
16
- service.debouncedStore = new DebouncedStore(app, serviceOptions);
17
- });
18
- };
19
- }
@@ -1,3 +0,0 @@
1
- export * from "./types";
2
- export * from "./DebouncedStore";
3
- export * from "./debounceMixin";
@@ -1,3 +0,0 @@
1
- export * from "./types";
2
- export * from "./DebouncedStore";
3
- export * from "./debounceMixin";
@@ -1,13 +0,0 @@
1
- import type { Application } from "@feathersjs/feathers";
2
- export interface InitDebounceMixinOptions {
3
- default: Partial<DebouncedStoreOptions>;
4
- blacklist: string[];
5
- [key: string]: unknown;
6
- }
7
- export type DebouncedFunctionApp = (app?: Application) => void | Promise<void>;
8
- export interface DebouncedStoreOptions {
9
- leading: boolean;
10
- maxWait: number | undefined;
11
- trailing: boolean;
12
- wait: number;
13
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export * from "./debounce-mixin";
@@ -1 +0,0 @@
1
- export * from "./debounce-mixin";
@@ -1,3 +0,0 @@
1
- import type { HookContext } from "@feathersjs/feathers";
2
- export type Predicate<T = any> = (item: T) => boolean;
3
- export type PredicateWithContext<T = any> = (item: T, context: HookContext) => boolean;
package/dist/esm/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,3 +0,0 @@
1
- export type MaybeArray<T> = T | T[];
2
- export type Promisable<T> = T | Promise<T>;
3
- export type Path = Array<string | number>;
@@ -1,3 +0,0 @@
1
- // here are types that are not meant to be exported!
2
- // just for internal use of this package
3
- export {};