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,132 +1,131 @@
1
- import { pushSet } from "./pushSet";
1
+ import { pushSet } from './pushSet.js'
2
2
 
3
- import type { HookContext } from "@feathersjs/feathers";
4
- import type { HookType } from "feathers-hooks-common";
5
- import type { MaybeArray } from "../typesInternal";
3
+ import type { HookContext } from '@feathersjs/feathers'
4
+ import type { HookType } from 'feathers-hooks-common'
5
+ import type { MaybeArray } from '../typesInternal.js'
6
6
 
7
7
  /**
8
8
  * util to mark a hook for skip, has to be used with `shouldSkip`
9
9
  */
10
10
  export function markHookForSkip<H extends HookContext = HookContext>(
11
11
  hookName: string,
12
- type: "all" | MaybeArray<HookType>,
12
+ type: 'all' | MaybeArray<HookType>,
13
13
  context?: H,
14
14
  ) {
15
15
  // @ts-expect-error context is not of type 'H'
16
- context = context || {};
17
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
18
- const params = context!.params || {};
19
- const types: string[] = Array.isArray(type) ? type : [type];
16
+ context = context || {}
17
+
18
+ const params = context!.params || {}
19
+ const types: string[] = Array.isArray(type) ? type : [type]
20
20
 
21
21
  types.forEach((t) => {
22
- const combinedName = t === "all" ? hookName : `${type}:${hookName}`;
23
- pushSet(params, ["skipHooks"], combinedName, { unique: true });
24
- });
22
+ const combinedName = t === 'all' ? hookName : `${type}:${hookName}`
23
+ pushSet(params, ['skipHooks'], combinedName, { unique: true })
24
+ })
25
25
 
26
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
27
- context!.params = params;
28
- return context;
26
+ context!.params = params
27
+ return context
29
28
  }
30
29
 
