@kubb/ast 5.0.0-alpha.32 → 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/src/nodes/code.ts CHANGED
@@ -14,7 +14,7 @@ export type JSDocNode = {
14
14
  /**
15
15
  * AST node representing a TypeScript `const` declaration.
16
16
  *
17
- * Mirrors the props of the `Const` component from `@kubb/react-fabric`.
17
+ * Mirrors the props of the `Const` component from `@kubb/renderer-jsx`.
18
18
  * The `children` prop of the component is represented as `nodes`.
19
19
  *
20
20
  * @example
@@ -53,15 +53,15 @@ export type ConstNode = BaseNode & {
53
53
  asConst?: boolean
54
54
  /**
55
55
  * Child nodes representing the value of the constant (children of the `Const` component).
56
- * Each entry is either a structured {@link CodeNode} or a raw string expression.
56
+ * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
57
57
  */
58
- nodes?: Array<CodeNode | string>
58
+ nodes?: Array<CodeNode>
59
59
  }
60
60
 
61
61
  /**
62
62
  * AST node representing a TypeScript `type` alias declaration.
63
63
  *
64
- * Mirrors the props of the `Type` component from `@kubb/react-fabric`.
64
+ * Mirrors the props of the `Type` component from `@kubb/renderer-jsx`.
65
65
  * The `children` prop of the component is represented as `nodes`.
66
66
  *
67
67
  * @example
@@ -90,9 +90,9 @@ export type TypeNode = BaseNode & {
90
90
  JSDoc?: JSDocNode
91
91
  /**
92
92
  * Child nodes representing the type body (children of the `Type` component).
93
- * Each entry is either a structured {@link CodeNode} or a raw string expression.
93
+ * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
94
94
  */
95
- nodes?: Array<CodeNode | string>
95
+ nodes?: Array<CodeNode>
96
96
  }
97
97
 
98
98
  /**
@@ -104,7 +104,7 @@ export type TypeDeclarationNode = TypeNode
104
104
  /**
105
105
  * AST node representing a TypeScript `function` declaration.
106
106
  *
107
- * Mirrors the props of the `Function` component from `@kubb/react-fabric`.
107
+ * Mirrors the props of the `Function` component from `@kubb/renderer-jsx`.
108
108
  * The `children` prop of the component is represented as `nodes`.
109
109
  *
110
110
  * @example
@@ -157,15 +157,15 @@ export type FunctionNode = BaseNode & {
157
157
  JSDoc?: JSDocNode
158
158
  /**
159
159
  * Child nodes representing the function body (children of the `Function` component).
160
- * Each entry is either a structured {@link CodeNode} or a raw string statement.
160
+ * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
161
161
  */
162
- nodes?: Array<CodeNode | string>
162
+ nodes?: Array<CodeNode>
163
163
  }
164
164
 
165
165
  /**
166
166
  * AST node representing a TypeScript arrow function (`const name = () => { ... }`).
167
167
  *
168
- * Mirrors the props of the `Function.Arrow` component from `@kubb/react-fabric`.
168
+ * Mirrors the props of the `Function.Arrow` component from `@kubb/renderer-jsx`.
169
169
  * The `children` prop of the component is represented as `nodes`.
170
170
  *
171
171
  * @example
@@ -223,15 +223,82 @@ export type ArrowFunctionNode = BaseNode & {
223
223
  singleLine?: boolean
224
224
  /**
225
225
  * Child nodes representing the function body (children of the `Function.Arrow` component).
226
- * Each entry is either a structured {@link CodeNode} or a raw string statement.
226
+ * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
227
227
  */
