{"version":3,"file":"mutate-result.util-C0nY6L7i.mjs","names":[],"sources":["../src/utils/get-data-is-array/get-data-is-array.util.ts","../src/utils/get-result-is-array/get-result-is-array.util.ts","../src/utils/replace-data/replace-data.util.ts","../src/utils/mutate-data/mutate-data.util.ts","../src/utils/replace-result/replace-result.util.ts","../src/utils/mutate-result/mutate-result.util.ts"],"sourcesContent":["import type { HookContext } from '@feathersjs/feathers'\nimport type { DataSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport type GetDataIsArrayReturn<H extends HookContext = HookContext> = {\n  isArray: boolean\n  data: DataSingleHookContext<H>[]\n}\n\n/**\n * Normalizes `context.data` into an array for uniform processing.\n * Returns `{ data, isArray }` where `data` is always an array and `isArray` indicates\n * whether the original value was already an array.\n *\n * @example\n * ```ts\n * import { getDataIsArray } from 'feathers-utils/utils'\n *\n * const { data, isArray } = getDataIsArray(context)\n * data.forEach(item => { /* process each item *\\/ })\n * ```\n *\n * @see https://utils.feathersjs.com/utils/get-data-is-array.html\n */\nexport function getDataIsArray<H extends HookContext = HookContext>(\n  context: H,\n): GetDataIsArrayReturn<H> {\n  if (!context.data) {\n    return {\n      isArray: false,\n      data: [],\n    }\n  }\n\n  const isArray = Array.isArray(context.data)\n\n  return {\n    isArray,\n    data: isArray ? context.data : [context.data],\n  }\n}\n","import type { HookContext } from '@feathersjs/feathers'\nimport { copy } from 'fast-copy'\nimport type { ResultSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport type GetResultIsArrayOptions = {\n  dispatch?: boolean\n}\n\nexport type GetResultIsArrayReturn<H extends HookContext = HookContext> = {\n  isArray: boolean\n  result: ResultSingleHookContext<H>[]\n  key: 'dispatch' | 'result'\n}\n\n/**\n * Normalizes `context.result` (or `context.dispatch`) into an array for uniform processing.\n * Handles paginated results by extracting the `data` array. Returns `{ result, isArray, key }`\n * where `key` indicates whether `'result'` or `'dispatch'` was used.\n *\n * @example\n * ```ts\n * import { getResultIsArray } from 'feathers-utils/utils'\n *\n * const { result, isArray } = getResultIsArray(context)\n * result.forEach(item => { /* process each item *\\/ })\n * ```\n *\n * @see https://utils.feathersjs.com/utils/get-result-is-array.html\n */\nexport function getResultIsArray<H extends HookContext = HookContext>(\n  context: H,\n  options?: GetResultIsArrayOptions,\n): GetResultIsArrayReturn<H> {\n  const { dispatch = false } = options || {}\n\n  const isDispatch: boolean = dispatch && context.dispatch !== undefined\n\n  const result = dispatch\n    ? isDispatch\n      ? context.dispatch\n      : copy(context.result)\n    : context.result\n\n  if (!result) {\n    return {\n      isArray: false,\n      result: [],\n      key: isDispatch ? 'dispatch' : 'result',\n    }\n  }\n\n  const items = context.method === 'find' ? result.data || result : result\n\n  const isArray = Array.isArray(items)\n\n  return {\n    isArray,\n    result: isArray ? items : items ? [items] : [],\n    key: isDispatch ? 'dispatch' : 'result',\n  }\n}\n","import type { HookContext } from \"@feathersjs/feathers\";\nimport type { DataSingleHookContext } from \"../../utility-types/hook-context.js\";\n\n/**\n * Replaces `context.data` wholesale with the given items, preserving the original\n * single-vs-array shape. This is the explicit inverse of `getDataIsArray`: get the\n * data as an array, modify or replace the items, then write them back.\n *\n * @example\n * ```ts\n * import { getDataIsArray, replaceData } from 'feathers-utils/utils'\n *\n * const { data } = getDataIsArray(context)\n * const next = data.map((item) => ({ ...item, slug: slugify(item.name) }))\n * replaceData(context, next)\n * ```\n *\n * @see https://utils.feathersjs.com/utils/replace-data.html\n */\nexport function replaceData<H extends HookContext = HookContext>(\n  context: H,\n  data: DataSingleHookContext<H>[],\n): H {\n  context.data = Array.isArray(context.data) ? data : data[0];\n  return context;\n}\n","import type { HookContext } from '@feathersjs/feathers'\nimport { getDataIsArray } from '../get-data-is-array/get-data-is-array.util.js'\nimport { replaceData } from '../replace-data/replace-data.util.js'\nimport { isPromise } from '../../common/index.js'\nimport type { Promisable } from '../../internal.utils.js'\nimport type { TransformerInputFn } from '../../types.js'\n\n/**\n * Applies a transformer function to each item in `context.data`, updating it in place.\n * If the transformer returns a new object, it replaces the original item.\n * Correctly handles both single-item and array data, preserving the original shape.\n *\n * @example\n * ```ts\n * import { mutateData } from 'feathers-utils/utils'\n *\n * await mutateData(context, (item) => { item.name = item.name.trim() })\n * ```\n *\n * @see https://utils.feathersjs.com/utils/mutate-data.html\n */\nexport function mutateData<H extends HookContext = HookContext>(\n  context: H,\n  transformer: TransformerInputFn<any, H>,\n): Promisable<H> {\n  if (!context.data) {\n    return context\n  }\n\n  // single-item fast path: avoid allocating a wrapper array + a mapped array\n  // for the common single create/update/patch case.\n  if (!Array.isArray(context.data)) {\n    const item = context.data\n    const result = transformer(item, { context, i: 0 })\n\n    if (isPromise(result)) {\n      return result.then((res: any) => {\n        context.data = res ?? item\n        return context\n      })\n    }\n\n    context.data = result ?? item\n    return context\n  }\n\n  const { data } = getDataIsArray(context)\n\n  if (!data.length) {\n    return context\n  }\n\n  let hasPromises = false\n\n  const results = data.map((item, i) => {\n    const result = transformer(item, { context, i })\n\n    if (isPromise(result)) {\n      hasPromises = true\n      return result.then((res: any) => res ?? item)\n    }\n\n    return result ?? item\n  })\n\n  function mutate(data: any) {\n    // delegate the array writeback (single is handled by the fast path above)\n    return replaceData(context, data)\n  }\n\n  if (hasPromises) {\n    return Promise.all(results).then(mutate)\n  } else {\n    return mutate(results)\n  }\n}\n","import type { HookContext } from \"@feathersjs/feathers\";\nimport { copy } from \"fast-copy\";\nimport { getResultIsArray } from \"../get-result-is-array/get-result-is-array.util.js\";\nimport type { DispatchOption } from \"../../types.js\";\nimport type { ResultSingleHookContext } from \"../../utility-types/hook-context.js\";\n\nexport type ReplaceResultOptions = {\n  /**\n   * Also (or only) write to `context.dispatch`. `true` writes dispatch, `'both'`\n   * writes both `result` and `dispatch`. When dispatch is requested and not yet\n   * present, it is seeded from a clone of `context.result`.\n   */\n  dispatch?: DispatchOption;\n};\n\n/**\n * Replaces `context.result` (and/or `context.dispatch`) wholesale with the given\n * items, preserving the original shape: single item, array, or paginated `{ data }`.\n * This is the explicit inverse of `getResultIsArray`.\n *\n * @example\n * ```ts\n * import { getResultIsArray, replaceResult } from 'feathers-utils/utils'\n *\n * const { result } = getResultIsArray(context)\n * replaceResult(context, result.filter((item) => item.public))\n * ```\n *\n * @see https://utils.feathersjs.com/utils/replace-result.html\n */\nexport function replaceResult<H extends HookContext = HookContext>(\n  context: H,\n  result: ResultSingleHookContext<H>[],\n  options?: ReplaceResultOptions,\n): H {\n  if (!!options?.dispatch && !context.dispatch) {\n    context.dispatch = copy(context.result);\n  }\n\n  const write = (dispatch: boolean) => {\n    const { isArray, key } = getResultIsArray(context, { dispatch });\n\n    if (!isArray) {\n      context[key] = result[0];\n    } else if (!Array.isArray(context[key]) && context[key]?.data) {\n      context[key].data = result;\n    } else {\n      context[key] = result;\n    }\n  };\n\n  if (options?.dispatch === \"both\") {\n    write(true);\n    write(false);\n  } else {\n    write(!!options?.dispatch);\n  }\n\n  return context;\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { getResultIsArray } from '../get-result-is-array/get-result-is-array.util.js'\nimport { replaceResult } from '../replace-result/replace-result.util.js'\nimport { isPromise } from '../../common/index.js'\nimport { copy } from 'fast-copy'\nimport type { Promisable } from '../../internal.utils.js'\nimport type { DispatchOption, TransformerInputFn } from '../../types.js'\n\nexport type MutateResultOptions = {\n  next?: NextFunction\n  transform?: (items: any[]) => any[]\n  dispatch?: DispatchOption\n}\n\n/**\n * Applies a transformer function to each item in `context.result` (and optionally `context.dispatch`).\n * Handles paginated results, single items, and arrays transparently.\n * Use the `dispatch` option to control whether result, dispatch, or both are transformed.\n *\n * @example\n * ```ts\n * import { mutateResult } from 'feathers-utils/utils'\n *\n * await mutateResult(context, (item) => { delete item.password })\n * ```\n *\n * @see https://utils.feathersjs.com/utils/mutate-result.html\n */\nexport function mutateResult<H extends HookContext = HookContext>(\n  context: H,\n  transformer: TransformerInputFn<any, H>,\n  options?: MutateResultOptions,\n): Promisable<H> {\n  if (!!options?.dispatch && !context.dispatch) {\n    context.dispatch = copy(context.result)\n  }\n\n  function forResult(dispatch: boolean): Promisable<H> {\n    const { result } = getResultIsArray(context, { dispatch })\n\n    if (!result.length) {\n      return context\n    }\n\n    let hasPromises = false\n\n    const results = result.map((item, i) => {\n      const result = transformer(item, { context, i })\n\n      if (isPromise(result)) {\n        hasPromises = true\n        return result.then((res: any) => res ?? item)\n      }\n\n      return result ?? item\n    })\n\n    function mutate(r: any) {\n      if (options?.transform) {\n        r = options.transform(r)\n      }\n\n      // delegate the single/array/paginated writeback to replaceResult\n      return replaceResult(context, r, { dispatch })\n    }\n\n    if (hasPromises) {\n      return Promise.all(results).then(mutate)\n    } else {\n      return mutate(results)\n    }\n  }\n\n  function run(): Promisable<H> {\n    if (options?.dispatch === 'both') {\n      const a = forResult(true)\n      const b = forResult(false)\n\n      if (isPromise(a) || isPromise(b)) {\n        return Promise.all([a, b]).then(() => context)\n      }\n\n      return context\n    }\n\n    return forResult(options?.dispatch ?? false)\n  }\n\n  if (options?.next) {\n    return options.next().then(run)\n  }\n\n  return run()\n}\n"],"mappings":"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"}