@kubb/ast 5.0.0-beta.28 → 5.0.0-beta.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +23 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +43 -15
- package/dist/index.js +23 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/factory.ts +15 -4
- package/src/nodes/response.ts +34 -13
- package/src/visitor.ts +9 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/ast",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.29",
|
|
4
4
|
"description": "Spec-agnostic AST layer for Kubb. Defines the node tree, visitor pattern, factory functions, and type guards used across all code generation plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast",
|
package/src/factory.ts
CHANGED
|
@@ -322,21 +322,32 @@ export function createParameter(
|
|
|
322
322
|
/**
|
|
323
323
|
* Creates a `ResponseNode`.
|
|
324
324
|
*
|
|
325
|
+
* Response body schemas live inside `content`. For convenience a single legacy `schema`
|
|
326
|
+
* (with optional `mediaType`/`keysToOmit`) is normalized into one `content` entry, so the same
|
|
327
|
+
* schema is never stored both at the node root and inside `content`.
|
|
328
|
+
*
|
|
325
329
|
* @example
|
|
326
330
|
* ```ts
|
|
327
331
|
* const response = createResponse({
|
|
328
332
|
* statusCode: '200',
|
|
329
|
-
*
|
|
330
|
-
* schema: createSchema({ type: 'object', properties: [] }),
|
|
333
|
+
* content: [{ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) }],
|
|
331
334
|
* })
|
|
332
335
|
* ```
|
|
333
336
|
*/
|
|
334
337
|
export function createResponse(
|
|
335
|
-
props: Pick<ResponseNode, 'statusCode'
|
|
338
|
+
props: Pick<ResponseNode, 'statusCode'> &
|
|
339
|
+
Partial<Omit<ResponseNode, 'kind' | 'statusCode'>> & {
|
|
340
|
+
schema?: SchemaNode
|
|
341
|
+
mediaType?: string | null
|
|
342
|
+
keysToOmit?: Array<string> | null
|
|
343
|
+
},
|
|
336
344
|
): ResponseNode {
|
|
345
|
+
const { schema, mediaType, keysToOmit, content, ...rest } = props
|
|
346
|
+
|
|
337
347
|
return {
|
|
338
|
-
...
|
|
348
|
+
...rest,
|
|
339
349
|
kind: 'Response',
|
|
350
|
+
content: content ?? (schema ? [{ contentType: mediaType ?? 'application/json', schema, keysToOmit: keysToOmit ?? null }] : undefined),
|
|
340
351
|
}
|
|
341
352
|
}
|
|
342
353
|
|
package/src/nodes/response.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import type { BaseNode } from './base.ts'
|
|
2
|
-
import type {
|
|
2
|
+
import type { StatusCode } from './http.ts'
|
|
3
3
|
import type { SchemaNode } from './schema.ts'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* AST node representing one operation response variant.
|
|
7
7
|
*
|
|
8
|
+
* Mirrors {@link OperationNode.requestBody}: the response body schemas live exclusively inside
|
|
9
|
+
* the `content` array (one entry per content type), so the same schema is never duplicated at the
|
|
10
|
+
* node root and inside `content`.
|
|
11
|
+
*
|
|
8
12
|
* @example
|
|
9
13
|
* ```ts
|
|
10
14
|
* const response: ResponseNode = {
|
|
11
15
|
* kind: 'Response',
|
|
12
16
|
* statusCode: '200',
|
|
13
|
-
* schema: createSchema({ type: 'string' }),
|
|
17
|
+
* content: [{ contentType: 'application/json', schema: createSchema({ type: 'string' }) }],
|
|
14
18
|
* }
|
|
15
19
|
* ```
|
|
16
20
|
*/
|
|
@@ -28,16 +32,33 @@ export type ResponseNode = BaseNode & {
|
|
|
28
32
|
*/
|
|
29
33
|
description?: string
|
|
30
34
|
/**
|
|
31
|
-
*
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
*
|
|
35
|
+
* All available content type entries for this response.
|
|
36
|
+
*
|
|
37
|
+
* When the adapter `contentType` option is set, this array contains exactly one entry for that
|
|
38
|
+
* content type. Otherwise it contains one entry per content type declared in the spec, so that
|
|
39
|
+
* plugins can generate a union of response types (e.g. `application/json` and `application/xml`).
|
|
40
|
+
* Body-less responses keep a single entry whose `schema` is the empty/`void` placeholder.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // spec response declares both application/json and application/xml
|
|
45
|
+
* response.content[0].contentType // 'application/json'
|
|
46
|
+
* response.content[1].contentType // 'application/xml'
|
|
47
|
+
* ```
|
|
41
48
|
*/
|
|
42
|
-
|
|
49
|
+
content?: Array<{
|
|
50
|
+
/**
|
|
51
|
+
* The content type for this entry (e.g. `'application/json'`).
|
|
52
|
+
*/
|
|
53
|
+
contentType: string
|
|
54
|
+
/**
|
|
55
|
+
* Response body schema for this content type.
|
|
56
|
+
*/
|
|
57
|
+
schema?: SchemaNode
|
|
58
|
+
/**
|
|
59
|
+
* Property keys to exclude from the generated type via `Omit<Type, Keys>`.
|
|
60
|
+
* Set when a referenced schema has `writeOnly` fields that should not appear in response types.
|
|
61
|
+
*/
|
|
62
|
+
keysToOmit?: Array<string> | null
|
|
63
|
+
}>
|
|
43
64
|
}
|
package/src/visitor.ts
CHANGED
|
@@ -319,7 +319,11 @@ function* getChildren(node: Node, recurse: boolean): Generator<Node, void, undef
|
|
|
319
319
|
return
|
|
320
320
|
}
|
|
321
321
|
if (node.kind === 'Response') {
|
|
322
|
-
if (node.
|
|
322
|
+
if (node.content) {
|
|
323
|
+
for (const c of node.content) {
|
|
324
|
+
if (c.schema) yield c.schema
|
|
325
|
+
}
|
|
326
|
+
}
|
|
323
327
|
return
|
|
324
328
|
}
|
|
325
329
|
}
|
|
@@ -498,7 +502,10 @@ export function transform(node: Node, options: TransformOptions): Node {
|
|
|
498
502
|
|
|
499
503
|
return {
|
|
500
504
|
...response,
|
|
501
|
-
|
|
505
|
+
content: response.content?.map((entry) => ({
|
|
506
|
+
...entry,
|
|
507
|
+
schema: entry.schema ? transform(entry.schema, { ...options, parent: response }) : entry.schema,
|
|
508
|
+
})),
|
|
502
509
|
}
|
|
503
510
|
}
|
|
504
511
|
|