@kubb/ast 4.33.5 → 4.35.0

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.
@@ -87,20 +87,20 @@ type NodeKind = 'Root' | 'Operation' | 'Schema' | 'Property' | 'Parameter' | 'Re
87
87
  /**
88
88
  * Common base for all AST nodes.
89
89
  */
90
- interface BaseNode {
90
+ type BaseNode = {
91
91
  kind: NodeKind;
92
- }
92
+ };
93
93
  //#endregion
94
94
  //#region src/nodes/property.d.ts
95
95
  /**
96
96
  * A named property within an object schema.
97
97
  */
98
- interface PropertyNode extends BaseNode {
98
+ type PropertyNode = BaseNode & {
99
99
  kind: 'Property';
100
100
  name: string;
101
101
  schema: SchemaNode;
102
102
  required: boolean;
103
- }
103
+ };
104
104
  //#endregion
105
105
  //#region src/nodes/schema.d.ts
106
106
  type PrimitiveSchemaType = 'string' | 'number' | 'integer' | 'bigint' | 'boolean' | 'null' | 'any' | 'unknown' | 'void' | 'object' | 'array' | 'date';
@@ -114,7 +114,7 @@ type ScalarSchemaType = Exclude<SchemaType, 'object' | 'array' | 'tuple' | 'unio
114
114
  /**
115
115
  * Base fields shared by every schema variant. Does not include spec-specific fields.
116
116
  */
117
- interface SchemaNodeBase extends BaseNode {
117
+ type SchemaNodeBase = BaseNode & {
118
118
  kind: 'Schema';
119
119
  /**
120
120
  * Named schema identifier (e.g. `"Pet"` from `#/components/schemas/Pet`). `undefined` for inline schemas.
@@ -137,11 +137,11 @@ interface SchemaNodeBase extends BaseNode {
137
137
  * Underlying primitive before format/semantic promotion (e.g. `'string'` for a `uuid` node).
138
138
  */
139
139
  primitive?: PrimitiveSchemaType;
140
- }
140
+ };
141
141
  /**
142
142
  * Object schema with ordered property definitions.
143
143
  */
144
- interface ObjectSchemaNode extends SchemaNodeBase {
144
+ type ObjectSchemaNode = SchemaNodeBase & {
145
145
  type: 'object';
146
146
  properties?: Array<PropertyNode>;
147
147
  /**
@@ -149,11 +149,11 @@ interface ObjectSchemaNode extends SchemaNodeBase {
149
149
  */
150
150
  additionalProperties?: SchemaNode | true;
151
151
  patternProperties?: Record<string, SchemaNode>;
152
- }
152
+ };
153
153
  /**
154
154
  * Array or tuple schema.
155
155
  */
