import { E as KeyOf, O as MaybeArray, f as HookType$1, j as UnpackMaybeArray, k as NeverFallback, l as DispatchOption, n as ResultSingleHookContext, p as MethodName, t as DataSingleHookContext, y as TransformParamsFn } from "./hook-context-BsxU1vfN.mjs"; import { d as InferFindParams, m as InferFindResultSingle } from "./infer-service-methods-C-9x7P40.mjs"; import { Application, HookContext, HookOptions, HookType, Id, Paginated, Params, Query, Service } from "@feathersjs/feathers"; import { PaginationOptions as PaginationOptions$1 } from "@feathersjs/adapter-commons"; //#region src/utils/add-skip/add-skip.util.d.ts type SkipHookName = 'all' | HookType | `${HookType}:${string}` | (string & {}); /** * Adds hook names to `context.params.skipHooks` so that `skippable`-wrapped hooks * will be bypassed for the current service call. Accepts a single name or an array. * Duplicates are automatically removed. * * @example * ```ts * import { addSkip } from 'feathers-utils/utils' * * // Inside a hook or custom code: * addSkip(context, 'myHook') * addSkip(context, ['hookA', 'hookB']) * ``` * * @see https://utils.feathersjs.com/utils/add-skip.html */ declare const addSkip: (context: H, hooks: MaybeArray) => void; //#endregion //#region src/utils/add-to-query/add-to-query.util.d.ts /** * Safely merges properties into a Feathers query object. If a property already exists * with a different value, it wraps both in a `$and` array to preserve both conditions. * If the exact same key-value pair already exists, no changes are made. When the added * query is itself a pure `$and` (`{ $and: [...] }`), its branches are flattened into the * target's `$and` rather than nested. * * @example * ```ts * import { addToQuery } from 'feathers-utils/utils' * * const query = { status: 'active' } * addToQuery(query, { role: 'admin' }) * // => { status: 'active', role: 'admin' } * ``` * * @see https://utils.feathersjs.com/utils/add-to-query.html */ declare function addToQuery(targetQuery: Q, query: Q): Q; //#endregion //#region src/predicates/is-context/is-context.predicate.d.ts type IsContextOptions = { path?: MaybeArray; type?: MaybeArray; method?: MaybeArray; }; /** * Returns a predicate that checks whether the hook context matches the given criteria. * You can filter by `path` (service name), `type` (before/after/around/error), * and/or `method` (find/get/create/update/patch/remove). * * @example * ```ts * import { iff, isContext } from 'feathers-utils/predicates' * * app.service('users').hooks({ * before: { all: [iff(isContext({ method: 'create', type: 'before' }), validateHook())] } * }) * ``` * * @see https://utils.feathersjs.com/predicates/is-context.html */ declare const isContext: (options: IsContextOptions) => (context: any) => boolean; //#endregion //#region src/utils/check-context/check-context.util.d.ts type NarrowedContext = H & (O extends { path: infer P; } ? [P] extends [undefined | null] ? unknown : { path: UnpackMaybeArray

; } : unknown) & (O extends { type: infer T; } ? [T] extends [undefined | null] ? unknown : { type: UnpackMaybeArray; } : unknown) & (O extends { method: infer M; } ? [M] extends [undefined | null] ? unknown : { method: UnpackMaybeArray; } : unknown); type CheckContextOptions = IsContextOptions & { label?: string; }; /** * Validates that the hook context matches the expected type(s) and method(s). * Throws an error if the context is invalid, preventing hooks from running in * unsupported configurations. Typically used internally by other hooks. * Also narrows the context type based on the passed options. * * @example * ```ts * import { checkContext } from 'feathers-utils/utils' * * const myHook = (context) => { * checkContext(context, ['before', 'around'], ['create', 'patch'], 'myHook') * // or with options object: * checkContext(context, { type: ['before', 'around'], method: ['create', 'patch'], label: 'myHook' }) * // context.type is now 'before' | 'around', context.method is now 'create' | 'patch' * } * ``` * * @see https://utils.feathersjs.com/utils/check-context.html */ declare function checkContext>>(context: H, options: O): asserts context is NarrowedContext; declare function checkContext(context: H, type?: T, methods?: M, label?: string): asserts context is NarrowedContext; //#endregion //#region src/utils/chunk-find/chunk-find.util.d.ts type PaginateOption$1 = { default?: number; max?: number; }; type ChunkFindOptions

