@kubb/ast 5.0.0-beta.63 → 5.0.0-beta.65
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/{defineMacro-Shz8f6SG.js → defineMacro-B76LsJwO.js} +4 -4
- package/dist/{defineMacro-Shz8f6SG.js.map → defineMacro-B76LsJwO.js.map} +1 -1
- package/dist/{defineMacro-BATi7xoC.d.ts → defineMacro-BQpu6Ags.d.ts} +3 -3
- package/dist/factory-B_qPwA1b.d.ts +27 -0
- package/dist/factory.d.ts +3 -27
- package/dist/factory.js +2 -2
- package/dist/{index-B9cc8MBS.d.ts → index-CeJAFegf.d.ts} +4 -4
- package/dist/index.cjs +55 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +32 -29
- package/dist/index.js +55 -9
- package/dist/index.js.map +1 -1
- package/dist/macros.d.ts +2 -2
- package/dist/macros.js +4 -4
- package/dist/{operationParams-k5CKwSWZ.d.ts → operationParams-DCY3q4C7.d.ts} +3 -3
- package/dist/{refs-BjNDuCBD.js → refs-Dx6U5LoE.js} +3 -3
- package/dist/{refs-BjNDuCBD.js.map → refs-Dx6U5LoE.js.map} +1 -1
- package/dist/schema-BkvrrOAr.cjs.map +1 -1
- package/dist/{schema-Cbnxmz4b.js → schema-YNbOtTCM.js} +2 -2
- package/dist/{schema-Cbnxmz4b.js.map → schema-YNbOtTCM.js.map} +1 -1
- package/dist/{types-BB_xgRJ3.d.ts → types-B6thixAv.d.ts} +8 -8
- package/dist/types.d.ts +5 -5
- package/dist/{utils-DaXkewb1.js → utils-BJi0y-xg.js} +4 -4
- package/dist/utils-BJi0y-xg.js.map +1 -0
- package/dist/utils-CEepwqmb.cjs.map +1 -1
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +3 -3
- package/package.json +1 -2
- package/dist/utils-DaXkewb1.js.map +0 -1
- package/src/constants.ts +0 -150
- package/src/defineMacro.ts +0 -139
- package/src/defineNode.ts +0 -102
- package/src/definePrinter.ts +0 -258
- package/src/dialect.ts +0 -86
- package/src/factory.ts +0 -44
- package/src/guards.ts +0 -28
- package/src/index.ts +0 -13
- package/src/infer.ts +0 -132
- package/src/macros/index.ts +0 -3
- package/src/macros/macroDiscriminatorEnum.ts +0 -50
- package/src/macros/macroEnumName.ts +0 -33
- package/src/macros/macroSimplifyUnion.ts +0 -60
- package/src/nodes/base.ts +0 -49
- package/src/nodes/code.ts +0 -355
- package/src/nodes/content.ts +0 -51
- package/src/nodes/file.ts +0 -380
- package/src/nodes/function.ts +0 -283
- package/src/nodes/index.ts +0 -93
- package/src/nodes/input.ts +0 -144
- package/src/nodes/operation.ts +0 -168
- package/src/nodes/output.ts +0 -49
- package/src/nodes/parameter.ts +0 -71
- package/src/nodes/property.ts +0 -67
- package/src/nodes/requestBody.ts +0 -54
- package/src/nodes/response.ts +0 -173
- package/src/nodes/schema.ts +0 -732
- package/src/optionality.ts +0 -15
- package/src/registry.ts +0 -75
- package/src/signature.ts +0 -207
- package/src/types.ts +0 -8
- package/src/utils/codegen.ts +0 -103
- package/src/utils/extractStringsFromNodes.ts +0 -35
- package/src/utils/fileMerge.ts +0 -183
- package/src/utils/index.ts +0 -11
- package/src/utils/operationParams.ts +0 -353
- package/src/utils/refs.ts +0 -134
- package/src/utils/schemaGraph.ts +0 -177
- package/src/utils/schemaMerge.ts +0 -34
- package/src/utils/schemaTraversal.ts +0 -86
- package/src/utils/strings.ts +0 -139
- package/src/visitor.ts +0 -519
- /package/dist/{chunk-CNktS9qV.js → rolldown-runtime-CNktS9qV.js} +0 -0
package/src/definePrinter.ts
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Runtime context passed as `this` to printer handlers.
|
|
5
|
-
*
|
|
6
|
-
* `this.transform` dispatches to node-level handlers from `nodes`.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* const context: PrinterHandlerContext<string, {}> = {
|
|
11
|
-
* options: {},
|
|
12
|
-
* transform: () => 'value',
|
|
13
|
-
* }
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
type PrinterHandlerContext<TOutput, TOptions extends object> = {
|
|
17
|
-
/**
|
|
18
|
-
* Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.
|
|
19
|
-
* Use `this.transform` inside `nodes` handlers and inside the `print` override.
|
|
20
|
-
*/
|
|
21
|
-
transform: (node: SchemaNode) => TOutput | null
|
|
22
|
-
/**
|
|
23
|
-
* Options for this printer instance.
|
|
24
|
-
*/
|
|
25
|
-
options: TOptions
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Handler for one schema node type.
|
|
30
|
-
*
|
|
31
|
-
* Use a regular function (not an arrow function) if you need `this`.
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* const handler: PrinterHandler<string, {}, 'string'> = function () {
|
|
36
|
-
* return 'string'
|
|
37
|
-
* }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (
|
|
41
|
-
this: PrinterHandlerContext<TOutput, TOptions>,
|
|
42
|
-
node: SchemaNodeByType[T],
|
|
43
|
-
) => TOutput | null
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Partial map of per-node-type handler overrides for a printer.
|
|
47
|
-
*
|
|
48
|
-
* Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).
|
|
49
|
-
* Supply only the handlers you want to replace. The printer's built-in
|
|
50
|
-
* defaults fill in the rest.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```ts
|
|
54
|
-
* pluginZod({
|
|
55
|
-
* printer: {
|
|
56
|
-
* nodes: {
|
|
57
|
-
* date(): string {
|
|
58
|
-
* return 'z.string().date()'
|
|
59
|
-
* },
|
|
60
|
-
* } satisfies PrinterPartial<string, PrinterZodOptions>,
|
|
61
|
-
* },
|
|
62
|
-
* })
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
export type PrinterPartial<TOutput, TOptions extends object> = Partial<{
|
|
66
|
-
[K in SchemaType]: PrinterHandler<TOutput, TOptions, K>
|
|
67
|
-
}>
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Generic shape used by `definePrinter`.
|
|
71
|
-
*
|
|
72
|
-
* - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)
|
|
73
|
-
* - `TOptions` options passed to and stored on the printer instance
|
|
74
|
-
* - `TOutput` the type emitted by node handlers
|
|
75
|
-
* - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```ts
|
|
79
|
-
* type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
export type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {
|
|
83
|
-
name: TName
|
|
84
|
-
options: TOptions
|
|
85
|
-
output: TOutput
|
|
86
|
-
printOutput: TPrintOutput
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Printer instance returned by a printer factory.
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```ts
|
|
94
|
-
* const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
export type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
|
|
98
|
-
/**
|
|
99
|
-
* Unique identifier supplied at creation time.
|
|
100
|
-
*/
|
|
101
|
-
name: T['name']
|
|
102
|
-
/**
|
|
103
|
-
* Options for this printer instance.
|
|
104
|
-
*/
|
|
105
|
-
options: T['options']
|
|
106
|
-
/**
|
|
107
|
-
* Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.
|
|
108
|
-
* Always dispatches through the `nodes` map. Never calls the `print` override.
|
|
109
|
-
* Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.
|
|
110
|
-
*/
|
|
111
|
-
transform: (node: SchemaNode) => T['output'] | null
|
|
112
|
-
/**
|
|
113
|
-
* Public printer. If the builder provides a root-level `print`, this calls that
|
|
114
|
-
* higher-level function (which may produce full declarations).
|
|
115
|
-
* Otherwise, falls back to the node-level dispatcher.
|
|
116
|
-
*/
|
|
117
|
-
print: (node: SchemaNode) => T['printOutput'] | null
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Builder function passed to `definePrinter`.
|
|
122
|
-
*
|
|
123
|
-
* It receives resolved options and returns:
|
|
124
|
-
* - `name`
|
|
125
|
-
* - `options`
|
|
126
|
-
* - `nodes` handlers
|
|
127
|
-
* - optional top-level `print` override
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* ```ts
|
|
131
|
-
* const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })
|
|
132
|
-
* ```
|
|
133
|
-
*/
|
|
134
|
-
type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {
|
|
135
|
-
name: T['name']
|
|
136
|
-
/**
|
|
137
|
-
* Options to store on the printer.
|
|
138
|
-
*/
|
|
139
|
-
options: T['options']
|
|
140
|
-
nodes: Partial<{
|
|
141
|
-
[K in SchemaType]: PrinterHandler<T['output'], T['options'], K>
|
|
142
|
-
}>
|
|
143
|
-
/**
|
|
144
|
-
* Optional root-level print override. When provided, becomes the public `printer.print`.
|
|
145
|
-
* Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),
|
|
146
|
-
* not the override itself, so recursion is safe.
|
|
147
|
-
*/
|
|
148
|
-
print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Defines a schema printer: a function that takes a `SchemaNode` and emits
|
|
152
|
-
* code in your target language. Each plugin that produces code from schemas
|
|
153
|
-
* (TypeScript types, Zod schemas, Faker factories) ships a printer built
|
|
154
|
-
* with this helper.
|
|
155
|
-
*
|
|
156
|
-
* The builder receives resolved options and returns:
|
|
157
|
-
*
|
|
158
|
-
* - `name` unique identifier for the printer.
|
|
159
|
-
* - `options` stored on the returned printer instance.
|
|
160
|
-
* - `nodes` map of `SchemaType` → handler. Handlers return the rendered
|
|
161
|
-
* output (a string, a TypeScript AST node, ...) for that schema type.
|
|
162
|
-
* - `print` (optional), top-level override exposed as `printer.print`.
|
|
163
|
-
* Use `this.transform(node)` inside it to dispatch to `nodes` recursively.
|
|
164
|
-
*
|
|
165
|
-
* Without a `print` override, `printer.print` falls back to `printer.transform`
|
|
166
|
-
* (the node-level dispatcher).
|
|
167
|
-
*
|
|
168
|
-
* @example Tiny Zod printer
|
|
169
|
-
* ```ts
|
|
170
|
-
* import { definePrinter, type PrinterFactoryOptions } from '@kubb/ast'
|
|
171
|
-
*
|
|
172
|
-
* type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>
|
|
173
|
-
*
|
|
174
|
-
* export const zodPrinter = definePrinter<PrinterZod>((options) => ({
|
|
175
|
-
* name: 'zod',
|
|
176
|
-
* options: { strict: options.strict ?? true },
|
|
177
|
-
* nodes: {
|
|
178
|
-
* string: () => 'z.string()',
|
|
179
|
-
* object(node) {
|
|
180
|
-
* const props = node.properties
|
|
181
|
-
* .map((p) => `${p.name}: ${this.transform(p.schema)}`)
|
|
182
|
-
* .join(', ')
|
|
183
|
-
* return `z.object({ ${props} })`
|
|
184
|
-
* },
|
|
185
|
-
* },
|
|
186
|
-
* }))
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
|
-
export function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {
|
|
190
|
-
return createPrinterFactory<SchemaNode, SchemaType, SchemaNodeByType>((node) => node.type)(build) as (options?: T['options']) => Printer<T>
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Generic printer factory behind `definePrinter`. Pass a `getKey` function that maps a node to its
|
|
195
|
-
* handler key, and it returns a `definePrinter`-style helper for that node and key type. `definePrinter`
|
|
196
|
-
* itself is this factory keyed by `node.type`.
|
|
197
|
-
*
|
|
198
|
-
* @example Key a printer by `node.kind` instead of `node.type`
|
|
199
|
-
* ```ts
|
|
200
|
-
* const defineFunctionPrinter = createPrinterFactory<FunctionParamNode, FunctionParamKind, Partial<Record<FunctionParamKind, FunctionParamNode>>>(
|
|
201
|
-
* (node) => node.kind,
|
|
202
|
-
* )
|
|
203
|
-
* ```
|
|
204
|
-
*/
|
|
205
|
-
export function createPrinterFactory<TNode, TKey extends string, TNodeByKey extends Partial<Record<TKey, TNode>>>(getKey: (node: TNode) => TKey | null) {
|
|
206
|
-
return function <T extends PrinterFactoryOptions>(
|
|
207
|
-
build: (options: T['options']) => {
|
|
208
|
-
name: T['name']
|
|
209
|
-
options: T['options']
|
|
210
|
-
nodes: Partial<{
|
|
211
|
-
[K in TKey]: (
|
|
212
|
-
this: {
|
|
213
|
-
transform: (node: TNode) => T['output'] | null
|
|
214
|
-
options: T['options']
|
|
215
|
-
},
|
|
216
|
-
node: TNodeByKey[K],
|
|
217
|
-
) => T['output'] | null
|
|
218
|
-
}>
|
|
219
|
-
print?: (
|
|
220
|
-
this: {
|
|
221
|
-
transform: (node: TNode) => T['output'] | null
|
|
222
|
-
options: T['options']
|
|
223
|
-
},
|
|
224
|
-
node: TNode,
|
|
225
|
-
) => T['printOutput'] | null
|
|
226
|
-
},
|
|
227
|
-
): (options?: T['options']) => {
|
|
228
|
-
name: T['name']
|
|
229
|
-
options: T['options']
|
|
230
|
-
transform: (node: TNode) => T['output'] | null
|
|
231
|
-
print: (node: TNode) => T['printOutput'] | null
|
|
232
|
-
} {
|
|
233
|
-
return (options) => {
|
|
234
|
-
const { name, options: resolvedOptions, nodes, print: printOverride } = build(options ?? ({} as T['options']))
|
|
235
|
-
|
|
236
|
-
const context = {
|
|
237
|
-
options: resolvedOptions,
|
|
238
|
-
transform: (node: TNode): T['output'] | null => {
|
|
239
|
-
const key = getKey(node)
|
|
240
|
-
if (key === null) return null
|
|
241
|
-
|
|
242
|
-
const handler = nodes[key]
|
|
243
|
-
|
|
244
|
-
if (!handler) return null
|
|
245
|
-
|
|
246
|
-
return (handler as (this: typeof context, node: TNode) => T['output'] | null).call(context, node)
|
|
247
|
-
},
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return {
|
|
251
|
-
name,
|
|
252
|
-
options: resolvedOptions,
|
|
253
|
-
transform: context.transform,
|
|
254
|
-
print: (printOverride ? printOverride.bind(context) : context.transform) as (node: TNode) => T['printOutput'] | null,
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
package/src/dialect.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import type { Node } from './nodes/index.ts'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The spec-specific questions a schema parser answers while turning a source document into Kubb
|
|
5
|
-
* AST nodes. The rest of the pipeline is generic JSON Schema, so this is the one seam where
|
|
6
|
-
* OpenAPI, AsyncAPI, and plain JSON Schema differ.
|
|
7
|
-
*/
|
|
8
|
-
export type SchemaDialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown> = {
|
|
9
|
-
/**
|
|
10
|
-
* Whether the schema is nullable.
|
|
11
|
-
*/
|
|
12
|
-
isNullable(schema?: TSchema): boolean
|
|
13
|
-
/**
|
|
14
|
-
* Whether the value is a `$ref` pointer.
|
|
15
|
-
*/
|
|
16
|
-
isReference(value?: unknown): value is TRef
|
|
17
|
-
/**
|
|
18
|
-
* Whether the schema carries a discriminator for polymorphism.
|
|
19
|
-
*/
|
|
20
|
-
isDiscriminator(value?: unknown): value is TDiscriminated
|
|
21
|
-
/**
|
|
22
|
-
* Whether the schema is binary data, converted to a `blob` node.
|
|
23
|
-
*/
|
|
24
|
-
isBinary(schema: TSchema): boolean
|
|
25
|
-
/**
|
|
26
|
-
* Resolves a local `$ref` against the document, or nullish when it cannot.
|
|
27
|
-
*/
|
|
28
|
-
resolveRef<TResolved>(document: TDocument, ref: string): TResolved | null | undefined
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* How a dialect collapses structurally identical schemas into shared definitions. The contract is
|
|
33
|
-
* generic over the plan and context types, which the adapter supplies. The mechanics live in the
|
|
34
|
-
* adapter, not here, so `@kubb/ast` carries no dedupe logic. The returned plan owns the rewriting
|
|
35
|
-
* behavior, so callers interact with one object.
|
|
36
|
-
*/
|
|
37
|
-
export type Dedupe<TPlan = unknown, TContext = unknown> = {
|
|
38
|
-
/**
|
|
39
|
-
* Scans a forest of nodes and produces a plan describing which shapes to share.
|
|
40
|
-
*/
|
|
41
|
-
plan(roots: ReadonlyArray<Node>, context: TContext): TPlan
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* A spec adapter's dialect. `name` identifies it in logs and diagnostics, `schema` holds the
|
|
46
|
-
* spec-specific schema questions the parser answers, and `dedupe` is the schema-sharing seam.
|
|
47
|
-
*/
|
|
48
|
-
export type Dialect<TSchema = unknown, TRef = TSchema, TDiscriminated = TSchema, TDocument = unknown, TDedupe extends Dedupe = Dedupe> = {
|
|
49
|
-
/**
|
|
50
|
-
* Identifies the dialect in logs and diagnostics.
|
|
51
|
-
*/
|
|
52
|
-
name: string
|
|
53
|
-
/**
|
|
54
|
-
* The spec-specific schema behavior. See {@link SchemaDialect}.
|
|
55
|
-
*/
|
|
56
|
-
schema: SchemaDialect<TSchema, TRef, TDiscriminated, TDocument>
|
|
57
|
-
/**
|
|
58
|
-
* The schema-sharing behavior. See {@link Dedupe}.
|
|
59
|
-
*/
|
|
60
|
-
dedupe: TDedupe
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Types a {@link Dialect} for an adapter. Adds no runtime behavior and only pins the
|
|
65
|
-
* dialect's type for inference.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* export const oasDialect = defineDialect({
|
|
70
|
-
* name: 'oas',
|
|
71
|
-
* schema: {
|
|
72
|
-
* isNullable,
|
|
73
|
-
* isReference,
|
|
74
|
-
* isDiscriminator,
|
|
75
|
-
* isBinary: (schema) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
|
|
76
|
-
* resolveRef,
|
|
77
|
-
* },
|
|
78
|
-
* dedupe: { plan },
|
|
79
|
-
* })
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
export function defineDialect<TSchema, TRef, TDiscriminated, TDocument, TDedupe extends Dedupe>(
|
|
83
|
-
dialect: Dialect<TSchema, TRef, TDiscriminated, TDocument, TDedupe>,
|
|
84
|
-
): Dialect<TSchema, TRef, TDiscriminated, TDocument, TDedupe> {
|
|
85
|
-
return dialect
|
|
86
|
-
}
|
package/src/factory.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { Node } from './nodes/index.ts'
|
|
2
|
-
|
|
3
|
-
// Node constructors, grouped under the `factory` namespace the way the TypeScript compiler exposes
|
|
4
|
-
// `ts.factory.createX`. Aggregating them here lets `export * as factory from './factory.ts'` in the
|
|
5
|
-
// barrel surface every `createX` alongside the `createFile`/`update` helpers from a single module.
|
|
6
|
-
export { createArrowFunction, createBreak, createConst, createFunction, createJsx, createText, createType } from './nodes/code.ts'
|
|
7
|
-
export { createContent } from './nodes/content.ts'
|
|
8
|
-
export { createExport, createFile, createImport, createSource } from './nodes/file.ts'
|
|
9
|
-
export type { UserFileNode } from './nodes/file.ts'
|
|
10
|
-
export { createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createTypeLiteral } from './nodes/function.ts'
|
|
11
|
-
export { createInput } from './nodes/input.ts'
|
|
12
|
-
export { createOperation } from './nodes/operation.ts'
|
|
13
|
-
export { createOutput } from './nodes/output.ts'
|
|
14
|
-
export { createParameter } from './nodes/parameter.ts'
|
|
15
|
-
export { createProperty } from './nodes/property.ts'
|
|
16
|
-
export { createRequestBody } from './nodes/requestBody.ts'
|
|
17
|
-
export { createResponse } from './nodes/response.ts'
|
|
18
|
-
export { createSchema } from './nodes/schema.ts'
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Identity-preserving node update: returns `node` unchanged when every field in
|
|
22
|
-
* `changes` already equals (by reference) the current value, otherwise a new node
|
|
23
|
-
* with the changes applied.
|
|
24
|
-
*
|
|
25
|
-
* Mirrors the TypeScript compiler's `factory.updateX` contract. Pair it with the
|
|
26
|
-
* structural sharing in {@link transform} so a no-op rewrite does not allocate and
|
|
27
|
-
* downstream passes can detect "nothing changed" by identity. Comparison is shallow,
|
|
28
|
-
* so a structurally equal but newly allocated array or object counts as a change.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* update(node, { name: node.name }) // -> same `node` reference
|
|
33
|
-
* update(node, { name: 'renamed' }) // -> new node, `name` replaced
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
export function update<T extends Node>(node: T, changes: Partial<T>): T {
|
|
37
|
-
for (const key in changes) {
|
|
38
|
-
if (changes[key] !== node[key as keyof T]) {
|
|
39
|
-
return { ...node, ...changes }
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return node
|
|
44
|
-
}
|
package/src/guards.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { HttpOperationNode, OperationNode, SchemaNode, SchemaNodeByType } from './nodes/index.ts'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Narrows a `SchemaNode` to the variant that matches `type`.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* const schema = createSchema({ type: 'string' })
|
|
9
|
-
* const stringNode = narrowSchema(schema, 'string') // StringSchemaNode | null
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
|
-
export function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | null {
|
|
13
|
-
return node?.type === type ? (node as SchemaNodeByType[T]) : null
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Narrows an `OperationNode` to an `HttpOperationNode` so `method` and `path` are present.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```ts
|
|
21
|
-
* if (isHttpOperationNode(node)) {
|
|
22
|
-
* console.log(node.method, node.path)
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export function isHttpOperationNode(node: OperationNode): node is HttpOperationNode {
|
|
27
|
-
return node.protocol === 'http' || (node.method !== undefined && node.path !== undefined)
|
|
28
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export { schemaTypes } from './constants.ts'
|
|
2
|
-
export { defineDialect } from './dialect.ts'
|
|
3
|
-
export { isHttpOperationNode, narrowSchema } from './guards.ts'
|
|
4
|
-
export { applyMacros, composeMacros, defineMacro } from './defineMacro.ts'
|
|
5
|
-
export { defineNode } from './defineNode.ts'
|
|
6
|
-
export { optionality } from './optionality.ts'
|
|
7
|
-
export { createPrinterFactory, definePrinter } from './definePrinter.ts'
|
|
8
|
-
export { signatureOf } from './signature.ts'
|
|
9
|
-
export { collect, transform, walk } from './visitor.ts'
|
|
10
|
-
|
|
11
|
-
export * as factory from './factory.ts'
|
|
12
|
-
export * from './registry.ts'
|
|
13
|
-
export type * from './types.ts'
|
package/src/infer.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ArraySchemaNode,
|
|
3
|
-
DateSchemaNode,
|
|
4
|
-
DatetimeSchemaNode,
|
|
5
|
-
EnumSchemaNode,
|
|
6
|
-
IntersectionSchemaNode,
|
|
7
|
-
NumberSchemaNode,
|
|
8
|
-
ObjectSchemaNode,
|
|
9
|
-
RefSchemaNode,
|
|
10
|
-
ScalarSchemaNode,
|
|
11
|
-
SchemaNode,
|
|
12
|
-
StringSchemaNode,
|
|
13
|
-
TimeSchemaNode,
|
|
14
|
-
UnionSchemaNode,
|
|
15
|
-
UrlSchemaNode,
|
|
16
|
-
} from './nodes/index.ts'
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Options that control how the adapter parser maps OpenAPI schemas to AST nodes.
|
|
20
|
-
*/
|
|
21
|
-
export type ParserOptions = {
|
|
22
|
-
/**
|
|
23
|
-
* How `format: 'date-time'` schemas are represented downstream.
|
|
24
|
-
* - `false` falls through to a plain `string` (no validation).
|
|
25
|
-
* - `'string'` emits a datetime string node.
|
|
26
|
-
* - `'stringOffset'` emits a datetime node with timezone offset.
|
|
27
|
-
* - `'stringLocal'` emits a local datetime node.
|
|
28
|
-
* - `'date'` emits a `date` node (JavaScript `Date` object).
|
|
29
|
-
*/
|
|
30
|
-
dateType: false | 'string' | 'stringOffset' | 'stringLocal' | 'date'
|
|
31
|
-
/**
|
|
32
|
-
* How `type: 'integer'` (and `format: 'int64'`) maps to TypeScript.
|
|
33
|
-
* - `'bigint'` is exact for 64-bit IDs, but does not round-trip through JSON.
|
|
34
|
-
* - `'number'` fits most JSON APIs. Loses precision above `Number.MAX_SAFE_INTEGER`.
|
|
35
|
-
*
|
|
36
|
-
* @default 'bigint'
|
|
37
|
-
*/
|
|
38
|
-
integerType?: 'number' | 'bigint'
|
|
39
|
-
/**
|
|
40
|
-
* AST type used when a schema's type cannot be inferred from the spec
|
|
41
|
-
* (`additionalProperties: true`, missing `type`, ...).
|
|
42
|
-
*/
|
|
43
|
-
unknownType: 'any' | 'unknown' | 'void'
|
|
44
|
-
/**
|
|
45
|
-
* AST type used for completely empty schemas (`{}`).
|
|
46
|
-
*/
|
|
47
|
-
emptySchemaType: 'any' | 'unknown' | 'void'
|
|
48
|
-
/**
|
|
49
|
-
* Suffix appended to derived enum names when Kubb has to invent one
|
|
50
|
-
* (typically for inline enums on object properties).
|
|
51
|
-
*/
|
|
52
|
-
enumSuffix: 'enum' | (string & {})
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Maps each `dateType` option value to the AST node produced by `format: 'date-time'`.
|
|
57
|
-
*/
|
|
58
|
-
type DateTimeNodeByDateType = {
|
|
59
|
-
date: DateSchemaNode
|
|
60
|
-
string: DatetimeSchemaNode
|
|
61
|
-
stringOffset: DatetimeSchemaNode
|
|
62
|
-
stringLocal: DatetimeSchemaNode
|
|
63
|
-
false: StringSchemaNode
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Resolves the AST node produced by `format: 'date-time'` based on the `dateType` option.
|
|
68
|
-
*/
|
|
69
|
-
type ResolveDateTimeNode<TDateType extends ParserOptions['dateType']> = DateTimeNodeByDateType[TDateType extends keyof DateTimeNodeByDateType
|
|
70
|
-
? TDateType
|
|
71
|
-
: 'string']
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Ordered list of `[schema-shape, SchemaNode]` pairs.
|
|
75
|
-
* `InferSchemaNode` walks this tuple in order and returns the first matching node type.
|
|
76
|
-
*/
|
|
77
|
-
type SchemaNodeMap<TDateType extends ParserOptions['dateType'] = 'string'> = [
|
|
78
|
-
[{ $ref: string }, RefSchemaNode],
|
|
79
|
-
[{ allOf: ReadonlyArray<unknown>; properties: object }, IntersectionSchemaNode],
|
|
80
|
-
[{ allOf: readonly [unknown, unknown, ...Array<unknown>] }, IntersectionSchemaNode],
|
|
81
|
-
[{ allOf: ReadonlyArray<unknown> }, SchemaNode],
|
|
82
|
-
[{ oneOf: ReadonlyArray<unknown> }, UnionSchemaNode],
|
|
83
|
-
[{ anyOf: ReadonlyArray<unknown> }, UnionSchemaNode],
|
|
84
|
-
[{ const: null }, ScalarSchemaNode],
|
|
85
|
-
[{ const: string | number | boolean }, EnumSchemaNode],
|
|
86
|
-
[{ type: ReadonlyArray<string> }, UnionSchemaNode],
|
|
87
|
-
[{ type: 'array'; enum: ReadonlyArray<unknown> }, ArraySchemaNode],
|
|
88
|
-
[{ enum: ReadonlyArray<unknown> }, EnumSchemaNode],
|
|
89
|
-
[{ type: 'enum' }, EnumSchemaNode],
|
|
90
|
-
[{ type: 'union' }, UnionSchemaNode],
|
|
91
|
-
[{ type: 'intersection' }, IntersectionSchemaNode],
|
|
92
|
-
[{ type: 'tuple' }, ArraySchemaNode],
|
|
93
|
-
[{ type: 'ref' }, RefSchemaNode],
|
|
94
|
-
[{ type: 'datetime' }, DatetimeSchemaNode],
|
|
95
|
-
[{ type: 'date' }, DateSchemaNode],
|
|
96
|
-
[{ type: 'time' }, TimeSchemaNode],
|
|
97
|
-
[{ type: 'url' }, UrlSchemaNode],
|
|
98
|
-
[{ type: 'object' }, ObjectSchemaNode],
|
|
99
|
-
[{ additionalProperties: boolean | {} }, ObjectSchemaNode],
|
|
100
|
-
[{ type: 'array' }, ArraySchemaNode],
|
|
101
|
-
[{ items: object }, ArraySchemaNode],
|
|
102
|
-
[{ prefixItems: ReadonlyArray<unknown> }, ArraySchemaNode],
|
|
103
|
-
[{ type: string; format: 'date-time' }, ResolveDateTimeNode<TDateType>],
|
|
104
|
-
[{ type: string; format: 'date' }, DateSchemaNode],
|
|
105
|
-
[{ type: string; format: 'time' }, TimeSchemaNode],
|
|
106
|
-
[{ format: 'date-time' }, ResolveDateTimeNode<TDateType>],
|
|
107
|
-
[{ format: 'date' }, DateSchemaNode],
|
|
108
|
-
[{ format: 'time' }, TimeSchemaNode],
|
|
109
|
-
[{ type: 'string' }, StringSchemaNode],
|
|
110
|
-
[{ type: 'number' }, NumberSchemaNode],
|
|
111
|
-
[{ type: 'integer' }, NumberSchemaNode],
|
|
112
|
-
[{ type: 'bigint' }, NumberSchemaNode],
|
|
113
|
-
[{ type: string }, ScalarSchemaNode],
|
|
114
|
-
[{ minLength: number }, StringSchemaNode],
|
|
115
|
-
[{ maxLength: number }, StringSchemaNode],
|
|
116
|
-
[{ pattern: string }, StringSchemaNode],
|
|
117
|
-
[{ minimum: number }, NumberSchemaNode],
|
|
118
|
-
[{ maximum: number }, NumberSchemaNode],
|
|
119
|
-
]
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Infers the matching AST `SchemaNode` type from an input schema shape.
|
|
123
|
-
*/
|
|
124
|
-
export type InferSchemaNode<
|
|
125
|
-
TSchema extends object,
|
|
126
|
-
TDateType extends ParserOptions['dateType'] = 'string',
|
|
127
|
-
TEntries extends ReadonlyArray<[object, SchemaNode]> = SchemaNodeMap<TDateType>,
|
|
128
|
-
> = TEntries extends [infer TEntry extends [object, SchemaNode], ...infer TRest extends ReadonlyArray<[object, SchemaNode]>]
|
|
129
|
-
? TSchema extends TEntry[0]
|
|
130
|
-
? TEntry[1]
|
|
131
|
-
: InferSchemaNode<TSchema, TDateType, TRest>
|
|
132
|
-
: SchemaNode
|
package/src/macros/index.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { defineMacro } from '../defineMacro.ts'
|
|
2
|
-
import { narrowSchema } from '../guards.ts'
|
|
3
|
-
import { createProperty } from '../nodes/property.ts'
|
|
4
|
-
import { createSchema } from '../nodes/schema.ts'
|
|
5
|
-
|
|
6
|
-
type Props = {
|
|
7
|
-
propertyName: string
|
|
8
|
-
values: Array<string>
|
|
9
|
-
enumName?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Builds a macro that replaces a discriminator property's schema with a string enum of the given
|
|
14
|
-
* values. Object schemas that lack the property are returned unchanged.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```ts
|
|
18
|
-
* const macro = macroDiscriminatorEnum({ propertyName: 'type', values: ['dog', 'cat'] })
|
|
19
|
-
* const next = applyMacros(objectSchema, [macro], { depth: 'shallow' })
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export function macroDiscriminatorEnum({ propertyName, values, enumName }: Props) {
|
|
23
|
-
return defineMacro({
|
|
24
|
-
name: 'discriminator-enum',
|
|
25
|
-
schema(node) {
|
|
26
|
-
const objectNode = narrowSchema(node, 'object')
|
|
27
|
-
if (!objectNode?.properties?.length) return undefined
|
|
28
|
-
if (!objectNode.properties.some((prop) => prop.name === propertyName)) return undefined
|
|
29
|
-
|
|
30
|
-
return createSchema({
|
|
31
|
-
...objectNode,
|
|
32
|
-
properties: objectNode.properties.map((prop) => {
|
|
33
|
-
if (prop.name !== propertyName) return prop
|
|
34
|
-
|
|
35
|
-
return createProperty({
|
|
36
|
-
...prop,
|
|
37
|
-
schema: createSchema({
|
|
38
|
-
type: 'enum',
|
|
39
|
-
primitive: 'string',
|
|
40
|
-
enumValues: values,
|
|
41
|
-
name: enumName,
|
|
42
|
-
readOnly: prop.schema.readOnly,
|
|
43
|
-
writeOnly: prop.schema.writeOnly,
|
|
44
|
-
}),
|
|
45
|
-
})
|
|
46
|
-
}),
|
|
47
|
-
})
|
|
48
|
-
},
|
|
49
|
-
})
|
|
50
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { defineMacro } from '../defineMacro.ts'
|
|
2
|
-
import { narrowSchema } from '../guards.ts'
|
|
3
|
-
import { enumPropName } from '../utils/refs.ts'
|
|
4
|
-
|
|
5
|
-
type Props = {
|
|
6
|
-
parentName: string | null | undefined
|
|
7
|
-
propName: string
|
|
8
|
-
enumSuffix: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Builds a macro that names an inline enum schema from its parent and property name. Boolean enums
|
|
13
|
-
* are left anonymous. Non-enum nodes are returned unchanged.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* const macro = macroEnumName({ parentName: 'Pet', propName: 'status', enumSuffix: 'enum' })
|
|
18
|
-
* const named = applyMacros(propSchema, [macro], { depth: 'shallow' })
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export function macroEnumName({ parentName, propName, enumSuffix }: Props) {
|
|
22
|
-
return defineMacro({
|
|
23
|
-
name: 'enum-name',
|
|
24
|
-
schema(node) {
|
|
25
|
-
const enumNode = narrowSchema(node, 'enum')
|
|
26
|
-
|
|
27
|
-
if (enumNode?.primitive === 'boolean') return { ...node, name: null }
|
|
28
|
-
if (enumNode) return { ...node, name: enumPropName(parentName, propName, enumSuffix) }
|
|
29
|
-
|
|
30
|
-
return undefined
|
|
31
|
-
},
|
|
32
|
-
})
|
|
33
|
-
}
|