import { ResolvedPadroneRuntime } from "../core/runtime.mjs"; import { AnyPadroneCommand, PadroneActionContext } from "./command.mjs"; import { AnyPadroneProgram } from "./builder.mjs"; import { StandardSchemaV1 } from "@standard-schema/spec"; //#region src/types/interceptor.d.ts /** Base context shared across all interceptor phases within a single execution. */ type InterceptorBaseContext = { /** The resolved command for this execution. In the parse phase, this is the root program. */command: AnyPadroneCommand; /** The raw CLI input string (undefined when invoked without input). */ input: string | undefined; /** Cancellation signal that fires when the process receives a termination signal. */ signal: AbortSignal; /** User-defined context object, resolved through the command's parent chain. */ context: TContext; /** The resolved runtime for this execution. Interceptors can override this before calling `next()`. */ runtime: ResolvedPadroneRuntime; /** The program instance. Available for extensions that need program-level methods. */ program: AnyPadroneProgram; /** The invocation method that triggered this execution (e.g. 'cli', 'eval', 'run'). */ caller: PadroneActionContext['caller']; }; /** Context for the parse phase. */ type InterceptorParseContext = InterceptorBaseContext; /** Result returned by the parse phase's `next()`. */ type InterceptorParseResult = { command: AnyPadroneCommand; rawArgs: Record; positionalArgs: string[]; }; /** Context for the route phase. Runs after the target command is resolved, before validation. */ type InterceptorRouteContext = InterceptorBaseContext & { /** Raw named arguments extracted by the parser. */rawArgs: Record; /** Positional argument strings extracted by the parser. */ positionalArgs: string[]; }; /** Context for the validate phase. */ type InterceptorValidateContext = InterceptorBaseContext & { /** Raw named arguments extracted by the parser. Mutable — modify before `next()` to inject/override values. */rawArgs: Record; /** Positional argument strings extracted by the parser. */ positionalArgs: string[]; /** Interactive mode override (set by the interactive extension when `--interactive` / `-i` flag is used). */ interactive?: boolean; /** Interactive mode preference from eval/cli options. Available for the interactive extension. */ evalInteractive?: boolean; }; /** Result returned by the validate phase's `next()`. */ type InterceptorValidateResult = { args: TArgs; argsResult: StandardSchemaV1.Result; }; /** Context for the execute phase. Includes validate context fields (rawArgs, positionalArgs). */ type InterceptorExecuteContext = InterceptorValidateContext & { /** Validated arguments that will be passed to the action. Mutable — modify before `next()` to override. */args: TArgs; }; /** Result returned by the execute phase's `next()`. */ type InterceptorExecuteResult = { result: TResult; }; /** Context for the start phase. Runs before parsing, wraps the entire pipeline. */ type InterceptorStartContext = InterceptorBaseContext; /** The pipeline phase that was executing when an error was thrown or the pipeline completed. */ type InterceptorPipelinePhase = 'start' | 'parse' | 'route' | 'validate' | 'execute'; /** Context for the error phase. Called when the pipeline throws. Includes pipeline state accumulated before the error. */ type InterceptorErrorContext = InterceptorBaseContext & { /** The error that was thrown. */error: unknown; /** The pipeline phase that was executing when the error was thrown. */ phase: InterceptorPipelinePhase; /** Raw named arguments (available if parse completed). */ rawArgs?: Record; /** Positional argument strings (available if parse completed). */ positionalArgs?: string[]; /** Validated arguments (available if validate completed). */ args?: unknown; }; /** Result returned by the error phase's `next()`. */ type InterceptorErrorResult = { /** The error (possibly transformed). Set to `undefined` to suppress the error. */error?: unknown; /** A replacement result when suppressing the error. */ result?: TResult; }; /** Context for the shutdown phase. Always runs after the pipeline (success or failure). Includes pipeline state accumulated before completion. */ type InterceptorShutdownContext = InterceptorBaseContext & { /** The error, if the pipeline failed (after error phase processing). */error?: unknown; /** The pipeline result, if it succeeded. */ result?: TResult; /** The last pipeline phase that was reached before completion or failure. */ phase: InterceptorPipelinePhase; /** Raw named arguments (available if parse completed). */ rawArgs?: Record; /** Positional argument strings (available if parse completed). */ positionalArgs?: string[]; /** Validated arguments (available if validate completed). */ args?: unknown; }; /** Overrides passable to `next()`. Provides autocomplete for common fields; accepts any phase-specific fields. */ type InterceptorNextOverrides = Partial & Record; /** * A phase handler function for the interceptor middleware chain. * * - `TCtx` — the context object available to the handler. * - `TNextResult` — the typed result returned by `next()`, giving the handler type-safe access to downstream output. * - `TReturn` — the type the handler itself returns. Defaults to `TNextResult` but can be wider, * allowing interceptors to transform or replace the result (e.g., error-recovery interceptors returning a different type). */ type InterceptorPhaseHandler = (ctx: TCtx, next: (overrides?: InterceptorNextOverrides) => TNextResult | Promise) => TReturn | Promise; /** Static metadata for an interceptor. Always available at registration time without calling the factory. */ type InterceptorMeta = { /** Display name for this interceptor. Used for identification in logs and debugging. */name: string; /** * Optional unique identifier for deduplication. When multiple interceptors share the same `id`, * only the last one registered is kept. Useful for allowing downstream code to override * an interceptor without accumulating duplicates. */ id?: string; /** * Ordering hint. Lower values run as outer layers (earlier before `next()`, later after). * Interceptors with the same order preserve registration order. Defaults to `0`. */ order?: number; /** * When `true`, the interceptor is skipped during execution. Combined with `id`-based deduplication, * this lets downstream code disable an interceptor by re-registering it with `disabled: true`. */ disabled?: boolean; /** * When `false`, the interceptor applies only to the command it was registered on * and is not inherited by subcommands. Defaults to `true`. */ inherit?: boolean; }; /** * Phase handler definitions returned by an interceptor factory. * The factory's closure provides typed, scoped cross-phase state. * * Type parameters: * - `TArgs` — the validated arguments type (output of the args schema). * - `TResult` — the command's return type. */ type InterceptorPhases = { /** * Runs before the pipeline (parse → validate → execute). `next()` proceeds to the pipeline. * Root interceptors only. Use for startup tasks like telemetry, update checks, or global config loading. */ start?: InterceptorPhaseHandler, unknown>; /** Intercepts command routing and raw argument extraction. */ parse?: InterceptorPhaseHandler, InterceptorParseResult>; /** * Runs after the target command is resolved (post-parse), before validation. * Use for per-command setup: authorization, resource loading, logging, etc. * Root and command-level interceptors both participate. */ route?: InterceptorPhaseHandler, void>; /** Intercepts argument preprocessing and schema validation. Interactive prompting is handled by the interactive extension. */ validate?: InterceptorPhaseHandler, InterceptorValidateResult, InterceptorValidateResult>; /** Intercepts handler execution. */ execute?: InterceptorPhaseHandler, InterceptorExecuteResult, InterceptorExecuteResult>; /** * Called when the pipeline throws an error. `next()` passes to the next error handler * (innermost returns `{ error }` unchanged). Return `{ result }` without `error` to suppress. */ error?: InterceptorPhaseHandler, InterceptorErrorResult, InterceptorErrorResult>; /** * Always runs after the pipeline completes (success or failure). `next()` calls the next shutdown handler. * Use for cleanup: closing connections, flushing logs, etc. */ shutdown?: InterceptorPhaseHandler, void>; }; /** * Factory function that creates phase handlers for an interceptor. * Called once per command execution — the closure provides typed, scoped cross-phase state across phases. */ type InterceptorFactory = () => InterceptorPhases; /** * A self-contained interceptor value: a factory function with static metadata as own properties. * Created via `defineInterceptor(meta, factory)`. This is the distributable form — a single * importable value that packages can export. * * Also accepted directly by `.intercept()` as the single-argument form. * Call `.provides()` to brand it as a context-providing interceptor. */ type PadroneInterceptorFn = InterceptorFactory & InterceptorMeta & { /** Brand this interceptor as providing additional context of type `TProvides`. No-op at runtime; purely a type-level cast. */provides: () => PadroneContextInterceptor; /** * Brand this interceptor as requiring context of type `TRequires` to be available. * `.intercept()` will produce a compile error if the required context is not satisfied. * Use optional properties for soft requirements: `.requires<{ db: DB; logger?: Logger }>()`. * No-op at runtime; purely a type-level cast. */ requires: () => PadroneInterceptorFn & InterceptorRequiresBrand; }; /** * A Padrone interceptor in its single-value distributable form. * Alias for `PadroneInterceptorFn` — this is the primary public type. * * Create with `defineInterceptor(meta, factory)` or pass `(meta, factory)` directly to `.intercept()`. */ type PadroneInterceptor = PadroneInterceptorFn; /** * A context-providing interceptor. Carries a phantom `'~context'` brand declaring what it adds * to the command context. When registered via `.intercept()`, the builder's context type is * intersected with `TProvides`. * * Created by calling `.provides()` on a `PadroneInterceptorFn`. * Chain `.requires()` to also declare context dependencies. */ type PadroneContextInterceptor = Omit, 'requires'> & InterceptorFactory & { /** Phantom brand — declares the context type this interceptor provides. */'~context': TProvides; /** Like `.requires()` on `PadroneInterceptorFn` but preserves the `'~context'` brand. */ requires: () => PadroneContextInterceptor & InterceptorRequiresBrand; }; /** * Phantom brand for context requirements. Uses a contravariant function type so that * `.intercept()` overloads can check `TAvailableContext extends TRequires` via assignability. */ type InterceptorRequiresBrand = { '~contextRequires': (ctx: TRequires) => void; }; /** Extracts the provided context type from a context-providing interceptor, or `unknown` if not branded. */ type ExtractInterceptorContext = T extends { '~context': infer C; } ? C : unknown; /** Extracts the required context type from an interceptor, or `unknown` if no requirements. */ type ExtractInterceptorRequires = T extends { '~contextRequires': (ctx: infer R) => void; } ? R : unknown; /** * Checks whether an interceptor's context requirements are satisfied by the available context. * Returns `true` if the interceptor has no requirements or if the available context extends the requirements. */ type InterceptorRequiresCheck = TInterceptor extends { '~contextRequires': (ctx: infer TReq) => void; } ? TAvailableContext extends TReq ? true : false : true; /** Error brand returned by `.intercept()` when the interceptor's required context is not satisfied. */ type InterceptorRequiresError = { readonly '~error': 'Required context not satisfied. Ensure required interceptors are registered before this one.'; }; /** * Builder returned by `defineInterceptor(meta)` (single-arg form). * Call `.requires()` to declare (and type) the context dependency, then `.factory()` to provide the phase handlers. */ type InterceptorDefBuilder = { /** Declare the context type this interceptor requires. Sets `TContext` for phase handler typing. */requires: () => InterceptorDefBuilder>; /** Provide the interceptor factory. Phase handlers receive the typed `TContext` from `.requires()`. */ factory: (factory: InterceptorFactory) => PadroneInterceptorFn & TBrand; }; /** * Internal stored form on command objects. Separates static metadata from the factory * so that deduplication and sorting can happen without calling the factory. */ type RegisteredInterceptor = { meta: InterceptorMeta; factory: InterceptorFactory; }; //#endregion export { ExtractInterceptorContext, ExtractInterceptorRequires, InterceptorBaseContext, InterceptorDefBuilder, InterceptorErrorContext, InterceptorErrorResult, InterceptorExecuteContext, InterceptorExecuteResult, InterceptorFactory, InterceptorMeta, InterceptorNextOverrides, InterceptorParseContext, InterceptorParseResult, InterceptorPhases, InterceptorPipelinePhase, InterceptorRequiresCheck, InterceptorRequiresError, InterceptorRouteContext, InterceptorShutdownContext, InterceptorStartContext, InterceptorValidateContext, InterceptorValidateResult, PadroneContextInterceptor, PadroneInterceptor, PadroneInterceptorFn, RegisteredInterceptor }; //# sourceMappingURL=interceptor.d.mts.map