= { params?: P & { paginate?: PaginateOption$1; }; }; /** * Use `for await` to iterate over chunks (pages) of results from a `find` method. * * This function is useful for processing large datasets in batches without loading everything into memory at once. * It uses pagination to fetch results in chunks, yielding each page's data array. * * @example * ```ts * import { chunkFind } from 'feathers-utils/utils' * * const app = feathers() * * // Assuming 'users' service has many records * for await (const users of chunkFind(app, 'users', { * params: { query: { active: true }, // Custom query parameters * } })) { * console.log(users) // Process each chunk of user records * } * ``` * * @see https://utils.feathersjs.com/utils/chunk-find.html */ declare function chunkFind, Service extends Services[Path] = Services[Path], P extends Params = InferFindParams, Item = InferFindResultSingle>(app: Application, servicePath: Path, options?: ChunkFindOptions

): AsyncGenerator; //#endregion //#region src/utils/context-to-json/context-to-json.util.d.ts /** * Converts a FeathersJS HookContext to a plain JSON object by calling `toJSON()` if available. * This is important when using lodash `get`/`has` on the context, since the HookContext * class uses getters that may not be enumerable. * * @example * ```ts * import { contextToJson } from 'feathers-utils/utils' * * const json = contextToJson(context) * console.log(json) * ``` * * @see https://utils.feathersjs.com/utils/context-to-json.html */ declare const contextToJson: (context: HookContext) => HookContext, any>; //#endregion //#region src/utils/define-hooks/define-hooks.util.d.ts /** * TypeScript helper that provides full type inference and autocompletion when defining * service hooks. It is an identity function that simply returns its input, * but enables your IDE to infer the correct hook context types. * * @example * ```ts * import { defineHooks } from 'feathers-utils/utils' * * export const userHooks = defineHooks({ * before: { create: [validateUser()] }, * after: { all: [sanitizeResult()] } * }) * ``` * * @see https://utils.feathersjs.com/utils/define-hooks.html */ declare function defineHooks>(hooks: Options): Options; //#endregion //#region src/utils/get-data-is-array/get-data-is-array.util.d.ts type GetDataIsArrayReturn = { isArray: boolean; data: DataSingleHookContext[]; }; /** * Normalizes `context.data` into an array for uniform processing. * Returns `{ data, isArray }` where `data` is always an array and `isArray` indicates * whether the original value was already an array. * * @example * ```ts * import { getDataIsArray } from 'feathers-utils/utils' * * const { data, isArray } = getDataIsArray(context) * data.forEach(item => { /* process each item *\/ }) * ``` * * @see https://utils.feathersjs.com/utils/get-data-is-array.html */ declare function getDataIsArray(context: H): GetDataIsArrayReturn; //#endregion //#region src/utils/get-exposed-methods/get-exposed-methods.util.d.ts /** * Returns the list of method names that are publicly exposed by a Feathers service. * Reads the internal `[SERVICE].methods` property set during service registration. * Throws if the service does not have any exposed methods configured. * * @example * ```ts * import { getExposedMethods } from 'feathers-utils/utils' * * const methods = getExposedMethods(app.service('users')) * // => ['find', 'get', 'create', 'patch', 'remove'] * ``` * * @see https://utils.feathersjs.com/utils/get-exposed-methods.html */ declare function getExposedMethods(service: Service): any[]; //#endregion //#region src/utils/get-paginate/get-paginate.util.d.ts /** * Resolves the active pagination options for the current hook context. * Checks (in order): `context.params.paginate`, `service.options.paginate`, * and `context.params.adapter.paginate`. Returns `undefined` if pagination is disabled. * * @example * ```ts * import { getPaginate } from 'feathers-utils/utils' * * const paginate = getPaginate(context) * if (paginate) { * console.log('Max items:', paginate.max) * } * ``` * * @see https://utils.feathersjs.com/utils/get-paginate.html */ declare const getPaginate: (context: H) => PaginationOptions$1 | undefined; //#endregion //#region src/utils/get-result-is-array/get-result-is-array.util.d.ts type GetResultIsArrayOptions = { dispatch?: boolean; }; type GetResultIsArrayReturn = { isArray: boolean; result: ResultSingleHookContext[]; key: 'dispatch' | 'result'; }; /** * Normalizes `context.result` (or `context.dispatch`) into an array for uniform processing. * Handles paginated results by extracting the `data` array. Returns `{ result, isArray, key }` * where `key` indicates whether `'result'` or `'dispatch'` was used. * * @example * ```ts * import { getResultIsArray } from 'feathers-utils/utils' * * const { result, isArray } = getResultIsArray(context) * result.forEach(item => { /* process each item *\/ }) * ``` * * @see https://utils.feathersjs.com/utils/get-result-is-array.html */ declare function getResultIsArray(context: H, options?: GetResultIsArrayOptions): GetResultIsArrayReturn; //#endregion //#region src/utils/iterate-find/iterate-find.util.d.ts type PaginateOption = { default?: number; max?: number; }; type IterateFindOptions

