import { PathLike } from "node:fs"; import * as semver from "semver"; import { RangeOptions, SemVer } from "semver"; import { getResolvedInput } from "@hey-api/json-schema-ref-parser"; import { IProject, Logger, NameConflictResolver, Node, Project, Ref, RenderContext, StructureLocation, Symbol, SymbolIdentifier, SymbolIn, SymbolMeta, log } from "@hey-api/codegen-core"; import { AnyObject, AnyString, MaybeArray, MaybeFunc, MaybePromise } from "@hey-api/types"; import { CodeSampleObject, JSONSchemaDraft2020_12, OpenAPIV2, OpenAPIV3, OpenAPIV3_1, SpecExtensions } from "@hey-api/spec-types"; //#region src/cli.d.ts /** * Checks the current environment based on the HEYAPI_CODEGEN_ENV environment variable. */ declare function isEnvironment(value: 'development'): boolean; declare function printCliIntro(initialDir: string, showLogo?: boolean): void; //#endregion //#region src/config/engine.d.ts declare function checkNodeVersion(): void; //#endregion //#region src/config/input/types.d.ts type JsonSchema = Record; type ApiRegistryShorthands = `https://get.heyapi.dev/${string}/${string}` | `${string}/${string}` | `readme:@${string}/${string}#${string}` | `readme:${string}` | `scalar:@${string}/${string}`; type UserInput = { /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Projects are private by default, you will need to be authenticated * to download OpenAPI specifications. We recommend using project API * keys in CI workflows and personal API keys for local development. * * API key isn't required for public projects. You can also omit this * parameter and provide an environment variable `HEY_API_TOKEN`. */ api_key?: string; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * You can fetch the last build from branch by providing the branch * name. */ branch?: string; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * You can fetch an exact specification by providing a commit sha. * This will always return the same file. */ commit_sha?: string; /** * You can pass any valid Fetch API options to the request for fetching your * specification. This is useful if your file is behind auth for example. */ fetch?: RequestInit; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Organization created in Hey API Platform. */ organization?: string; /** * Path to the OpenAPI specification. This can be: * - path * - URL * - API registry shorthand * * Both JSON and YAML file formats are supported. You can also pass the parsed * object directly if you're fetching the file yourself. */ path?: ApiRegistryShorthands | AnyString | JsonSchema; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Project created in Hey API Platform. */ project?: string; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * If you're tagging your specifications with custom tags, you can use * them to filter the results. When you provide multiple tags, only * the first match will be returned. */ tags?: ReadonlyArray; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Every OpenAPI document contains a required version field. You can * use this value to fetch the last uploaded specification matching * the value. */ version?: string; /** * Regenerate the client when the input file changes? You can alternatively * pass a numeric value for the interval in ms. * * @default false */ watch?: UserWatch; }; type Input = { /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Projects are private by default, you will need to be authenticated * to download OpenAPI specifications. We recommend using project API * keys in CI workflows and personal API keys for local development. * * API key isn't required for public projects. You can also omit this * parameter and provide an environment variable `HEY_API_TOKEN`. */ api_key?: string; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * You can fetch the last build from branch by providing the branch * name. */ branch?: string; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * You can fetch an exact specification by providing a commit sha. * This will always return the same file. */ commit_sha?: string; /** * You can pass any valid Fetch API options to the request for fetching your * specification. This is useful if your file is behind auth for example. */ fetch?: RequestInit; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Organization created in Hey API Platform. */ organization?: string; /** * Path to the OpenAPI specification. This can be: * - path * - URL * - API registry shorthand * * Both JSON and YAML file formats are supported. You can also pass the parsed * object directly if you're fetching the file yourself. */ path: ApiRegistryShorthands | AnyString | JsonSchema; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Project created in Hey API Platform. */ project?: string; /** * If input path was resolved to a registry, this contains the registry * identifier so we don't need to parse it again. * * @default undefined */ registry?: 'hey-api' | 'readme' | 'scalar'; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * If you're tagging your specifications with custom tags, you can use * them to filter the results. When you provide multiple tags, only * the first match will be returned. */ tags?: ReadonlyArray; /** * **Requires `registry` to be `readme`** * * The unique identifier for the ReadMe API registry entry. */ uuid?: string; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * * Every OpenAPI document contains a required version field. You can * use this value to fetch the last uploaded specification matching * the value. */ version?: string; /** * Regenerate the client when the input file changes? You can alternatively * pass a numeric value for the interval in ms. */ watch: Watch; }; type UserWatch = boolean | number | Watch; type Watch = { /** * Whether this feature is enabled. * * @default false */ enabled?: boolean; /** * How often should we attempt to detect the input file change? (in ms) * * @default 1000 */ interval?: number; /** * How long will we wait before the request times out? * * @default 60_000 */ timeout?: number; }; //#endregion //#region src/config/input/input.d.ts declare function getInput(userConfig: { input: MaybeArray['path']>; watch?: UserWatch; }): ReadonlyArray; //#endregion //#region src/types/logs.d.ts type LogLevel = 'debug' | 'error' | 'fatal' | 'info' | 'silent' | 'trace' | 'warn'; type Logs = { /** * Whether or not error logs should be written to a file or not * * @default true * */ file?: boolean; /** * The logging level to control the verbosity of log output. * Determines which messages are logged based on their severity. * * Available levels (in increasing order of severity): * - `trace`: Detailed debug information, primarily for development. * - `debug`: Diagnostic information useful during debugging. * - `info`: General operational messages that indicate normal application behavior. * - `warn`: Potentially problematic situations that require attention. * - `error`: Errors that prevent some functionality but do not crash the application. * - `fatal`: Critical errors that cause the application to terminate. * - `silent`: Disables all logging. * * Messages with a severity equal to or higher than the specified level will be logged. * * @default 'info' */ level?: LogLevel; /** * The relative location of the logs folder * * @default process.cwd() */ path?: string; }; //#endregion //#region src/config/input/path.d.ts declare function compileInputPath(input: Omit): Pick, "api_key" | "branch" | "commit_sha" | "organization" | "project" | "registry" | "tags" | "uuid" | "version"> & Pick; declare function logInputPaths(inputPaths: ReadonlyArray>, jobIndex: number, logLevel?: LogLevel): void; //#endregion //#region src/config/logs.d.ts declare function getLogs(input: string | Logs | undefined): Logs; //#endregion //#region src/config/output/postprocess.d.ts type Output = { /** * The absolute path to the output folder. */ path: string; /** * Post-processing commands to run on the output folder, executed in order. */ postProcess: ReadonlyArray; }; type UserPostProcessor = { /** * Arguments to pass to the command. Use `{{path}}` as a placeholder * for the output directory path. * * @example ['format', '--write', '{{path}}'] */ args: ReadonlyArray; /** * The command to run (e.g., 'biome', 'prettier', 'eslint'). */ command: string; /** * Display name for logging. Defaults to the command name. */ name?: string; }; type PostProcessor = { /** * Arguments to pass to the command. */ args: ReadonlyArray; /** * The command to run. */ command: string; /** * Display name for logging. */ name: string; }; declare function postprocessOutput(config: Output, postProcessors: Record, jobPrefix: string): void; //#endregion //#region src/config/utils/dependencies.d.ts type Dependency = { /** * Get the installed version of a package. * @param name The name of the package to get the version for. * @returns A SemVer object containing version information, or undefined if the package is not installed * or the version string is invalid. */ getVersion: (name: string) => SemVer | undefined; /** * Check if a given package is installed in the project. * @param name The name of the package to check. */ isInstalled: (name: string) => boolean; /** * Check if the installed version of a package or a given SemVer object satisfies a semver range. * @param nameOrVersion The name of the package to check, or a SemVer object. * @param range The semver range to check against. * @returns True if the version satisfies the range, false otherwise. */ satisfies: (nameOrVersion: string | SemVer, range: string, optionsOrLoose?: boolean | RangeOptions) => boolean; }; declare const satisfies: typeof semver.satisfies; declare function dependencyFactory(dependencies: Record): Dependency; //#endregion //#region src/normalize/coerce.d.ts declare const COERCER: unique symbol; type Coercer = { readonly [COERCER]: (value: In, context: TContext) => Out; }; /** * Wraps a function as a coercer — a field-level resolver that receives the * raw user value and optional context, and returns the resolved field value. * * Unlike plain defaults, coercers run unconditionally on every resolution, * giving full control over the output regardless of what the user provides. * * Use when a field's resolved value requires computation, context access, * or delegation to another config normalizer. * * @param fn - Receives the raw input value and resolution context, returns * the resolved field value. * * @example * ```ts * // Delegate watch resolution to a nested config normalizer * watch: coerce((value) => watchConfig(value)), * * // Resolve a field from context * output: coerce((value, ctx) => value ?? ctx.defaultOutput), * ``` */ declare function coerce(fn: (value: In, context: TContext) => Out): Coercer; declare function isCoercer(value: unknown): value is Coercer; //#endregion //#region src/normalize/value.d.ts type CoercerMap = { boolean?: (value: boolean) => Partial; function?: (value: (...args: Array) => any) => Partial; number?: (value: number) => Partial; string?: (value: string) => Partial; }; type CoercionEvent = { type: 'boolean'; value: boolean; } | { type: 'function'; value: (...args: Array) => any; } | { type: 'number'; value: number; } | { type: 'object'; value: Record; } | { type: 'string'; value: string; }; type TableDirectives = { /** * Keys resolved first, in order. Their resolved values are available as * context to all subsequent fields in the same table. * * @example * ```ts * $cascade: ['strategy'], * strategy: 'flat', * methodName: coerce((value, context) => ({ * casing: 'camelCase', * name: context.strategy === 'flat' ? '{{name}}Request' : undefined, * })), * ``` */ readonly $cascade?: ReadonlyArray; /** * Per-type coercers. Each handler receives the raw user input of the matching * type and returns a partial object merged into the resolved config. * Applied after `$coerceAny`. * * @example * ```ts * $coerce: { * string: (v) => ({ name: v }), * function: (v) => ({ name: v }), * } * ``` */ $coerce?: CoercerMap; /** * Fires for any non-`undefined` input before type-specific `$coerce` handlers. * * @example * ```ts * $coerceAny: ({ type, value }) => ({ enabled: Boolean(value) }) * ``` */ $coerceAny?: (event: CoercionEvent) => Partial; /** * Fields whose resolved string values are registered as plugin dependencies * after this table is resolved. * * @example * ```ts * $dependencies: ['client'], * client: coerce((value, context) => context.resolveTag('client')), * ``` */ readonly $dependencies?: ReadonlyArray; /** * Runs after all fields in this scope have been resolved. * Use for cross-field fixups that depend on multiple resolved values. * * @example * ```ts * $finalize(config) { * if (config.output === 'cjs' && config.format === undefined) { * config.format = 'commonjs'; * } * } * ``` */ $finalize?: (config: TShape, input: TInput) => void; }; type WithCoercers = [T] extends [(...args: Array) => any] ? T | Coercer : [T] extends [object] ? ({ [K in keyof T]: WithCoercers } & TableDirectives) | Coercer : T | Coercer; declare function collectDeps(spec: Record, resolved: Record, deps: Set): void; //#endregion //#region src/normalize/config.d.ts type ObjectMember = Extract> extends infer O ? O extends ((...args: Array) => any) ? never : O : never; type TableSpec = [Out] extends [(...args: Array) => any] ? [NonNullable] extends [Out] ? Out | Coercer : Coercer : Coercer | ([Out] extends [object] ? { [K in keyof Out]?: TableSpec ? ObjectMember[K] : undefined, TContext> } & TableDirectives : [NonNullable] extends [Out] ? Out : never); type ConfigTableEntries = { [K in keyof TResolved]?: TableSpec ? ObjectMember[K] : undefined, TContext> }; type ConfigTable = ConfigTableEntries & TableDirectives; type ConfigNormalizer = ((config: TInput, externalContext?: Record) => TResolved) & Coercer; /** * Creates a typed config normalizer from a resolution table. * * @example * ```ts * const normalizePlugin = defineConfig({ * $coerce: { * boolean: (enabled) => ({ enabled }), * function: (name) => ({ name, enabled: true }), * string: (name) => ({ name, enabled: true }), * }, * enabled: false, * name: '', * output: coerce((val, ctx) => val ?? ctx.defaultOutput), * }); * ``` */ declare function defineConfig, TResolved extends object = Record>(table: ConfigTable | ((config: TInput) => ConfigTable)): ConfigNormalizer; //#endregion //#region src/ir/mediaType.d.ts type IRMediaType = 'form-data' | 'json' | 'text' | 'url-search-params' | 'octet-stream'; //#endregion //#region src/ir/types.d.ts interface IRBodyObject { mediaType: string; /** * Does body control pagination? We handle only simple values * for now, up to 1 nested field. */ pagination?: boolean | string; required?: boolean; schema: IRSchemaObject; type?: IRMediaType; } interface IRComponentsObject { parameters?: Record; requestBodies?: Record; schemas?: Record; } interface IROperationObject extends SpecExtensions { body?: IRBodyObject; deprecated?: boolean; description?: string; id: string; method: keyof IRPathItemObject; operationId?: string; parameters?: IRParametersObject; path: keyof IRPathsObject; responses?: IRResponsesObject; security?: ReadonlyArray; servers?: ReadonlyArray; summary?: string; tags?: ReadonlyArray; } interface IRParametersObject { cookie?: Record; header?: Record; path?: Record; query?: Record; } interface IRParameterObject extends Pick, SpecExtensions { /** * Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 `:/?#[]@!$&'()*+,;=` to be included without percent-encoding. The default value is `false`. This property SHALL be ignored if the request body media type is not `application/x-www-form-urlencoded` or `multipart/form-data`. If a value is explicitly defined, then the value of `contentType` (implicit or explicit) SHALL be ignored. */ allowReserved?: boolean; /** * When this is true, property values of type `array` or `object` generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect. When `style` is `form`, the default value is `true`. For all other styles, the default value is `false`. This property SHALL be ignored if the request body media type is not `application/x-www-form-urlencoded` or `multipart/form-data`. If a value is explicitly defined, then the value of `contentType` (implicit or explicit) SHALL be ignored. */ explode: boolean; /** * Endpoint parameters must specify their location. */ location: 'cookie' | 'header' | 'path' | 'query'; name: string; /** * Does this parameter control pagination? We handle only simple values * for now, up to 1 nested field. */ pagination?: boolean | string; required?: boolean; schema: IRSchemaObject; /** * Describes how the parameter value will be serialized depending on the type of the parameter value. Default values (based on value of `in`): for `query` - `form`; for `path` - `simple`; for `header` - `simple`; for `cookie` - `form`. */ style: 'deepObject' | 'form' | 'label' | 'matrix' | 'pipeDelimited' | 'simple' | 'spaceDelimited'; } interface IRPathsObject { [path: `/${string}`]: IRPathItemObject; } interface IRPathItemObject { delete?: IROperationObject; get?: IROperationObject; head?: IROperationObject; options?: IROperationObject; patch?: IROperationObject; post?: IROperationObject; put?: IROperationObject; trace?: IROperationObject; } interface IRRequestBodyObject extends Pick { required?: boolean; schema: IRSchemaObject; } interface IRResponsesObject { /** * Any {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#http-status-codes HTTP status code} can be used as the property name, but only one property per code, to describe the expected response for that HTTP status code. This field MUST be enclosed in quotation marks (for example, "200") for compatibility between JSON and YAML. To define a range of response codes, this field MAY contain the uppercase wildcard character `X`. For example, `2XX` represents all response codes between `[200-299]`. Only the following range definitions are allowed: `1XX`, `2XX`, `3XX`, `4XX`, and `5XX`. If a response is defined using an explicit code, the explicit code definition takes precedence over the range definition for that code. */ [statusCode: string]: IRResponseObject | undefined; /** * The documentation of responses other than the ones declared for specific HTTP response codes. Use this field to cover undeclared responses. */ default?: IRResponseObject; } interface IRResponseObject { mediaType?: string; schema: IRSchemaObject; } interface IRSchemaObject extends Pick, Pick, SpecExtensions { /** * If the schema is intended to be used as an object property, it can be * marked as read-only or write-only. This value controls whether the schema * receives the "readonly" TypeScript keyword. */ accessScope?: 'read' | 'write'; /** * If type is `object`, `additionalProperties` can be used to either define * a schema for properties not included in `properties` or disallow such * properties altogether. */ additionalProperties?: IRSchemaObject | false; /** * When present on a union schema, indicates that this union uses a * discriminator for polymorphism. */ discriminator?: { mapping?: Record; propertyName: string; }; /** * Any string value is accepted as `format`. */ format?: JSONSchemaDraft2020_12.Document['format'] | 'binary' | 'integer'; /** * If schema resolves into multiple items instead of a simple `type`, they * will be included in `items` array. */ items?: ReadonlyArray; /** * When resolving a list of items, we need to know the relationship between * them. `logicalOperator` specifies this logical relationship. * * @default 'or' */ logicalOperator?: 'and' | 'or'; /** * When used with `$ref` or `symbolRef`, specifies properties to omit from the referenced schema. * Useful for handling discriminator property conflicts in allOf compositions. */ omit?: ReadonlyArray; /** * When type is `object`, `patternProperties` can be used to define a schema * for properties that match a specific regex pattern. */ patternProperties?: Record; /** * When type is `object`, `properties` will contain a map of its properties. */ properties?: Record; /** * The names of `properties` can be validated against a schema, irrespective * of their values. This can be useful if you don't want to enforce specific * properties, but you want to make sure that the names of those properties * follow a specific convention. */ propertyNames?: IRSchemaObject; /** * Reference to symbol instead of `$ref` string. */ symbolRef?: Symbol; /** * Each schema eventually resolves into `type`. */ type?: 'array' | 'boolean' | 'enum' | 'integer' | 'never' | 'null' | 'number' | 'object' | 'string' | 'tuple' | 'undefined' | 'unknown' | 'void'; } type IRSecurityObject = OpenAPIV3_1.SecuritySchemeObject & { /** * Name of the entry under `components.securitySchemes` that this security * object came from. Populated only when the spec defines two or more * security schemes whose canonical `Auth` shape would otherwise collide, * so consumers can disambiguate which token to return at runtime. */ key?: string; }; interface IRServerObject extends OpenAPIV3_1.ServerObject {} type IRWebhookObject = IRPathItemObject; interface IRModel { components?: IRComponentsObject; paths?: IRPathsObject; servers?: ReadonlyArray; webhooks?: Record; } declare namespace IR { type BodyObject = IRBodyObject; type ComponentsObject = IRComponentsObject; type Model = IRModel; type OperationObject = IROperationObject; type ParameterObject = IRParameterObject; type ParametersObject = IRParametersObject; type PathItemObject = IRPathItemObject; type PathsObject = IRPathsObject; type ReferenceObject = OpenAPIV3_1.ReferenceObject; type RequestBodyObject = IRRequestBodyObject; type ResponseObject = IRResponseObject; type ResponsesObject = IRResponsesObject; type SchemaObject = IRSchemaObject; type SecurityObject = IRSecurityObject; type ServerObject = IRServerObject; type WebhookObject = IRWebhookObject; } //#endregion //#region src/ir/schema-processor.d.ts interface SchemaProcessor { /** Current inherited context (set by withContext) */ readonly context: { readonly anchor: string | undefined; readonly tags: ReadonlyArray | undefined; }; /** Check if pointer was already emitted */ hasEmitted: (path: ReadonlyArray) => boolean; /** Mark pointer as emitted. Returns false if already emitted. */ markEmitted: (path: ReadonlyArray) => boolean; /** Execute with inherited context for nested extractions */ withContext: (ctx: { anchor?: string; tags?: ReadonlyArray; }, fn: () => T) => T; } interface SchemaProcessorContext { meta: { resource: string; resourceId: string; role?: string; }; namingAnchor?: string; path: ReadonlyArray; schema: IR.SchemaObject; tags?: ReadonlyArray; } interface SchemaProcessorResult { process: (ctx: Context) => void; } type SchemaExtractor = (ctx: Context) => IR.SchemaObject; declare function createSchemaProcessor(): SchemaProcessor; //#endregion //#region src/openApi/shared/utils/graph.d.ts /** * Represents the possible access scopes for OpenAPI nodes. * - 'normal': Default scope for regular nodes. * - 'read': Node is read-only (e.g., readOnly: true). * - 'write': Node is write-only (e.g., writeOnly: true). */ type Scope = 'normal' | 'read' | 'write'; /** * Builds a graph of all nodes in an OpenAPI spec, indexed by normalized JSON Pointer, * and tracks all $ref dependencies and reverse dependencies between nodes. * * - All keys in the returned maps are normalized JSON Pointers (RFC 6901, always starting with '#'). * - The `nodes` map allows fast lookup of any node and its parent/key context. * - The `dependencies` map records, for each node, the set of normalized pointers it references via $ref. * - After construction, all nodes will have their local and propagated scopes annotated. * * @param root The root object (e.g., the OpenAPI spec) * @returns An object with: * - nodes: Map from normalized JSON Pointer string to NodeInfo * - dependencies: Map from normalized JSON Pointer string to Set of referenced normalized JSON Pointers */ declare function buildGraph(root: unknown, logger: Logger): { graph: Graph; }; //#endregion //#region src/graph/types/graph.d.ts /** * The main graph structure for OpenAPI node analysis. * * @property nodeDependencies - For each node with at least one dependency, the set of normalized JSON Pointers it references via $ref. Nodes with no dependencies are omitted. * @property nodes - Map from normalized JSON Pointer to NodeInfo for every node in the spec. */ type Graph = { /** * For each node with at least one dependency, the set of normalized JSON Pointers it references via $ref. * Nodes with no dependencies are omitted from this map. */ nodeDependencies: Map>; /** * Map from normalized JSON Pointer to NodeInfo for every node in the spec. */ nodes: Map; /** * For each node, the set of direct $ref targets that appear anywhere inside the node's * subtree (the node itself and its children). This is populated during graph construction * and is used to compute top-level dependency relationships where $ref may be attached to * child pointers instead of the parent. */ subtreeDependencies: Map>; /** * For each node, the set of all (transitive) normalized JSON Pointers it references via $ref anywhere in its subtree. * This includes both direct and indirect dependencies, making it useful for filtering, codegen, and tree-shaking. */ transitiveDependencies: Map>; }; /** * Information about a node in the OpenAPI graph. * * @property deprecated - Whether the node is deprecated. Optional. * @property key - The property name or array index in the parent, or null for root. * @property node - The actual object at this pointer in the spec. * @property parentPointer - The JSON Pointer of the parent node, or null for root. * @property scopes - The set of access scopes for this node, if any. Optional. * @property tags - The set of tags for this node, if any. Optional. */ type NodeInfo = { /** Whether the node is deprecated. Optional. */deprecated?: boolean; /** The property name or array index in the parent, or null for root. */ key: string | number | null; /** The actual object at this pointer in the spec. */ node: unknown; /** The JSON Pointer of the parent node, or null for root. */ parentPointer: string | null; /** The set of access scopes for this node, if any. Optional. */ scopes?: Set; /** The set of tags for this node, if any. Optional. */ tags?: Set; }; //#endregion //#region src/graph/types/walk.d.ts type GetPointerPriorityFn = (pointer: string) => number; type MatchPointerToGroupFn = (pointer: string, kind?: T) => PointerGroupMatch; type PointerGroupMatch = { kind: T; matched: true; } | { kind?: undefined; matched: false; }; type WalkOptions = { /** * Optional priority function used to compute a numeric priority for each * pointer. Lower values are emitted earlier. Useful to customize ordering * beyond the built-in group preferences. */ getPointerPriority?: GetPointerPriorityFn; /** * Optional function to match a pointer to a group name. * * @param pointer The pointer string * @returns The group name, or undefined if no match */ matchPointerToGroup?: MatchPointerToGroupFn; /** * Order of walking schemas. * * The "declarations" option ensures that schemas are walked in the order * they are declared in the input document. This is useful for scenarios where * the order of declaration matters, such as when generating code that relies * on the sequence of schema definitions. * * The "topological" option ensures that schemas are walked in an order * where dependencies are visited before the schemas that depend on them. * This is useful for scenarios where you need to process or generate * schemas in a way that respects their interdependencies. * * @default 'topological' */ order?: 'declarations' | 'topological'; /** * Optional grouping preference for walking. When provided, walk function * will prefer emitting kinds listed earlier in this array when it is safe * to do so (it will only apply the preference when doing so does not * violate dependency ordering). */ preferGroups?: ReadonlyArray; }; //#endregion //#region src/ir/intents.d.ts interface ExampleIntent { run(ctx: IntentContext): MaybePromise; } declare class IntentContext = any> { private spec; constructor(spec: Spec); private getOperation; setExample(operation: IR.OperationObject, example: CodeSampleObject): void; } //#endregion //#region src/ir/context.d.ts declare class Context = any, Config extends AnyConfig = AnyConfig> { /** * Configuration for parsing and generating the output. This * is a mix of user-provided and default values. */ config: Config; /** The code generation project instance used to manage files, symbols, */ gen: Project; /** The dependency graph built from the intermediate representation. */ graph: Graph | undefined; /** Intents declared by plugins. */ intents: Array; /** Intermediate representation model obtained from `spec`. */ ir: IR.Model; /** Logger instance. */ logger: Logger; /** * The package metadata and utilities for the current context, constructed * from the provided dependencies. Used for managing package-related * information such as name, version, and dependency resolution during * code generation. */ package: Dependency; /** * A map of registered plugin instances, keyed by plugin name. Plugins are * registered through the `registerPlugin` method and can be accessed by * their configured name from the config. */ plugins: Partial>>; /** Resolved specification from `input`. */ spec: Spec; constructor({ config, dependencies, logger, project, spec }: { config: Config; dependencies: Record; logger: Logger; project: Project; spec: Spec; }); /** * Returns a resolved and dereferenced schema from `spec`. */ dereference(schema: { $ref: string; }): T; /** * Registers a new plugin to the global context. * * @param name Plugin name. * @returns Registered plugin instance. */ private registerPlugin; /** * Registers all plugins in the order specified by the configuration and returns * an array of the registered PluginInstance objects. Each plugin is instantiated * and added to the context's plugins map. * * @returns {ReadonlyArray} An array of registered plugin instances in order. */ registerPlugins(): ReadonlyArray; resolveIrRef($ref: string): T; /** * Returns a resolved reference from `spec`. */ resolveRef($ref: string): T; } //#endregion //#region src/ir/graph.d.ts declare const irTopLevelKinds: readonly ["operation", "parameter", "requestBody", "schema", "server", "webhook"]; type IrTopLevelKind = (typeof irTopLevelKinds)[number]; //#endregion //#region src/utils/symbols.d.ts interface PluginInstanceTypes {} /** * Resolves the Node type, falling back to base Node if not augmented. */ type ResolvedNode = 'Node' extends keyof PluginInstanceTypes ? PluginInstanceTypes['Node'] : Node; type EventHooks = { [K in keyof Required>]: Array[K]>> }; declare class SymbolFactory { private readonly eventHooks; private readonly project; private readonly plugin?; constructor(props: { eventHooks: EventHooks; plugin?: PluginInstance; project: IProject; }); static buildEventHooks(scopes: ReadonlyArray | undefined>): EventHooks; isRegistered(identifier: SymbolIdentifier): boolean; query(filter: SymbolMeta, tags?: ReadonlyArray>, predicate?: (symbol: Symbol) => boolean): Symbol | undefined; queryAll(filter: SymbolMeta, tags?: ReadonlyArray>, predicate?: (symbol: Symbol) => boolean): Array>; reference(meta: SymbolMeta): Symbol; register(name: SymbolIn['name'], symbol?: Omit): Symbol; } //#endregion //#region src/plugins/shared/types/instance.d.ts type BaseEvent = { /** * Path to the node, derived from the pointer. */ _path: ReadonlyArray; /** * Pointer to the node in the graph. */ pointer: string; /** * Tags associated with the node. */ tags?: ReadonlyArray; }; type WalkEvents = BaseEvent & ({ method: keyof IR.PathItemObject; operation: IR.OperationObject; path: string; type: Extract; } | { /** Name of the parameter (e.g., "id" for a parameter defined as "#/components/parameters/id"). */name: string; parameter: IR.ParameterObject; type: Extract; } | { /** Name of the request body (e.g., "CreateUserRequest" for a request body defined as "#/components/requestBodies/CreateUserRequest"). */name: string; requestBody: IR.RequestBodyObject; type: Extract; } | { /** Name of the schema (e.g., "User" for a schema defined as "#/components/schemas/User"). */name: string; schema: IR.SchemaObject; type: Extract; } | { server: IR.ServerObject; type: Extract; } | { key: string; method: keyof IR.PathItemObject; operation: IR.OperationObject; type: Extract; }); type WalkEvent = Extract; //#endregion //#region src/plugins/shared/utils/instance.d.ts declare class PluginInstance { api: T['api']; config: Omit; context: Context; dependencies: Set; private eventHooks; gen: IProject; private handler; /** External symbols imported from other modules. */ imports: T['imports']; name: T['resolvedConfig']['name']; /** * The package metadata and utilities for the current context, constructed * from the provided dependencies. Used for managing package-related * information such as name, version, and dependency resolution during * code generation. */ package: Dependency; /** Factory for creating and managing symbols. */ symbolFactory: SymbolFactory; /** Metadata merged into every symbol this plugin creates. */ symbolMeta: Plugin.Config['symbolMeta']; readonly isSymbolRegistered: SymbolFactory['isRegistered']; readonly querySymbol: SymbolFactory['query']; readonly referenceSymbol: SymbolFactory['reference']; constructor(props: Pick, 'api' | 'handler' | 'imports' | 'name' | 'symbolMeta'> & { config: Omit; context: Context; dependencies: Set; gen: IProject; }); /** * Iterates over various input elements as specified by the event types, in * a specific order: servers, schemas, parameters, request bodies, then * operations. * * This ensures, for example, that schemas are always processed before * operations, which may reference them. * * @template TKind - The event type(s) to yield. Defaults to all event types. * @param events - The event types to walk over. If none are provided, all event types are included. * @param callback - Function to execute for each event. * * @example * // Iterate over all operations and schemas * plugin.forEach('operation', 'schema', (event) => { * if (event.type === 'operation') { * // handle operation * } else if (event.type === 'schema') { * // handle schema * } * }); */ forEach(...args: [...events: ReadonlyArray, callback: (event: WalkEvent) => void]): void; forEach(...args: [...events: ReadonlyArray, callback: (event: WalkEvent) => void, options: WalkOptions]): void; getHooks(selector: (hooks: Hooks) => T | undefined, ...customHooks: ReadonlyArray): Array>; /** * Retrieves a registered plugin instance by its name from the context. This * allows plugins to access other plugins that have been registered in the * same context, enabling cross-plugin communication and dependencies. * * @param name Plugin name as defined in the configuration. * @returns The plugin instance if found, undefined otherwise. */ getPlugin(name: TName): TName extends any ? PluginInstance | undefined : never; /** * Retrieves a registered plugin instance by its name from the context. This * allows plugins to access other plugins that have been registered in the * same context, enabling cross-plugin communication and dependencies. * * @param name Plugin name as defined in the configuration. * @returns The plugin instance if found, throw otherwise. */ getPluginOrThrow(name: TName): TName extends any ? PluginInstance : never; hooks: { operation: { isMutation: (operation: IR.OperationObject) => boolean; isQuery: (operation: IR.OperationObject) => boolean; }; }; /** * Registers an intent in the context's intent list. * * @param intent The intent to be registered. * @returns void */ intent(intent: ExampleIntent): void; /** * Sets or adds a node to the project graph. * * @param node The node to be added or updated in the project graph. * @param index The index at which to update the node. If undefined, the node will be added. * @returns The index of the added node or void if updated. */ node(node: Node | null, index?: T): T extends number ? void : number; /** * Executes plugin's handler function. */ run(): Promise; symbol(name: SymbolIn['name'], symbol?: Omit): Symbol; symbol(symbol: SymbolIn): Symbol; /** * Registers a symbol only if it does not already exist based on the provided * name and metadata. This prevents duplicate symbols from being created in * the project. */ symbolOnce(name: SymbolIn['name'], symbol?: Omit): Symbol; private forEachError; private getSymbolExportFromFilePath; private getSymbolFilePath; private isOperationKind; } //#endregion //#region src/utils/naming/types.d.ts /** * Available casing strategies. */ type Casing = 'camelCase' | 'PascalCase' | 'preserve' | 'snake_case' | 'SCREAMING_SNAKE_CASE'; /** * Name transformer: template string or function. * * Template supports `{{name}}` variable. */ type NameTransformer = MaybeFunc<(name: string) => string>; /** * Full naming configuration. */ interface NamingConfig { /** * Casing strategy applied after transformation. * * @deprecated Use `casing` instead. */ case?: Casing; /** * Casing strategy applied after transformation. */ casing?: Casing; /** * Name template or transformer function. * * Applied before `casing` transformation. */ name?: NameTransformer; } /** * Name customization: shorthand or full configuration. */ type NamingRule = NameTransformer | NamingConfig; //#endregion //#region src/parser/hooks.d.ts type Hooks = { /** * Event hooks. */ events?: { /** * Triggered after adding or updating a node. * * You can use this to perform actions after a node is added or updated. * * @param args Arguments object. * @returns void */ 'node:set:after'?: (args: { /** The node added or updated. */node: Node | null; /** Plugin that added or updated the node. */ plugin: PluginInstance; }) => void; /** * Triggered before adding or updating a node. * * You can use this to modify the node before it's added or updated. * * @param args Arguments object. * @returns void */ 'node:set:before'?: (args: { /** The node to be added or updated. */node: Node | null; /** Plugin adding or updating the node. */ plugin: PluginInstance; }) => void; /** * Triggered after executing a plugin handler. * * @param args Arguments object. * @returns void */ 'plugin:handler:after'?: (args: { /** Plugin that just executed. */plugin: PluginInstance; }) => void; /** * Triggered before executing a plugin handler. * * @param args Arguments object. * @returns void */ 'plugin:handler:before'?: (args: { /** Plugin about to execute. */plugin: PluginInstance; }) => void; /** * Triggered after registering a symbol. * * You can use this to perform actions after a symbol is registered. * * @param args Arguments object. * @returns void */ 'symbol:register:after'?: (args: { /** Plugin that registered the symbol, if available. */plugin?: PluginInstance; /** The registered symbol. */ symbol: Symbol; }) => void; /** * Triggered before registering a symbol. * * You can use this to modify the symbol before it's registered. * * @param args Arguments object. * @returns void */ 'symbol:register:before'?: (args: { /** Plugin registering the symbol, if available. */plugin?: PluginInstance; /** Symbol to register. */ symbol: SymbolIn; }) => void; }; /** * Hooks specifically for overriding operations behavior. * * Use these to classify operations, decide which outputs to generate, * or apply custom behavior to individual operations. */ operations?: { /** * Classify the given operation into one or more kinds. * * Each kind determines how we treat the operation (e.g., generating queries or mutations). * * **Default behavior:** * - GET → 'query' * - DELETE, PATCH, POST, PUT → 'mutation' * * **Resolution order:** * 1. If `isQuery` or `isMutation` returns `true` or `false`, that overrides `getKind`. * 2. If `isQuery` or `isMutation` returns `undefined`, the result of `getKind` is used. * * @param operation - The operation object to classify. * @returns An array containing one or more of 'query' or 'mutation', or undefined to fallback to default behavior. * @example * ```ts * getKind: (operation) => { * if (operation.method === 'get' && operation.path === '/search') { * return ['query', 'mutation']; * } * return; // fallback to default behavior * } * ``` */ getKind?: (operation: IROperationObject) => ReadonlyArray<'mutation' | 'query'> | undefined; /** * Check if the given operation should be treated as a mutation. * * This affects which outputs are generated for the operation. * * **Default behavior:** DELETE, PATCH, POST, and PUT operations are treated as mutations. * * **Resolution order:** If this returns `true` or `false`, it overrides `getKind`. * If it returns `undefined`, `getKind` is used instead. * * @param operation - The operation object to check. * @returns true if the operation is a mutation, false otherwise, or undefined to fallback to `getKind`. * @example * ```ts * isMutation: (operation) => { * if (operation.method === 'post' && operation.path === '/search') { * return true; * } * return; // fallback to default behavior * } * ``` */ isMutation?: (operation: IROperationObject) => boolean | undefined; /** * Check if the given operation should be treated as a query. * * This affects which outputs are generated for the operation. * * **Default behavior:** GET operations are treated as queries. * * **Resolution order:** If this returns `true` or `false`, it overrides `getKind`. * If it returns `undefined`, `getKind` is used instead. * * @param operation - The operation object to check. * @returns true if the operation is a query, false otherwise, or undefined to fallback to `getKind`. * @example * ```ts * isQuery: (operation) => { * if (operation.method === 'post' && operation.path === '/search') { * return true; * } * return; // fallback to default behavior * } * ``` */ isQuery?: (operation: IROperationObject) => boolean | undefined; }; schemas?: { /** * Whether to extract the given schema into a separate symbol. * * This affects how schemas are processed and output. * * @param ctx - The processing context for the schema. * @returns true to extract the schema, false to keep it inline, or undefined to fallback to default behavior. * @example * ```ts * shouldExtract: (ctx) => { * if (ctx.meta.resource === 'requestBody') { * return true; * } * return; // fallback to default behavior * } * ``` */ shouldExtract?: MaybeFunc<(ctx: SchemaProcessorContext) => boolean>; }; /** * Hooks specifically for overriding symbols behavior. * * Use these to customize file placement. */ symbols?: { /** * Optional output strategy to override default plugin behavior. * * Use this to re-export symbols from specific files. * * @returns The file path(s) that re-export this symbol, or undefined to fallback to default behavior. */ getExportFromFilePath?: (symbol: Symbol) => ReadonlyArray | undefined; /** * Optional output strategy to override default plugin behavior. * * Use this to route symbols to specific files. * * @returns The file path to output the symbol to, or undefined to fallback to default behavior. */ getFilePath?: (symbol: Symbol) => string | undefined; /** * Optional output strategy to override default plugin behavior. * * Use this to customize symbol names. * * @returns The name to register the symbol with, or undefined to fallback to default behavior. */ getName?: (ctx: GetNameContext) => MaybeFunc<(ctx: GetNameContext) => string | undefined>; }; }; interface GetNameContext { /** Arbitrary metadata about the symbol. */ meta: SymbolMeta; /** The proposed name for the symbol. */ name: string; /** The naming configuration for the symbol. */ naming?: NamingConfig; /** The operation object associated with the symbol. */ operation?: IROperationObject; /** Path to the resource this symbol represents. */ path?: ReadonlyArray; /** The schema object associated with the symbol. */ schema?: IRSchemaObject; } //#endregion //#region src/plugins/types.d.ts interface PluginConfigMap {} type PluginNames = keyof PluginConfigMap extends never ? string : keyof PluginConfigMap; type AnyPluginName = PluginNames | AnyString; type PluginTag = 'client' | 'handler' | 'sdk' | 'source' | 'transformer' | 'validator'; type ResolveTagOptions = { /** * Plugin to use if no plugin with the given tag is found in the user's * plugin list. Must itself carry the requested tag. If it does not exist * in the registry, resolution falls through to `fallback`. */ defaultPlugin?: T; /** * Value returned when no matching plugin is found and `defaultPlugin` is * absent or also unresolvable. Defaults to `false`. */ fallback?: T | false; /** * Warning message emitted when resolution falls back. */ warn?: string; }; type PluginContext = { package: Dependency; /** * Resolves the first plugin in the user's plugin list that carries `tag`. * Falls back to `options.defaultPlugin` if provided and registered, then * to `options.fallback` (default: `false`). * * @example * ```ts * client: coerce((value, context) => { * if (value === false) return false; * if (typeof value === 'string') return value; * return (context as PluginContext).resolveTag('client', { * defaultPlugin: '@hey-api/client-httpx', * }); * }), * ``` */ resolveTag: (tag: PluginTag, options?: ResolveTagOptions) => T | false; }; /** Map of symbols imported from external modules. */ type PluginImports = { [key: string]: Symbol | PluginImports; }; type BaseApi = Record; type PluginBaseConfig = UserIndexExportOption & { /** Hooks to override default plugin behavior. */$hooks?: Hooks; name: AnyPluginName; /** * Hooks to override default plugin behavior. * * @deprecated Use `$hooks` instead. */ '~hooks'?: Hooks; }; /** Public Plugin API. */ declare namespace Plugin { type Config = Pick & { config: ConfigTable, T['resolvedConfig']>; /** * Dependency plugins will be always processed, regardless of whether user * explicitly defines them in their `plugins` config. */ dependencies?: ReadonlyArray; handler: (args: { plugin: PluginInstance; }) => void; /** Declares symbols this plugin imports from external modules. */ imports?: (plugin: PluginInstance) => T['imports']; name: T['config']['name']; /** Metadata merged into every symbol this plugin creates. */ symbolMeta?: (symbol: Omit) => SymbolMeta; /** * Tags can be used to help with deciding plugin order and resolving * plugin configuration options. */ tags?: ReadonlyArray; }; type Comments = CommentsOption; type UserComments = UserCommentsOption; type Exports = IndexExportOption; type UserExports = UserIndexExportOption; /** Generic wrapper for plugin hooks. */ type Hooks = Pick; interface Name { name: Name; } /** * Generic wrapper for plugin resolvers. * * Provides a namespaced configuration entry (`$resolvers`) * where plugins can define how specific schema constructs * should be resolved or overridden. */ type Resolvers = Record> = { /** * Custom behavior resolvers. * * Used to define how specific schema constructs are * resolved into AST or runtime logic. */ $resolvers?: T; /** * Custom behavior resolvers. * * Used to define how specific schema constructs are * resolved into AST or runtime logic. * * @deprecated Use `$resolvers` instead. */ '~resolvers'?: T; }; interface ResolverNodes { /** Nodes used to build different parts of the result. */ nodes: T; } /** Resolved plugin shape stored in Config['plugins'] after processing. */ type Stored = Omit, 'config' | 'dependencies'> & { config: T['resolvedConfig']; dependencies: Set; }; /** * @typeParam Config - User-facing config shape. * @typeParam ResolvedConfig - Fully resolved config shape after normalization. * @typeParam Api - Public API surface exposed by this plugin to other plugins. * @typeParam Imports - Shape of the external symbol imports map. */ type Types> = ([Api] extends [never] ? { api?: BaseApi; } : { api: Api; }) & { config: Config; imports: Imports; resolvedConfig: ResolvedConfig; }; } /** * Convenience type that derives all plugin-related types from a single * set of type parameters. * * @typeParam Config - User-facing config shape. * @typeParam ResolvedConfig - Fully resolved config shape after normalization. * @typeParam Api - Public API surface exposed by this plugin to other plugins. * @typeParam Imports - Shape of the external symbol imports map. */ type DefinePlugin> = { Config: Plugin.Config>; Handler: (args: { plugin: PluginInstance>; }) => void; /** The plugin instance. */ Instance: PluginInstance>; Types: Plugin.Types; }; //#endregion //#region src/config/output/types.d.ts type OutputHeader = MaybeFunc<(ctx: Pick & Pick, 'file'> & { /** The default header value. */defaultValue: ReadonlyArray; }) => MaybeArray | null | undefined>; //#endregion //#region src/config/parser/filters.d.ts type Filters = { /** * Include deprecated resources in the output? * * @default true */ deprecated?: boolean; operations?: { /** * Prevent operations matching the `exclude` filters from being processed. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['GET /api/v1/foo'] */ exclude?: ReadonlyArray; /** * Process only operations matching the `include` filters. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['GET /api/v1/foo'] */ include?: ReadonlyArray; }; /** * Keep reusable components without any references from operations in the * output? By default, we exclude orphaned resources. * * @default false */ orphans?: boolean; parameters?: { /** * Prevent parameters matching the `exclude` filters from being processed. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['QueryParam'] */ exclude?: ReadonlyArray; /** * Process only parameters matching the `include` filters. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['QueryParam'] */ include?: ReadonlyArray; }; /** * Should we preserve the key order when overwriting your input? This * option is disabled by default to improve performance. * * @default false */ preserveOrder?: boolean; requestBodies?: { /** * Prevent request bodies matching the `exclude` filters from being processed. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['Foo'] */ exclude?: ReadonlyArray; /** * Process only request bodies matching the `include` filters. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['Foo'] */ include?: ReadonlyArray; }; responses?: { /** * Prevent responses matching the `exclude` filters from being processed. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['Foo'] */ exclude?: ReadonlyArray; /** * Process only responses matching the `include` filters. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['Foo'] */ include?: ReadonlyArray; }; schemas?: { /** * Prevent schemas matching the `exclude` filters from being processed. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['Foo'] */ exclude?: ReadonlyArray; /** * Process only schemas matching the `include` filters. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['Foo'] */ include?: ReadonlyArray; }; tags?: { /** * Prevent tags matching the `exclude` filters from being processed. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['foo'] */ exclude?: ReadonlyArray; /** * Process only tags matching the `include` filters. * * In case of conflicts, `exclude` takes precedence over `include`. * * @example ['foo'] */ include?: ReadonlyArray; }; }; //#endregion //#region src/openApi/types.d.ts declare namespace OpenApi { type V2_0_X = OpenAPIV2.Document; type V3_0_X = OpenAPIV3.Document; type V3_1_X = OpenAPIV3_1.Document; } declare namespace OpenApiMetaObject { type V2_0_X = OpenAPIV2.InfoObject; type V3_0_X = OpenAPIV3.InfoObject; type V3_1_X = OpenAPIV3_1.InfoObject; } declare namespace OpenApiOperationObject { type V2_0_X = OpenAPIV2.OperationObject; type V3_0_X = OpenAPIV3.OperationObject; type V3_1_X = OpenAPIV3_1.OperationObject; } declare namespace OpenApiParameterObject { type V3_0_X = OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject; type V3_1_X = OpenAPIV3_1.ParameterObject | OpenAPIV3_1.ReferenceObject; } declare namespace OpenApiRequestBodyObject { type V3_0_X = OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject; type V3_1_X = OpenAPIV3_1.RequestBodyObject | OpenAPIV3_1.ReferenceObject; } declare namespace OpenApiResponseObject { type V3_0_X = OpenAPIV3.ResponseObject | OpenAPIV3.ReferenceObject; type V3_1_X = OpenAPIV3_1.ResponseObject | OpenAPIV3_1.ReferenceObject; } declare namespace OpenApiSchemaObject { type V2_0_X = OpenAPIV2.SchemaObject; type V3_0_X = OpenAPIV3.SchemaObject; type V3_1_X = OpenAPIV3_1.SchemaObject; } //#endregion //#region src/config/parser/patch.d.ts type PatchInputFn = (spec: OpenApi.V2_0_X | OpenApi.V3_0_X | OpenApi.V3_1_X) => void | Promise; type Patch = PatchInputFn | { /** * Patch the raw OpenAPI spec object in place. Called before all other * patch callbacks. Useful for bulk/structural transformations such as * adding new component definitions or modifying many operations at once. * * @param spec The OpenAPI spec object for the current version. * * @example * ```ts * input: (spec) => { * // Create new component parameters * if (!spec.components) spec.components = {}; * if (!spec.components.parameters) spec.components.parameters = {}; * spec.components.parameters.MyParam = { * in: 'query', * name: 'myParam', * schema: { type: 'string' } * }; * * // Inject parameters into operations * for (const [path, pathItem] of Object.entries(spec.paths ?? {})) { * if (pathItem?.get) { * if (!Array.isArray(pathItem.get.parameters)) { * pathItem.get.parameters = []; * } * pathItem.get.parameters.push({ * $ref: '#/components/parameters/MyParam' * }); * } * } * } * ``` */ input?: PatchInputFn; /** * Patch the OpenAPI meta object in place. Useful for modifying general metadata such as title, description, version, or custom fields before further processing. * * @param meta The OpenAPI meta object for the current version. */ meta?: (meta: OpenApiMetaObject.V2_0_X | OpenApiMetaObject.V3_0_X | OpenApiMetaObject.V3_1_X) => void; /** * Patch OpenAPI operations in place. Each function receives the operation * object to be modified in place. Common use cases include injecting * `operationId` for specs that don't have them, adding `x-*` extensions, * setting `deprecated` based on path patterns, or injecting `security` * requirements globally. * * Can be: * - `Record`: Patch specific operations by `"METHOD /path"` key * - `function`: Bulk callback receives `(method, path, operation)` for every operation * * Both patterns support async functions for operations like fetching data * from external sources or performing I/O. * * @example * ```js * // Named operations * operations: { * 'GET /foo': (operation) => { * operation.responses['200'].description = 'Success'; * }, * 'POST /bar': (operation) => { * operation.deprecated = true; * } * } * * // Bulk callback for all operations * operations: (method, path, operation) => { * if (!operation.operationId) { * operation.operationId = method + buildOperationName(path); * } * } * * // Async example - inject operationId based on path patterns * operations: async (method, path, operation) => { * if (operation.operationId) return; * * const segments = path.split('/').filter(Boolean); * const parts = segments * .map((seg) => seg.startsWith('{') ? 'ById' : seg) * .join(''); * operation.operationId = method + parts; * } * ``` */ operations?: Record void | Promise> | ((method: string, path: string, operation: OpenApiOperationObject.V2_0_X | OpenApiOperationObject.V3_0_X | OpenApiOperationObject.V3_1_X) => void | Promise); /** * Patch OpenAPI parameters in place. The key is the parameter name, and the function receives the parameter object to modify directly. * * @example * parameters: { * limit: (parameter) => { * parameter.schema.type = 'integer'; * } * } */ parameters?: Record void>; /** * Patch OpenAPI request bodies in place. The key is the request body name, and the function receives the request body object to modify directly. * * @example * requestBodies: { * CreateUserRequest: (requestBody) => { * requestBody.required = true; * } * } */ requestBodies?: Record void>; /** * Patch OpenAPI responses in place. The key is the response name, and the function receives the response object to modify directly. * * @example * responses: { * NotFound: (response) => { * response.description = 'Resource not found.'; * } * } */ responses?: Record void>; /** * Each function receives the schema object to be modified in place. Common * use cases include fixing incorrect data types, removing unwanted * properties, adding missing fields, or standardizing date/time formats. * * Can be: * - `Record`: Patch specific named schemas * - `function`: Bulk callback receives `(name, schema)` for every schema * * Both patterns support async functions for operations like fetching data * from external sources or performing I/O. * * @example * ```js * // Named schemas * schemas: { * Foo: (schema) => { * // convert date-time format to timestamp * delete schema.properties.updatedAt.format; * schema.properties.updatedAt.type = 'number'; * }, * Bar: (schema) => { * // add missing property * schema.properties.metadata = { * additionalProperties: true, * type: 'object', * }; * schema.required = ['metadata']; * }, * Baz: (schema) => { * // remove property * delete schema.properties.internalField; * } * } * * // Bulk callback for all schemas * schemas: (name, schema) => { * const match = name.match(/_v(\d+)_(\d+)_(\d+)_/); * if (match) { * schema.description = (schema.description || '') + * `\n@version ${match[1]}.${match[2]}.${match[3]}`; * } * } * * // Async example - fetch metadata from external source * schemas: async (name, schema) => { * const metadata = await fetchSchemaMetadata(name); * if (metadata) { * schema.description = `${schema.description}\n\n${metadata.notes}`; * } * } * ``` */ schemas?: Record void | Promise> | ((name: string, schema: OpenApiSchemaObject.V2_0_X | OpenApiSchemaObject.V3_0_X | OpenApiSchemaObject.V3_1_X) => void | Promise); /** * Patch the OpenAPI version string. The function receives the current version and should return the new version string. * Useful for normalizing or overriding the version value before further processing. * * @param version The current OpenAPI version string. * @returns The new version string to use. * * @example * version: (version) => version.replace(/^v/, '') */ version?: MaybeFunc<(version: string) => string>; }; //#endregion //#region src/config/parser/types.d.ts type EnumsMode = 'inline' | 'root'; type UserParser = { /** * Filters can be used to select a subset of your input before it's passed * to plugins. */ filters?: Filters; /** * Optional hooks to override default plugin behavior. * * Use these to classify resources, control which outputs are generated, * or provide custom behavior for specific resources. */ hooks?: Hooks; /** * Pagination configuration. */ pagination?: { /** * Array of keywords to be considered as pagination field names. * These will be used to detect pagination fields in schemas and parameters. * * @default ['after', 'before', 'cursor', 'offset', 'page', 'start'] */ keywords?: ReadonlyArray; }; /** * Custom input transformations to execute before parsing. Use this * to modify, fix, or enhance input before it's passed to plugins. */ patch?: Patch; /** * Built-in transformations that modify or normalize the input before it's * passed to plugins. These options enable predictable, documented behaviors * and are distinct from custom patches. Use this to perform structural * changes to input in a standardized way. */ transforms?: { /** * Your input might contain two types of enums: * - enums defined as reusable components (root enums) * - non-reusable enums nested within other schemas (inline enums) * * You may want all enums to be reusable. This is because only root enums * are typically exported by plugins. Inline enums will never be directly * importable since they're nested inside other schemas. * * For example, to export nested enum types with the `@hey-api/typescript` * plugin, set `enums` to `root`. Likewise, if you don't want to export any * enum types, set `enums` to `inline`. * * @default false */ enums?: boolean | EnumsMode | { /** * Casing convention for generated names. * * @default 'PascalCase' */ case?: Casing; /** * Whether this feature is enabled. * * @default true */ enabled?: boolean; /** * Controls whether enums are promoted to reusable root components * ('root') or kept inline within schemas ('inline'). * * @default 'root' */ mode?: EnumsMode; /** * Customize the generated name of enums. * * @default '{{name}}Enum' */ name?: NameTransformer; }; /** * By default, any object schema with a missing `required` keyword is * interpreted as "no properties are required." This is the correct * behavior according to the OpenAPI standard. However, some specifications * interpret a missing `required` keyword as "all properties should be * required." * * This option allows you to change the default behavior so that * properties are required by default unless explicitly marked as optional. * * @default false */ propertiesRequiredByDefault?: boolean; /** * Your schemas might contain read-only or write-only fields. Using such * schemas directly could mean asking the user to provide a read-only * field in requests, or expecting a write-only field in responses. * * We separate schemas for requests and responses if direct usage * would result in such scenarios. You can still disable this * behavior if you prefer. * * @default true */ readWrite?: boolean | { /** * Whether this feature is enabled. * * @default true */ enabled?: boolean; /** * Configuration for generated request-specific schemas. * * Can be: * - `string` or `function`: Shorthand for `{ name: string | function }` * - `object`: Full configuration object * * @default '{{name}}Writable' */ requests?: NameTransformer | { /** * Casing convention for generated names. * * @default 'preserve' */ case?: Casing; /** * Customize the generated name of schemas used in requests or * containing write-only fields. * * @default '{{name}}Writable' */ name?: NameTransformer; }; /** * Configuration for generated response-specific schemas. * * Can be: * - `string` or `function`: Shorthand for `{ name: string | function }` * - `object`: Full configuration object * * @default '{{name}}' */ responses?: NameTransformer | { /** * Casing convention for generated names. * * @default 'preserve' */ case?: Casing; /** * Customize the generated name of schemas used in responses or * containing read-only fields. We default to the original name * to avoid breaking output when a read-only field is added. * * @default '{{name}}' */ name?: NameTransformer; }; }; /** * Sometimes your schema names are auto-generated or follow a naming convention * that produces verbose or awkward type names. You can rename schema component * keys throughout the specification, automatically updating all `$ref` pointers. * * @example * ```ts * { * schemaName: (name) => name.replace(/_v\d+_\d+_\d+_/, '_') * } * ``` * * @default undefined */ schemaName?: NameTransformer; }; /** * **This is an experimental feature.** * * Validate the input before generating output? This is an experimental, * lightweight feature and support will be added on an ad hoc basis. Setting * `validate_EXPERIMENTAL` to `true` is the same as `warn`. * * @default false */ validate_EXPERIMENTAL?: boolean | 'strict' | 'warn'; }; type Parser = { /** * Filters can be used to select a subset of your input before it's passed * to plugins. */ filters?: Filters; /** * Optional hooks to override default plugin behavior. * * Use these to classify resources, control which outputs are generated, * or provide custom behavior for specific resources. */ hooks: Hooks; /** * Pagination configuration. */ pagination: { /** * Array of keywords to be considered as pagination field names. * These will be used to detect pagination fields in schemas and parameters. * * @default ['after', 'before', 'cursor', 'offset', 'page', 'start'] */ keywords: ReadonlyArray; }; /** * Custom input transformations to execute before parsing. Use this * to modify, fix, or enhance input before it's passed to plugins. */ patch?: Patch; /** * Built-in transformations that modify or normalize the input before it's * passed to plugins. These options enable predictable, documented behaviors * and are distinct from custom patches. Use this to perform structural * changes to input in a standardized way. */ transforms: { /** * Your input might contain two types of enums: * - enums defined as reusable components (root enums) * - non-reusable enums nested within other schemas (inline enums) * * You may want all enums to be reusable. This is because only root enums * are typically exported by plugins. Inline enums will never be directly * importable since they're nested inside other schemas. * * For example, to export nested enum types with the `@hey-api/typescript` * plugin, set `enums` to `root`. Likewise, if you don't want to export any * enum types, set `enums` to `inline`. */ enums: NamingOptions & FeatureToggle & { /** * Controls whether enums are promoted to reusable root components * ('root') or kept inline within schemas ('inline'). * * @default 'root' */ mode: EnumsMode; }; /** * By default, any object schema with a missing `required` keyword is * interpreted as "no properties are required." This is the correct * behavior according to the OpenAPI standard. However, some specifications * interpret a missing `required` keyword as "all properties should be * required." * * This option allows you to change the default behavior so that * properties are required by default unless explicitly marked as optional. * * @default false */ propertiesRequiredByDefault: boolean; /** * Your schemas might contain read-only or write-only fields. Using such * schemas directly could mean asking the user to provide a read-only * field in requests, or expecting a write-only field in responses. * * We separate schemas for requests and responses if direct usage * would result in such scenarios. You can still disable this * behavior if you prefer. */ readWrite: FeatureToggle & { /** * Configuration for generated request-specific schemas. */ requests: NamingOptions; /** * Configuration for generated response-specific schemas. */ responses: NamingOptions; }; /** * Rename schema component keys and automatically update all `$ref` pointers * throughout the specification. * * @default undefined */ schemaName?: NameTransformer; }; /** * **This is an experimental feature.** * * Validate the input before generating output? This is an experimental, * lightweight feature and support will be added on an ad hoc basis. Setting * `validate_EXPERIMENTAL` to `true` is the same as `warn`. * * @default false */ validate_EXPERIMENTAL: false | 'strict' | 'warn'; }; //#endregion //#region src/config/presets.d.ts interface PresetPlugin { [key: string]: unknown; name: string; } interface Preset { /** Plugin configurations contributed by this preset. */ plugins?: ReadonlyArray; } //#endregion //#region src/config/shared.d.ts type FeatureToggle = { /** * Whether this feature is enabled. */ enabled: boolean; }; type UserIndexExportOption = { /** * Whether exports should be re-exported from the entry file. * * - `true` — include all exports * - `false` — exclude all exports * - `(symbol) => boolean` — include exports matching the predicate * * @default false * @deprecated use `includeInEntry` instead */ exportFromIndex?: boolean | ((symbol: Symbol) => boolean); /** * Whether exports should be re-exported from the entry file. * * - `true` — include all exports * - `false` — exclude all exports * - `(symbol) => boolean` — include exports matching the predicate * * @default false */ includeInEntry?: boolean | ((symbol: Symbol) => boolean); }; type IndexExportOption = { /** * Whether exports should be re-exported from the entry file. * * @deprecated use `includeInEntry` instead */ exportFromIndex: boolean | ((symbol: Symbol) => boolean); /** * Whether exports should be re-exported from the entry file. */ includeInEntry: boolean | ((symbol: Symbol) => boolean); }; type UserCommentsOption = { /** * Whether to add comments to the generated code. * * @default true */ comments?: boolean; }; type CommentsOption = { /** * Whether to add comments to the generated code. */ comments: boolean; }; type NamingOptions = { /** * Casing convention for generated names. */ case: Casing; /** * Naming pattern for generated names. */ name: NameTransformer; }; /** * Base output shape all packages must satisfy. */ interface BaseUserOutput { /** * Defines casing of the output fields. By default, we preserve `input` * values as data transforms incur a performance penalty at runtime. * * @default undefined */ case?: Casing; /** * Clean the `output` folder on every run? If disabled, this folder may * be used to store additional files. The default option is `true` to * reduce the risk of keeping outdated files around when configuration, * input, or package version changes. * * @default true */ clean?: boolean; /** * Whether to generate an entry file that re-exports symbols for convenient imports. * * Plugins control their inclusion via `includeInEntry`. * * @default true */ entryFile?: boolean; /** * Optional function to transform file names before they are used. * * @param name The original file name. * @returns The transformed file name. * @default '{{name}}' */ fileName?: NameTransformer | { /** * Casing convention for generated names. * * @default 'preserve' */ case?: Casing; /** * Naming pattern for generated names. * * @default '{{name}}' */ name?: NameTransformer; /** * Suffix to append to file names (before the extension). For example, * with a suffix of `.gen`, `example.ts` becomes `example.gen.ts`. * * @default '.gen' * @example * // Given a suffix of `.gen` * 'index.ts' -> 'index.ts' (index files are not renamed) * 'user.ts' -> 'user.gen.ts' * 'order.gen.ts' -> 'order.gen.ts' (files already containing the suffix are not renamed) */ suffix?: string | null; }; /** * Text to include at the top of every generated file. */ header?: OutputHeader; /** * Whether to generate an entry file that re-exports symbols for convenient imports. * * Plugins control their inclusion via `includeInEntry`. * * @default true * @deprecated use `entryFile` instead */ indexFile?: boolean; /** * Options for module specifier resolution. */ module?: { /** * If specified, this will be the extension used when importing other * modules. By default, we don't add an extension unless we detect that * you're using a module resolution strategy that requires one. * * @default undefined */ extension?: TModuleExtension | AnyString | null; /** * Function to transform module specifiers. * * @default undefined */ resolve?: ResolveModuleFn; }; /** * Optional name conflict resolver to customize how naming conflicts * are handled. */ nameConflictResolver?: NameConflictResolver; /** * The absolute path to the output folder. */ path: string; /** * Optional function to transform module specifiers. * * @default undefined * @deprecated use `module.resolve` instead */ resolveModuleName?: ResolveModuleFn; /** * Configuration for generating a copy of the input source used to produce this output. * * Set to `false` to skip generating the source, or `true` to use defaults. * * You can also provide a configuration object to further customize behavior. * * @default false */ source?: boolean | UserSourceConfig; } /** * Base output shape all packages must satisfy. */ interface BaseOutput { /** * Defines casing of the output fields. By default, we preserve `input` * values as data transforms incur a performance penalty at runtime. */ case: Casing | undefined; /** * Clean the `output` folder on every run? If disabled, this folder may * be used to store additional files. The default option is `true` to * reduce the risk of keeping outdated files around when configuration, * input, or package version changes. */ clean: boolean; /** Whether to generate an entry file that re-exports symbols for convenient imports. */ entryFile: boolean; /** * Optional function to transform file names before they are used. * * @param name The original file name. * @returns The transformed file name. */ fileName: NamingOptions & { /** * Suffix to append to file names (before the extension). For example, * with a suffix of `.gen`, `example.ts` becomes `example.gen.ts`. * * @example * // Given a suffix of `.gen` * 'index.ts' -> 'index.ts' (index files are not renamed) * 'user.ts' -> 'user.gen.ts' * 'order.gen.ts' -> 'order.gen.ts' (files already containing the suffix are not renamed) */ suffix: string | null; }; /** Text to include at the top of every generated file. */ header: OutputHeader; /** * Whether to generate an entry file that re-exports symbols for convenient imports. * * @deprecated use `entryFile` instead */ indexFile: boolean; /** Options for module specifier resolution. */ module: { /** The extension used when importing other modules. */extension: TModuleExtension | AnyString | null; /** Function to transform module specifiers. */ resolve: ResolveModuleFn | undefined; }; /** Name conflict resolver to customize how naming conflicts are handled. */ nameConflictResolver: NameConflictResolver | undefined; /** The absolute path to the output folder. */ path: string; /** Post-processing commands to run on the output folder, executed in order. */ postProcess: ReadonlyArray; /** Configuration for generating a copy of the input source used to produce this output. */ source: SourceConfig; } /** * Core configuration shared across all packages. */ type BaseUserConfig = { /** * Path to the config file. Set this value if you don't use the default * config file name, or it's not located in the project root. * * @default undefined */ configFile?: string; /** * Skip writing files to disk? * * @default false */ dryRun?: boolean; /** * Path to the OpenAPI specification. This can be: * - path * - URL * - API registry shorthand * * Both JSON and YAML file formats are supported. You can also pass the parsed * object directly if you're fetching the file yourself. * * Alternatively, you can define a configuration object with more options. * * If you define an array, we will generate a single output from multiple * inputs. If you define an array of outputs with the same length, we will * generate multiple outputs, one for each input. */ input: MaybeArray['path']>; /** * Show an interactive error reporting tool when the program crashes? You * generally want to keep this disabled (default). * * @default false */ interactive?: boolean; /** * The relative location of the logs folder. * * @default process.cwd() */ logs?: string | Logs; /** * Path to the output folder. * * If you define an array of outputs with the same length as inputs, we will * generate multiple outputs, one for each input. */ output: MaybeArray; /** * Customize how the input is parsed and transformed before it's passed to * plugins. * * @default undefined */ parser?: UserParser; /** * Configuration presets. * * @default [] */ presets?: ReadonlyArray; /** * @deprecated use `input.watch` instead */ watch?: UserWatch; }; /** * Core configuration shared across all packages. */ type BaseConfig = Omit, 'input' | 'logs' | 'output' | 'parser' | 'plugins' | 'watch'> & { /** * Path to the input specification. */ input: ReadonlyArray; logs: Logs; /** * Path to the output folder. */ output: TOutput; /** * Customize how the input is parsed and transformed before it's passed to * plugins. */ parser: Parser; pluginOrder: ReadonlyArray; plugins: Record | undefined>; }; /** * For shared utilities that operate on any config. */ type AnyConfig = BaseConfig, BaseOutput>; /** * Function to transform module specifiers. */ type ResolveModuleFn = (path: string, ctx: RenderContext) => string | undefined; //#endregion //#region src/config/output/source/types.d.ts type SourceExtension = 'json'; type UserSourceConfig = { /** * Callback invoked with the serialized source string. * * Runs after the `serialize` function. * * @example * source => console.log(source) */ callback?: (source: string) => MaybePromise; /** * Whether this feature is enabled. * * @default true */ enabled?: boolean; /** * File extension for the source file. * * @default 'json' */ extension?: SourceExtension; /** * Base file name for the source file. * * The extension from `extension` will be appended automatically. * * @default 'source' */ fileName?: string; /** * Target location for the source file. * * - `true` / `undefined` → write to output root (default) * - `string` → relative to output root or absolute path * - `false` / `null` → do not write * * @default true */ path?: boolean | string | null; /** * Function to serialize the input object into a string. * * @default * JSON.stringify(input, null, 2) * * @example * input => JSON.stringify(input, null, 0) // minified */ serialize?: (input: Record) => MaybePromise; }; type SourceConfig = FeatureToggle & { /** * Callback invoked with the serialized source string. * * Runs after the `serialize` function. */ callback?: (source: string) => MaybePromise; /** * File extension for the source file. */ extension: SourceExtension; /** * Base file name for the source file. */ fileName: string; /** * Target location for the source file. */ path: string | null; /** * Function to serialize the input object into a string. */ serialize: (input: Record) => MaybePromise; }; //#endregion //#region src/config/output/source/config.d.ts declare const sourceConfig: ConfigNormalizer; //#endregion //#region src/config/parser/config.d.ts declare const defaultPaginationKeywords: readonly ["after", "before", "cursor", "offset", "page", "start"]; declare function getParser(input: { parser?: UserParser; }): Parser; //#endregion //#region src/debug/ir.d.ts interface PrintOptions { /** * Indentation depth for `JSON.stringify()` when printing objects. * * @default 2 */ depth?: number; /** * Which section of the IR to print. Use 'all' to print every section. * * @default 'all' */ section?: keyof IR.Model | 'all'; /** * How much detail to print. * * - `summary` → only keys, names, operationIds, status codes * - `full` → dump full JSON structures * * @default 'summary' */ verbosity?: 'full' | 'summary'; } //#endregion //#region src/debug/index.d.ts declare const debugTools: { graph: { readonly analyzeStructure: (graph: Graph) => { maxChildren: number; maxDepth: number; totalNodes: number; }; readonly exportForVisualization: (graph: Graph) => { children: number; childrenPointers: string[]; pointer: string; }[]; }; ir: { readonly print: (ir: IR.Model, options?: PrintOptions) => void; }; }; //#endregion //#region src/error.d.ts type IJobError = { error: Error; jobIndex: number; }; /** * Represents a single configuration error. * * Used for reporting issues with a specific config instance. */ declare class ConfigError extends Error { constructor(message: string); } /** * Aggregates multiple config errors with their job indices for reporting. */ declare class ConfigValidationError extends Error { readonly errors: ReadonlyArray; constructor(errors: Array); } /** * Represents an error caused by invalid or inaccessible input. * * Used for errors like file not found, URL not reachable, etc. */ declare class InputError extends Error { readonly originalError: Error & { source?: string; }; constructor(message: string, originalError: Error & { source?: string; }); } /** * Represents a runtime error originating from a specific job. * * Used for reporting job-level failures that are not config validation errors. */ declare class JobError extends Error { readonly originalError: IJobError; constructor(message: string, error: IJobError); } declare class HeyApiError extends Error { args: ReadonlyArray; event: string; pluginName: string; constructor({ args, error, event, name, pluginName }: { args: unknown[]; error: Error; event: string; name: string; pluginName: string; }); } declare function logCrashReport(error: unknown, logsDir: string): string | undefined; declare function openGitHubIssueWithCrashReport(error: unknown, initialDir: string): Promise; declare function getInputError(error: unknown): InputError | undefined; declare function printCrashReport({ error, logPath }: { error: unknown; logPath: string | undefined; }): void; declare function shouldReportCrash({ error, isInteractive }: { error: unknown; isInteractive: boolean | undefined; }): Promise; //#endregion //#region src/fs.d.ts declare function ensureDirSync(path: PathLike): void; //#endregion //#region src/types/watch.d.ts type WatchValues = { /** * Headers to be sent with each HEAD and/or GET request. This effectively * serves as a mechanism resolver because setting certain headers will opt * into comparing the specifications using that method. */ headers: Headers; /** * Can we send a HEAD request instead of fetching the whole specification? * This value will be set after the first successful fetch. */ isHeadMethodSupported?: boolean; /** * String content of the last successfully fetched specification. */ lastValue?: string; }; //#endregion //#region src/getSpec.d.ts type SpecResponse = { arrayBuffer: ArrayBuffer | undefined; error?: never; resolvedInput: ReturnType; response?: never; }; type SpecError = { arrayBuffer?: never; error: 'not-modified' | 'not-ok'; resolvedInput?: never; response: Response; }; /** * @internal */ declare function getSpec({ fetchOptions, inputPath, timeout, watch }: { fetchOptions?: RequestInit; inputPath: Input['path']; timeout: number | undefined; watch: WatchValues; }): Promise; //#endregion //#region src/ir/pagination.d.ts interface Pagination { in: 'body' | 'cookie' | 'header' | 'path' | 'query'; name: string; schema: IR.SchemaObject; } //#endregion //#region src/ir/operation.d.ts declare function hasOperationDataRequired(operation: IR.OperationObject): boolean; declare function createOperationKey({ method, path }: { method: string; path: string; }): string; declare function operationPagination({ context, operation }: { context: Context; operation: IR.OperationObject; }): Pagination | undefined; type StatusGroup = '1XX' | '2XX' | '3XX' | '4XX' | '5XX' | 'default'; declare function statusCodeToGroup({ statusCode }: { statusCode: string; }): StatusGroup; interface OperationResponsesMap { /** * A deduplicated union of all error types. Unknown types are omitted. */ error?: IR.SchemaObject; /** * An object containing a map of status codes for each error type. */ errors?: IR.SchemaObject; /** * A deduplicated union of all response types. Unknown types are omitted. */ response?: IR.SchemaObject; /** * An object containing a map of status codes for each response type. */ responses?: IR.SchemaObject; } declare function operationResponsesMap(operation: IR.OperationObject): OperationResponsesMap; //#endregion //#region src/ir/parameter.d.ts declare function hasParameterGroupObjectRequired(parameterGroup?: Record): boolean; declare function hasParametersObjectRequired(parameters: IR.ParametersObject | undefined): boolean; declare function parameterWithPagination({ context, parameters }: { context: Context; parameters: IR.ParametersObject | undefined; }): Pagination | undefined; //#endregion //#region src/ir/schema.d.ts /** * Ensure we don't produce redundant types, e.g., string | string. */ declare function deduplicateSchema({ detectFormat, schema }: { detectFormat?: boolean; schema: T; }): T; //#endregion //#region src/plugins/shared/types/schema.d.ts type SchemaWithType['type'] = Required['type']> = Omit & { type: Extract['type'], T>; }; //#endregion //#region src/ir/schema-walker.d.ts /** * Context passed to all visitor methods. */ interface SchemaVisitorContext { /** Current path in the schema tree. */ path: Ref>; /** The plugin instance. */ plugin: TPlugin; } /** * The walk function signature. Fully generic over TResult. */ type Walker = (schema: IR.SchemaObject, ctx: SchemaVisitorContext) => TResult; /** * The visitor interface. Plugins define their own TResult type. * * The walker handles orchestration (dispatch, deduplication, path tracking). * Result shape and semantics are entirely plugin-defined. */ interface SchemaVisitor { /** * Apply modifiers to a result. */ applyModifiers(result: TResult, ctx: SchemaVisitorContext, context?: { /** Is this property optional? */optional?: boolean; }): unknown; array(schema: SchemaWithType<'array'>, ctx: SchemaVisitorContext, walk: Walker): TResult; boolean(schema: SchemaWithType<'boolean'>, ctx: SchemaVisitorContext): TResult; enum(schema: SchemaWithType<'enum'>, ctx: SchemaVisitorContext, walk: Walker): TResult; integer(schema: SchemaWithType<'integer'>, ctx: SchemaVisitorContext): TResult; /** * Called before any dispatch logic. Return a result to short-circuit, * or undefined to continue normal dispatch. */ intercept?(schema: IR.SchemaObject, ctx: SchemaVisitorContext, walk: Walker): TResult | undefined; /** * Handle intersection types. Receives already-walked child results. */ intersection(items: Array, schemas: ReadonlyArray, parentSchema: IR.SchemaObject, ctx: SchemaVisitorContext): TResult; never(schema: SchemaWithType<'never'>, ctx: SchemaVisitorContext): TResult; null(schema: SchemaWithType<'null'>, ctx: SchemaVisitorContext): TResult; number(schema: SchemaWithType<'number'>, ctx: SchemaVisitorContext): TResult; object(schema: SchemaWithType<'object'>, ctx: SchemaVisitorContext, walk: Walker): TResult; /** * Called after each typed schema visitor returns. */ postProcess?(result: TResult, schema: IR.SchemaObject, ctx: SchemaVisitorContext): TResult; /** * Handle $ref to another schema. */ reference($ref: string, schema: IR.SchemaObject, ctx: SchemaVisitorContext): TResult; string(schema: SchemaWithType<'string'>, ctx: SchemaVisitorContext): TResult; tuple(schema: SchemaWithType<'tuple'>, ctx: SchemaVisitorContext, walk: Walker): TResult; undefined(schema: SchemaWithType<'undefined'>, ctx: SchemaVisitorContext): TResult; /** * Handle union types. Receives already-walked child results. */ union(items: Array, schemas: ReadonlyArray, parentSchema: IR.SchemaObject, ctx: SchemaVisitorContext): TResult; unknown(schema: SchemaWithType<'unknown'>, ctx: SchemaVisitorContext): TResult; void(schema: SchemaWithType<'void'>, ctx: SchemaVisitorContext): TResult; } /** * Create a schema walker from a visitor. * * The walker handles: * - Dispatch order ($ref → type → items → fallback) * - Deduplication of union/intersection schemas * - Path tracking for child schemas */ declare function createSchemaWalker(visitor: SchemaVisitor): Walker; /** * Helper to create a child context with an extended path. */ declare function childContext(ctx: SchemaVisitorContext, ...segments: ReadonlyArray): SchemaVisitorContext; //#endregion //#region src/ir/utils.d.ts /** * Simply adds `items` to the schema. Also handles setting the logical operator * and avoids setting it for a single item or tuples. */ declare function addItemsToSchema({ items, logicalOperator, mutateSchemaOneItem, schema }: { items: Array; logicalOperator?: IR.SchemaObject['logicalOperator']; mutateSchemaOneItem?: boolean; schema: IR.SchemaObject; }): IR.SchemaObject; //#endregion //#region src/openApi/index.d.ts /** * @internal * Parse the resolved OpenAPI specification. This will populate and return * `context` with intermediate representation obtained from the parsed spec. */ declare function parseOpenApiSpec(context: Context): Context; //#endregion //#region src/openApi/2.0.x/parser/index.d.ts declare const parseV2_0_X: (context: Context) => void; //#endregion //#region src/openApi/3.0.x/parser/index.d.ts declare const parseV3_0_X: (context: Context) => void; //#endregion //#region src/openApi/3.1.x/parser/index.d.ts declare const parseV3_1_X: (context: Context) => void; //#endregion //#region src/openApi/shared/locations/operation.d.ts /** * A function that derives path segments from an operation. * * Used by location strategies to build paths within containers. */ type OperationPathStrategy = (operation: IR.OperationObject) => ReadonlyArray; /** * A function that determines where an operation appears in the structure. * * Returns one or more locations, each with a full path. */ type OperationStructureStrategy = (operation: IR.OperationObject) => ReadonlyArray; type OperationsStrategy = 'byTags' | 'flat' | 'single' | OperationStructureStrategy; /** * Built-in strategies for operations. */ declare const OperationStrategy: { /** * Creates one root container per operation tag. * * Operations with multiple tags appear in multiple root containers. * Operations without tags use the fallback root container. * * @example * // Operation with tags: ['users', 'admin'] * // Path function returns: ['list'] * // Result: [{ path: ['users', 'list'], shell }, { path: ['admin', 'list'], shell }] */ byTags: (config: { /** * Root name for operations without tags. */ fallback: string; /** * Derives path segments from the operation. * * @default OperationPath.id() */ path?: OperationPathStrategy; }) => OperationStructureStrategy; /** * Creates flat functions without any container. * * Each operation becomes a standalone function at the root level. * No shell is applied. * * @example * // Operation id: 'getUsers' * // Result: [{ path: ['getUsers'] }] */ flat: (config?: { /** * Derives path segments within the root from the operation. * * @default OperationPath.id() */ path?: OperationPathStrategy; }) => OperationStructureStrategy; /** * Places all operations under a single root container. * * @example * // Root: 'Sdk', path function returns: ['users', 'list'] * // Result: [{ path: ['Sdk', 'users', 'list'], shell }] */ single: (config: { /** * Derives path segments within the root from the operation. * * @default OperationPath.id() */ path?: OperationPathStrategy; /** * Name of the container. */ root: string; }) => OperationStructureStrategy; }; /** * Built-in path derivation helpers for operations. */ declare const OperationPath: { /** * Splits operationId by delimiters to create nested paths. * * @example * // operationId: 'users.accounts.list' * // Result: ['users', 'accounts', 'list'] * * @example * // operationId: 'users/accounts/getAll' * // Result: ['users', 'accounts', 'getAll'] */ fromOperationId: (config?: { /** * Pattern to split operationId. * * @default /[./]/ */ delimiters?: RegExp; /** * Fallback strategy if operationId is missing. * * @default OperationPath.id() */ fallback?: OperationPathStrategy; }) => OperationPathStrategy; /** * Splits path by delimiters to create nested paths. * * Can include the method as a prefix or suffix segment. * * @example * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'none' * // Result: ['users', 'id', 'accounts'] * * @example * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'prefix' * // Result: ['get', 'users', 'id', 'accounts'] * * @example * // path: '/users/{id}/accounts', method: 'get', delimiters: /[\/{}]+/, methodPosition: 'suffix' * // Result: ['users', 'id', 'accounts', 'get'] */ fromPath: (config?: { /** * Pattern to split the path. * * @default /[./]/ */ delimiters?: RegExp; /** * Position of the method segment. * * @default 'none' */ methodPosition?: "prefix" | "suffix"; }) => OperationPathStrategy; /** * Uses operation.id as a single path segment. * * @example * // operation.id: 'getUserById' * // Result: ['getUserById'] */ id: () => OperationPathStrategy; }; //#endregion //#region src/openApi/shared/utils/discriminator.d.ts /** * Supported types for discriminator properties. */ type DiscriminatorPropertyType = 'boolean' | 'integer' | 'number' | 'string'; /** * Converts a string discriminator mapping value to the appropriate type based on * the actual property type in the schema. * * OpenAPI discriminator mappings always use string keys, but the actual discriminator * property may be a boolean, number, or integer. This function converts the string * key to the correct runtime value and IR type. */ declare function convertDiscriminatorValue(value: string, propertyType: DiscriminatorPropertyType): { const: IR.SchemaObject['const']; type: IR.SchemaObject['type']; }; declare function discriminatorValues($ref: string, mapping?: Record, shouldUseRefAsValue?: () => boolean): ReadonlyArray; interface DiscriminatedUnionMember { /** The discriminator value for this member. */ discriminatedValue: unknown; /** * True when the referenced schema does not already define the discriminator * property as a const/literal. The plugin must inject it explicitly. */ needsExtend: boolean; /** The resolved $ref string for this member. */ ref: string; } interface DiscriminatedUnionData { discriminatorKey: string; members: Array; } declare function buildDiscriminatedUnion({ parentSchema, resolveIrRef, schemas }: { parentSchema: IR.SchemaObject; resolveIrRef: (ref: string) => IR.SchemaObject | undefined; schemas: ReadonlyArray; }): DiscriminatedUnionData | null; //#endregion //#region src/openApi/shared/utils/patch.d.ts declare function patchOpenApiSpec({ patchOptions, spec: _spec }: { patchOptions: Patch | undefined; spec: unknown; }): Promise; //#endregion //#region src/plugins/config.d.ts declare function definePluginConfig(pluginConfig: Plugin.Config): (userConfig?: Omit) => { config: Plugin.Config["config"]; /** * Cast name to `any` so it doesn't throw type error in `plugins` array. * We could allow any `string` as plugin `name` in the object syntax, but * that TypeScript trick would cause all string methods to appear as * suggested auto completions, which is undesirable. */ name: any; api?: T["api"] | undefined; dependencies?: ReadonlyArray; handler: (args: { plugin: PluginInstance; }) => void; imports?: ((plugin: PluginInstance) => T["imports"]) | undefined; symbolMeta?: (symbol: Omit) => log; tags?: ReadonlyArray; }; interface PluginResolutionInput { /** Registry of built-in plugin definitions keyed by name. */ defaultPluginConfigs: Partial>; /** Plugins to include when the user doesn't specify any. */ defaultPlugins: ReadonlyArray; /** Resolved project dependencies. */ dependencies: Record; /** Raw user configuration (only the `plugins` field is read). */ userConfig: { plugins?: ReadonlyArray; presets?: ReadonlyArray; }; } interface PluginResolutionResult { pluginOrder: ReadonlyArray; plugins: Record; } declare function resolvePlugins({ defaultPluginConfigs, defaultPlugins, dependencies, userConfig }: PluginResolutionInput): PluginResolutionResult; //#endregion //#region src/plugins/helper.d.ts type PluginConfig = PluginConfigMap[K]['config'] & { name: K; }; type PluginHelper = (config?: Omit) => PluginConfig; declare function pluginHelper(name: K): PluginHelper; //#endregion //#region src/plugins/symbol.d.ts /** * Function to build the input for symbol registration, applying naming hooks if provided. */ declare function buildSymbolIn({ plugin, ...ctx }: GetNameContext & { plugin: { getHooks: PluginInstance['getHooks']; }; }): SymbolIn; //#endregion //#region src/plugins/validator.d.ts /** * Configuration for a single validator layer (e.g. body, headers, path, query). */ interface RequestValidatorLayer { /** * Output property name in the composite schema. * * @default Same as the layer name ('body', 'path', 'query') */ as?: string; /** * Wrap the layer schema in an optional modifier. * * @default true */ optional?: boolean; /** * Behavior when this layer has no schema defined. * * Can be: * - `'strict'` — Generate a schema that rejects any value * - `'passthrough'` — Generate a schema that accepts any object * - `'omit'` — Exclude this property from the composite shape * * @default 'strict' */ whenEmpty?: 'strict' | 'passthrough' | 'omit'; } /** * A {@link RequestValidatorLayer} with all optional properties resolved to their required form. */ type ResolvedRequestValidatorLayer = Required; /** * A map from a set of layer keys to optional layer configuration objects. * * @template Keys - The union of layer key names. * @template Layer - The shape of an individual layer configuration. */ type ValidatorLayers = { [K in Keys]?: Layer }; /** * A map from a set of layer keys to fully-resolved (required) layer configuration objects. * Represents the default fallback values used when a layer is not explicitly configured. * * @template Keys - The union of layer key names. * @template Layer - The shape of an individual layer configuration. */ type DefaultValidatorLayers = { [K in Keys]: Required }; /** * The ordered list of standard HTTP request layer keys. */ declare const requestValidatorLayers: readonly ["body", "headers", "path", "query"]; /** * Optional per-layer configuration for the standard HTTP request layers * (body, headers, path, query). */ type RequestValidatorLayers = ValidatorLayers<(typeof requestValidatorLayers)[number], RequestValidatorLayer>; /** * Required default configuration for all standard HTTP request layers * (body, headers, path, query). */ type DefaultRequestValidatorLayers = DefaultValidatorLayers<(typeof requestValidatorLayers)[number], RequestValidatorLayer>; /** * Context passed to request schema helpers. * * @template Plugin - The plugin instance type. */ interface RequestSchemaContext { /** * Per-layer configuration. Omitted layers use defaults. * * @default { body: {}, headers: {}, path: {}, query: {} } */ layers?: RequestValidatorLayers; /** The operation object. */ operation: IR.OperationObject; /** * When `true` and every non-omitted layer is optional, wrap the entire * composite schema in an outer optional wrapper. */ outerOptional?: boolean; /** The plugin instance. */ plugin: Plugin; } /** * Resolves the effective configuration for a single layer by merging the * layer's defaults with any explicit overrides supplied in `layers`. * * @param layers - Optional map of per-layer overrides. * @param key - The layer key to resolve. * @param defaultValues - Required fallback values for every layer key. * @returns The fully-resolved layer configuration. */ declare function resolveValidatorLayer, Key extends keyof Layers>(layers: Layers | undefined, key: Key, defaultValues: { [K in keyof Layers]-?: Required> }): Required>; //#endregion //#region src/tsConfig.d.ts declare function findPackageJson(initialDir: string): unknown | undefined; type PackageJson = { bugs: { url: string; }; name: string; version: string; }; declare function loadPackageJson(initialDir: string): PackageJson | undefined; declare function findTsConfigPath(baseDir: string, tsConfigPath?: AnyString | null): string | null; //#endregion //#region src/utils/escape.d.ts declare function escapeComment(value: string): string; //#endregion //#region src/utils/naming/naming.d.ts /** * Convert a string to the specified casing. * * @param value - The string to convert * @param casing - The target casing * @param options - Additional options * @returns The converted string */ declare function toCase(value: string, casing: Casing | undefined, options?: { /** * If leading separators have a semantic meaning, we might not want to * remove them. */ stripLeadingSeparators?: boolean; }): string; /** * Normalize a NamingRule to NamingConfig. */ declare function resolveNaming(rule: NamingRule | undefined): NamingConfig; /** * Apply naming configuration to a value. * * Casing is applied first, then transformation. */ declare function applyNaming(value: string, config: NamingConfig): string; //#endregion //#region src/utils/exports.d.ts /** * Utilities shared across the package. */ declare const utils: { /** * @deprecated use `toCase` instead */ stringCase({ case: casing, stripLeadingSeparators, value }: { readonly case: Casing | undefined; /** * If leading separators have a semantic meaning, we might not want to * remove them. */ stripLeadingSeparators?: boolean; value: string; }): string; /** * Converts the given string to the specified casing. */ toCase: typeof toCase; }; //#endregion //#region src/utils/header.d.ts /** * Converts an {@link OutputHeader} value to a string prefix for file content. */ declare function outputHeaderToPrefix(ctx: { defaultValue: ReadonlyArray; header: OutputHeader; project: IProject; }): string; //#endregion //#region src/utils/input/index.d.ts declare function inputToApiRegistry(input: Input & { path: string; }): void; //#endregion //#region src/utils/input/heyApi.d.ts declare const heyApiRegistryBaseUrl = "https://get.heyapi.dev"; //#endregion //#region src/utils/minHeap.d.ts declare class MinHeap { declIndex: Map; private heap; constructor(declIndex: Map); isEmpty(): boolean; pop(): string | undefined; push(item: string): void; private bubbleUp; private sinkDown; } //#endregion //#region src/utils/object.d.ts declare function isPlainObject(value: unknown): value is Record; declare function deepMerge>(target: T, source: T): T; //#endregion //#region src/utils/path.d.ts interface PathToNameOptions { /** * When provided, replaces the root semantic segments with this anchor. * Structural suffixes are still derived from path. */ anchor?: string; } /** * Derives a composite name from a path. * * Examples: * .../User → 'User' * .../User/properties/address → 'UserAddress' * .../User/properties/properties → 'UserProperties' * .../User/properties/address/properties/city → 'UserAddressCity' * .../Pet/additionalProperties → 'PetValue' * .../Order/properties/items/items/0 → 'OrderItems' * paths//event/get/properties/query → 'EventGetQuery' * * With anchor: * paths//event/get/properties/query, { anchor: 'event.subscribe' } * → 'event.subscribe-Query' */ declare function pathToName(path: ReadonlyArray, options?: PathToNameOptions): string; //#endregion //#region src/utils/ref.d.ts /** * Returns the reusable component name from `$ref`. */ declare function refToName($ref: string): string; /** * Encodes a path segment for use in a JSON Pointer (RFC 6901). * * - Replaces all '~' with '~0'. * - Replaces all '/' with '~1'. * * This ensures that path segments containing these characters are safely * represented in JSON Pointer strings. * * @param segment - The path segment (string or number) to encode. * @returns The encoded segment as a string. */ declare function encodeJsonPointerSegment(segment: string | number): string; /** * Converts a JSON Pointer string (RFC 6901) to an array of path segments. * * - Removes the leading '#' if present. * - Splits the pointer on '/'. * - Decodes '~1' to '/' and '~0' to '~' in each segment. * - Returns an empty array for the root pointer ('#' or ''). * * @param pointer - The JSON Pointer string to convert (e.g., '#/components/schemas/Foo'). * @returns An array of decoded path segments. */ declare function jsonPointerToPath(pointer: string): ReadonlyArray; /** * Normalizes a JSON Pointer string to a canonical form. * * - Ensures the pointer starts with '#'. * - Removes trailing slashes (except for root). * - Collapses multiple consecutive slashes into one. * - Trims whitespace from the input. * * @param pointer - The JSON Pointer string to normalize. * @returns The normalized JSON Pointer string. */ declare function normalizeJsonPointer(pointer: string): string; /** * Encode path as JSON Pointer (RFC 6901). * * @param path * @returns */ declare function pathToJsonPointer(path: ReadonlyArray): string; /** * Checks if a $ref or path points to a top-level component (not a deep path reference). * * Top-level component references: * - OpenAPI 3.x: #/components/{type}/{name} (3 segments) * - OpenAPI 2.0: #/definitions/{name} (2 segments) * * Deep path references (4+ segments for 3.x, 3+ for 2.0) should be inlined * because they don't have corresponding registered symbols. * * @param refOrPath - The $ref string or path array to check * @returns true if the ref points to a top-level component, false otherwise */ declare function isTopLevelComponent(refOrPath: string | ReadonlyArray): boolean; declare function resolveRef({ $ref, spec }: { $ref: string; spec: Record; }): T; //#endregion //#region src/utils/url.d.ts interface Url { host: string; path: string; port: string; protocol: string; } /** * Resolve the base URL string if it's a valid URL or path. */ declare function getBaseUrl(config: string | number | boolean, ir: IR.Model): string | undefined; declare function parseUrl(value: string): Url; //#endregion export { type AnyConfig, type AnyPluginName, type BaseConfig, type BaseOutput, type BaseUserConfig, type BaseUserOutput, COERCER, type Casing, type Coercer, type CoercerMap, type CommentsOption, ConfigError, type ConfigNormalizer, type ConfigTable, ConfigValidationError, Context, type DefaultRequestValidatorLayers, type DefaultValidatorLayers, type DefinePlugin, type Dependency, type DiscriminatedUnionData, type DiscriminatedUnionMember, type DiscriminatorPropertyType, type EventHooks, type FeatureToggle, type Filters, type GetNameContext, HeyApiError, type Hooks, type IR, type IRModel, type IROperationObject, type IRParameterObject, type IRParametersObject, type IRSchemaObject, type IRServerObject, type IndexExportOption, type Input, InputError, IntentContext, JobError, type LogLevel, type Logs, MinHeap, type NameTransformer, type NamingConfig, type NamingOptions, type NamingRule, type OpenApi, type OpenApiMetaObject, type OpenApiOperationObject, type OpenApiParameterObject, type OpenApiRequestBodyObject, type OpenApiResponseObject, type OpenApiSchemaObject, OperationPath, type OperationPathStrategy, OperationStrategy, type OperationStructureStrategy, type OperationsStrategy, type OutputHeader, type Parser, type Patch, type Plugin, type PluginConfigMap, type PluginContext, type PluginImports, PluginInstance, type PluginInstanceTypes, type PluginNames, type PluginResolutionInput, type PluginResolutionResult, type PluginTag, type PostProcessor, type Preset, type PresetPlugin, type RequestSchemaContext, type RequestValidatorLayer, type RequestValidatorLayers, type ResolveModuleFn, type ResolvedNode, type ResolvedRequestValidatorLayer, type SchemaExtractor, type SchemaProcessor, type SchemaProcessorContext, type SchemaProcessorResult, type SchemaVisitor, type SchemaVisitorContext, type SchemaWithType, type SourceConfig, SymbolFactory, type TableDirectives, type UserCommentsOption, type UserIndexExportOption, type UserInput, type UserParser, type UserPostProcessor, type UserSourceConfig, type UserWatch, type ValidatorLayers, type Walker, type Watch, type WatchValues, type WithCoercers, addItemsToSchema, applyNaming, buildDiscriminatedUnion, buildGraph, buildSymbolIn, checkNodeVersion, childContext, coerce, collectDeps, compileInputPath, convertDiscriminatorValue, createOperationKey, createSchemaProcessor, createSchemaWalker, debugTools, deduplicateSchema, deepMerge, defaultPaginationKeywords, defineConfig, definePluginConfig, dependencyFactory, discriminatorValues, encodeJsonPointerSegment, ensureDirSync, escapeComment, findPackageJson, findTsConfigPath, getBaseUrl, getInput, getInputError, getLogs, getParser, getSpec, hasOperationDataRequired, hasParameterGroupObjectRequired, hasParametersObjectRequired, heyApiRegistryBaseUrl, inputToApiRegistry, isCoercer, isEnvironment, isPlainObject, isTopLevelComponent, jsonPointerToPath, loadPackageJson, logCrashReport, logInputPaths, normalizeJsonPointer, openGitHubIssueWithCrashReport, operationPagination, operationResponsesMap, outputHeaderToPrefix, parameterWithPagination, parseOpenApiSpec, parseUrl, parseV2_0_X, parseV3_0_X, parseV3_1_X, patchOpenApiSpec, pathToJsonPointer, pathToName, pluginHelper, postprocessOutput, printCliIntro, printCrashReport, refToName, requestValidatorLayers, resolveNaming, resolvePlugins, resolveRef, resolveValidatorLayer, satisfies, shouldReportCrash, sourceConfig, statusCodeToGroup, toCase, utils }; //# sourceMappingURL=index.d.mts.map