🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@kubb/ast

Package Overview
Dependencies
Maintainers
1
Versions
191
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kubb/ast - npm Package Compare versions

Comparing version
5.0.0-beta.79
to
5.0.0-beta.80
+259
dist/types-CWF7DV0f.d.ts
import { n as __name } from "./rolldown-runtime-CNktS9qV.js";
import { et as SchemaNode, nt as SchemaType, tt as SchemaNodeByType } from "./index-Cu2zmNxv.js";
//#region src/defineDialect.d.ts
/**
* The spec-specific questions a schema parser answers while turning a source document into Kubb
* AST nodes. The rest of the pipeline is generic, so this is the one seam where source formats
* differ.
*/
type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
/**
* Whether the schema is nullable.
*/
isNullable(schema?: TSchema): boolean;
/**
* Whether the value is a `$ref` pointer.
*/
isReference(value?: unknown): value is TRef;
/**
* Whether the schema carries a discriminator for polymorphism.
*/
isDiscriminator(value?: unknown): value is TDiscriminated;
/**
* Whether the schema is binary data, converted to a `blob` node.
*/
isBinary(schema: TSchema): boolean;
/**
* Resolves a local `$ref` against the document, or nullish when it cannot.
*/
resolveRef<TResolved>(document: TDocument, ref: string): TResolved | null | undefined;
};
/**
* A spec adapter's dialect. `name` identifies it in logs and diagnostics, and `schema` holds the
* spec-specific schema questions the parser answers.
*/
type Dialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
/**
* Identifies the dialect in logs and diagnostics.
*/
name: string;
/**
* The spec-specific schema behavior. See {@link SchemaDialect}.
*/
schema: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>;
};
/**
* Types a {@link Dialect} for an adapter. Adds no runtime behavior and only pins the
* dialect's type for inference.
*
* @example
* ```ts
* export const oasDialect = defineDialect({
* name: 'oas',
* schema: {
* isNullable,
* isReference,
* isDiscriminator,
* isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
* resolveRef,
* },
* })
* ```
*/
declare function defineDialect<TSchema, TRef, TDiscriminated, TDocument>(dialect: Dialect<TSchema, TRef, TDiscriminated, TDocument>): Dialect<TSchema, TRef, TDiscriminated, TDocument>;
//#endregion
//#region src/createPrinter.d.ts
/**
* Runtime context passed as `this` to printer handlers.
*
* `this.transform` dispatches to node-level handlers from `nodes`.
*
* @example
* ```ts
* const context: PrinterHandlerContext<string, {}> = {
* options: {},
* transform: () => 'value',
* }
* ```
*/
type PrinterHandlerContext<TOutput, TOptions extends object> = {
/**
* Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.
* Use `this.transform` inside `nodes` handlers and inside the `print` override.
*/
transform: (node: SchemaNode) => TOutput | null;
/**
* Run the printer's built-in handler for the node, ignoring any override for its type.
* Inside an override, `this.base(node)` returns what the printer would have emitted,
* so the override can wrap it instead of re-implementing the handler. Nested nodes
* still dispatch through the overrides.
*/
base: (node: SchemaNode) => TOutput | null;
/**
* Options for this printer instance.
*/
options: TOptions;
};
/**
* Handler for one schema node type.
*
* Use a regular function (not an arrow function) if you need `this`.
*
* @example
* ```ts
* const handler: PrinterHandler<string, {}, 'string'> = function () {
* return 'string'
* }
* ```
*/
type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (this: PrinterHandlerContext<TOutput, TOptions>, node: SchemaNodeByType[T]) => TOutput | null;
/**
* Partial map of per-node-type handler overrides for a printer.
*
* Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).
* Supply only the handlers you want to replace. The printer's built-in
* defaults fill in the rest.
*
* @example
* ```ts
* pluginZod({
* printer: {
* nodes: {
* date(): string {
* return 'z.string().date()'
* },
* } satisfies PrinterPartial<string, PrinterZodOptions>,
* },
* })
* ```
*/
type PrinterPartial<TOutput, TOptions extends object> = Partial<{ [K in SchemaType]: PrinterHandler<TOutput, TOptions, K> }>;
/**
* Generic shape used by `definePrinter`.
*
* - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)
* - `TOptions` options passed to and stored on the printer instance
* - `TOutput` the type emitted by node handlers
* - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)
*
* @example
* ```ts
* type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>
* ```
*/
type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {
name: TName;
options: TOptions;
output: TOutput;
printOutput: TPrintOutput;
};
/**
* Printer instance returned by a printer factory.
*
* @example
* ```ts
* const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})
* ```
*/
type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
/**
* Unique identifier supplied at creation time.
*/
name: T['name'];
/**
* Options for this printer instance.
*/
options: T['options'];
/**
* Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.
* Always dispatches through the `nodes` map. Never calls the `print` override.
* Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.
*/
transform: (node: SchemaNode) => T['output'] | null;
/**
* Public printer. If the builder provides a root-level `print`, this calls that
* higher-level function (which may produce full declarations).
* Otherwise, falls back to the node-level dispatcher.
*/
print: (node: SchemaNode) => T['printOutput'] | null;
};
/**
* Builder function passed to `definePrinter`.
*
* It receives resolved options and returns:
* - `name`
* - `options`
* - `nodes` handlers
* - optional top-level `print` override
*
* @example
* ```ts
* const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })
* ```
*/
type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {
name: T['name'];
/**
* Options to store on the printer.
*/
options: T['options'];
nodes: Partial<{ [K in SchemaType]: PrinterHandler<T['output'], T['options'], K> }>;
/**
* User-supplied handler overrides. An override wins over the matching `nodes` handler,
* and can call `this.base(node)` to reuse the handler it replaced. Pass overrides here
* instead of spreading them into `nodes`, otherwise `this.base` cannot find the original.
*/
overrides?: Partial<{ [K in SchemaType]: PrinterHandler<T['output'], T['options'], K> }>;
/**
* Optional root-level print override. When provided, becomes the public `printer.print`.
* Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),
* not the override itself, so recursion is safe.
*/
print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null;
};
/**
* Creates a schema printer: a function that takes a `SchemaNode` and emits
* code in your target language. Each plugin that produces code from schemas
* (TypeScript types, Zod schemas, Faker factories) ships a printer built
* with this helper.
*
* The builder receives resolved options and returns:
*
* - `name` unique identifier for the printer.
* - `options` stored on the returned printer instance.
* - `nodes` map of `SchemaType` → handler. Handlers return the rendered
* output (a string, a TypeScript AST node, ...) for that schema type.
* - `overrides` (optional), user-supplied handlers that win over `nodes`.
* An override can call `this.base(node)` to reuse the handler it replaced.
* - `print` (optional), top-level override exposed as `printer.print`.
* Use `this.transform(node)` inside it to dispatch to `nodes` recursively.
*
* Without a `print` override, `printer.print` falls back to `printer.transform`
* (the node-level dispatcher).
*
* @example Tiny Zod printer
* ```ts
* import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'
*
* type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
*
* export const zodPrinter = createPrinter<PrinterZod>((options) => ({
* name: 'zod',
* options: { strict: options.strict ?? true },
* nodes: {
* string: () => 'z.string()',
* object(node) {
* const props = node.properties
* .map((p) => `${p.name}: ${this.transform(p.schema)}`)
* .join(', ')
* return `z.object({ ${props} })`
* },
* },
* }))
* ```
*/
declare function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T>;
//#endregion
export { Dialect as a, createPrinter as i, PrinterFactoryOptions as n, SchemaDialect as o, PrinterPartial as r, defineDialect as s, Printer as t };
//# sourceMappingURL=types-CWF7DV0f.d.ts.map
+12
-1

@@ -40,2 +40,4 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });

* output (a string, a TypeScript AST node, ...) for that schema type.
* - `overrides` (optional), user-supplied handlers that win over `nodes`.
* An override can call `this.base(node)` to reuse the handler it replaced.
* - `print` (optional), top-level override exposed as `printer.print`.

@@ -70,6 +72,15 @@ * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.

