{"version":3,"file":"loggerLink-ineCN1PO.mjs","names":["value: unknown","opts: LoggerLinkFnOptions<any> & {\n    colorMode: ColorMode;\n    withContext?: boolean;\n  }","parts: string[]","args: any[]","fn: 'error' | 'log'","opts: LoggerLinkOptions<TRouter>","result:\n            | OperationResultEnvelope<unknown, TRPCClientError<TRouter>>\n            | TRPCClientError<TRouter>"],"sources":["../src/links/loggerLink.ts"],"sourcesContent":["/// <reference lib=\"dom.iterable\" />\n\n// `dom.iterable` types are explicitly required for extracting `FormData` values,\n// as all implementations of `Symbol.iterable` are separated from the main `dom` types.\n// Using triple-slash directive makes sure that it will be available,\n// even if end-user `tsconfig.json` omits it in the `lib` array.\n\nimport { observable, tap } from '@trpc/server/observable';\nimport type {\n  AnyRouter,\n  InferrableClientTypes,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type { TRPCClientError } from '../TRPCClientError';\nimport type { Operation, OperationResultEnvelope, TRPCLink } from './types';\n\ntype ConsoleEsque = {\n  log: (...args: any[]) => void;\n  error: (...args: any[]) => void;\n};\n\ntype EnableFnOptions<TRouter extends InferrableClientTypes> =\n  | {\n      direction: 'down';\n      result:\n        | OperationResultEnvelope<unknown, TRPCClientError<TRouter>>\n        | TRPCClientError<TRouter>;\n    }\n  | (Operation & {\n      direction: 'up';\n    });\ntype EnabledFn<TRouter extends AnyRouter> = (\n  opts: EnableFnOptions<TRouter>,\n) => boolean;\n\ntype LoggerLinkFnOptions<TRouter extends AnyRouter> = Operation &\n  (\n    | {\n        /**\n         * Request result\n         */\n        direction: 'down';\n        result:\n          | OperationResultEnvelope<unknown, TRPCClientError<TRouter>>\n          | TRPCClientError<TRouter>;\n        elapsedMs: number;\n      }\n    | {\n        /**\n         * Request was just initialized\n         */\n        direction: 'up';\n      }\n  );\n\ntype LoggerLinkFn<TRouter extends AnyRouter> = (\n  opts: LoggerLinkFnOptions<TRouter>,\n) => void;\n\ntype ColorMode = 'ansi' | 'css' | 'none';\n\nexport interface LoggerLinkOptions<TRouter extends AnyRouter> {\n  logger?: LoggerLinkFn<TRouter>;\n  enabled?: EnabledFn<TRouter>;\n  /**\n   * Used in the built-in defaultLogger\n   */\n  console?: ConsoleEsque;\n  /**\n   * Color mode\n   * @default typeof window === 'undefined' ? 'ansi' : 'css'\n   */\n  colorMode?: ColorMode;\n\n  /**\n   * Include context in the log - defaults to false unless `colorMode` is 'css'\n   */\n  withContext?: boolean;\n}\n\nfunction isFormData(value: unknown): value is FormData {\n  if (typeof FormData === 'undefined') {\n    // FormData is not supported\n    return false;\n  }\n  return value instanceof FormData;\n}\n\nconst palettes = {\n  css: {\n    query: ['72e3ff', '3fb0d8'],\n    mutation: ['c5a3fc', '904dfc'],\n    subscription: ['ff49e1', 'd83fbe'],\n  },\n  ansi: {\n    regular: {\n      // Cyan background, black and white text respectively\n      query: ['\\x1b[30;46m', '\\x1b[97;46m'],\n      // Magenta background, black and white text respectively\n      mutation: ['\\x1b[30;45m', '\\x1b[97;45m'],\n      // Green background, black and white text respectively\n      subscription: ['\\x1b[30;42m', '\\x1b[97;42m'],\n    },\n    bold: {\n      query: ['\\x1b[1;30;46m', '\\x1b[1;97;46m'],\n      mutation: ['\\x1b[1;30;45m', '\\x1b[1;97;45m'],\n      subscription: ['\\x1b[1;30;42m', '\\x1b[1;97;42m'],\n    },\n  },\n} as const;\n\nfunction constructPartsAndArgs(\n  opts: LoggerLinkFnOptions<any> & {\n    colorMode: ColorMode;\n    withContext?: boolean;\n  },\n) {\n  const { direction, type, withContext, path, id, input } = opts;\n\n  const parts: string[] = [];\n  const args: any[] = [];\n\n  if (opts.colorMode === 'none') {\n    parts.push(direction === 'up' ? '>>' : '<<', type, `#${id}`, path);\n  } else if (opts.colorMode === 'ansi') {\n    const [lightRegular, darkRegular] = palettes.ansi.regular[type];\n    const [lightBold, darkBold] = palettes.ansi.bold[type];\n    const reset = '\\x1b[0m';\n\n    parts.push(\n      direction === 'up' ? lightRegular : darkRegular,\n      direction === 'up' ? '>>' : '<<',\n      type,\n      direction === 'up' ? lightBold : darkBold,\n      `#${id}`,\n      path,\n      reset,\n    );\n  } else {\n    // css color mode\n    const [light, dark] = palettes.css[type];\n    const css = `\n    background-color: #${direction === 'up' ? light : dark};\n    color: ${direction === 'up' ? 'black' : 'white'};\n    padding: 2px;\n  `;\n\n    parts.push(\n      '%c',\n      direction === 'up' ? '>>' : '<<',\n      type,\n      `#${id}`,\n      `%c${path}%c`,\n      '%O',\n    );\n    args.push(\n      css,\n      `${css}; font-weight: bold;`,\n      `${css}; font-weight: normal;`,\n    );\n  }\n\n  if (direction === 'up') {\n    args.push(withContext ? { input, context: opts.context } : { input });\n  } else {\n    args.push({\n      input,\n      result: opts.result,\n      elapsedMs: opts.elapsedMs,\n      ...(withContext && { context: opts.context }),\n    });\n  }\n\n  return { parts, args };\n}\n\n// maybe this should be moved to it's own package\nconst defaultLogger =\n  <TRouter extends AnyRouter>({\n    c = console,\n    colorMode = 'css',\n    withContext,\n  }: {\n    c?: ConsoleEsque;\n    colorMode?: ColorMode;\n    withContext?: boolean;\n  }): LoggerLinkFn<TRouter> =>\n  (props) => {\n    const rawInput = props.input;\n    const input = isFormData(rawInput)\n      ? Object.fromEntries(rawInput)\n      : rawInput;\n\n    const { parts, args } = constructPartsAndArgs({\n      ...props,\n      colorMode,\n      input,\n      withContext,\n    });\n\n    const fn: 'error' | 'log' =\n      props.direction === 'down' &&\n      props.result &&\n      (props.result instanceof Error ||\n        ('error' in props.result.result && props.result.result.error))\n        ? 'error'\n        : 'log';\n\n    c[fn].apply(null, [parts.join(' ')].concat(args));\n  };\n\n/**\n * @see https://trpc.io/docs/v11/client/links/loggerLink\n */\nexport function loggerLink<TRouter extends AnyRouter = AnyRouter>(\n  opts: LoggerLinkOptions<TRouter> = {},\n): TRPCLink<TRouter> {\n  const { enabled = () => true } = opts;\n\n  const colorMode =\n    opts.colorMode ?? (typeof window === 'undefined' ? 'ansi' : 'css');\n  const withContext = opts.withContext ?? colorMode === 'css';\n  const {\n    logger = defaultLogger({ c: opts.console, colorMode, withContext }),\n  } = opts;\n\n  return () => {\n    return ({ op, next }) => {\n      return observable((observer) => {\n        // ->\n        if (enabled({ ...op, direction: 'up' })) {\n          logger({\n            ...op,\n            direction: 'up',\n          });\n        }\n        const requestStartTime = Date.now();\n        function logResult(\n          result:\n            | OperationResultEnvelope<unknown, TRPCClientError<TRouter>>\n            | TRPCClientError<TRouter>,\n        ) {\n          const elapsedMs = Date.now() - requestStartTime;\n\n          if (enabled({ ...op, direction: 'down', result })) {\n            logger({\n              ...op,\n              direction: 'down',\n              elapsedMs,\n              result,\n            });\n          }\n        }\n        return next(op)\n          .pipe(\n            tap({\n              next(result) {\n                logResult(result);\n              },\n              error(result) {\n                logResult(result);\n              },\n            }),\n          )\n          .subscribe(observer);\n      });\n    };\n  };\n}\n"],"mappings":"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"}