@kubb/ast 5.0.0-beta.55 → 5.0.0-beta.57
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/README.md +2 -2
- package/dist/index.cjs +1710 -1745
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -46
- package/dist/index.js +1682 -1740
- package/dist/index.js.map +1 -1
- package/dist/{types-BL7RpQAE.d.ts → types-C5aVnRE1.d.ts} +1730 -1789
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/dedupe.ts +1 -1
- package/src/factory.ts +3 -763
- package/src/guards.ts +1 -53
- package/src/index.ts +35 -20
- package/src/mocks.ts +6 -1
- package/src/node.ts +128 -0
- package/src/nodes/base.ts +3 -2
- package/src/nodes/code.ts +115 -0
- package/src/nodes/content.ts +19 -0
- package/src/nodes/file.ts +54 -0
- package/src/nodes/function.ts +221 -146
- package/src/nodes/index.ts +11 -3
- package/src/nodes/input.ts +36 -0
- package/src/nodes/operation.ts +59 -1
- package/src/nodes/output.ts +23 -0
- package/src/nodes/parameter.ts +33 -0
- package/src/nodes/property.ts +36 -0
- package/src/nodes/requestBody.ts +23 -1
- package/src/nodes/response.ts +39 -1
- package/src/nodes/schema.ts +72 -0
- package/src/registry.ts +70 -0
- package/src/transformers.ts +2 -2
- package/src/types.ts +5 -3
- package/src/utils/ast.ts +116 -193
- package/src/visitor.ts +3 -47
package/src/nodes/property.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { defineNode, syncOptionality } from '../node.ts'
|
|
1
2
|
import type { BaseNode } from './base.ts'
|
|
2
3
|
import type { SchemaNode } from './schema.ts'
|
|
3
4
|
|
|
@@ -32,3 +33,38 @@ export type PropertyNode = BaseNode & {
|
|
|
32
33
|
*/
|
|
33
34
|
required: boolean
|
|
34
35
|
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Loosely-typed property accepted by `createProperty`, with `required` optional.
|
|
39
|
+
*/
|
|
40
|
+
export type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Definition for the {@link PropertyNode}. `required` defaults to `false` and the
|
|
44
|
+
* schema's `optional`/`nullish` flags are kept in sync with it.
|
|
45
|
+
*/
|
|
46
|
+
export const propertyDef = defineNode<PropertyNode, UserPropertyNode>({
|
|
47
|
+
kind: 'Property',
|
|
48
|
+
build: (props) => {
|
|
49
|
+
const required = props.required ?? false
|
|
50
|
+
return { ...props, required, schema: syncOptionality(props.schema, required) }
|
|
51
|
+
},
|
|
52
|
+
children: ['schema'],
|
|
53
|
+
visitorKey: 'property',
|
|
54
|
+
rebuild: true,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Creates a `PropertyNode`.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* const property = createProperty({
|
|
63
|
+
* name: 'status',
|
|
64
|
+
* required: true,
|
|
65
|
+
* schema: createSchema({ type: 'string', nullable: true }),
|
|
66
|
+
* })
|
|
67
|
+
* // required=true, no optional/nullish
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export const createProperty = propertyDef.create
|
package/src/nodes/requestBody.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { defineNode } from '../node.ts'
|
|
1
2
|
import type { BaseNode } from './base.ts'
|
|
2
|
-
import type
|
|
3
|
+
import { type ContentNode, createContent, type UserContent } from './content.ts'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* AST node representing an operation request body.
|
|
@@ -40,3 +41,24 @@ export type RequestBodyNode = BaseNode & {
|
|
|
40
41
|
*/
|
|
41
42
|
content?: Array<ContentNode>
|
|
42
43
|
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Loosely-typed request body accepted by `createOperation`, normalized into a {@link RequestBodyNode}.
|
|
47
|
+
*/
|
|
48
|
+
export type UserRequestBody = Omit<RequestBodyNode, 'kind' | 'content'> & {
|
|
49
|
+
content?: Array<UserContent>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Definition for the {@link RequestBodyNode}, normalizing each content entry into a `ContentNode`.
|
|
54
|
+
*/
|
|
55
|
+
export const requestBodyDef = defineNode<RequestBodyNode, UserRequestBody>({
|
|
56
|
+
kind: 'RequestBody',
|
|
57
|
+
build: (props) => ({ ...props, content: props.content?.map(createContent) }),
|
|
58
|
+
children: ['content'],
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates a `RequestBodyNode`, normalizing each content entry into a `ContentNode`.
|
|
63
|
+
*/
|
|
64
|
+
export const createRequestBody = requestBodyDef.create
|
package/src/nodes/response.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { defineNode } from '../node.ts'
|
|
1
2
|
import type { BaseNode } from './base.ts'
|
|
2
|
-
import type
|
|
3
|
+
import { type ContentNode, createContent, type UserContent } from './content.ts'
|
|
3
4
|
import type { StatusCode } from './http.ts'
|
|
5
|
+
import type { SchemaNode } from './schema.ts'
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* AST node representing one operation response variant.
|
|
@@ -48,3 +50,39 @@ export type ResponseNode = BaseNode & {
|
|
|
48
50
|
*/
|
|
49
51
|
content?: Array<ContentNode>
|
|
50
52
|
}
|
|
53
|
+
|
|
54
|
+
type ResponseInput = Pick<ResponseNode, 'statusCode'> &
|
|
55
|
+
Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'content'>> & {
|
|
56
|
+
content?: Array<UserContent>
|
|
57
|
+
schema?: SchemaNode
|
|
58
|
+
mediaType?: string | null
|
|
59
|
+
keysToOmit?: Array<string> | null
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Definition for the {@link ResponseNode}. A single legacy `schema` (with optional
|
|
64
|
+
* `mediaType`/`keysToOmit`) is normalized into one `content` entry.
|
|
65
|
+
*/
|
|
66
|
+
export const responseDef = defineNode<ResponseNode, ResponseInput>({
|
|
67
|
+
kind: 'Response',
|
|
68
|
+
build: (props) => {
|
|
69
|
+
const { schema, mediaType, keysToOmit, content, ...rest } = props
|
|
70
|
+
const entries = content ?? (schema ? [{ contentType: mediaType ?? 'application/json', schema, keysToOmit: keysToOmit ?? null }] : undefined)
|
|
71
|
+
return { ...rest, content: entries?.map(createContent) }
|
|
72
|
+
},
|
|
73
|
+
children: ['content'],
|
|
74
|
+
visitorKey: 'response',
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a `ResponseNode`.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const response = createResponse({
|
|
83
|
+
* statusCode: '200',
|
|
84
|
+
* content: [{ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) }],
|
|
85
|
+
* })
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export const createResponse = responseDef.create
|
package/src/nodes/schema.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { InferSchemaNode } from '../infer.ts'
|
|
2
|
+
import { defineNode, type DistributiveOmit } from '../node.ts'
|
|
1
3
|
import type { BaseNode } from './base.ts'
|
|
2
4
|
import type { PropertyNode } from './property.ts'
|
|
3
5
|
|
|
@@ -657,3 +659,73 @@ export type SchemaNode =
|
|
|
657
659
|
| Ipv4SchemaNode
|
|
658
660
|
| Ipv6SchemaNode
|
|
659
661
|
| ScalarSchemaNode
|
|
662
|
+
|
|
663
|
+
type CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties' | 'primitive'> & { properties?: Array<PropertyNode>; primitive?: 'object' }
|
|
664
|
+
type CreateSchemaInput = CreateSchemaObjectInput | DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>
|
|
665
|
+
type CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {
|
|
666
|
+
kind: 'Schema'
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Maps schema `type` to its underlying `primitive`.
|
|
671
|
+
* Primitive types map to themselves. Special string formats map to `'string'`.
|
|
672
|
+
* Complex types (`ref`, `enum`, `union`, `intersection`, `tuple`, `blob`) are left unset.
|
|
673
|
+
*/
|
|
674
|
+
const TYPE_TO_PRIMITIVE: Partial<Record<SchemaNode['type'], PrimitiveSchemaType>> = {
|
|
675
|
+
string: 'string',
|
|
676
|
+
number: 'number',
|
|
677
|
+
integer: 'integer',
|
|
678
|
+
bigint: 'bigint',
|
|
679
|
+
boolean: 'boolean',
|
|
680
|
+
null: 'null',
|
|
681
|
+
any: 'any',
|
|
682
|
+
unknown: 'unknown',
|
|
683
|
+
void: 'void',
|
|
684
|
+
never: 'never',
|
|
685
|
+
object: 'object',
|
|
686
|
+
array: 'array',
|
|
687
|
+
date: 'date',
|
|
688
|
+
uuid: 'string',
|
|
689
|
+
email: 'string',
|
|
690
|
+
url: 'string',
|
|
691
|
+
datetime: 'string',
|
|
692
|
+
time: 'string',
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Definition for the {@link SchemaNode}. Object schemas default `properties` to an
|
|
697
|
+
* empty array, and `primitive` is inferred from `type` when not explicitly provided.
|
|
698
|
+
*/
|
|
699
|
+
export const schemaDef = defineNode<SchemaNode, CreateSchemaInput>({
|
|
700
|
+
kind: 'Schema',
|
|
701
|
+
build: (props) => {
|
|
702
|
+
if (props.type === 'object') {
|
|
703
|
+
return { properties: [], primitive: 'object' as const, ...props }
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return { primitive: TYPE_TO_PRIMITIVE[props.type as keyof typeof TYPE_TO_PRIMITIVE], ...props }
|
|
707
|
+
},
|
|
708
|
+
children: ['properties', 'items', 'members', 'additionalProperties'],
|
|
709
|
+
visitorKey: 'schema',
|
|
710
|
+
})
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Creates a `SchemaNode`, narrowed to the variant of `props.type`.
|
|
714
|
+
*
|
|
715
|
+
* @example
|
|
716
|
+
* ```ts
|
|
717
|
+
* const scalar = createSchema({ type: 'string' })
|
|
718
|
+
* // { kind: 'Schema', type: 'string', primitive: 'string' }
|
|
719
|
+
* ```
|
|
720
|
+
*
|
|
721
|
+
* @example
|
|
722
|
+
* ```ts
|
|
723
|
+
* const object = createSchema({ type: 'object' })
|
|
724
|
+
* // { kind: 'Schema', type: 'object', primitive: 'object', properties: [] }
|
|
725
|
+
* ```
|
|
726
|
+
*/
|
|
727
|
+
export function createSchema<T extends CreateSchemaInput>(props: T): CreateSchemaOutput<T>
|
|
728
|
+
export function createSchema(props: CreateSchemaInput): SchemaNode
|
|
729
|
+
export function createSchema(props: CreateSchemaInput): SchemaNode {
|
|
730
|
+
return schemaDef.create(props)
|
|
731
|
+
}
|
package/src/registry.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { NodeDef } from './node.ts'
|
|
2
|
+
import { arrowFunctionDef, breakDef, constDef, functionDef, jsxDef, textDef, typeDef } from './nodes/code.ts'
|
|
3
|
+
import { contentDef } from './nodes/content.ts'
|
|
4
|
+
import { exportDef, fileDef, importDef, sourceDef } from './nodes/file.ts'
|
|
5
|
+
import { functionParameterDef, functionParametersDef, indexedAccessTypeDef, objectBindingPatternDef, typeLiteralDef } from './nodes/function.ts'
|
|
6
|
+
import type { Node, NodeKind } from './nodes/index.ts'
|
|
7
|
+
import { inputDef } from './nodes/input.ts'
|
|
8
|
+
import { operationDef } from './nodes/operation.ts'
|
|
9
|
+
import { outputDef } from './nodes/output.ts'
|
|
10
|
+
import { parameterDef } from './nodes/parameter.ts'
|
|
11
|
+
import { propertyDef } from './nodes/property.ts'
|
|
12
|
+
import { requestBodyDef } from './nodes/requestBody.ts'
|
|
13
|
+
import { responseDef } from './nodes/response.ts'
|
|
14
|
+
import { schemaDef } from './nodes/schema.ts'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Every node definition. Adding a node means adding its `defineNode` to one
|
|
18
|
+
* `nodes/*.ts` file and listing it here. The visitor tables below derive from it.
|
|
19
|
+
*/
|
|
20
|
+
export const nodeDefs = [
|
|
21
|
+
inputDef,
|
|
22
|
+
outputDef,
|
|
23
|
+
operationDef,
|
|
24
|
+
requestBodyDef,
|
|
25
|
+
contentDef,
|
|
26
|
+
responseDef,
|
|
27
|
+
schemaDef,
|
|
28
|
+
propertyDef,
|
|
29
|
+
parameterDef,
|
|
30
|
+
functionParameterDef,
|
|
31
|
+
functionParametersDef,
|
|
32
|
+
typeLiteralDef,
|
|
33
|
+
indexedAccessTypeDef,
|
|
34
|
+
objectBindingPatternDef,
|
|
35
|
+
constDef,
|
|
36
|
+
typeDef,
|
|
37
|
+
functionDef,
|
|
38
|
+
arrowFunctionDef,
|
|
39
|
+
textDef,
|
|
40
|
+
breakDef,
|
|
41
|
+
jsxDef,
|
|
42
|
+
importDef,
|
|
43
|
+
exportDef,
|
|
44
|
+
sourceDef,
|
|
45
|
+
fileDef,
|
|
46
|
+
] satisfies ReadonlyArray<NodeDef>
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Child node fields per node kind, in traversal order (Babel's `VISITOR_KEYS`).
|
|
50
|
+
* Derived from each definition's `children`.
|
|
51
|
+
*/
|
|
52
|
+
export const VISITOR_KEYS = Object.fromEntries(nodeDefs.flatMap((def) => (def.children ? [[def.kind, def.children] as const] : []))) as Partial<
|
|
53
|
+
Record<NodeKind, ReadonlyArray<string>>
|
|
54
|
+
>
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Maps a node kind to the matching visitor callback name. Derived from each
|
|
58
|
+
* definition's `visitorKey`.
|
|
59
|
+
*/
|
|
60
|
+
export const VISITOR_KEY_BY_KIND = Object.fromEntries(nodeDefs.flatMap((def) => (def.visitorKey ? [[def.kind, def.visitorKey] as const] : []))) as Partial<
|
|
61
|
+
Record<NodeKind, NonNullable<NodeDef['visitorKey']>>
|
|
62
|
+
>
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Per-kind builders rerun after children are rebuilt. Derived from each
|
|
66
|
+
* definition's `rebuild` flag.
|
|
67
|
+
*/
|
|
68
|
+
export const nodeRebuilders = Object.fromEntries(
|
|
69
|
+
nodeDefs.flatMap((def) => (def.rebuild ? [[def.kind, def.create as unknown as (node: Node) => Node] as const] : [])),
|
|
70
|
+
) as Partial<Record<NodeKind, (node: Node) => Node>>
|
package/src/transformers.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isScalarPrimitive } from './constants.ts'
|
|
2
|
-
import { createProperty, createSchema } from './factory.ts'
|
|
3
2
|
import { narrowSchema } from './guards.ts'
|
|
4
|
-
import
|
|
3
|
+
import { createProperty } from './nodes/property.ts'
|
|
4
|
+
import { createSchema, type SchemaNode } from './nodes/schema.ts'
|
|
5
5
|
import { enumPropName } from './utils/index.ts'
|
|
6
6
|
|
|
7
7
|
/**
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { DedupeCanonical, DedupeLookups, DedupePlan } from './dedupe.ts'
|
|
2
2
|
export type { SchemaDialect } from './dialect.ts'
|
|
3
|
-
export type { DistributiveOmit } from './
|
|
3
|
+
export type { DistributiveOmit } from './node.ts'
|
|
4
4
|
export type { InferSchemaNode, ParserOptions } from './infer.ts'
|
|
5
5
|
export type {
|
|
6
6
|
ArraySchemaNode,
|
|
@@ -20,6 +20,7 @@ export type {
|
|
|
20
20
|
HttpMethod,
|
|
21
21
|
HttpOperationNode,
|
|
22
22
|
ImportNode,
|
|
23
|
+
IndexedAccessTypeNode,
|
|
23
24
|
InputMeta,
|
|
24
25
|
InputNode,
|
|
25
26
|
IntersectionSchemaNode,
|
|
@@ -28,13 +29,12 @@ export type {
|
|
|
28
29
|
Node,
|
|
29
30
|
NodeKind,
|
|
30
31
|
NumberSchemaNode,
|
|
32
|
+
ObjectBindingPatternNode,
|
|
31
33
|
ObjectSchemaNode,
|
|
32
34
|
OperationNode,
|
|
33
35
|
OutputNode,
|
|
34
|
-
ParameterGroupNode,
|
|
35
36
|
ParameterLocation,
|
|
36
37
|
ParameterNode,
|
|
37
|
-
ParamsTypeNode,
|
|
38
38
|
PrimitiveSchemaType,
|
|
39
39
|
PropertyNode,
|
|
40
40
|
RefSchemaNode,
|
|
@@ -48,6 +48,8 @@ export type {
|
|
|
48
48
|
StringSchemaNode,
|
|
49
49
|
TextNode,
|
|
50
50
|
TimeSchemaNode,
|
|
51
|
+
TypeExpression,
|
|
52
|
+
TypeLiteralNode,
|
|
51
53
|
TypeNode,
|
|
52
54
|
UnionSchemaNode,
|
|
53
55
|
UrlSchemaNode,
|