return (options) => {
const { name, options: resolvedOptions, nodes, print: printOverride } = build(options ?? {});
const { name, options: resolvedOptions, nodes, overrides, print: printOverride } = build(options ?? {});
const merged = overrides ? {
...nodes,
...overrides
} : nodes;
const context = {
options: resolvedOptions,
transform: (node) => {
const handler = merged[node.type];
if (!handler) return null;
return handler.call(context, node);
},
base: (node) => {
const handler = nodes[node.type];

@@ -76,0 +87,0 @@ if (!handler) return null;

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","names":[],"sources":["../src/defineDialect.ts","../src/createPrinter.ts","../src/factory.ts","../src/exports.ts"],"sourcesContent":["/**\n * The spec-specific questions a schema parser answers while turning a source document into Kubb\n * AST nodes. The rest of the pipeline is generic, so this is the one seam where source formats\n * differ.\n */\nexport type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Whether the schema is nullable.\n */\n isNullable(schema?: TSchema): boolean\n /**\n * Whether the value is a `$ref` pointer.\n */\n isReference(value?: unknown): value is TRef\n /**\n * Whether the schema carries a discriminator for polymorphism.\n */\n isDiscriminator(value?: unknown): value is TDiscriminated\n /**\n * Whether the schema is binary data, converted to a `blob` node.\n */\n isBinary(schema: TSchema): boolean\n /**\n * Resolves a local `$ref` against the document, or nullish when it cannot.\n */\n resolveRef<TResolved>(document: TDocument, ref: string): TResolved | null | undefined\n}\n\n/**\n * A spec adapter's dialect. `name` identifies it in logs and diagnostics, and `schema` holds the\n * spec-specific schema questions the parser answers.\n */\nexport type Dialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Identifies the dialect in logs and diagnostics.\n */\n name: string\n /**\n * The spec-specific schema behavior. See {@link SchemaDialect}.\n */\n schema: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>\n}\n\n/**\n * Types a {@link Dialect} for an adapter. Adds no runtime behavior and only pins the\n * dialect's type for inference.\n *\n * @example\n * ```ts\n * export const oasDialect = defineDialect({\n * name: 'oas',\n * schema: {\n * isNullable,\n * isReference,\n * isDiscriminator,\n * isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',\n * resolveRef,\n * },\n * })\n * ```\n */\nexport function defineDialect<TSchema, TRef, TDiscriminated, TDocument>(\n dialect: Dialect<TSchema, TRef, TDiscriminated, TDocument>,\n): Dialect<TSchema, TRef, TDiscriminated, TDocument> {\n return dialect\n}\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Runtime context passed as `this` to printer handlers.\n *\n * `this.transform` dispatches to node-level handlers from `nodes`.\n *\n * @example\n * ```ts\n * const context: PrinterHandlerContext<string, {}> = {\n * options: {},\n * transform: () => 'value',\n * }\n * ```\n */\ntype PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.\n * Use `this.transform` inside `nodes` handlers and inside the `print` override.\n */\n transform: (node: SchemaNode) => TOutput | null\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for one schema node type.\n *\n * Use a regular function (not an arrow function) if you need `this`.\n *\n * @example\n * ```ts\n * const handler: PrinterHandler<string, {}, 'string'> = function () {\n * return 'string'\n * }\n * ```\n */\ntype PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null\n\n/**\n * Partial map of per-node-type handler overrides for a printer.\n *\n * Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).\n * Supply only the handlers you want to replace. The printer's built-in\n * defaults fill in the rest.\n *\n * @example\n * ```ts\n * pluginZod({\n * printer: {\n * nodes: {\n * date(): string {\n * return 'z.string().date()'\n * },\n * } satisfies PrinterPartial<string, PrinterZodOptions>,\n * },\n * })\n * ```\n */\nexport type PrinterPartial<TOutput, TOptions extends object> = Partial<{\n [K in SchemaType]: PrinterHandler<TOutput, TOptions, K>\n}>\n\n/**\n * Generic shape used by `definePrinter`.\n *\n * - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` options passed to and stored on the printer instance\n * - `TOutput` the type emitted by node handlers\n * - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)\n *\n * @example\n * ```ts\n * type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>\n * ```\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {\n name: TName\n options: TOptions\n output: TOutput\n printOutput: TPrintOutput\n}\n\n/**\n * Printer instance returned by a printer factory.\n *\n * @example\n * ```ts\n * const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})\n * ```\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.\n * Always dispatches through the `nodes` map. Never calls the `print` override.\n * Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.\n */\n transform: (node: SchemaNode) => T['output'] | null\n /**\n * Public printer. If the builder provides a root-level `print`, this calls that\n * higher-level function (which may produce full declarations).\n * Otherwise, falls back to the node-level dispatcher.\n */\n print: (node: SchemaNode) => T['printOutput'] | null\n}\n\n/**\n * Builder function passed to `definePrinter`.\n *\n * It receives resolved options and returns:\n * - `name`\n * - `options`\n * - `nodes` handlers\n * - optional top-level `print` override\n *\n * @example\n * ```ts\n * const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })\n * ```\n */\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * Optional root-level print override. When provided, becomes the public `printer.print`.\n * Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),\n * not the override itself, so recursion is safe.\n */\n print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null\n}\n/**\n * Creates a schema printer: a function that takes a `SchemaNode` and emits\n * code in your target language. Each plugin that produces code from schemas\n * (TypeScript types, Zod schemas, Faker factories) ships a printer built\n * with this helper.\n *\n * The builder receives resolved options and returns:\n *\n * - `name` unique identifier for the printer.\n * - `options` stored on the returned printer instance.\n * - `nodes` map of `SchemaType` → handler. Handlers return the rendered\n * output (a string, a TypeScript AST node, ...) for that schema type.\n * - `print` (optional), top-level override exposed as `printer.print`.\n * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.\n *\n * Without a `print` override, `printer.print` falls back to `printer.transform`\n * (the node-level dispatcher).\n *\n * @example Tiny Zod printer\n * ```ts\n * import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'\n *\n * type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>\n *\n * export const zodPrinter = createPrinter<PrinterZod>((options) => ({\n * name: 'zod',\n * options: { strict: options.strict ?? true },\n * nodes: {\n * string: () => 'z.string()',\n * object(node) {\n * const props = node.properties\n * .map((p) => `${p.name}: ${this.transform(p.schema)}`)\n * .join(', ')\n * return `z.object({ ${props} })`\n * },\n * },\n * }))\n * ```\n */\nexport function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes, print: printOverride } = build(options ?? ({} as T['options']))\n\n const context = {\n options: resolvedOptions,\n transform: (node: SchemaNode): T['output'] | null => {\n const handler = nodes[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n transform: context.transform,\n print: (printOverride ? printOverride.bind(context) : context.transform) as (node: SchemaNode) => T['printOutput'] | null,\n }\n }\n}\n","import type { Node } from './nodes/index.ts'\n\n// Node constructors, grouped under the `factory` namespace the way the TypeScript compiler exposes\n// `ts.factory.createX`. Aggregating them here lets `export * as factory from './factory.ts'` in the\n// barrel surface every `createX` alongside the `createFile`/`update` helpers from a single module.\nexport { createArrowFunction, createBreak, createConst, createFunction, createJsx, createText, createType } from './nodes/code.ts'\nexport { createContent } from './nodes/content.ts'\nexport { createExport, createFile, createImport, createSource } from './nodes/file.ts'\nexport type { UserFileNode } from './nodes/file.ts'\nexport { createInput } from './nodes/input.ts'\nexport { createOperation } from './nodes/operation.ts'\nexport { createOutput } from './nodes/output.ts'\nexport { createParameter } from './nodes/parameter.ts'\nexport { createProperty } from './nodes/property.ts'\nexport { createRequestBody } from './nodes/requestBody.ts'\nexport { createResponse } from './nodes/response.ts'\nexport { createSchema } from './nodes/schema.ts'\n\n/**\n * Identity-preserving node update: returns `node` unchanged when every field in\n * `changes` already equals (by reference) the current value, otherwise a new node\n * with the changes applied.\n *\n * Mirrors the TypeScript compiler's `factory.updateX` contract. Pair it with the\n * structural sharing in {@link transform} so a no-op rewrite does not allocate and\n * downstream passes can detect \"nothing changed\" by identity. Comparison is shallow,\n * so a structurally equal but newly allocated array or object counts as a change.\n *\n * @example\n * ```ts\n * update(node, { name: node.name }) // -> same `node` reference\n * update(node, { name: 'renamed' }) // -> new node, `name` replaced\n * ```\n */\nexport function update<T extends Node>(node: T, changes: Partial<T>): T {\n for (const key in changes) {\n if (changes[key] !== node[key as keyof T]) {\n return { ...node, ...changes }\n }\n }\n\n return node\n}\n","export { schemaTypes } from './constants.ts'\nexport { defineDialect } from './defineDialect.ts'\nexport { isHttpOperationNode, narrowSchema } from './guards.ts'\nexport { applyMacros, composeMacros, defineMacro } from './defineMacro.ts'\nexport { defineNode } from './defineNode.ts'\nexport { optionality } from './optionality.ts'\nexport { createPrinter } from './createPrinter.ts'\nexport { collect, transform, walk } from './visitor.ts'\n\nexport * as factory from './factory.ts'\nexport * from './registry.ts'\nexport type * from './types.ts'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6DA,SAAgB,cACd,SACmD;CACnD,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC2HA,SAAgB,cAAuE,OAAkE;CACvJ,QAAQ,YAAY;EAClB,MAAM,EAAE,MAAM,SAAS,iBAAiB,OAAO,OAAO,kBAAkB,MAAM,WAAY,CAAC,CAAkB;EAE7G,MAAM,UAAU;GACd,SAAS;GACT,YAAY,SAAyC;IACnD,MAAM,UAAU,MAAM,KAAK;IAC3B,IAAI,CAAC,SAAS,OAAO;IAErB,OAAQ,QAA2E,KAAK,SAAS,IAAI;GACvG;EACF;EAEA,OAAO;GACL;GACA,SAAS;GACT,WAAW,QAAQ;GACnB,OAAQ,gBAAgB,cAAc,KAAK,OAAO,IAAI,QAAQ;EAChE;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/KA,SAAgB,OAAuB,MAAS,SAAwB;CACtE,KAAK,MAAM,OAAO,SAChB,IAAI,QAAQ,SAAS,KAAK,MACxB,OAAO;EAAE,GAAG;EAAM,GAAG;CAAQ;CAIjC,OAAO;AACT"}
{"version":3,"file":"index.cjs","names":[],"sources":["../src/defineDialect.ts","../src/createPrinter.ts","../src/factory.ts","../src/exports.ts"],"sourcesContent":["/**\n * The spec-specific questions a schema parser answers while turning a source document into Kubb\n * AST nodes. The rest of the pipeline is generic, so this is the one seam where source formats\n * differ.\n */\nexport type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Whether the schema is nullable.\n */\n isNullable(schema?: TSchema): boolean\n /**\n * Whether the value is a `$ref` pointer.\n */\n isReference(value?: unknown): value is TRef\n /**\n * Whether the schema carries a discriminator for polymorphism.\n */\n isDiscriminator(value?: unknown): value is TDiscriminated\n /**\n * Whether the schema is binary data, converted to a `blob` node.\n */\n isBinary(schema: TSchema): boolean\n /**\n * Resolves a local `$ref` against the document, or nullish when it cannot.\n */\n resolveRef<TResolved>(document: TDocument, ref: string): TResolved | null | undefined\n}\n\n/**\n * A spec adapter's dialect. `name` identifies it in logs and diagnostics, and `schema` holds the\n * spec-specific schema questions the parser answers.\n */\nexport type Dialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Identifies the dialect in logs and diagnostics.\n */\n name: string\n /**\n * The spec-specific schema behavior. See {@link SchemaDialect}.\n */\n schema: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>\n}\n\n/**\n * Types a {@link Dialect} for an adapter. Adds no runtime behavior and only pins the\n * dialect's type for inference.\n *\n * @example\n * ```ts\n * export const oasDialect = defineDialect({\n * name: 'oas',\n * schema: {\n * isNullable,\n * isReference,\n * isDiscriminator,\n * isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',\n * resolveRef,\n * },\n * })\n * ```\n */\nexport function defineDialect<TSchema, TRef, TDiscriminated, TDocument>(\n dialect: Dialect<TSchema, TRef, TDiscriminated, TDocument>,\n): Dialect<TSchema, TRef, TDiscriminated, TDocument> {\n return dialect\n}\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Runtime context passed as `this` to printer handlers.\n *\n * `this.transform` dispatches to node-level handlers from `nodes`.\n *\n * @example\n * ```ts\n * const context: PrinterHandlerContext<string, {}> = {\n * options: {},\n * transform: () => 'value',\n * }\n * ```\n */\ntype PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.\n * Use `this.transform` inside `nodes` handlers and inside the `print` override.\n */\n transform: (node: SchemaNode) => TOutput | null\n /**\n * Run the printer's built-in handler for the node, ignoring any override for its type.\n * Inside an override, `this.base(node)` returns what the printer would have emitted,\n * so the override can wrap it instead of re-implementing the handler. Nested nodes\n * still dispatch through the overrides.\n */\n base: (node: SchemaNode) => TOutput | null\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for one schema node type.\n *\n * Use a regular function (not an arrow function) if you need `this`.\n *\n * @example\n * ```ts\n * const handler: PrinterHandler<string, {}, 'string'> = function () {\n * return 'string'\n * }\n * ```\n */\ntype PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null\n\n/**\n * Partial map of per-node-type handler overrides for a printer.\n *\n * Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).\n * Supply only the handlers you want to replace. The printer's built-in\n * defaults fill in the rest.\n *\n * @example\n * ```ts\n * pluginZod({\n * printer: {\n * nodes: {\n * date(): string {\n * return 'z.string().date()'\n * },\n * } satisfies PrinterPartial<string, PrinterZodOptions>,\n * },\n * })\n * ```\n */\nexport type PrinterPartial<TOutput, TOptions extends object> = Partial<{\n [K in SchemaType]: PrinterHandler<TOutput, TOptions, K>\n}>\n\n/**\n * Generic shape used by `definePrinter`.\n *\n * - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` options passed to and stored on the printer instance\n * - `TOutput` the type emitted by node handlers\n * - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)\n *\n * @example\n * ```ts\n * type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>\n * ```\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {\n name: TName\n options: TOptions\n output: TOutput\n printOutput: TPrintOutput\n}\n\n/**\n * Printer instance returned by a printer factory.\n *\n * @example\n * ```ts\n * const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})\n * ```\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.\n * Always dispatches through the `nodes` map. Never calls the `print` override.\n * Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.\n */\n transform: (node: SchemaNode) => T['output'] | null\n /**\n * Public printer. If the builder provides a root-level `print`, this calls that\n * higher-level function (which may produce full declarations).\n * Otherwise, falls back to the node-level dispatcher.\n */\n print: (node: SchemaNode) => T['printOutput'] | null\n}\n\n/**\n * Builder function passed to `definePrinter`.\n *\n * It receives resolved options and returns:\n * - `name`\n * - `options`\n * - `nodes` handlers\n * - optional top-level `print` override\n *\n * @example\n * ```ts\n * const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })\n * ```\n */\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * User-supplied handler overrides. An override wins over the matching `nodes` handler,\n * and can call `this.base(node)` to reuse the handler it replaced. Pass overrides here\n * instead of spreading them into `nodes`, otherwise `this.base` cannot find the original.\n */\n overrides?: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * Optional root-level print override. When provided, becomes the public `printer.print`.\n * Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),\n * not the override itself, so recursion is safe.\n */\n print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null\n}\n/**\n * Creates a schema printer: a function that takes a `SchemaNode` and emits\n * code in your target language. Each plugin that produces code from schemas\n * (TypeScript types, Zod schemas, Faker factories) ships a printer built\n * with this helper.\n *\n * The builder receives resolved options and returns:\n *\n * - `name` unique identifier for the printer.\n * - `options` stored on the returned printer instance.\n * - `nodes` map of `SchemaType` → handler. Handlers return the rendered\n * output (a string, a TypeScript AST node, ...) for that schema type.\n * - `overrides` (optional), user-supplied handlers that win over `nodes`.\n * An override can call `this.base(node)` to reuse the handler it replaced.\n * - `print` (optional), top-level override exposed as `printer.print`.\n * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.\n *\n * Without a `print` override, `printer.print` falls back to `printer.transform`\n * (the node-level dispatcher).\n *\n * @example Tiny Zod printer\n * ```ts\n * import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'\n *\n * type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>\n *\n * export const zodPrinter = createPrinter<PrinterZod>((options) => ({\n * name: 'zod',\n * options: { strict: options.strict ?? true },\n * nodes: {\n * string: () => 'z.string()',\n * object(node) {\n * const props = node.properties\n * .map((p) => `${p.name}: ${this.transform(p.schema)}`)\n * .join(', ')\n * return `z.object({ ${props} })`\n * },\n * },\n * }))\n * ```\n */\nexport function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes, overrides, print: printOverride } = build(options ?? ({} as T['options']))\n const merged = overrides ? { ...nodes, ...overrides } : nodes\n\n const context = {\n options: resolvedOptions,\n transform: (node: SchemaNode): T['output'] | null => {\n const handler = merged[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n base: (node: SchemaNode): T['output'] | null => {\n const handler = nodes[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n transform: context.transform,\n print: (printOverride ? printOverride.bind(context) : context.transform) as (node: SchemaNode) => T['printOutput'] | null,\n }\n }\n}\n","import type { Node } from './nodes/index.ts'\n\n// Node constructors, grouped under the `factory` namespace the way the TypeScript compiler exposes\n// `ts.factory.createX`. Aggregating them here lets `export * as factory from './factory.ts'` in the\n// barrel surface every `createX` alongside the `createFile`/`update` helpers from a single module.\nexport { createArrowFunction, createBreak, createConst, createFunction, createJsx, createText, createType } from './nodes/code.ts'\nexport { createContent } from './nodes/content.ts'\nexport { createExport, createFile, createImport, createSource } from './nodes/file.ts'\nexport type { UserFileNode } from './nodes/file.ts'\nexport { createInput } from './nodes/input.ts'\nexport { createOperation } from './nodes/operation.ts'\nexport { createOutput } from './nodes/output.ts'\nexport { createParameter } from './nodes/parameter.ts'\nexport { createProperty } from './nodes/property.ts'\nexport { createRequestBody } from './nodes/requestBody.ts'\nexport { createResponse } from './nodes/response.ts'\nexport { createSchema } from './nodes/schema.ts'\n\n/**\n * Identity-preserving node update: returns `node` unchanged when every field in\n * `changes` already equals (by reference) the current value, otherwise a new node\n * with the changes applied.\n *\n * Mirrors the TypeScript compiler's `factory.updateX` contract. Pair it with the\n * structural sharing in {@link transform} so a no-op rewrite does not allocate and\n * downstream passes can detect \"nothing changed\" by identity. Comparison is shallow,\n * so a structurally equal but newly allocated array or object counts as a change.\n *\n * @example\n * ```ts\n * update(node, { name: node.name }) // -> same `node` reference\n * update(node, { name: 'renamed' }) // -> new node, `name` replaced\n * ```\n */\nexport function update<T extends Node>(node: T, changes: Partial<T>): T {\n for (const key in changes) {\n if (changes[key] !== node[key as keyof T]) {\n return { ...node, ...changes }\n }\n }\n\n return node\n}\n","export { schemaTypes } from './constants.ts'\nexport { defineDialect } from './defineDialect.ts'\nexport { isHttpOperationNode, narrowSchema } from './guards.ts'\nexport { applyMacros, composeMacros, defineMacro } from './defineMacro.ts'\nexport { defineNode } from './defineNode.ts'\nexport { optionality } from './optionality.ts'\nexport { createPrinter } from './createPrinter.ts'\nexport { collect, transform, walk } from './visitor.ts'\n\nexport * as factory from './factory.ts'\nexport * from './registry.ts'\nexport type * from './types.ts'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6DA,SAAgB,cACd,SACmD;CACnD,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC4IA,SAAgB,cAAuE,OAAkE;CACvJ,QAAQ,YAAY;EAClB,MAAM,EAAE,MAAM,SAAS,iBAAiB,OAAO,WAAW,OAAO,kBAAkB,MAAM,WAAY,CAAC,CAAkB;EACxH,MAAM,SAAS,YAAY;GAAE,GAAG;GAAO,GAAG;EAAU,IAAI;EAExD,MAAM,UAAU;GACd,SAAS;GACT,YAAY,SAAyC;IACnD,MAAM,UAAU,OAAO,KAAK;IAC5B,IAAI,CAAC,SAAS,OAAO;IAErB,OAAQ,QAA2E,KAAK,SAAS,IAAI;GACvG;GACA,OAAO,SAAyC;IAC9C,MAAM,UAAU,MAAM,KAAK;IAC3B,IAAI,CAAC,SAAS,OAAO;IAErB,OAAQ,QAA2E,KAAK,SAAS,IAAI;GACvG;EACF;EAEA,OAAO;GACL;GACA,SAAS;GACT,WAAW,QAAQ;GACnB,OAAQ,gBAAgB,cAAc,KAAK,OAAO,IAAI,QAAQ;EAChE;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvMA,SAAgB,OAAuB,MAAS,SAAwB;CACtE,KAAK,MAAM,OAAO,SAChB,IAAI,QAAQ,SAAS,KAAK,MACxB,OAAO;EAAE,GAAG;EAAM,GAAG;CAAQ;CAIjC,OAAO;AACT"}
import { n as __name, t as __exportAll } from "./rolldown-runtime-CNktS9qV.js";
import { a as defineMacro, c as VisitorContext, d as walk, f as schemaTypes, i as composeMacros, l as collect, n as Macro, o as ParentOf, r as applyMacros, s as Visitor, t as Enforce, u as transform } from "./defineMacro-DzsACbFo.js";
import { a as Dialect, i as createPrinter, n as PrinterFactoryOptions, o as SchemaDialect, r as PrinterPartial, s as defineDialect, t as Printer } from "./types-Ctz5NB1o.js";
import { a as Dialect, i as createPrinter, n as PrinterFactoryOptions, o as SchemaDialect, r as PrinterPartial, s as defineDialect, t as Printer } from "./types-CWF7DV0f.js";
import { $ as ScalarSchemaType, A as SourceNode, At as createFunction, B as ContentNode, Bt as defineNode, C as ParameterNode, Ct as TypeNode, D as ExportNode, Dt as createArrowFunction, E as parameterDef, Et as constDef, F as createSource, Ft as jsxDef, G as DatetimeSchemaNode, H as createContent, Ht as NodeKind, I as exportDef, It as textDef, J as NumberSchemaNode, K as EnumSchemaNode, L as fileDef, Lt as typeDef, M as createExport, Mt as createText, N as createFile, Nt as createType, O as FileNode, Ot as createBreak, P as createImport, Pt as functionDef, Q as ScalarSchemaNode, R as importDef, Rt as DistributiveOmit, S as ParameterLocation, St as TextNode, T as createParameter, Tt as breakDef, U as ArraySchemaNode, V as contentDef, Vt as BaseNode, W as DateSchemaNode, X as PrimitiveSchemaType, Y as ObjectSchemaNode, Z as RefSchemaNode, _ as createResponse, _t as CodeNode, a as InputMeta, at as UnionSchemaNode, b as createRequestBody, bt as JSDocNode, c as inputDef, ct as schemaDef, d as HttpOperationNode, dt as createProperty, et as SchemaNode, f as OperationNode, ft as propertyDef, g as StatusCode, gt as BreakNode, h as ResponseNode, ht as ArrowFunctionNode, i as outputDef, it as TimeSchemaNode, j as UserFileNode, jt as createJsx, k as ImportNode, kt as createConst, l as GenericOperationNode, lt as PropertyNode, m as operationDef, mt as ParserOptions, n as OutputNode, nt as SchemaType, o as InputNode, ot as UrlSchemaNode, p as createOperation, pt as InferSchemaNode, q as IntersectionSchemaNode, r as createOutput, rt as StringSchemaNode, s as createInput, st as createSchema, t as Node, tt as SchemaNodeByType, u as HttpMethod, ut as UserPropertyNode, v as responseDef, vt as ConstNode, w as ParameterStyle, wt as arrowFunctionDef, x as requestBodyDef, xt as JsxNode, y as RequestBodyNode, yt as FunctionNode, z as sourceDef, zt as NodeDef } from "./index-Cu2zmNxv.js";

@@ -61,3 +61,3 @@

*/
declare const nodeDefs: (NodeDef<PropertyNode, UserPropertyNode> | NodeDef<ConstNode, Omit<ConstNode, "kind">> | NodeDef<TypeNode, Omit<TypeNode, "kind">> | NodeDef<FunctionNode, Omit<FunctionNode, "kind">> | NodeDef<ArrowFunctionNode, Omit<ArrowFunctionNode, "kind">> | NodeDef<TextNode, string> | NodeDef<BreakNode, void> | NodeDef<JsxNode, string> | NodeDef<SchemaNode, (Omit<ObjectSchemaNode, "kind" | "primitive" | "properties"> & {
declare const nodeDefs: (NodeDef<PropertyNode, UserPropertyNode> | NodeDef<ConstNode, Omit<ConstNode, "kind">> | NodeDef<TypeNode, Omit<TypeNode, "kind">> | NodeDef<FunctionNode, Omit<FunctionNode, "kind">> | NodeDef<ArrowFunctionNode, Omit<ArrowFunctionNode, "kind">> | NodeDef<TextNode, string> | NodeDef<BreakNode, void> | NodeDef<JsxNode, string> | NodeDef<SchemaNode, (Omit<ObjectSchemaNode, "properties" | "kind" | "primitive"> & {
properties?: Array<PropertyNode>;

@@ -129,3 +129,3 @@ primitive?: "object";

keysToOmit?: Array<string> | null;
}> | NodeDef<ParameterNode, Pick<ParameterNode, "name" | "schema" | "in"> & Partial<Omit<ParameterNode, "kind" | "name" | "schema" | "in">>> | NodeDef<ImportNode, Omit<ImportNode, "kind">> | NodeDef<ExportNode, Omit<ExportNode, "kind">> | NodeDef<SourceNode, Omit<SourceNode, "kind">> | NodeDef<FileNode<object>, Omit<FileNode<object>, "kind">>)[];
}> | NodeDef<ParameterNode, Pick<ParameterNode, "name" | "schema" | "in"> & Partial<Omit<ParameterNode, "name" | "kind" | "schema" | "in">>> | NodeDef<ImportNode, Omit<ImportNode, "kind">> | NodeDef<ExportNode, Omit<ExportNode, "kind">> | NodeDef<SourceNode, Omit<SourceNode, "kind">> | NodeDef<FileNode<object>, Omit<FileNode<object>, "kind">>)[];
declare namespace exports_d_exports {

@@ -132,0 +132,0 @@ export { ArraySchemaNode, ArrowFunctionNode, BreakNode, CodeNode, ConstNode, ContentNode, DateSchemaNode, DatetimeSchemaNode, Dialect, DistributiveOmit, Enforce, EnumSchemaNode, ExportNode, FileNode, FunctionNode, GenericOperationNode, HttpMethod, HttpOperationNode, ImportNode, InferSchemaNode, InputMeta, InputNode, IntersectionSchemaNode, JSDocNode, JsxNode, Macro, Node, NodeDef, NodeKind, NumberSchemaNode, ObjectSchemaNode, OperationNode, OutputNode, ParameterLocation, ParameterNode, ParameterStyle, ParentOf, ParserOptions, PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, PropertyNode, RefSchemaNode, RequestBodyNode, ResponseNode, ScalarSchemaNode, ScalarSchemaType, SchemaDialect, SchemaNode, SchemaNodeByType, SchemaType, SourceNode, StatusCode, StringSchemaNode, TextNode, TimeSchemaNode, TypeNode, UnionSchemaNode, UrlSchemaNode, UserFileNode, Visitor, VisitorContext, applyMacros, arrowFunctionDef, breakDef, collect, composeMacros, constDef, contentDef, createPrinter, defineDialect, defineMacro, defineNode, exportDef, factory_d_exports as factory, fileDef, functionDef, importDef, inputDef, isHttpOperationNode, jsxDef, narrowSchema, nodeDefs, operationDef, optionality, outputDef, parameterDef, propertyDef, requestBodyDef, responseDef, schemaDef, schemaTypes, sourceDef, textDef, transform, typeDef, walk };

@@ -40,2 +40,4 @@ import { t as __exportAll } from "./rolldown-runtime-CNktS9qV.js";

* output (a string, a TypeScript AST node, ...) for that schema type.
* - `overrides` (optional), user-supplied handlers that win over `nodes`.
* An override can call `this.base(node)` to reuse the handler it replaced.
* - `print` (optional), top-level override exposed as `printer.print`.

@@ -70,6 +72,15 @@ * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.

return (options) => {
const { name, options: resolvedOptions, nodes, print: printOverride } = build(options ?? {});
const { name, options: resolvedOptions, nodes, overrides, print: printOverride } = build(options ?? {});
const merged = overrides ? {
...nodes,
...overrides
} : nodes;
const context = {
options: resolvedOptions,
transform: (node) => {
const handler = merged[node.type];
if (!handler) return null;
return handler.call(context, node);
},
base: (node) => {
const handler = nodes[node.type];

@@ -76,0 +87,0 @@ if (!handler) return null;

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","names":[],"sources":["../src/defineDialect.ts","../src/createPrinter.ts","../src/factory.ts","../src/exports.ts"],"sourcesContent":["/**\n * The spec-specific questions a schema parser answers while turning a source document into Kubb\n * AST nodes. The rest of the pipeline is generic, so this is the one seam where source formats\n * differ.\n */\nexport type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Whether the schema is nullable.\n */\n isNullable(schema?: TSchema): boolean\n /**\n * Whether the value is a `$ref` pointer.\n */\n isReference(value?: unknown): value is TRef\n /**\n * Whether the schema carries a discriminator for polymorphism.\n */\n isDiscriminator(value?: unknown): value is TDiscriminated\n /**\n * Whether the schema is binary data, converted to a `blob` node.\n */\n isBinary(schema: TSchema): boolean\n /**\n * Resolves a local `$ref` against the document, or nullish when it cannot.\n */\n resolveRef<TResolved>(document: TDocument, ref: string): TResolved | null | undefined\n}\n\n/**\n * A spec adapter's dialect. `name` identifies it in logs and diagnostics, and `schema` holds the\n * spec-specific schema questions the parser answers.\n */\nexport type Dialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Identifies the dialect in logs and diagnostics.\n */\n name: string\n /**\n * The spec-specific schema behavior. See {@link SchemaDialect}.\n */\n schema: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>\n}\n\n/**\n * Types a {@link Dialect} for an adapter. Adds no runtime behavior and only pins the\n * dialect's type for inference.\n *\n * @example\n * ```ts\n * export const oasDialect = defineDialect({\n * name: 'oas',\n * schema: {\n * isNullable,\n * isReference,\n * isDiscriminator,\n * isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',\n * resolveRef,\n * },\n * })\n * ```\n */\nexport function defineDialect<TSchema, TRef, TDiscriminated, TDocument>(\n dialect: Dialect<TSchema, TRef, TDiscriminated, TDocument>,\n): Dialect<TSchema, TRef, TDiscriminated, TDocument> {\n return dialect\n}\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Runtime context passed as `this` to printer handlers.\n *\n * `this.transform` dispatches to node-level handlers from `nodes`.\n *\n * @example\n * ```ts\n * const context: PrinterHandlerContext<string, {}> = {\n * options: {},\n * transform: () => 'value',\n * }\n * ```\n */\ntype PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.\n * Use `this.transform` inside `nodes` handlers and inside the `print` override.\n */\n transform: (node: SchemaNode) => TOutput | null\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for one schema node type.\n *\n * Use a regular function (not an arrow function) if you need `this`.\n *\n * @example\n * ```ts\n * const handler: PrinterHandler<string, {}, 'string'> = function () {\n * return 'string'\n * }\n * ```\n */\ntype PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null\n\n/**\n * Partial map of per-node-type handler overrides for a printer.\n *\n * Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).\n * Supply only the handlers you want to replace. The printer's built-in\n * defaults fill in the rest.\n *\n * @example\n * ```ts\n * pluginZod({\n * printer: {\n * nodes: {\n * date(): string {\n * return 'z.string().date()'\n * },\n * } satisfies PrinterPartial<string, PrinterZodOptions>,\n * },\n * })\n * ```\n */\nexport type PrinterPartial<TOutput, TOptions extends object> = Partial<{\n [K in SchemaType]: PrinterHandler<TOutput, TOptions, K>\n}>\n\n/**\n * Generic shape used by `definePrinter`.\n *\n * - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` options passed to and stored on the printer instance\n * - `TOutput` the type emitted by node handlers\n * - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)\n *\n * @example\n * ```ts\n * type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>\n * ```\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {\n name: TName\n options: TOptions\n output: TOutput\n printOutput: TPrintOutput\n}\n\n/**\n * Printer instance returned by a printer factory.\n *\n * @example\n * ```ts\n * const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})\n * ```\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.\n * Always dispatches through the `nodes` map. Never calls the `print` override.\n * Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.\n */\n transform: (node: SchemaNode) => T['output'] | null\n /**\n * Public printer. If the builder provides a root-level `print`, this calls that\n * higher-level function (which may produce full declarations).\n * Otherwise, falls back to the node-level dispatcher.\n */\n print: (node: SchemaNode) => T['printOutput'] | null\n}\n\n/**\n * Builder function passed to `definePrinter`.\n *\n * It receives resolved options and returns:\n * - `name`\n * - `options`\n * - `nodes` handlers\n * - optional top-level `print` override\n *\n * @example\n * ```ts\n * const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })\n * ```\n */\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * Optional root-level print override. When provided, becomes the public `printer.print`.\n * Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),\n * not the override itself, so recursion is safe.\n */\n print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null\n}\n/**\n * Creates a schema printer: a function that takes a `SchemaNode` and emits\n * code in your target language. Each plugin that produces code from schemas\n * (TypeScript types, Zod schemas, Faker factories) ships a printer built\n * with this helper.\n *\n * The builder receives resolved options and returns:\n *\n * - `name` unique identifier for the printer.\n * - `options` stored on the returned printer instance.\n * - `nodes` map of `SchemaType` → handler. Handlers return the rendered\n * output (a string, a TypeScript AST node, ...) for that schema type.\n * - `print` (optional), top-level override exposed as `printer.print`.\n * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.\n *\n * Without a `print` override, `printer.print` falls back to `printer.transform`\n * (the node-level dispatcher).\n *\n * @example Tiny Zod printer\n * ```ts\n * import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'\n *\n * type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>\n *\n * export const zodPrinter = createPrinter<PrinterZod>((options) => ({\n * name: 'zod',\n * options: { strict: options.strict ?? true },\n * nodes: {\n * string: () => 'z.string()',\n * object(node) {\n * const props = node.properties\n * .map((p) => `${p.name}: ${this.transform(p.schema)}`)\n * .join(', ')\n * return `z.object({ ${props} })`\n * },\n * },\n * }))\n * ```\n */\nexport function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes, print: printOverride } = build(options ?? ({} as T['options']))\n\n const context = {\n options: resolvedOptions,\n transform: (node: SchemaNode): T['output'] | null => {\n const handler = nodes[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n transform: context.transform,\n print: (printOverride ? printOverride.bind(context) : context.transform) as (node: SchemaNode) => T['printOutput'] | null,\n }\n }\n}\n","import type { Node } from './nodes/index.ts'\n\n// Node constructors, grouped under the `factory` namespace the way the TypeScript compiler exposes\n// `ts.factory.createX`. Aggregating them here lets `export * as factory from './factory.ts'` in the\n// barrel surface every `createX` alongside the `createFile`/`update` helpers from a single module.\nexport { createArrowFunction, createBreak, createConst, createFunction, createJsx, createText, createType } from './nodes/code.ts'\nexport { createContent } from './nodes/content.ts'\nexport { createExport, createFile, createImport, createSource } from './nodes/file.ts'\nexport type { UserFileNode } from './nodes/file.ts'\nexport { createInput } from './nodes/input.ts'\nexport { createOperation } from './nodes/operation.ts'\nexport { createOutput } from './nodes/output.ts'\nexport { createParameter } from './nodes/parameter.ts'\nexport { createProperty } from './nodes/property.ts'\nexport { createRequestBody } from './nodes/requestBody.ts'\nexport { createResponse } from './nodes/response.ts'\nexport { createSchema } from './nodes/schema.ts'\n\n/**\n * Identity-preserving node update: returns `node` unchanged when every field in\n * `changes` already equals (by reference) the current value, otherwise a new node\n * with the changes applied.\n *\n * Mirrors the TypeScript compiler's `factory.updateX` contract. Pair it with the\n * structural sharing in {@link transform} so a no-op rewrite does not allocate and\n * downstream passes can detect \"nothing changed\" by identity. Comparison is shallow,\n * so a structurally equal but newly allocated array or object counts as a change.\n *\n * @example\n * ```ts\n * update(node, { name: node.name }) // -> same `node` reference\n * update(node, { name: 'renamed' }) // -> new node, `name` replaced\n * ```\n */\nexport function update<T extends Node>(node: T, changes: Partial<T>): T {\n for (const key in changes) {\n if (changes[key] !== node[key as keyof T]) {\n return { ...node, ...changes }\n }\n }\n\n return node\n}\n","export { schemaTypes } from './constants.ts'\nexport { defineDialect } from './defineDialect.ts'\nexport { isHttpOperationNode, narrowSchema } from './guards.ts'\nexport { applyMacros, composeMacros, defineMacro } from './defineMacro.ts'\nexport { defineNode } from './defineNode.ts'\nexport { optionality } from './optionality.ts'\nexport { createPrinter } from './createPrinter.ts'\nexport { collect, transform, walk } from './visitor.ts'\n\nexport * as factory from './factory.ts'\nexport * from './registry.ts'\nexport type * from './types.ts'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6DA,SAAgB,cACd,SACmD;CACnD,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC2HA,SAAgB,cAAuE,OAAkE;CACvJ,QAAQ,YAAY;EAClB,MAAM,EAAE,MAAM,SAAS,iBAAiB,OAAO,OAAO,kBAAkB,MAAM,WAAY,CAAC,CAAkB;EAE7G,MAAM,UAAU;GACd,SAAS;GACT,YAAY,SAAyC;IACnD,MAAM,UAAU,MAAM,KAAK;IAC3B,IAAI,CAAC,SAAS,OAAO;IAErB,OAAQ,QAA2E,KAAK,SAAS,IAAI;GACvG;EACF;EAEA,OAAO;GACL;GACA,SAAS;GACT,WAAW,QAAQ;GACnB,OAAQ,gBAAgB,cAAc,KAAK,OAAO,IAAI,QAAQ;EAChE;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/KA,SAAgB,OAAuB,MAAS,SAAwB;CACtE,KAAK,MAAM,OAAO,SAChB,IAAI,QAAQ,SAAS,KAAK,MACxB,OAAO;EAAE,GAAG;EAAM,GAAG;CAAQ;CAIjC,OAAO;AACT"}
{"version":3,"file":"index.js","names":[],"sources":["../src/defineDialect.ts","../src/createPrinter.ts","../src/factory.ts","../src/exports.ts"],"sourcesContent":["/**\n * The spec-specific questions a schema parser answers while turning a source document into Kubb\n * AST nodes. The rest of the pipeline is generic, so this is the one seam where source formats\n * differ.\n */\nexport type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Whether the schema is nullable.\n */\n isNullable(schema?: TSchema): boolean\n /**\n * Whether the value is a `$ref` pointer.\n */\n isReference(value?: unknown): value is TRef\n /**\n * Whether the schema carries a discriminator for polymorphism.\n */\n isDiscriminator(value?: unknown): value is TDiscriminated\n /**\n * Whether the schema is binary data, converted to a `blob` node.\n */\n isBinary(schema: TSchema): boolean\n /**\n * Resolves a local `$ref` against the document, or nullish when it cannot.\n */\n resolveRef<TResolved>(document: TDocument, ref: string): TResolved | null | undefined\n}\n\n/**\n * A spec adapter's dialect. `name` identifies it in logs and diagnostics, and `schema` holds the\n * spec-specific schema questions the parser answers.\n */\nexport type Dialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {\n /**\n * Identifies the dialect in logs and diagnostics.\n */\n name: string\n /**\n * The spec-specific schema behavior. See {@link SchemaDialect}.\n */\n schema: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>\n}\n\n/**\n * Types a {@link Dialect} for an adapter. Adds no runtime behavior and only pins the\n * dialect's type for inference.\n *\n * @example\n * ```ts\n * export const oasDialect = defineDialect({\n * name: 'oas',\n * schema: {\n * isNullable,\n * isReference,\n * isDiscriminator,\n * isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',\n * resolveRef,\n * },\n * })\n * ```\n */\nexport function defineDialect<TSchema, TRef, TDiscriminated, TDocument>(\n dialect: Dialect<TSchema, TRef, TDiscriminated, TDocument>,\n): Dialect<TSchema, TRef, TDiscriminated, TDocument> {\n return dialect\n}\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Runtime context passed as `this` to printer handlers.\n *\n * `this.transform` dispatches to node-level handlers from `nodes`.\n *\n * @example\n * ```ts\n * const context: PrinterHandlerContext<string, {}> = {\n * options: {},\n * transform: () => 'value',\n * }\n * ```\n */\ntype PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.\n * Use `this.transform` inside `nodes` handlers and inside the `print` override.\n */\n transform: (node: SchemaNode) => TOutput | null\n /**\n * Run the printer's built-in handler for the node, ignoring any override for its type.\n * Inside an override, `this.base(node)` returns what the printer would have emitted,\n * so the override can wrap it instead of re-implementing the handler. Nested nodes\n * still dispatch through the overrides.\n */\n base: (node: SchemaNode) => TOutput | null\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for one schema node type.\n *\n * Use a regular function (not an arrow function) if you need `this`.\n *\n * @example\n * ```ts\n * const handler: PrinterHandler<string, {}, 'string'> = function () {\n * return 'string'\n * }\n * ```\n */\ntype PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null\n\n/**\n * Partial map of per-node-type handler overrides for a printer.\n *\n * Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).\n * Supply only the handlers you want to replace. The printer's built-in\n * defaults fill in the rest.\n *\n * @example\n * ```ts\n * pluginZod({\n * printer: {\n * nodes: {\n * date(): string {\n * return 'z.string().date()'\n * },\n * } satisfies PrinterPartial<string, PrinterZodOptions>,\n * },\n * })\n * ```\n */\nexport type PrinterPartial<TOutput, TOptions extends object> = Partial<{\n [K in SchemaType]: PrinterHandler<TOutput, TOptions, K>\n}>\n\n/**\n * Generic shape used by `definePrinter`.\n *\n * - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` options passed to and stored on the printer instance\n * - `TOutput` the type emitted by node handlers\n * - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)\n *\n * @example\n * ```ts\n * type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>\n * ```\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {\n name: TName\n options: TOptions\n output: TOutput\n printOutput: TPrintOutput\n}\n\n/**\n * Printer instance returned by a printer factory.\n *\n * @example\n * ```ts\n * const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})\n * ```\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.\n * Always dispatches through the `nodes` map. Never calls the `print` override.\n * Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.\n */\n transform: (node: SchemaNode) => T['output'] | null\n /**\n * Public printer. If the builder provides a root-level `print`, this calls that\n * higher-level function (which may produce full declarations).\n * Otherwise, falls back to the node-level dispatcher.\n */\n print: (node: SchemaNode) => T['printOutput'] | null\n}\n\n/**\n * Builder function passed to `definePrinter`.\n *\n * It receives resolved options and returns:\n * - `name`\n * - `options`\n * - `nodes` handlers\n * - optional top-level `print` override\n *\n * @example\n * ```ts\n * const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })\n * ```\n */\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * User-supplied handler overrides. An override wins over the matching `nodes` handler,\n * and can call `this.base(node)` to reuse the handler it replaced. Pass overrides here\n * instead of spreading them into `nodes`, otherwise `this.base` cannot find the original.\n */\n overrides?: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * Optional root-level print override. When provided, becomes the public `printer.print`.\n * Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),\n * not the override itself, so recursion is safe.\n */\n print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null\n}\n/**\n * Creates a schema printer: a function that takes a `SchemaNode` and emits\n * code in your target language. Each plugin that produces code from schemas\n * (TypeScript types, Zod schemas, Faker factories) ships a printer built\n * with this helper.\n *\n * The builder receives resolved options and returns:\n *\n * - `name` unique identifier for the printer.\n * - `options` stored on the returned printer instance.\n * - `nodes` map of `SchemaType` → handler. Handlers return the rendered\n * output (a string, a TypeScript AST node, ...) for that schema type.\n * - `overrides` (optional), user-supplied handlers that win over `nodes`.\n * An override can call `this.base(node)` to reuse the handler it replaced.\n * - `print` (optional), top-level override exposed as `printer.print`.\n * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.\n *\n * Without a `print` override, `printer.print` falls back to `printer.transform`\n * (the node-level dispatcher).\n *\n * @example Tiny Zod printer\n * ```ts\n * import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'\n *\n * type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>\n *\n * export const zodPrinter = createPrinter<PrinterZod>((options) => ({\n * name: 'zod',\n * options: { strict: options.strict ?? true },\n * nodes: {\n * string: () => 'z.string()',\n * object(node) {\n * const props = node.properties\n * .map((p) => `${p.name}: ${this.transform(p.schema)}`)\n * .join(', ')\n * return `z.object({ ${props} })`\n * },\n * },\n * }))\n * ```\n */\nexport function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes, overrides, print: printOverride } = build(options ?? ({} as T['options']))\n const merged = overrides ? { ...nodes, ...overrides } : nodes\n\n const context = {\n options: resolvedOptions,\n transform: (node: SchemaNode): T['output'] | null => {\n const handler = merged[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n base: (node: SchemaNode): T['output'] | null => {\n const handler = nodes[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n transform: context.transform,\n print: (printOverride ? printOverride.bind(context) : context.transform) as (node: SchemaNode) => T['printOutput'] | null,\n }\n }\n}\n","import type { Node } from './nodes/index.ts'\n\n// Node constructors, grouped under the `factory` namespace the way the TypeScript compiler exposes\n// `ts.factory.createX`. Aggregating them here lets `export * as factory from './factory.ts'` in the\n// barrel surface every `createX` alongside the `createFile`/`update` helpers from a single module.\nexport { createArrowFunction, createBreak, createConst, createFunction, createJsx, createText, createType } from './nodes/code.ts'\nexport { createContent } from './nodes/content.ts'\nexport { createExport, createFile, createImport, createSource } from './nodes/file.ts'\nexport type { UserFileNode } from './nodes/file.ts'\nexport { createInput } from './nodes/input.ts'\nexport { createOperation } from './nodes/operation.ts'\nexport { createOutput } from './nodes/output.ts'\nexport { createParameter } from './nodes/parameter.ts'\nexport { createProperty } from './nodes/property.ts'\nexport { createRequestBody } from './nodes/requestBody.ts'\nexport { createResponse } from './nodes/response.ts'\nexport { createSchema } from './nodes/schema.ts'\n\n/**\n * Identity-preserving node update: returns `node` unchanged when every field in\n * `changes` already equals (by reference) the current value, otherwise a new node\n * with the changes applied.\n *\n * Mirrors the TypeScript compiler's `factory.updateX` contract. Pair it with the\n * structural sharing in {@link transform} so a no-op rewrite does not allocate and\n * downstream passes can detect \"nothing changed\" by identity. Comparison is shallow,\n * so a structurally equal but newly allocated array or object counts as a change.\n *\n * @example\n * ```ts\n * update(node, { name: node.name }) // -> same `node` reference\n * update(node, { name: 'renamed' }) // -> new node, `name` replaced\n * ```\n */\nexport function update<T extends Node>(node: T, changes: Partial<T>): T {\n for (const key in changes) {\n if (changes[key] !== node[key as keyof T]) {\n return { ...node, ...changes }\n }\n }\n\n return node\n}\n","export { schemaTypes } from './constants.ts'\nexport { defineDialect } from './defineDialect.ts'\nexport { isHttpOperationNode, narrowSchema } from './guards.ts'\nexport { applyMacros, composeMacros, defineMacro } from './defineMacro.ts'\nexport { defineNode } from './defineNode.ts'\nexport { optionality } from './optionality.ts'\nexport { createPrinter } from './createPrinter.ts'\nexport { collect, transform, walk } from './visitor.ts'\n\nexport * as factory from './factory.ts'\nexport * from './registry.ts'\nexport type * from './types.ts'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6DA,SAAgB,cACd,SACmD;CACnD,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC4IA,SAAgB,cAAuE,OAAkE;CACvJ,QAAQ,YAAY;EAClB,MAAM,EAAE,MAAM,SAAS,iBAAiB,OAAO,WAAW,OAAO,kBAAkB,MAAM,WAAY,CAAC,CAAkB;EACxH,MAAM,SAAS,YAAY;GAAE,GAAG;GAAO,GAAG;EAAU,IAAI;EAExD,MAAM,UAAU;GACd,SAAS;GACT,YAAY,SAAyC;IACnD,MAAM,UAAU,OAAO,KAAK;IAC5B,IAAI,CAAC,SAAS,OAAO;IAErB,OAAQ,QAA2E,KAAK,SAAS,IAAI;GACvG;GACA,OAAO,SAAyC;IAC9C,MAAM,UAAU,MAAM,KAAK;IAC3B,IAAI,CAAC,SAAS,OAAO;IAErB,OAAQ,QAA2E,KAAK,SAAS,IAAI;GACvG;EACF;EAEA,OAAO;GACL;GACA,SAAS;GACT,WAAW,QAAQ;GACnB,OAAQ,gBAAgB,cAAc,KAAK,OAAO,IAAI,QAAQ;EAChE;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvMA,SAAgB,OAAuB,MAAS,SAAwB;CACtE,KAAK,MAAM,OAAO,SAChB,IAAI,QAAQ,SAAS,KAAK,MACxB,OAAO;EAAE,GAAG;EAAM,GAAG;CAAQ;CAIjC,OAAO;AACT"}
import { c as VisitorContext, n as Macro, o as ParentOf, s as Visitor, t as Enforce } from "./defineMacro-DzsACbFo.js";
import { a as Dialect, n as PrinterFactoryOptions, o as SchemaDialect, r as PrinterPartial, t as Printer } from "./types-Ctz5NB1o.js";
import { a as Dialect, n as PrinterFactoryOptions, o as SchemaDialect, r as PrinterPartial, t as Printer } from "./types-CWF7DV0f.js";
import { $ as ScalarSchemaType, A as SourceNode, B as ContentNode, C as ParameterNode, Ct as TypeNode, D as ExportNode, G as DatetimeSchemaNode, Ht as NodeKind, J as NumberSchemaNode, K as EnumSchemaNode, O as FileNode, Q as ScalarSchemaNode, Rt as DistributiveOmit, S as ParameterLocation, St as TextNode, U as ArraySchemaNode, W as DateSchemaNode, X as PrimitiveSchemaType, Y as ObjectSchemaNode, Z as RefSchemaNode, _t as CodeNode, a as InputMeta, at as UnionSchemaNode, bt as JSDocNode, d as HttpOperationNode, et as SchemaNode, f as OperationNode, g as StatusCode, gt as BreakNode, h as ResponseNode, ht as ArrowFunctionNode, it as TimeSchemaNode, j as UserFileNode, k as ImportNode, l as GenericOperationNode, lt as PropertyNode, mt as ParserOptions, n as OutputNode, nt as SchemaType, o as InputNode, ot as UrlSchemaNode, pt as InferSchemaNode, q as IntersectionSchemaNode, rt as StringSchemaNode, t as Node, tt as SchemaNodeByType, u as HttpMethod, vt as ConstNode, w as ParameterStyle, xt as JsxNode, y as RequestBodyNode, yt as FunctionNode, zt as NodeDef } from "./index-Cu2zmNxv.js";
export type { ArraySchemaNode, ArrowFunctionNode, BreakNode, CodeNode, ConstNode, ContentNode, DateSchemaNode, DatetimeSchemaNode, Dialect, DistributiveOmit, Enforce, EnumSchemaNode, ExportNode, FileNode, FunctionNode, GenericOperationNode, HttpMethod, HttpOperationNode, ImportNode, InferSchemaNode, InputMeta, InputNode, IntersectionSchemaNode, JSDocNode, JsxNode, Macro, Node, NodeDef, NodeKind, NumberSchemaNode, ObjectSchemaNode, OperationNode, OutputNode, ParameterLocation, ParameterNode, ParameterStyle, ParentOf, ParserOptions, PrimitiveSchemaType, Printer, PrinterFactoryOptions, PrinterPartial, PropertyNode, RefSchemaNode, RequestBodyNode, ResponseNode, ScalarSchemaNode, ScalarSchemaType, SchemaDialect, SchemaNode, SchemaNodeByType, SchemaType, SourceNode, StatusCode, StringSchemaNode, TextNode, TimeSchemaNode, TypeNode, UnionSchemaNode, UrlSchemaNode, UserFileNode, Visitor, VisitorContext };
{
"name": "@kubb/ast",
"version": "5.0.0-beta.79",
"version": "5.0.0-beta.80",
"description": "Spec-agnostic AST layer for Kubb. Defines the node tree, visitor pattern, factory functions, and type guards used across all code generation plugins.",

@@ -5,0 +5,0 @@ "keywords": [

import { n as __name } from "./rolldown-runtime-CNktS9qV.js";
import { et as SchemaNode, nt as SchemaType, tt as SchemaNodeByType } from "./index-Cu2zmNxv.js";
//#region src/defineDialect.d.ts
/**
* The spec-specific questions a schema parser answers while turning a source document into Kubb
* AST nodes. The rest of the pipeline is generic, so this is the one seam where source formats
* differ.
*/
type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
/**
* Whether the schema is nullable.
*/
isNullable(schema?: TSchema): boolean;
/**
* Whether the value is a `$ref` pointer.
*/
isReference(value?: unknown): value is TRef;
/**
* Whether the schema carries a discriminator for polymorphism.
*/
isDiscriminator(value?: unknown): value is TDiscriminated;
/**
* Whether the schema is binary data, converted to a `blob` node.
*/
isBinary(schema: TSchema): boolean;
/**
* Resolves a local `$ref` against the document, or nullish when it cannot.
*/
resolveRef<TResolved>(document: TDocument, ref: string): TResolved | null | undefined;
};
/**
* A spec adapter's dialect. `name` identifies it in logs and diagnostics, and `schema` holds the
* spec-specific schema questions the parser answers.
*/
type Dialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
/**
* Identifies the dialect in logs and diagnostics.
*/
name: string;
/**
* The spec-specific schema behavior. See {@link SchemaDialect}.
*/
schema: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>;
};
/**
* Types a {@link Dialect} for an adapter. Adds no runtime behavior and only pins the
* dialect's type for inference.
*
* @example
* ```ts
* export const oasDialect = defineDialect({
* name: 'oas',
* schema: {
* isNullable,
* isReference,
* isDiscriminator,
* isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
* resolveRef,
* },
* })
* ```
*/
declare function defineDialect<TSchema, TRef, TDiscriminated, TDocument>(dialect: Dialect<TSchema, TRef, TDiscriminated, TDocument>): Dialect<TSchema, TRef, TDiscriminated, TDocument>;
//#endregion
//#region src/createPrinter.d.ts
/**
* Runtime context passed as `this` to printer handlers.
*
* `this.transform` dispatches to node-level handlers from `nodes`.
*
* @example
* ```ts
* const context: PrinterHandlerContext<string, {}> = {
* options: {},
* transform: () => 'value',
* }
* ```
*/
type PrinterHandlerContext<TOutput, TOptions extends object> = {
/**
* Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.
* Use `this.transform` inside `nodes` handlers and inside the `print` override.
*/
transform: (node: SchemaNode) => TOutput | null;
/**
* Options for this printer instance.
*/
options: TOptions;
};
/**
* Handler for one schema node type.
*
* Use a regular function (not an arrow function) if you need `this`.
*
* @example
* ```ts
* const handler: PrinterHandler<string, {}, 'string'> = function () {
* return 'string'
* }
* ```
*/
type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (this: PrinterHandlerContext<TOutput, TOptions>, node: SchemaNodeByType[T]) => TOutput | null;
/**
* Partial map of per-node-type handler overrides for a printer.
*
* Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).
* Supply only the handlers you want to replace. The printer's built-in
* defaults fill in the rest.
*
* @example
* ```ts
* pluginZod({
* printer: {
* nodes: {
* date(): string {
* return 'z.string().date()'
* },
* } satisfies PrinterPartial<string, PrinterZodOptions>,
* },
* })
* ```
*/
type PrinterPartial<TOutput, TOptions extends object> = Partial<{ [K in SchemaType]: PrinterHandler<TOutput, TOptions, K> }>;
/**
* Generic shape used by `definePrinter`.
*
* - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)
* - `TOptions` options passed to and stored on the printer instance
* - `TOutput` the type emitted by node handlers
* - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)
*
* @example
* ```ts
* type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>
* ```
*/
type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {
name: TName;
options: TOptions;
output: TOutput;
printOutput: TPrintOutput;
};
/**
* Printer instance returned by a printer factory.
*
* @example
* ```ts
* const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})
* ```
*/
type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
/**
* Unique identifier supplied at creation time.
*/
name: T['name'];
/**
* Options for this printer instance.
*/
options: T['options'];
/**
* Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.
* Always dispatches through the `nodes` map. Never calls the `print` override.
* Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.
*/
transform: (node: SchemaNode) => T['output'] | null;
/**
* Public printer. If the builder provides a root-level `print`, this calls that
* higher-level function (which may produce full declarations).
* Otherwise, falls back to the node-level dispatcher.
*/
print: (node: SchemaNode) => T['printOutput'] | null;
};
/**
* Builder function passed to `definePrinter`.
*
* It receives resolved options and returns:
* - `name`
* - `options`
* - `nodes` handlers
* - optional top-level `print` override
*
* @example
* ```ts
* const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })
* ```
*/
type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {
name: T['name'];
/**
* Options to store on the printer.
*/
options: T['options'];
nodes: Partial<{ [K in SchemaType]: PrinterHandler<T['output'], T['options'], K> }>;
/**
* Optional root-level print override. When provided, becomes the public `printer.print`.
* Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),
* not the override itself, so recursion is safe.
*/
print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null;
};
/**
* Creates a schema printer: a function that takes a `SchemaNode` and emits
* code in your target language. Each plugin that produces code from schemas
* (TypeScript types, Zod schemas, Faker factories) ships a printer built
* with this helper.
*
* The builder receives resolved options and returns:
*
* - `name` unique identifier for the printer.
* - `options` stored on the returned printer instance.
* - `nodes` map of `SchemaType` → handler. Handlers return the rendered
* output (a string, a TypeScript AST node, ...) for that schema type.
* - `print` (optional), top-level override exposed as `printer.print`.
* Use `this.transform(node)` inside it to dispatch to `nodes` recursively.
*
* Without a `print` override, `printer.print` falls back to `printer.transform`
* (the node-level dispatcher).
*
* @example Tiny Zod printer
* ```ts
* import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'
*
* type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
*
* export const zodPrinter = createPrinter<PrinterZod>((options) => ({
* name: 'zod',
* options: { strict: options.strict ?? true },
* nodes: {
* string: () => 'z.string()',
* object(node) {
* const props = node.properties
* .map((p) => `${p.name}: ${this.transform(p.schema)}`)
* .join(', ')
* return `z.object({ ${props} })`
* },
* },
* }))
* ```
*/
declare function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T>;
//#endregion
export { Dialect as a, createPrinter as i, PrinterFactoryOptions as n, SchemaDialect as o, PrinterPartial as r, defineDialect as s, Printer as t };
//# sourceMappingURL=types-Ctz5NB1o.d.ts.map