156
- interface ArraySchemaNode extends SchemaNodeBase {
156
+ type ArraySchemaNode = SchemaNodeBase & {
157
157
  type: 'array' | 'tuple';
158
158
  items?: Array<SchemaNode>;
159
159
  /**
@@ -163,41 +163,41 @@ interface ArraySchemaNode extends SchemaNodeBase {
163
163
  min?: number;
164
164
  max?: number;
165
165
  unique?: boolean;
166
- }
166
+ };
167
167
  /**
168
168
  * Shared base for union and intersection schemas.
169
169
  */
170
- interface CompositeSchemaNodeBase extends SchemaNodeBase {
170
+ type CompositeSchemaNodeBase = SchemaNodeBase & {
171
171
  members?: Array<SchemaNode>;
172
- }
172
+ };
173
173
  /**
174
174
  * Union schema (`oneOf` / `anyOf`).
175
175
  */
176
- interface UnionSchemaNode extends CompositeSchemaNodeBase {
176
+ type UnionSchemaNode = CompositeSchemaNodeBase & {
177
177
  type: 'union';
178
178
  /**
179
179
  * Discriminator property from OAS `discriminator.propertyName`.
180
180
  */
181
181
  discriminatorPropertyName?: string;
182
- }
182
+ };
183
183
  /**
184
184
  * Intersection schema (`allOf`).
185
185
  */
186
- interface IntersectionSchemaNode extends CompositeSchemaNodeBase {
186
+ type IntersectionSchemaNode = CompositeSchemaNodeBase & {
187
187
  type: 'intersection';
188
- }
188
+ };
189
189
  /**
190
190
  * A named enum variant.
191
191
  */
192
- interface EnumValueNode {
192
+ type EnumValueNode = {
193
193
  name: string;
194
194
  value: string | number | boolean;
195
195
  format: 'string' | 'number' | 'boolean';
196
- }
196
+ };
197
197
  /**
198
198
  * Enum schema.
199
199
  */
200
- interface EnumSchemaNode extends SchemaNodeBase {
200
+ type EnumSchemaNode = SchemaNodeBase & {
201
201
  type: 'enum';
202
202
  /**
203
203
  * Enum member type. Generators should use const assertions for `'number'` / `'boolean'`.
@@ -211,11 +211,11 @@ interface EnumSchemaNode extends SchemaNodeBase {
211
211
  * Named variants (rich form). Takes priority over `enumValues` when present.
212
212
  */
213
213
  namedEnumValues?: Array<EnumValueNode>;
214
- }
214
+ };
215
215
  /**
216
216
  * Ref schema — pointer to another schema definition.
217
217
  */
218
- interface RefSchemaNode extends SchemaNodeBase {
218
+ type RefSchemaNode = SchemaNodeBase & {
219
219
  type: 'ref';
220
220
  name?: string;
221
221
  /**
@@ -226,11 +226,11 @@ interface RefSchemaNode extends SchemaNodeBase {
226
226
  * Pattern constraint propagated from a sibling `pattern` field next to the `$ref`.
227
227
  */
228
228
  pattern?: string;
229
- }
229
+ };
230
230
  /**
231
231
  * Datetime schema.
232
232
  */
233
- interface DatetimeSchemaNode extends SchemaNodeBase {
233
+ type DatetimeSchemaNode = SchemaNodeBase & {
234
234
  type: 'datetime';
235
235
  /**
236
236
  * Includes timezone offset (`dateType: 'stringOffset'`).
@@ -240,17 +240,17 @@ interface DatetimeSchemaNode extends SchemaNodeBase {
240
240
  * Local datetime without timezone (`dateType: 'stringLocal'`).
241
241
  */
242
242
  local?: boolean;
243
- }
243
+ };
244
244
  /**
245
245
  * Base for `date` and `time` schemas.
246
246
  */
247
- interface TemporalSchemaNodeBase<T extends 'date' | 'time'> extends SchemaNodeBase {
247
+ type TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {
248
248
  type: T;
249
249
  /**
250
250
  * Representation in generated code: native `Date` or plain string.
251
251
  */
252
252
  representation: 'date' | 'string';
253
- }
253
+ };
254
254
  /**
255
255
  * Date schema.
256
256
  */
@@ -262,28 +262,28 @@ type TimeSchemaNode = TemporalSchemaNodeBase<'time'>;
262
262
  /**
263
263
  * String schema.
264
264
  */
265
- interface StringSchemaNode extends SchemaNodeBase {
265
+ type StringSchemaNode = SchemaNodeBase & {
266
266
  type: 'string';
267
267
  min?: number;
268
268
  max?: number;
269
269
  pattern?: string;
270
- }
270
+ };
271
271
  /**
272
272
  * Number, integer, or bigint schema.
273
273
  */
274
- interface NumberSchemaNode extends SchemaNodeBase {
274
+ type NumberSchemaNode = SchemaNodeBase & {
275
275
  type: 'number' | 'integer' | 'bigint';
276
276
  min?: number;
277
277
  max?: number;
278
278
  exclusiveMinimum?: number;
279
279
  exclusiveMaximum?: number;
280
- }
280
+ };
281
281
  /**
282
282
  * Schema for scalar types with no additional constraints.
283
283
  */
284
- interface ScalarSchemaNode extends SchemaNodeBase {
284
+ type ScalarSchemaNode = SchemaNodeBase & {
285
285
  type: ScalarSchemaType;
286
- }
286
+ };
287
287
  /**
288
288
  * Maps each schema type string to its `SchemaNode` variant. Used by `narrowSchema`.
289
289
  */
@@ -322,13 +322,13 @@ type ParameterLocation = 'path' | 'query' | 'header' | 'cookie';
322
322
  /**
323
323
  * A single input parameter for an operation.
324
324
  */
325
- interface ParameterNode extends BaseNode {
325
+ type ParameterNode = BaseNode & {
326
326
  kind: 'Parameter';
327
327
  name: string;
328
328
  in: ParameterLocation;
329
329
  schema: SchemaNode;
330
330
  required: boolean;
331
- }
331
+ };
332
332
  //#endregion
333
333
  //#region src/nodes/http.d.ts
334
334
  /**
@@ -350,7 +350,7 @@ type MediaType = 'application/json' | 'application/xml' | 'application/x-www-for
350
350
  /**
351
351
  * A single response variant for an operation.
352
352
  */
353
- interface ResponseNode extends BaseNode {
353
+ type ResponseNode = BaseNode & {
354
354
  kind: 'Response';
355
355
  /**
356
356
  * HTTP status code or `'default'` for a fallback response.
@@ -359,14 +359,14 @@ interface ResponseNode extends BaseNode {
359
359
  description?: string;
360
360
  schema?: SchemaNode;
361
361
  mediaType?: MediaType;
362
- }
362
+ };
363
363
  //#endregion
364
364
  //#region src/nodes/operation.d.ts
365
365
  type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';
366
366
  /**
367
367
  * A spec-agnostic representation of a single API operation.
368
368
  */
369
- interface OperationNode extends BaseNode {
369
+ type OperationNode = BaseNode & {
370
370
  kind: 'Operation';
371
371
  /**
372
372
  * Unique operation identifier (maps to `operationId` in OAS).
@@ -384,17 +384,33 @@ interface OperationNode extends BaseNode {
384
384
  */
385
385
  requestBody?: SchemaNode;
386
386
  responses: Array<ResponseNode>;
387
- }
387
+ };
388
388
  //#endregion
389
389
  //#region src/nodes/root.d.ts
390
+ /**
391
+ * Format-agnostic metadata about the API document.
392
+ * Adapters populate whichever fields are available in their source format.
393
+ */
394
+ type RootMeta = {
395
+ /** API title (from `info.title` in OAS/AsyncAPI). */title?: string; /** API version string (from `info.version` in OAS/AsyncAPI). */
396
+ version?: string;
397
+ /**
398
+ * Resolved base URL for the API.
399
+ * OAS: derived from `servers[serverIndex].url` with variable substitution.
400
+ * AsyncAPI: derived from `servers[serverIndex].url`.
401
+ * Drizzle / schema-only formats: not set.
402
+ */
403
+ baseURL?: string;
404
+ };
390
405
  /**
391
406
  * Top-level container for all schemas and operations in a single API document.
392
407
  */
393
- interface RootNode extends BaseNode {
408
+ type RootNode = BaseNode & {
394
409
  kind: 'Root';
395
410
  schemas: Array<SchemaNode>;
396
- operations: Array<OperationNode>;
397
- }
411
+ operations: Array<OperationNode>; /** Format-agnostic document metadata populated by the adapter. */
412
+ meta?: RootMeta;
413
+ };
398
414
  //#endregion
399
415
  //#region src/nodes/index.d.ts
400
416
  /**
@@ -438,6 +454,105 @@ declare function createParameter(props: Pick<ParameterNode, 'name' | 'in' | 'sch
438
454
  */
439
455
  declare function createResponse(props: Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode'>>): ResponseNode;
440
456
  //#endregion
457
+ //#region src/printer.d.ts
458
+ /**
459
+ * Handler context for `definePrinter` — mirrors `PluginContext` from `@kubb/core`.
460
+ * Available as `this` inside each node handler.
461
+ */
462
+ type PrinterHandlerContext<TOutput, TOptions extends object> = {
463
+ /**
464
+ * Recursively print a nested `SchemaNode`.
465
+ */
466
+ print: (node: SchemaNode) => TOutput | null | undefined;
467
+ /**
468
+ * Options for this printer instance.
469
+ */
470
+ options: TOptions;
471
+ };
472
+ /**
473
+ * Handler for a specific `SchemaNode` variant identified by `SchemaType` key `T`.
474
+ * Use a regular function (not an arrow function) so that `this` is available.
475
+ */
476
+ type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (this: PrinterHandlerContext<TOutput, TOptions>, node: SchemaNodeByType[T]) => TOutput | null | undefined;
477
+ /**
478
+ * Shape of the type parameter passed to `definePrinter`.
479
+ * Mirrors `AdapterFactoryOptions` / `PluginFactoryOptions` from `@kubb/core`.
480
+ *
481
+ * - `TName` — unique string identifier (e.g. `'zod'`, `'ts'`)
482
+ * - `TOptions` — options passed to and stored on the printer
483
+ * - `TOutput` — the type emitted by `print` (typically `string`)
484
+ */
485
+ type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown> = {
486
+ name: TName;
487
+ options: TOptions;
488
+ output: TOutput;
489
+ };
490
+ /**
491
+ * The object returned by calling a `definePrinter` instance.
492
+ * Mirrors the shape of `Adapter` from `@kubb/core`.
493
+ */
494
+ type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {
495
+ /**
496
+ * Unique identifier supplied at creation time.
497
+ */
498
+ name: T['name'];
499
+ /**
500
+ * Options for this printer instance.
501
+ */
502
+ options: T['options'];
503
+ /**
504
+ * Emits `TOutput` from a `SchemaNode`. Returns `null | undefined` when no handler matches.
505
+ */
506
+ print: (node: SchemaNode) => T['output'] | null | undefined;
507
+ /**
508
+ * Maps `print` over an array of `SchemaNode`s.
509
+ */
510
+ for: (nodes: Array<SchemaNode>) => Array<T['output'] | null | undefined>;
511
+ };
512
+ type PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {
513
+ name: T['name'];
514
+ /**
515
+ * Options to store on the printer.
516
+ */
517
+ options: T['options'];
518
+ nodes: Partial<{ [K in SchemaType]: PrinterHandler<T['output'], T['options'], K> }>;
519
+ };
520
+ /**
521
+ * Creates a named printer factory. Mirrors the `definePlugin` / `defineAdapter` pattern
522
+ * from `@kubb/core` — wraps a builder to make options optional and separates raw options
523
+ * from resolved options.
524
+ *
525
+ * @example
526
+ * ```ts
527
+ * type ZodPrinter = PrinterFactoryOptions<'zod', { strict?: boolean }, { strict: boolean }, string>
528
+ *
529
+ * export const zodPrinter = definePrinter<ZodPrinter>((options) => {
530
+ * const { strict = true } = options
531
+ * return {
532
+ * name: 'zod',
533
+ * options: { strict },
534
+ * nodes: {
535
+ * string(node) {
536
+ * return `z.string()`
537
+ * },
538
+ * object(node) {
539
+ * const props = node.properties
540
+ * ?.map(p => `${p.name}: ${this.print(p)}`)
541
+ * .join(', ') ?? ''
542
+ * return `z.object({ ${props} })`
543
+ * },
544
+ * },
545
+ * }
546
+ * })
547
+ *
548
+ * const printer = zodPrinter({ strict: false })
549
+ * printer.name // 'zod'
550
+ * printer.options // { strict: false }
551
+ * printer.print(node) // 'z.string()'
552
+ * ```
553
+ */
554
+ declare function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T>;
555
+ //#endregion
441
556
  //#region src/refs.d.ts
442
557
  /**
443
558
  * Schema name to `SchemaNode` mapping.
@@ -462,43 +577,49 @@ declare function refMapToObject(refMap: RefMap): Record<string, SchemaNode>;
462
577
  */
463
578
  type VisitorOptions = {
464
579
  depth?: VisitorDepth;
580
+ /**
581
+ * Maximum number of sibling nodes visited concurrently inside `walk`.
582
+ * @default 30
583
+ */
584
+ concurrency?: number;
465
585
  };
466
586
  /**
467
587
  * Synchronous visitor for `transform` and `walk`.
468
588
  */
469
- interface Visitor {
589
+ type Visitor = {
470
590
  root?(node: RootNode): void | RootNode;
471
591
  operation?(node: OperationNode): void | OperationNode;
472
592
  schema?(node: SchemaNode): void | SchemaNode;
473
593
  property?(node: PropertyNode): void | PropertyNode;
474
594
  parameter?(node: ParameterNode): void | ParameterNode;
475
595
  response?(node: ResponseNode): void | ResponseNode;
476
- }
596
+ };
477
597
  type MaybePromise<T> = T | Promise<T>;
478
598
  /**
479
599
  * Async visitor for `walk`. Synchronous `Visitor` objects are compatible.
480
600
  */
481
- interface AsyncVisitor {
601
+ type AsyncVisitor = {
482
602
  root?(node: RootNode): MaybePromise<void | RootNode>;
483
603
  operation?(node: OperationNode): MaybePromise<void | OperationNode>;
484
604
  schema?(node: SchemaNode): MaybePromise<void | SchemaNode>;
485
605
  property?(node: PropertyNode): MaybePromise<void | PropertyNode>;
486
606
  parameter?(node: ParameterNode): MaybePromise<void | ParameterNode>;
487
607
  response?(node: ResponseNode): MaybePromise<void | ResponseNode>;
488
- }
608
+ };
489
609
  /**
490
610
  * Visitor for `collect`.
491
611
  */
492
- interface CollectVisitor<T> {
612
+ type CollectVisitor<T> = {
493
613
  root?(node: RootNode): T | undefined;
494
614
  operation?(node: OperationNode): T | undefined;
495
615
  schema?(node: SchemaNode): T | undefined;
496
616
  property?(node: PropertyNode): T | undefined;
497
617
  parameter?(node: ParameterNode): T | undefined;
498
618
  response?(node: ResponseNode): T | undefined;
499
- }
619
+ };
500
620
  /**
501
621
  * Depth-first traversal for side effects. Visitor return values are ignored.
622
+ * Sibling nodes at each level are visited concurrently up to `options.concurrency` (default: 30).
502
623
  */
503
624
  declare function walk(node: Node, visitor: AsyncVisitor, options?: VisitorOptions): Promise<void>;
504
625
  /**
@@ -516,5 +637,5 @@ declare function transform(node: Node, visitor: Visitor, options?: VisitorOption
516
637
  */
517
638
  declare function collect<T>(node: Node, visitor: CollectVisitor<T>, options?: VisitorOptions): Array<T>;
518
639
  //#endregion
519
- export { httpMethods as $, ComplexSchemaType as A, ScalarSchemaNode as B, ResponseNode as C, ParameterLocation as D, StatusCode as E, IntersectionSchemaNode as F, SpecialSchemaType as G, SchemaNode as H, NumberSchemaNode as I, UnionSchemaNode as J, StringSchemaNode as K, ObjectSchemaNode as L, DatetimeSchemaNode as M, EnumSchemaNode as N, ParameterNode as O, EnumValueNode as P, VisitorDepth as Q, PrimitiveSchemaType as R, OperationNode as S, MediaType as T, SchemaNodeByType as U, ScalarSchemaType as V, SchemaType as W, BaseNode as X, PropertyNode as Y, NodeKind as Z, createRoot as _, collect as a, RootNode as b, RefMap as c, resolveRef as d, mediaTypes as et, DistributiveOmit as f, createResponse as g, createProperty as h, VisitorOptions as i, DateSchemaNode as j, ArraySchemaNode as k, buildRefMap as l, createParameter as m, CollectVisitor as n, schemaTypes as nt, transform as o, createOperation as p, TimeSchemaNode as q, Visitor as r, walk as s, AsyncVisitor as t, nodeKinds as tt, refMapToObject as u, createSchema as v, HttpStatusCode as w, HttpMethod as x, Node as y, RefSchemaNode as z };
520
- //# sourceMappingURL=visitor-D9_Eb8I1.d.ts.map
640
+ export { NodeKind as $, ParameterNode as A, PrimitiveSchemaType as B, HttpMethod as C, MediaType as D, HttpStatusCode as E, EnumSchemaNode as F, SchemaNodeByType as G, ScalarSchemaNode as H, EnumValueNode as I, StringSchemaNode as J, SchemaType as K, IntersectionSchemaNode as L, ComplexSchemaType as M, DateSchemaNode as N, StatusCode as O, DatetimeSchemaNode as P, BaseNode as Q, NumberSchemaNode as R, RootNode as S, ResponseNode as T, ScalarSchemaType as U, RefSchemaNode as V, SchemaNode as W, UnionSchemaNode as X, TimeSchemaNode as Y, PropertyNode as Z, createResponse as _, transform as a, Node as b, buildRefMap as c, Printer as d, VisitorDepth as et, definePrinter as f, createProperty as g, createParameter as h, collect as i, schemaTypes as it, ArraySchemaNode as j, ParameterLocation as k, refMapToObject as l, createOperation as m, CollectVisitor as n, mediaTypes as nt, walk as o, DistributiveOmit as p, SpecialSchemaType as q, Visitor as r, nodeKinds as rt, RefMap as s, AsyncVisitor as t, httpMethods as tt, resolveRef as u, createRoot as v, OperationNode as w, RootMeta as x, createSchema as y, ObjectSchemaNode as z };
641
+ //# sourceMappingURL=visitor-8N3AiSUr.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/ast",
3
- "version": "4.33.5",
3
+ "version": "4.35.0",
4
4
  "description": "Spec-agnostic AST layer for Kubb. Defines nodes, visitor pattern, and factory functions used across codegen plugins.",
5
5
  "keywords": [
6
6
  "kubb",
package/src/constants.ts CHANGED
@@ -76,6 +76,11 @@ export const parameterLocations = {
76
76
  cookie: 'cookie',
77
77
  } as const satisfies Record<ParameterLocation, ParameterLocation>
78
78
 
79
+ /**
80
+ * Default max concurrent visitor calls in `walk`.
81
+ */
82
+ export const WALK_CONCURRENCY = 30
83
+
79
84
  /**
80
85
  * Fallback status code string for API spec responses.
81
86
  */
package/src/guards.ts CHANGED
@@ -8,7 +8,7 @@ export function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | un
8
8
  }
9
9
 
10
10
  function isKind<T extends Node>(kind: NodeKind) {
11
- return (node: Node): node is T => node.kind === kind
11
+ return (node: unknown): node is T => (node as Node).kind === kind
12
12
  }
13
13
 
14
14
  /**
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { httpMethods, mediaTypes, nodeKinds, schemaTypes } from './constants.ts'
2
2
  export { createOperation, createParameter, createProperty, createResponse, createRoot, createSchema } from './factory.ts'
3
3
  export { isOperationNode, isParameterNode, isPropertyNode, isResponseNode, isRootNode, isSchemaNode, narrowSchema } from './guards.ts'
4
+ export { definePrinter } from './printer.ts'
4
5
  export { buildRefMap, refMapToObject, resolveRef } from './refs.ts'
5
6
  export { collect, transform, walk } from './visitor.ts'
package/src/nodes/base.ts CHANGED
@@ -6,7 +6,7 @@ export type NodeKind = 'Root' | 'Operation' | 'Schema' | 'Property' | 'Parameter
6
6
  /**
7
7
  * Common base for all AST nodes.
8
8
  */
9
- export interface BaseNode {
9
+ export type BaseNode = {
10
10
  kind: NodeKind
11
11
  }
12
12
 
@@ -11,7 +11,7 @@ export type { HttpMethod, OperationNode } from './operation.ts'
11
11
  export type { ParameterLocation, ParameterNode } from './parameter.ts'
12
12
  export type { PropertyNode } from './property.ts'
13
13
  export type { ResponseNode } from './response.ts'
14
- export type { RootNode } from './root.ts'
14
+ export type { RootMeta, RootNode } from './root.ts'
15
15
  export type {
16
16
  ArraySchemaNode,
17
17
  ComplexSchemaType,
@@ -8,7 +8,7 @@ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' |
8
8
  /**
9
9
  * A spec-agnostic representation of a single API operation.
10
10
  */
11
- export interface OperationNode extends BaseNode {
11
+ export type OperationNode = BaseNode & {
12
12
  kind: 'Operation'
13
13
  /**
14
14
  * Unique operation identifier (maps to `operationId` in OAS).
@@ -6,7 +6,7 @@ export type ParameterLocation = 'path' | 'query' | 'header' | 'cookie'
6
6
  /**
7
7
  * A single input parameter for an operation.
8
8
  */
9
- export interface ParameterNode extends BaseNode {
9
+ export type ParameterNode = BaseNode & {
10
10
  kind: 'Parameter'
11
11
  name: string
12
12
  in: ParameterLocation
@@ -4,7 +4,7 @@ import type { SchemaNode } from './schema.ts'
4
4
  /**
5
5
  * A named property within an object schema.
6
6
  */
7
- export interface PropertyNode extends BaseNode {
7
+ export type PropertyNode = BaseNode & {
8
8
  kind: 'Property'
9
9
  name: string
10
10
  schema: SchemaNode
@@ -5,7 +5,7 @@ import type { SchemaNode } from './schema.ts'
5
5
  /**
6
6
  * A single response variant for an operation.
7
7
  */
8
- export interface ResponseNode extends BaseNode {
8
+ export type ResponseNode = BaseNode & {
9
9
  kind: 'Response'
10
10
  /**
11
11
  * HTTP status code or `'default'` for a fallback response.
package/src/nodes/root.ts CHANGED
@@ -2,11 +2,31 @@ import type { BaseNode } from './base.ts'
2
2
  import type { OperationNode } from './operation.ts'
3
3
  import type { SchemaNode } from './schema.ts'
4
4
 
5
+ /**
6
+ * Format-agnostic metadata about the API document.
7
+ * Adapters populate whichever fields are available in their source format.
8
+ */
9
+ export type RootMeta = {
10
+ /** API title (from `info.title` in OAS/AsyncAPI). */
11
+ title?: string
12
+ /** API version string (from `info.version` in OAS/AsyncAPI). */
13
+ version?: string
14
+ /**
15
+ * Resolved base URL for the API.
16
+ * OAS: derived from `servers[serverIndex].url` with variable substitution.
17
+ * AsyncAPI: derived from `servers[serverIndex].url`.
18
+ * Drizzle / schema-only formats: not set.
19
+ */
20
+ baseURL?: string
21
+ }
22
+
5
23
  /**
6
24
  * Top-level container for all schemas and operations in a single API document.
7
25
  */
8
- export interface RootNode extends BaseNode {
26
+ export type RootNode = BaseNode & {
9
27
  kind: 'Root'
10
28
  schemas: Array<SchemaNode>
11
29
  operations: Array<OperationNode>
30
+ /** Format-agnostic document metadata populated by the adapter. */
31
+ meta?: RootMeta
12
32
  }