{"version":3,"file":"hooks-DpFQfcFa.mjs","names":["defaultError","_traverse"],"sources":["../src/hooks/cache/cache-utils.ts","../src/hooks/cache/cache.hook.ts","../src/hooks/check-multi/check-multi.hook.ts","../src/hooks/check-required/check-required.hook.ts","../src/hooks/create-related/create-related.hook.ts","../src/hooks/debug/debug.hook.ts","../src/hooks/disable-pagination/disable-pagination.hook.ts","../src/hooks/disallow/disallow.hook.ts","../src/hooks/find-or-create/find-or-create.hook.ts","../src/hooks/mute-event/mute-event.hook.ts","../src/hooks/on-delete/on-delete.hook.ts","../src/hooks/params-for-server/params-for-from-shared.ts","../src/hooks/params-for-server/params-for-server.hook.ts","../src/hooks/params-from-client/params-from-client.hook.ts","../src/hooks/prevent-changes/prevent-changes.hook.ts","../src/hooks/rate-limit/rate-limit.hook.ts","../src/hooks/set-data/set-data.hook.ts","../src/hooks/set-field/set-field.hook.ts","../src/hooks/set-query-defaults/set-query-defaults.hook.ts","../src/hooks/set-result/set-result.hook.ts","../src/hooks/set-slug/set-slug.hook.ts","../src/hooks/soft-delete/soft-delete.hook.ts","../src/hooks/stashable/stashable.hook.ts","../src/hooks/throw-if-is-multi/throw-if-is-multi.hook.ts","../src/hooks/throw-if-is-provider/throw-if-is-provider.hook.ts","../src/hooks/traverse/traverse.hook.ts"],"sourcesContent":["import { sortQueryProperties } from '../../utils/sort-query-properties/sort-query-properties.util.js'\n\nexport { sortQueryProperties }\n\nexport const stableStringify = (obj: Record<string, any>) => {\n  // Canonicalize the whole params object once (recursive key-sort + operator-array\n  // sort). The JSON.stringify pass then only needs to reject non-JSON values\n  // instead of re-sorting and re-allocating every node.\n  const normalized = sortQueryProperties(obj as any)\n\n  return JSON.stringify(normalized, (_key, value) => {\n    if (typeof value === 'function') {\n      throw new Error('Cannot stringify non JSON value')\n    }\n    return value\n  })\n}\n","import type { HookContext, NextFunction, Params } from '@feathersjs/feathers'\nimport { stableStringify } from './cache-utils.js'\nimport { copy } from 'fast-copy'\nimport type { Promisable } from '../../internal.utils.js'\n\ntype Cache = {\n  get: (key: string) => Promisable<any>\n  set: (key: string, value: any) => Promisable<any>\n  delete: (key: string) => Promisable<any>\n  clear: () => any\n  keys: () => IterableIterator<string>\n}\n\nexport type CacheEvent =\n  | { type: 'hit'; method: string; key: string }\n  | { type: 'miss'; method: string; key: string }\n  | { type: 'set'; method: string; key: string }\n  | { type: 'invalidate'; method: string; key: string }\n  | { type: 'clear'; method: string }\n\nexport type CacheOptions = {\n  /**\n   * The cache implementation to use. It should implement the methods `get`, `set`, `delete`, `clear`, and `keys`.\n   * This can be a Map, Redis client, or any other cache implementation.\n   *\n   * Use 'lru-cache' for an LRU cache implementation.\n   */\n  map: Cache\n  /**\n   * The id field to use for caching. Defaults to `service.options.id` and if not found, then 'id'.\n   */\n  id?: string\n  /**\n   * params are stringified for the key-value cache.\n   * There are params properties you don't want to include in the cache key.\n   * You can use this function to transform the params before they are stringified.\n   */\n  transformParams: (params: Params) => Params\n  /**\n   * Custom serialization function for converting params into a cache key string.\n   * By default, uses `stableStringify` which sorts object keys and normalizes\n   * query operator arrays (`$or`, `$and`, `$in`, etc.) for order-independent caching.\n   *\n   * Override this to use a custom serialization strategy.\n   *\n   * @example\n   * ```ts\n   * cache({\n   *   map: new Map(),\n   *   transformParams: (params) => ({ query: params.query }),\n   *   serialize: (params) => JSON.stringify(params),\n   * })\n   * ```\n   */\n  serialize?: (params: Params) => string\n  /**\n   * Optional logger callback for cache events (hit, miss, set, invalidate, clear).\n   * Useful for debugging and monitoring cache behavior.\n   *\n   * @example\n   * ```ts\n   * cache({\n   *   map: new Map(),\n   *   transformParams: (params) => ({ query: params.query }),\n   *   logger: (event) => console.log(`cache ${event.type}`, event),\n   * })\n   * ```\n   */\n  logger?: (event: CacheEvent) => void\n  /**\n   * How to clone results on store and on hit so callers can't mutate the shared\n   * cached object. Defaults to a `fast-copy` deep clone.\n   *\n   * Set to `false` to skip cloning entirely (fastest, but the caller MUST treat\n   * results as immutable), or pass a custom clone function (e.g. `structuredClone`).\n   *\n   * @default true\n   */\n  clone?: boolean | (<T>(value: T) => T)\n}\n\n/**\n * Caches `get` and `find` results based on `params`. On mutating methods (`create`, `update`,\n * `patch`, `remove`), affected cache entries are automatically invalidated.\n * Works as a `before`, `after`, or `around` hook.\n *\n * @example\n * ```ts\n * import { cache } from 'feathers-utils/hooks'\n *\n * const myCache = new Map()\n *\n * app.service('users').hooks({\n *   around: {\n *     all: [cache({ map: myCache, transformParams: (params) => ({ query: params.query }) })]\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/cache.html\n */\nexport const cache = <H extends HookContext = HookContext>(\n  options: CacheOptions,\n) => {\n  const cacheMap = new ContextCacheMap(options)\n  return async (context: H, next?: NextFunction): Promise<void> => {\n    if (context.type === 'before') {\n      return await cacheBefore(context, cacheMap)\n    }\n    if (context.type === 'after') {\n      return await cacheAfter(context, cacheMap)\n    }\n\n    if (context.type === 'around' && next) {\n      await cacheBefore(context, cacheMap)\n      await next()\n      await cacheAfter(context, cacheMap)\n      return\n    }\n  }\n}\n\nconst cacheBefore = async (\n  context: HookContext,\n  cacheMap: ContextCacheMap,\n): Promise<void> => {\n  if (context.method === 'get' || context.method === 'find') {\n    const value = await cacheMap.get(context)\n    if (value) {\n      context.result = value\n    }\n  }\n}\n\nconst cacheAfter = async (\n  context: HookContext,\n  cacheMap: ContextCacheMap,\n): Promise<void> => {\n  if (context.method === 'get' || context.method === 'find') {\n    await cacheMap.set(context)\n  } else {\n    await cacheMap.clear(context)\n  }\n}\n\nclass ContextCacheMap {\n  map: Cache\n  private delimiter = ':'\n  private options: CacheOptions\n  private log: ((event: CacheEvent) => void) | undefined\n  private serialize: (params: Params) => string\n  private clone: <T>(value: T) => T\n\n  constructor(options: CacheOptions) {\n    this.map = options.map\n    this.options = options\n    this.log = options.logger\n    this.serialize = options.serialize ?? stableStringify\n    this.clone =\n      options.clone === false\n        ? (value) => value\n        : typeof options.clone === 'function'\n          ? options.clone\n          : copy\n  }\n\n  private stringifyCacheKey(context: HookContext) {\n    if (context.method !== 'get' && context.method !== 'find') {\n      throw new Error(\n        `Cache can only be used with 'get' or 'find' methods, not '${context.method}'`,\n      )\n    }\n\n    const stringifiedParams = this.serialize(\n      this.options.transformParams(context.params ?? {}),\n    )\n\n    return `${context.id ?? 'null'}${this.delimiter}${stringifiedParams}`\n  }\n\n  private getCachedId(key: string) {\n    const index = key.indexOf(this.delimiter)\n    if (index === -1) {\n      throw new Error(\n        `Cache key '${key}' does not contain a delimiter '${this.delimiter}'`,\n      )\n    }\n    return key.substring(0, index)\n  }\n\n  private getId(item: Record<string, any>, context: HookContext) {\n    const idField = context.service.options?.id || this.options.id || 'id'\n    const id = item[idField]\n    return id && id.toString ? id.toString() : id\n  }\n\n  /**\n   * Called before get() and find()\n   *\n   * returns a cached result for the given context if it exists.\n   */\n  async get(context: HookContext) {\n    const key = this.stringifyCacheKey(context)\n    const result = await this.map.get(key)\n    if (result) {\n      this.log?.({ type: 'hit', method: context.method, key })\n      return this.clone(result) // clone to avoid mutation of the cached result\n    }\n    this.log?.({ type: 'miss', method: context.method, key })\n  }\n\n  /**\n   * Called after get() and find()\n   *\n   * Caches the result for the given context.\n   */\n  async set(context: HookContext) {\n    const key = this.stringifyCacheKey(context)\n    this.log?.({ type: 'set', method: context.method, key })\n    // clone to avoid later mutation of the cached result\n    return this.map.set(key, this.clone(context.result))\n  }\n\n  // Called after create(), update(), patch(), and remove()\n  async clear<H extends HookContext>(context: H): Promise<H> {\n    const results = Array.isArray(context.result)\n      ? context.result\n      : [context.result]\n\n    const promises: Promise<any>[] = []\n\n    const itemIds = results\n      .map((item: any) => this.getId(item, context))\n      .filter(Boolean)\n\n    // If no itemIds are found, clear the entire cache to avoid stale data\n    if (!itemIds.length) {\n      this.log?.({ type: 'clear', method: context.method })\n      await this.map.clear()\n      return context\n    }\n\n    // O(1) membership instead of an O(itemIds) scan per cached key.\n    const idSet = new Set<string>(itemIds.map((id: any) => `${id}`))\n\n    for (const key of this.map.keys()) {\n      const cachedId = this.getCachedId(key)\n      if (cachedId === 'null') {\n        // This is a cached `find` request. Any create/patch/update/del\n        // could affect the results of this query so it should be deleted\n        this.log?.({ type: 'invalidate', method: context.method, key })\n        promises.push(this.map.delete(key))\n        continue\n      }\n\n      // This is a cached `get` request\n\n      if (context.method === 'create') {\n        // If this is a create, we don't need to delete any cached get requests\n        continue\n      }\n\n      if (idSet.has(cachedId)) {\n        // If the cached id matches a mutated item id, delete the cached get\n        this.log?.({ type: 'invalidate', method: context.method, key })\n        promises.push(this.map.delete(key))\n      }\n    }\n\n    await Promise.all(promises)\n\n    return context\n  }\n}\n","import type { FeathersError } from '@feathersjs/errors'\nimport { MethodNotAllowed } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { isMulti } from '../../predicates/index.js'\n\nexport type CheckMultiOptions = {\n  /**\n   * Customize the error that is thrown if the service does not allow multi operations.\n   *\n   * If not provided, throws a `MethodNotAllowed` error with a message indicating the operation.\n   */\n  error?: (context: HookContext) => FeathersError\n}\n\n/**\n * Checks if the `multi` option is enabled for the current method and throws a\n * `MethodNotAllowed` error if multi operations are not permitted.\n * Useful to guard against accidental bulk `create`, `patch`, or `remove` calls.\n *\n * @example\n * ```ts\n * import { checkMulti } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: { create: [checkMulti()] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/check-multi.html\n */\nexport function checkMulti<H extends HookContext = HookContext>(\n  options?: CheckMultiOptions,\n) {\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    const { service, method } = context\n    if (\n      !service.allowsMulti ||\n      !isMulti(context) ||\n      method === 'find' ||\n      service.allowsMulti(method)\n    ) {\n      if (next) return next()\n      return\n    }\n\n    throw options?.error\n      ? options.error(context)\n      : new MethodNotAllowed(`Can not ${method} multiple entries`)\n  }\n  return hook\n}\n","import _get from 'lodash/get.js'\nimport _has from 'lodash/has.js'\nimport { BadRequest } from '@feathersjs/errors'\n\nimport { checkContext, getDataIsArray } from '../../utils/index.js'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\n\n/**\n * Validates that the specified fields exist on `context.data` and are not falsy.\n * Numeric `0` and boolean `false` are treated as valid values.\n * Throws a `BadRequest` error if any required field is missing or null.\n *\n * @example\n * ```ts\n * import { checkRequired } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: { create: [checkRequired(['email', 'password'])] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/check-required.html\n */\nexport function checkRequired<H extends HookContext = HookContext>(\n  fieldNames: MaybeArray<string>,\n) {\n  const fieldNamesArray = toArray(fieldNames)\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    checkContext(context, {\n      type: ['before', 'around'],\n      method: ['create', 'update', 'patch'],\n      label: 'checkRequired',\n    })\n\n    const { data } = getDataIsArray(context)\n\n    for (let i = 0; i < data.length; i++) {\n      const item = data[i]\n\n      for (let j = 0; j < fieldNamesArray.length; j++) {\n        const name = fieldNamesArray[j]\n\n        if (!_has(item, name)) {\n          throw new BadRequest(`Field ${name} does not exist. (required)`)\n        }\n\n        const value = _get(item, name)\n\n        if (!value && value !== 0 && value !== false) {\n          throw new BadRequest(`Field ${name} is null. (required)`)\n        }\n      }\n    }\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext, getResultIsArray } from '../../utils/index.js'\nimport type { MaybeArray, Promisable } from '../../internal.utils.js'\nimport type { InferCreateDataSingle } from '../../utility-types/infer-service-methods.js'\nimport type { ResultSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport interface CreateRelatedOptions<\n  H extends HookContext = HookContext,\n  Services extends H['app']['services'] = H['app']['services'],\n  S extends keyof Services = keyof Services,\n> {\n  service: S\n  /**\n   * Is relevant when the current context result is an array.\n   *\n   * If true, will create multiple related records in a single call to the related service's create method.\n   * If false or not provided, will create related records one by one.\n   *\n   * @default false\n   */\n  multi?: boolean\n  /**\n   * A function that returns the data to be created in the related service.\n   *\n   * Receives the current item from the context result and the full hook context as arguments.\n   * Can return a single data object, an array of data objects, or a promise that resolves to either.\n   *\n   * If the function returns undefined, no related record will be created for that item.\n   */\n  data: (\n    item: ResultSingleHookContext<H>,\n    context: H,\n  ) => Promisable<MaybeArray<InferCreateDataSingle<Services[S]>> | undefined>\n}\n\n/**\n * Creates related records in other services after a successful `create` call.\n * For each result item, a `data` function produces the record to create in the target service.\n * Supports creating records one-by-one or in a single multi-create when `multi: true`.\n *\n * @example\n * ```ts\n * import { createRelated } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   after: {\n *     create: [createRelated({ service: 'profiles', data: (user) => ({ userId: user.id }) })]\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/create-related.html\n */\nexport function createRelated<H extends HookContext = HookContext>(\n  options: MaybeArray<CreateRelatedOptions<H>>,\n) {\n  return async (context: H, next?: NextFunction): Promise<void> => {\n    checkContext(context, {\n      type: ['after', 'around'],\n      method: ['create'],\n      label: 'createRelated',\n    })\n\n    if (next) {\n      await next()\n    }\n\n    const { result } = getResultIsArray(context)\n\n    const entries = Array.isArray(options) ? options : [options]\n\n    await Promise.all(\n      entries.map(async (entry) => {\n        const { data, service, multi } = entry\n\n        const dataToCreate = (\n          await Promise.all(result.map(async (item) => data(item, context)))\n        )\n          .flat()\n          .filter((x) => !!x)\n\n        if (!dataToCreate || dataToCreate.length <= 0) {\n          return\n        }\n\n        if (multi || dataToCreate.length === 1) {\n          await context.app\n            .service(service as string)\n            .create(\n              dataToCreate.length === 1\n                ? (dataToCreate[0] as any)\n                : (dataToCreate as any),\n            )\n        } else {\n          await Promise.all(\n            dataToCreate.map(async (item) =>\n              context.app.service(service as string).create(item as any),\n            ),\n          )\n        }\n      }),\n    )\n  }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\n\n/**\n * Logs the current hook context to the console for debugging purposes.\n * Displays timestamp, service path, method, type, id, data, query, result, and\n * any additional param fields you specify.\n *\n * @example\n * ```ts\n * import { debug } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: { find: [debug('before find', 'user')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/debug.html\n */\nexport const debug =\n  <H extends HookContext = HookContext>(msg: string, ...fieldNames: string[]) =>\n  async (context: H, next?: NextFunction): Promise<void> => {\n    if (next) {\n      await next()\n    }\n\n    // display timestamp\n    const now = new Date()\n    console.log(\n      `${now.getFullYear()}-${\n        now.getMonth() + 1\n      }-${now.getDate()} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`,\n    )\n\n    if (msg) {\n      console.log(msg)\n    }\n\n    // display service, method & type of hook (before/after/error)\n    console.log(\n      `${context.type} service('${context.path}').${context.method}()`,\n    )\n\n    // display id for get, patch, update & remove\n    if (!['find', 'create'].includes(context.method) && 'id' in context) {\n      console.log('id:', context.id)\n    }\n\n    if (context.data) {\n      console.log('data:', context.data)\n    }\n\n    if (context.params?.query) {\n      console.log('query:', context.params.query)\n    }\n\n    if (context.result) {\n      console.log('result:', context.result)\n    }\n\n    // display additional params\n    const params = context.params || {}\n    console.log('params props:', Object.keys(params).sort())\n\n    fieldNames.forEach((name) => {\n      console.log(`params.${name}:`, params[name])\n    })\n\n    if (context.error) {\n      console.log('error', context.error)\n    }\n  }\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext } from '../../utils/index.js'\n\n/**\n * Disables pagination when `query.$limit` is `-1` or `'-1'`.\n * Removes the `$limit` from the query and sets `params.paginate = false`.\n * Must be used as a `before` or `around` hook on the `find` method.\n *\n * @example\n * ```ts\n * import { disablePagination } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: { find: [disablePagination()] }\n * })\n * // Then call: app.service('users').find({ query: { $limit: -1 } })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/disable-pagination.html\n */\nexport const disablePagination = <H extends HookContext = HookContext>() => {\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    checkContext(context, {\n      type: ['before', 'around'],\n      method: ['find'],\n      label: 'disablePagination',\n    })\n    const $limit = context.params?.query?.$limit\n\n    if ($limit === '-1' || $limit === -1) {\n      context.params.paginate = false\n      delete context.params.query.$limit\n    }\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import { MethodNotAllowed } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { TransportName } from '../../types.js'\nimport { isProvider } from '../../predicates/index.js'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\n\n/**\n * Prevents access to a service method completely or for specific transports.\n * When called without arguments, the method is blocked for all callers.\n * When called with transport names, only those transports are blocked.\n *\n * @example\n * ```ts\n * import { disallow } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: {\n *     remove: [disallow('external')], // block external access\n *     update: [disallow()],           // block completely\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/disallow.html\n */\nexport const disallow = <H extends HookContext = HookContext>(\n  transports?: MaybeArray<TransportName>,\n) => {\n  const transportsArr = toArray(transports)\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    // No transports (undefined) or an empty list means \"block completely\".\n    // Fail closed for a guard hook rather than throwing a confusing internal error.\n    if (!transports || transportsArr.length === 0) {\n      throw new MethodNotAllowed('Method not allowed')\n    }\n\n    if (isProvider(...(transportsArr as TransportName[]))(context)) {\n      throw new MethodNotAllowed(\n        `Provider '${context.params.provider}' can not call '${context.method}' on '${context.path}'. (disallow)`,\n      )\n    }\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import _get from 'lodash/get.js'\nimport _set from 'lodash/set.js'\nimport { BadRequest } from '@feathersjs/errors'\nimport type { HookContext, NextFunction, Params } from '@feathersjs/feathers'\nimport { checkContext, getDataIsArray } from '../../utils/index.js'\nimport {\n  toArray,\n  type KeyOfOrDotNotation,\n  type MaybeArray,\n  type NeverFallback,\n} from '../../internal.utils.js'\nimport type {\n  InferCreateDataSingle,\n  InferFindParams,\n} from '../../utility-types/infer-service-methods.js'\n\n/**\n * The valid `uniqueBy` paths for a service's create data. Falls back to a plain\n * `string` when the create data type can't be inferred (e.g. an untyped app), so\n * the hook stays usable without a strongly-typed `feathers()` instance.\n */\ntype UniqueByPath<S> = NeverFallback<\n  KeyOfOrDotNotation<InferCreateDataSingle<S>>,\n  string\n>\n\nexport interface FindOrCreateOptions<\n  H extends HookContext = HookContext,\n  Services extends H['app']['services'] = H['app']['services'],\n  S extends keyof Services = keyof Services,\n> {\n  /** The service to search before creating. Must be a service registered on the app. */\n  service: S\n  /**\n   * One or more property paths (dot-notation supported) read from `context.data` to build\n   * the lookup query — the upsert \"conflict target\". A path whose value is `undefined` in\n   * the data is skipped.\n   */\n  uniqueBy: MaybeArray<UniqueByPath<Services[S]>>\n  /**\n   * Optional function returning extra `find` params. `query` is merged with (and overridden\n   * by) the `uniqueBy` values; `paginate` is always forced to `false`.\n   */\n  params?: (context: H) => InferFindParams<Services[S]>\n  /**\n   * What to do when more than one record matches the `uniqueBy` query.\n   * - `'create'` (default): proceed to create a new record.\n   * - `'throw'`: throw a `BadRequest`.\n   * - `'first'`: short-circuit with the first match.\n   *\n   * @default 'create'\n   */\n  onMultiple?: 'create' | 'throw' | 'first'\n}\n\n/**\n * A `before:create` (or `around:create`) hook that looks for an existing record before creating one.\n *\n * It builds a query from the `uniqueBy` paths read out of `context.data`, runs\n * `find({ paginate: false })` on the target service, and if **exactly one** record matches, sets\n * `context.result` to that record — short-circuiting the create. With zero matches (or array data)\n * the create proceeds; with multiple matches the `onMultiple` option decides.\n *\n * @example\n * ```ts\n * import { findOrCreate } from 'feathers-utils/hooks'\n *\n * app.service('tags').hooks({\n *   before: {\n *     create: [findOrCreate({ service: 'tags', uniqueBy: 'name' })]\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/find-or-create.html\n */\nexport function findOrCreate<H extends HookContext = HookContext>(\n  options: FindOrCreateOptions<H>,\n) {\n  return async (context: H, next?: NextFunction): Promise<void> => {\n    checkContext(context, {\n      type: ['before', 'around'],\n      method: ['create'],\n      label: 'findOrCreate',\n    })\n\n    const { service, uniqueBy, onMultiple = 'create' } = options\n    const { data, isArray } = getDataIsArray(context)\n\n    // find-or-create is single-record only; arrays/empty fall through to the normal create.\n    if (isArray || data.length !== 1) {\n      if (next) await next()\n      return\n    }\n\n    const [item] = data as Record<string, unknown>[]\n\n    const baseParams: Params = options.params ? options.params(context) : {}\n    const query: Record<string, unknown> = { ...(baseParams.query ?? {}) }\n    for (const path of toArray(uniqueBy as MaybeArray<string>)) {\n      const val = _get(item, path)\n      if (val === undefined) continue\n      _set(query, path, val)\n    }\n\n    const found = (await context.app.service(service as string).find({\n      ...baseParams,\n      query,\n      paginate: false as const,\n    })) as unknown[]\n    const items = Array.isArray(found) ? found : []\n\n    if (items.length === 1 || (items.length > 1 && onMultiple === 'first')) {\n      // Short-circuit: skips the real create for `before` (Feathers skips the method) and for\n      // `around` (we never call next()).\n      context.result = items[0] as H['result']\n      return\n    }\n\n    if (items.length > 1 && onMultiple === 'throw') {\n      throw new BadRequest(\n        `findOrCreate: found ${items.length} records matching the unique query on '${String(service)}'`,\n      )\n    }\n\n    // No single match: proceed to create.\n    if (next) await next()\n  }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { PredicateFn } from '../../types.js'\n\nexport type MuteEventOptions<H extends HookContext = HookContext> = {\n  /**\n   * Only mute when this is truthy. Can be a boolean or a predicate that\n   * receives the `HookContext`. Defaults to always muting.\n   *\n   * @example isProvider('server')\n   */\n  when?: boolean | PredicateFn<H>\n}\n\n/**\n * Suppresses the service event for the current call by setting `context.event`\n * to `null`. Feathers emits the standard `created`/`updated`/`patched`/`removed`\n * event (the value of `context.event`) after the method runs; setting it to\n * `null` prevents that emission so real-time subscribers and channels are not\n * notified.\n *\n * Useful for seeding, migrations and internal syncs that should not trigger\n * downstream listeners. Works as a `before`, `after` or `around` hook.\n *\n * @example\n * ```ts\n * import { muteEvent } from 'feathers-utils/hooks'\n * import { isProvider } from 'feathers-utils/predicates'\n *\n * app.service('users').hooks({\n *   before: {\n *     all: [muteEvent()],                              // mute every call\n *     create: [muteEvent({ when: isProvider('server') })], // only server calls\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/mute-event.html\n */\nexport const muteEvent = <H extends HookContext = HookContext>(\n  options?: MuteEventOptions<H>,\n) => {\n  const when = options?.when\n\n  return async (context: H, next?: NextFunction): Promise<void> => {\n    const should =\n      typeof when === 'function' ? await when(context) : (when ?? true)\n\n    if (should) {\n      context.event = null\n    }\n\n    if (next) {\n      await next()\n    }\n  }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext, getResultIsArray } from '../../utils/index.js'\nimport type { MaybeArray, NeverFallback } from '../../internal.utils.js'\nimport type {\n  InferFindParams,\n  InferGetResult,\n} from '../../utility-types/infer-service-methods.js'\nimport type { ResultSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport type OnDeleteAction = 'cascade' | 'set null'\n\nexport interface OnDeleteOptions<\n  H extends HookContext = HookContext,\n  S extends keyof H['app']['services'] = keyof H['app']['services'],\n> {\n  /**\n   * The related service where related items should be manipulated\n   */\n  service: S\n  /**\n   * The propertyKey in the related service\n   */\n  keyThere: NeverFallback<keyof InferGetResult<H['app']['services'][S]>, string>\n  /**\n   * The propertyKey in the current service.\n   */\n  keyHere: keyof ResultSingleHookContext<H>\n  /**\n   * The action to perform on the related items.\n   *\n   * - `cascade`: remove related items\n   * - `set null`: set the related property to null\n   */\n  onDelete: OnDeleteAction\n  /**\n   * Additional query to merge into the service call.\n   * Typed based on the related service's query type.\n   */\n  query?: InferFindParams<H['app']['services'][S]>['query']\n  /**\n   * If true, the hook will wait for the service to finish before continuing\n   *\n   * @default false\n   */\n  blocking?: boolean\n  /**\n   * Called when a non-blocking (`blocking: false`) related-service call rejects.\n   * Without this, fire-and-forget rejections are swallowed (but never leak as an\n   * unhandled rejection). In `blocking` mode the error is thrown to the caller instead.\n   */\n  onError?: (error: any, context: H) => void\n}\n\n/**\n * Manipulates related items when a record is deleted, similar to SQL foreign key actions.\n * Supports `'cascade'` (remove related records) and `'set null'` (nullify the foreign key).\n * Unlike database-level cascades, this hook triggers service events and hooks for related items.\n *\n * @example\n * ```ts\n * import { onDelete } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   after: {\n *     remove: [onDelete({ service: 'posts', keyHere: 'id', keyThere: 'userId', onDelete: 'cascade' })]\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/on-delete.html\n */\ntype OnDeleteOptionsDistributed<H extends HookContext> = {\n  [S in keyof H['app']['services'] & string]: OnDeleteOptions<H, S>\n}[keyof H['app']['services'] & string]\n\nexport const onDelete = <H extends HookContext = HookContext>(\n  options: MaybeArray<OnDeleteOptionsDistributed<H>>,\n) => {\n  const optionsMulti = Array.isArray(options) ? options : [options]\n\n  return async (context: H, next?: NextFunction): Promise<void> => {\n    checkContext(context, {\n      type: ['after', 'around'],\n      method: 'remove',\n      label: 'onDelete',\n    })\n\n    if (next) {\n      await next()\n    }\n\n    const { result } = getResultIsArray(context)\n\n    if (!result.length) {\n      return\n    }\n\n    const blockingPromises: Promise<any>[] = []\n\n    for (const {\n      keyHere,\n      keyThere,\n      onDelete,\n      service,\n      blocking,\n      query,\n      onError,\n    } of optionsMulti) {\n      let ids = result.map((x) => x[keyHere]).filter((x) => !!x)\n      ids = [...new Set(ids)]\n\n      if (!ids || ids.length <= 0) {\n        continue\n      }\n\n      const params = {\n        query: {\n          ...query,\n          ...(ids.length === 1\n            ? { [keyThere]: ids[0] }\n            : { [keyThere]: { $in: ids } }),\n        },\n        paginate: false,\n      }\n\n      let promise: Promise<any> | undefined = undefined\n\n      if (onDelete === 'cascade') {\n        promise = context.app.service(service as string).remove(null, params)\n      } else if (onDelete === 'set null') {\n        const data = { [keyThere]: null }\n        promise = context.app\n          .service(service as string)\n          .patch(null, data, params)\n      }\n\n      if (!promise) {\n        continue\n      }\n\n      if (blocking) {\n        blockingPromises.push(promise)\n      } else {\n        // fire-and-forget: always attach a catch so a rejection never becomes\n        // an unhandled promise rejection. Surface it via `onError` if provided.\n        promise.catch((error) => onError?.(error, context))\n      }\n    }\n\n    if (blockingPromises.length) {\n      await Promise.all(blockingPromises)\n    }\n\n    return\n  }\n}\n","export const FROM_CLIENT_FOR_SERVER_DEFAULT_KEY = '_$client' as const\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\nimport { FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } from './params-for-from-shared.js'\n\nexport type ParamsForServerOptions = {\n  /**\n   * @default '_$client'\n   */\n  keyToHide?: string\n}\n\n/**\n * Client-side hook that moves whitelisted `params` properties into `query._$client`\n * so they survive the client-to-server transport. The server only receives `query`\n * from params — use `paramsFromClient` on the server to restore them.\n *\n * @example\n * ```ts\n * import { paramsForServer } from 'feathers-utils/hooks'\n *\n * // Client-side\n * app.service('users').hooks({\n *   before: { all: [paramsForServer('populateParams')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/params-for-server.html\n */\nexport const paramsForServer = (\n  whitelist: MaybeArray<string>,\n  options?: ParamsForServerOptions,\n) => {\n  const whitelistArr = toArray(whitelist)\n\n  const { keyToHide = FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } = options || {}\n\n  function hook<H extends HookContext>(context: H): void\n  function hook<H extends HookContext>(\n    context: H,\n    next: NextFunction,\n  ): Promise<void>\n  function hook<H extends HookContext>(\n    context: H,\n    next?: NextFunction,\n  ): void | Promise<void> {\n    // clone params on demand\n    let clonedParams: any\n\n    Object.keys(context.params).forEach((key) => {\n      if (key === 'query') {\n        return\n      }\n\n      if (whitelistArr.includes(key)) {\n        if (!clonedParams) {\n          clonedParams = {\n            ...context.params,\n            query: {\n              ...context.params.query,\n            },\n          }\n        }\n\n        if (!clonedParams.query[keyToHide]) {\n          clonedParams.query[keyToHide] = {}\n        } else {\n          // The shallow query copy still aliases a pre-existing key object;\n          // clone it so we don't mutate the caller's original params.\n          clonedParams.query[keyToHide] = { ...clonedParams.query[keyToHide] }\n        }\n\n        clonedParams.query[keyToHide][key] = clonedParams[key]\n        delete clonedParams[key]\n      }\n    })\n\n    if (clonedParams) {\n      context.params = clonedParams\n    }\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\nimport { FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } from '../params-for-server/params-for-from-shared.js'\n\nexport type paramsFromClientOptions = {\n  /**\n   * @default '_$client'\n   */\n  keyToHide?: string\n}\n\n/**\n * Server-side hook that extracts whitelisted properties from `query._$client` back\n * into `context.params`. This is the counterpart to `paramsForServer`, which encodes\n * params on the client side for transport.\n *\n * @example\n * ```ts\n * import { paramsFromClient } from 'feathers-utils/hooks'\n *\n * // Server-side\n * app.service('users').hooks({\n *   before: { all: [paramsFromClient('populateParams')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/params-from-client.html\n */\nexport const paramsFromClient = (\n  whitelist: MaybeArray<string>,\n  options?: paramsFromClientOptions,\n) => {\n  const whitelistArr = toArray(whitelist)\n  const { keyToHide = FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } = options || {}\n  function hook(context: HookContext): void\n  function hook(context: HookContext, next: NextFunction): Promise<void>\n  function hook(\n    context: HookContext,\n    next?: NextFunction,\n  ): void | Promise<void> {\n    if (\n      !context.params?.query?.[keyToHide] ||\n      typeof context.params.query[keyToHide] !== 'object'\n    ) {\n      if (next) return next()\n      return\n    }\n\n    const params = {\n      ...context.params,\n      query: {\n        ...context.params.query,\n        [keyToHide]: {\n          ...context.params.query[keyToHide],\n        },\n      },\n    }\n\n    const client = params.query[keyToHide]\n\n    whitelistArr.forEach((key) => {\n      if (key in client) {\n        params[key] = client[key]\n        delete client[key]\n      }\n    })\n\n    if (Object.keys(client).length === 0) {\n      delete params.query[keyToHide]\n    }\n\n    context.params = params\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import _has from 'lodash/has.js'\nimport _omit from 'lodash/omit.js'\nimport type { FeathersError } from '@feathersjs/errors'\nimport { BadRequest } from '@feathersjs/errors'\nimport { transformData } from '../transform-data/transform-data.hook.js'\nimport type { KeyOfOrDotNotation, MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\nimport type { HookContext } from '@feathersjs/feathers'\nimport type { DataSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport type PreventChangesOptions<D, Keys extends KeyOfOrDotNotation<D>> = {\n  /**\n   * Customize the error that is thrown if the service tries to patch a field that is not allowed.\n   *\n   * If not provided, throws a `BadRequest` error with a message indicating the field that is not allowed.\n   */\n  error?: boolean | ((item: D, name: Keys) => FeathersError)\n}\n\n/**\n * Prevents `patch` calls from modifying certain fields. By default, the protected\n * fields are silently removed from `context.data`. When `error` is set, a `BadRequest`\n * is thrown if any protected field is present.\n *\n * Supports dot.notation for nested fields.\n *\n * @example\n * ```ts\n * import { preventChanges } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: { patch: [preventChanges(['email', 'role'], { error: true })] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/prevent-changes.html\n */\nexport const preventChanges = <\n  H extends HookContext = HookContext,\n  D extends DataSingleHookContext<H> = DataSingleHookContext<H>,\n  Keys extends KeyOfOrDotNotation<D> = KeyOfOrDotNotation<D>,\n>(\n  fieldNames: MaybeArray<Keys>,\n  options?: PreventChangesOptions<D, Keys>,\n) => {\n  const fieldNamesArr = toArray(fieldNames)\n\n  return transformData<H>((item) => {\n    if (options?.error) {\n      for (let i = 0; i < fieldNamesArr.length; i++) {\n        const name = fieldNamesArr[i]\n\n        if (_has(item, name)) {\n          const error =\n            typeof options.error === 'function'\n              ? options.error(item as D, name)\n              : new BadRequest(\n                  `Field ${String(name)} may not be patched. (preventChanges)`,\n                )\n\n          throw error\n        }\n      }\n    } else {\n      return _omit(item, fieldNamesArr)\n    }\n\n    return item\n  })\n}\n","import { TooManyRequests } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { RateLimiterAbstract, RateLimiterRes } from 'rate-limiter-flexible'\nimport { checkContext } from '../../utils/index.js'\nimport type { Promisable } from '../../internal.utils.js'\n\nexport type RateLimitOptions<H extends HookContext = HookContext> = {\n  /** Generate the rate-limiting key. Defaults to `context.path`. */\n  key?: (context: H) => Promisable<string>\n  /** Number of points to consume per request. Defaults to `1`. */\n  points?: (context: H) => Promisable<number>\n}\n\n/**\n * Rate limits service method calls using `rate-limiter-flexible`.\n * You provide a pre-configured `RateLimiterAbstract` instance\n * (Memory, Redis, Mongo, etc.) and the hook consumes points per request.\n *\n * @example\n * ```ts\n * import { rateLimit } from 'feathers-utils/hooks'\n * import { RateLimiterMemory } from 'rate-limiter-flexible'\n *\n * const rateLimiter = new RateLimiterMemory({ points: 10, duration: 1 })\n *\n * app.service('users').hooks({\n *   before: { find: [rateLimit(rateLimiter)] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/rate-limit.html\n */\nexport const rateLimit = <H extends HookContext = HookContext>(\n  rateLimiter: RateLimiterAbstract,\n  options?: RateLimitOptions<H>,\n) => {\n  const key = options?.key ?? ((context: HookContext) => context.path)\n  const points = options?.points ?? (() => 1)\n\n  return async (context: H, next?: NextFunction): Promise<void> => {\n    checkContext(context, { type: ['before', 'around'], label: 'rateLimit' })\n\n    const resolvedKey = await key(context)\n    const resolvedPoints = await points(context)\n\n    try {\n      const res = await rateLimiter.consume(resolvedKey, resolvedPoints)\n      context.params.rateLimit = res\n    } catch (res) {\n      context.params.rateLimit = res as RateLimiterRes\n      throw new TooManyRequests('Too many requests', {\n        rateLimitRes: res as RateLimiterRes,\n      })\n    }\n\n    if (next) await next()\n  }\n}\n","import _get from 'lodash/get.js'\nimport _set from 'lodash/set.js'\nimport _has from 'lodash/has.js'\n\nimport type { FeathersError } from '@feathersjs/errors'\nimport { Forbidden } from '@feathersjs/errors'\n\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { PropertyPath } from 'lodash'\nimport { contextToJson } from '../../utils/context-to-json/context-to-json.util.js'\nimport { getDataIsArray } from '../../utils/index.js'\nimport type { PredicateItemWithContext } from '../../types.js'\n\nexport interface HookSetDataOptions {\n  /**\n   * Wether to throw if the context[from] is undefined.\n   *\n   * @default false\n   */\n  allowUndefined?: boolean\n  /**\n   * @default true\n   */\n  overwrite?: boolean | PredicateItemWithContext\n  /**\n   * Customize the error that is thrown if the context[from] is not available.\n   * If not provided, throws a `Forbidden` error with a message indicating the missing field.\n   */\n  error?: (context: HookContext, from: PropertyPath) => FeathersError\n}\n\n/**\n * Sets a property on each item in `context.data` from another property on the hook context.\n * Supports dot-notation paths for both source and target. Throws a `Forbidden` error\n * if the source field is missing (unless `allowUndefined` is `true`).\n *\n * @example\n * ```ts\n * import { setData } from 'feathers-utils/hooks'\n *\n * app.service('posts').hooks({\n *   before: { create: [setData('params.user.id', 'userId')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-data.html\n */\nexport function setData<H extends HookContext = HookContext>(\n  /**\n   * The property path of the context to set the value from. 'dot.notation' is supported.\n   *\n   * If the property does not exist, the hook will throw an error unless `allowUndefined` is set to true.\n   * If the property exists, it will be set to the value of the `to` property path of the data item.\n   *\n   * @example 'params.user.id'\n   */\n  from: PropertyPath,\n  /**\n   * The property path of the data item to set the value to. 'dot.notation' is supported.\n   *\n   * If the property does not exist, it will be created.\n   * If the property exists, it will be overwritten unless `overwrite` is set to false.\n   *\n   * @example 'userId'\n   */\n  to: PropertyPath,\n  options?: HookSetDataOptions,\n) {\n  const { allowUndefined = false, overwrite = true } = options ?? {}\n\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    const { data } = getDataIsArray(context)\n\n    const contextJson = contextToJson(context)\n\n    if (!_has(contextJson, from)) {\n      if (!context.params?.provider || allowUndefined === true) {\n        if (next) return next()\n        return\n      }\n\n      if (\n        !overwrite &&\n        data.every((item: Record<string, unknown>) => _has(item, to))\n      ) {\n        if (next) return next()\n        return\n      }\n\n      throw options?.error\n        ? options.error(context, from)\n        : new Forbidden(`Expected field ${from.toString()} not available`)\n    }\n\n    const val = _get(contextJson, from)\n\n    for (let i = 0, len = data.length; i < len; i++) {\n      const item: Record<string, unknown> = data[i]\n\n      const currentOverwrite =\n        typeof overwrite === 'function' ? overwrite(item, context) : overwrite\n\n      if (!currentOverwrite && _has(item, to)) {\n        continue\n      }\n\n      _set(item, to, val)\n    }\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import _get from 'lodash/get.js'\nimport _setWith from 'lodash/setWith.js'\nimport _clone from 'lodash/clone.js'\nimport { checkContext } from '../../utils/index.js'\nimport type { FeathersError } from '@feathersjs/errors'\nimport { Forbidden } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\n\nexport interface SetFieldOptions<H extends HookContext = HookContext> {\n  /**\n   * The target path(s) to set. Pass an array to write the same value to several\n   * paths (e.g. multiple query keys).\n   *\n   * @example 'params.query.userId'\n   * @example ['params.query.userId', 'params.query.ownerId']\n   */\n  as: string | string[]\n  /**\n   * The source of the value: a `dot.notation` path on the context, or a function\n   * that derives the value from the context.\n   *\n   * @example 'params.user.id'\n   * @example (context) => context.params.user?.id\n   */\n  from: string | ((context: H) => unknown)\n  /**\n   * If set to `true`, allows the field to be undefined.\n   * If the field is not available and this is `true`, the hook will not throw an error.\n   *\n   * If set to `false`, the hook will throw an error if the field is not available.\n   *\n   * @default false\n   */\n  allowUndefined?: boolean\n  /**\n   * Customize the error that is thrown if the field is not available.\n   *\n   * If not provided, throws a `Forbidden` error with a message indicating the missing field.\n   */\n  error?: (\n    context: H,\n    from: string | ((context: H) => unknown),\n  ) => FeathersError\n}\n\n/**\n * Sets a field on the hook context (e.g. `params.query`) based on the value of another\n * context field (e.g. `params.user.id`). Useful for scoping queries to the authenticated user.\n * Throws a `Forbidden` error if the source field is missing (unless `allowUndefined` is `true`).\n *\n * @example\n * ```ts\n * import { setField } from 'feathers-utils/hooks'\n *\n * app.service('posts').hooks({\n *   before: { all: [setField({ from: 'params.user.id', as: 'params.query.userId' })] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-field.html\n */\nexport const setField = <H extends HookContext = HookContext>({\n  as,\n  from,\n  allowUndefined = false,\n  error,\n}: SetFieldOptions<H>) => {\n  const targets = Array.isArray(as) ? as : [as]\n\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    const { params } = context\n\n    checkContext(context, { type: ['before', 'around'], label: 'setField' })\n\n    const value =\n      typeof from === 'function' ? from(context) : _get(context, from)\n\n    if (value === undefined) {\n      if (!params.provider || allowUndefined) {\n        if (next) return next()\n        return\n      }\n\n      throw error\n        ? error(context, from)\n        : new Forbidden(`Expected field ${targets.join(', ')} not available`)\n    }\n\n    for (const target of targets) {\n      _setWith(context, target, value, _clone)\n    }\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import type { HookContext, NextFunction, Query } from '@feathersjs/feathers'\nimport { queryDefaults } from '../../utils/query-defaults/query-defaults.util.js'\n\n/**\n * Adds default properties to `context.params.query` for fields the incoming query does\n * not already constrain (including fields referenced nested in `$and`/`$or`/`$nor`).\n * The query equivalent of the `defaults` transformer: e.g. hide template rows by default\n * while still letting callers opt in via `{ isTemplate: true }`. This is the same pattern\n * `softDelete` uses to filter out deleted rows. Works as a `before` or `around` hook.\n *\n * @example\n * ```ts\n * import { setQueryDefaults } from 'feathers-utils/hooks'\n *\n * app.service('posts').hooks({\n *   before: { all: [setQueryDefaults({ isTemplate: false })] },\n * })\n * // find() => filters out templates\n * // find({ query: { isTemplate: true } }) => caller keeps control\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-query-defaults.html\n */\nexport const setQueryDefaults = <H extends HookContext = HookContext>(\n  defaults: Query,\n) => {\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    context.params.query = queryDefaults(context.params.query, defaults)\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import _get from 'lodash/get.js'\nimport _set from 'lodash/set.js'\nimport _has from 'lodash/has.js'\nimport { copy } from 'fast-copy'\n\nimport type { FeathersError } from '@feathersjs/errors'\nimport { Forbidden } from '@feathersjs/errors'\n\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { PropertyPath } from 'lodash'\nimport { contextToJson } from '../../utils/context-to-json/context-to-json.util.js'\nimport { getResultIsArray } from '../../utils/index.js'\nimport type { DispatchOption, PredicateItemWithContext } from '../../types.js'\n\nexport interface SetResultOptions {\n  /**\n   * Wether to throw if the context[from] is undefined.\n   *\n   * @default false\n   */\n  allowUndefined?: boolean\n  /**\n   * @default true\n   */\n  overwrite?: boolean | PredicateItemWithContext\n  /**\n   * Customize the error that is thrown if the context[from] is not available.\n   * If not provided, throws a `Forbidden` error with a message indicating the missing field.\n   */\n  error?: (context: HookContext, from: PropertyPath) => FeathersError\n  dispatch?: DispatchOption\n}\n\n/**\n * Sets a property on each item in `context.result` from another property on the hook context.\n * Supports dot-notation paths for both source and target, and can optionally\n * operate on `context.dispatch` as well.\n *\n * @example\n * ```ts\n * import { setResult } from 'feathers-utils/hooks'\n *\n * app.service('posts').hooks({\n *   after: { all: [setResult('params.user.id', 'currentUserId')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-result.html\n */\nexport function setResult<H extends HookContext = HookContext>(\n  /**\n   * The property path of the context to set the value from. 'dot.notation' is supported.\n   *\n   * If the property does not exist, the hook will throw an error unless `allowUndefined` is set to true.\n   * If the property exists, it will be set to the value of the `to` property path of the data item.\n   *\n   * @example 'params.user.id'\n   */\n  from: PropertyPath,\n  /**\n   * The property path of the data item to set the value to. 'dot.notation' is supported.\n   *\n   * If the property does not exist, it will be created.\n   * If the property exists, it will be overwritten unless `overwrite` is set to false.\n   *\n   * @example 'userId'\n   */\n  to: PropertyPath,\n  options?: SetResultOptions,\n) {\n  const { allowUndefined = false, overwrite = true } = options ?? {}\n\n  const forResultOrDispatch = (context: H, dispatch: boolean) => {\n    const { result } = getResultIsArray(context, { dispatch })\n\n    const contextJson = contextToJson(context)\n\n    if (!_has(contextJson, from)) {\n      if (!context.params?.provider || allowUndefined === true) {\n        return context\n      }\n\n      if (\n        !overwrite &&\n        result.every((item: Record<string, unknown>) => _has(item, to))\n      ) {\n        return context\n      }\n\n      throw options?.error\n        ? options.error(context, from)\n        : new Forbidden(`Expected field ${from.toString()} not available`)\n    }\n\n    const val = _get(contextJson, from)\n\n    for (let i = 0; i < result.length; i++) {\n      const item: Record<string, unknown> = result[i]\n\n      const currentOverwrite =\n        typeof overwrite === 'function' ? overwrite(item, context) : overwrite\n\n      if (!currentOverwrite && _has(item, to)) {\n        continue\n      }\n\n      _set(item, to, val)\n    }\n\n    return context\n  }\n\n  const fn = (context: H) => {\n    // Seed context.dispatch from result so the dispatch branch mutates (and\n    // persists to) a real object instead of a throwaway copy. Mirrors mutateResult.\n    if (!!options?.dispatch && !context.dispatch) {\n      context.dispatch = copy(context.result)\n    }\n\n    if (options?.dispatch === 'both') {\n      forResultOrDispatch(context, true)\n      return forResultOrDispatch(context, false)\n    }\n\n    return forResultOrDispatch(context, !!options?.dispatch)\n  }\n\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    if (next) {\n      return next().then(() => {\n        fn(context)\n      })\n    }\n\n    fn(context)\n    return\n  }\n  return hook\n}\n","import _set from 'lodash/set.js'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\n\n/**\n * Extracts URL route parameters (slugs) and sets them on `params.query`.\n * For example, given a route `/stores/:storeId`, this hook copies the resolved\n * `storeId` value from `params.route` into the query. Only applies to the `rest` provider.\n *\n * @example\n * ```ts\n * import { setSlug } from 'feathers-utils/hooks'\n *\n * app.service('stores/:storeId/products').hooks({\n *   before: { all: [setSlug('storeId')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-slug.html\n */\nexport const setSlug = <H extends HookContext = HookContext>(\n  slug: string,\n  fieldName?: string,\n) => {\n  const targetField: string =\n    typeof fieldName === 'string' ? fieldName : `query.${slug}`\n\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    if (context.params && context.params.provider === 'rest') {\n      const value = context.params.route[slug]\n      if (typeof value === 'string' && value[0] !== ':') {\n        _set(context.params, targetField, value)\n      }\n    }\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { addToQuery, checkContext, queryDefaults } from '../../utils/index.js'\nimport type { TransformParamsFn } from '../../types.js'\nimport { transformParams } from '../../utils/transform-params/transform-params.util.js'\nimport { early, type Promisable } from '../../internal.utils.js'\nimport { isPromise } from '../../common/index.js'\n\nexport type SoftDeleteOptionFunction<H extends HookContext = HookContext> = (\n  context?: H,\n) => Promisable<{ [key: string]: any }>\n\nexport interface SoftDeleteOptions<H extends HookContext = HookContext> {\n  /**\n   * @example { deletedAt: null }\n   */\n  deletedQuery: { [key: string]: any } | SoftDeleteOptionFunction<H>\n  /**\n   * @example { deletedAt: new Date() }\n   */\n  removeData: { [key: string]: any } | SoftDeleteOptionFunction<H>\n  /**\n   * Transform the params before calling the service method. E.g. remove 'params.provider' or add custom params.\n   */\n  transformParams?: TransformParamsFn\n\n  /**\n   * Key in `params` to disable the soft delete functionality.\n   *\n   * @default 'disableSoftDelete'\n   */\n  disableSoftDeleteKey?: string\n\n  /**\n   * `softDelete` uses `._patch()` internally to mark items as deleted.\n   *\n   * If you set this option to `true`, it will use the `.patch()` method with hooks instead.\n   */\n  usePatchWithHooks?: boolean\n\n  /**\n   * By default, if the incoming `params.query` already references a key of\n   * `deletedQuery` (e.g. `deletedAt`) — including nested inside `$and`/`$or`/`$nor` —\n   * the `deletedQuery` filter is NOT added, letting the caller read soft-deleted\n   * items while `remove` still soft-deletes them.\n   *\n   * Set this to `false` to always enforce the `deletedQuery` filter.\n   *\n   * @default true\n   */\n  allowQueryOverride?: boolean\n}\n\n/**\n * Marks items as deleted instead of physically removing them. On `remove`, the hook\n * patches the record with `removeData` (e.g. `{ deletedAt: new Date() }`). On all other\n * methods, it appends `deletedQuery` (e.g. `{ deletedAt: null }`) to filter out soft-deleted items.\n *\n * @example\n * ```ts\n * import { softDelete } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   around: {\n *     all: [softDelete({ deletedQuery: { deletedAt: null }, removeData: { deletedAt: new Date() } })]\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/soft-delete.html\n */\nexport const softDelete = <H extends HookContext = HookContext>(\n  options: SoftDeleteOptions<H>,\n) => {\n  if (!options?.deletedQuery || !options?.removeData) {\n    throw new Error(\n      'You must provide `deletedQuery` and `removeData` options to the softDelete hook.',\n    )\n  }\n\n  return async (context: H, next?: NextFunction): Promise<void> => {\n    checkContext(context, { type: ['before', 'around'], label: 'softDelete' })\n\n    const { disableSoftDeleteKey = 'disableSoftDelete' } = options\n\n    if (context.params[disableSoftDeleteKey]) {\n      await early(context, next)\n      return\n    }\n\n    const { deletedQuery, removeData, allowQueryOverride = true } = options\n\n    let deleteQuery = getValue(deletedQuery, context)\n    if (isPromise(deleteQuery)) {\n      deleteQuery = await deleteQuery\n    }\n\n    const query = allowQueryOverride\n      ? queryDefaults(context.params.query, deleteQuery)\n      : addToQuery(context.params.query, deleteQuery)\n\n    const params = transformParams(\n      {\n        ...context.params,\n        query,\n      },\n      options.transformParams,\n    )\n\n    context.params = params\n\n    if (context.method === 'remove') {\n      let data = getValue(removeData, context)\n      if (isPromise(data)) {\n        data = await data\n      }\n      const method = options.usePatchWithHooks ? 'patch' : '_patch'\n      const result = await context.service[method](context.id, data, params)\n\n      context.result = result\n    }\n\n    if (next) {\n      await next()\n    }\n  }\n}\n\nconst getValue = (value: any, ...args: any[]) => {\n  if (typeof value === 'function') {\n    return value(...args)\n  }\n  return value\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext } from '../../utils/index.js'\n\nexport type StashableOptions = {\n  /** The property name on `context.params` to store the stash function. @default 'stashed' */\n  propName?: string\n  /** Custom function to fetch the pre-mutation state. Defaults to `service.get` or `service.find`. */\n  stashFunc?: (context: HookContext) => Promise<any>\n}\n\nconst defaultStashFunc = (context: HookContext) => {\n  const isMulti = context.id == null\n\n  const params = {\n    ...context.params,\n    _stashable: true,\n    ...(isMulti ? { paginate: false } : {}),\n  }\n\n  return isMulti\n    ? context.service.find(params)\n    : context.service.get(context.id, params)\n}\n\n/**\n * Stashes the pre-mutation state of a record into `context.params`.\n * Eagerly starts the fetch but exposes a memoized function — calling it\n * multiple times only hits the database once.\n * Use in `before` hooks on `update`, `patch`, or `remove` methods.\n *\n * @example\n * ```ts\n * import { stashable } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: { patch: [stashable()] }\n * })\n *\n * // In a later hook (before or after):\n * const before = await context.params.stashed()\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/stashable.html\n */\nexport function stashable<H extends HookContext = HookContext>(\n  options?: StashableOptions,\n) {\n  const propName = options?.propName ?? 'stashed'\n  const stashFunc = options?.stashFunc ?? defaultStashFunc\n\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    if (context.params._stashable) {\n      if (next) return next()\n      return\n    }\n\n    checkContext(context, {\n      type: ['before', 'around'],\n      method: ['update', 'patch', 'remove'],\n      label: 'stashable',\n    })\n\n    const promise = stashFunc(context).catch(() => undefined)\n\n    context.params[propName] = () => promise\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n","import type { HookContext } from '@feathersjs/feathers'\nimport type { PredicateFn } from '../../types.js'\nimport { BadRequest, type FeathersError } from '@feathersjs/errors'\nimport { every, isMulti } from '../../predicates/index.js'\nimport { throwIf } from '../throw-if/throw-if.hook.js'\n\nexport type ThrowIfIsMultiOptions = {\n  /**\n   * A predicate function to filter the contexts that should be checked for multi operations.\n   * If provided, only contexts that pass this predicate will be checked for multi operations.\n   */\n  filter?: PredicateFn\n  /**\n   * Customize the error that is thrown if the context is multi and the service does not allow it.\n   * If not provided, throws a `BadRequest` error.\n   */\n  error?: (context: HookContext) => FeathersError\n}\n\nconst defaultError = (context: HookContext) =>\n  new BadRequest(`Cannot perform multi operation on method '${context.method}'`)\n\n/**\n * Throws a `BadRequest` error when the current operation is a multi operation\n * (array data on `create`, or `id === null` on `patch`/`remove`).\n * Useful to prevent bulk operations on services that should only handle single items.\n *\n * @example\n * ```ts\n * import { throwIfIsMulti } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   before: { all: [throwIfIsMulti()] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/throw-if-is-multi.html\n */\nexport const throwIfIsMulti = <H extends HookContext = HookContext>(\n  options?: ThrowIfIsMultiOptions,\n) =>\n  throwIf<H>(\n    every(\n      every(isMulti, (context) => context.method !== 'find'),\n      options?.filter,\n    ),\n    {\n      error: options?.error ?? defaultError,\n    },\n  )\n","import type { HookContext } from '@feathersjs/feathers'\nimport type { PredicateFn, TransportName } from '../../types.js'\nimport { throwIf } from '../throw-if/throw-if.hook.js'\nimport { every, isProvider } from '../../predicates/index.js'\nimport type { FeathersError } from '@feathersjs/errors'\nimport { MethodNotAllowed } from '@feathersjs/errors'\nimport { toArray } from '../../internal.utils.js'\n\nconst defaultError = (context: HookContext) =>\n  new MethodNotAllowed(\n    `Provider '${context.params.provider}' can not call '${context.method}'.`,\n  )\n\nexport type ThrowIfIsIsProviderOptions = {\n  filter?: PredicateFn\n  /**\n   * Customize the error that is thrown if the context is a provider and the service does not allow it.\n   * If not provided, throws a `MethodNotAllowed` error.\n   */\n  error?: (context: HookContext) => FeathersError\n}\n\n/**\n * Throws a `MethodNotAllowed` error when the request comes from one of the specified transports.\n * Combines `throwIf` with the `isProvider` predicate for a convenient one-liner.\n * Use this to restrict methods to server-only or specific transport types.\n *\n * @example\n * ```ts\n * import { throwIfIsProvider } from 'feathers-utils/hooks'\n *\n * app.service('internal').hooks({\n *   before: { all: [throwIfIsProvider('external')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/throw-if-is-provider.html\n */\nexport const throwIfIsProvider = <H extends HookContext = HookContext>(\n  transports: TransportName | TransportName[],\n  options?: ThrowIfIsIsProviderOptions,\n) => {\n  const disallowTransports = toArray(transports)\n\n  return throwIf<H>(\n    every(isProvider(...(disallowTransports as any)), options?.filter),\n    {\n      error: options?.error ?? defaultError,\n    },\n  )\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { traverse as _traverse } from '../../common/index.js'\n\nexport type TraverseOptions = {\n  transformer: (transformContext: any) => any\n  getObject: (\n    context: HookContext,\n  ) => Record<string, any> | Record<string, any>[]\n  /**\n   * For `around` hooks only: run the traversal *after* `next()` instead of before.\n   * Required when `getObject` targets `context.result`, which is only populated\n   * once the service method has run. Defaults to `false` (run before `next()`),\n   * which is correct for `context.data`/`context.params.query` targets.\n   *\n   * @default false\n   */\n  runAfter?: boolean\n}\n\n/**\n * Recursively walks and transforms fields in record(s) using `neotraverse`.\n * The `getObject` function extracts the target from the context, and `transformer`\n * is called for every node during traversal --- ideal for deep, structural transformations.\n *\n * @example\n * ```ts\n * import { traverse } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n *   after: {\n *     all: [traverse({ getObject: (ctx) => ctx.result, transformer: function () { if (this.key === 'password') this.remove() } })]\n *   }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/traverse.html\n */\nexport const traverse = <H extends HookContext = HookContext>({\n  transformer,\n  getObject,\n  runAfter = false,\n}: TraverseOptions) => {\n  const runTraverse = (context: H) => _traverse(getObject(context), transformer)\n\n  function hook(context: H): void\n  function hook(context: H, next: NextFunction): Promise<void>\n  function hook(context: H, next?: NextFunction): void | Promise<void> {\n    if (next && runAfter) {\n      // around hook targeting context.result: transform after the method ran\n      return next().then(() => {\n        runTraverse(context)\n      })\n    }\n\n    runTraverse(context)\n\n    if (next) return next()\n\n    return\n  }\n  return hook\n}\n"],"mappings":"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"}