feathers-utils 6.0.0 → 7.0.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 (59) hide show
  1. package/README.md +3 -4
  2. package/dist/index.cjs +81 -99
  3. package/dist/index.d.cts +35 -33
  4. package/dist/index.d.mts +35 -33
  5. package/dist/index.d.ts +35 -33
  6. package/dist/index.mjs +81 -99
  7. package/package.json +29 -32
  8. package/src/.DS_Store +0 -0
  9. package/src/filters/array.ts +11 -13
  10. package/src/filters/index.ts +2 -2
  11. package/src/filters/object.ts +11 -11
  12. package/src/hooks/.DS_Store +0 -0
  13. package/src/hooks/checkMulti.ts +98 -82
  14. package/src/hooks/createRelated.ts +41 -41
  15. package/src/hooks/forEach.ts +32 -32
  16. package/src/hooks/from-client-for-server/common.ts +1 -1
  17. package/src/hooks/from-client-for-server/index.ts +2 -2
  18. package/src/hooks/from-client-for-server/paramsForServer.ts +32 -32
  19. package/src/hooks/from-client-for-server/paramsFromClient.ts +25 -25
  20. package/src/hooks/index.ts +9 -9
  21. package/src/hooks/onDelete.ts +54 -55
  22. package/src/hooks/parseFields.ts +13 -13
  23. package/src/hooks/removeRelated.ts +22 -20
  24. package/src/hooks/runPerItem.ts +17 -18
  25. package/src/hooks/setData.ts +295 -264
  26. package/src/index.ts +6 -6
  27. package/src/mixins/debounce-mixin/DebouncedStore.ts +29 -29
  28. package/src/mixins/debounce-mixin/debounceMixin.ts +17 -17
  29. package/src/mixins/debounce-mixin/index.ts +3 -3
  30. package/src/mixins/debounce-mixin/types.ts +9 -9
  31. package/src/mixins/debounce-mixin/utils.ts +3 -3
  32. package/src/mixins/index.ts +1 -1
  33. package/src/types.ts +3 -5
  34. package/src/typesInternal.ts +14 -14
  35. package/src/utility-types/index.ts +48 -48
  36. package/src/utils/_utils.internal.ts +5 -5
  37. package/src/utils/defineHooks.ts +8 -8
  38. package/src/utils/deflattenQuery.ts +31 -31
  39. package/src/utils/filterQuery.ts +58 -58
  40. package/src/utils/flattenQuery.ts +54 -54
  41. package/src/utils/getItemsIsArray.ts +148 -149
  42. package/src/utils/getPaginate.ts +31 -31
  43. package/src/utils/index.ts +17 -17
  44. package/src/utils/isMulti.ts +48 -40
  45. package/src/utils/isPaginated.ts +30 -30
  46. package/src/utils/markHookForSkip.ts +177 -178
  47. package/src/utils/mergeQuery/index.ts +3 -3
  48. package/src/utils/mergeQuery/mergeArrays.ts +67 -67
  49. package/src/utils/mergeQuery/mergeQuery.ts +211 -211
  50. package/src/utils/mergeQuery/types.ts +12 -12
  51. package/src/utils/mergeQuery/utils.ts +224 -224
  52. package/src/utils/optimizeBatchPatch.ts +42 -42
  53. package/src/utils/pushSet.ts +57 -57
  54. package/src/utils/setQueryKeySafely.ts +68 -68
  55. package/src/utils/setResultEmpty.ts +125 -123
  56. package/src/utils/shouldSkip.ts +72 -72
  57. package/src/utils/toJSON.ts +4 -4
  58. package/src/utils/validateQueryProperty.ts +10 -10
  59. package/src/hooks/makeSequelizeQuery.ts_ +0 -90
package/dist/index.mjs CHANGED
@@ -13,7 +13,7 @@ function defineHooks(hooks) {
13
13
  }
14
14
 
