@kubb/ast 5.0.0-alpha.5 → 5.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +40 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +40 -27
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{visitor-CE4-xBHW.d.ts → visitor-D1tc_9X5.d.ts} +61 -37
- package/package.json +1 -1
- package/src/printer.ts +70 -42
package/src/printer.ts
CHANGED
|
@@ -2,11 +2,12 @@ import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Handler context for `definePrinter` — mirrors `PluginContext` from `@kubb/core`.
|
|
5
|
-
* Available as `this` inside each node handler
|
|
5
|
+
* Available as `this` inside each node handler and the optional root-level `print`.
|
|
6
|
+
* `this.print` always dispatches to the `nodes` handlers (node-level printer).
|
|
6
7
|
*/
|
|
7
8
|
export type PrinterHandlerContext<TOutput, TOptions extends object> = {
|
|
8
9
|
/**
|
|
9
|
-
* Recursively print a nested `SchemaNode
|
|
10
|
+
* Recursively print a nested `SchemaNode` using the node-level handlers.
|
|
10
11
|
*/
|
|
11
12
|
print: (node: SchemaNode) => TOutput | null | undefined
|
|
12
13
|
/**
|
|
@@ -28,19 +29,20 @@ export type PrinterHandler<TOutput, TOptions extends object, T extends SchemaTyp
|
|
|
28
29
|
* Shape of the type parameter passed to `definePrinter`.
|
|
29
30
|
* Mirrors `AdapterFactoryOptions` / `PluginFactoryOptions` from `@kubb/core`.
|
|
30
31
|
*
|
|
31
|
-
* - `TName`
|
|
32
|
-
* - `TOptions`
|
|
33
|
-
* - `TOutput`
|
|
32
|
+
* - `TName` — unique string identifier (e.g. `'zod'`, `'ts'`)
|
|
33
|
+
* - `TOptions` — options passed to and stored on the printer
|
|
34
|
+
* - `TOutput` — the type emitted by node handlers
|
|
35
|
+
* - `TPrintOutput` — the type emitted by the public `print` override (defaults to `TOutput`)
|
|
34
36
|
*/
|
|
35
|
-
export type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown> = {
|
|
37
|
+
export type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {
|
|
36
38
|
name: TName
|
|
37
39
|
options: TOptions
|
|
38
40
|
output: TOutput
|
|
41
|
+
printOutput: TPrintOutput
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
45
|
* The object returned by calling a `definePrinter` instance.
|
|
43
|
-
* Mirrors the shape of `Adapter` from `@kubb/core`.
|
|
44
46
|
*/
|
|
45
47
|
export type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
|
|
46
48
|
/**
|
|
@@ -52,15 +54,18 @@ export type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
|
|
|
52
54
|
*/
|
|
53
55
|
options: T['options']
|
|
54
56
|
/**
|
|
55
|
-
*
|
|
57
|
+
* Public printer. If the builder provides a root-level `print`, this calls that
|
|
58
|
+
* higher-level function (which may produce full declarations). Otherwise falls back
|
|
59
|
+
* to the node-level dispatcher
|
|
56
60
|
*/
|
|
57
|
-
print: (node: SchemaNode) => T['
|
|
58
|
-
/**
|
|
59
|
-
* Maps `print` over an array of `SchemaNode`s.
|
|
60
|
-
*/
|
|
61
|
-
for: (nodes: Array<SchemaNode>) => Array<T['output'] | null | undefined>
|
|
61
|
+
print: (node: SchemaNode) => T['printOutput'] | null | undefined
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Builder function passed to `definePrinter`. Receives the resolved options and returns the
|
|
66
|
+
* printer configuration: a unique `name`, the stored `options`, node-level `nodes` handlers,
|
|
67
|
+
* and an optional root-level `print` override.
|
|
68
|
+
*/
|
|
64
69
|
type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {
|
|
65
70
|
name: T['name']
|
|
66
71
|
/**
|
|
@@ -70,6 +75,12 @@ type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) =
|
|
|
70
75
|
nodes: Partial<{
|
|
71
76
|
[K in SchemaType]: PrinterHandler<T['output'], T['options'], K>
|
|
72
77
|
}>
|
|
78
|
+
/**
|
|
79
|
+
* Optional root-level print override. When provided, becomes the public `printer.print`.
|
|
80
|
+
* `this.print(node)` inside this function calls the node-level dispatcher (`nodes` handlers),
|
|
81
|
+
* not the override itself — so recursion is safe.
|
|
82
|
+
*/
|
|
83
|
+
print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null | undefined
|
|
73
84
|
}
|
|
74
85
|
|
|
75
86
|
/**
|
|
@@ -77,53 +88,70 @@ type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) =
|
|
|
77
88
|
* from `@kubb/core` — wraps a builder to make options optional and separates raw options
|
|
78
89
|
* from resolved options.
|
|
79
90
|
*
|
|
80
|
-
*
|
|
91
|
+
* The builder receives resolved options and returns:
|
|
92
|
+
* - `name` — a unique identifier for the printer
|
|
93
|
+
* - `options` — options stored on the returned printer instance
|
|
94
|
+
* - `nodes` — a map of `SchemaType` → handler functions that convert a `SchemaNode` to `TOutput`
|
|
95
|
+
* - `print` _(optional)_ — a root-level override that becomes the public `printer.print`.
|
|
96
|
+
* Inside it, `this.print(node)` still dispatches to the `nodes` map — safe recursion, no infinite loop.
|
|
97
|
+
*
|
|
98
|
+
* When no `print` override is provided, `printer.print` is the node-level dispatcher directly.
|
|
99
|
+
*
|
|
100
|
+
* @example Basic usage — Zod schema printer
|
|
81
101
|
* ```ts
|
|
82
|
-
* type ZodPrinter = PrinterFactoryOptions<'zod', { strict?: boolean },
|
|
102
|
+
* type ZodPrinter = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
|
|
83
103
|
*
|
|
84
|
-
* export const zodPrinter = definePrinter<ZodPrinter>((options) => {
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* },
|
|
93
|
-
* object(node) {
|
|
94
|
-
* const props = node.properties
|
|
95
|
-
* ?.map(p => `${p.name}: ${this.print(p)}`)
|
|
96
|
-
* .join(', ') ?? ''
|
|
97
|
-
* return `z.object({ ${props} })`
|
|
98
|
-
* },
|
|
104
|
+
* export const zodPrinter = definePrinter<ZodPrinter>((options) => ({
|
|
105
|
+
* name: 'zod',
|
|
106
|
+
* options: { strict: options.strict ?? true },
|
|
107
|
+
* nodes: {
|
|
108
|
+
* string: () => 'z.string()',
|
|
109
|
+
* object(node) {
|
|
110
|
+
* const props = node.properties.map(p => `${p.name}: ${this.print(p.schema)}`).join(', ')
|
|
111
|
+
* return `z.object({ ${props} })`
|
|
99
112
|
* },
|
|
100
|
-
* }
|
|
101
|
-
* })
|
|
113
|
+
* },
|
|
114
|
+
* }))
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @example With a root-level `print` override to wrap output in a full declaration
|
|
118
|
+
* ```ts
|
|
119
|
+
* type TsPrinter = PrinterFactoryOptions<'ts', { typeName?: string }, ts.TypeNode, ts.Node>
|
|
102
120
|
*
|
|
103
|
-
* const
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
121
|
+
* export const printerTs = definePrinter<TsPrinter>((options) => ({
|
|
122
|
+
* name: 'ts',
|
|
123
|
+
* options,
|
|
124
|
+
* nodes: { string: () => factory.keywordTypeNodes.string },
|
|
125
|
+
* print(node) {
|
|
126
|
+
* const type = this.print(node) // calls the node-level dispatcher
|
|
127
|
+
* if (!type || !this.options.typeName) return type
|
|
128
|
+
* return factory.createTypeAliasDeclaration(this.options.typeName, type)
|
|
129
|
+
* },
|
|
130
|
+
* }))
|
|
107
131
|
* ```
|
|
108
132
|
*/
|
|
109
133
|
export function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {
|
|
110
134
|
return (options) => {
|
|
111
|
-
const { name, options: resolvedOptions, nodes } = build(options ?? ({} as T['options']))
|
|
135
|
+
const { name, options: resolvedOptions, nodes, print: printOverride } = build(options ?? ({} as T['options']))
|
|
112
136
|
|
|
113
137
|
const context: PrinterHandlerContext<T['output'], T['options']> = {
|
|
114
138
|
options: resolvedOptions,
|
|
115
139
|
print: (node: SchemaNode) => {
|
|
116
|
-
const
|
|
117
|
-
const handler = nodes[
|
|
118
|
-
|
|
140
|
+
const schemaType = node.type
|
|
141
|
+
const handler = nodes[schemaType]
|
|
142
|
+
|
|
143
|
+
if (!handler) return undefined
|
|
144
|
+
|
|
145
|
+
const typedHandler = handler as PrinterHandler<T['output'], T['options']>
|
|
146
|
+
|
|
147
|
+
return typedHandler.call(context, node as SchemaNodeByType[SchemaType])
|
|
119
148
|
},
|
|
120
149
|
}
|
|
121
150
|
|
|
122
151
|
return {
|
|
123
152
|
name,
|
|
124
153
|
options: resolvedOptions,
|
|
125
|
-
print: context.print,
|
|
126
|
-
for: (nodes) => nodes.map(context.print),
|
|
154
|
+
print: (printOverride ? printOverride.bind(context) : context.print) as Printer<T>['print'],
|
|
127
155
|
}
|
|
128
156
|
}
|
|
129
157
|
}
|