228
- nodes?: Array<CodeNode | string>
228
+ nodes?: Array<CodeNode>
229
+ }
230
+
231
+ /**
232
+ * AST node representing a raw text/string fragment in the source output.
233
+ *
234
+ * Used instead of bare `string` values so that all entries in `nodes` arrays
235
+ * are typed `CodeNode` objects rather than a mixed `CodeNode | string` union.
236
+ *
237
+ * @example
238
+ * ```ts
239
+ * createText('return fetch(id)')
240
+ * // { kind: 'Text', value: 'return fetch(id)' }
241
+ * ```
242
+ */
243
+ export type TextNode = BaseNode & {
244
+ /**
245
+ * Node kind.
246
+ */
247
+ kind: 'Text'
248
+ /**
249
+ * The raw string content.
250
+ */
251
+ value: string
252
+ }
253
+
254
+ /**
255
+ * AST node representing a line break in the source output.
256
+ *
257
+ * Corresponds to `<br/>` in JSX components. When printed, produces an empty
258
+ * string that — joined with `\n` by `printNodes` — creates a blank line
259
+ * between surrounding code nodes.
260
+ *
261
+ * @example
262
+ * ```ts
263
+ * createBreak()
264
+ * // { kind: 'Break' }
265
+ * // prints as '' → blank line when surrounded by other nodes
266
+ * ```
267
+ */
268
+ export type BreakNode = BaseNode & {
269
+ /**
270
+ * Node kind.
271
+ */
272
+ kind: 'Break'
273
+ }
274
+
275
+ /**
276
+ * AST node representing a raw JSX fragment in the source output.
277
+ *
278
+ * Mirrors the `Jsx` component from `@kubb/renderer-jsx`. Use this to embed raw
279
+ * JSX/TSX markup (including fragments `<>…</>`) directly in generated code.
280
+ *
281
+ * @example
282
+ * ```ts
283
+ * createJsx('<>\n <a href={href}>Open</a>\n</>')
284
+ * // { kind: 'Jsx', value: '<>\n <a href={href}>Open</a>\n</>' }
285
+ * ```
286
+ */
287
+ export type JsxNode = BaseNode & {
288
+ /**
289
+ * Node kind.
290
+ */
291
+ kind: 'Jsx'
292
+ /**
293
+ * The raw JSX string content.
294
+ */
295
+ value: string
229
296
  }
230
297
 
231
298
  /**
232
299
  * Union of all code-generation AST nodes.
233
300
  *
234
- * These nodes mirror the JSX components from `@kubb/react-fabric` and are used as
301
+ * These nodes mirror the JSX components from `@kubb/renderer-jsx` and are used as
235
302
  * structured children in {@link SourceNode.nodes}.
236
303
  */