15
15
  function filterQuery(providedQuery) {
16
- providedQuery ?? (providedQuery = {});
16
+ providedQuery ??= {};
17
17
  const { $select, $limit, $skip, $sort, ...query } = providedQuery;
18
18
  const result = { query };
19
19
  if ("$select" in providedQuery) {
@@ -381,12 +381,12 @@ function handleCircular(target, source, prependKey, options) {
381
381
  }
382
382
  }
383
383
  function makeDefaultOptions$1(options) {
384
- options ?? (options = {});
385
- options.defaultHandle ?? (options.defaultHandle = "combine");
386
- options.useLogicalConjunction ?? (options.useLogicalConjunction = false);
387
- options.actionOnEmptyIntersect ?? (options.actionOnEmptyIntersect = () => {
384
+ options ??= {};
385
+ options.defaultHandle ??= "combine";
386
+ options.useLogicalConjunction ??= false;
387
+ options.actionOnEmptyIntersect ??= () => {
388
388
  throw new Forbidden("You're not allowed to make this request");
389
- });
389
+ };
390
390
  options.handle = options.handle || {};
391
391
  if (options.defaultHandle === "intersect") {
392
392
  options.handle.$select = options.handle.$select || "intersectOrFull";
@@ -506,7 +506,6 @@ function mergeQuery(target, source, _options) {
506
506
  }
507
507
 
508
508
  const setQueryKeySafely = (params, key, value, operator = "$eq", options) => {
509
- var _a;
510
509
  const { mutate = false } = options || {};
511
510
  if (!mutate) {
512
511
  params = structuredClone(params);
@@ -527,7 +526,7 @@ const setQueryKeySafely = (params, key, value, operator = "$eq", options) => {
527
526
  if (isPlainObject(params.query[key]) && !(operator in params.query[key])) {
528
527
  params.query[key][operator] = value;
529
528
  } else {
530
- (_a = params.query).$and ?? (_a.$and = []);
529
+ params.query.$and ??= [];
531
530
  params.query.$and.push(
532
531
  operator === "$eq" ? { [key]: value } : {
533
532
  [key]: {
@@ -718,37 +717,35 @@ function checkMulti() {
718
717
  };
719
718
  }
720
719
 
721
- function createRelated({
722
- service,
723
- multi = true,
724
- data,
725
- createItemsInDataArraySeparately = true
726
- }) {
727
- if (!service || !data) {
728
- throw "initialize hook 'createRelated' completely!";
729
- }
720
+ function createRelated(options) {
730
721
  return async (context) => {
731
722
  if (shouldSkip("createRelated", context)) {
732
723
  return context;
733
724
  }
734
725
  checkContext(context, "after", void 0, "createRelated");
735
726
  const { items } = getItemsIsArray(context);
736
- let dataToCreate = (await Promise.all(items.map(async (item) => data(item, context)))).filter((x) => !!x);
737
- if (createItemsInDataArraySeparately) {
738
- dataToCreate = dataToCreate.flat();
739
- }
740
- if (!dataToCreate || dataToCreate.length <= 0) {
741
- return context;
742
- }
743
- if (multi) {
744
- await context.app.service(service).create(dataToCreate);
745
- } else {
746
- await Promise.all(
747
- dataToCreate.map(
748
- async (item) => context.app.service(service).create(item)
749
- )
750
- );
751
- }
727
+ const entries = Array.isArray(options) ? options : [options];
728
+ await Promise.all(
729
+ entries.map(async (entry) => {
730
+ const { data, service, createItemsInDataArraySeparately, multi } = entry;
731
+ let dataToCreate = (await Promise.all(items.map(async (item) => data(item, context)))).filter((x) => !!x);
732
+ if (createItemsInDataArraySeparately) {
733
+ dataToCreate = dataToCreate.flat();
734
+ }
735
+ if (!dataToCreate || dataToCreate.length <= 0) {
736
+ return context;
737
+ }
738
+ if (multi) {
739
+ await context.app.service(service).create(dataToCreate);
740
+ } else {
741
+ await Promise.all(
742
+ dataToCreate.map(
743
+ async (item) => context.app.service(service).create(item)
744
+ )
745
+ );
746
+ }
747
+ })
748
+ );
752
749
  return context;
753
750
  };
754
751
  }
@@ -786,46 +783,44 @@ const forEach = (actionPerItem, options) => {
786
783
  };
787
784
  };
788
785
 
789
- function onDelete(service, {
790
- keyThere,
791
- keyHere = "id",
792
- onDelete: onDelete2 = "cascade",
793
- blocking = true
794
- }) {
795
- if (!service || !keyThere) {
796
- throw "initialize hook 'removeRelated' completely!";
797
- }
798
- if (!["cascade", "set null"].includes(onDelete2)) {
799
- throw "onDelete must be 'cascade' or 'set null'";
800
- }
786
+ function onDelete(options) {
801
787
  return async (context) => {
802
788
  if (shouldSkip("onDelete", context)) {
803
789
  return context;
804
790
  }
805
791
  checkContext(context, "after", "remove", "onDelete");
806
792
  const { items } = getItemsIsArray(context);
807
- let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
808
- ids = [...new Set(ids)];
809
- if (!ids || ids.length <= 0) {
810
- return context;
811
- }
812
- const params = {
813
- query: {
814
- [keyThere]: {
815
- $in: ids
793
+ const entries = Array.isArray(options) ? options : [options];
794
+ const promises = [];
795
+ entries.forEach(
796
+ async ({ keyHere, keyThere, onDelete: onDelete2, service, blocking }) => {
797
+ let ids = items.map((x) => x[keyHere]).filter((x) => !!x);
798
+ ids = [...new Set(ids)];
799
+ if (!ids || ids.length <= 0) {
800
+ return context;
816
801
  }
817
- },
818
- paginate: false
819
- };
820
- let promise;
821
- if (onDelete2 === "cascade") {
822
- promise = context.app.service(service).remove(null, params);
823
- } else if (onDelete2 === "set null") {
824
- const data = { [keyThere]: null };
825
- promise = context.app.service(service).patch(null, data, params);
826
- }
827
- if (blocking) {
828
- await promise;
802
+ const params = {
803
+ query: {
804
+ [keyThere]: {
805
+ $in: ids
806
+ }
807
+ },
808
+ paginate: false
809
+ };
810
+ let promise = void 0;
811
+ if (onDelete2 === "cascade") {
812
+ promise = context.app.service(service).remove(null, params);
813
+ } else if (onDelete2 === "set null") {
814
+ const data = { [keyThere]: null };
815
+ promise = context.app.service(service).patch(null, data, params);
816
+ }
817
+ if (blocking && promise) {
818
+ promises.push(promise);
819
+ }
820
+ }
821
+ );
822
+ if (promises.length) {
823
+ await Promise.all(promises);
829
824
  }
830
825
  return context;
831
826
  };
@@ -959,19 +954,18 @@ function defineParamsForServer(keyToHide) {
959
954
  return;
960
955
  }
961
956
  if (whitelist.includes(key)) {
962
- if (!clonedParams) {
963
- clonedParams = {
964
- ...context.params,
965
- query: {
966
- ...context.params.query
967
- }
968
- };
957
+ const currentParams = clonedParams ?? {
958
+ ...context.params,
959
+ query: {
960
+ ...context.params.query
961
+ }
962
+ };
963
+ if (!currentParams.query[keyToHide]) {
964
+ currentParams.query[keyToHide] = {};
969
965
  }
970
- if (!clonedParams.query[keyToHide]) {
971
- clonedParams.query[keyToHide] = {};
972
- }
973
- clonedParams.query[keyToHide][key] = clonedParams[key];
974
- delete clonedParams[key];
966
+ currentParams.query[keyToHide][key] = currentParams[key];
967
+ delete currentParams[key];
968
+ clonedParams = currentParams;
975
969
  }
976
970
  });
977
971
  if (clonedParams) {
@@ -1028,20 +1022,14 @@ const makeDefaultOptions = () => {
1028
1022
  };
1029
1023
  };
1030
1024
 
1031
- var __defProp = Object.defineProperty;
1032
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1033
- var __publicField = (obj, key, value) => {
1034
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1035
- return value;
1036
- };
1037
1025
  class DebouncedStore {
1026
+ _app;
1027
+ _options;
1028
+ _isRunningById;
1029
+ _queueById;
1030
+ //_waitingById: Record<string, WaitingObject>;
1031
+ add;
1038
1032
  constructor(app, options) {
1039
- __publicField(this, "_app");
1040
- __publicField(this, "_options");
1041
- __publicField(this, "_isRunningById");
1042
- __publicField(this, "_queueById");
1043
- //_waitingById: Record<string, WaitingObject>;
1044
- __publicField(this, "add");
1045
1033
  this._app = app;
1046
1034
  this._options = Object.assign(makeDefaultOptions(), options);
1047
1035
  this._queueById = {};
@@ -1084,13 +1072,9 @@ class DebouncedStore {
1084
1072
  function debounceMixin(options) {
1085
1073
  return (app) => {
1086
1074
  options = options || {};
1087
- const defaultOptions = Object.assign(
1088
- makeDefaultOptions(),
1089
- options?.default
1090
- );
1075
+ const defaultOptions = Object.assign(makeDefaultOptions(), options?.default);
1091
1076
  app.mixins.push((service, path) => {
1092
- if (options?.blacklist && options.blacklist.includes(path))
1093
- return;
1077
+ if (options?.blacklist && options.blacklist.includes(path)) return;
1094
1078
  if (service.debouncedStore) {
1095
1079
  console.warn(
1096
1080
  `[feathers-utils] service: '${path}' already has a property 'debouncedStore'. Mixin will skip creating a new debouncedStore`
@@ -1108,9 +1092,7 @@ function debounceMixin(options) {
1108
1092
 
1109
1093
  const filterQueryArray = (key) => (arr, { operators }) => {
1110
1094
  if (arr && !Array.isArray(arr)) {
1111
- throw new Error(
1112
- `Invalid query parameter '${key}'. It has to be an array`
1113
- );
1095
+ throw new Error(`Invalid query parameter '${key}'. It has to be an array`);
1114
1096
  }
1115
1097
  if (Array.isArray(arr)) {
1116
1098
  return arr.map((current) => validateQueryProperty(current, operators));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feathers-utils",
3
- "version": "6.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "Some utils for projects using '@feathersjs/feathers'",
5
5
  "author": "fratzinger",
6
6
  "repository": {
@@ -22,6 +22,7 @@
22
22
  "main": "./dist/index.cjs",
23
23
  "module": "./dist/index.mjs",
24
24
  "types": "./dist/index.d.ts",
25
+ "type": "module",
25
26
  "files": [
26
27
  "CHANGELOG.md",
27
28
  "LICENSE",
@@ -30,43 +31,39 @@
30
31
  "lib/**",
31
32
  "dist/**"
32
33
  ],
33
- "scripts": {
34
- "build": "unbuild",
35
- "version": "npm run build",
36
- "release": "np",
37
- "test": "vitest run",
38
- "vitest": "vitest",
39
- "coverage": "vitest run --coverage",
40
- "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
41
- },
42
34
  "dependencies": {
43
- "@feathersjs/adapter-commons": "^5.0.13",
44
- "@feathersjs/errors": "^5.0.13",
45
- "@feathersjs/feathers": "^5.0.13",
46
- "fast-equals": "^5.0.1",
47
- "feathers-hooks-common": "^8.1.1",
35
+ "@feathersjs/adapter-commons": "^5.0.33",
36
+ "@feathersjs/errors": "^5.0.33",
37
+ "@feathersjs/feathers": "^5.0.33",
38
+ "fast-equals": "^5.2.2",
39
+ "feathers-hooks-common": "^8.2.1",
48
40
  "lodash": "^4.17.21"
49
41
  },
50
42
  "devDependencies": {
51
- "@feathersjs/memory": "^5.0.13",
52
- "@types/lodash": "^4.14.202",
53
- "@types/node": "^20.10.6",
54
- "@typescript-eslint/eslint-plugin": "^6.16.0",
55
- "@typescript-eslint/parser": "^6.16.0",
56
- "@vitest/coverage-v8": "^1.1.0",
57
- "eslint": "^8.56.0",
58
- "eslint-config-prettier": "^9.1.0",
59
- "eslint-import-resolver-typescript": "^3.6.1",
60
- "eslint-plugin-import": "^2.29.1",
61
- "eslint-plugin-prettier": "^5.1.2",
62
- "np": "^9.2.0",
63
- "prettier": "^3.1.1",
43
+ "@feathers-community/eslint-config": "^0.0.4",
44
+ "@feathersjs/memory": "^5.0.33",
45
+ "@tsconfig/node22": "^22.0.0",
46
+ "@types/lodash": "^4.17.16",
47
+ "@types/node": "^22.13.9",
48
+ "@vitest/coverage-v8": "^3.0.7",
49
+ "eslint": "^9.21.0",
50
+ "np": "^10.2.0",
51
+ "prettier": "^3.5.3",
64
52
  "shx": "^0.3.4",
65
- "typescript": "^5.3.3",
66
- "unbuild": "^2.0.0",
67
- "vitest": "^1.1.0"
53
+ "typescript": "^5.8.2",
54
+ "unbuild": "^3.5.0",
55
+ "vitest": "^3.0.7"
68
56
  },
69
57
  "peerDependencies": {
70
58
  "@feathersjs/feathers": "^5.0.0"
59
+ },
60
+ "scripts": {
61
+ "build": "unbuild",
62
+ "version": "npm run build",
63
+ "release": "np",
64
+ "test": "vitest run",
65
+ "vitest": "vitest",
66
+ "coverage": "vitest run --coverage",
67
+ "lint": "eslint"
71
68
  }
72
- }
69
+ }
package/src/.DS_Store ADDED
Binary file
@@ -1,30 +1,28 @@
1
- import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
2
- import { validateQueryProperty } from "../utils/validateQueryProperty";
1
+ import type { FilterQueryOptions } from '@feathersjs/adapter-commons'
2
+ import { validateQueryProperty } from '../utils/validateQueryProperty.js'
3
3
 
4
4
  const filterQueryArray =
5
5
  (key: string) =>
6
6
  (arr: any, { operators }: FilterQueryOptions) => {
7
7
  if (arr && !Array.isArray(arr)) {
8
- throw new Error(
9
- `Invalid query parameter '${key}'. It has to be an array`,
10
- );
8
+ throw new Error(`Invalid query parameter '${key}'. It has to be an array`)
11
9
  }
12
10
 
13
11
  if (Array.isArray(arr)) {
14
- return arr.map((current) => validateQueryProperty(current, operators));
12
+ return arr.map((current) => validateQueryProperty(current, operators))
15
13
  }
16
14
 
17
- return arr;
18
- };
15
+ return arr
16
+ }
19
17
 
20
18
  export const filterArray = <T extends string[]>(...keys: T) => {
21
19
  const result: {
22
- [key in T[number]]: (value: any, options: FilterQueryOptions) => any;
23
- } = {} as any;
20
+ [key in T[number]]: (value: any, options: FilterQueryOptions) => any
21
+ } = {} as any
24
22
 
25
23
  for (const key of keys) {
26
- result[key as T[number]] = filterQueryArray(key);
24
+ result[key as T[number]] = filterQueryArray(key)
27
25
  }
28
26
 
29
- return result;
30
- };
27
+ return result
28
+ }
@@ -1,2 +1,2 @@
1
- export * from "./array";
2
- export * from "./object";
1
+ export * from './array.js'
2
+ export * from './object.js'
@@ -1,6 +1,6 @@
1
- import type { FilterQueryOptions } from "@feathersjs/adapter-commons";
2
- import { validateQueryProperty } from "../utils/validateQueryProperty";
3
- import { isObject } from "../utils/_utils.internal";
1
+ import type { FilterQueryOptions } from '@feathersjs/adapter-commons'
2
+ import { validateQueryProperty } from '../utils/validateQueryProperty.js'
3
+ import { isObject } from '../utils/_utils.internal.js'
4
4
 
5
5
  const filterQueryObject =
6
6
  (key: string) =>
@@ -8,20 +8,20 @@ const filterQueryObject =
8
8
  if (obj && !isObject(obj)) {
9
9
  throw new Error(
10
10
  `Invalid query parameter: '${key}'. It has to be an object`,
11
- );
11
+ )
12
12
  }
13
13
 
14
- return validateQueryProperty(obj, operators);
15
- };
14
+ return validateQueryProperty(obj, operators)
15
+ }
16
16
 
17
17
  export const filterObject = <T extends string[]>(...keys: T) => {
18
18
  const result: {
19
- [key in T[number]]: (value: any, options: FilterQueryOptions) => any;
20
- } = {} as any;
19
+ [key in T[number]]: (value: any, options: FilterQueryOptions) => any
20
+ } = {} as any
21
21
 
22
22
  for (const key of keys) {
23
- result[key as T[number]] = filterQueryObject(key);
23
+ result[key as T[number]] = filterQueryObject(key)
24
24
  }
25
25
 
26
- return result;
27
- };
26
+ return result
27
+ }
Binary file