export type PortableJsonSchema = { type?: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null'; properties?: Record; required?: string[]; items?: PortableJsonSchema; enum?: unknown[]; additionalProperties?: boolean | PortableJsonSchema; minLength?: number; maxLength?: number; minimum?: number; maximum?: number; }; export interface IPortableFunctionContext { product: string; env: string; workspace_id?: string; feature_id: string; feature_tag: string; feature_run_id?: string; step_tag: string; step_run_id?: string; invocation_id: string; trace_id?: string; parent_span_id?: string; /** Inherited feature session. Kept outside business input. */ session?: string; session_id?: string; session_tag?: string; session_user_id?: string; deadline_at?: number; idempotency_key?: string; } export interface IPortableFunctionHttpTransport { type: 'http'; url: string; timeout_ms?: number; /** HMAC-SHA256 using the SDK access key. Unsigned HTTP invocation is intentionally unsupported. */ authentication: 'ductape_hmac_sha256'; } export interface IPortableFunctionLocalTransport { type: 'local'; } export interface IPortableFunctionGrpcTransport { type: 'grpc'; /** Host and port only; grpc:// URLs are deliberately rejected. */ endpoint: string; /** Defaults to ductape.functions.v1.PortableFunctions. */ service?: string; /** Defaults to Invoke. */ method?: string; timeout_ms?: number; /** Production gRPC requires mutually authenticated TLS. */ authentication: 'mtls'; /** Optional TLS server name override used for certificate verification. */ server_name?: string; /** Environment-variable names containing PEM material; never put PEM/secrets in a contract. */ tls?: { ca_env?: string; cert_env?: string; key_env?: string; }; /** Permit fallback after UNAVAILABLE/deadline failures. Defaults to true. Auth/schema errors never fall back. */ allow_fallback?: boolean; } export interface IPortableFunctionEventsTransport { type: 'events'; /** Full broker/topic event names. */ request_event: string; response_event: string; timeout_ms?: number; } export type PortableFunctionTransport = IPortableFunctionLocalTransport | IPortableFunctionGrpcTransport | IPortableFunctionHttpTransport | IPortableFunctionEventsTransport; export type PortableFunctionGrpcInvoker = (transport: IPortableFunctionGrpcTransport, invocation: IPortableFunctionInvocation) => Promise; export type PortableFunctionEventsInvoker = (transport: IPortableFunctionEventsTransport, invocation: IPortableFunctionInvocation) => Promise; export interface IPortableFunctionOperationContract, TOutput = unknown> { input: PortableJsonSchema; output: PortableJsonSchema; description?: string; timeout_ms?: number; idempotent?: boolean; transports?: PortableFunctionTransport[]; handler?: (input: TInput, context: IPortableFunctionContext) => Promise | TOutput; } export interface IPortableFunctionContract> = Record>> { namespace: string; version: string; description?: string; operations: TOperations; } export interface IPortableFunctionReference { namespace: string; operation: string; version: string; input_schema: PortableJsonSchema; output_schema: PortableJsonSchema; transports: PortableFunctionTransport[]; timeout_ms?: number; idempotent?: boolean; } export interface IPortableFunctionInvocation> { function: Pick; input: TInput; context: IPortableFunctionContext; } export interface IPortableFunctionInvocationResponse { invocation_id: string; output?: TOutput; error?: { code: string; message: string; retryable?: boolean; details?: unknown; }; } export type PortableFunctionClient = { [K in keyof TContract['operations']]: TContract['operations'][K] extends IPortableFunctionOperationContract ? (input: TInput) => Promise : never; }; export declare function defineFunctions(contract: T): T; /** * Preserves an operation's application input/output types even when the portable * contract intentionally contains no local handler. */ export declare function defineFunction(operation: IPortableFunctionOperationContract): IPortableFunctionOperationContract;