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
@@ -1,15 +1,15 @@
1
- import _merge from "lodash/merge.js";
2
- import type { Query } from "@feathersjs/feathers";
1
+ import _merge from 'lodash/merge.js'
2
+ import type { Query } from '@feathersjs/feathers'
3
3
  import {
4
4
  areQueriesOverlapping,
5
5
  handleArray,
6
6
  handleCircular,
7
7
  isQueryMoreExplicitThanQuery,
8
8
  makeDefaultOptions,
9
- } from "./utils";
10
- import type { MergeQueryOptions } from "./types";
11
- import { filterQuery } from "../filterQuery";
12
- import { hasOwnProperty, isEmpty } from "../_utils.internal";
9
+ } from './utils.js'
10
+ import type { MergeQueryOptions } from './types.js'
11
+ import { filterQuery } from '../filterQuery.js'
12
+ import { hasOwnProperty, isEmpty } from '../_utils.internal.js'
13
13
 
14
14
  /**
15
15
  * Merges two queries into one.
@@ -23,111 +23,111 @@ export function mergeQuery(
23
23
  source: Query,
24
24
  _options?: Partial<MergeQueryOptions>,
25
25
  ): Query {
26
- const options = makeDefaultOptions(_options);
26
+ const options = makeDefaultOptions(_options)
27
27
 
28
- const { query: targetQuery, ...targetFilters } = filterQuery(target);
28
+ const { query: targetQuery, ...targetFilters } = filterQuery(target)
29
29
 
30
30
  // eslint-disable-next-line prefer-const
31
- let { query: sourceQuery, ...sourceFilters } = filterQuery(source);
31
+ let { query: sourceQuery, ...sourceFilters } = filterQuery(source)
32
32
 
33
33
  //#region filters
34
- handleArray(targetFilters, sourceFilters, ["$select"], options);
34
+ handleArray(targetFilters, sourceFilters, ['$select'], options)
35
35
  // remaining filters
36
- delete sourceFilters["$select"];
37
- _merge(targetFilters, sourceFilters);
36
+ delete sourceFilters['$select']
37
+ _merge(targetFilters, sourceFilters)
38
38
 
39
39
  //#endregion
40
40
 
41
- const subsetQuery = isQueryMoreExplicitThanQuery(targetQuery, sourceQuery);
41
+ const subsetQuery = isQueryMoreExplicitThanQuery(targetQuery, sourceQuery)
42
42
 
43
43
  if (
44
- options.defaultHandle === "intersect" &&
44
+ options.defaultHandle === 'intersect' &&
45
45
  !!subsetQuery &&
46
- !hasOwnProperty(targetQuery, "$or", "$and") &&
47
- !hasOwnProperty(sourceQuery, "$or", "$and")
46
+ !hasOwnProperty(targetQuery, '$or', '$and') &&
47
+ !hasOwnProperty(sourceQuery, '$or', '$and')
48
48
  ) {
49
49
  return {
50
50
  ...targetFilters,
51
51
  ...subsetQuery,
52
- };
52
+ }
53
53
  }
54
54
 
55
55
  if (
56
- options.defaultHandle === "intersect" &&
56
+ options.defaultHandle === 'intersect' &&
57
57
  !areQueriesOverlapping(targetQuery, sourceQuery) &&
58
- !hasOwnProperty(targetQuery, "$or", "$and") &&
59
- !hasOwnProperty(sourceQuery, "$or", "$and")
58
+ !hasOwnProperty(targetQuery, '$or', '$and') &&
59
+ !hasOwnProperty(sourceQuery, '$or', '$and')
60
60
  ) {
61
61
  return {
62
62
  ...targetFilters,
63
63
  ...targetQuery,
64
64
  ...sourceQuery,
65
- };
65
+ }
66
66
  }
67
67
 
68
68
  //#region '$or' / '$and'
69
69
 
70
70
  if (
71
71
  options.useLogicalConjunction &&
72
- (options.defaultHandle === "combine" ||
73
- options.defaultHandle === "intersect") &&
72
+ (options.defaultHandle === 'combine' ||
73
+ options.defaultHandle === 'intersect') &&
74
74
  !isEmpty(targetQuery)
75
75
  ) {
76
- const logicalOp = options.defaultHandle === "combine" ? "$or" : "$and";
76
+ const logicalOp = options.defaultHandle === 'combine' ? '$or' : '$and'
77
77
  if (hasOwnProperty(sourceQuery, logicalOp)) {
78
78
  // omit '$or'/'$and' and put all other props into '$or'/'$and'
79
- const andOr = sourceQuery[logicalOp] as unknown[];
80
- delete sourceQuery[logicalOp];
81
- andOr.push(sourceQuery);
82
- sourceQuery = { [logicalOp]: andOr };
79
+ const andOr = sourceQuery[logicalOp] as unknown[]
80
+ delete sourceQuery[logicalOp]
81
+ andOr.push(sourceQuery)
82
+ sourceQuery = { [logicalOp]: andOr }
83
83
  } else {
84
- sourceQuery = { [logicalOp]: [sourceQuery] };
84
+ sourceQuery = { [logicalOp]: [sourceQuery] }
85
85
  }
86
86
  }
87
87
 
88
88
  //#endregion
89
89
 
90
- const keys = Object.keys(sourceQuery);
90
+ const keys = Object.keys(sourceQuery)
91
91
  for (let i = 0, n = keys.length; i < n; i++) {
92
- const key = keys[i];
93
- handleCircular(targetQuery, sourceQuery, [key], options);
92
+ const key = keys[i]
93
+ handleCircular(targetQuery, sourceQuery, [key], options)
94
94
  }
95
95
 
96
96
  return {
97
97
  ...targetFilters,
98
98
  ...targetQuery,
99
- };
99
+ }
100
100
  }
101
101
 
102
102
  if (import.meta.vitest) {
103
- const { it, describe, expect } = import.meta.vitest;
104
- const { feathers } = await import("@feathersjs/feathers");
105
- const { MemoryService } = await import("@feathersjs/memory");
106
- const { filterArray } = await import("../../filters/array");
107
- const { Forbidden } = await import("@feathersjs/errors");
103
+ const { it, describe, expect } = import.meta.vitest
104
+ const { feathers } = await import('@feathersjs/feathers')
105
+ const { MemoryService } = await import('@feathersjs/memory')
106
+ const { filterArray } = await import('../../filters/array.js')
107
+ const { Forbidden } = await import('@feathersjs/errors')
108
108
 
109
- describe("general", function () {
110
- it("$limit: -1", function () {
109
+ describe('general', function () {
110
+ it('$limit: -1', function () {
111
111
  expect(mergeQuery({ $limit: -1 }, { id: 1 })).toEqual({
112
112
  $limit: -1,
113
113
  id: 1,
114
- });
115
- });
116
- });
114
+ })
115
+ })
116
+ })
117
117
 
118
- describe("simple objects passing", function () {
119
- const app = feathers();
118
+ describe('simple objects passing', function () {
119
+ const app = feathers()
120
120
  app.use(
121
- "/service",
121
+ '/service',
122
122
  new MemoryService({
123
123
  paginate: { default: 10, max: 100 },
124
- operators: ["$and"],
124
+ operators: ['$and'],
125
125
  filters: {
126
- ...filterArray("$and"),
126
+ ...filterArray('$and'),
127
127
  },
128
128
  }),
129
- );
130
- const service = app.service("/service");
129
+ )
130
+ const service = app.service('/service')
131
131
  const passingPairs = {
132
132
  empty: {
133
133
  target: {},
@@ -138,100 +138,100 @@ if (import.meta.vitest) {
138
138
  target: {
139
139
  target: { id: 1, test1: true },
140
140
  source: { id: 2, test2: false },
141
- options: { defaultHandle: "target", useLogicalConjunction: false },
141
+ options: { defaultHandle: 'target', useLogicalConjunction: false },
142
142
  expected: { id: 1, test1: true, test2: false },
143
143
  },
144
144
  source: {
145
145
  target: { id: 1, test1: true },
146
146
  source: { id: 2, test2: false },
147
- options: { defaultHandle: "source", useLogicalConjunction: false },
147
+ options: { defaultHandle: 'source', useLogicalConjunction: false },
148
148
  expected: { id: 2, test1: true, test2: false },
149
149
  },
150
- "native booleans": {
150
+ 'native booleans': {
151
151
  target: { test: true },
152
152
  source: { test: false },
153
153
  options: { useLogicalConjunction: false },
154
154
  expected: { test: false },
155
155
  },
156
- "native nested to boolean": {
156
+ 'native nested to boolean': {
157
157
  target: { test: { nested: [{ deep: true }] } },
158
158
  source: { test: false },
159
159
  options: { useLogicalConjunction: false },
160
160
  expected: { test: false },
161
161
  },
162
- };
162
+ }
163
163
  for (const key in passingPairs) {
164
- const { target, source, options, expected } = passingPairs[key];
164
+ const { target, source, options, expected } = (passingPairs as any)[key]
165
165
  it(`'${key}'`, function () {
166
166
  expect(
167
167
  mergeQuery(target, source, Object.assign({ service }, options)),
168
- ).toEqual(expected);
169
- });
168
+ ).toEqual(expected)
169
+ })
170
170
  }
171
- });
171
+ })
172
172
 
173
- describe("simple objects passing with handle combine", function () {
174
- const app = feathers();
173
+ describe('simple objects passing with handle combine', function () {
174
+ const app = feathers()
175
175
  app.use(
176
- "/service",
176
+ '/service',
177
177
  new MemoryService({
178
178
  paginate: { default: 10, max: 100 },
179
- operators: ["$and"],
179
+ operators: ['$and'],
180
180
  filters: {
181
- ...filterArray("$and"),
181
+ ...filterArray('$and'),
182
182
  },
183
183
  }),
184
- );
185
- const service = app.service("/service");
184
+ )
185
+ const service = app.service('/service')
186
186
  const passingPairs = {
187
- "combine two numbers": {
187
+ 'combine two numbers': {
188
188
  target: { id: 1 },
189
189
  source: { id: 2 },
190
- options: { defaultHandle: "combine", useLogicalConjunction: false },
190
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
191
191
  expected: { id: { $in: [1, 2] } },
192
192
  },
193
- "combine $in different types": {
194
- target: { id: "1" },
193
+ 'combine $in different types': {
194
+ target: { id: '1' },
195
195
  source: { id: 2 },
196
- options: { defaultHandle: "combine", useLogicalConjunction: false },
197
- expected: { id: { $in: ["1", 2] } },
196
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
197
+ expected: { id: { $in: ['1', 2] } },
198
198
  },
199
- "combine number to $in with overlapping": {
199
+ 'combine number to $in with overlapping': {
200
200
  target: { id: 1 },
201
201
  source: { id: { $in: [1, 2] } },
202
- options: { defaultHandle: "combine", useLogicalConjunction: false },
202
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
203
203
  expected: { id: { $in: [1, 2] } },
204
204
  },
205
- "combine numbers in $in": {
205
+ 'combine numbers in $in': {
206
206
  target: { id: 1 },
207
207
  source: { id: { $in: [2, 3] } },
208
- options: { defaultHandle: "combine", useLogicalConjunction: false },
208
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
209
209
  expected: { id: { $in: [2, 3, 1] } },
210
210
  },
211
- "combine two $in": {
211
+ 'combine two $in': {
212
212
  target: { id: { $in: [2] } },
213
213
  source: { id: { $in: [3, 4] } },
214
- options: { defaultHandle: "combine", useLogicalConjunction: false },
214
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
215
215
  expected: { id: { $in: [2, 3, 4] } },
216
216
  },
217
- "combine two $or queries": {
217
+ 'combine two $or queries': {
218
218
  target: { $or: [{ id: 1 }, { id: 2 }] },
219
219
  source: { $or: [{ id: 3 }] },
220
- options: { defaultHandle: "combine", useLogicalConjunction: false },
220
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
221
221
  expected: { $or: [{ id: 1 }, { id: 2 }, { id: 3 }] },
222
222
  },
223
- "combine two $and queries": {
223
+ 'combine two $and queries': {
224
224
  target: { $and: [{ id: 1 }, { id: 2 }] },
225
225
  source: { $and: [{ id: 3 }] },
226
- options: { defaultHandle: "combine", useLogicalConjunction: false },
226
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
227
227
  expected: {
228
228
  $or: [{ $and: [{ id: 1 }, { id: 2 }] }, { $and: [{ id: 3 }] }],
229
229
  },
230
230
  },
231
- "combine $or and $and queries": {
231
+ 'combine $or and $and queries': {
232
232
  target: { $or: [{ id: 1 }, { id: 2 }], $and: [{ id: 4 }] },
233
233
  source: { $or: [{ id: 3 }], $and: [{ id: 5 }] },
234
- options: { defaultHandle: "combine", useLogicalConjunction: false },
234
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
235
235
  expected: {
236
236
  $or: [
237
237
  { id: 1 },
@@ -242,161 +242,161 @@ if (import.meta.vitest) {
242
242
  ],
243
243
  },
244
244
  },
245
- "removes empty $or for both": {
245
+ 'removes empty $or for both': {
246
246
  target: { $or: [{}] },
247
247
  source: { $or: [{}] },
248
- options: { defaultHandle: "combine", useLogicalConjunction: false },
248
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
249
249
  expected: {},
250
250
  },
251
- "removes empty $and for both": {
251
+ 'removes empty $and for both': {
252
252
  target: { $and: [{}] },
253
253
  source: { $and: [{}] },
254
- options: { defaultHandle: "combine", useLogicalConjunction: false },
254
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
255
255
  expected: {},
256
256
  },
257
- "removes duplicate entries in $or": {
257
+ 'removes duplicate entries in $or': {
258
258
  target: { $or: [{ id: 1 }, { id: 1 }, { id: 2 }] },
259
259
  source: { $or: [{ id: 2 }] },
260
- options: { defaultHandle: "combine", useLogicalConjunction: false },
260
+ options: { defaultHandle: 'combine', useLogicalConjunction: false },
261
261
  expected: { $or: [{ id: 1 }, { id: 2 }] },
262
262
  },
263
- "$in and other props": {
264
- target: { id: { $in: [1, 2, 3] }, status: "complete" },
263
+ '$in and other props': {
264
+ target: { id: { $in: [1, 2, 3] }, status: 'complete' },
265
265
  source: {
266
266
  id: { $in: [2, 3, 4] },
267
- status: { $in: ["complete", "pending", "draft"] },
267
+ status: { $in: ['complete', 'pending', 'draft'] },
268
268
  },
269
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
270
- expected: { id: { $in: [2, 3] }, status: "complete" },
269
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
270
+ expected: { id: { $in: [2, 3] }, status: 'complete' },
271
271
  },
272
- };
272
+ }
273
273
  for (const key in passingPairs) {
274
- const { target, source, options, expected } = passingPairs[key];
274
+ const { target, source, options, expected } = (passingPairs as any)[key]
275
275
  it(`'${key}'`, function () {
276
276
  expect(
277
277
  mergeQuery(target, source, Object.assign({ service }, options)),
278
- ).toEqual(expected);
279
- });
278
+ ).toEqual(expected)
279
+ })
280
280
  }
281
281
 
282
- describe("with useLogicalConjunction: true", function () {
283
- const app = feathers();
282
+ describe('with useLogicalConjunction: true', function () {
283
+ const app = feathers()
284
284
  app.use(
285
- "/service",
285
+ '/service',
286
286
  new MemoryService({
287
287
  paginate: { default: 10, max: 100 },
288
- operators: ["$and"],
288
+ operators: ['$and'],
289
289
  filters: {
290
- ...filterArray("$and"),
290
+ ...filterArray('$and'),
291
291
  },
292
292
  }),
293
- );
294
- const service = app.service("/service");
293
+ )
294
+ const service = app.service('/service')
295
295
  const passingPairs = {
296
- "merge empty source": {
296
+ 'merge empty source': {
297
297
  target: { id: 1 },
298
298
  source: {},
299
- options: { defaultHandle: "combine", useLogicalConjunction: true },
299
+ options: { defaultHandle: 'combine', useLogicalConjunction: true },
300
300
  expected: { id: 1 },
301
301
  },
302
- "merge empty target": {
302
+ 'merge empty target': {
303
303
  target: {},
304
304
  source: { id: 1 },
305
- options: { defaultHandle: "combine", useLogicalConjunction: true },
305
+ options: { defaultHandle: 'combine', useLogicalConjunction: true },
306
306
  expected: { id: 1 },
307
307
  },
308
- "merge queries with $or": {
308
+ 'merge queries with $or': {
309
309
  target: { id: 1 },
310
310
  source: { $or: [{ id: { $in: [1, 3] } }], id: 2 },
311
- options: { defaultHandle: "combine", useLogicalConjunction: true },
311
+ options: { defaultHandle: 'combine', useLogicalConjunction: true },
312
312
  expected: { id: 1, $or: [{ id: { $in: [1, 3] } }, { id: 2 }] },
313
313
  },
314
- "merge queries with existing $or": {
314
+ 'merge queries with existing $or': {
315
315
  target: { id: 1 },
316
316
  source: { $or: [{ id: { $in: [1, 3] } }], id: 2 },
317
- options: { defaultHandle: "combine", useLogicalConjunction: true },
317
+ options: { defaultHandle: 'combine', useLogicalConjunction: true },
318
318
  expected: { id: 1, $or: [{ id: { $in: [1, 3] } }, { id: 2 }] },
319
319
  },
320
- "merge queries with existing $and": {
320
+ 'merge queries with existing $and': {
321
321
  target: { id: 1 },
322
322
  source: { $and: [{ id: 2 }] },
323
- options: { defaultHandle: "combine", useLogicalConjunction: true },
323
+ options: { defaultHandle: 'combine', useLogicalConjunction: true },
324
324
  expected: { id: 1, $or: [{ $and: [{ id: 2 }] }] },
325
325
  },
326
- "merge queries with existing $or in target": {
326
+ 'merge queries with existing $or in target': {
327
327
  target: { $or: [{ id: 1 }], id: 3 },
328
328
  source: { id: 2 },
329
- options: { defaultHandle: "combine", useLogicalConjunction: true },
329
+ options: { defaultHandle: 'combine', useLogicalConjunction: true },
330
330
  expected: { $or: [{ id: 1 }, { id: 2 }], id: 3 },
331
331
  },
332
- };
332
+ }
333
333
  for (const key in passingPairs) {
334
- const { target, source, options, expected } = passingPairs[key];
334
+ const { target, source, options, expected } = (passingPairs as any)[key]
335
335
  it(`'${key}'`, function () {
336
336
  expect(
337
337
  mergeQuery(target, source, Object.assign({ service }, options)),
338
- ).toEqual(expected);
339
- });
338
+ ).toEqual(expected)
339
+ })
340
340
  }
341
- });
342
- });
341
+ })
342
+ })
343
343
 
344
- describe("simple objects passing with handle intersect", function () {
345
- const app = feathers();
344
+ describe('simple objects passing with handle intersect', function () {
345
+ const app = feathers()
346
346
  app.use(
347
- "/service",
347
+ '/service',
348
348
  new MemoryService({
349
349
  paginate: { default: 10, max: 100 },
350
- whitelist: ["$and"],
350
+ whitelist: ['$and'],
351
351
  filters: {
352
- ...filterArray("$and"),
352
+ ...filterArray('$and'),
353
353
  },
354
354
  }),
355
- );
356
- const service = app.service("/service");
355
+ )
356
+ const service = app.service('/service')
357
357
  const passingPairs = {
358
- "intersect number and overlapping $in": {
358
+ 'intersect number and overlapping $in': {
359
359
  target: { id: 1 },
360
360
  source: { id: { $in: [1, 3] } },
361
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
361
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
362
362
  expected: { id: 1 },
363
363
  },
364
- "intersect $in and $in with overlapping": {
364
+ 'intersect $in and $in with overlapping': {
365
365
  target: { id: { $in: [1, 2] } },
366
366
  source: { id: { $in: [1, 3] } },
367
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
367
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
368
368
  expected: { id: 1 },
369
369
  },
370
- "$limit for target stays the same": {
370
+ '$limit for target stays the same': {
371
371
  target: { $limit: 50, $skip: 10, $sort: { id: 1 } },
372
372
  source: { id: 1 },
373
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
373
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
374
374
  expected: { id: 1, $limit: 50, $skip: 10, $sort: { id: 1 } },
375
375
  },
376
- "$limit gets overridden": {
376
+ '$limit gets overridden': {
377
377
  target: { $limit: 50, $skip: 10, $sort: { id: 1 } },
378
378
  source: { $limit: 10, id: 1 },
379
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
379
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
380
380
  expected: { id: 1, $limit: 10, $skip: 10, $sort: { id: 1 } },
381
381
  },
382
- "intersects two $or queries": {
382
+ 'intersects two $or queries': {
383
383
  target: { $or: [{ id: 1 }, { id: 2 }] },
384
384
  source: { $or: [{ id: 3 }] },
385
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
385
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
386
386
  expected: {
387
387
  $and: [{ $or: [{ id: 1 }, { id: 2 }] }, { $or: [{ id: 3 }] }],
388
388
  },
389
389
  },
390
- "intersects two $and queries": {
390
+ 'intersects two $and queries': {
391
391
  target: { $and: [{ id: 1 }, { id: 2 }] },
392
392
  source: { $and: [{ id: 3 }] },
393
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
393
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
394
394
  expected: { $and: [{ id: 1 }, { id: 2 }, { id: 3 }] },
395
395
  },
396
- "intersect $or and $and queries": {
396
+ 'intersect $or and $and queries': {
397
397
  target: { $or: [{ id: 1 }, { id: 2 }], $and: [{ id: 4 }] },
398
398
  source: { $or: [{ id: 3 }], $and: [{ id: 5 }] },
399
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
399
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
400
400
  expected: {
401
401
  $and: [
402
402
  { id: 4 },
@@ -406,157 +406,157 @@ if (import.meta.vitest) {
406
406
  ],
407
407
  },
408
408
  },
409
- "cleans up $and with empty entries": {
409
+ 'cleans up $and with empty entries': {
410
410
  target: { $and: [{}, { id: 1 }, { id: 1 }, { id: 2 }] },
411
411
  source: { $and: [{}, { id: 2 }] },
412
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
412
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
413
413
  expected: { $and: [{ id: 1 }, { id: 2 }] },
414
414
  },
415
- "removes duplicate entries in $and": {
415
+ 'removes duplicate entries in $and': {
416
416
  target: { $and: [{ id: 1 }, { id: 1 }, { id: 2 }] },
417
417
  source: { $and: [{ id: 2 }] },
418
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
418
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
419
419
  expected: { $and: [{ id: 1 }, { id: 2 }] },
420
420
  },
421
- "removes unnecessary $or in target with intersect": {
421
+ 'removes unnecessary $or in target with intersect': {
422
422
  target: { $or: [{ id: 1 }, {}] },
423
- source: { hi: "test" },
424
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
425
- expected: { hi: "test" },
423
+ source: { hi: 'test' },
424
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
425
+ expected: { hi: 'test' },
426
426
  },
427
- "removes unnecessary $or in source with intersect": {
428
- target: { hi: "test" },
427
+ 'removes unnecessary $or in source with intersect': {
428
+ target: { hi: 'test' },
429
429
  source: { $or: [{ id: 1 }, {}] },
430
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
431
- expected: { hi: "test" },
430
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
431
+ expected: { hi: 'test' },
432
432
  },
433
- "$in and other props": {
434
- target: { id: { $in: [1, 2, 3] }, status: "complete" },
433
+ '$in and other props': {
434
+ target: { id: { $in: [1, 2, 3] }, status: 'complete' },
435
435
  source: {
436
436
  id: { $in: [2, 3, 4] },
437
- status: { $in: ["complete", "pending", "draft"] },
437
+ status: { $in: ['complete', 'pending', 'draft'] },
438
438
  },
439
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
440
- expected: { id: { $in: [2, 3] }, status: "complete" },
439
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
440
+ expected: { id: { $in: [2, 3] }, status: 'complete' },
441
441
  },
442
- };
442
+ }
443
443
  for (const key in passingPairs) {
444
- const { target, source, options, expected } = passingPairs[key];
444
+ const { target, source, options, expected } = (passingPairs as any)[key]
445
445
  it(`'${key}'`, function () {
446
446
  expect(
447
447
  mergeQuery(target, source, Object.assign({ service }, options)),
448
- ).toEqual(expected);
449
- });
448
+ ).toEqual(expected)
449
+ })
450
450
  }
451
451
 
452
- describe("with useLogicalConjunction: true", function () {
453
- const app = feathers();
452
+ describe('with useLogicalConjunction: true', function () {
453
+ const app = feathers()
454
454
  app.use(
455
- "/service",
455
+ '/service',
456
456
  new MemoryService({
457
457
  paginate: { default: 10, max: 100 },
458
- operators: ["$and"],
458
+ operators: ['$and'],
459
459
  filters: {
460
- ...filterArray("$and"),
460
+ ...filterArray('$and'),
461
461
  },
462
462
  }),
463
- );
464
- const service = app.service("/service");
463
+ )
464
+ const service = app.service('/service')
465
465
  const passingPairs = {
466
- "merge empty source": {
466
+ 'merge empty source': {
467
467
  target: { id: 1 },
468
468
  source: {},
469
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
469
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
470
470
  expected: { id: 1 },
471
471
  },
472
- "merge empty target": {
472
+ 'merge empty target': {
473
473
  target: {},
474
474
  source: { id: 1 },
475
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
475
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
476
476
  expected: { id: 1 },
477
477
  },
478
- "merge queries with $and": {
478
+ 'merge queries with $and': {
479
479
  target: { id: 1 },
480
480
  source: { id: { $in: [1, 3] } },
481
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
481
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
482
482
  expected: { id: 1, $and: [{ id: { $in: [1, 3] } }] },
483
483
  },
484
- "merge queries with existing $and": {
484
+ 'merge queries with existing $and': {
485
485
  target: { id: 1 },
486
486
  source: { $and: [{ id: { $in: [1, 3] } }], id: 2 },
487
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
487
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
488
488
  expected: { id: 1, $and: [{ id: { $in: [1, 3] } }, { id: 2 }] },
489
489
  },
490
- "merge queries with existing $or": {
490
+ 'merge queries with existing $or': {
491
491
  target: { id: 1 },
492
492
  source: { $or: [{ id: 2 }] },
493
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
493
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
494
494
  expected: { id: 1, $and: [{ $or: [{ id: 2 }] }] },
495
495
  },
496
- "merge queries with existing $and in target": {
496
+ 'merge queries with existing $and in target': {
497
497
  target: { $and: [{ id: 1 }], id: 3 },
498
498
  source: { id: 2 },
499
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
499
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
500
500
  expected: { $and: [{ id: 1 }, { id: 2 }], id: 3 },
501
501
  },
502
- "merge queries without $and": {
502
+ 'merge queries without $and': {
503
503
  target: { id: 1 },
504
504
  source: { userId: 2 },
505
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
505
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
506
506
  expected: { id: 1, userId: 2 },
507
507
  },
508
- "skip merge if source is in target": {
508
+ 'skip merge if source is in target': {
509
509
  target: { id: 1, userId: 2 },
510
510
  source: { userId: 2 },
511
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
511
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
512
512
  expected: { id: 1, userId: 2 },
513
513
  },
514
- "skip merge if target is in source": {
514
+ 'skip merge if target is in source': {
515
515
  target: { userId: 2 },
516
516
  source: { id: 1, userId: 2 },
517
- options: { defaultHandle: "intersect", useLogicalConjunction: true },
517
+ options: { defaultHandle: 'intersect', useLogicalConjunction: true },
518
518
  expected: { id: 1, userId: 2 },
519
519
  },
520
- };
520
+ }
521
521
  for (const key in passingPairs) {
522
- const { target, source, options, expected } = passingPairs[key];
522
+ const { target, source, options, expected } = (passingPairs as any)[key]
523
523
  it(`'${key}'`, function () {
524
524
  expect(
525
525
  mergeQuery(target, source, Object.assign({ service }, options)),
526
- ).toEqual(expected);
527
- });
526
+ ).toEqual(expected)
527
+ })
528
528
  }
529
- });
530
- });
529
+ })
530
+ })
531
531
 
532
- describe("simple objects failing", function () {
532
+ describe('simple objects failing', function () {
533
533
  const failingPairs = {
534
- "intersect two numbers": {
534
+ 'intersect two numbers': {
535
535
  target: { id: 1 },
536
536
  source: { id: 2 },
537
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
537
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
538
538
  },
539
- "intersect booleans": {
539
+ 'intersect booleans': {
540
540
  target: { test: true },
541
541
  source: { test: false },
542
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
542
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
543
543
  },
544
- "intersect number and $in": {
544
+ 'intersect number and $in': {
545
545
  target: { id: 1 },
546
546
  source: { id: { $in: [2, 3] } },
547
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
547
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
548
548
  },
549
- "intersect two $in": {
549
+ 'intersect two $in': {
550
550
  target: { id: { $in: [1, 3] } },
551
551
  source: { id: { $in: [2, 4] } },
552
- options: { defaultHandle: "intersect", useLogicalConjunction: false },
552
+ options: { defaultHandle: 'intersect', useLogicalConjunction: false },
553
553
  },
554
- };
554
+ }
555
555
  for (const key in failingPairs) {
556
- const { target, source, options } = failingPairs[key];
556
+ const { target, source, options } = (failingPairs as any)[key]
557
557
  it(`'${key}'`, function () {
558
- expect(() => mergeQuery(target, source, options)).toThrow(Forbidden);
559
- });
558
+ expect(() => mergeQuery(target, source, options)).toThrow(Forbidden)
559
+ })
560
560
  }
561
- });
561
+ })
562
562
  }