feathers-utils 5.1.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  # feathers-utils
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/feathers-utils)](https://www.npmjs.com/package/feathers-utils)
4
- [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/fratzinger/feathers-utils/Node.js%20CI)](https://github.com/fratzinger/feathers-utils/actions/workflows/node.js.yml?query=branch%3Amain)
4
+ [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/fratzinger/feathers-utils/node.js.yml?branch=main)](https://github.com/fratzinger/feathers-utils/actions/workflows/node.js.yml?query=branch%3Amain)
5
5
  [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/fratzinger/feathers-utils)](https://codeclimate.com/github/fratzinger/feathers-utils)
6
6
  [![Code Climate coverage](https://img.shields.io/codeclimate/coverage/fratzinger/feathers-utils)](https://codeclimate.com/github/fratzinger/feathers-utils)
7
- [![libraries.io](https://img.shields.io/librariesio/release/npm/feathers-utils)](https://libraries.io/npm/feathers-utils)
8
7
  [![npm](https://img.shields.io/npm/dm/feathers-utils)](https://www.npmjs.com/package/feathers-utils)
9
8
  [![GitHub license](https://img.shields.io/github/license/fratzinger/feathers-utils)](https://github.com/fratzinger/feathers-utils/blob/main/LICENSE.md)
10
9
 
@@ -40,6 +39,8 @@ npm i feathers-utils
40
39
 
41
40
  - `defineHooks`
42
41
  - `filterQuery`
42
+ - `flattenQuery`
43
+ - `deflattenQuery`
43
44
  - `getItemsIsArray(context)`: returns `{ items: any[], isArray: boolean }`
44
45
  - `getPaginate`
45
46
  - `isMulti(context) => Boolean`: returns true, if `find`, `create/patch/remove`: multi
package/dist/index.cjs CHANGED
@@ -1,30 +1,23 @@
1
1
  'use strict';
2
2
 
3
3
  const errors = require('@feathersjs/errors');
4
- const _isEqual = require('lodash/isEqual.js');
4
+ const fastEquals = require('fast-equals');
5
5
  const _get = require('lodash/get.js');
6
6
  const _set = require('lodash/set.js');
7
7
  const _merge = require('lodash/merge.js');
8
- const _isEmpty = require('lodash/isEmpty.js');
9
8
  const _has = require('lodash/has.js');
10
9
  const _uniqWith = require('lodash/uniqWith.js');
11
- const fastEquals = require('fast-equals');
12
- const commons = require('@feathersjs/commons');
13
10
  const feathersHooksCommon = require('feathers-hooks-common');
14
11
  const _debounce = require('lodash/debounce.js');
15
- const _isObject = require('lodash/isObject.js');
16
12
 
17
13
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
18
14
 
19
- const _isEqual__default = /*#__PURE__*/_interopDefaultCompat(_isEqual);
20
15
  const _get__default = /*#__PURE__*/_interopDefaultCompat(_get);
21
16
  const _set__default = /*#__PURE__*/_interopDefaultCompat(_set);
22
17
  const _merge__default = /*#__PURE__*/_interopDefaultCompat(_merge);
23
- const _isEmpty__default = /*#__PURE__*/_interopDefaultCompat(_isEmpty);
24
18
  const _has__default = /*#__PURE__*/_interopDefaultCompat(_has);
25
19
  const _uniqWith__default = /*#__PURE__*/_interopDefaultCompat(_uniqWith);
26
20
  const _debounce__default = /*#__PURE__*/_interopDefaultCompat(_debounce);
27
- const _isObject__default = /*#__PURE__*/_interopDefaultCompat(_isObject);
28
21
 
29
22
  function defineHooks(hooks) {
30
23
  return hooks;
@@ -48,6 +41,23 @@ function filterQuery(providedQuery) {
48
41
  }
49
42
  return result;
50
43
  }
44
+ function reassembleQuery(query) {
45
+ const { $select, $limit, $skip, $sort, query: rest } = query;
46
+ const result = rest;
47
+ if ($select !== void 0) {
48
+ result.$select = $select;
49
+ }
50
+ if ($limit !== void 0) {
51
+ result.$limit = $limit;
52
+ }
53
+ if ($skip !== void 0) {
54
+ result.$skip = $skip;
55
+ }
56
+ if ($sort !== void 0) {
57
+ result.$sort = $sort;
58
+ }
59
+ return result;
60
+ }
51
61
 
52
62
  const getItemsIsArray = (context, options) => {
53
63
  const { from = "automatic" } = options || {};
@@ -72,7 +82,9 @@ const getItemsIsArray = (context, options) => {
72
82
  const hasOwnProperty = (obj, ...keys) => {
73
83
  return keys.some((x) => Object.prototype.hasOwnProperty.call(obj, x));
74
84
  };
75
- const isPlainObject$1 = (value) => value && [void 0, Object].includes(value.constructor);
85
+ const isObject = (item) => !!item && typeof item === "object" && !Array.isArray(item);
86
+ const isPlainObject = (value) => isObject(value) && value.constructor === {}.constructor;
87
+ const isEmpty = (obj) => [Object, Array].includes((obj || {}).constructor) && !Object.keys(obj || {}).length;
76
88
 
77
89
  const getPaginate = (context) => {
78
90
  if (hasOwnProperty(context.params, "paginate")) {
@@ -120,7 +132,7 @@ const pushSet = (obj, path, val, options) => {
120
132
  _set__default(obj, path, arr);
121
133
  return arr;
122
134
  } else {
123
- if (options.unique && arr.some((x) => _isEqual__default(x, val))) {
135
+ if (options.unique && arr.some((x) => fastEquals.deepEqual(x, val))) {
124
136
  return arr;
125
137
  }
126
138
  arr.push(val);
@@ -403,7 +415,7 @@ function cleanOr(target) {
403
415
  if (!target || !Array.isArray(target) || target.length <= 0) {
404
416
  return target;
405
417
  }
406
- if (target.some((x) => _isEmpty__default(x))) {
418
+ if (target.some((x) => isEmpty(x))) {
407
419
  return void 0;
408
420
  } else {
409
421
  return arrayWithoutDuplicates(target);
@@ -413,10 +425,10 @@ function cleanAnd(target) {
413
425
  if (!target || !Array.isArray(target) || target.length <= 0) {
414
426
  return target;
415
427
  }
416
- if (target.every((x) => _isEmpty__default(x))) {
428
+ if (target.every((x) => isEmpty(x))) {
417
429
  return void 0;
418
430
  } else {
419
- target = target.filter((x) => !_isEmpty__default(x));
431
+ target = target.filter((x) => !isEmpty(x));
420
432
  return arrayWithoutDuplicates(target);
421
433
  }
422
434
  }
@@ -482,7 +494,7 @@ function mergeQuery(target, source, _options) {
482
494
  ...sourceQuery
483
495
  };
484
496
  }
485
- if (options.useLogicalConjunction && (options.defaultHandle === "combine" || options.defaultHandle === "intersect") && !_isEmpty__default(targetQuery)) {
497
+ if (options.useLogicalConjunction && (options.defaultHandle === "combine" || options.defaultHandle === "intersect") && !isEmpty(targetQuery)) {
486
498
  const logicalOp = options.defaultHandle === "combine" ? "$or" : "$and";
487
499
  if (hasOwnProperty(sourceQuery, logicalOp)) {
488
500
  const andOr = sourceQuery[logicalOp];
@@ -523,7 +535,7 @@ const setQueryKeySafely = (params, key, value, operator = "$eq", options) => {
523
535
  }
524
536
  return params;
525
537
  }
526
- if (isPlainObject$1(params.query[key]) && !(operator in params.query[key])) {
538
+ if (isPlainObject(params.query[key]) && !(operator in params.query[key])) {
527
539
  params.query[key][operator] = value;
528
540
  } else {
529
541
  (_a = params.query).$and ?? (_a.$and = []);
@@ -588,9 +600,8 @@ const toJSON = (context) => {
588
600
  return context;
589
601
  };
590
602
 
591
- const isPlainObject = (value) => commons._.isObject(value) && value.constructor === {}.constructor;
592
603
  const validateQueryProperty = (query, operators = []) => {
593
- if (!isPlainObject(query)) {
604
+ if (!isObject(query)) {
594
605
  return query;
595
606
  }
596
607
  for (const key of Object.keys(query)) {
@@ -598,7 +609,7 @@ const validateQueryProperty = (query, operators = []) => {
598
609
  throw new errors.BadRequest(`Invalid query parameter ${key}`, query);
599
610
  }
600
611
  const value = query[key];
601
- if (isPlainObject(value)) {
612
+ if (isObject(value)) {
602
613
  query[key] = validateQueryProperty(value, operators);
603
614
  }
604
615
  }
@@ -609,13 +620,18 @@ const validateQueryProperty = (query, operators = []) => {
609
620
 
610
621
  function optimizeBatchPatch(items, options) {
611
622
  const map = [];
612
- const id = options?.id ?? "id";
613
- for (const [id2, data] of items) {
614
- const index = map.findIndex((item) => fastEquals.deepEqual(item.data, data));
623
+ const idKey = options?.id ?? "id";
624
+ for (const _data of items) {
625
+ const data = _data;
626
+ const id = _data[idKey];
627
+ delete data[idKey];
628
+ const index = map.findIndex((item) => {
629
+ return fastEquals.deepEqual(item.data, data);
630
+ });
615
631
  if (index === -1) {
616
- map.push({ ids: [id2], data });
632
+ map.push({ ids: [id], data });
617
633
  } else {
618
- map[index].ids.push(id2);
634
+ map[index].ids.push(id);
619
635
  }
620
636
  }
621
637
  return map.map(({ ids, data }) => {
@@ -624,13 +640,79 @@ function optimizeBatchPatch(items, options) {
624
640
  data,
625
641
  {
626
642
  query: {
627
- [id]: { $in: ids }
643
+ [idKey]: { $in: ids }
628
644
  }
629
645
  }
630
646
  ];
631
647
  });
632
648
  }
633
649
 
650
+ function flattenQuery(q) {
651
+ if (Array.isArray(q)) {
652
+ return q.map(flattenQuery);
653
+ }
654
+ if (!isObject(q)) {
655
+ return q;
656
+ }
657
+ const { query, $limit, $select, $skip, $sort } = filterQuery(q);
658
+ const res = {};
659
+ function step(object, options) {
660
+ const { prev = [], result = res } = options ?? {};
661
+ Object.keys(object).forEach((key) => {
662
+ const value = object[key];
663
+ if (Array.isArray(value)) {
664
+ const newValues = value.map(
665
+ (v) => step(v, {
666
+ result: {}
667
+ })
668
+ );
669
+ _set__default(result, [...prev, key], newValues);
670
+ return;
671
+ }
672
+ if (key.startsWith("$")) {
673
+ _set__default(result, [...prev, key], value);
674
+ return;
675
+ }
676
+ const newKey = !prev.length ? [key] : [...prev.slice(0, -1), `${prev[prev.length - 1]}.${key}`];
677
+ if (!isObject(value)) {
678
+ _set__default(result, newKey, value);
679
+ return;
680
+ } else {
681
+ step(value, {
682
+ prev: newKey,
683
+ result
684
+ });
685
+ return;
686
+ }
687
+ });
688
+ return result;
689
+ }
690
+ return reassembleQuery({
691
+ $limit,
692
+ $select,
693
+ $skip,
694
+ $sort,
695
+ query: step(query)
696
+ });
697
+ }
698
+
699
+ function deflattenQuery(query) {
700
+ const result = {};
701
+ Object.keys(query).forEach((key) => {
702
+ const value = query[key];
703
+ if (Array.isArray(value)) {
704
+ _set__default(result, key, value.map(deflattenQuery));
705
+ return;
706
+ }
707
+ if (isObject(value)) {
708
+ _set__default(result, key, deflattenQuery(value));
709
+ return;
710
+ }
711
+ _set__default(result, key, query[key]);
712
+ });
713
+ return result;
714
+ }
715
+
634
716
  function checkMulti() {
635
717
  return (context) => {
636
718
  if (shouldSkip("checkMulti", context)) {
@@ -948,12 +1030,6 @@ const paramsFromClient = defineParamsFromClient(
948
1030
  FROM_CLIENT_FOR_SERVER_DEFAULT_KEY
949
1031
  );
950
1032
 
951
- var __defProp = Object.defineProperty;
952
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
953
- var __publicField = (obj, key, value) => {
954
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
955
- return value;
956
- };
957
1033
  const makeDefaultOptions = () => {
958
1034
  return {
959
1035
  leading: false,
@@ -962,6 +1038,13 @@ const makeDefaultOptions = () => {
962
1038
  wait: 100
963
1039
  };
964
1040
  };
1041
+
1042
+ var __defProp = Object.defineProperty;
1043
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1044
+ var __publicField = (obj, key, value) => {
1045
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1046
+ return value;
1047
+ };
965
1048
  class DebouncedStore {
966
1049
  constructor(app, options) {
967
1050
  __publicField(this, "_app");
@@ -1054,7 +1137,7 @@ const filterArray = (...keys) => {
1054
1137
  };
1055
1138
 
1056
1139
  const filterQueryObject = (key) => (obj, { operators }) => {
1057
- if (obj && !_isObject__default(obj)) {
1140
+ if (obj && !isObject(obj)) {
1058
1141
  throw new Error(
1059
1142
  `Invalid query parameter: '${key}'. It has to be an object`
1060
1143
  );
@@ -1076,15 +1159,16 @@ exports.debounceMixin = debounceMixin;
1076
1159
  exports.defineHooks = defineHooks;
1077
1160
  exports.defineParamsForServer = defineParamsForServer;
1078
1161
  exports.defineParamsFromClient = defineParamsFromClient;
1162
+ exports.deflattenQuery = deflattenQuery;
1079
1163
  exports.filterArray = filterArray;
1080
1164
  exports.filterObject = filterObject;
1081
1165
  exports.filterQuery = filterQuery;
1166
+ exports.flattenQuery = flattenQuery;
1082
1167
  exports.forEach = forEach;
1083
1168
  exports.getItemsIsArray = getItemsIsArray;
1084
1169
  exports.getPaginate = getPaginate;
1085
1170
  exports.isMulti = isMulti;
1086
1171
  exports.isPaginated = isPaginated;
1087
- exports.makeDefaultOptions = makeDefaultOptions;
1088
1172
  exports.markHookForSkip = markHookForSkip;
1089
1173
  exports.mergeArrays = mergeArrays;
1090
1174
  exports.mergeQuery = mergeQuery;
@@ -1094,6 +1178,7 @@ exports.paramsForServer = paramsForServer;
1094
1178
  exports.paramsFromClient = paramsFromClient;
1095
1179
  exports.parseFields = parseFields;
1096
1180
  exports.pushSet = pushSet;
1181
+ exports.reassembleQuery = reassembleQuery;
1097
1182
  exports.removeRelated = removeRelated;
1098
1183
  exports.runPerItem = runPerItem;
1099
1184
  exports.setData = setData;
package/dist/index.d.cts CHANGED
@@ -14,6 +14,7 @@ type MaybeArray<T> = T | T[];
14
14
  type Promisable<T> = T | Promise<T>;
15
15
  type Path = Array<string | number>;
16
16
  type ReturnAsyncHook<H extends HookContext$1 = HookContext$1> = (context: H) => Promise<H>;
17
+ type KeyOf<T> = Extract<keyof T, string>;
17
18
 
18
19
  interface CreateRelatedOptions<S = Record<string, any>> {
19
20
  service: keyof S;
@@ -127,7 +128,6 @@ interface DebouncedStoreOptions {
127
128
  wait: number;
128
129
  }
129
130
 
130
- declare const makeDefaultOptions: () => DebouncedStoreOptions;
131
131
  type DebouncedService<T = any> = T & {
132
132
  debouncedStore: DebouncedStore;
133
133
  };
@@ -154,7 +154,7 @@ declare function defineHooks<A extends Application = Application, S = {
154
154
  remove: any;
155
155
  }, Options = HookOptions<A, S>>(hooks: Options): Options;
156
156
 
157
- type FilterQueryResult<Q extends Query> = {
157
+ type FilterQueryResult<Q extends Query = Query> = {
158
158
  $select: Q["$select"] extends any ? Q["$select"] : never;
159
159
  $limit: Q["$limit"] extends any ? Q["$limit"] : never;
160
160
  $skip: Q["$skip"] extends any ? Q["$skip"] : never;
@@ -168,6 +168,7 @@ type FilterQueryResult<Q extends Query> = {
168
168
  * @returns
169
169
  */
170
170
  declare function filterQuery<Q extends Query>(providedQuery?: Q): FilterQueryResult<Q>;
171
+ declare function reassembleQuery(query: FilterQueryResult): Query;
171
172
 
172
173
  /**
173
174
  * util to get paginate options from context
@@ -199,7 +200,6 @@ declare const isPaginated: <H extends HookContext<_feathersjs_feathers.Applicati
199
200
  declare function markHookForSkip<H extends HookContext = HookContext>(hookName: string, type: "all" | MaybeArray<HookType>, context?: H): H;
200
201
 
201
202
  type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
202
- type FirstLast = "first" | "last";
203
203
  type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
204
204
  interface MergeQueryOptions {
205
205
  defaultHandle: Handle;
@@ -232,7 +232,7 @@ declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val:
232
232
  type SetQueryKeySafelyOptions = {
233
233
  mutate?: boolean;
234
234
  };
235
- declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
235
+ declare const setQueryKeySafely: (params: Params, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => Params;
236
236
 
237
237
  /**
238
238
  * util to set `context.result` to an empty array or object, depending on the hook type
@@ -254,11 +254,16 @@ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers
254
254
  */
255
255
  declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
256
256
 
257
- type OptimizeBatchPatchOptions = {
258
- id?: string;
257
+ type OptimizeBatchPatchOptions<IdKey extends string> = {
258
+ /** the key of the id property */
259
+ id?: IdKey;
259
260
  };
260
261
  type OptimizeBatchPatchResultItem<T = Record<string, unknown>, P = Params> = [Id, T, P | undefined];
261
- declare function optimizeBatchPatch<T extends Record<string, unknown>, P extends Params>(items: Map<Id, T>, options?: OptimizeBatchPatchOptions): OptimizeBatchPatchResultItem<T, P>[];
262
+ declare function optimizeBatchPatch<T extends Record<string, any>, IdKey extends KeyOf<T>, P extends Params, R extends Omit<T, IdKey> = Omit<T, IdKey>>(items: T[], options?: OptimizeBatchPatchOptions<IdKey>): OptimizeBatchPatchResultItem<R, P>[];
263
+
264
+ declare function flattenQuery(q: Query): any;
265
+
266
+ declare function deflattenQuery(query: Query): Query;
262
267
 
263
268
  declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
264
269
 
@@ -310,4 +315,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
310
315
  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;
311
316
  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;
312
317
 
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 };
318
+ export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, 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, deflattenQuery, filterArray, filterObject, filterQuery, flattenQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, paramsForServer, paramsFromClient, parseFields, pushSet, reassembleQuery, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
package/dist/index.d.mts CHANGED
@@ -14,6 +14,7 @@ type MaybeArray<T> = T | T[];
14
14
  type Promisable<T> = T | Promise<T>;
15
15
  type Path = Array<string | number>;
16
16
  type ReturnAsyncHook<H extends HookContext$1 = HookContext$1> = (context: H) => Promise<H>;
17
+ type KeyOf<T> = Extract<keyof T, string>;
17
18
 
18
19
  interface CreateRelatedOptions<S = Record<string, any>> {
19
20
  service: keyof S;
@@ -127,7 +128,6 @@ interface DebouncedStoreOptions {
127
128
  wait: number;
128
129
  }
129
130
 
130
- declare const makeDefaultOptions: () => DebouncedStoreOptions;
131
131
  type DebouncedService<T = any> = T & {
132
132
  debouncedStore: DebouncedStore;
133
133
  };
@@ -154,7 +154,7 @@ declare function defineHooks<A extends Application = Application, S = {
154
154
  remove: any;
155
155
  }, Options = HookOptions<A, S>>(hooks: Options): Options;
156
156
 
157
- type FilterQueryResult<Q extends Query> = {
157
+ type FilterQueryResult<Q extends Query = Query> = {
158
158
  $select: Q["$select"] extends any ? Q["$select"] : never;
159
159
  $limit: Q["$limit"] extends any ? Q["$limit"] : never;
160
160
  $skip: Q["$skip"] extends any ? Q["$skip"] : never;
@@ -168,6 +168,7 @@ type FilterQueryResult<Q extends Query> = {
168
168
  * @returns
169
169
  */
170
170
  declare function filterQuery<Q extends Query>(providedQuery?: Q): FilterQueryResult<Q>;
171
+ declare function reassembleQuery(query: FilterQueryResult): Query;
171
172
 
172
173
  /**
173
174
  * util to get paginate options from context
@@ -199,7 +200,6 @@ declare const isPaginated: <H extends HookContext<_feathersjs_feathers.Applicati
199
200
  declare function markHookForSkip<H extends HookContext = HookContext>(hookName: string, type: "all" | MaybeArray<HookType>, context?: H): H;
200
201
 
201
202
  type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
202
- type FirstLast = "first" | "last";
203
203
  type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
204
204
  interface MergeQueryOptions {
205
205
  defaultHandle: Handle;
@@ -232,7 +232,7 @@ declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val:
232
232
  type SetQueryKeySafelyOptions = {
233
233
  mutate?: boolean;
234
234
  };
235
- declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
235
+ declare const setQueryKeySafely: (params: Params, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => Params;
236
236
 
237
237
  /**
238
238
  * util to set `context.result` to an empty array or object, depending on the hook type
@@ -254,11 +254,16 @@ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers
254
254
  */
255
255
  declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
256
256
 
257
- type OptimizeBatchPatchOptions = {
258
- id?: string;
257
+ type OptimizeBatchPatchOptions<IdKey extends string> = {
258
+ /** the key of the id property */
259
+ id?: IdKey;
259
260
  };
260
261
  type OptimizeBatchPatchResultItem<T = Record<string, unknown>, P = Params> = [Id, T, P | undefined];
261
- declare function optimizeBatchPatch<T extends Record<string, unknown>, P extends Params>(items: Map<Id, T>, options?: OptimizeBatchPatchOptions): OptimizeBatchPatchResultItem<T, P>[];
262
+ declare function optimizeBatchPatch<T extends Record<string, any>, IdKey extends KeyOf<T>, P extends Params, R extends Omit<T, IdKey> = Omit<T, IdKey>>(items: T[], options?: OptimizeBatchPatchOptions<IdKey>): OptimizeBatchPatchResultItem<R, P>[];
263
+
264
+ declare function flattenQuery(q: Query): any;
265
+
266
+ declare function deflattenQuery(query: Query): Query;
262
267
 
263
268
  declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
264
269
 
@@ -310,4 +315,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
310
315
  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;
311
316
  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;
312
317
 
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 };
318
+ export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, 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, deflattenQuery, filterArray, filterObject, filterQuery, flattenQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, paramsForServer, paramsFromClient, parseFields, pushSet, reassembleQuery, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ type MaybeArray<T> = T | T[];
14
14
  type Promisable<T> = T | Promise<T>;
15
15
  type Path = Array<string | number>;
16
16
  type ReturnAsyncHook<H extends HookContext$1 = HookContext$1> = (context: H) => Promise<H>;
17
+ type KeyOf<T> = Extract<keyof T, string>;
17
18
 
18
19
  interface CreateRelatedOptions<S = Record<string, any>> {
19
20
  service: keyof S;
@@ -127,7 +128,6 @@ interface DebouncedStoreOptions {
127
128
  wait: number;
128
129
  }
129
130
 
130
- declare const makeDefaultOptions: () => DebouncedStoreOptions;
131
131
  type DebouncedService<T = any> = T & {
132
132
  debouncedStore: DebouncedStore;
133
133
  };
@@ -154,7 +154,7 @@ declare function defineHooks<A extends Application = Application, S = {
154
154
  remove: any;
155
155
  }, Options = HookOptions<A, S>>(hooks: Options): Options;
156
156
 
157
- type FilterQueryResult<Q extends Query> = {
157
+ type FilterQueryResult<Q extends Query = Query> = {
158
158
  $select: Q["$select"] extends any ? Q["$select"] : never;
159
159
  $limit: Q["$limit"] extends any ? Q["$limit"] : never;
160
160
  $skip: Q["$skip"] extends any ? Q["$skip"] : never;
@@ -168,6 +168,7 @@ type FilterQueryResult<Q extends Query> = {
168
168
  * @returns
169
169
  */
170
170
  declare function filterQuery<Q extends Query>(providedQuery?: Q): FilterQueryResult<Q>;
171
+ declare function reassembleQuery(query: FilterQueryResult): Query;
171
172
 
172
173
  /**
173
174
  * util to get paginate options from context
@@ -199,7 +200,6 @@ declare const isPaginated: <H extends HookContext<_feathersjs_feathers.Applicati
199
200
  declare function markHookForSkip<H extends HookContext = HookContext>(hookName: string, type: "all" | MaybeArray<HookType>, context?: H): H;
200
201
 
201
202
  type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
202
- type FirstLast = "first" | "last";
203
203
  type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
204
204
  interface MergeQueryOptions {
205
205
  defaultHandle: Handle;
@@ -232,7 +232,7 @@ declare const pushSet: (obj: Record<string, unknown>, path: string | Path, val:
232
232
  type SetQueryKeySafelyOptions = {
233
233
  mutate?: boolean;
234
234
  };
235
- declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
235
+ declare const setQueryKeySafely: (params: Params, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => Params;
236
236
 
237
237
  /**
238
238
  * util to set `context.result` to an empty array or object, depending on the hook type
@@ -254,11 +254,16 @@ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers
254
254
  */
255
255
  declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
256
256
 
257
- type OptimizeBatchPatchOptions = {
258
- id?: string;
257
+ type OptimizeBatchPatchOptions<IdKey extends string> = {
258
+ /** the key of the id property */
259
+ id?: IdKey;
259
260
  };
260
261
  type OptimizeBatchPatchResultItem<T = Record<string, unknown>, P = Params> = [Id, T, P | undefined];
261
- declare function optimizeBatchPatch<T extends Record<string, unknown>, P extends Params>(items: Map<Id, T>, options?: OptimizeBatchPatchOptions): OptimizeBatchPatchResultItem<T, P>[];
262
+ declare function optimizeBatchPatch<T extends Record<string, any>, IdKey extends KeyOf<T>, P extends Params, R extends Omit<T, IdKey> = Omit<T, IdKey>>(items: T[], options?: OptimizeBatchPatchOptions<IdKey>): OptimizeBatchPatchResultItem<R, P>[];
263
+
264
+ declare function flattenQuery(q: Query): any;
265
+
266
+ declare function deflattenQuery(query: Query): Query;
262
267
 
263
268
  declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
264
269
 
@@ -310,4 +315,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
310
315
  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;
311
316
  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;
312
317
 
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 };
318
+ export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, 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, deflattenQuery, filterArray, filterObject, filterQuery, flattenQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, markHookForSkip, mergeArrays, mergeQuery, onDelete, optimizeBatchPatch, paramsForServer, paramsFromClient, parseFields, pushSet, reassembleQuery, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };