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

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/src/index.ts CHANGED
@@ -1,7 +1,25 @@
1
- export { httpMethods, mediaTypes, nodeKinds, schemaTypes } from './constants.ts'
2
- export { createOperation, createParameter, createProperty, createResponse, createRoot, createSchema } from './factory.ts'
3
- export { isOperationNode, isParameterNode, isPropertyNode, isResponseNode, isRootNode, isSchemaNode, narrowSchema } from './guards.ts'
4
- export { definePrinter } from './printer.ts'
5
- export { buildRefMap, refMapToObject, resolveRef } from './refs.ts'
6
- export { isPlainStringType } from './utils.ts'
7
- export { collect, transform, walk } from './visitor.ts'
1
+ export type { ScalarPrimitive } from './constants.ts'
2
+ export { httpMethods, isScalarPrimitive, mediaTypes, schemaTypes } from './constants.ts'
3
+ export {
4
+ createFunctionParameter,
5
+ createFunctionParameters,
6
+ createOperation,
7
+ createParameter,
8
+ createParameterGroup,
9
+ createProperty,
10
+ createResponse,
11
+ createRoot,
12
+ createSchema,
13
+ createTypeNode,
14
+ syncOptionality,
15
+ } from './factory.ts'
16
+ export { isOperationNode, isSchemaNode, narrowSchema } from './guards.ts'
17
+ export type { ParserOptions } from './infer.ts'
18
+ export type { Printer, PrinterFactoryOptions, PrinterPartial } from './printer.ts'
19
+ export { createPrinterFactory, definePrinter } from './printer.ts'
20
+ export { extractRefName } from './refs.ts'
21
+ export { childName, collectImports, enumPropName, findDiscriminator } from './resolvers.ts'
22
+ export { mergeAdjacentObjects, setDiscriminatorEnum, setEnumName, simplifyUnion } from './transformers.ts'
23
+ export type { OperationParamsResolver } from './utils.ts'
24
+ export { caseParams, createDiscriminantNode, createOperationParams, isStringType, syncSchemaRef } from './utils.ts'
25
+ export { collect, composeTransformers, transform, walk } from './visitor.ts'
package/src/infer.ts ADDED
@@ -0,0 +1,130 @@
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
+ * Shared parser options used by OAS-to-AST inference and parser flows.
20
+ */
21
+ export type ParserOptions = {
22
+ /**
23
+ * How `format: 'date-time'` schemas are represented. `false` falls through to a plain string.
24
+ */
25
+ dateType: false | 'string' | 'stringOffset' | 'stringLocal' | 'date'
26
+ /**
27
+ * Whether `type: 'integer'` and `format: 'int64'` produce `number` or `bigint` nodes.
28
+ */
29
+ integerType?: 'number' | 'bigint'
30
+ /**
31
+ * AST type used when no schema type can be inferred.
32
+ */
33
+ unknownType: 'any' | 'unknown' | 'void'
34
+ /**
35
+ * AST type used for completely empty schemas (`{}`).
36
+ */
37
+ emptySchemaType: 'any' | 'unknown' | 'void'
38
+ /**
39
+ * Suffix appended to derived enum names when building property schema names.
40
+ */
41
+ enumSuffix: 'enum' | (string & {})
42
+ }
43
+
44
+ /**
45
+ * Maps each `dateType` option value to the AST node produced by `format: 'date-time'`.
46
+ */
47
+ type DateTimeNodeByDateType = {
48
+ date: DateSchemaNode
49
+ string: DatetimeSchemaNode
50
+ stringOffset: DatetimeSchemaNode
51
+ stringLocal: DatetimeSchemaNode
52
+ false: StringSchemaNode
53
+ }
54
+
55
+ /**
56
+ * Resolves the AST node produced by `format: 'date-time'` based on the `dateType` option.
57
+ */
58
+ type ResolveDateTimeNode<TDateType extends ParserOptions['dateType']> = DateTimeNodeByDateType[TDateType extends keyof DateTimeNodeByDateType
59
+ ? TDateType
60
+ : 'string']
61
+
62
+ /**
63
+ * Ordered list of `[schema-shape, SchemaNode]` pairs.
64
+ * `InferSchemaNode` walks this tuple in order and returns the first matching node type.
65
+ */
66
+ type SchemaNodeMap<TDateType extends ParserOptions['dateType'] = 'string'> = [
67
+ [{ $ref: string }, RefSchemaNode],
68
+ [{ allOf: ReadonlyArray<unknown>; properties: object }, IntersectionSchemaNode],
69
+ [{ allOf: readonly [unknown, unknown, ...unknown[]] }, IntersectionSchemaNode],
70
+ [{ allOf: ReadonlyArray<unknown> }, SchemaNode],
71
+ [{ oneOf: ReadonlyArray<unknown> }, UnionSchemaNode],
72
+ [{ anyOf: ReadonlyArray<unknown> }, UnionSchemaNode],
73
+ [{ const: null }, ScalarSchemaNode],
74
+ [{ const: string | number | boolean }, EnumSchemaNode],
75
+ [{ type: ReadonlyArray<string> }, UnionSchemaNode],
76
+ [{ type: 'array'; enum: ReadonlyArray<unknown> }, ArraySchemaNode],
77
+ [{ enum: ReadonlyArray<unknown> }, EnumSchemaNode],
78
+ [{ type: 'enum' }, EnumSchemaNode],
79
+ [{ type: 'union' }, UnionSchemaNode],
80
+ [{ type: 'intersection' }, IntersectionSchemaNode],
81
+ [{ type: 'tuple' }, ArraySchemaNode],
82
+ [{ type: 'ref' }, RefSchemaNode],
83
+ [{ type: 'datetime' }, DatetimeSchemaNode],
84
+ [{ type: 'date' }, DateSchemaNode],
85
+ [{ type: 'time' }, TimeSchemaNode],
86
+ [{ type: 'url' }, UrlSchemaNode],
87
+ [{ type: 'object' }, ObjectSchemaNode],
88
+ [{ additionalProperties: boolean | {} }, ObjectSchemaNode],
89
+ [{ type: 'array' }, ArraySchemaNode],
90
+ [{ items: object }, ArraySchemaNode],
91
+ [{ prefixItems: ReadonlyArray<unknown> }, ArraySchemaNode],
92
+ [{ type: string; format: 'date-time' }, ResolveDateTimeNode<TDateType>],
93
+ [{ type: string; format: 'date' }, DateSchemaNode],
94
+ [{ type: string; format: 'time' }, TimeSchemaNode],
95
+ [{ format: 'date-time' }, ResolveDateTimeNode<TDateType>],
96
+ [{ format: 'date' }, DateSchemaNode],
97
+ [{ format: 'time' }, TimeSchemaNode],
98
+ [{ type: 'string' }, StringSchemaNode],
99
+ [{ type: 'number' }, NumberSchemaNode],
100
+ [{ type: 'integer' }, NumberSchemaNode],
101
+ [{ type: 'bigint' }, NumberSchemaNode],
102
+ [{ type: string }, ScalarSchemaNode],
103
+ [{ minLength: number }, StringSchemaNode],
104
+ [{ maxLength: number }, StringSchemaNode],
105
+ [{ pattern: string }, StringSchemaNode],
106
+ [{ minimum: number }, NumberSchemaNode],
107
+ [{ maximum: number }, NumberSchemaNode],
108
+ ]
109
+
110
+ /**
111
+ * Infers the matching AST `SchemaNode` type from an input schema shape.
112
+ */
113
+ export type InferSchemaNode<
114
+ TSchema extends object,
115
+ TDateType extends ParserOptions['dateType'] = 'string',
116
+ TEntries extends ReadonlyArray<[object, SchemaNode]> = SchemaNodeMap<TDateType>,
117
+ > = TEntries extends [infer TEntry extends [object, SchemaNode], ...infer TRest extends ReadonlyArray<[object, SchemaNode]>]
118
+ ? TSchema extends TEntry[0]
119
+ ? TEntry[1]
120
+ : InferSchemaNode<TSchema, TDateType, TRest>
121
+ : SchemaNode
122
+
123
+ /**
124
+ * Backward-compatible alias for `InferSchemaNode`.
125
+ */
126
+ export type InferSchema<
127
+ TSchema extends object,
128
+ TDateType extends ParserOptions['dateType'] = 'string',
129
+ TEntries extends ReadonlyArray<[object, SchemaNode]> = SchemaNodeMap<TDateType>,
130
+ > = InferSchemaNode<TSchema, TDateType, TEntries>
package/src/mocks.ts CHANGED
@@ -2,7 +2,7 @@ import { createOperation, createParameter, createProperty, createResponse, creat
2
2
  import type { RootNode } from './nodes/root.ts'
3
3
 
4
4
  /**
5
- * Minimal single-resource tree: one `Pet` schema and one `getPetById` operation.
5
+ * Builds a minimal sample AST with one `Pet` schema and one `getPetById` operation.
6
6
  */
7
7
  export function buildSampleTree(): RootNode {
8
8
  const petSchema = createSchema({
@@ -20,15 +20,22 @@ export function buildSampleTree(): RootNode {
20
20
  path: '/pets/{petId}',
21
21
  tags: ['pets'],
22
22
  parameters: [createParameter({ name: 'petId', in: 'path', schema: createSchema({ type: 'integer' }), required: true })],
23
- responses: [createResponse({ statusCode: '200', schema: createSchema({ type: 'ref', name: 'Pet' }) }), createResponse({ statusCode: '404' })],
23
+ responses: [
24
+ createResponse({ statusCode: '200', schema: createSchema({ type: 'ref', name: 'Pet' }) }),
25
+ createResponse({
26
+ statusCode: '404',
27
+ schema: createSchema({ type: 'ref', name: 'Error' }),
28
+ }),
29
+ ],
24
30
  })
25
31
 
26
32
  return createRoot({ schemas: [petSchema], operations: [operation] })
27
33
  }
28
34
 
29
35
  /**
30
- * PetStore-like tree: six named schemas (`Pet`, `NewPet`, `PetList`, `Error`, `PetOrError`, `FullPet`)
31
- * and two operations (`listPets`, `createPet`).
36
+ * Builds a PetStore-like fixture AST with:
37
+ * - six named schemas (`Pet`, `NewPet`, `PetList`, `Error`, `PetOrError`, `FullPet`)
38
+ * - two operations (`listPets`, `createPet`)
32
39
  */
33
40
  export function buildFixture(): RootNode {
34
41
  const refPet = createSchema({ type: 'ref', ref: 'Pet' })
@@ -92,7 +99,7 @@ export function buildFixture(): RootNode {
92
99
  method: 'POST',
93
100
  path: '/pets',
94
101
  tags: ['pets'],
95
- requestBody: createSchema({ type: 'ref', ref: 'NewPet' }),
102
+ requestBody: { schema: createSchema({ type: 'ref', ref: 'NewPet' }) },
96
103
  responses: [createResponse({ statusCode: '201', schema: refPet, mediaType: 'application/json' })],
97
104
  }),
98
105
  ],
package/src/nodes/base.ts CHANGED
@@ -1,16 +1,44 @@
1
1
  /**
2
- * Kind discriminant for every AST node.
2
+ * `kind` values used by AST nodes.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * const kind: NodeKind = 'Schema'
7
+ * ```
3
8
  */
4
- export type NodeKind = 'Root' | 'Operation' | 'Schema' | 'Property' | 'Parameter' | 'Response'
9
+ export type NodeKind =
10
+ | 'Root'
11
+ | 'Operation'
12
+ | 'Schema'
13
+ | 'Property'
14
+ | 'Parameter'
15
+ | 'Response'
16
+ | 'FunctionParameter'
17
+ | 'ParameterGroup'
18
+ | 'FunctionParameters'
19
+ | 'Type'
5
20
 
6
21
  /**
7
- * Common base for all AST nodes.
22
+ * Base shape shared by all AST nodes.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const base: BaseNode = { kind: 'Root' }
27
+ * ```
8
28
  */
9
29
  export type BaseNode = {
30
+ /**
31
+ * Node discriminator.
32
+ */
10
33
  kind: NodeKind
11
34
  }
12
35
 
13
36
  /**
14
- * Any AST node.
37
+ * Minimal node type when only `kind` is needed.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const node: Node = { kind: 'Operation' }
42
+ * ```
15
43
  */
16
44
  export type Node = BaseNode
@@ -0,0 +1,201 @@
1
+ import type { BaseNode } from './base.ts'
2
+
3
+ /**
4
+ * AST node representing a language-agnostic type expression produced during parameter resolution.
5
+ * Each language printer renders the variant into its own syntax.
6
+ *
7
+ * - `struct` — an inline anonymous type grouping named fields.
8
+ * TypeScript renders as `{ petId: string; name?: string }`, Python as a `TypedDict` reference.
9
+ * - `member` — a single named field accessed from a named group type.
10
+ * TypeScript renders as `PathParams['petId']`, C# as `PathParams.PetId`.
11
+ */
12
+ export type TypeNode = BaseNode & {
13
+ /**
14
+ * Node kind.
15
+ */
16
+ kind: 'Type'
17
+ } & (
18
+ | {
19
+ /**
20
+ * Reference variant — a plain type name or identifier.
21
+ * TypeScript renders as-is, e.g. `string`, `QueryParams`, `Partial<Config>`.
22
+ */
23
+ variant: 'reference'
24
+ /**
25
+ * The full type name string, e.g. `'string'`, `'QueryParams'`, `'Partial<Config>'`.
26
+ */
27
+ name: string
28
+ }
29
+ | {
30
+ /**
31
+ * Struct variant — an inline anonymous type grouping named fields.
32
+ * TypeScript renders as `{ key: Type; other?: OtherType }`.
33
+ */
34
+ variant: 'struct'
35
+ /**
36
+ * Properties of the struct type.
37
+ */
38
+ properties: Array<{ name: string; optional: boolean; type: TypeNode }>
39
+ }
40
+ | {
41
+ /**
42
+ * Member variant — a single named field accessed from a group type.
43
+ * TypeScript renders as `Base['key']`.
44
+ */
45
+ variant: 'member'
46
+ /**
47
+ * Base type name, e.g. `'DeletePetPathParams'`.
48
+ */
49
+ base: string
50
+ /**
51
+ * The field name to access, e.g. `'petId'`.
52
+ */
53
+ key: string
54
+ }
55
+ )
56
+
57
+ /**
58
+ * AST node for one function parameter.
59
+ *
60
+ * @example Required parameter
61
+ * `name: Type`
62
+ *
63
+ * @example Optional parameter
64
+ * `name?: Type`
65
+ *
66
+ * @example Parameter with default value
67
+ * `name: Type = defaultValue`
68
+ *
69
+ * @example Rest parameter
70
+ * `...name: Type[]`
71
+ */
72
+ export type FunctionParameterNode = BaseNode & {
73
+ /**
74
+ * Node kind.
75
+ */
76
+ kind: 'FunctionParameter'
77
+ /**
78
+ * Parameter name in the generated signature.
79
+ */
80
+ name: string
81
+ /**
82
+ * Type annotation as a structured {@link TypeNode}.
83
+ * Omit for untyped output.
84
+ *
85
+ * @example Reference type node
86
+ * `{ kind: 'Type', variant: 'reference', name: 'string' }` → `petId: string`
87
+ *
88
+ * @example Struct type node
89
+ * `{ kind: 'Type', variant: 'struct', properties: [...] }` → `{ key: Type; other?: OtherType }`
90
+ *
91
+ * @example Member type node
92
+ * `{ kind: 'Type', variant: 'member', base: 'PathParams', key: 'petId' }` → `PathParams['petId']`
93
+ */
94
+ type?: TypeNode
95
+ /**
96
+ * When `true` the parameter is emitted as a rest parameter.
97
+ *
98
+ * @example Rest parameter
99
+ * `...name: Type[]`
100
+ */
101
+ rest?: boolean
102
+ } /**
103
+ * Optional parameter — rendered with `?` and may be omitted by the caller.
104
+ * Cannot be combined with `default` because a defaulted parameter is already optional.
105
+ */ & (
106
+ | { optional: true; default?: never }
107
+ /**
108
+ * Required parameter, or a parameter with a default value.
109
+ *
110
+ * @example Required
111
+ * `name: Type`
112
+ *
113
+ * @example With default
114
+ * `name: Type = default`
115
+ */
116
+ | { optional?: false; default?: string }
117
+ )
118
+
119
+ /**
120
+ * AST node for a group of related function parameters treated as a single unit.
121
+ *
122
+ * Each language printer decides how to render this group:
123
+ * - TypeScript/JS: destructured object `{ key1, key2 }: { key1: Type1; key2: Type2 } = {}`
124
+ * - Python: keyword-only args or a typed dict parameter
125
+ * - C# / Kotlin: named record / data-class parameter
126
+ *
127
+ * When `inline` is `true`, the group is spread as individual top-level parameters
128
+ * rather than wrapped in a single grouped construct.
129
+ *
130
+ * @example Grouped destructuring
131
+ * `{ id, name }: { id: string; name: string } = {}`
132
+ *
133
+ * @example Inline (spread as individual parameters)
134
+ * `id: string, name: string`
135
+ */
136
+ export type ParameterGroupNode = BaseNode & {
137
+ /**
138
+ * Node kind.
139
+ */
140
+ kind: 'ParameterGroup'
141
+ /**
142
+ * The individual parameters that form the group.
143
+ * Rendered as a destructured object or spread inline when `inline` is `true`.
144
+ */
145
+ properties: Array<FunctionParameterNode>
146
+ /**
147
+ * Optional explicit type annotation for the whole group.
148
+ * When absent, printers auto-compute it from `properties`.
149
+ */
150
+ type?: TypeNode
151
+ /**
152
+ * When `true`, `properties` are emitted as individual top-level parameters instead of
153
+ * being wrapped in a single grouped construct.
154
+ *
155
+ * @default false
156
+ */
157
+ inline?: boolean
158
+ /**
159
+ * Whether the group as a whole is optional.
160
+ * If omitted, printers infer this from child properties.
161
+ */
162
+ optional?: boolean
163
+ /**
164
+ * Default value for the group, written verbatim after `=`.
165
+ * Commonly `'{}'` to allow omitting the argument entirely.
166
+ */
167
+ default?: string
168
+ }
169
+
170
+ /**
171
+ * AST node for a complete function parameter list.
172
+ *
173
+ * Printers are responsible for sorting (`required` → `optional` → `defaulted`).
174
+ * Nodes are plain immutable data.
175
+ *
176
+ * Renders differently depending on the output mode:
177
+ * - `declaration` → `(id: string, config: Config = {})` — function declaration parameters
178
+ * - `call` → `(id, { method, url })` — function call arguments
179
+ * - `keys` → `{ id, config }` — key names only (for destructuring)
180
+ * - `values` → `{ id: id, config: config }` — key → value pairs
181
+ */
182
+ export type FunctionParametersNode = BaseNode & {
183
+ /**
184
+ * Node kind.
185
+ */
186
+ kind: 'FunctionParameters'
187
+ /**
188
+ * Ordered parameter nodes.
189
+ */
190
+ params: ReadonlyArray<FunctionParameterNode | ParameterGroupNode>
191
+ }
192
+
193
+ /**
194
+ * The four function-signature AST node variants.
195
+ */
196
+ export type FunctionNode = FunctionParameterNode | ParameterGroupNode | FunctionParametersNode | TypeNode
197
+
198
+ /**
199
+ * Handler map keys — one per `FunctionNode` kind.
200
+ */
201
+ export type FunctionNodeType = 'functionParameter' | 'parameterGroup' | 'functionParameters' | 'type'
package/src/nodes/http.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * All IANA-registered HTTP status codes as string literals, matching how
3
- * they appear as keys in API specifications (e.g. `"200"`, `"404"`).
2
+ * All supported HTTP status code literals as strings, as used in API specs
3
+ * (for example, `"200"` and `"404"`).
4
4
  */
5
5
  export type HttpStatusCode =
6
6
  // 1xx Informational
@@ -72,13 +72,25 @@ export type HttpStatusCode =
72
72
  | '511'
73
73
 
74
74
  /**
75
- * A status code as used in an operation response: a specific HTTP status
76
- * code string or `"default"` as a catch-all fallback.
75
+ * Response status code literal used by operations.
76
+ *
77
+ * Includes specific HTTP status code strings and `"default"` for catch-all responses.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const status: StatusCode = '200'
82
+ * const fallback: StatusCode = 'default'
83
+ * ```
77
84
  */
78
85
  export type StatusCode = HttpStatusCode | 'default'
79
86
 
80
87
  /**
81
- * Common IANA media types used in API request/response bodies.
88
+ * Supported media type strings used in request and response bodies.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * const mediaType: MediaType = 'application/json'
93
+ * ```
82
94
  */
83
95
  export type MediaType =
84
96
  // Application
@@ -1,3 +1,4 @@
1
+ import type { FunctionNode } from './function.ts'
1
2
  import type { OperationNode } from './operation.ts'
2
3
  import type { ParameterNode } from './parameter.ts'
3
4
  import type { PropertyNode } from './property.ts'
@@ -6,6 +7,7 @@ import type { RootNode } from './root.ts'
6
7
  import type { SchemaNode } from './schema.ts'
7
8
 
8
9
  export type { BaseNode, NodeKind } from './base.ts'
10
+ export type { FunctionNode, FunctionNodeType, FunctionParameterNode, FunctionParametersNode, ParameterGroupNode, TypeNode } from './function.ts'
9
11
  export type { HttpStatusCode, MediaType, StatusCode } from './http.ts'
10
12
  export type { HttpMethod, OperationNode } from './operation.ts'
11
13
  export type { ParameterLocation, ParameterNode } from './parameter.ts'
@@ -19,7 +21,10 @@ export type {
19
21
  DatetimeSchemaNode,
20
22
  EnumSchemaNode,
21
23
  EnumValueNode,
24
+ FormatStringSchemaNode,
22
25
  IntersectionSchemaNode,
26
+ Ipv4SchemaNode,
27
+ Ipv6SchemaNode,
23
28
  NumberSchemaNode,
24
29
  ObjectSchemaNode,
25
30
  PrimitiveSchemaType,
@@ -33,13 +38,24 @@ export type {
33
38
  StringSchemaNode,
34
39
  TimeSchemaNode,
35
40
  UnionSchemaNode,
41
+ UrlSchemaNode,
36
42
  } from './schema.ts'
37
43
 
38
44
  /**
39
- * Discriminated union of every AST node.
45
+ * Union of all AST node types.
40
46
  *
41
- * Using a concrete union (instead of the bare `BaseNode` alias) lets
42
- * TypeScript narrow the type automatically inside `switch (node.kind)`
43
- * blocks, eliminating the need for manual `as TypeName` casts.
47
+ * This lets TypeScript narrow types in `switch (node.kind)` blocks.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * function getKind(node: Node): string {
52
+ * switch (node.kind) {
53
+ * case 'Root':
54
+ * return 'root'
55
+ * default:
56
+ * return 'other'
57
+ * }
58
+ * }
59
+ * ```
44
60
  */
45
- export type Node = RootNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode
61
+ export type Node = RootNode | OperationNode | SchemaNode | PropertyNode | ParameterNode | ResponseNode | FunctionNode
@@ -6,28 +6,91 @@ import type { SchemaNode } from './schema.ts'
6
6
  export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE'
7
7
 
8
8
  /**
9
- * A spec-agnostic representation of a single API operation.
9
+ * AST node representing one API operation.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const operation: OperationNode = {
14
+ * kind: 'Operation',
15
+ * operationId: 'listPets',
16
+ * method: 'GET',
17
+ * path: '/pets',
18
+ * tags: [],
19
+ * parameters: [],
20
+ * responses: [],
21
+ * }
22
+ * ```
10
23
  */
11
24
  export type OperationNode = BaseNode & {
25
+ /**
26
+ * Node kind.
27
+ */
12
28
  kind: 'Operation'
13
29
  /**
14
- * Unique operation identifier (maps to `operationId` in OAS).
30
+ * Operation identifier, usually from OpenAPI `operationId`.
15
31
  */
16
32
  operationId: string
33
+ /**
34
+ * HTTP Method like 'GET'
35
+ */
17
36
  method: HttpMethod
18
37
  /**
19
- * Express-style path string, e.g. `/pets/:petId`.
20
- * Derived from the OpenAPI path by converting `{param}` tokens to `:param`.
38
+ * OpenAPI-style path string, for example `/pets/{petId}`.
39
+ * Path parameters retain the `{param}` notation from the original spec.
21
40
  */
22
41
  path: string
42
+ /**
43
+ * Group labels for the operation.
44
+ * Usually copied from OpenAPI `tags`.
45
+ */
23
46
  tags: Array<string>
47
+ /**
48
+ * Short one-line operation summary.
49
+ */
24
50
  summary?: string
51
+ /**
52
+ * Full operation description.
53
+ */
25
54
  description?: string
55
+ /**
56
+ * Marks the operation as deprecated.
57
+ */
26
58
  deprecated?: boolean
59
+ /**
60
+ * Parameters that could be used, we have QueryParams, PathParams, HeaderParams and CookieParams
61
+ */
27
62
  parameters: Array<ParameterNode>
28
63
  /**
29
- * Request body schema. For OAS, this is the schema of the first content entry.
64
+ * Request body metadata for the operation.
65
+ */
66
+ requestBody?: {
67
+ /**
68
+ * Human-readable request body description.
69
+ */
70
+ description?: string
71
+ /**
72
+ * Request body schema.
73
+ * For OpenAPI, this is the schema from the first `content` entry.
74
+ */
75
+ schema?: SchemaNode
76
+ /**
77
+ * Property keys to exclude from the generated request body type via `Omit<Type, Keys>`.
78
+ * Set when a referenced schema has `readOnly` fields that should be omitted in request types.
79
+ */
80
+ keysToOmit?: Array<string>
81
+ /**
82
+ * Whether the request body is required (`requestBody.required: true` in the spec).
83
+ * When `false` or absent, the generated `data` parameter should be optional.
84
+ */
85
+ required?: boolean
86
+ /**
87
+ * Media type of the request body (e.g. `'application/json'`, `'multipart/form-data'`).
88
+ * Extracted from the first `content` entry of the OpenAPI `requestBody`.
89
+ */
90
+ contentType?: string
91
+ }
92
+ /**
93
+ * Operation responses.
30
94
  */
31
- requestBody?: SchemaNode
32
95
  responses: Array<ResponseNode>
33
96
  }
@@ -4,12 +4,38 @@ import type { SchemaNode } from './schema.ts'
4
4
  export type ParameterLocation = 'path' | 'query' | 'header' | 'cookie'
5
5
 
6
6
  /**
7
- * A single input parameter for an operation.
7
+ * AST node representing one operation parameter.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const param: ParameterNode = {
12
+ * kind: 'Parameter',
13
+ * name: 'petId',
14
+ * in: 'path',
15
+ * schema: createSchema({ type: 'string' }),
16
+ * required: true,
17
+ * }
18
+ * ```
8
19
  */
9
20
  export type ParameterNode = BaseNode & {
21
+ /**
22
+ * Node kind.
23
+ */
10
24
  kind: 'Parameter'
25
+ /**
26
+ * Parameter name.
27
+ */
11
28
  name: string
29
+ /**
30
+ * Parameter location (`path`, `query`, `header`, or `cookie`).
31
+ */
12
32
  in: ParameterLocation
33
+ /**
34
+ * Parameter schema.
35
+ */
13
36
  schema: SchemaNode
37
+ /**
38
+ * Whether the parameter is required.
39
+ */
14
40
  required: boolean
15
41
  }