{"version":3,"file":"interceptors.mjs","names":[],"sources":["../../src/core/interceptors.ts"],"sourcesContent":["import type {\n  AnyPadroneCommand,\n  AnyPadroneProgram,\n  InterceptorDefBuilder,\n  InterceptorErrorContext,\n  InterceptorErrorResult,\n  InterceptorFactory,\n  InterceptorMeta,\n  InterceptorPipelinePhase,\n  InterceptorShutdownContext,\n  InterceptorStartContext,\n  PadroneInterceptorFn,\n  RegisteredInterceptor,\n  ResolvedInterceptor,\n} from '../types/index.ts';\nimport { thenMaybe } from './results.ts';\nimport type { ResolvedPadroneRuntime } from './runtime.ts';\n\n// ---------------------------------------------------------------------------\n// defineInterceptor — creates a single-value distributable interceptor\n// ---------------------------------------------------------------------------\n\nfunction buildInterceptorFn(meta: InterceptorMeta, factory: InterceptorFactory<any, any, any>): PadroneInterceptorFn<any, any, any> {\n  Object.defineProperty(factory, 'name', { value: meta.name, configurable: true });\n  if (meta.id !== undefined) (factory as any).id = meta.id;\n  if (meta.order !== undefined) (factory as any).order = meta.order;\n  if (meta.disabled !== undefined) (factory as any).disabled = meta.disabled;\n  if (meta.inherit !== undefined) (factory as any).inherit = meta.inherit;\n  (factory as any).provides = () => factory;\n  (factory as any).requires = () => factory;\n  return factory as PadroneInterceptorFn<any, any, any>;\n}\n\n/**\n * Creates a self-contained interceptor value by attaching static metadata to the factory function.\n * The returned value can be passed directly to `.intercept()` or exported from a package.\n *\n * Two-arg form — define metadata and factory in one call:\n * ```ts\n * export const myInterceptor = defineInterceptor(\n *   { name: 'my-interceptor', order: 10 },\n *   () => ({\n *     execute(ctx, next) { return next(); },\n *   }),\n * );\n * ```\n *\n * Single-arg form — chain `.requires<T>()` for typed context, then `.factory()`:\n * ```ts\n * export const myInterceptor = defineInterceptor({ name: 'with-db' })\n *   .requires<{ db: DB }>()\n *   .factory(() => ({\n *     execute(ctx, next) {\n *       ctx.context.db; // typed!\n *       return next();\n *     },\n *   }));\n * ```\n */\nexport function defineInterceptor<TArgs = unknown, TResult = unknown>(\n  meta: InterceptorMeta,\n  factory: InterceptorFactory<TArgs, TResult>,\n): PadroneInterceptorFn<TArgs, TResult>;\nexport function defineInterceptor(meta: InterceptorMeta): InterceptorDefBuilder;\nexport function defineInterceptor(\n  meta: InterceptorMeta,\n  factory?: InterceptorFactory<any, any, any>,\n): PadroneInterceptorFn<any, any, any> | InterceptorDefBuilder {\n  if (factory) return buildInterceptorFn(meta, factory);\n  const builder: InterceptorDefBuilder = {\n    requires: () => builder as any,\n    factory: (f) => buildInterceptorFn(meta, f) as any,\n  };\n  return builder;\n}\n\n// ---------------------------------------------------------------------------\n// Registration normalization\n// ---------------------------------------------------------------------------\n\n/**\n * Normalizes an interceptor input (single-value form or two-arg form) into the internal\n * `RegisteredInterceptor` storage format.\n */\nexport function toRegisteredInterceptor(\n  metaOrFn: InterceptorMeta | PadroneInterceptorFn<any, any, any>,\n  factory?: InterceptorFactory<any, any, any>,\n): RegisteredInterceptor {\n  if (typeof metaOrFn === 'function') {\n    // Single-value form: PadroneInterceptorFn (factory with meta as own properties)\n    return {\n      meta: { name: metaOrFn.name, id: metaOrFn.id, order: metaOrFn.order, disabled: metaOrFn.disabled, inherit: metaOrFn.inherit },\n      factory: metaOrFn,\n    };\n  }\n  // Two-arg form: (meta, factory)\n  return { meta: metaOrFn, factory: factory! };\n}\n\n// ---------------------------------------------------------------------------\n// Factory resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves registered interceptors by calling their factories and merging the resulting\n * phase handlers with the static metadata. Uses a cache to ensure each factory is called\n * at most once per execution (so root interceptor closures are shared across all phases).\n */\nexport function resolveRegisteredInterceptors(\n  registered: RegisteredInterceptor[],\n  cache: Map<RegisteredInterceptor, ResolvedInterceptor>,\n): ResolvedInterceptor[] {\n  return registered.map((reg) => {\n    let resolved = cache.get(reg);\n    if (!resolved) {\n      resolved = { ...reg.meta, ...reg.factory() };\n      cache.set(reg, resolved);\n    }\n    return resolved;\n  });\n}\n\n// ---------------------------------------------------------------------------\n// Interceptor chain runner\n// ---------------------------------------------------------------------------\n\n/**\n * Deduplicates interceptors by `id`. When multiple interceptors share the same `id`,\n * only the last one in the array is kept. Interceptors without an `id` are always kept.\n */\nfunction deduplicateInterceptors(interceptors: ResolvedInterceptor[]): ResolvedInterceptor[] {\n  // Fast path: no ids at all\n  if (!interceptors.some((p) => p.id)) return interceptors;\n\n  // Find the last index for each id\n  const lastIndex = new Map<string, number>();\n  for (let i = 0; i < interceptors.length; i++) {\n    const id = interceptors[i]!.id;\n    if (id) lastIndex.set(id, i);\n  }\n\n  return interceptors.filter((p, i) => !p.id || lastIndex.get(p.id) === i);\n}\n\n/**\n * Runs an interceptor chain for a given phase using the onion/middleware pattern.\n * Interceptors are sorted by `order` (ascending, stable), then composed so that\n * the first interceptor in sorted order is the outermost wrapper.\n * If no interceptors handle this phase, `core` is called directly.\n *\n * Each interceptor's `next()` accepts optional partial overrides that are merged\n * into the context before passing to the next interceptor or core function.\n */\nexport function runInterceptorChain<TCtx extends object, TResult>(\n  phase: 'start' | 'parse' | 'route' | 'validate' | 'execute' | 'error' | 'shutdown',\n  interceptors: ResolvedInterceptor[],\n  ctx: TCtx,\n  core: (ctx: TCtx) => TResult | Promise<TResult>,\n): TResult | Promise<TResult> {\n  // Deduplicate by id (last wins), then filter to enabled interceptors that have a handler for this phase\n  const deduped = deduplicateInterceptors(interceptors);\n  const phaseInterceptors = deduped.filter((p) => p[phase] && !p.disabled);\n  if (phaseInterceptors.length === 0) return core(ctx);\n\n  // Stable sort by order (lower = outermost). Equal order preserves registration order.\n  phaseInterceptors.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n\n  // Build chain from inside out: last interceptor wraps core, first interceptor is outermost\n  let next: (currentCtx: TCtx) => TResult | Promise<TResult> = core;\n  for (let i = phaseInterceptors.length - 1; i >= 0; i--) {\n    const handler = phaseInterceptors[i]![phase]! as unknown as (\n      ctx: TCtx,\n      next: (overrides?: Record<string, unknown>) => TResult | Promise<TResult>,\n    ) => TResult | Promise<TResult>;\n    const prevNext = next;\n    next = (currentCtx: TCtx) =>\n      handler(currentCtx, (overrides?: Record<string, unknown>) => {\n        if (!overrides) return prevNext(currentCtx);\n        // Auto-merge context: `next({ context: { user } })` merges into existing context\n        // instead of replacing it, so interceptors can't accidentally drop context.\n        if (overrides.context != null && typeof overrides.context === 'object') {\n          overrides = { ...overrides, context: Object.assign({}, (currentCtx as Record<string, unknown>).context, overrides.context) };\n        }\n        return prevNext(Object.assign({}, currentCtx, overrides) as TCtx);\n      });\n  }\n\n  return next(ctx);\n}\n\n/**\n * Wraps a pipeline with start → error → shutdown lifecycle hooks.\n * - `start` interceptors wrap the pipeline (onion pattern, root interceptors only).\n * - On error: `error` interceptors run (can transform/suppress the error).\n * - Always: `shutdown` interceptors run (success or failure).\n */\nexport function wrapWithLifecycle<T>(\n  interceptors: ResolvedInterceptor[],\n  command: AnyPadroneCommand,\n  input: string | undefined,\n  pipeline: (signal: AbortSignal, context: unknown) => T | Promise<T>,\n  wrapErrorResult?: (result: unknown) => T,\n  signal?: AbortSignal,\n  context?: unknown,\n  runtime?: ResolvedPadroneRuntime,\n  program?: AnyPadroneProgram,\n  caller: 'cli' | 'eval' | 'run' | 'repl' | 'serve' | 'mcp' | 'tool' = 'eval',\n  pipelineState?: { phase: InterceptorPipelinePhase; rawArgs?: Record<string, unknown>; positionalArgs?: string[]; args?: unknown },\n): T | Promise<T> {\n  const defaultSignal = typeof AbortSignal !== 'undefined' ? AbortSignal.abort() : (undefined as unknown as AbortSignal);\n  const hasStart = interceptors.some((p) => p.start);\n  const hasError = interceptors.some((p) => p.error);\n  const hasShutdown = interceptors.some((p) => p.shutdown);\n\n  const effectivePipelineState = pipelineState ?? { phase: 'start' as const };\n\n  // Fast path: no lifecycle interceptors\n  if (!hasStart && !hasError && !hasShutdown) return pipeline(signal ?? defaultSignal, context);\n  // Mutable refs: start-phase interceptors can override signal and context (e.g., signal extension, auth),\n  // and the overrides propagate to error/shutdown contexts.\n  let effectiveSignal = signal ?? defaultSignal;\n  let effectiveContext = context;\n\n  const runShutdown = (error?: unknown, result?: unknown) => {\n    if (!hasShutdown) return;\n    const ctx: InterceptorShutdownContext = {\n      command,\n      input,\n      error,\n      result,\n      signal: effectiveSignal,\n      context: effectiveContext as object,\n      runtime: runtime!,\n      program: program!,\n      caller,\n      ...effectivePipelineState,\n    };\n    return runInterceptorChain('shutdown', interceptors, ctx, () => {});\n  };\n\n  const runError = (error: unknown): T | Promise<T> => {\n    if (!hasError) {\n      const s = runShutdown(error);\n      if (s instanceof Promise)\n        return s.then(() => {\n          throw error;\n        });\n      throw error;\n    }\n    const ctx: InterceptorErrorContext = {\n      command,\n      input,\n      error,\n      signal: effectiveSignal,\n      context: effectiveContext as object,\n      runtime: runtime!,\n      program: program!,\n      caller,\n      ...effectivePipelineState,\n    };\n    const errorResult = runInterceptorChain('error', interceptors, ctx, (): InterceptorErrorResult => ({ error }));\n    return thenMaybe(errorResult, (er) => {\n      if (er.error !== undefined) {\n        const s = runShutdown(er.error);\n        return thenMaybe(s as void | Promise<void>, () => {\n          throw er.error;\n        });\n      }\n      const wrapped = wrapErrorResult ? wrapErrorResult(er.result) : (er.result as T);\n      const s = runShutdown(undefined, wrapped);\n      return thenMaybe(s as void | Promise<void>, () => wrapped);\n    });\n  };\n\n  const handleSuccess = (result: T): T | Promise<T> => {\n    const s = runShutdown(undefined, result);\n    if (s instanceof Promise) return s.then(() => result);\n    return result;\n  };\n\n  const startCtx: InterceptorStartContext = {\n    command,\n    signal: effectiveSignal,\n    context: effectiveContext as object,\n    runtime: runtime!,\n    program: program!,\n    input,\n    caller,\n  };\n  let result: T | Promise<T>;\n  try {\n    result = (\n      hasStart\n        ? runInterceptorChain('start', interceptors, startCtx, (ctx) => {\n            // Capture overrides from start-phase interceptors so downstream phases see them.\n            effectiveSignal = ctx.signal;\n            effectiveContext = ctx.context;\n            return pipeline(ctx.signal, ctx.context);\n          })\n        : pipeline(effectiveSignal, effectiveContext)\n    ) as T | Promise<T>;\n  } catch (e) {\n    return runError(e);\n  }\n\n  if (result instanceof Promise) {\n    return result.then(handleSuccess, runError);\n  }\n\n  return handleSuccess(result);\n}\n\n/**\n * Wraps a command-level pipeline (validate + execute) with error → shutdown lifecycle hooks.\n * Unlike `wrapWithLifecycle`, this has no `start` phase and uses the resolved command context.\n * Only interceptors exclusive to the command chain (not in root) should be passed here.\n */\nexport function wrapWithCommandLifecycle<T>(\n  interceptors: ResolvedInterceptor[],\n  command: AnyPadroneCommand,\n  input: string | undefined,\n  pipeline: () => T | Promise<T>,\n  wrapErrorResult: ((result: unknown) => T) | undefined,\n  signal: AbortSignal,\n  context: unknown,\n  runtime: ResolvedPadroneRuntime,\n  program: AnyPadroneProgram,\n  caller: 'cli' | 'eval' | 'run' | 'repl' | 'serve' | 'mcp' | 'tool',\n  pipelineState: { phase: InterceptorPipelinePhase; rawArgs?: Record<string, unknown>; positionalArgs?: string[]; args?: unknown },\n): T | Promise<T> {\n  const hasError = interceptors.some((p) => p.error);\n  const hasShutdown = interceptors.some((p) => p.shutdown);\n\n  if (!hasError && !hasShutdown) return pipeline();\n\n  const runShutdown = (error?: unknown, result?: unknown) => {\n    if (!hasShutdown) return;\n    const ctx: InterceptorShutdownContext = {\n      command,\n      input,\n      error,\n      result,\n      signal,\n      context: context as object,\n      runtime,\n      program,\n      caller,\n      ...pipelineState,\n    };\n    return runInterceptorChain('shutdown', interceptors, ctx, () => {});\n  };\n\n  const runError = (error: unknown): T | Promise<T> => {\n    if (!hasError) {\n      const s = runShutdown(error);\n      if (s instanceof Promise)\n        return s.then(() => {\n          throw error;\n        });\n      throw error;\n    }\n    const ctx: InterceptorErrorContext = {\n      command,\n      input,\n      error,\n      signal,\n      context: context as object,\n      runtime,\n      program,\n      caller,\n      ...pipelineState,\n    };\n    const errorResult = runInterceptorChain('error', interceptors, ctx, (): InterceptorErrorResult => ({ error }));\n    return thenMaybe(errorResult, (er) => {\n      if (er.error !== undefined) {\n        const s = runShutdown(er.error);\n        return thenMaybe(s as void | Promise<void>, () => {\n          throw er.error;\n        });\n      }\n      const wrapped = wrapErrorResult ? wrapErrorResult(er.result) : (er.result as T);\n      const s = runShutdown(undefined, wrapped);\n      return thenMaybe(s as void | Promise<void>, () => wrapped);\n    });\n  };\n\n  const handleSuccess = (result: T): T | Promise<T> => {\n    const s = runShutdown(undefined, result);\n    if (s instanceof Promise) return s.then(() => result);\n    return result;\n  };\n\n  let result: T | Promise<T>;\n  try {\n    result = pipeline();\n  } catch (e) {\n    return runError(e);\n  }\n\n  if (result instanceof Promise) {\n    return result.then(handleSuccess, runError);\n  }\n\n  return handleSuccess(result);\n}\n"],"mappings":"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"}