feathers-utils 10.1.0 → 10.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/{hooks-Bg5XWcV7.mjs → hooks-DpFQfcFa.mjs} +122 -59
  2. package/dist/hooks-DpFQfcFa.mjs.map +1 -0
  3. package/dist/hooks.d.mts +110 -36
  4. package/dist/hooks.mjs +5 -5
  5. package/dist/{index-DKA0E_ad.d.mts → index-C6MN6wag.d.mts} +181 -64
  6. package/dist/index.d.mts +3 -3
  7. package/dist/index.mjs +7 -7
  8. package/dist/{internal.utils-BMzV_-xp.mjs → internal.utils-BBB-b6Ud.mjs} +16 -2
  9. package/dist/internal.utils-BBB-b6Ud.mjs.map +1 -0
  10. package/dist/{mutate-result.util-Dqzepn1M.mjs → mutate-result.util-C0nY6L7i.mjs} +2 -2
  11. package/dist/{mutate-result.util-Dqzepn1M.mjs.map → mutate-result.util-C0nY6L7i.mjs.map} +1 -1
  12. package/dist/{predicates-puYa4nkf.mjs → predicates-NOnUyMic.mjs} +53 -53
  13. package/dist/{predicates-puYa4nkf.mjs.map → predicates-NOnUyMic.mjs.map} +1 -1
  14. package/dist/predicates.d.mts +18 -18
  15. package/dist/predicates.mjs +1 -1
  16. package/dist/{resolve-B9hRleHY.mjs → resolve-BflgIVD8.mjs} +2 -2
  17. package/dist/{resolve-B9hRleHY.mjs.map → resolve-BflgIVD8.mjs.map} +1 -1
  18. package/dist/resolvers.mjs +1 -1
  19. package/dist/{transform-result.hook-B65pTRJO.mjs → transform-result.hook-V2QYN2K0.mjs} +2 -2
  20. package/dist/{transform-result.hook-B65pTRJO.mjs.map → transform-result.hook-V2QYN2K0.mjs.map} +1 -1
  21. package/dist/transformers.mjs +3 -3
  22. package/dist/{utils-Br6DNQ1B.mjs → utils-DByCpAsf.mjs} +407 -146
  23. package/dist/utils-DByCpAsf.mjs.map +1 -0
  24. package/dist/utils.d.mts +2 -2
  25. package/dist/utils.mjs +4 -4
  26. package/package.json +1 -1
  27. package/src/common/index.ts +1 -0
  28. package/src/common/is-empty-object.ts +38 -0
  29. package/src/hooks/index.ts +3 -1
  30. package/src/hooks/mute-event/mute-event.hook.ts +56 -0
  31. package/src/hooks/set-query-defaults/set-query-defaults.hook.ts +37 -0
  32. package/src/hooks/soft-delete/soft-delete.hook.ts +17 -3
  33. package/src/predicates/index.ts +3 -3
  34. package/src/utils/add-to-query/add-to-query.util.ts +19 -1
  35. package/src/utils/index.ts +5 -2
  36. package/src/utils/merge-query/dedupe-branches.ts +42 -0
  37. package/src/utils/merge-query/extract-query-filters.ts +80 -0
  38. package/src/utils/merge-query/has-conflict.ts +39 -0
  39. package/src/utils/merge-query/logical-branches.ts +39 -0
  40. package/src/utils/merge-query/merge-query-bodies.ts +136 -0
  41. package/src/utils/merge-query/merge-query.util.ts +102 -0
  42. package/src/utils/merge-query/merge-select.ts +64 -0
  43. package/src/utils/query-defaults/query-defaults.util.ts +39 -0
  44. package/src/utils/query-has-property/query-has-property.util.ts +37 -0
  45. package/src/utils/walk-query/walk-query.util.ts +43 -3
  46. package/dist/hooks-Bg5XWcV7.mjs.map +0 -1
  47. package/dist/internal.utils-BMzV_-xp.mjs.map +0 -1
  48. package/dist/utils-Br6DNQ1B.mjs.map +0 -1