= { params?: P & { paginate?: PaginateOption; }; }; /** * Use `for await` to iterate over the results of a `find` method. * * This function is useful for iterating over large datasets without loading everything into memory at once. * It uses pagination to fetch results in chunks, allowing you to process each item as it is retrieved. * * @example * ```ts * import { iterateFind } from 'feathers-utils/utils' * * const app = feathers() * * // Assuming 'users' service has many records * for await (const user of iterateFind(app, 'users', { * params: { query: { active: true }, // Custom query parameters * } })) { * console.log(user) // Process each user record * } * ``` * * @see https://utils.feathersjs.com/utils/iterate-find.html */ declare function iterateFind, Service extends Services[Path] = Services[Path], P extends Params = InferFindParams, Item = InferFindResultSingle>(app: Application, servicePath: Path, options?: IterateFindOptions

): AsyncGenerator; //#endregion //#region src/utils/merge-query/merge-query.util.d.ts type MergeQueryMode = 'target' | 'source' | 'combine' | 'intersect'; interface MergeQueryOptions { /** * How to merge query properties that both queries constrain. * * - `combine` (default): broaden — the two queries always become branches of an `$or`. * - `intersect`: narrow — non-conflicting properties merge flat, conflicts become an `$and`. * - `target`: keep the target's value on conflict. * - `source`: keep the source's value on conflict. */ mode?: MergeQueryMode; } /** * Properties are combined with a logical operator rather than merged at the value * level, so the result is always a valid query: `combine` always wraps the two * queries in `$or` (broaden — OR has no flat form), while `intersect` merges * non-conflicting properties flat and wraps conflicts in `$and` (narrow). The * special filters `$select`, `$limit`, `$skip` and `$sort` are merged separately. * Inputs are never mutated. * * This is well suited to merging a client-provided query with a server-side * restriction inside a hook. * * @param target Query to be merged into * @param source Query to be merged from * @param options * @returns the merged query * * @example * ```ts * import { mergeQuery } from 'feathers-utils/utils' * * // combine (default): the two queries always become an $or * mergeQuery({ id: 1 }, { id: 2 }) * // => { $or: [{ id: 1 }, { id: 2 }] } * * mergeQuery({ status: 'active' }, { authorId: 5 }) * // => { $or: [{ status: 'active' }, { authorId: 5 }] } * ``` * * @example * ```ts * // intersect: non-conflicting properties merge flat, conflicts become an $and * mergeQuery({ status: 'active' }, { authorId: 5 }, { mode: 'intersect' }) * // => { status: 'active', authorId: 5 } * * mergeQuery({ id: 1 }, { id: 2 }, { mode: 'intersect' }) * // => { $and: [{ id: 1 }, { id: 2 }] } * ``` * * @see https://utils.feathersjs.com/utils/merge-query.html */ declare function mergeQuery(target: Query, source: Query, options?: MergeQueryOptions): Query; //#endregion //#region src/utils/patch-batch/patch-batch.util.d.ts type PatchBatchOptions = { /** the key of the id property */id?: IdKey; }; type PatchBatchResultItem, P = Params> = [Id | null, T, P | undefined]; /** * Batch patching utility that takes an array of items to be changed and returns an array of arguments to be called with the `patch` method. * * This utility is useful when you need to patch multiple items with varying data in as few requests as possible. * * @example * ```ts * const items = [ * { id: 1, value: 10 }, * { id: 2, value: 10 }, * { id: 3, value: 20 }, * ]; * * const batched = patchBatch(items, { id: 'id' }); * // batched will be: * // [ * // [null, { value: 10 }, { query: { id: { $in: [1, 2] } } }], * // [3, { value: 20 }, undefined], * // ] * * await Promise.all(batched.map(args => service.patch(...args))); * ``` * * @see https://utils.feathersjs.com/utils/patch-batch.html */ declare function patchBatch, IdKey extends KeyOf, P extends Params, R extends Omit = Omit>(items: T[], options?: PatchBatchOptions): PatchBatchResultItem[]; //#endregion //#region src/utils/query-defaults/query-defaults.util.d.ts /** * Adds default properties to a Feathers query — but only for fields the query does * not already constrain. Presence is checked with {@link queryHasProperty}, so a field * referenced anywhere (including nested in `$and`/`$or`/`$nor`) is left untouched and * the caller keeps control over it. The query is treated as the `data` equivalent of * the `defaults` transformer. Each default is applied independently (per-field). * * @example * ```ts * import { queryDefaults } from 'feathers-utils/utils' * * queryDefaults({ status: 'active' }, { isTemplate: false }) * // => { status: 'active', isTemplate: false } * * queryDefaults({ $or: [{ isTemplate: true }] }, { isTemplate: false }) * // => { $or: [{ isTemplate: true }] } (untouched — already referenced) * ``` * * @see https://utils.feathersjs.com/utils/query-defaults.html */ declare const queryDefaults: (query: Query | undefined, defaults: Query) => Query; //#endregion //#region src/utils/query-has-property/query-has-property.util.d.ts /** * Checks whether a Feathers query contains one or more properties — including * properties nested inside `$and`/`$or`/`$nor` arrays. Returns `true` as soon as * any of the given property names is found. The query is not mutated. * * @example * ```ts * import { queryHasProperty } from 'feathers-utils/utils' * * queryHasProperty({ isTemplate: true }, 'isTemplate') // true * queryHasProperty({ $or: [{ isTemplate: true }] }, 'isTemplate') // true * queryHasProperty({ age: { $gt: 18 } }, ['isTemplate', 'status']) // false * ``` * * @see https://utils.feathersjs.com/utils/query-has-property.html */ declare const queryHasProperty: (query: Query, property: MaybeArray) => boolean; //#endregion //#region src/utils/replace-data/replace-data.util.d.ts /** * Replaces `context.data` wholesale with the given items, preserving the original * single-vs-array shape. This is the explicit inverse of `getDataIsArray`: get the * data as an array, modify or replace the items, then write them back. * * @example * ```ts * import { getDataIsArray, replaceData } from 'feathers-utils/utils' * * const { data } = getDataIsArray(context) * const next = data.map((item) => ({ ...item, slug: slugify(item.name) })) * replaceData(context, next) * ``` * * @see https://utils.feathersjs.com/utils/replace-data.html */ declare function replaceData(context: H, data: DataSingleHookContext[]): H; //#endregion //#region src/utils/replace-result/replace-result.util.d.ts type ReplaceResultOptions = { /** * Also (or only) write to `context.dispatch`. `true` writes dispatch, `'both'` * writes both `result` and `dispatch`. When dispatch is requested and not yet * present, it is seeded from a clone of `context.result`. */ dispatch?: DispatchOption; }; /** * Replaces `context.result` (and/or `context.dispatch`) wholesale with the given * items, preserving the original shape: single item, array, or paginated `{ data }`. * This is the explicit inverse of `getResultIsArray`. * * @example * ```ts * import { getResultIsArray, replaceResult } from 'feathers-utils/utils' * * const { result } = getResultIsArray(context) * replaceResult(context, result.filter((item) => item.public)) * ``` * * @see https://utils.feathersjs.com/utils/replace-result.html */ declare function replaceResult(context: H, result: ResultSingleHookContext[], options?: ReplaceResultOptions): H; //#endregion //#region src/utils/skip-result/skip-result.util.d.ts /** * Sets `context.result` to an appropriate empty value based on the hook method. * Returns an empty paginated object for paginated `find`, an empty array for multi * operations, or `null` for single-item operations. Does nothing if a result already exists. * * @example * ```ts * import { skipResult } from 'feathers-utils/utils' * * // In a before hook to skip the actual database call: * skipResult(context) * ``` * * @see https://utils.feathersjs.com/utils/skip-result.html */ declare const skipResult: (context: H) => H; //#endregion //#region src/utils/sort-query-properties/sort-query-properties.util.d.ts /** * Recursively normalizes a Feathers query object for order-independent comparison. * Sorts object keys and sorts arrays within `$or`, `$and`, `$nor`, `$not`, `$in`, * and `$nin` operators so that different orderings produce the same result. * * This is useful for generating stable cache keys where * `{ $or: [{ a: 1 }, { b: 2 }] }` and `{ $or: [{ b: 2 }, { a: 1 }] }` * should be treated as equivalent. * * @example * ```ts * import { sortQueryProperties } from 'feathers-utils/utils' * * const normalized = sortQueryProperties({ * $or: [{ name: 'Jane' }, { name: 'John' }], * age: { $in: [30, 25] }, * }) * // => { $or: [{ name: 'John' }, { name: 'Jane' }], age: { $in: [25, 30] } } * // (sorted by stable stringify comparison) * ``` * * @see https://utils.feathersjs.com/utils/sort-query-properties.html */ declare const sortQueryProperties: (query: Q) => Q; //#endregion //#region src/utils/to-paginated/to-paginated.util.d.ts /** * Ensures a result is in Feathers paginated format (`{ total, limit, skip, data }`). * If the input is already paginated, it is returned as-is. If it is a plain array, * it is wrapped in a paginated object with `total` and `limit` set to the array length. * * @example * ```ts * import { toPaginated } from 'feathers-utils/utils' * * const paginated = toPaginated([{ id: 1 }, { id: 2 }]) * // => { total: 2, limit: 2, skip: 0, data: [{ id: 1 }, { id: 2 }] } * ``` * * @see https://utils.feathersjs.com/utils/to-paginated.html */ declare function toPaginated(result: R[] | Paginated): Paginated; //#endregion //#region src/utils/transform-params/transform-params.util.d.ts /** * Safely applies a `transformParams` function to a params object. * If no function is provided, the original params are returned unchanged. * The function receives a shallow copy of params, so the original is not mutated. * * @example * ```ts * import { transformParams } from 'feathers-utils/utils' * * const params = transformParams(context.params, (p) => { delete p.provider; return p }) * ``` * * @see https://utils.feathersjs.com/utils/transform-params.html */ declare const transformParams:

