{"version":3,"file":"index.cjs","names":["otelTraceApi","autotelTraceFn","hashJson","getEventQueue","getSdk","getLogger","_closeEmbeddedDevtools","mergeInto","nodeAsyncHooks","otelTrace","createTraceContext","flattenToAttributes","createStructuredError"],"sources":["../src/trace-hybrid.ts","../src/define-event.ts","../src/shutdown.ts","../src/request-logger.ts","../src/error-catalog.ts","../src/drain-toolkit.ts","../src/enricher-toolkit.ts"],"sourcesContent":["/**\n * Hybrid `trace` export: callable like autotel's `trace(fn)`, AND exposes the\n * full `@opentelemetry/api` `TraceAPI` surface (`trace.getActiveSpan()`,\n * `trace.getTracer()`, …) so existing OTel code \"just works\" when imported\n * from `autotel`.\n *\n * Implementation: `Object.assign` mutates the autotel `trace` function to\n * attach the OTel TraceAPI methods. Because every reference to `trace` across\n * autotel resolves to the same function instance, this is a one-time, global\n * augmentation.\n */\n\nimport { trace as otelTraceApi } from '@opentelemetry/api';\nimport { trace as autotelTraceFn } from './functional';\n\nconst otelMethods = {\n  // Class methods on TraceAPI — bind to the singleton.\n  setGlobalTracerProvider:\n    otelTraceApi.setGlobalTracerProvider.bind(otelTraceApi),\n  getTracerProvider: otelTraceApi.getTracerProvider.bind(otelTraceApi),\n  getTracer: otelTraceApi.getTracer.bind(otelTraceApi),\n  disable: otelTraceApi.disable.bind(otelTraceApi),\n  // Instance fields on TraceAPI — already standalone, copy by reference.\n  wrapSpanContext: otelTraceApi.wrapSpanContext,\n  isSpanContextValid: otelTraceApi.isSpanContextValid,\n  deleteSpan: otelTraceApi.deleteSpan,\n  getSpan: otelTraceApi.getSpan,\n  getActiveSpan: otelTraceApi.getActiveSpan,\n  getSpanContext: otelTraceApi.getSpanContext,\n  setSpan: otelTraceApi.setSpan,\n  setSpanContext: otelTraceApi.setSpanContext,\n};\n\nexport const trace: typeof autotelTraceFn & typeof otelTraceApi = Object.assign(\n  autotelTraceFn,\n  otelMethods,\n) as typeof autotelTraceFn & typeof otelTraceApi;\n","import { track } from './track';\nimport { hashJson } from './stable-hash';\nimport type { EventSchemaMetadata } from './event-subscriber';\n\ntype SafeParseResult<T> =\n  | { success: true; data: T }\n  | { success: false; error: unknown };\n\nexport interface SchemaLike<T> {\n  safeParse(input: unknown): SafeParseResult<T>;\n}\n\nexport interface DefineEventOptions<S> {\n  toJsonSchema?: (schema: S) => unknown;\n}\n\nexport interface DefinedEvent<Name extends string, Payload> {\n  readonly name: Name;\n  readonly schemaMetadata?: EventSchemaMetadata;\n  track(payload: Payload): void;\n}\n\nexport function defineEvent<\n  Name extends string,\n  Payload,\n  S extends SchemaLike<Payload>,\n>(\n  name: Name,\n  schema: S,\n  options: DefineEventOptions<S> = {},\n): DefinedEvent<Name, Payload> {\n  const jsonSchema = options.toJsonSchema?.(schema);\n  const schemaMetadata = jsonSchema\n    ? {\n        source: 'zod' as const,\n        jsonSchema,\n        hash: hashJson(jsonSchema),\n      }\n    : undefined;\n\n  return {\n    name,\n    schemaMetadata,\n    track(payload: Payload) {\n      const parsed = schema.safeParse(payload);\n      if (!parsed.success) {\n        throw new Error(\n          `Invalid payload for event \"${name}\". Schema validation failed.`,\n        );\n      }\n      track(\n        name,\n        parsed.data,\n        schemaMetadata ? { schema: schemaMetadata } : undefined,\n      );\n    },\n  };\n}\n","/**\n * Graceful shutdown with flush and cleanup\n */\n\nimport { getSdk, getLogger, _closeEmbeddedDevtools } from './init';\nimport { getEventQueue, resetEventQueue } from './track';\nimport { resetEvents } from './event';\nimport { resetMetrics } from './metric';\n\n/**\n * Flush all pending telemetry\n *\n * Flushes both events events and OpenTelemetry spans to their destinations.\n * Includes timeout protection to prevent hanging in serverless environments.\n *\n * Safe to call multiple times.\n *\n * @param options - Optional configuration\n * @param options.timeout - Timeout in milliseconds (default: 2000ms)\n * @param options.forShutdown - If true, permanently disables the events queue after flush (used internally by shutdown())\n *\n * @example Manual flush in serverless\n * ```typescript\n * import { flush } from 'autotel';\n *\n * export const handler = async (event) => {\n *   // ... process event\n *   await flush(); // Flush before function returns\n *   return result;\n * };\n * ```\n *\n * @example With custom timeout\n * ```typescript\n * await flush({ timeout: 5000 }); // 5 second timeout\n * ```\n */\nexport async function flush(options?: {\n  timeout?: number;\n  forShutdown?: boolean;\n}): Promise<void> {\n  const timeout = options?.timeout ?? 2000;\n  const forShutdown = options?.forShutdown ?? false;\n\n  const doFlush = async () => {\n    // Flush events queue (or shutdown queue when tearing down)\n    const eventsQueue = getEventQueue();\n    if (eventsQueue) {\n      if (forShutdown) {\n        await eventsQueue.shutdown();\n      } else {\n        await eventsQueue.flush();\n      }\n    }\n\n    // Flush OpenTelemetry spans\n    // This ensures spans are exported immediately, critical for serverless\n    const sdk = getSdk();\n    if (sdk) {\n      try {\n        // Type assertion needed as getTracerProvider is not in the public NodeSDK interface\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        const sdkAny = sdk as any;\n        if (typeof sdkAny.getTracerProvider === 'function') {\n          const tracerProvider = sdkAny.getTracerProvider();\n          if (\n            tracerProvider &&\n            typeof tracerProvider.forceFlush === 'function'\n          ) {\n            await tracerProvider.forceFlush();\n          }\n        }\n      } catch {\n        // Ignore errors when accessing tracer provider (may not be available in test mocks)\n      }\n    }\n  };\n\n  // Add timeout protection to prevent hanging\n  let timeoutHandle: NodeJS.Timeout | undefined;\n  try {\n    await Promise.race([\n      doFlush().finally(() => {\n        // Clear timeout as soon as flush completes\n        if (timeoutHandle) {\n          clearTimeout(timeoutHandle);\n        }\n      }),\n      new Promise<void>((_, reject) => {\n        timeoutHandle = setTimeout(\n          () => reject(new Error('Flush timeout')),\n          timeout,\n        );\n        // Use unref() to allow Node to exit if flush completes first\n        // This prevents the 2s delay in serverless when flush succeeds immediately\n        timeoutHandle.unref();\n      }),\n    ]);\n  } catch (error) {\n    // Clear timeout on error too\n    if (timeoutHandle) {\n      clearTimeout(timeoutHandle);\n    }\n    const logger = getLogger();\n    logger.error(\n      {\n        err: error instanceof Error ? error : new Error(String(error)),\n      },\n      '[autotel] Flush error',\n    );\n    throw error;\n  }\n}\n\n/**\n * Shutdown telemetry and cleanup resources\n *\n * - Flushes all pending data\n * - Shuts down OpenTelemetry SDK\n * - Cleans up resources\n *\n * Call this before process exit.\n *\n * Always performs cleanup even if flush fails, preventing resource leaks\n * in serverless handlers or tests.\n *\n * @example Express server\n * ```typescript\n * const server = app.listen(3000)\n *\n * process.on('SIGTERM', async () => {\n *   await server.close()\n *   await shutdown()\n *   process.exit(0)\n * })\n * ```\n */\nexport async function shutdown(): Promise<void> {\n  const logger = getLogger();\n  let shutdownError: Error | null = null;\n\n  // Attempt to flush (with queue shutdown so new events are rejected), but continue with cleanup even if it fails\n  try {\n    await flush({ forShutdown: true });\n  } catch (error) {\n    const err = error instanceof Error ? error : new Error(String(error));\n    shutdownError = err;\n    logger.error(\n      {\n        err,\n      },\n      '[autotel] Flush failed during shutdown, continuing cleanup',\n    );\n  }\n\n  // Always shutdown SDK and clean up resources\n  try {\n    // Shutdown OpenTelemetry SDK\n    const sdk = getSdk();\n    if (sdk) {\n      await sdk.shutdown();\n    }\n  } catch (error) {\n    const err = error instanceof Error ? error : new Error(String(error));\n\n    // Ignore ECONNREFUSED errors - this happens when no OTLP endpoint was configured\n    // The SDK tries to flush exporters that don't exist, which is harmless\n    const isConnectionRefused =\n      typeof error === 'object' &&\n      error !== null &&\n      'code' in error &&\n      error.code === 'ECONNREFUSED';\n\n    if (!isConnectionRefused) {\n      // Only store/log non-connection errors\n      if (!shutdownError) {\n        shutdownError = err;\n      }\n      logger.error({ err }, '[autotel] SDK shutdown failed');\n    }\n  } finally {\n    await _closeEmbeddedDevtools();\n\n    // Clean up singleton Maps and queues to prevent memory leaks\n    // This runs even if SDK shutdown fails\n    const eventsQueue = getEventQueue();\n    if (eventsQueue && typeof eventsQueue.cleanup === 'function') {\n      eventsQueue.cleanup();\n    }\n    resetEvents();\n    resetMetrics();\n    resetEventQueue();\n  }\n\n  // Rethrow first error after cleanup completes\n  // This allows tests and CI to detect failures while still ensuring cleanup\n  if (shutdownError) {\n    throw shutdownError;\n  }\n}\n\n/**\n * Register automatic shutdown hooks for common signals\n *\n * Handles:\n * - SIGTERM (Docker/K8s graceful shutdown)\n * - SIGINT (Ctrl+C)\n *\n * @internal Called automatically on module load\n */\nfunction registerShutdownHooks(): void {\n  if (typeof process === 'undefined') return; // Not in Node.js\n\n  const signals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT'];\n  let shuttingDown = false;\n\n  for (const signal of signals) {\n    process.on(signal, async () => {\n      if (shuttingDown) return; // Prevent double shutdown\n      shuttingDown = true;\n\n      if (process.env.NODE_ENV !== 'test') {\n        getLogger().info(\n          {},\n          `[autotel] Received ${signal}, flushing telemetry...`,\n        );\n      }\n\n      try {\n        await shutdown();\n      } catch (error) {\n        getLogger().error(\n          {\n            err: error instanceof Error ? error : undefined,\n          },\n          '[autotel] Error during shutdown',\n        );\n      } finally {\n        process.exit(0);\n      }\n    });\n  }\n}\n\n// Auto-register shutdown hooks\nregisterShutdownHooks();\n","// namespace import for browser-bundler compat — see node-require.ts\nimport * as nodeAsyncHooks from 'node:async_hooks';\nimport { trace as otelTrace } from '@opentelemetry/api';\nimport type { TraceContext } from './trace-context';\nimport { createTraceContext } from './trace-context';\nimport { recordStructuredError } from './structured-error';\nimport { flattenToAttributes } from './flatten-attributes';\nimport { emitCorrelatedEvent } from './correlated-events';\n\nconst POST_EMIT_FORK_HINT =\n  \"For intentional background work tied to this request, use log.fork('label', fn) when available.\";\n\nfunction warnPostEmit(method: string, detail: string): void {\n  console.warn(\n    `[autotel] ${method} called after the wide event was emitted — ${detail} This data will not appear in observability. ${POST_EMIT_FORK_HINT}`,\n  );\n}\n\nfunction mergeInto(\n  target: Record<string, unknown>,\n  source: Record<string, unknown>,\n): void {\n  for (const key in source) {\n    const sourceVal = source[key];\n    if (sourceVal === undefined) continue;\n    const targetVal = target[key];\n    if (\n      sourceVal !== null &&\n      typeof sourceVal === 'object' &&\n      !Array.isArray(sourceVal) &&\n      targetVal !== null &&\n      typeof targetVal === 'object' &&\n      !Array.isArray(targetVal)\n    ) {\n      mergeInto(\n        targetVal as Record<string, unknown>,\n        sourceVal as Record<string, unknown>,\n      );\n    } else if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {\n      target[key] = [...targetVal, ...sourceVal];\n    } else {\n      target[key] = sourceVal;\n    }\n  }\n}\n\nconst requestContextStore =\n  new nodeAsyncHooks.AsyncLocalStorage<TraceContext>();\n\nexport function runWithRequestContext<T>(ctx: TraceContext, fn: () => T): T {\n  return requestContextStore.run(ctx, fn);\n}\n\nexport interface RequestLogger {\n  set(fields: Record<string, unknown>): void;\n  info(message: string, fields?: Record<string, unknown>): void;\n  warn(message: string, fields?: Record<string, unknown>): void;\n  error(error: Error | string, fields?: Record<string, unknown>): void;\n  getContext(): Record<string, unknown>;\n  emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot;\n  fork(\n    label: string,\n    fn: () => void | Promise<void>,\n    options?: ForkOptions,\n  ): void;\n}\n\nexport interface RequestLogSnapshot {\n  timestamp: string;\n  traceId: string;\n  spanId: string;\n  correlationId: string;\n  context: Record<string, unknown>;\n}\n\nexport interface RequestLoggerOptions {\n  /** Callback invoked by emitNow() for manual fan-out. */\n  onEmit?: (snapshot: RequestLogSnapshot) => void | Promise<void>;\n}\n\n/**\n * Optional lifecycle hooks for adapters that need to track child loggers\n * spawned by `log.fork()` (e.g. active logger maps in framework integrations).\n */\nexport interface ForkLifecycle {\n  /** Called after the child logger is created, before `fn` runs. */\n  onChildEnter?: (child: RequestLogger) => void;\n  /** Called after the child has finished (emit + drain), success or failure. */\n  onChildExit?: (child: RequestLogger) => void;\n}\n\nexport interface ForkOptions {\n  lifecycle?: ForkLifecycle;\n}\n\nfunction resolveContext(ctx?: TraceContext): TraceContext {\n  if (ctx) return ctx;\n\n  const stored = requestContextStore.getStore();\n  if (stored) return stored;\n\n  const span = otelTrace.getActiveSpan();\n  if (!span) {\n    throw new Error(\n      '[autotel] getRequestLogger() requires an active span or runWithRequestContext(). Wrap your handler with trace() or use runWithRequestContext().',\n    );\n  }\n  return createTraceContext(span);\n}\n\nexport function getRequestLogger(\n  ctx?: TraceContext,\n  options?: RequestLoggerOptions,\n): RequestLogger {\n  const activeContext = resolveContext(ctx);\n  const contextState: Record<string, unknown> = {};\n  let emitted = false;\n  let lastSnapshot: RequestLogSnapshot | null = null;\n\n  const addLogEvent = (\n    level: 'info' | 'warn' | 'error',\n    message: string,\n    fields?: Record<string, unknown>,\n  ) => {\n    const attrs = fields ? flattenToAttributes(fields) : undefined;\n    emitCorrelatedEvent(activeContext, `log.${level}`, {\n      message,\n      ...attrs,\n    });\n  };\n\n  const sealCheck = (method: string, keys: string[]): void => {\n    if (emitted) {\n      warnPostEmit(\n        method,\n        `Keys dropped: ${keys.length > 0 ? keys.join(', ') : '(empty)'}.`,\n      );\n    }\n  };\n\n  return {\n    set(fields: Record<string, unknown>) {\n      sealCheck('log.set()', Object.keys(fields));\n      if (emitted) return;\n      mergeInto(contextState, fields);\n      activeContext.setAttributes(flattenToAttributes(fields));\n    },\n\n    info(message: string, fields?: Record<string, unknown>) {\n      const keys = fields\n        ? ['message', ...Object.keys(fields).filter((k) => k !== 'requestLogs')]\n        : ['message'];\n      sealCheck('log.info()', keys);\n      if (emitted) return;\n      addLogEvent('info', message, fields);\n      if (fields) {\n        mergeInto(contextState, fields);\n        activeContext.setAttributes(flattenToAttributes(fields));\n      }\n    },\n\n    warn(message: string, fields?: Record<string, unknown>) {\n      const keys = fields\n        ? ['message', ...Object.keys(fields).filter((k) => k !== 'requestLogs')]\n        : ['message'];\n      sealCheck('log.warn()', keys);\n      if (emitted) return;\n      addLogEvent('warn', message, fields);\n      activeContext.setAttribute('autotel.log.level', 'warn');\n      if (fields) {\n        mergeInto(contextState, fields);\n        activeContext.setAttributes(flattenToAttributes(fields));\n      }\n    },\n\n    error(error: Error | string, fields?: Record<string, unknown>) {\n      const keys = fields ? [...Object.keys(fields), 'error'] : ['error'];\n      sealCheck('log.error()', keys);\n      if (emitted) return;\n      const err = typeof error === 'string' ? new Error(error) : error;\n      recordStructuredError(activeContext, err);\n      addLogEvent('error', err.message, fields);\n\n      if (fields) {\n        mergeInto(contextState, fields);\n        activeContext.setAttributes(flattenToAttributes(fields));\n      }\n      activeContext.setAttribute('autotel.log.level', 'error');\n    },\n\n    getContext() {\n      return { ...contextState };\n    },\n\n    emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot {\n      if (emitted) {\n        warnPostEmit('log.emitNow()', 'Ignoring duplicate emit.');\n        return lastSnapshot as RequestLogSnapshot;\n      }\n\n      const mergedContext = {\n        ...contextState,\n        ...overrides,\n      };\n      const flattened = flattenToAttributes(mergedContext);\n      activeContext.setAttributes(flattened);\n\n      const snapshot: RequestLogSnapshot = {\n        timestamp: new Date().toISOString(),\n        traceId: activeContext.traceId,\n        spanId: activeContext.spanId,\n        correlationId: activeContext.correlationId,\n        context: mergedContext,\n      };\n\n      emitCorrelatedEvent(activeContext, 'log.emit.manual', {\n        ...flattened,\n      });\n\n      if (options?.onEmit) {\n        Promise.resolve(options.onEmit(snapshot)).catch((error) => {\n          console.warn('[autotel] request logger onEmit failed:', error);\n        });\n      }\n\n      emitted = true;\n      lastSnapshot = snapshot;\n      return snapshot;\n    },\n\n    fork(\n      label: string,\n      fn: () => void | Promise<void>,\n      forkOptions?: ForkOptions,\n    ): void {\n      const parentRequestId = activeContext.correlationId;\n      if (typeof parentRequestId !== 'string' || parentRequestId.length === 0) {\n        throw new Error(\n          '[autotel] log.fork() requires the parent logger to have a correlationId. ' +\n            'Ensure the request was created by autotel middleware.',\n        );\n      }\n\n      const tracer = otelTrace.getTracer('autotel.request-logger');\n      const lifecycle = forkOptions?.lifecycle;\n      void tracer.startActiveSpan(`request.fork:${label}`, (childSpan) => {\n        const childContext: TraceContext = {\n          ...createTraceContext(childSpan),\n          correlationId: crypto.randomUUID(),\n        };\n\n        requestContextStore.run(childContext, () => {\n          const childLog = getRequestLogger(childContext);\n          childLog.set({\n            operation: label,\n            _parentCorrelationId: parentRequestId,\n          });\n\n          lifecycle?.onChildEnter?.(childLog);\n\n          void Promise.resolve()\n            .then(() => fn())\n            .then(() => {\n              childLog.emitNow();\n            })\n            .catch((error_: unknown) => {\n              const error =\n                error_ instanceof Error ? error_ : new Error(String(error_));\n              childLog.error(error);\n              childLog.emitNow();\n            })\n            .finally(() => {\n              try {\n                lifecycle?.onChildExit?.(childLog);\n              } catch (hookError) {\n                console.warn(\n                  '[autotel] fork onChildExit hook threw:',\n                  hookError,\n                );\n              }\n              childSpan.end();\n            });\n        });\n      });\n    },\n  };\n}\n\n/**\n * Returns `true` when a request-logger context can be resolved without throwing —\n * i.e. an explicit `ctx` was provided, a `runWithRequestContext()` scope is active,\n * or there is an active OpenTelemetry span.\n *\n * Use this to branch on observability availability instead of wrapping\n * {@link getRequestLogger} in try/catch.\n */\nexport function hasRequestContext(ctx?: TraceContext): boolean {\n  if (ctx) return true;\n  if (requestContextStore.getStore()) return true;\n  return otelTrace.getActiveSpan() != null;\n}\n\n/**\n * Like {@link getRequestLogger}, but returns `null` instead of throwing when no\n * request context is available. Intended for best-effort instrumentation where a\n * missing telemetry context must never crash business logic.\n */\nexport function getRequestLoggerSafe(\n  ctx?: TraceContext,\n  options?: RequestLoggerOptions,\n): RequestLogger | null {\n  if (!hasRequestContext(ctx)) return null;\n  return getRequestLogger(ctx, options);\n}\n\n/**\n * A no-op {@link RequestLogger} whose methods do nothing. Used as a fallback by\n * best-effort instrumentation so wrapped handlers can run un-instrumented without\n * branching on logger presence.\n */\nexport function createNoopRequestLogger(): RequestLogger {\n  const snapshot = (): RequestLogSnapshot => ({\n    timestamp: new Date().toISOString(),\n    traceId: '',\n    spanId: '',\n    correlationId: '',\n    context: {},\n  });\n\n  return {\n    set() {},\n    info() {},\n    warn() {},\n    error() {},\n    getContext() {\n      return {};\n    },\n    emitNow() {\n      return snapshot();\n    },\n    fork(_label, fn) {\n      void Promise.resolve().then(() => fn());\n    },\n  };\n}\n","/**\n * Typed error and audit catalogs.\n *\n * Group related errors into one catalog and get a refactor-safe builder per\n * code, with autocomplete at every call site and typed message parameters.\n *\n * @example\n * ```typescript\n * import { defineErrorCatalog } from 'autotel';\n *\n * export const billing = defineErrorCatalog('billing', {\n *   PAYMENT_DECLINED: {\n *     status: 402,\n *     message: 'Card declined',\n *     why: 'The issuer rejected the charge',\n *     fix: 'Try a different payment method',\n *   },\n *   INSUFFICIENT_FUNDS: {\n *     status: 402,\n *     message: ({ available, required }: { available: number; required: number }) =>\n *       `Insufficient funds: $${available} of $${required}`,\n *   },\n * });\n *\n * throw billing.PAYMENT_DECLINED({ cause: stripeError });\n * throw billing.INSUFFICIENT_FUNDS({ available: 5, required: 100 });\n *\n * // In a catch block — refactor-safe, no magic strings:\n * if (billing.PAYMENT_DECLINED.match(err)) { ... }\n * ```\n */\n\nimport {\n  createStructuredError,\n  type StructuredError,\n} from './structured-error';\n\nconst catalogCodeKey = Symbol.for('autotel.catalog.code');\n\n/** Definition of a single error in a catalog. */\nexport interface ErrorCatalogEntry {\n  /**\n   * Human-readable message. Use a function to interpolate typed parameters;\n   * the parameter type flows through to the call site.\n   */\n  message: string | ((params: never) => string);\n  /** HTTP status to surface to clients. */\n  status?: number;\n  /** Stable error code. Defaults to `${namespace}.${KEY}`. */\n  code?: string | number;\n  /** Why it happened. A function receives the same params as `message`. */\n  why?: string | ((params: never) => string);\n  /** What the caller should do next. */\n  fix?: string;\n  /** Docs or runbook link. */\n  link?: string;\n  /** Error name. Defaults to the catalog key. */\n  name?: string;\n}\n\n/** Per-call options passed alongside (or instead of) typed params. */\nexport interface ErrorBuildOptions {\n  cause?: unknown;\n  details?: Record<string, unknown>;\n  /** Backend-only context. Never serialized to clients. */\n  internal?: Record<string, unknown>;\n}\n\ntype ParamsOf<E> = E extends { message: (params: infer P) => string }\n  ? P\n  : E extends { why: (params: infer P) => string }\n    ? P\n    : void;\n\ntype BuilderArgs<E extends ErrorCatalogEntry> =\n  ParamsOf<E> extends void\n    ? [options?: ErrorBuildOptions]\n    : [params: ParamsOf<E>, options?: ErrorBuildOptions];\n\n/** A callable error factory produced by {@link defineErrorCatalog}. */\nexport interface ErrorBuilder<E extends ErrorCatalogEntry> {\n  (...args: BuilderArgs<E>): StructuredError;\n  /** Stable code assigned to every error from this entry. */\n  readonly code: string | number;\n  /** True when `error` was produced by this catalog entry. */\n  match(error: unknown): boolean;\n}\n\nexport type ErrorCatalog<T extends Record<string, ErrorCatalogEntry>> = {\n  readonly [K in keyof T]: ErrorBuilder<T[K]>;\n};\n\nfunction readCatalogCode(error: unknown): string | number | undefined {\n  if (error === null || typeof error !== 'object') return undefined;\n  return (error as Record<symbol, unknown>)[catalogCodeKey] as\n    | string\n    | number\n    | undefined;\n}\n\n/** True when `error` was produced by any autotel error catalog. */\nexport function isCatalogError(error: unknown): error is StructuredError {\n  return readCatalogCode(error) !== undefined;\n}\n\n/** Returns the catalog code of `error`, or `undefined` if it has none. */\nexport function getCatalogCode(error: unknown): string | number | undefined {\n  return readCatalogCode(error);\n}\n\n/**\n * Define a typed error catalog. Returns an object whose keys are error\n * builders. Each builder produces a {@link StructuredError} carrying the\n * entry's message, status, code, why, fix, and link.\n */\nexport function defineErrorCatalog<\n  const T extends Record<string, ErrorCatalogEntry>,\n>(namespace: string, entries: T): ErrorCatalog<T> {\n  const catalog: Record<string, ErrorBuilder<ErrorCatalogEntry>> = {};\n\n  for (const [key, entry] of Object.entries(entries) as [\n    string,\n    ErrorCatalogEntry,\n  ][]) {\n    const code = entry.code ?? `${namespace}.${key}`;\n    const usesParams =\n      typeof entry.message === 'function' || typeof entry.why === 'function';\n\n    const builder = ((\n      paramsOrOptions?: unknown,\n      maybeOptions?: ErrorBuildOptions,\n    ): StructuredError => {\n      const params = usesParams ? paramsOrOptions : undefined;\n      const options = (usesParams ? maybeOptions : paramsOrOptions) as\n        | ErrorBuildOptions\n        | undefined;\n\n      const message =\n        typeof entry.message === 'function'\n          ? (entry.message as (p: unknown) => string)(params)\n          : entry.message;\n      const why =\n        typeof entry.why === 'function'\n          ? (entry.why as (p: unknown) => string)(params)\n          : entry.why;\n\n      const error = createStructuredError({\n        message,\n        name: entry.name ?? key,\n        code,\n        ...(entry.status === undefined ? {} : { status: entry.status }),\n        ...(why === undefined ? {} : { why }),\n        ...(entry.fix === undefined ? {} : { fix: entry.fix }),\n        ...(entry.link === undefined ? {} : { link: entry.link }),\n        ...(options?.cause === undefined ? {} : { cause: options.cause }),\n        ...(options?.details === undefined ? {} : { details: options.details }),\n        ...(options?.internal === undefined\n          ? {}\n          : { internal: options.internal }),\n      });\n\n      Object.defineProperty(error, catalogCodeKey, {\n        value: code,\n        enumerable: false,\n        writable: false,\n        configurable: true,\n      });\n\n      return error;\n    }) as ErrorBuilder<ErrorCatalogEntry>;\n\n    Object.defineProperty(builder, 'code', {\n      value: code,\n      enumerable: true,\n    });\n    Object.defineProperty(builder, 'match', {\n      value: (error: unknown): boolean => readCatalogCode(error) === code,\n      enumerable: false,\n    });\n\n    catalog[key] = builder;\n  }\n\n  return Object.freeze(catalog) as ErrorCatalog<T>;\n}\n\n/** Severity of an audit action. */\nexport type AuditSeverity = 'info' | 'warn' | 'critical';\n\n/** Definition of a single action in an audit catalog. */\nexport interface AuditCatalogEntry {\n  /** Human-readable description. Use a function for typed params. */\n  message?: string | ((params: never) => string);\n  /** Stable action name. Defaults to `${namespace}.${KEY}`. */\n  action?: string;\n  /** Severity of the action. Defaults to `'info'`. */\n  severity?: AuditSeverity;\n}\n\n/** A resolved audit action descriptor produced by an audit catalog. */\nexport interface AuditAction {\n  readonly action: string;\n  readonly severity: AuditSeverity;\n  readonly message?: string;\n}\n\ntype AuditDescriptorArgs<E extends AuditCatalogEntry> =\n  ParamsOf<E> extends void ? [] : [params: ParamsOf<E>];\n\n/** A callable audit-action descriptor produced by {@link defineAuditCatalog}. */\nexport interface AuditDescriptor<E extends AuditCatalogEntry> {\n  (...args: AuditDescriptorArgs<E>): AuditAction;\n  readonly action: string;\n  readonly severity: AuditSeverity;\n}\n\nexport type AuditCatalog<T extends Record<string, AuditCatalogEntry>> = {\n  readonly [K in keyof T]: AuditDescriptor<T[K]>;\n};\n\n/**\n * Define a typed audit catalog. Returns typed action descriptors you can pass\n * to `track()` or audit helpers without scattering magic strings.\n */\nexport function defineAuditCatalog<\n  const T extends Record<string, AuditCatalogEntry>,\n>(namespace: string, entries: T): AuditCatalog<T> {\n  const catalog: Record<string, AuditDescriptor<AuditCatalogEntry>> = {};\n\n  for (const [key, entry] of Object.entries(entries) as [\n    string,\n    AuditCatalogEntry,\n  ][]) {\n    const action = entry.action ?? `${namespace}.${key}`;\n    const severity: AuditSeverity = entry.severity ?? 'info';\n\n    const descriptor = ((params?: unknown): AuditAction => {\n      const message =\n        typeof entry.message === 'function'\n          ? (entry.message as (p: unknown) => string)(params)\n          : entry.message;\n      return Object.freeze({\n        action,\n        severity,\n        ...(message === undefined ? {} : { message }),\n      });\n    }) as AuditDescriptor<AuditCatalogEntry>;\n\n    Object.defineProperty(descriptor, 'action', {\n      value: action,\n      enumerable: true,\n    });\n    Object.defineProperty(descriptor, 'severity', {\n      value: severity,\n      enumerable: true,\n    });\n\n    catalog[key] = descriptor;\n  }\n\n  return Object.freeze(catalog) as AuditCatalog<T>;\n}\n","export interface DrainOptions<TContext, TConfig, TPayload = TContext> {\n  /** Stable identifier used in error logs. */\n  name: string;\n  /** Return null to skip draining (e.g. missing API key in dev). */\n  resolve: () => TConfig | null | Promise<TConfig | null>;\n  /** Transform contexts into payloads. Defaults to identity. */\n  transform?: (contexts: TContext[]) => TPayload[];\n  /** Transport implementation. */\n  send: (payloads: TPayload[], config: TConfig) => Promise<void>;\n}\n\nexport interface HttpDrainRequest {\n  url: string;\n  headers: Record<string, string>;\n  body: string;\n}\n\nexport interface HttpDrainOptions<\n  TContext,\n  TConfig,\n  TPayload = TContext,\n> extends Omit<DrainOptions<TContext, TConfig, TPayload>, 'send'> {\n  encode: (payloads: TPayload[], config: TConfig) => HttpDrainRequest | null;\n  timeoutMs?: number;\n  retries?: number;\n  resolveTimeoutMs?: (config: TConfig) => number | undefined;\n  resolveRetries?: (config: TConfig) => number | undefined;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_RETRIES = 2;\n\nfunction delay(ms: number): Promise<void> {\n  return new Promise((resolve) => {\n    const t = setTimeout(resolve, ms);\n    t.unref?.();\n  });\n}\n\nasync function postWithRetry(options: {\n  name: string;\n  request: HttpDrainRequest;\n  timeoutMs: number;\n  retries: number;\n}): Promise<void> {\n  const { name, request, timeoutMs, retries } = options;\n  const attempts = Math.max(1, retries);\n  let lastError: unknown;\n\n  for (let attempt = 1; attempt <= attempts; attempt++) {\n    const controller = new AbortController();\n    const timeout = setTimeout(() => controller.abort(), timeoutMs);\n    timeout.unref?.();\n    try {\n      const response = await fetch(request.url, {\n        method: 'POST',\n        headers: request.headers,\n        body: request.body,\n        signal: controller.signal,\n      });\n      if (!response.ok) {\n        throw new Error(\n          `[autotel/${name}] HTTP ${response.status} draining ${request.url}`,\n        );\n      }\n      return;\n    } catch (error) {\n      lastError = error;\n      if (attempt < attempts) {\n        await delay(100 * attempt);\n      }\n    } finally {\n      clearTimeout(timeout);\n    }\n  }\n\n  throw lastError;\n}\n\nexport function defineDrain<TContext, TConfig, TPayload = TContext>(\n  options: DrainOptions<TContext, TConfig, TPayload>,\n): (ctx: TContext | TContext[]) => Promise<void> {\n  return async (ctx: TContext | TContext[]) => {\n    const contexts = Array.isArray(ctx) ? ctx : [ctx];\n    if (contexts.length === 0) return;\n\n    const config = await options.resolve();\n    if (!config) return;\n\n    const payloads = options.transform\n      ? options.transform(contexts)\n      : (contexts as unknown as TPayload[]);\n\n    if (payloads.length === 0) return;\n\n    try {\n      await options.send(payloads, config);\n    } catch (error) {\n      console.error(`[autotel/${options.name}] drain failed:`, error);\n    }\n  };\n}\n\nexport function defineHttpDrain<TContext, TConfig, TPayload = TContext>(\n  options: HttpDrainOptions<TContext, TConfig, TPayload>,\n): (ctx: TContext | TContext[]) => Promise<void> {\n  return defineDrain<TContext, TConfig, TPayload>({\n    name: options.name,\n    resolve: options.resolve,\n    transform: options.transform,\n    send: async (payloads, config) => {\n      const request = options.encode(payloads, config);\n      if (!request) return;\n      const timeoutMs =\n        options.resolveTimeoutMs?.(config) ??\n        options.timeoutMs ??\n        DEFAULT_TIMEOUT_MS;\n      const retries =\n        options.resolveRetries?.(config) ?? options.retries ?? DEFAULT_RETRIES;\n\n      await postWithRetry({\n        name: options.name,\n        request,\n        timeoutMs,\n        retries,\n      });\n    },\n  });\n}\n","export interface EnrichContext<TEvent extends Record<string, unknown>> {\n  event: TEvent;\n  request?: {\n    method?: string;\n    path?: string;\n    requestId?: string;\n  };\n  response?: {\n    status?: number;\n  };\n  headers?: Record<string, string>;\n}\n\nexport interface EnricherDefinition<\n  TEvent extends Record<string, unknown>,\n  TValue extends object,\n> {\n  /** Stable identifier used in error logs. */\n  name: string;\n  /** Top-level field to merge computed values into. */\n  field: keyof TEvent & string;\n  /** Return undefined to skip enrichment. */\n  compute: (ctx: EnrichContext<TEvent>) => TValue | undefined;\n}\n\nexport interface EnricherOptions {\n  /** Replace existing field value instead of merge. Default false. */\n  overwrite?: boolean;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction mergeInto(\n  target: Record<string, unknown>,\n  source: Record<string, unknown>,\n): void {\n  for (const key in source) {\n    const sourceVal = source[key];\n    if (sourceVal === undefined) continue;\n    const targetVal = target[key];\n    if (isPlainObject(sourceVal) && isPlainObject(targetVal)) {\n      mergeInto(targetVal, sourceVal);\n    } else {\n      target[key] = sourceVal;\n    }\n  }\n}\n\nexport function defineEnricher<\n  TEvent extends Record<string, unknown>,\n  TValue extends object,\n>(\n  def: EnricherDefinition<TEvent, TValue>,\n  options: EnricherOptions = {},\n): (ctx: EnrichContext<TEvent>) => void {\n  return (ctx: EnrichContext<TEvent>) => {\n    let computed: TValue | undefined;\n    try {\n      computed = def.compute(ctx);\n    } catch (error) {\n      console.error(`[autotel/${def.name}] enrich failed:`, error);\n      return;\n    }\n\n    if (!computed) return;\n\n    if (options.overwrite || !isPlainObject(ctx.event[def.field])) {\n      (ctx.event as Record<string, unknown>)[def.field] = computed;\n      return;\n    }\n\n    mergeInto(\n      ctx.event[def.field] as unknown as Record<string, unknown>,\n      computed as unknown as Record<string, unknown>,\n    );\n  };\n}\n"],"mappings":"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"}