@kubb/ast 5.0.0-alpha.31 → 5.0.0-alpha.33

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/ast",
3
- "version": "5.0.0-alpha.31",
3
+ "version": "5.0.0-alpha.33",
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
@@ -15,7 +15,8 @@ export const visitorDepths = {
15
15
  } as const satisfies Record<VisitorDepth, VisitorDepth>
16
16
 
17
17
  export const nodeKinds = {
18
- root: 'Root',
18
+ input: 'Input',
19
+ output: 'Output',
19
20
  operation: 'Operation',
20
21
  schema: 'Schema',
21
22
  property: 'Property',
@@ -24,6 +25,13 @@ export const nodeKinds = {
24
25
  functionParameter: 'FunctionParameter',
25
26
  parameterGroup: 'ParameterGroup',
26
27
  functionParameters: 'FunctionParameters',
28
+ type: 'Type',
29
+ file: 'File',
30
+ import: 'Import',
31
+ export: 'Export',
32
+ source: 'Source',
33
+ text: 'Text',
34
+ break: 'Break',
27
35
  } as const satisfies Record<string, NodeKind>
28
36
 
29
37
  /**
package/src/factory.ts CHANGED
@@ -1,18 +1,34 @@
1
+ import { createHash } from 'node:crypto'
2
+ import path from 'node:path'
3
+ import { trimExtName } from '@internals/utils'
1
4
  import type { InferSchemaNode } from './infer.ts'
2
5
  import type {
6
+ ArrowFunctionNode,
7
+ BreakNode,
8
+ ConstNode,
9
+ ExportNode,
10
+ FileNode,
11
+ FunctionNode,
3
12
  FunctionParameterNode,
4
13
  FunctionParametersNode,
14
+ ImportNode,
15
+ InputNode,
16
+ JsxNode,
5
17
  ObjectSchemaNode,
6
18
  OperationNode,
19
+ OutputNode,
7
20
  ParameterGroupNode,
8
21
  ParameterNode,
22
+ ParamsTypeNode,
9
23
  PrimitiveSchemaType,
10
24
  PropertyNode,
11
25
  ResponseNode,
12
- RootNode,
13
26
  SchemaNode,
27
+ SourceNode,
28
+ TextNode,
14
29
  TypeNode,
15
30
  } from './nodes/index.ts'
31
+ import { combineExports, combineImports, combineSources, extractStringsFromNodes } from './utils.ts'
16
32
 
17
33
  /**
18
34
  * Syncs property/parameter schema optionality flags from `required` and `schema.nullable`.
@@ -48,26 +64,48 @@ type CreateSchemaInput = CreateSchemaObjectInput | DistributiveOmit<Exclude<Sche
48
64
  type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & { kind: 'Schema' }
49
65
 
50
66
  /**
51
- * Creates a `RootNode` with stable defaults for `schemas` and `operations`.
67
+ * Creates an `InputNode` with stable defaults for `schemas` and `operations`.
52
68
  *
53
69
  * @example
54
70
  * ```ts
55
- * const root = createRoot()
56
- * // { kind: 'Root', schemas: [], operations: [] }
71
+ * const input = createInput()
72
+ * // { kind: 'Input', schemas: [], operations: [] }
57
73
  * ```
58
74
  *
59
75
  * @example
60
76
  * ```ts
61
- * const root = createRoot({ schemas: [petSchema] })
77
+ * const input = createInput({ schemas: [petSchema] })
62
78
  * // keeps default operations: []
63
79
  * ```
64
80
  */
65
- export function createRoot(overrides: Partial<Omit<RootNode, 'kind'>> = {}): RootNode {
81
+ export function createInput(overrides: Partial<Omit<InputNode, 'kind'>> = {}): InputNode {
66
82
  return {
67
83
  schemas: [],
68
84
  operations: [],
69
85
  ...overrides,
70
- kind: 'Root',
86
+ kind: 'Input',
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Creates an `OutputNode` with a stable default for `files`.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * const output = createOutput()
96
+ * // { kind: 'Output', files: [] }
97
+ * ```
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * const output = createOutput({ files: [petFile] })
102
+ * ```
103
+ */
104
+ export function createOutput(overrides: Partial<Omit<OutputNode, 'kind'>> = {}): OutputNode {
105
+ return {
106
+ files: [],
107
+ ...overrides,
108
+ kind: 'Output',
71
109
  }
72
110
  }
73
111
 
@@ -176,6 +214,8 @@ export function createSchema(props: CreateSchemaInput): SchemaNode {
176
214
  return { primitive: inferredPrimitive, ...props, kind: 'Schema' } as CreateSchemaOutput<typeof props>
177
215
  }
178
216
 
217
+ type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>
218
+
179
219
  /**
180
220
  * Creates a `PropertyNode`.
181
221
  *
@@ -201,7 +241,7 @@ export function createSchema(props: CreateSchemaInput): SchemaNode {
201
241
  * // required=true, no optional/nullish
202
242
  * ```
203
243
  */
204
- export function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode {
244
+ export function createProperty(props: UserPropertyNode): PropertyNode {
205
245
  const required = props.required ?? false
206
246
 
207
247
  return {
@@ -278,24 +318,24 @@ export function createResponse(
278
318
  *
279
319
  * @example Required typed param
280
320
  * ```ts
281
- * createFunctionParameter({ name: 'petId', type: createTypeNode({ variant: 'reference', name: 'string' }) })
321
+ * createFunctionParameter({ name: 'petId', type: createParamsType({ variant: 'reference', name: 'string' }) })
282
322
  * // → petId: string
283
323
  * ```
284
324
  *
285
325
  * @example Optional param
286
326
  * ```ts
287
- * createFunctionParameter({ name: 'params', type: createTypeNode({ variant: 'reference', name: 'QueryParams' }), optional: true })
327
+ * createFunctionParameter({ name: 'params', type: createParamsType({ variant: 'reference', name: 'QueryParams' }), optional: true })
288
328
  * // → params?: QueryParams
289
329
  * ```
290
330
  *
291
331
  * @example Param with default (implicitly optional; cannot combine with `optional: true`)
292
332
  * ```ts
293
- * createFunctionParameter({ name: 'config', type: createTypeNode({ variant: 'reference', name: 'RequestConfig' }), default: '{}' })
333
+ * createFunctionParameter({ name: 'config', type: createParamsType({ variant: 'reference', name: 'RequestConfig' }), default: '{}' })
294
334
  * // → config: RequestConfig = {}
295
335
  * ```
296
336
  */
297
337
  export function createFunctionParameter(
298
- props: { name: string; type?: TypeNode; rest?: boolean } & ({ optional: true; default?: never } | { optional?: false; default?: string }),
338
+ props: { name: string; type?: ParamsTypeNode; rest?: boolean } & ({ optional: true; default?: never } | { optional?: false; default?: string }),
299
339
  ): FunctionParameterNode {
300
340
  return {
301
341
  optional: false,
@@ -313,26 +353,26 @@ export function createFunctionParameter(
313
353
  *
314
354
  * @example Reference type (TypeScript: `QueryParams`)
315
355
  * ```ts
316
- * createTypeNode({ variant: 'reference', name: 'QueryParams' })
356
+ * createParamsType({ variant: 'reference', name: 'QueryParams' })
317
357
  * ```
318
358
  *
319
359
  * @example Struct type (TypeScript: `{ petId: string }`)
320
360
  * ```ts
321
- * createTypeNode({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createTypeNode({ variant: 'reference', name: 'string' }) }] })
361
+ * createParamsType({ variant: 'struct', properties: [{ name: 'petId', optional: false, type: createParamsType({ variant: 'reference', name: 'string' }) }] })
322
362
  * ```
323
363
  *
324
364
  * @example Member type (TypeScript: `DeletePetPathParams['petId']`)
325
365
  * ```ts
326
- * createTypeNode({ variant: 'member', base: 'DeletePetPathParams', key: 'petId' })
366
+ * createParamsType({ variant: 'member', base: 'DeletePetPathParams', key: 'petId' })
327
367
  * ```
328
368
  */
329
- export function createTypeNode(
369
+ export function createParamsType(
330
370
  props:
331
371
  | { variant: 'reference'; name: string }
332
- | { variant: 'struct'; properties: Array<{ name: string; optional: boolean; type: TypeNode }> }
372
+ | { variant: 'struct'; properties: Array<{ name: string; optional: boolean; type: ParamsTypeNode }> }
333
373
  | { variant: 'member'; base: string; key: string },
334
- ): TypeNode {
335
- return { ...props, kind: 'Type' } as TypeNode
374
+ ): ParamsTypeNode {
375
+ return { ...props, kind: 'ParamsType' } as ParamsTypeNode
336
376
  }
337
377
 
338
378
  /**
@@ -342,8 +382,8 @@ export function createTypeNode(
342
382
  * ```ts
343
383
  * createParameterGroup({
344
384
  * properties: [
345
- * createFunctionParameter({ name: 'id', type: createTypeNode({ variant: 'reference', name: 'string' }), optional: false }),
346
- * createFunctionParameter({ name: 'name', type: createTypeNode({ variant: 'reference', name: 'string' }), optional: true }),
385
+ * createFunctionParameter({ name: 'id', type: createParamsType({ variant: 'reference', name: 'string' }), optional: false }),
386
+ * createFunctionParameter({ name: 'name', type: createParamsType({ variant: 'reference', name: 'string' }), optional: true }),
347
387
  * ],
348
388
  * default: '{}',
349
389
  * })
@@ -354,7 +394,7 @@ export function createTypeNode(
354
394
  * @example Inline (spread) — children emitted as individual top-level parameters
355
395
  * ```ts
356
396
  * createParameterGroup({
357
- * properties: [createFunctionParameter({ name: 'petId', type: createTypeNode({ variant: 'reference', name: 'string' }), optional: false })],
397
+ * properties: [createFunctionParameter({ name: 'petId', type: createParamsType({ variant: 'reference', name: 'string' }), optional: false })],
358
398
  * inline: true,
359
399
  * })
360
400
  * // declaration → petId: string
@@ -377,8 +417,8 @@ export function createParameterGroup(
377
417
  * ```ts
378
418
  * createFunctionParameters({
379
419
  * params: [
380
- * createFunctionParameter({ name: 'petId', type: createTypeNode({ variant: 'reference', name: 'string' }), optional: false }),
381
- * createFunctionParameter({ name: 'config', type: createTypeNode({ variant: 'reference', name: 'RequestConfig' }), optional: false, default: '{}' }),
420
+ * createFunctionParameter({ name: 'petId', type: createParamsType({ variant: 'reference', name: 'string' }), optional: false }),
421
+ * createFunctionParameter({ name: 'config', type: createParamsType({ variant: 'reference', name: 'RequestConfig' }), optional: false, default: '{}' }),
382
422
  * ],
383
423
  * })
384
424
  * ```
@@ -396,3 +436,289 @@ export function createFunctionParameters(props: Partial<Omit<FunctionParametersN
396
436
  kind: 'FunctionParameters',
397
437
  }
398
438
  }
439
+
440
+ /**
441
+ * Creates an `ImportNode` representing a language-agnostic import/dependency declaration.
442
+ *
443
+ * @example Named import
444
+ * ```ts
445
+ * createImport({ name: ['useState'], path: 'react' })
446
+ * // import { useState } from 'react'
447
+ * ```
448
+ *
449
+ * @example Type-only import
450
+ * ```ts
451
+ * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })
452
+ * // import type { FC } from 'react'
453
+ * ```
454
+ */
455
+ export function createImport(props: Omit<ImportNode, 'kind'>): ImportNode {
456
+ return { ...props, kind: 'Import' }
457
+ }
458
+
459
+ /**
460
+ * Creates an `ExportNode` representing a language-agnostic export/public API declaration.
461
+ *
462
+ * @example Named export
463
+ * ```ts
464
+ * createExport({ name: ['Pet'], path: './Pet' })
465
+ * // export { Pet } from './Pet'
466
+ * ```
467
+ *
468
+ * @example Wildcard export
469
+ * ```ts
470
+ * createExport({ path: './utils' })
471
+ * // export * from './utils'
472
+ * ```
473
+ */
474
+ export function createExport(props: Omit<ExportNode, 'kind'>): ExportNode {
475
+ return { ...props, kind: 'Export' }
476
+ }
477
+
478
+ /**
479
+ * Creates a `SourceNode` representing a fragment of source code within a file.
480
+ *
481
+ * @example
482
+ * ```ts
483
+ * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })
484
+ * ```
485
+ */
486
+ export function createSource(props: Omit<SourceNode, 'kind'>): SourceNode {
487
+ return { ...props, kind: 'Source' }
488
+ }
489
+
490
+ type UserFileNode<TMeta extends object = object> = Omit<FileNode<TMeta>, 'kind' | 'id' | 'name' | 'extname' | 'imports' | 'exports' | 'sources'> &
491
+ Pick<Partial<FileNode<TMeta>>, 'imports' | 'exports' | 'sources'>
492
+
493
+ /**
494
+ * Creates a fully resolved `FileNode` from a file input descriptor.
495
+ *
496
+ * Computes:
497
+ * - `id` — SHA256 hash of the file path
498
+ * - `name` — `baseName` without extension
499
+ * - `extname` — extension extracted from `baseName`
500
+ *
501
+ * Deduplicates:
502
+ * - `sources` via `combineSources`
503
+ * - `exports` via `combineExports`
504
+ * - `imports` via `combineImports` (also filters unused imports)
505
+ *
506
+ * @throws {Error} when `baseName` has no extension.
507
+ *
508
+ * @example
509
+ * ```ts
510
+ * const file = createFile({
511
+ * baseName: 'petStore.ts',
512
+ * path: 'src/models/petStore.ts',
513
+ * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')] })],
514
+ * imports: [createImport({ name: ['z'], path: 'zod' })],
515
+ * exports: [createExport({ name: ['Pet'], path: './petStore' })],
516
+ * })
517
+ * // file.id = SHA256 hash of 'src/models/petStore.ts'
518
+ * // file.name = 'petStore'
519
+ * // file.extname = '.ts'
520
+ * ```
521
+ */
522
+ export function createFile<TMeta extends object = object>(input: UserFileNode<TMeta>): FileNode<TMeta> {
523
+ const rawExtname = path.extname(input.baseName)
524
+ // Handle dotfile basename like '.ts' where path.extname returns ''
525
+ const extname = (rawExtname || (input.baseName.startsWith('.') ? input.baseName : '')) as `.${string}`
526
+ if (!extname) {
527
+ throw new Error(`No extname found for ${input.baseName}`)
528
+ }
529
+
530
+ const source = (input.sources ?? [])
531
+ .flatMap((item) => item.nodes ?? [])
532
+ .map((node) => extractStringsFromNodes([node]))
533
+ .filter(Boolean)
534
+ .join('\n\n')
535
+ const resolvedExports = input.exports?.length ? combineExports(input.exports) : []
536
+ const resolvedImports = input.imports?.length ? combineImports(input.imports, resolvedExports, source || undefined) : []
537
+ const resolvedSources = input.sources?.length ? combineSources(input.sources) : []
538
+
539
+ return {
540
+ kind: 'File',
541
+ ...input,
542
+ id: createHash('sha256').update(input.path).digest('hex'),
543
+ name: trimExtName(input.baseName),
544
+ extname,
545
+ imports: resolvedImports,
546
+ exports: resolvedExports,
547
+ sources: resolvedSources,
548
+ meta: input.meta ?? ({} as TMeta),
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Creates a `ConstNode` representing a TypeScript `const` declaration.
554
+ *
555
+ * Mirrors the `Const` component from `@kubb/renderer-jsx`.
556
+ * The component's `children` are represented as `nodes`.
557
+ *
558
+ * @example Simple constant
559
+ * ```ts
560
+ * createConst({ name: 'pet' })
561
+ * // const pet = ...
562
+ * ```
563
+ *
564
+ * @example Exported constant with type and `as const`
565
+ * ```ts
566
+ * createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true })
567
+ * // export const pets: Pet[] = ... as const
568
+ * ```
569
+ *
570
+ * @example With JSDoc and child nodes
571
+ * ```ts
572
+ * createConst({
573
+ * name: 'config',
574
+ * export: true,
575
+ * JSDoc: { comments: ['@description App configuration'] },
576
+ * nodes: [],
577
+ * })
578
+ * ```
579
+ */
580
+ export function createConst(props: Omit<ConstNode, 'kind'>): ConstNode {
581
+ return { ...props, kind: 'Const' }
582
+ }
583
+
584
+ /**
585
+ * Creates a `TypeNode` representing a TypeScript `type` alias declaration.
586
+ *
587
+ * Mirrors the `Type` component from `@kubb/renderer-jsx`.
588
+ * The component's `children` are represented as `nodes`.
589
+ *
590
+ * @example Simple type alias
591
+ * ```ts
592
+ * createType({ name: 'Pet' })
593
+ * // type Pet = ...
594
+ * ```
595
+ *
596
+ * @example Exported type with JSDoc
597
+ * ```ts
598
+ * createType({
599
+ * name: 'PetStatus',
600
+ * export: true,
601
+ * JSDoc: { comments: ['@description Status of a pet'] },
602
+ * })
603
+ * // export type PetStatus = ...
604
+ * ```
605
+ */
606
+ export function createType(props: Omit<TypeNode, 'kind'>): TypeNode {
607
+ return { ...props, kind: 'Type' }
608
+ }
609
+
610
+ /**
611
+ * Creates a `FunctionNode` representing a TypeScript `function` declaration.
612
+ *
613
+ * Mirrors the `Function` component from `@kubb/renderer-jsx`.
614
+ * The component's `children` are represented as `nodes`.
615
+ *
616
+ * @example Simple function
617
+ * ```ts
618
+ * createFunction({ name: 'getPet' })
619
+ * // function getPet() { ... }
620
+ * ```
621
+ *
622
+ * @example Exported async function with return type
623
+ * ```ts
624
+ * createFunction({ name: 'fetchPet', export: true, async: true, returnType: 'Pet' })
625
+ * // export async function fetchPet(): Promise<Pet> { ... }
626
+ * ```
627
+ *
628
+ * @example Function with generics and params
629
+ * ```ts
630
+ * createFunction({
631
+ * name: 'identity',
632
+ * export: true,
633
+ * generics: ['T'],
634
+ * params: 'value: T',
635
+ * returnType: 'T',
636
+ * })
637
+ * // export function identity<T>(value: T): T { ... }
638
+ * ```
639
+ */
640
+ export function createFunction(props: Omit<FunctionNode, 'kind'>): FunctionNode {
641
+ return { ...props, kind: 'Function' }
642
+ }
643
+
644
+ /**
645
+ * Creates an `ArrowFunctionNode` representing a TypeScript arrow function.
646
+ *
647
+ * Mirrors the `Function.Arrow` component from `@kubb/renderer-jsx`.
648
+ * The component's `children` are represented as `nodes`.
649
+ *
650
+ * @example Simple arrow function
651
+ * ```ts
652
+ * createArrowFunction({ name: 'getPet' })
653
+ * // const getPet = () => { ... }
654
+ * ```
655
+ *
656
+ * @example Single-line exported arrow function
657
+ * ```ts
658
+ * createArrowFunction({ name: 'double', export: true, params: 'n: number', singleLine: true })
659
+ * // export const double = (n: number) => ...
660
+ * ```
661
+ *
662
+ * @example Async arrow function with generics
663
+ * ```ts
664
+ * createArrowFunction({
665
+ * name: 'fetchPet',
666
+ * export: true,
667
+ * async: true,
668
+ * generics: ['T'],
669
+ * params: 'id: string',
670
+ * returnType: 'T',
671
+ * })
672
+ * // export const fetchPet = async <T>(id: string): Promise<T> => { ... }
673
+ * ```
674
+ */
675
+ export function createArrowFunction(props: Omit<ArrowFunctionNode, 'kind'>): ArrowFunctionNode {
676
+ return { ...props, kind: 'ArrowFunction' }
677
+ }
678
+
679
+ /**
680
+ * Creates a {@link TextNode} representing a raw string fragment in the source output.
681
+ *
682
+ * Use this instead of bare strings when building `nodes` arrays so that every
683
+ * entry in the array is a typed {@link CodeNode}.
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * createText('return fetch(id)')
688
+ * // { kind: 'Text', value: 'return fetch(id)' }
689
+ * ```
690
+ */
691
+ export function createText(value: string): TextNode {
692
+ return { value, kind: 'Text' }
693
+ }
694
+
695
+ /**
696
+ * Creates a {@link BreakNode} representing a line break in the source output.
697
+ *
698
+ * Corresponds to `<br/>` in JSX components. Prints as an empty string which,
699
+ * when joined with `\n` by `printNodes`, produces a blank line.
700
+ *
701
+ * @example
702
+ * ```ts
703
+ * createBreak()
704
+ * // { kind: 'Break' }
705
+ * ```
706
+ */
707
+ export function createBreak(): BreakNode {
708
+ return { kind: 'Break' }
709
+ }
710
+
711
+ /**
712
+ * Creates a {@link JsxNode} representing a raw JSX fragment in the source output.
713
+ *
714
+ * Use this to embed JSX markup (including fragments `<>…</>`) directly in generated code.
715
+ *
716
+ * @example
717
+ * ```ts
718
+ * createJsx('<>\n <a href={href}>Open</a>\n</>')
719
+ * // { kind: 'Jsx', value: '<>\n <a href={href}>Open</a>\n</>' }
720
+ * ```
721
+ */
722
+ export function createJsx(value: string): JsxNode {
723
+ return { value, kind: 'Jsx' }
724
+ }
package/src/guards.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  import type {
2
2
  FunctionParameterNode,
3
3
  FunctionParametersNode,
4
+ InputNode,
4
5
  Node,
5
6
  NodeKind,
6
7
  OperationNode,
8
+ OutputNode,
7
9
  ParameterGroupNode,
8
10
  ParameterNode,
9
11
  PropertyNode,
10
12
  ResponseNode,
11
- RootNode,
12
13
  SchemaNode,
13
14
  SchemaNodeByType,
14
15
  } from './nodes/index.ts'
@@ -31,16 +32,28 @@ function isKind<T extends Node>(kind: NodeKind) {
31
32
  }
32
33
 
33
34
  /**
34
- * Returns `true` when the input is a `RootNode`.
35
+ * Returns `true` when the input is an `InputNode`.
35
36
  *
36
37
  * @example
37
38
  * ```ts
38
- * if (isRootNode(node)) {
39
+ * if (isInputNode(node)) {
39
40
  * console.log(node.schemas.length)
40
41
  * }
41
42
  * ```
42
43
  */
43
- export const isRootNode = isKind<RootNode>('Root')
44
+ export const isInputNode = isKind<InputNode>('Input')
45
+
46
+ /**
47
+ * Returns `true` when the input is an `OutputNode`.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * if (isOutputNode(node)) {
52
+ * console.log(node.files.length)
53
+ * }
54
+ * ```
55
+ */
56
+ export const isOutputNode = isKind<OutputNode>('Output')
44
57
 
45
58
  /**
46
59
  * Returns `true` when the input is an `OperationNode`.
package/src/index.ts CHANGED
@@ -1,19 +1,31 @@
1
1
  export type { ScalarPrimitive } from './constants.ts'
2
- export { httpMethods, isScalarPrimitive, mediaTypes, schemaTypes } from './constants.ts'
2
+ export { httpMethods, isScalarPrimitive, mediaTypes, nodeKinds, schemaTypes } from './constants.ts'
3
3
  export {
4
+ createArrowFunction,
5
+ createBreak,
6
+ createConst,
7
+ createExport,
8
+ createFile,
9
+ createFunction,
4
10
  createFunctionParameter,
5
11
  createFunctionParameters,
12
+ createImport,
13
+ createInput,
14
+ createJsx,
6
15
  createOperation,
16
+ createOutput,
7
17
  createParameter,
8
18
  createParameterGroup,
19
+ createParamsType,
9
20
  createProperty,
10
21
  createResponse,
11
- createRoot,
12
22
  createSchema,
13
- createTypeNode,
23
+ createSource,
24
+ createText,
25
+ createType,
14
26
  syncOptionality,
15
27
  } from './factory.ts'
16
- export { isOperationNode, isSchemaNode, narrowSchema } from './guards.ts'
28
+ export { isInputNode, isOperationNode, isOutputNode, isSchemaNode, narrowSchema } from './guards.ts'
17
29
  export type { ParserOptions } from './infer.ts'
18
30
  export type { Printer, PrinterFactoryOptions, PrinterPartial } from './printer.ts'
19
31
  export { createPrinterFactory, definePrinter } from './printer.ts'
@@ -21,5 +33,12 @@ export { extractRefName } from './refs.ts'
21
33
  export { childName, collectImports, enumPropName, findDiscriminator } from './resolvers.ts'
22
34
  export { mergeAdjacentObjects, setDiscriminatorEnum, setEnumName, simplifyUnion } from './transformers.ts'
23
35
  export type { OperationParamsResolver } from './utils.ts'
24
- export { caseParams, createDiscriminantNode, createOperationParams, isStringType, syncSchemaRef } from './utils.ts'
36
+ export {
37
+ caseParams,
38
+ createDiscriminantNode,
39
+ createOperationParams,
40
+ extractStringsFromNodes,
41
+ isStringType,
42
+ syncSchemaRef,
43
+ } from './utils.ts'
25
44
  export { collect, composeTransformers, transform, walk } from './visitor.ts'
package/src/mocks.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { createOperation, createParameter, createProperty, createResponse, createRoot, createSchema } from './factory.ts'
2
- import type { RootNode } from './nodes/root.ts'
1
+ import { createInput, createOperation, createParameter, createProperty, createResponse, createSchema } from './factory.ts'
2
+ import type { InputNode } from './nodes/root.ts'
3
3
 
4
4
  /**
5
5
  * Builds a minimal sample AST with one `Pet` schema and one `getPetById` operation.
6
6
  */
7
- export function buildSampleTree(): RootNode {
7
+ export function buildSampleTree(): InputNode {
8
8
  const petSchema = createSchema({
9
9
  type: 'object',
10
10
  name: 'Pet',
@@ -29,7 +29,7 @@ export function buildSampleTree(): RootNode {
29
29
  ],
30
30
  })
31
31
 
32
- return createRoot({ schemas: [petSchema], operations: [operation] })
32
+ return createInput({ schemas: [petSchema], operations: [operation] })
33
33
  }
34
34
 
35
35
  /**
@@ -37,11 +37,11 @@ export function buildSampleTree(): RootNode {
37
37
  * - six named schemas (`Pet`, `NewPet`, `PetList`, `Error`, `PetOrError`, `FullPet`)
38
38
  * - two operations (`listPets`, `createPet`)
39
39
  */
40
- export function buildFixture(): RootNode {
40
+ export function buildFixture(): InputNode {
41
41
  const refPet = createSchema({ type: 'ref', ref: 'Pet' })
42
42
  const refError = createSchema({ type: 'ref', ref: 'Error' })
43
43
 
44
- return createRoot({
44
+ return createInput({
45
45
  schemas: [
46
46
  createSchema({
47
47
  name: 'Pet',
package/src/nodes/base.ts CHANGED
@@ -7,7 +7,8 @@
7
7
  * ```
8
8
  */
9
9
  export type NodeKind =
10
- | 'Root'
10
+ | 'Input'
11
+ | 'Output'
11
12
  | 'Operation'
12
13
  | 'Schema'
13
14
  | 'Property'
@@ -17,13 +18,24 @@ export type NodeKind =
17
18
  | 'ParameterGroup'
18
19
  | 'FunctionParameters'
19
20
  | 'Type'
21
+ | 'ParamsType'
22
+ | 'File'
23
+ | 'Import'
24
+ | 'Export'
25
+ | 'Source'
26
+ | 'Const'
27
+ | 'Function'
28
+ | 'ArrowFunction'
29
+ | 'Text'
30
+ | 'Break'
31
+ | 'Jsx'
20
32
 
21
33
  /**
22
34
  * Base shape shared by all AST nodes.
23
35
  *
24
36
  * @example
25
37
  * ```ts
26
- * const base: BaseNode = { kind: 'Root' }
38
+ * const base: BaseNode = { kind: 'Input' }
27
39
  * ```
28
40
  */
29
41
  export type BaseNode = {