237
- export type CodeNode = ConstNode | TypeNode | FunctionNode | ArrowFunctionNode
304
+ export type CodeNode = ConstNode | TypeNode | FunctionNode | ArrowFunctionNode | TextNode | BreakNode | JsxNode
package/src/nodes/file.ts CHANGED
@@ -121,12 +121,12 @@ export type ExportNode = BaseNode & {
121
121
  *
122
122
  * @example Named exportable source
123
123
  * ```ts
124
- * createSource({ name: 'Pet', value: 'export type Pet = { id: number }', isExportable: true, isIndexable: true })
124
+ * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })
125
125
  * ```
126
126
  *
127
127
  * @example Inline unnamed code block
128
128
  * ```ts
129
- * createSource({ value: 'const x = 1' })
129
+ * createSource({ nodes: [createText('const x = 1')] })
130
130
  * ```
131
131
  */
132
132
  export type SourceNode = BaseNode & {
@@ -135,10 +135,6 @@ export type SourceNode = BaseNode & {
135
135
  * Optional name identifying this source (used for deduplication and barrel generation).
136
136
  */
137
137
  name?: string
138
- /**
139
- * The source code value.
140
- */
141
- value?: string
142
138
  /**
143
139
  * Mark this source as a type-only export.
144
140
  * @default false
@@ -155,9 +151,8 @@ export type SourceNode = BaseNode & {
155
151
  */
156
152
  isIndexable?: boolean
157
153
  /**
158
- * Structured child nodes representing the content of this source fragment.
159
- * These correspond to the children of the `File.Source` component from `@kubb/react-fabric`
160
- * (e.g. `ConstNode`, `TypeDeclarationNode`, `FunctionDeclarationNode`, `ArrowFunctionDeclarationNode`).
154
+ * Structured child nodes representing the content of this source fragment, in DOM order.
155
+ * Each entry is a {@link CodeNode}; use {@link TextNode} for raw string content.
161
156
  */
162
157
  nodes?: Array<CodeNode>
163
158
  }
@@ -173,7 +168,7 @@ export type SourceNode = BaseNode & {
173
168
  * const file = createFile({
174
169
  * baseName: 'petStore.ts',
175
170
  * path: 'src/models/petStore.ts',
176
- * sources: [createSource({ name: 'Pet', value: 'export type Pet = { id: number }', isExportable: true })],
171
+ * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],
177
172
  * imports: [createImport({ name: ['z'], path: 'zod' })],
178
173
  * exports: [createExport({ name: ['Pet'], path: './petStore' })],
179
174
  * })
@@ -10,7 +10,7 @@ import type { InputNode } from './root.ts'
10
10
  import type { SchemaNode } from './schema.ts'
11
11
 
12
12
  export type { BaseNode, NodeKind } from './base.ts'
13
- export type { ArrowFunctionNode, CodeNode, ConstNode, FunctionNode, JSDocNode, TypeDeclarationNode, TypeNode } from './code.ts'
13
+ export type { ArrowFunctionNode, BreakNode, CodeNode, ConstNode, FunctionNode, JSDocNode, JsxNode, TextNode, TypeDeclarationNode, TypeNode } from './code.ts'
14
14
  export type { ExportNode, FileNode, ImportNode, SourceNode } from './file.ts'
15
15
  export type { FunctionNodeType, FunctionParameterNode, FunctionParametersNode, FunctionParamNode, ParameterGroupNode, ParamsTypeNode } from './function.ts'
16
16
  export type { HttpStatusCode, MediaType, StatusCode } from './http.ts'
package/src/types.ts CHANGED
@@ -5,6 +5,7 @@ export type {
5
5
  ArraySchemaNode,
6
6
  ArrowFunctionNode,
7
7
  BaseNode,
8
+ BreakNode,
8
9
  CodeNode,
9
10
  ComplexSchemaType,
10
11
  ConstNode,
@@ -29,6 +30,7 @@ export type {
29
30
  Ipv4SchemaNode,
30
31
  Ipv6SchemaNode,
31
32
  JSDocNode,
33
+ JsxNode,
32
34
  MediaType,
33
35
  Node,
34
36
  NodeKind,
@@ -53,6 +55,7 @@ export type {
53
55
  SpecialSchemaType,
54
56
  StatusCode,
55
57
  StringSchemaNode,
58
+ TextNode,
56
59
  TimeSchemaNode,
57
60
  TypeDeclarationNode,
58
61
  TypeNode,
package/src/utils.ts CHANGED
@@ -3,6 +3,7 @@ import { camelCase, isValidVarName } from '@internals/utils'
3
3
  import { createFunctionParameter, createFunctionParameters, createParameterGroup, createParamsType, createProperty, createSchema } from './factory.ts'
4
4
  import { narrowSchema } from './guards.ts'
5
5
  import type {
6
+ CodeNode,
6
7
  ExportNode,
7
8
  FunctionParameterNode,
8
9
  FunctionParametersNode,
@@ -470,7 +471,8 @@ function toStructType({
470
471
  }
471
472
 
472
473
  function sourceKey(source: SourceNode): string {
473
- return `${source.name ?? source.value ?? ''}:${source.isExportable ?? false}:${source.isTypeOnly ?? false}`
474
+ const nameKey = source.name ?? extractStringsFromNodes(source.nodes)
475
+ return `${nameKey}:${source.isExportable ?? false}:${source.isTypeOnly ?? false}`
474
476
  }
475
477
 
476
478
  function pathTypeKey(path: string, isTypeOnly: boolean | undefined): string {
@@ -500,7 +502,7 @@ function sortKey(node: { name?: string | Array<unknown>; isTypeOnly?: boolean; p
500
502
  /**
501
503
  * Deduplicates an array of `SourceNode` objects.
502
504
  * Named sources are deduplicated by `name + isExportable + isTypeOnly`.
503
- * Unnamed sources are deduplicated by `value`.
505
+ * Unnamed sources are deduplicated by object reference.
504
506
  */
505
507
  export function combineSources(sources: Array<SourceNode>): Array<SourceNode> {
506
508
  const seen = new Map<string, SourceNode>()
@@ -607,3 +609,32 @@ export function combineImports(imports: Array<ImportNode>, exports: Array<Export
607
609
 
608
610
  return result
609
611
  }
612
+
613
+ /**
614
+ * Recursively extracts all string content embedded in a {@link CodeNode} tree.
615
+ *
616
+ * Includes text node values, and string attribute fields (`params`, `generics`,
617
+ * `returnType`, `type`) that may reference identifiers needing imports.
618
+ * Used by `createFile` to build the full source string for import filtering.
619
+ */
620
+ export function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): string {
621
+ if (!nodes?.length) return ''
622
+ return nodes
623
+ .map((node) => {
624
+ // Backward-compat: compiled plugins may still pass bare strings at runtime
625
+ if (typeof node === 'string') return node as string
626
+ if (node.kind === 'Text') return node.value
627
+ if (node.kind === 'Break') return ''
628
+ if (node.kind === 'Jsx') return node.value
629
+ const parts: string[] = []
630
+ if ('params' in node && node.params) parts.push(node.params)
631
+ if ('generics' in node && node.generics) parts.push(Array.isArray(node.generics) ? node.generics.join(', ') : node.generics)
632
+ if ('returnType' in node && node.returnType) parts.push(node.returnType)
633
+ if ('type' in node && typeof node.type === 'string') parts.push(node.type)
634
+ const nested = extractStringsFromNodes(node.nodes)
635
+ if (nested) parts.push(nested)
636
+ return parts.join('\n')
637
+ })
638
+ .filter(Boolean)
639
+ .join('\n')
640
+ }