package/dist/hooks.d.mts CHANGED
@@ -4,7 +4,7 @@ import { a as IffHook, i as skippable, n as ThrowIfOptions, o as iff, r as throw
4
4
  import { i as transformData, n as transformResult, r as transformQuery, t as TransformResultOptions } from "./transform-result.hook-C9wMLWs2.mjs";
5
5
  import { i as resolveData, n as resolveQuery, r as resolveResult, t as resolve } from "./resolve-Cmxskunj.mjs";
6
6
  import { FeathersError } from "@feathersjs/errors";
7
- import { HookContext, NextFunction, Params } from "@feathersjs/feathers";
7
+ import { HookContext, NextFunction, Params, Query } from "@feathersjs/feathers";
8
8
  import { RateLimiterAbstract } from "rate-limiter-flexible";
9
9
  import { PropertyPath } from "lodash";
10
10
 
@@ -249,6 +249,54 @@ declare function createRelated<H extends HookContext = HookContext>(options: May
249
249
  */
250
250
  declare const debug: <H extends HookContext = HookContext>(msg: string, ...fieldNames: string[]) => (context: H, next?: NextFunction) => Promise<void>;
251
251
  //#endregion
252
+ //#region src/hooks/disable-pagination/disable-pagination.hook.d.ts
253
+ /**
254
+ * Disables pagination when `query.$limit` is `-1` or `'-1'`.
255
+ * Removes the `$limit` from the query and sets `params.paginate = false`.
256
+ * Must be used as a `before` or `around` hook on the `find` method.
257
+ *
258
+ * @example
259
+ * ```ts
260
+ * import { disablePagination } from 'feathers-utils/hooks'
261
+ *
262
+ * app.service('users').hooks({
263
+ * before: { find: [disablePagination()] }
264
+ * })
265
+ * // Then call: app.service('users').find({ query: { $limit: -1 } })
266
+ * ```
267
+ *
268
+ * @see https://utils.feathersjs.com/hooks/disable-pagination.html
269
+ */
270
+ declare const disablePagination: <H extends HookContext = HookContext>() => {
271
+ (context: H): void;
272
+ (context: H, next: NextFunction): Promise<void>;
273
+ };
274
+ //#endregion
275
+ //#region src/hooks/disallow/disallow.hook.d.ts
276
+ /**
277
+ * Prevents access to a service method completely or for specific transports.
278
+ * When called without arguments, the method is blocked for all callers.
279
+ * When called with transport names, only those transports are blocked.
280
+ *
281
+ * @example
282
+ * ```ts
283
+ * import { disallow } from 'feathers-utils/hooks'
284
+ *
285
+ * app.service('users').hooks({
286
+ * before: {
287
+ * remove: [disallow('external')], // block external access
288
+ * update: [disallow()], // block completely
289
+ * }
290
+ * })
291
+ * ```
292
+ *
293
+ * @see https://utils.feathersjs.com/hooks/disallow.html
294
+ */
295
+ declare const disallow: <H extends HookContext = HookContext>(transports?: MaybeArray<TransportName>) => {
296
+ (context: H): void;
297
+ (context: H, next: NextFunction): Promise<void>;
298
+ };
299
+ //#endregion
252
300
  //#region src/hooks/find-or-create/find-or-create.hook.d.ts
253
301
  /**
254
302
  * The valid `uniqueBy` paths for a service's create data. Falls back to a plain
@@ -303,53 +351,42 @@ interface FindOrCreateOptions<H extends HookContext = HookContext, Services exte
303
351
  */
304
352
  declare function findOrCreate<H extends HookContext = HookContext>(options: FindOrCreateOptions<H>): (context: H, next?: NextFunction) => Promise<void>;
305
353
  //#endregion
306
- //#region src/hooks/disable-pagination/disable-pagination.hook.d.ts
307
- /**
308
- * Disables pagination when `query.$limit` is `-1` or `'-1'`.
309
- * Removes the `$limit` from the query and sets `params.paginate = false`.
310
- * Must be used as a `before` or `around` hook on the `find` method.
311
- *
312
- * @example
313
- * ```ts
314
- * import { disablePagination } from 'feathers-utils/hooks'
315
- *
316
- * app.service('users').hooks({
317
- * before: { find: [disablePagination()] }
318
- * })
319
- * // Then call: app.service('users').find({ query: { $limit: -1 } })
320
- * ```
321
- *
322
- * @see https://utils.feathersjs.com/hooks/disable-pagination.html
323
- */
324
- declare const disablePagination: <H extends HookContext = HookContext>() => {
325
- (context: H): void;
326
- (context: H, next: NextFunction): Promise<void>;
354
+ //#region src/hooks/mute-event/mute-event.hook.d.ts
355
+ type MuteEventOptions<H extends HookContext = HookContext> = {
356
+ /**
357
+ * Only mute when this is truthy. Can be a boolean or a predicate that
358
+ * receives the `HookContext`. Defaults to always muting.
359
+ *
360
+ * @example isProvider('server')
361
+ */
362
+ when?: boolean | PredicateFn<H>;
327
363
  };
328
- //#endregion
329
- //#region src/hooks/disallow/disallow.hook.d.ts
330
364
  /**
331
- * Prevents access to a service method completely or for specific transports.
332
- * When called without arguments, the method is blocked for all callers.
333
- * When called with transport names, only those transports are blocked.
365
+ * Suppresses the service event for the current call by setting `context.event`
366
+ * to `null`. Feathers emits the standard `created`/`updated`/`patched`/`removed`
367
+ * event (the value of `context.event`) after the method runs; setting it to
368
+ * `null` prevents that emission so real-time subscribers and channels are not
369
+ * notified.
370
+ *
371
+ * Useful for seeding, migrations and internal syncs that should not trigger
372
+ * downstream listeners. Works as a `before`, `after` or `around` hook.
334
373
  *
335
374
  * @example
336
375
  * ```ts
337
- * import { disallow } from 'feathers-utils/hooks'
376
+ * import { muteEvent } from 'feathers-utils/hooks'
377
+ * import { isProvider } from 'feathers-utils/predicates'
338
378
  *
339
379
  * app.service('users').hooks({
340
380
  * before: {
341
- * remove: [disallow('external')], // block external access
342
- * update: [disallow()], // block completely
381
+ * all: [muteEvent()], // mute every call
382
+ * create: [muteEvent({ when: isProvider('server') })], // only server calls
343
383
  * }
344
384
  * })
345
385
  * ```
346
386
  *
347
- * @see https://utils.feathersjs.com/hooks/disallow.html
387
+ * @see https://utils.feathersjs.com/hooks/mute-event.html
348
388
  */
349
- declare const disallow: <H extends HookContext = HookContext>(transports?: MaybeArray<TransportName>) => {
350
- (context: H): void;
351
- (context: H, next: NextFunction): Promise<void>;
352
- };
389
+ declare const muteEvent: <H extends HookContext = HookContext>(options?: MuteEventOptions<H>) => (context: H, next?: NextFunction) => Promise<void>;
353
390
  //#endregion
354
391
  //#region src/hooks/on-delete/on-delete.hook.d.ts
355
392
  type OnDeleteAction = 'cascade' | 'set null';
@@ -644,6 +681,32 @@ declare const setField: <H extends HookContext = HookContext>({
644
681
  (context: H, next: NextFunction): Promise<void>;
645
682
  };
646
683
  //#endregion
684
+ //#region src/hooks/set-query-defaults/set-query-defaults.hook.d.ts
685
+ /**
686
+ * Adds default properties to `context.params.query` for fields the incoming query does
687
+ * not already constrain (including fields referenced nested in `$and`/`$or`/`$nor`).
688
+ * The query equivalent of the `defaults` transformer: e.g. hide template rows by default
689
+ * while still letting callers opt in via `{ isTemplate: true }`. This is the same pattern
690
+ * `softDelete` uses to filter out deleted rows. Works as a `before` or `around` hook.
691
+ *
692
+ * @example
693
+ * ```ts
694
+ * import { setQueryDefaults } from 'feathers-utils/hooks'
695
+ *
696
+ * app.service('posts').hooks({
697
+ * before: { all: [setQueryDefaults({ isTemplate: false })] },
698
+ * })
699
+ * // find() => filters out templates
700
+ * // find({ query: { isTemplate: true } }) => caller keeps control
701
+ * ```
702
+ *
703
+ * @see https://utils.feathersjs.com/hooks/set-query-defaults.html
704
+ */
705
+ declare const setQueryDefaults: <H extends HookContext = HookContext>(defaults: Query) => {
706
+ (context: H): void;
707
+ (context: H, next: NextFunction): Promise<void>;
708
+ };
709
+ //#endregion
647
710
  //#region src/hooks/set-result/set-result.hook.d.ts
648
711
  interface SetResultOptions {
649
712
  /**
@@ -759,6 +822,17 @@ interface SoftDeleteOptions<H extends HookContext = HookContext> {
759
822
  * If you set this option to `true`, it will use the `.patch()` method with hooks instead.
760
823
  */
761
824
  usePatchWithHooks?: boolean;
825
+ /**
826
+ * By default, if the incoming `params.query` already references a key of
827
+ * `deletedQuery` (e.g. `deletedAt`) — including nested inside `$and`/`$or`/`$nor` —
828
+ * the `deletedQuery` filter is NOT added, letting the caller read soft-deleted
829
+ * items while `remove` still soft-deletes them.
830
+ *
831
+ * Set this to `false` to always enforce the `deletedQuery` filter.
832
+ *
833
+ * @default true
834
+ */
835
+ allowQueryOverride?: boolean;
762
836
  }
763
837
  /**
764
838
  * Marks items as deleted instead of physically removing them. On `remove`, the hook
@@ -909,5 +983,5 @@ declare const traverse: <H extends HookContext = HookContext>({
909
983
  (context: H, next: NextFunction): Promise<void>;
910
984
  };
911
985
  //#endregion
912
- export { CacheEvent, CacheOptions, CheckMultiOptions, CreateRelatedOptions, FindOrCreateOptions, HookSetDataOptions, IffHook, OnDeleteAction, OnDeleteOptions, ParamsForServerOptions, PreventChangesOptions, RateLimitOptions, SetFieldOptions, SetResultOptions, SoftDeleteOptionFunction, SoftDeleteOptions, StashableOptions, ThrowIfIsIsProviderOptions, ThrowIfIsMultiOptions, ThrowIfOptions, TransformResultOptions, TraverseOptions, cache, checkMulti, checkRequired, combine, createRelated, debug, disablePagination, disallow, findOrCreate, iff, iff as when, iffElse, onDelete, paramsForServer, paramsFromClient, paramsFromClientOptions, preventChanges, rateLimit, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setResult, setSlug, skippable, softDelete, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, transformData, transformQuery, transformResult, traverse, unless };
986
+ export { CacheEvent, CacheOptions, CheckMultiOptions, CreateRelatedOptions, FindOrCreateOptions, HookSetDataOptions, IffHook, MuteEventOptions, OnDeleteAction, OnDeleteOptions, ParamsForServerOptions, PreventChangesOptions, RateLimitOptions, SetFieldOptions, SetResultOptions, SoftDeleteOptionFunction, SoftDeleteOptions, StashableOptions, ThrowIfIsIsProviderOptions, ThrowIfIsMultiOptions, ThrowIfOptions, TransformResultOptions, TraverseOptions, cache, checkMulti, checkRequired, combine, createRelated, debug, disablePagination, disallow, findOrCreate, iff, iff as when, iffElse, muteEvent, onDelete, paramsForServer, paramsFromClient, paramsFromClientOptions, preventChanges, rateLimit, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setQueryDefaults, setResult, setSlug, skippable, softDelete, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, transformData, transformQuery, transformResult, traverse, unless };
913
987
  //# sourceMappingURL=hooks.d.mts.map
package/dist/hooks.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { _ as combine, a as iffElse, i as iff, n as skippable, r as unless, t as throwIf } from "./predicates-puYa4nkf.mjs";
2
- import { S as cache, _ as findOrCreate, a as softDelete, b as checkRequired, c as setField, d as preventChanges, f as paramsFromClient, g as disablePagination, h as disallow, i as stashable, l as setData, m as onDelete, n as throwIfIsProvider, o as setSlug, p as paramsForServer, r as throwIfIsMulti, s as setResult, t as traverse, u as rateLimit, v as debug, x as checkMulti, y as createRelated } from "./hooks-Bg5XWcV7.mjs";
3
- import { n as transformQuery, r as transformData, t as transformResult } from "./transform-result.hook-B65pTRJO.mjs";
4
- import { i as resolveData, n as resolveQuery, r as resolveResult, t as resolve } from "./resolve-B9hRleHY.mjs";
5
- export { cache, checkMulti, checkRequired, combine, createRelated, debug, disablePagination, disallow, findOrCreate, iff, iff as when, iffElse, onDelete, paramsForServer, paramsFromClient, preventChanges, rateLimit, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setResult, setSlug, skippable, softDelete, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, transformData, transformQuery, transformResult, traverse, unless };
1
+ import { _ as combine, a as iffElse, i as iff, n as throwIf, r as skippable, t as unless } from "./predicates-NOnUyMic.mjs";
2
+ import { C as checkMulti, S as checkRequired, _ as findOrCreate, a as softDelete, b as debug, c as setQueryDefaults, d as rateLimit, f as preventChanges, g as muteEvent, h as onDelete, i as stashable, l as setField, m as paramsForServer, n as throwIfIsProvider, o as setSlug, p as paramsFromClient, r as throwIfIsMulti, s as setResult, t as traverse, u as setData, v as disallow, w as cache, x as createRelated, y as disablePagination } from "./hooks-DpFQfcFa.mjs";
3
+ import { n as transformQuery, r as transformData, t as transformResult } from "./transform-result.hook-V2QYN2K0.mjs";
4
+ import { i as resolveData, n as resolveQuery, r as resolveResult, t as resolve } from "./resolve-BflgIVD8.mjs";
5
+ export { cache, checkMulti, checkRequired, combine, createRelated, debug, disablePagination, disallow, findOrCreate, iff, iff as when, iffElse, muteEvent, onDelete, paramsForServer, paramsFromClient, preventChanges, rateLimit, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setQueryDefaults, setResult, setSlug, skippable, softDelete, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, transformData, transformQuery, transformResult, traverse, unless };
@@ -23,45 +23,13 @@ type SkipHookName = 'all' | HookType | `${HookType}:${string}` | (string & {});
23
23
  */
24
24
  declare const addSkip: <H extends HookContext>(context: H, hooks: MaybeArray<SkipHookName>) => void;
25
25
  //#endregion
26
- //#region src/utils/chunk-find/chunk-find.util.d.ts
27
- type PaginateOption$1 = {
28
- default?: number;
29
- max?: number;
30
- };
31
- type ChunkFindOptions<P extends Params = Params> = {
32
- params?: P & {
33
- paginate?: PaginateOption$1;
34
- };
35
- };
36
- /**
37
- * Use `for await` to iterate over chunks (pages) of results from a `find` method.
38
- *
39
- * This function is useful for processing large datasets in batches without loading everything into memory at once.
40
- * It uses pagination to fetch results in chunks, yielding each page's data array.
41
- *
42
- * @example
43
- * ```ts
44
- * import { chunkFind } from 'feathers-utils/utils'
45
- *
46
- * const app = feathers()
47
- *
48
- * // Assuming 'users' service has many records
49
- * for await (const users of chunkFind(app, 'users', {
50
- * params: { query: { active: true }, // Custom query parameters
51
- * } })) {
52
- * console.log(users) // Process each chunk of user records
53
- * }
54
- * ```
55
- *
56
- * @see https://utils.feathersjs.com/utils/chunk-find.html
57
- */
58
- declare function chunkFind<Services, Path extends KeyOf<Services>, Service extends Services[Path] = Services[Path], P extends Params = InferFindParams<Service>, Item = InferFindResultSingle<Service>>(app: Application<Services>, servicePath: Path, options?: ChunkFindOptions<P>): AsyncGenerator<Item[], void, unknown>;
59
- //#endregion
60
26
  //#region src/utils/add-to-query/add-to-query.util.d.ts
61
27
  /**
62
28
  * Safely merges properties into a Feathers query object. If a property already exists
63
29
  * with a different value, it wraps both in a `$and` array to preserve both conditions.
64
- * If the exact same key-value pair already exists, no changes are made.
30
+ * If the exact same key-value pair already exists, no changes are made. When the added
31
+ * query is itself a pure `$and` (`{ $and: [...] }`), its branches are flattened into the
32
+ * target's `$and` rather than nested.
65
33
  *
66
34
  * @example
67
35
  * ```ts
@@ -143,6 +111,40 @@ declare function checkContext<H extends HookContext, const T extends HookType$1
143
111
  method: M;
144
112
  }>;
145
113
  //#endregion
114
+ //#region src/utils/chunk-find/chunk-find.util.d.ts
115
+ type PaginateOption$1 = {
116
+ default?: number;
117
+ max?: number;
118
+ };
119
+ type ChunkFindOptions<P extends Params = Params> = {
120
+ params?: P & {
121
+ paginate?: PaginateOption$1;
122
+ };
123
+ };
124
+ /**
125
+ * Use `for await` to iterate over chunks (pages) of results from a `find` method.
126
+ *
127
+ * This function is useful for processing large datasets in batches without loading everything into memory at once.
128
+ * It uses pagination to fetch results in chunks, yielding each page's data array.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * import { chunkFind } from 'feathers-utils/utils'
133
+ *
134
+ * const app = feathers()
135
+ *
136
+ * // Assuming 'users' service has many records
137
+ * for await (const users of chunkFind(app, 'users', {
138
+ * params: { query: { active: true }, // Custom query parameters
139
+ * } })) {
140
+ * console.log(users) // Process each chunk of user records
141
+ * }
142
+ * ```
143
+ *
144
+ * @see https://utils.feathersjs.com/utils/chunk-find.html
145
+ */
146
+ declare function chunkFind<Services, Path extends KeyOf<Services>, Service extends Services[Path] = Services[Path], P extends Params = InferFindParams<Service>, Item = InferFindResultSingle<Service>>(app: Application<Services>, servicePath: Path, options?: ChunkFindOptions<P>): AsyncGenerator<Item[], void, unknown>;
147
+ //#endregion
146
148
  //#region src/utils/context-to-json/context-to-json.util.d.ts
147
149
  /**
148
150
  * Converts a FeathersJS HookContext to a plain JSON object by calling `toJSON()` if available.
@@ -308,6 +310,61 @@ type IterateFindOptions<P extends Params = Params> = {
308
310
  */
309
311
  declare function iterateFind<Services, Path extends KeyOf<Services>, Service extends Services[Path] = Services[Path], P extends Params = InferFindParams<Service>, Item = InferFindResultSingle<Service>>(app: Application<Services>, servicePath: Path, options?: IterateFindOptions<P>): AsyncGenerator<Item, void, unknown>;
310
312
  //#endregion
313
+ //#region src/utils/merge-query/merge-query.util.d.ts
314
+ type MergeQueryMode = 'target' | 'source' | 'combine' | 'intersect';
315
+ interface MergeQueryOptions {
316
+ /**
317
+ * How to merge query properties that both queries constrain.
318
+ *
319
+ * - `combine` (default): broaden — the two queries always become branches of an `$or`.
320
+ * - `intersect`: narrow — non-conflicting properties merge flat, conflicts become an `$and`.
321
+ * - `target`: keep the target's value on conflict.
322
+ * - `source`: keep the source's value on conflict.
323
+ */
324
+ mode?: MergeQueryMode;
325
+ }
326
+ /**
327
+ * Properties are combined with a logical operator rather than merged at the value
328
+ * level, so the result is always a valid query: `combine` always wraps the two
329
+ * queries in `$or` (broaden — OR has no flat form), while `intersect` merges
330
+ * non-conflicting properties flat and wraps conflicts in `$and` (narrow). The
331
+ * special filters `$select`, `$limit`, `$skip` and `$sort` are merged separately.
332
+ * Inputs are never mutated.
333
+ *
334
+ * This is well suited to merging a client-provided query with a server-side
335
+ * restriction inside a hook.
336
+ *
337
+ * @param target Query to be merged into
338
+ * @param source Query to be merged from
339
+ * @param options
340
+ * @returns the merged query
341
+ *
342
+ * @example
343
+ * ```ts
344
+ * import { mergeQuery } from 'feathers-utils/utils'
345
+ *
346
+ * // combine (default): the two queries always become an $or
347
+ * mergeQuery({ id: 1 }, { id: 2 })
348
+ * // => { $or: [{ id: 1 }, { id: 2 }] }
349
+ *
350
+ * mergeQuery({ status: 'active' }, { authorId: 5 })
351
+ * // => { $or: [{ status: 'active' }, { authorId: 5 }] }
352
+ * ```
353
+ *
354
+ * @example
355
+ * ```ts
356
+ * // intersect: non-conflicting properties merge flat, conflicts become an $and
357
+ * mergeQuery({ status: 'active' }, { authorId: 5 }, { mode: 'intersect' })
358
+ * // => { status: 'active', authorId: 5 }
359
+ *
360
+ * mergeQuery({ id: 1 }, { id: 2 }, { mode: 'intersect' })
361
+ * // => { $and: [{ id: 1 }, { id: 2 }] }
362
+ * ```
363
+ *
364
+ * @see https://utils.feathersjs.com/utils/merge-query.html
365
+ */
366
+ declare function mergeQuery(target: Query, source: Query, options?: MergeQueryOptions): Query;
367
+ //#endregion
311
368
  //#region src/utils/patch-batch/patch-batch.util.d.ts
312
369
  type PatchBatchOptions<IdKey extends string> = {
313
370
  /** the key of the id property */id?: IdKey;
@@ -340,6 +397,48 @@ type PatchBatchResultItem<T = Record<string, unknown>, P = Params> = [Id | null,
340
397
  */
341
398
  declare function patchBatch<T extends Record<string, any>, IdKey extends KeyOf<T>, P extends Params, R extends Omit<T, IdKey> = Omit<T, IdKey>>(items: T[], options?: PatchBatchOptions<IdKey>): PatchBatchResultItem<R, P>[];
342
399
  //#endregion
400
+ //#region src/utils/query-defaults/query-defaults.util.d.ts
401
+ /**
402
+ * Adds default properties to a Feathers query — but only for fields the query does
403
+ * not already constrain. Presence is checked with {@link queryHasProperty}, so a field
404
+ * referenced anywhere (including nested in `$and`/`$or`/`$nor`) is left untouched and
405
+ * the caller keeps control over it. The query is treated as the `data` equivalent of
406
+ * the `defaults` transformer. Each default is applied independently (per-field).
407
+ *
408
+ * @example
409
+ * ```ts
410
+ * import { queryDefaults } from 'feathers-utils/utils'
411
+ *
412
+ * queryDefaults({ status: 'active' }, { isTemplate: false })
413
+ * // => { status: 'active', isTemplate: false }
414
+ *
415
+ * queryDefaults({ $or: [{ isTemplate: true }] }, { isTemplate: false })
416
+ * // => { $or: [{ isTemplate: true }] } (untouched — already referenced)
417
+ * ```
418
+ *
419
+ * @see https://utils.feathersjs.com/utils/query-defaults.html
420
+ */
421
+ declare const queryDefaults: (query: Query | undefined, defaults: Query) => Query;
422
+ //#endregion
423
+ //#region src/utils/query-has-property/query-has-property.util.d.ts
424
+ /**
425
+ * Checks whether a Feathers query contains one or more properties — including
426
+ * properties nested inside `$and`/`$or`/`$nor` arrays. Returns `true` as soon as
427
+ * any of the given property names is found. The query is not mutated.
428
+ *
429
+ * @example
430
+ * ```ts
431
+ * import { queryHasProperty } from 'feathers-utils/utils'
432
+ *
433
+ * queryHasProperty({ isTemplate: true }, 'isTemplate') // true
434
+ * queryHasProperty({ $or: [{ isTemplate: true }] }, 'isTemplate') // true
435
+ * queryHasProperty({ age: { $gt: 18 } }, ['isTemplate', 'status']) // false
436
+ * ```
437
+ *
438
+ * @see https://utils.feathersjs.com/utils/query-has-property.html
439
+ */
440
+ declare const queryHasProperty: (query: Query, property: MaybeArray<string>) => boolean;
441
+ //#endregion
343
442
  //#region src/utils/replace-data/replace-data.util.d.ts
344
443
  /**
345
444
  * Replaces `context.data` wholesale with the given items, preserving the original
@@ -403,6 +502,32 @@ declare function replaceResult<H extends HookContext = HookContext>(context: H,
403
502
  */
404
503
  declare const skipResult: <H extends HookContext = HookContext>(context: H) => H;
405
504
  //#endregion
505
+ //#region src/utils/sort-query-properties/sort-query-properties.util.d.ts
506
+ /**
507
+ * Recursively normalizes a Feathers query object for order-independent comparison.
508
+ * Sorts object keys and sorts arrays within `$or`, `$and`, `$nor`, `$not`, `$in`,
509
+ * and `$nin` operators so that different orderings produce the same result.
510
+ *
511
+ * This is useful for generating stable cache keys where
512
+ * `{ $or: [{ a: 1 }, { b: 2 }] }` and `{ $or: [{ b: 2 }, { a: 1 }] }`
513
+ * should be treated as equivalent.
514
+ *
515
+ * @example
516
+ * ```ts
517
+ * import { sortQueryProperties } from 'feathers-utils/utils'
518
+ *
519
+ * const normalized = sortQueryProperties({
520
+ * $or: [{ name: 'Jane' }, { name: 'John' }],
521
+ * age: { $in: [30, 25] },
522
+ * })
523
+ * // => { $or: [{ name: 'John' }, { name: 'Jane' }], age: { $in: [25, 30] } }
524
+ * // (sorted by stable stringify comparison)
525
+ * ```
526
+ *
527
+ * @see https://utils.feathersjs.com/utils/sort-query-properties.html
528
+ */
529
+ declare const sortQueryProperties: <Q extends Query>(query: Q) => Q;
530
+ //#endregion
406
531
  //#region src/utils/to-paginated/to-paginated.util.d.ts
407
532
  /**
408
533
  * Ensures a result is in Feathers paginated format (`{ total, limit, skip, data }`).
@@ -438,32 +563,6 @@ declare function toPaginated<R>(result: R[] | Paginated<R>): Paginated<R>;
438
563
  */
439
564
  declare const transformParams: <P extends Params = Params>(params: P, fn: TransformParamsFn<P> | undefined) => P;
440
565
  //#endregion
441
- //#region src/utils/sort-query-properties/sort-query-properties.util.d.ts
442
- /**
443
- * Recursively normalizes a Feathers query object for order-independent comparison.
444
- * Sorts object keys and sorts arrays within `$or`, `$and`, `$nor`, `$not`, `$in`,
445
- * and `$nin` operators so that different orderings produce the same result.
446
- *
447
- * This is useful for generating stable cache keys where
448
- * `{ $or: [{ a: 1 }, { b: 2 }] }` and `{ $or: [{ b: 2 }, { a: 1 }] }`
449
- * should be treated as equivalent.
450
- *
451
- * @example
452
- * ```ts
453
- * import { sortQueryProperties } from 'feathers-utils/utils'
454
- *
455
- * const normalized = sortQueryProperties({
456
- * $or: [{ name: 'Jane' }, { name: 'John' }],
457
- * age: { $in: [30, 25] },
458
- * })
459
- * // => { $or: [{ name: 'John' }, { name: 'Jane' }], age: { $in: [25, 30] } }
460
- * // (sorted by stable stringify comparison)
461
- * ```
462
- *
463
- * @see https://utils.feathersjs.com/utils/sort-query-properties.html
464
- */
465
- declare const sortQueryProperties: <Q extends Query>(query: Q) => Q;
466
- //#endregion
467
566
  //#region src/utils/wait-for-service-event/wait-for-service-event.util.d.ts
468
567
  /**
469
568
  * The standard Feathers service events, plus any custom event name a service
@@ -539,12 +638,18 @@ type WalkQueryOptions = {
539
638
  operator: string | undefined;
540
639
  value: any;
541
640
  path: (string | number)[];
641
+ /**
642
+ * Stops the traversal. Any replacement value returned from the current walker
643
+ * call is still applied, but no further properties are visited.
644
+ */
645
+ stop: () => void;
542
646
  };
543
647
  type WalkQueryCallback = (options: WalkQueryOptions) => any;
544
648
  /**
545
649
  * Walks every property of a Feathers query (including nested `$and`/`$or`/`$nor` arrays)
546
650
  * and calls the `walker` function for each one. The walker receives the property name, operator,
547
- * value, and path, and can return a replacement value. Returns a new query only if changes were made.
651
+ * value, path, and a `stop` function, and can return a replacement value. Calling `stop()` halts
652
+ * the traversal early. Returns a new query only if changes were made.
548
653
  *
549
654
  * @example
550
655
  * ```ts
@@ -556,6 +661,18 @@ type WalkQueryCallback = (options: WalkQueryOptions) => any;
556
661
  * // => { age: { $gt: 18 } }
557
662
  * ```
558
663
  *
664
+ * @example
665
+ * ```ts
666
+ * // stop early once a property is found
667
+ * let found = false
668
+ * walkQuery(query, ({ property, stop }) => {
669
+ * if (property === 'isTemplate') {
670
+ * found = true
671
+ * stop()
672
+ * }
673
+ * })
674
+ * ```
675
+ *
559
676
  * @see https://utils.feathersjs.com/utils/walk-query.html
560
677
  */
561
678
  declare const walkQuery: <Q extends Query>(query: Q, walker: WalkQueryCallback) => Q;
@@ -585,5 +702,5 @@ type ZipDataResultItem<D, R> = {
585
702
  */
586
703
  declare function zipDataResult<H extends HookContext, D extends DataSingleHookContext<H> = DataSingleHookContext<H>, R extends ResultSingleHookContext<H> = ResultSingleHookContext<H>>(context: H, options?: ZipDataResultOptions): ZipDataResultItem<D, R>[];
587
704
  //#endregion
588
- export { defineHooks as A, GetResultIsArrayOptions as C, getExposedMethods as D, getPaginate as E, isContext as F, addToQuery as I, chunkFind as L, CheckContextOptions as M, checkContext as N, GetDataIsArrayReturn as O, IsContextOptions as P, SkipHookName as R, iterateFind as S, getResultIsArray as T, replaceResult as _, WalkQueryOptions as a, PatchBatchResultItem as b, WaitForServiceEventDefaults as c, waitForServiceEvent as d, sortQueryProperties as f, ReplaceResultOptions as g, skipResult as h, WalkQueryCallback as i, contextToJson as j, getDataIsArray as k, WaitForServiceEventOptions as l, toPaginated as m, ZipDataResultOptions as n, walkQuery as o, transformParams as p, zipDataResult as r, ServiceEventName as s, ZipDataResultItem as t, WaitForServiceEventResult as u, replaceData as v, GetResultIsArrayReturn as w, patchBatch as x, PatchBatchOptions as y, addSkip as z };
589
- //# sourceMappingURL=index-DKA0E_ad.d.mts.map
705
+ export { getResultIsArray as A, IsContextOptions as B, patchBatch as C, iterateFind as D, mergeQuery as E, defineHooks as F, addToQuery as H, contextToJson as I, chunkFind as L, getExposedMethods as M, GetDataIsArrayReturn as N, GetResultIsArrayOptions as O, getDataIsArray as P, CheckContextOptions as R, PatchBatchResultItem as S, MergeQueryOptions as T, SkipHookName as U, isContext as V, addSkip as W, replaceResult as _, WalkQueryOptions as a, queryDefaults as b, WaitForServiceEventDefaults as c, waitForServiceEvent as d, transformParams as f, ReplaceResultOptions as g, skipResult as h, WalkQueryCallback as i, getPaginate as j, GetResultIsArrayReturn as k, WaitForServiceEventOptions as l, sortQueryProperties as m, ZipDataResultOptions as n, walkQuery as o, toPaginated as p, zipDataResult as r, ServiceEventName as s, ZipDataResultItem as t, WaitForServiceEventResult as u, replaceData as v, MergeQueryMode as w, PatchBatchOptions as x, queryHasProperty as y, checkContext as z };
706
+ //# sourceMappingURL=index-C6MN6wag.d.mts.map
package/dist/index.d.mts CHANGED
@@ -3,8 +3,8 @@ import { C as InferResultFromPath, D as InferUpdateResultFromPath, E as InferUpd
3
3
  import { a as IffHook, i as skippable, n as ThrowIfOptions, o as iff, r as throwIf, s as iffElse, t as unless } from "./unless.hook-CVw1wX_x.mjs";
4
4
  import { i as transformData, n as transformResult, r as transformQuery, t as TransformResultOptions } from "./transform-result.hook-C9wMLWs2.mjs";
5
5
  import { i as resolveData, n as resolveQuery, r as resolveResult, t as resolve } from "./resolve-Cmxskunj.mjs";
6
- import { CacheEvent, CacheOptions, CheckMultiOptions, CreateRelatedOptions, FindOrCreateOptions, HookSetDataOptions, OnDeleteAction, OnDeleteOptions, ParamsForServerOptions, PreventChangesOptions, RateLimitOptions, SetFieldOptions, SetResultOptions, SoftDeleteOptionFunction, SoftDeleteOptions, StashableOptions, ThrowIfIsIsProviderOptions, ThrowIfIsMultiOptions, TraverseOptions, cache, checkMulti, checkRequired, combine, createRelated, debug, disablePagination, disallow, findOrCreate, onDelete, paramsForServer, paramsFromClient, paramsFromClientOptions, preventChanges, rateLimit, setData, setField, setResult, setSlug, softDelete, stashable, throwIfIsMulti, throwIfIsProvider, traverse } from "./hooks.mjs";
7
- import { A as defineHooks, C as GetResultIsArrayOptions, D as getExposedMethods, E as getPaginate, I as addToQuery, L as chunkFind, M as CheckContextOptions, N as checkContext, O as GetDataIsArrayReturn, R as SkipHookName, S as iterateFind, T as getResultIsArray, _ as replaceResult, a as WalkQueryOptions, b as PatchBatchResultItem, c as WaitForServiceEventDefaults, d as waitForServiceEvent, f as sortQueryProperties, g as ReplaceResultOptions, h as skipResult, i as WalkQueryCallback, j as contextToJson, k as getDataIsArray, l as WaitForServiceEventOptions, m as toPaginated, n as ZipDataResultOptions, o as walkQuery, p as transformParams, r as zipDataResult, s as ServiceEventName, t as ZipDataResultItem, u as WaitForServiceEventResult, v as replaceData, w as GetResultIsArrayReturn, x as patchBatch, y as PatchBatchOptions, z as addSkip } from "./index-DKA0E_ad.mjs";
6
+ import { CacheEvent, CacheOptions, CheckMultiOptions, CreateRelatedOptions, FindOrCreateOptions, HookSetDataOptions, MuteEventOptions, OnDeleteAction, OnDeleteOptions, ParamsForServerOptions, PreventChangesOptions, RateLimitOptions, SetFieldOptions, SetResultOptions, SoftDeleteOptionFunction, SoftDeleteOptions, StashableOptions, ThrowIfIsIsProviderOptions, ThrowIfIsMultiOptions, TraverseOptions, cache, checkMulti, checkRequired, combine, createRelated, debug, disablePagination, disallow, findOrCreate, muteEvent, onDelete, paramsForServer, paramsFromClient, paramsFromClientOptions, preventChanges, rateLimit, setData, setField, setQueryDefaults, setResult, setSlug, softDelete, stashable, throwIfIsMulti, throwIfIsProvider, traverse } from "./hooks.mjs";
7
+ import { A as getResultIsArray, C as patchBatch, D as iterateFind, E as mergeQuery, F as defineHooks, H as addToQuery, I as contextToJson, L as chunkFind, M as getExposedMethods, N as GetDataIsArrayReturn, O as GetResultIsArrayOptions, P as getDataIsArray, R as CheckContextOptions, S as PatchBatchResultItem, T as MergeQueryOptions, U as SkipHookName, W as addSkip, _ as replaceResult, a as WalkQueryOptions, b as queryDefaults, c as WaitForServiceEventDefaults, d as waitForServiceEvent, f as transformParams, g as ReplaceResultOptions, h as skipResult, i as WalkQueryCallback, j as getPaginate, k as GetResultIsArrayReturn, l as WaitForServiceEventOptions, m as sortQueryProperties, n as ZipDataResultOptions, o as walkQuery, p as toPaginated, r as zipDataResult, s as ServiceEventName, t as ZipDataResultItem, u as WaitForServiceEventResult, v as replaceData, w as MergeQueryMode, x as PatchBatchOptions, y as queryHasProperty, z as checkContext } from "./index-C6MN6wag.mjs";
8
8
  import { n as mutateResult, r as mutateData, t as MutateResultOptions } from "./mutate-result.util-DR9JMsvl.mjs";
9
9
  import { Paginated, PaginationOptions } from "@feathersjs/feathers";
10
10
 
@@ -15,5 +15,5 @@ type PaginatedOrArray<R, P = undefined> = P extends {
15
15
  paginate: PaginationOptions;
16
16
  } ? Paginated<R> : Paginated<R> | R[];
17
17
  //#endregion
18
- export { CacheEvent, CacheOptions, CheckContextOptions, CheckMultiOptions, ContextFunction, ContextFunctionAsync, ContextFunctionSync, CreateRelatedOptions, DataSingleHookContext, DefaultsInput, DispatchOption, FieldKey, FindOrCreateOptions, GetDataIsArrayReturn, GetResultIsArrayOptions, GetResultIsArrayReturn, GetService, HookFunction, HookSetDataOptions, HookType, IffHook, InferCreateData, InferCreateDataFromPath, InferCreateDataSingle, InferCreateDataSingleFromPath, InferCreateResult, InferCreateResultFromPath, InferCreateResultSingle, InferCreateResultSingleFromPath, InferDataFromPath, InferFindParams, InferFindResult, InferFindResultFromPath, InferFindResultSingle, InferGetResult, InferGetResultFromPath, InferPatchData, InferPatchDataFromPath, InferPatchResult, InferPatchResultFromPath, InferRemoveResult, InferRemoveResultFromPath, InferResultFromPath, InferUpdateData, InferUpdateDataFromPath, InferUpdateResult, InferUpdateResultFromPath, MethodName, MutateResultOptions, OnDeleteAction, OnDeleteOptions, PaginatedOrArray, ParamsForServerOptions, PatchBatchOptions, PatchBatchResultItem, PredicateContextAsync, PredicateContextSync, PredicateFn, PredicateItemWithContext, PreventChangesOptions, RateLimitOptions, ReplaceResultOptions, ResultSingleHookContext, ServiceEventName, SetFieldOptions, SetResultOptions, SkipHookName, SoftDeleteOptionFunction, SoftDeleteOptions, StashableOptions, StringFieldKey, ThrowIfIsIsProviderOptions, ThrowIfIsMultiOptions, ThrowIfOptions, TransformParamsFn, TransformResultOptions, TransformerFn, TransformerInputFn, TransportName, TraverseOptions, UnwrapPaginated, UnwrapPaginatedOrArray, WaitForServiceEventDefaults, WaitForServiceEventOptions, WaitForServiceEventResult, WalkQueryCallback, WalkQueryOptions, ZipDataResultItem, ZipDataResultOptions, addSkip, addToQuery, cache, checkContext, checkMulti, checkRequired, chunkFind, combine, contextToJson, createRelated, debug, defineHooks, disablePagination, disallow, findOrCreate, getDataIsArray, getExposedMethods, getPaginate, getResultIsArray, hookTypes, iff, iff as when, iffElse, iterateFind, methodNames, mutateData, mutateResult, onDelete, paramsForServer, paramsFromClient, paramsFromClientOptions, patchBatch, preventChanges, rateLimit, replaceData, replaceResult, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setResult, setSlug, skipResult, skippable, softDelete, sortQueryProperties, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, toPaginated, transformData, transformParams, transformQuery, transformResult, traverse, unless, waitForServiceEvent, walkQuery, zipDataResult };
18
+ export { CacheEvent, CacheOptions, CheckContextOptions, CheckMultiOptions, ContextFunction, ContextFunctionAsync, ContextFunctionSync, CreateRelatedOptions, DataSingleHookContext, DefaultsInput, DispatchOption, FieldKey, FindOrCreateOptions, GetDataIsArrayReturn, GetResultIsArrayOptions, GetResultIsArrayReturn, GetService, HookFunction, HookSetDataOptions, HookType, IffHook, InferCreateData, InferCreateDataFromPath, InferCreateDataSingle, InferCreateDataSingleFromPath, InferCreateResult, InferCreateResultFromPath, InferCreateResultSingle, InferCreateResultSingleFromPath, InferDataFromPath, InferFindParams, InferFindResult, InferFindResultFromPath, InferFindResultSingle, InferGetResult, InferGetResultFromPath, InferPatchData, InferPatchDataFromPath, InferPatchResult, InferPatchResultFromPath, InferRemoveResult, InferRemoveResultFromPath, InferResultFromPath, InferUpdateData, InferUpdateDataFromPath, InferUpdateResult, InferUpdateResultFromPath, MergeQueryMode, MergeQueryOptions, MethodName, MutateResultOptions, MuteEventOptions, OnDeleteAction, OnDeleteOptions, PaginatedOrArray, ParamsForServerOptions, PatchBatchOptions, PatchBatchResultItem, PredicateContextAsync, PredicateContextSync, PredicateFn, PredicateItemWithContext, PreventChangesOptions, RateLimitOptions, ReplaceResultOptions, ResultSingleHookContext, ServiceEventName, SetFieldOptions, SetResultOptions, SkipHookName, SoftDeleteOptionFunction, SoftDeleteOptions, StashableOptions, StringFieldKey, ThrowIfIsIsProviderOptions, ThrowIfIsMultiOptions, ThrowIfOptions, TransformParamsFn, TransformResultOptions, TransformerFn, TransformerInputFn, TransportName, TraverseOptions, UnwrapPaginated, UnwrapPaginatedOrArray, WaitForServiceEventDefaults, WaitForServiceEventOptions, WaitForServiceEventResult, WalkQueryCallback, WalkQueryOptions, ZipDataResultItem, ZipDataResultOptions, addSkip, addToQuery, cache, checkContext, checkMulti, checkRequired, chunkFind, combine, contextToJson, createRelated, debug, defineHooks, disablePagination, disallow, findOrCreate, getDataIsArray, getExposedMethods, getPaginate, getResultIsArray, hookTypes, iff, iff as when, iffElse, iterateFind, mergeQuery, methodNames, mutateData, mutateResult, muteEvent, onDelete, paramsForServer, paramsFromClient, paramsFromClientOptions, patchBatch, preventChanges, queryDefaults, queryHasProperty, rateLimit, replaceData, replaceResult, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setQueryDefaults, setResult, setSlug, skipResult, skippable, softDelete, sortQueryProperties, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, toPaginated, transformData, transformParams, transformQuery, transformResult, traverse, unless, waitForServiceEvent, walkQuery, zipDataResult };
19
19
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
- import { _ as combine, a as iffElse, f as getPaginate, i as iff, n as skippable, r as unless, t as throwIf } from "./predicates-puYa4nkf.mjs";
2
- import { a as toPaginated, c as iterateFind, d as contextToJson, f as checkContext, g as sortQueryProperties, h as addSkip, i as transformParams, l as getExposedMethods, m as chunkFind, n as walkQuery, o as skipResult, p as addToQuery, r as waitForServiceEvent, s as patchBatch, t as zipDataResult, u as defineHooks } from "./utils-Br6DNQ1B.mjs";
3
- import { S as cache, _ as findOrCreate, a as softDelete, b as checkRequired, c as setField, d as preventChanges, f as paramsFromClient, g as disablePagination, h as disallow, i as stashable, l as setData, m as onDelete, n as throwIfIsProvider, o as setSlug, p as paramsForServer, r as throwIfIsMulti, s as setResult, t as traverse, u as rateLimit, v as debug, x as checkMulti, y as createRelated } from "./hooks-Bg5XWcV7.mjs";
4
- import { a as getResultIsArray, i as replaceData, n as replaceResult, o as getDataIsArray, r as mutateData, t as mutateResult } from "./mutate-result.util-Dqzepn1M.mjs";
5
- import { n as transformQuery, r as transformData, t as transformResult } from "./transform-result.hook-B65pTRJO.mjs";
6
- import { i as resolveData, n as resolveQuery, r as resolveResult, t as resolve } from "./resolve-B9hRleHY.mjs";
1
+ import { _ as combine, a as iffElse, f as getPaginate, i as iff, n as throwIf, r as skippable, t as unless } from "./predicates-NOnUyMic.mjs";
2
+ import { _ as addToQuery, a as skipResult, c as walkQuery, d as iterateFind, f as getExposedMethods, g as checkContext, h as chunkFind, i as toPaginated, l as patchBatch, m as contextToJson, n as waitForServiceEvent, o as queryDefaults, p as defineHooks, r as transformParams, s as queryHasProperty, t as zipDataResult, u as mergeQuery, v as addSkip, y as sortQueryProperties } from "./utils-DByCpAsf.mjs";
3
+ import { C as checkMulti, S as checkRequired, _ as findOrCreate, a as softDelete, b as debug, c as setQueryDefaults, d as rateLimit, f as preventChanges, g as muteEvent, h as onDelete, i as stashable, l as setField, m as paramsForServer, n as throwIfIsProvider, o as setSlug, p as paramsFromClient, r as throwIfIsMulti, s as setResult, t as traverse, u as setData, v as disallow, w as cache, x as createRelated, y as disablePagination } from "./hooks-DpFQfcFa.mjs";
4
+ import { a as getResultIsArray, i as replaceData, n as replaceResult, o as getDataIsArray, r as mutateData, t as mutateResult } from "./mutate-result.util-C0nY6L7i.mjs";
5
+ import { n as transformQuery, r as transformData, t as transformResult } from "./transform-result.hook-V2QYN2K0.mjs";
6
+ import { i as resolveData, n as resolveQuery, r as resolveResult, t as resolve } from "./resolve-BflgIVD8.mjs";
7
7
  //#region src/types.ts
8
8
  const hookTypes = [
9
9
  "around",
@@ -20,6 +20,6 @@ const methodNames = [
20
20
  "remove"
21
21
  ];
22
22
  //#endregion
23
- export { addSkip, addToQuery, cache, checkContext, checkMulti, checkRequired, chunkFind, combine, contextToJson, createRelated, debug, defineHooks, disablePagination, disallow, findOrCreate, getDataIsArray, getExposedMethods, getPaginate, getResultIsArray, hookTypes, iff, iff as when, iffElse, iterateFind, methodNames, mutateData, mutateResult, onDelete, paramsForServer, paramsFromClient, patchBatch, preventChanges, rateLimit, replaceData, replaceResult, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setResult, setSlug, skipResult, skippable, softDelete, sortQueryProperties, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, toPaginated, transformData, transformParams, transformQuery, transformResult, traverse, unless, waitForServiceEvent, walkQuery, zipDataResult };
23
+ export { addSkip, addToQuery, cache, checkContext, checkMulti, checkRequired, chunkFind, combine, contextToJson, createRelated, debug, defineHooks, disablePagination, disallow, findOrCreate, getDataIsArray, getExposedMethods, getPaginate, getResultIsArray, hookTypes, iff, iff as when, iffElse, iterateFind, mergeQuery, methodNames, mutateData, mutateResult, muteEvent, onDelete, paramsForServer, paramsFromClient, patchBatch, preventChanges, queryDefaults, queryHasProperty, rateLimit, replaceData, replaceResult, resolve, resolveData, resolveQuery, resolveResult, setData, setField, setQueryDefaults, setResult, setSlug, skipResult, skippable, softDelete, sortQueryProperties, stashable, throwIf, throwIfIsMulti, throwIfIsProvider, toPaginated, transformData, transformParams, transformQuery, transformResult, traverse, unless, waitForServiceEvent, walkQuery, zipDataResult };
24
24
 
25
25
  //# sourceMappingURL=index.mjs.map
@@ -15,6 +15,20 @@ function traverse(items, converter) {
15
15
  });
16
16
  }
17
17
  //#endregion
18
+ //#region src/common/is-empty-object.ts
19
+ /**
20
+ * Returns `true` only for a plain empty object (`{}`). Arrays, `null`, primitives
21
+ * and non-empty objects are all `false`.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * isEmptyObject({}) // => true
26
+ * isEmptyObject({ a: 1 }) // => false
27
+ * isEmptyObject([]) // => false
28
+ * ```
29
+ */
30
+ const isEmptyObject = (obj) => !!obj && typeof obj === "object" && !Array.isArray(obj) && Object.keys(obj).length === 0;
31
+ //#endregion
18
32
  //#region src/common/index.ts
19
33
  /**
20
34
  * Type guard that checks if a value is a `Promise` instance.
@@ -50,6 +64,6 @@ const early = (context, next) => {
50
64
  if (next) return next(context);
51
65
  };
52
66
  //#endregion
53
- export { traverse as a, isPromise as i, hasOwnProperty as n, toArray as r, early as t };
67
+ export { isEmptyObject as a, isPromise as i, hasOwnProperty as n, traverse as o, toArray as r, early as t };
54
68
 
55
- //# sourceMappingURL=internal.utils-BMzV_-xp.mjs.map
69
+ //# sourceMappingURL=internal.utils-BBB-b6Ud.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.utils-BBB-b6Ud.mjs","names":[],"sources":["../src/common/traverse.ts","../src/common/is-empty-object.ts","../src/common/index.ts","../src/internal.utils.ts"],"sourcesContent":["import _traverse from 'neotraverse'\n\n/**\n * Recursively traverses items (or an array of items) and applies a converter function\n * to every node using `neotraverse`. Modifications happen in place.\n *\n * @example\n * ```ts\n * traverse(items, function () { if (this.key === 'secret') this.remove() })\n * ```\n */\nexport function traverse<T extends Record<string, any>>(\n items: T | T[],\n converter: (item: T) => void,\n) {\n ;(Array.isArray(items) ? items : [items]).forEach((item) => {\n _traverse(item).forEach(converter) // replacement is in place\n })\n}\n","/**\n * Returns `true` only for a plain empty object (`{}`). Arrays, `null`, primitives\n * and non-empty objects are all `false`.\n *\n * @example\n * ```ts\n * isEmptyObject({}) // => true\n * isEmptyObject({ a: 1 }) // => false\n * isEmptyObject([]) // => false\n * ```\n */\nexport const isEmptyObject = (obj: unknown): boolean =>\n !!obj &&\n typeof obj === 'object' &&\n !Array.isArray(obj) &&\n Object.keys(obj).length === 0\n\nif (import.meta.vitest) {\n const { describe, it, expect } = import.meta.vitest\n\n describe('isEmptyObject', () => {\n it('is true only for a plain empty object', () => {\n expect(isEmptyObject({})).toBe(true)\n })\n\n it('is false for a non-empty object', () => {\n expect(isEmptyObject({ a: 1 })).toBe(false)\n })\n\n it('is false for arrays, null, undefined and primitives', () => {\n expect(isEmptyObject([])).toBe(false)\n expect(isEmptyObject(null)).toBe(false)\n expect(isEmptyObject(undefined)).toBe(false)\n expect(isEmptyObject('')).toBe(false)\n expect(isEmptyObject(0)).toBe(false)\n })\n })\n}\n","/**\n * Type guard that checks if a value is a `Promise` instance.\n *\n * @example\n * ```ts\n * const result = maybeSyncFn()\n * if (isPromise(result)) {\n * await result\n * }\n * ```\n */\nexport function isPromise(p: any): p is Promise<any> {\n return p instanceof Promise\n}\n\nexport { traverse } from './traverse.js'\nexport { clone } from './clone.js'\nexport { isEmptyObject } from './is-empty-object.js'\n","import type { HookContext } from '@feathersjs/feathers'\n\nexport const hasOwnProperty = (\n obj: Record<string, unknown>,\n ...keys: string[]\n): boolean => {\n return keys.some((x) => Object.prototype.hasOwnProperty.call(obj, x))\n}\n\nexport type MaybeArray<T> = T | readonly T[]\nexport type UnpackMaybeArray<T> = T extends readonly (infer E)[] ? E : T\n/**\n * Normalizes a value or array into an array. The returned array MUST be treated\n * as read-only — when the input is already an array it is returned as-is (no copy)\n * to avoid a per-call allocation on hook hot paths.\n */\nexport const toArray = <T>(value: T | readonly T[]): T[] =>\n Array.isArray(value) ? (value as T[]) : [value as T]\n\nexport type Promisable<T> = T | Promise<T>\nexport type KeyOf<T> = Extract<keyof T, string>\n\nexport type UnwrapArray<T> = T extends Array<infer U> ? U : T\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false\n\nexport type AnyFallback<T, Fallback> = IsAny<T> extends true ? Fallback : T\n\nexport type NeverFallback<Never, Fallback> = [Never] extends [never]\n ? Fallback\n : Never\n\nexport type KeyOfOrDotNotation<D> = KeyOf<D> | `${KeyOf<D>}.${string}`\n\n/**+\n * Can be used to early return a hook.\n *\n * If it's an around hook, it will call `next` if provided.\n */\nexport const early = <H extends HookContext>(\n context: H,\n next?: (context: H) => Promisable<void>,\n): Promisable<void> => {\n if (next) {\n return next(context)\n }\n return\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,SACd,OACA,WACA;CACC,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAA,CAAG,SAAS,SAAS;EAC1D,UAAU,IAAI,CAAC,CAAC,QAAQ,SAAS;CACnC,CAAC;AACH;;;;;;;;;;;;;;ACPA,MAAa,iBAAiB,QAC5B,CAAC,CAAC,OACF,OAAO,QAAQ,YACf,CAAC,MAAM,QAAQ,GAAG,KAClB,OAAO,KAAK,GAAG,CAAC,CAAC,WAAW;;;;;;;;;;;;;;ACJ9B,SAAgB,UAAU,GAA2B;CACnD,OAAO,aAAa;AACtB;;;ACXA,MAAa,kBACX,KACA,GAAG,SACS;CACZ,OAAO,KAAK,MAAM,MAAM,OAAO,UAAU,eAAe,KAAK,KAAK,CAAC,CAAC;AACtE;;;;;;AASA,MAAa,WAAc,UACzB,MAAM,QAAQ,KAAK,IAAK,QAAgB,CAAC,KAAU;;;;;;AAsBrD,MAAa,SACX,SACA,SACqB;CACrB,IAAI,MACF,OAAO,KAAK,OAAO;AAGvB"}