(params: P, fn: TransformParamsFn

| undefined) => P; //#endregion //#region src/utils/wait-for-service-event/wait-for-service-event.util.d.ts /** * The standard Feathers service events, plus any custom event name a service * might emit. */ type ServiceEventName = 'created' | 'updated' | 'patched' | 'removed' | (string & {}); type WaitForServiceEventOptions = { /** * Reject after this many milliseconds. Pass `false` to wait indefinitely. * * @default 5000 */ timeout?: number | false; /** * Only resolve for events whose data passes this predicate. Receives the * emitted record and the `HookContext` (the second argument Feathers emits). */ filter?: (data: Result, context: HookContext) => boolean; /** * Abort waiting via an `AbortSignal`. The promise rejects with the signal's * `reason` (or a generic abort error) and all listeners are detached. */ signal?: AbortSignal; }; /** * Service-agnostic defaults that can be bound once when currying with the app. * `filter` is intentionally omitted because it depends on the per-service * record type. */ type WaitForServiceEventDefaults = Pick; type WaitForServiceEventResult = [/** The emitted record. */data: Result, meta: { /** The event that fired (one of the requested events). */event: Event; /** The `HookContext` Feathers emitted alongside the record. */ context: HookContext; }]; /** * Wait for a service event to fire and resolve with the emitted record. Useful * in tests to await the result of an asynchronous service event, a bit like * `promisify` for Feathers events. * * Curried: bind the `app` (and optional defaults) once, then call the returned * function per service/event. Resolves with a `[data, { event, context }]` * tuple: `data` is typed as the service's record type, and `event` is the union * of the requested events. * * Feathers emits events as `emit(event, record, context)` and fires one event * per record, so each resolution carries a single record and its `HookContext`. * * @example * ```ts * import { waitForServiceEvent } from 'feathers-utils/utils' * * const app = feathers() * const waitForEvent = waitForServiceEvent(app) * * // Wait for the next `users` record to be created. * const [user] = await waitForEvent('users', 'created') * * // Wait for a specific record, with a custom timeout and filter. * const [data, { event }] = await waitForEvent( * 'users', * ['created', 'patched'], * { filter: (user) => user.email === 'jane@example.com', timeout: 1000 }, * ) * ``` * * @see https://utils.feathersjs.com/utils/wait-for-service-event.html */ declare function waitForServiceEvent(app: Application, defaultOptions?: WaitForServiceEventDefaults): , const Event extends ServiceEventName, Service extends Services[Path] = Services[Path], Result = NeverFallback, unknown>>(servicePath: Path, eventOrEvents: Event | Event[], options?: WaitForServiceEventOptions) => Promise>; //#endregion //#region src/utils/walk-query/walk-query.util.d.ts type WalkQueryOptions = { property: string; operator: string | undefined; value: any; path: (string | number)[]; /** * Stops the traversal. Any replacement value returned from the current walker * call is still applied, but no further properties are visited. */ stop: () => void; }; type WalkQueryCallback = (options: WalkQueryOptions) => any; /** * Walks every property of a Feathers query (including nested `$and`/`$or`/`$nor` arrays) * and calls the `walker` function for each one. The walker receives the property name, operator, * value, path, and a `stop` function, and can return a replacement value. Calling `stop()` halts * the traversal early. Returns a new query only if changes were made. * * @example * ```ts * import { walkQuery } from 'feathers-utils/utils' * * const query = walkQuery({ age: { $gt: '18' } }, ({ value, operator }) => { * if (operator === '$gt') return Number(value) * }) * // => { age: { $gt: 18 } } * ``` * * @example * ```ts * // stop early once a property is found * let found = false * walkQuery(query, ({ property, stop }) => { * if (property === 'isTemplate') { * found = true * stop() * } * }) * ``` * * @see https://utils.feathersjs.com/utils/walk-query.html */ declare const walkQuery: (query: Q, walker: WalkQueryCallback) => Q; //#endregion //#region src/utils/zip-data-result/zip-data-result.util.d.ts type ZipDataResultOptions = { onMismatch?: (context: HookContext) => void; }; type ZipDataResultItem = { data: D | undefined; result: R | undefined; }; /** * Pairs each item in `context.data` with its corresponding item in `context.result` by index. * Handles both single-item and array data, normalizing them into an array of `{ data, result }` pairs. * Only works in `after`/`around` hooks for `create`, `update`, and `patch` methods. * * @example * ```ts * import { zipDataResult } from 'feathers-utils/utils' * * const pairs = zipDataResult(context) * pairs.forEach(({ data, result }) => { /* process each pair *\/ }) * ``` * * @see https://utils.feathersjs.com/utils/zip-data-result.html */ declare function zipDataResult = DataSingleHookContext, R extends ResultSingleHookContext = ResultSingleHookContext>(context: H, options?: ZipDataResultOptions): ZipDataResultItem[]; //#endregion 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 }; //# sourceMappingURL=index-C6MN6wag.d.mts.map