31
30
  if (import.meta.vitest) {
32
- const { it, assert } = import.meta.vitest;
33
- const { feathers } = await import("@feathersjs/feathers");
34
- const { MemoryService } = await import("@feathersjs/memory");
35
- const { hasOwnProperty } = await import("./_utils.internal");
36
- const { shouldSkip } = await import("./shouldSkip");
31
+ const { it, assert } = import.meta.vitest
32
+ const { feathers } = await import('@feathersjs/feathers')
33
+ const { MemoryService } = await import('@feathersjs/memory')
34
+ const { hasOwnProperty } = await import('./_utils.internal.js')
35
+ const { shouldSkip } = await import('./shouldSkip.js')
37
36
 
38
- it("returns hook object", function () {
39
- const context = markHookForSkip("test", "all");
40
- assert.ok(context, "returned context");
41
- assert.ok(context.params.skipHooks, "has skipHooks");
42
- });
37
+ it('returns hook object', function () {
38
+ const context = markHookForSkip('test', 'all')
39
+ assert.ok(context, 'returned context')
40
+ assert.ok(context?.params.skipHooks, 'has skipHooks')
41
+ })
43
42
 
44
- it("returns hook object for undefined context", function () {
45
- const context = markHookForSkip("test", "all");
46
- assert.ok(context, "returned context");
47
- assert.ok(context.params.skipHooks, "has skipHooks");
48
- });
43
+ it('returns hook object for undefined context', function () {
44
+ const context = markHookForSkip('test', 'all')
45
+ assert.ok(context, 'returned context')
46
+ assert.ok(context?.params.skipHooks, 'has skipHooks')
47
+ })
49
48
 
50
- it("skips explicitly before hook", async function () {
51
- const app = feathers();
52
- app.use("service", new MemoryService());
53
- const service = app.service("service");
54
- const ranInto = {};
49
+ it('skips explicitly before hook', async function () {
50
+ const app = feathers()
51
+ app.use('service', new MemoryService())
52
+ const service = app.service('service')
53
+ const ranInto: Record<string, boolean> = {}
55
54
  service.hooks({
56
55
  before: {
57
56
  all: [
58
57
  (context) => {
59
- markHookForSkip("test", "before", context);
58
+ markHookForSkip('test', 'before', context)
60
59
  },
61
60
  ],
62
61
  find: [
63
62
  (context) => {
64
- if (shouldSkip("test", context)) {
65
- return context;
63
+ if (shouldSkip('test', context)) {
64
+ return context
66
65
  }
67
- ranInto["find"] = true;
66
+ ranInto['find'] = true
68
67
  },
69
68
  (context) => {
70
- context.result = null;
69
+ context.result = null
71
70
  },
72
71
  ],
73
72
  get: [
74
73
  (context) => {
75
- if (shouldSkip("test", context)) {
76
- return context;
74
+ if (shouldSkip('test', context)) {
75
+ return context
77
76
  }
78
- ranInto["get"] = true;
77
+ ranInto['get'] = true
79
78
  },
80
79
  (context) => {
81
- context.result = null;
80
+ context.result = null
82
81
  },
83
82
  ],
84
83
  create: [
85
84
  (context) => {
86
- if (shouldSkip("test", context)) {
87
- return context;
85
+ if (shouldSkip('test', context)) {
86
+ return context
88
87
  }
89
- ranInto["create"] = true;
88
+ ranInto['create'] = true
90
89
  },
91
90
  (context) => {
92
- context.result = null;
91
+ context.result = null
93
92
  },
94
93
  ],
95
94
  update: [
96
95
  (context) => {
97
- if (shouldSkip("test", context)) {
98
- return context;
96
+ if (shouldSkip('test', context)) {
97
+ return context
99
98
  }
100
- ranInto["update"] = true;
99
+ ranInto['update'] = true
101
100
  },
102
101
  (context) => {
103
- context.result = null;
102
+ context.result = null
104
103
  },
105
104
  ],
106
105
  patch: [
107
106
  (context) => {
108
- if (shouldSkip("test", context)) {
109
- return context;
107
+ if (shouldSkip('test', context)) {
108
+ return context
110
109
  }
111
- ranInto["patch"] = true;
110
+ ranInto['patch'] = true
112
111
  },
113
112
  (context) => {
114
- context.result = null;
113
+ context.result = null
115
114
  },
116
115
  ],
117
116
  remove: [
118
117
  (context) => {
119
- if (shouldSkip("test", context)) {
120
- return context;
118
+ if (shouldSkip('test', context)) {
119
+ return context
121
120
  }
122
- ranInto["remove"] = true;
121
+ ranInto['remove'] = true
123
122
  },
124
123
  (context) => {
125
- context.result = null;
124
+ context.result = null
126
125
  },
127
126
  ],
128
127
  },
129
- });
128
+ })
130
129
  const methods = {
131
130
  find: [],
132
131
  get: [1],
@@ -134,109 +133,109 @@ if (import.meta.vitest) {
134
133
  update: [1, {}],
135
134
  patch: [1, {}],
136
135
  remove: [1],
137
- };
136
+ }
138
137
  const promises = Object.keys(methods).map(async (method) => {
139
- await service[method](...methods[method]);
138
+ await ((service as any)[method] as any)(...(methods as any)[method])
140
139
  assert.ok(
141
140
  !hasOwnProperty(ranInto, method),
142
141
  `'${method}': did not run into hook`,
143
- );
144
- return true;
145
- });
142
+ )
143
+ return true
144
+ })
146
145
 
147
- const results = await Promise.all(promises);
146
+ const results = await Promise.all(promises)
148
147
  assert.ok(
149
148
  results.every((x) => x === true),
150
- "all ok",
151
- );
152
- });
149
+ 'all ok',
150
+ )
151
+ })
153
152
 
154
- it("skips explicitly after hook", async function () {
155
- const app = feathers();
156
- app.use("service", new MemoryService());
157
- const service = app.service("service");
158
- const ranInto = {};
153
+ it('skips explicitly after hook', async function () {
154
+ const app = feathers()
155
+ app.use('service', new MemoryService())
156
+ const service = app.service('service')
157
+ const ranInto: Record<string, boolean> = {}
159
158
  service.hooks({
160
159
  before: {
161
160
  all: [
162
161
  (context) => {
163
- markHookForSkip("test", "after", context);
162
+ markHookForSkip('test', 'after', context)
164
163
  },
165
164
  (context) => {
166
- context.result = null;
167
- return context;
165
+ context.result = null
166
+ return context
168
167
  },
169
168
  ],
170
169
  },
171
170
  after: {
172
171
  find: [
173
172
  (context) => {
174
- if (shouldSkip("test", context)) {
175
- return context;
173
+ if (shouldSkip('test', context)) {
174
+ return context
176
175
  }
177
- ranInto["find"] = true;
176
+ ranInto['find'] = true
178
177
  },
179
178
  (context) => {
180
- context.result = null;
179
+ context.result = null
181
180
  },
182
181
  ],
183
182
  get: [
184
183
  (context) => {
185
- if (shouldSkip("test", context)) {
186
- return context;
184
+ if (shouldSkip('test', context)) {
185
+ return context
187
186
  }
188
- ranInto["get"] = true;
187
+ ranInto['get'] = true
189
188
  },
190
189
  (context) => {
191
- context.result = null;
190
+ context.result = null
192
191
  },
193
192
  ],
194
193
  create: [
195
194
  (context) => {
196
- if (shouldSkip("test", context)) {
197
- return context;
195
+ if (shouldSkip('test', context)) {
196
+ return context
198
197
  }
199
- ranInto["create"] = true;
198
+ ranInto['create'] = true
200
199
  },
201
200
  (context) => {
202
- context.result = null;
201
+ context.result = null
203
202
  },
204
203
  ],
205
204
  update: [
206
205
  (context) => {
207
- if (shouldSkip("test", context)) {
208
- return context;
206
+ if (shouldSkip('test', context)) {
207
+ return context
209
208
  }
210
- ranInto["update"] = true;
209
+ ranInto['update'] = true
211
210
  },
212
211
  (context) => {
213
- context.result = null;
212
+ context.result = null
214
213
  },
215
214
  ],
216
215
  patch: [
217
216
  (context) => {
218
- if (shouldSkip("test", context)) {
219
- return context;
217
+ if (shouldSkip('test', context)) {
218
+ return context
220
219
  }
221
- ranInto["patch"] = true;
220
+ ranInto['patch'] = true
222
221
  },
223
222
  (context) => {
224
- context.result = null;
223
+ context.result = null
225
224
  },
226
225
  ],
227
226
  remove: [
228
227
  (context) => {
229
- if (shouldSkip("test", context)) {
230
- return context;
228
+ if (shouldSkip('test', context)) {
229
+ return context
231
230
  }
232
- ranInto["remove"] = true;
231
+ ranInto['remove'] = true
233
232
  },
234
233
  (context) => {
235
- context.result = null;
234
+ context.result = null
236
235
  },
237
236
  ],
238
237
  },
239
- });
238
+ })
240
239
  const methods = {
241
240
  find: [],
242
241
  get: [1],
@@ -244,172 +243,172 @@ if (import.meta.vitest) {
244
243
  update: [1, {}],
245
244
  patch: [1, {}],
246
245
  remove: [1],
247
- };
246
+ }
248
247
  const promises = Object.keys(methods).map(async (method) => {
249
- await service[method](...methods[method]);
248
+ await ((service as any)[method] as any)(...(methods as any)[method])
250
249
  assert.ok(
251
250
  !hasOwnProperty(ranInto, method),
252
251
  `'${method}': did not run into hook`,
253
- );
254
- return true;
255
- });
252
+ )
253
+ return true
254
+ })
256
255
 
257
- const results = await Promise.all(promises);
256
+ const results = await Promise.all(promises)
258
257
  assert.ok(
259
258
  results.every((x) => x === true),
260
- "all ok",
261
- );
262
- });
259
+ 'all ok',
260
+ )
261
+ })
263
262
 
264
- it("skips all hooks", async function () {
265
- const app = feathers();
266
- app.use("service", new MemoryService());
267
- const service = app.service("service");
268
- const ranIntoBefore = {};
269
- const ranIntoAfter = {};
263
+ it('skips all hooks', async function () {
264
+ const app = feathers()
265
+ app.use('service', new MemoryService())
266
+ const service = app.service('service')
267
+ const ranIntoBefore: Record<string, boolean> = {}
268
+ const ranIntoAfter: Record<string, boolean> = {}
270
269
  service.hooks({
271
270
  before: {
272
271
  all: [
273
272
  (context) => {
274
- markHookForSkip("test", "all", context);
273
+ markHookForSkip('test', 'all', context)
275
274
  },
276
275
  ],
277
276
  find: [
278
277
  (context) => {
279
- if (shouldSkip("test", context)) {
280
- return context;
278
+ if (shouldSkip('test', context)) {
279
+ return context
281
280
  }
282
- ranIntoBefore["find"] = true;
281
+ ranIntoBefore['find'] = true
283
282
  },
284
283
  (context) => {
285
- context.result = null;
284
+ context.result = null
286
285
  },
287
286
  ],
288
287
  get: [
289
288
  (context) => {
290
- if (shouldSkip("test", context)) {
291
- return context;
289
+ if (shouldSkip('test', context)) {
290
+ return context
292
291
  }
293
- ranIntoBefore["get"] = true;
292
+ ranIntoBefore['get'] = true
294
293
  },
295
294
  (context) => {
296
- context.result = null;
295
+ context.result = null
297
296
  },
298
297
  ],
299
298
  create: [
300
299
  (context) => {
301
- if (shouldSkip("test", context)) {
302
- return context;
300
+ if (shouldSkip('test', context)) {
301
+ return context
303
302
  }
304
- ranIntoBefore["create"] = true;
303
+ ranIntoBefore['create'] = true
305
304
  },
306
305
  (context) => {
307
- context.result = null;
306
+ context.result = null
308
307
  },
309
308
  ],
310
309
  update: [
311
310
  (context) => {
312
- if (shouldSkip("test", context)) {
313
- return context;
311
+ if (shouldSkip('test', context)) {
312
+ return context
314
313
  }
315
- ranIntoBefore["update"] = true;
314
+ ranIntoBefore['update'] = true
316
315
  },
317
316
  (context) => {
318
- context.result = null;
317
+ context.result = null
319
318
  },
320
319
  ],
321
320
  patch: [
322
321
  (context) => {
323
- if (shouldSkip("test", context)) {
324
- return context;
322
+ if (shouldSkip('test', context)) {
323
+ return context
325
324
  }
326
- ranIntoBefore["patch"] = true;
325
+ ranIntoBefore['patch'] = true
327
326
  },
328
327
  (context) => {
329
- context.result = null;
328
+ context.result = null
330
329
  },
331
330
  ],
332
331
  remove: [
333
332
  (context) => {
334
- if (shouldSkip("test", context)) {
335
- return context;
333
+ if (shouldSkip('test', context)) {
334
+ return context
336
335
  }
337
- ranIntoBefore["remove"] = true;
336
+ ranIntoBefore['remove'] = true
338
337
  },
339
338
  (context) => {
340
- context.result = null;
339
+ context.result = null
341
340
  },
342
341
  ],
343
342
  },
344
343
  after: {
345
344
  find: [
346
345
  (context) => {
347
- if (shouldSkip("test", context)) {
348
- return context;
346
+ if (shouldSkip('test', context)) {
347
+ return context
349
348
  }
350
- ranIntoAfter["find"] = true;
349
+ ranIntoAfter['find'] = true
351
350
  },
352
351
  (context) => {
353
- context.result = null;
352
+ context.result = null
354
353
  },
355
354
  ],
356
355
  get: [
357
356
  (context) => {
358
- if (shouldSkip("test", context)) {
359
- return context;
357
+ if (shouldSkip('test', context)) {
358
+ return context
360
359
  }
361
- ranIntoAfter["get"] = true;
360
+ ranIntoAfter['get'] = true
362
361
  },
363
362
  (context) => {
364
- context.result = null;
363
+ context.result = null
365
364
  },
366
365
  ],
367
366
  create: [
368
367
  (context) => {
369
- if (shouldSkip("test", context)) {
370
- return context;
368
+ if (shouldSkip('test', context)) {
369
+ return context
371
370
  }
372
- ranIntoAfter["create"] = true;
371
+ ranIntoAfter['create'] = true
373
372
  },
374
373
  (context) => {
375
- context.result = null;
374
+ context.result = null
376
375
  },
377
376
  ],
378
377
  update: [
379
378
  (context) => {
380
- if (shouldSkip("test", context)) {
381
- return context;
379
+ if (shouldSkip('test', context)) {
380
+ return context
382
381
  }
383
- ranIntoAfter["update"] = true;
382
+ ranIntoAfter['update'] = true
384
383
  },
385
384
  (context) => {
386
- context.result = null;
385
+ context.result = null
387
386
  },
388
387
  ],
389
388
  patch: [
390
389
  (context) => {
391
- if (shouldSkip("test", context)) {
392
- return context;
390
+ if (shouldSkip('test', context)) {
391
+ return context
393
392
  }
394
- ranIntoAfter["patch"] = true;
393
+ ranIntoAfter['patch'] = true
395
394
  },
396
395
  (context) => {
397
- context.result = null;
396
+ context.result = null
398
397
  },
399
398
  ],
400
399
  remove: [
401
400
  (context) => {
402
- if (shouldSkip("test", context)) {
403
- return context;
401
+ if (shouldSkip('test', context)) {
402
+ return context
404
403
  }
405
- ranIntoAfter["remove"] = true;
404
+ ranIntoAfter['remove'] = true
406
405
  },
407
406
  (context) => {
408
- context.result = null;
407
+ context.result = null
409
408
  },
410
409
  ],
411
410
  },
412
- });
411
+ })
413
412
  const methods = {
414
413
  find: [],
415
414
  get: [1],
@@ -417,24 +416,24 @@ if (import.meta.vitest) {
417
416
  update: [1, {}],
418
417
  patch: [1, {}],
419
418
  remove: [1],
420
- };
419
+ }
421
420
  const promises = Object.keys(methods).map(async (method) => {
422
- await service[method](...methods[method]);
421
+ await ((service as any)[method] as any)(...(methods as any)[method])
423
422
  assert.ok(
424
423
  !hasOwnProperty(ranIntoBefore, method),
425
424
  `'${method}': did not run into before hook`,
426
- );
425
+ )
427
426
  assert.ok(
428
427
  !hasOwnProperty(ranIntoAfter, method),
429
428
  `'${method}': did not run into after hook`,
430
- );
431
- return true;
432
- });
429
+ )
430
+ return true
431
+ })
433
432
 
434
- const results = await Promise.all(promises);
433
+ const results = await Promise.all(promises)
435
434
  assert.ok(
436
435
  results.every((x) => x === true),
437
- "all ok",
438
- );
439
- });
436
+ 'all ok',
437
+ )
438
+ })
440
439
  }
@@ -1,3 +1,3 @@
1
- export * from "./mergeArrays";
2
- export * from "./mergeQuery";
3
- export * from "./types";
1
+ export * from './mergeArrays.js'
2
+ export * from './mergeQuery.js'
3
+ export * from './types.js'