import { z } from "zod"; import type { ZapierSdk } from "../sdk"; export interface FormattedItem { title: string; id?: string; key?: string; keys?: string[]; description?: string; data?: unknown; details: Array<{ label?: string; text: string; style: "normal" | "dim" | "accent" | "warning" | "success"; }>; } export interface FormatMetadata { format: (item: TItem) => FormattedItem; } export interface OutputFormatter, TContext = unknown> { fetch?: (sdk: ZapierSdk, params: TParams, item: TItem, context: TContext | undefined) => Promise; format: (item: TItem, context?: TContext) => FormattedItem; } export declare function withFormatter(schema: T, formatMeta: FormatMetadata>): T; export declare function getOutputSchema(inputSchema: z.ZodType): z.ZodType | undefined; export declare function withOutputSchema(inputSchema: T, outputSchema: z.ZodType): T & { _def: T["_def"] & { outputSchema: z.ZodType; }; }; export interface PromptConfig { type: "list" | "checkbox" | "confirm"; name: string; message: string; choices?: Array<{ name: string; value: unknown; /** * Optional secondary info shown after `name`. The CLI wraps it in * dimmed parens; an array is joined with ", ". Use for keys, ids, or * other context that's useful but shouldn't compete visually with * the primary label. */ hint?: string | string[]; }>; default?: unknown; filter?: (value: unknown) => unknown; /** * Return `true` for valid; a string for a custom invalid message; or * `false` for invalid with a generic fallback message ("X: invalid * value."). Prefer returning a string so users see something specific. */ validate?: (value: unknown) => boolean | string; } /** A PromptConfig narrowed to single-select list mode. */ export type ListPromptConfig = PromptConfig & { type: "list"; }; export interface Resolver { type: string; depends?: readonly string[] | string[]; } export interface StaticResolver extends Resolver { type: "static"; inputType?: "text" | "password" | "email"; placeholder?: string; } /** * A resolver that always resolves to a fixed value, never prompts. Use to * pin an implicit parameter that downstream resolvers or SDK calls require * but the user shouldn't have to provide. Triggers, for example, are always * `actionType: "read"` from the SDK's perspective; createTriggerInbox * declares `actionType: { type: "constant", value: "read" }` so the * standard `actionKeyResolver` and `inputsResolver` (which depend on * `actionType`) work without any pinned variants. * * Constants attached to keys that aren't in the schema are seeded into * `resolvedParams` upfront, so dependent resolvers find them in context * without the key appearing in the user-facing surface (TS option type, * CLI flags, generated docs). */ export interface ConstantResolver extends Resolver { type: "constant"; value: unknown; } /** * Fields shared by both variants of {@link DynamicResolver}. */ interface DynamicResolverBase extends Resolver { type: "dynamic"; prompt: (items: TItem[], params: TParams) => PromptConfig; /** Capabilities that expand results. The parameter resolver shows a hint for any that aren't enabled. */ requireCapabilities?: string[]; /** * Optional hook called before fetch/prompt. If it returns a non-null object, * resolvedValue is used directly and fetch/prompt are skipped entirely. Return * null to fall through to the normal resolution flow. Implementations should * catch their own errors and return null on failure rather than throwing, so * that a transient API error does not block the CLI entirely. */ tryResolveWithoutPrompt?: (sdk: ZapierSdk, params: TParams) => Promise<{ resolvedValue: unknown; } | null>; } /** * The classic dynamic-resolver variant: `fetch` returns a list of items * that the CLI renders as a search-filterable dropdown. The user picks one. */ export interface DynamicListResolver extends DynamicResolverBase { /** Explicitly absent on the list variant — set `inputType: "search"` to opt into the search variant. */ inputType?: never; /** Only meaningful for the search variant; set to `never` here so TS catches misuse. */ placeholder?: never; fetch: (sdk: ZapierSdk, resolvedParams: TParams) => PromiseLike>; } /** * The search-input variant: the CLI prompts the user for free-form text * first, then calls `fetch` with `{ ...resolvedParams, search }`. * * `fetch` can short-circuit by returning a primitive (`string | number`), * which the CLI treats as an exact match — no dropdown is rendered. Any * other return (array, page, async iterable) is rendered as the normal * search-filterable dropdown. * * The `search` key is injected by the CLI at call time; it isn't part of * `TParams` because callers that invoke `fetch` directly (outside the CLI) * are responsible for passing it themselves. Search-mode resolvers should * type `TParams` as `{ search?: string; ...otherDeps }` to make this * explicit. */ export interface DynamicSearchResolver extends Omit, "prompt"> { inputType: "search"; /** * Hint text appended to the search prompt's message. NOT used as * inquirer's `default` value, because inquirer prefills `default` as * editable text that the user has to delete before typing. */ placeholder?: string; /** * Search-mode always renders a single-select @inquirer/search dropdown, * so `prompt` must return a list-typed PromptConfig. Checkbox/confirm * configs would be silently ignored at runtime; the type narrows so * misuse fails at compile time. * * Note: a primitive return from `fetch` (string | number) is treated * as an exact match and short-circuits without running this prompt or * the resolver's validate/filter. Canonicalize inside `fetch` if the * exact-match path needs normalization. */ prompt: (items: TItem[], params: TParams) => ListPromptConfig; fetch: (sdk: ZapierSdk, resolvedParams: TParams) => PromiseLike>; } /** * A dynamic resolver — either a classic list (`inputType` absent) or a * search-input variant (`inputType: "search"`). The discriminator is the * `inputType` field; TS narrows to the right variant when you check it. */ export type DynamicResolver> = DynamicListResolver | DynamicSearchResolver; export interface ResolverFieldItem { type: string; key: string; title?: string; is_required?: boolean; value_type?: string; choices?: Array<{ label: string; value: string; }>; fields?: ResolverFieldItem[]; resolver?: ResolverMetadata; } export interface FieldsResolver, TResult = Record> extends Resolver { type: "fields"; fetch: (sdk: ZapierSdk, resolvedParams: TParams) => Promise; transform?: (value: Record) => TResult; } export interface ArrayResolver> extends Resolver { type: "array"; fetch: (sdk: ZapierSdk, resolvedParams: TParams) => Promise>; minItems?: number; maxItems?: number; } export type ResolverMetadata> = StaticResolver | ConstantResolver | DynamicResolver | FieldsResolver | ArrayResolver; export interface ResolverConfig> { resolver: ResolverMetadata; } export declare function withResolver>(schema: T, config: ResolverConfig): T; export declare function getSchemaDescription(schema: z.ZodSchema): string | undefined; export declare function getFieldDescriptions(schema: z.ZodObject): Record; export interface PositionalMetadata { positionalMeta: { positional: true; }; } export declare function withPositional(schema: T): T & { _def: T["_def"] & PositionalMetadata; }; export declare function isPositional(schema: z.ZodType): boolean; export {}; //# sourceMappingURL=schema-utils.d.ts.map