/** * InputResolver - Resolves flat input to structured IActionRequest format * * This utility enables developers to provide flat key-value inputs that get * automatically resolved to the correct location (body, params, query, headers) * based on the action's schema definition. * * Features: * - Auto-resolution: Keys are automatically placed based on action schema * - Conflict handling: Use prefix syntax (e.g., 'body:id', 'params:id') for conflicts * - Strict mode: Throws errors for unknown keys or conflicts without prefixes * - Nested object support: Objects are placed naturally without deep prefixes * * @example * ```ts * // Flat input * const input = { amount: 1000, currency: 'usd', 'params:id': 'user_123' }; * * // Resolved to structured format * const resolved = resolver.resolve(input, action); * // { body: { amount: 1000, currency: 'usd' }, params: { id: 'user_123' } } * ``` */ import { IAppAction } from '../../types'; /** * Input location types that map to IActionRequest fields */ export type InputLocation = 'body' | 'params' | 'query' | 'headers'; /** * Prefix patterns for explicit location specification */ export declare const LOCATION_PREFIXES: readonly InputLocation[]; /** * Headers that should NEVER be auto-populated (authorization-related) * Users must explicitly provide these for security reasons * * All other headers from the action schema will be auto-populated * from their sample values if not provided in the input. */ export declare const AUTH_RELATED_HEADERS: readonly string[]; /** * Check if a header key is authorization-related (case-insensitive) * Uses both exact match and pattern-based detection */ export declare function isAuthRelatedHeader(key: string): boolean; /** * Error thrown when input resolution fails */ export declare class InputResolutionError extends Error { readonly key: string; readonly errorType: 'unknown_key' | 'conflict' | 'missing_prefix' | 'invalid_value' | 'validation_error'; constructor(message: string, key: string, errorType: 'unknown_key' | 'conflict' | 'missing_prefix' | 'invalid_value' | 'validation_error'); } /** * Maps keys to their location in the action schema */ export interface ILocationMap { /** Key -> locations where this key exists */ keyToLocations: Map; /** Keys that exist in multiple locations (conflicts) */ conflictingKeys: Set; /** All valid keys across all locations */ allValidKeys: Set; } /** * Resolved structured input ready for action execution */ export interface IResolvedInput { body?: Record; params?: Record; query?: Record; headers?: Record; } /** * Options for input resolution */ export interface IResolveOptions { /** * Strict mode (default: true) * - true: Throws error for unknown keys or conflicts without prefix * - false: Unknown keys go to body by default (not recommended) */ strict?: boolean; /** * Auth context to merge into the input (from ductape.action.auth()) */ authContext?: IResolvedInput; /** * Default location for unknown keys when strict mode is off */ defaultLocation?: InputLocation; /** * Auto-populate non-auth headers from schema sample values (default: true) * When enabled, headers like Content-Type, Accept, etc. will be * automatically populated from the action schema if not provided in input. */ autoPopulateHeaders?: boolean; } /** * InputResolver resolves flat input objects to structured IActionRequest format * based on the action's schema definition. */ export declare class InputResolver { /** * Build a location map from an action's schema * This maps each key to the location(s) where it's defined */ buildLocationMap(action: IAppAction): ILocationMap; /** * Extract keys from parsed sample data * Handles nested structures by tracking top-level keys only */ private extractKeysFromSample; /** * Extract auto-populatable headers from the action schema * Returns headers with their sample values that are NOT auth-related */ getAutoPopulatableHeaders(action: IAppAction): Record; /** * Parse a key to extract location prefix if present * @returns [location | null, actualKey] */ parseKey(key: string): [InputLocation | null, string]; /** * Resolve flat input to structured IActionRequest format * * @param flatInput - Flat key-value input from user * @param action - Action schema containing params, query, headers, body definitions * @param options - Resolution options * @returns Structured input ready for action execution * @throws InputResolutionError for invalid inputs in strict mode */ resolve(flatInput: Record, action: IAppAction, options?: IResolveOptions): IResolvedInput; /** * Validate that all required fields are present in the resolved input * * @param resolved - Resolved input * @param action - Action schema * @throws InputResolutionError if required fields are missing */ validateRequired(resolved: IResolvedInput, action: IAppAction): void; /** * Get a list of all valid keys for an action with their locations * Useful for providing helpful error messages */ getValidKeys(action: IAppAction): Array<{ key: string; locations: InputLocation[]; }>; /** * Get conflicting keys that require explicit prefixes */ getConflictingKeys(action: IAppAction): Array<{ key: string; locations: InputLocation[]; }>; } /** * Singleton instance for convenience */ export declare const inputResolver: InputResolver; /** * Convenience function to resolve flat input */ export declare function resolveInput(flatInput: Record, action: IAppAction, options?: IResolveOptions): IResolvedInput;