@kubb/renderer-jsx 5.0.0-beta.21 → 5.0.0-beta.23

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 CHANGED
@@ -18382,19 +18382,29 @@ var SyncRuntime = class {
18382
18382
  //#endregion
18383
18383
  //#region src/createRenderer.tsx
18384
18384
  /**
18385
- * Renderer factory for generators that produce JSX output.
18385
+ * Renderer factory that turns the JSX produced by a generator into
18386
+ * `FileNode`s using React's reconciler under the hood. Pass as the `renderer`
18387
+ * property on `defineGenerator`. Kubb core stays generic, with no hard
18388
+ * dependency on `@kubb/renderer-jsx`.
18386
18389
  *
18387
- * Pass as the `renderer` property of `defineGenerator`. Core drives rendering
18388
- * without a hard dependency on `@kubb/renderer-jsx`.
18390
+ * Use this when generators rely on React features (hooks, suspense, context).
18391
+ * For pure-function components, see {@link jsxRendererSync} for ~2-4× faster
18392
+ * rendering.
18389
18393
  *
18390
- * @example
18391
- * ```ts
18394
+ * @example Wire up a JSX generator
18395
+ * ```tsx
18396
+ * import { defineGenerator } from '@kubb/core'
18392
18397
  * import { jsxRenderer } from '@kubb/renderer-jsx'
18393
18398
  *
18394
18399
  * export const myGenerator = defineGenerator<PluginTs>({
18400
+ * name: 'types',
18395
18401
  * renderer: jsxRenderer,
18396
- * schema(node, options) {
18397
- * return <File baseName="output.ts" path="src/output.ts">...</File>
18402
+ * schema(node, ctx) {
18403
+ * return (
18404
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
18405
+ * <Type node={node} resolver={ctx.resolver} />
18406
+ * </File>
18407
+ * )
18398
18408
  * },
18399
18409
  * })
18400
18410
  * ```
@@ -18420,28 +18430,40 @@ const jsxRenderer = () => {
18420
18430
  };
18421
18431
  };
18422
18432
  /**
18423
- * Lightweight renderer factory with no React fiber, scheduler, or work loop.
18433
+ * Lightweight renderer that walks the JSX tree in a single recursive pass —
18434
+ * no React reconciler, no scheduler. Drop-in replacement for
18435
+ * {@link jsxRenderer} at roughly 2–4× the throughput.
18424
18436
  *
18425
- * Walks the JSX element tree in a single recursive pass. All components must be
18426
- * pure functions; hooks and class components are not supported. Drop-in
18427
- * replacement for {@link jsxRenderer} at approximately 2–4× the speed.
18437
+ * Constraints: every component must be a pure function. Hooks, suspense, and
18438
+ * class components are not supported.
18428
18439
  *
18429
- * @example Drop-in replacement
18430
- * ```ts
18440
+ * Use this for generators that produce large amounts of output and do not need
18441
+ * React's runtime features. It also exposes `stream()` for incremental file
18442
+ * emission.
18443
+ *
18444
+ * @example Drop-in faster renderer
18445
+ * ```tsx
18446
+ * import { defineGenerator } from '@kubb/core'
18431
18447
  * import { jsxRendererSync } from '@kubb/renderer-jsx'
18432
18448
  *
18433
18449
  * export const myGenerator = defineGenerator<PluginTs>({
18450
+ * name: 'types',
18434
18451
  * renderer: jsxRendererSync,
18435
- * schema(node, options) {
18436
- * return <File baseName="output.ts" path="src/output.ts">...</File>
18452
+ * schema(node, ctx) {
18453
+ * return (
18454
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
18455
+ * <Type node={node} resolver={ctx.resolver} />
18456
+ * </File>
18457
+ * )
18437
18458
  * },
18438
18459
  * })
18439
18460
  * ```
18440
18461
  *
18441
18462
  * @example Stream files as they are produced
18442
- * ```ts
18443
- * for await (const file of jsxRendererSync().stream(element)) {
18444
- * await writeFile(file)
18463
+ * ```tsx
18464
+ * const renderer = jsxRendererSync()
18465
+ * for (const file of renderer.stream(element)) {
18466
+ * await writeFile(file.path, file.sources[0])
18445
18467
  * }
18446
18468
  * ```
18447
18469
  */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as __name } from "./chunk-Bb7HlUDG.js";
2
- import { a as JSDoc, h as KubbReactNode, m as KubbReactElement, o as Key } from "./types-D3-ni438.js";
2
+ import { a as JSDoc, h as KubbReactNode, m as KubbReactElement, o as Key } from "./types-ChkUbtyQ.js";
3
3
  import { ExportNode, FileNode, ImportNode, SourceNode } from "@kubb/ast";
4
4
  import * as _$react from "react";
5
5
 
@@ -63,26 +63,26 @@ type ConstProps = {
63
63
  * - `false` generates `const name = …`
64
64
  * @default false
65
65
  */
66
- export?: boolean;
66
+ export?: boolean | null;
67
67
  /**
68
68
  * TypeScript type annotation for the constant, written verbatim after `const name:`.
69
69
  *
70
70
  * @example
71
71
  * `type: 'Pet'` → `const pet: Pet = …`
72
72
  */
73
- type?: string;
73
+ type?: string | null;
74
74
  /**
75
75
  * JSDoc block to prepend to the constant declaration.
76
76
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
77
77
  */
78
- JSDoc?: JSDoc;
78
+ JSDoc?: JSDoc | null;
79
79
  /**
80
80
  * Append `as const` after the initialiser, enabling TypeScript const assertions.
81
81
  * - `true` generates `const name = … as const`
82
82
  * - `false` generates `const name = …`
83
83
  * @default false
84
84
  */
85
- asConst?: boolean;
85
+ asConst?: boolean | null;
86
86
  /**
87
87
  * Child nodes rendered as the initialiser expression of the constant.
88
88
  */
@@ -140,7 +140,7 @@ type BasePropsWithoutBaseName = {
140
140
  * Fully qualified path to the generated file.
141
141
  * Optional when `baseName` is omitted — the component renders its children inline.
142
142
  */
143
- path?: string;
143
+ path?: string | null;
144
144
  };
145
145
  type BaseProps = BasePropsWithBaseName | BasePropsWithoutBaseName;
146
146
  type Props$2<TMeta> = BaseProps & {
@@ -149,15 +149,17 @@ type Props$2<TMeta> = BaseProps & {
149
149
  * Arbitrary metadata attached to the file node.
150
150
  * Used by plugins for barrel generation and custom post-processing.
151
151
  */
152
- meta?: TMeta;
152
+ meta?: TMeta | null;
153
153
  /**
154
154
  * Text prepended to the generated file content before any source blocks.
155
+ * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
155
156
  */
156
- banner?: string;
157
+ banner?: string | null;
157
158
  /**
158
159
  * Text appended to the generated file content after all source blocks.
160
+ * Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
159
161
  */
160
- footer?: string;
162
+ footer?: string | null;
161
163
  /**
162
164
  * Child nodes rendered as the content of this file (source blocks, imports, exports).
163
165
  */
@@ -293,28 +295,28 @@ type Props$1 = {
293
295
  * Requires `export` to also be `true`.
294
296
  * @default false
295
297
  */
296
- default?: boolean;
298
+ default?: boolean | null;
297
299
  /**
298
300
  * Parameter list written verbatim between the function's parentheses.
299
301
  *
300
302
  * @example
301
303
  * `params: 'petId: string, options?: RequestOptions'`
302
304
  */
303
- params?: string;
305
+ params?: string | null;
304
306
  /**
305
307
  * Emit the `export` keyword before the function declaration.
306
308
  * - `true` generates `export function name(…) { … }`
307
309
  * - `false` generates `function name(…) { … }`
308
310
  * @default false
309
311
  */
310
- export?: boolean;
312
+ export?: boolean | null;
311
313
  /**
312
314
  * Emit the `async` keyword, making this an async function.
313
315
  * The return type is automatically wrapped in `Promise<returnType>` when both
314
316
  * `async` and `returnType` are set.
315
317
  * @default false
316
318
  */
317
- async?: boolean;
319
+ async?: boolean | null;
318
320
  /**
319
321
  * TypeScript generic type parameters written verbatim between `<` and `>`.
320
322
  * Pass an array to emit multiple parameters separated by commas.
@@ -325,7 +327,7 @@ type Props$1 = {
325
327
  * @example Multiple generics
326
328
  * `generics: ['TData', 'TError = unknown']`
327
329
  */
328
- generics?: string | string[];
330
+ generics?: string | string[] | null;
329
331
  /**
330
332
  * TypeScript return type annotation written verbatim after `:`.
331
333
  * When `async` is `true`, the value is automatically wrapped in `Promise<…>`.
@@ -333,12 +335,12 @@ type Props$1 = {
333
335
  * @example
334
336
  * `returnType: 'Pet'`
335
337
  */
336
- returnType?: string;
338
+ returnType?: string | null;
337
339
  /**
338
340
  * JSDoc block to prepend to the function declaration.
339
341
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
340
342
  */
341
- JSDoc?: JSDoc;
343
+ JSDoc?: JSDoc | null;
342
344
  /**
343
345
  * Child nodes rendered as the body of the function.
344
346
  */
@@ -372,7 +374,7 @@ type ArrowFunctionProps = Props$1 & {
372
374
  * - `false` generates `const name = (…) => { … }`
373
375
  * @default false
374
376
  */
375
- singleLine?: boolean;
377
+ singleLine?: boolean | null;
376
378
  };
377
379
  /**
378
380
  * Generates an arrow function expression assigned to a `const`.
@@ -478,12 +480,12 @@ type TypeProps = {
478
480
  * - `false` generates `type Name = …`
479
481
  * @default false
480
482
  */
481
- export?: boolean;
483
+ export?: boolean | null;
482
484
  /**
483
485
  * JSDoc block to prepend to the type alias declaration.
484
486
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
485
487
  */
486
- JSDoc?: JSDoc;
488
+ JSDoc?: JSDoc | null;
487
489
  /**
488
490
  * Child nodes rendered as the type expression on the right-hand side of the alias.
489
491
  */
@@ -520,19 +522,29 @@ declare namespace Type {
520
522
  //#endregion
521
523
  //#region src/createRenderer.d.ts
522
524
  /**
523
- * Renderer factory for generators that produce JSX output.
525
+ * Renderer factory that turns the JSX produced by a generator into
526
+ * `FileNode`s using React's reconciler under the hood. Pass as the `renderer`
527
+ * property on `defineGenerator`. Kubb core stays generic, with no hard
528
+ * dependency on `@kubb/renderer-jsx`.
524
529
  *
525
- * Pass as the `renderer` property of `defineGenerator`. Core drives rendering
526
- * without a hard dependency on `@kubb/renderer-jsx`.
530
+ * Use this when generators rely on React features (hooks, suspense, context).
531
+ * For pure-function components, see {@link jsxRendererSync} for ~2-4× faster
532
+ * rendering.
527
533
  *
528
- * @example
529
- * ```ts
534
+ * @example Wire up a JSX generator
535
+ * ```tsx
536
+ * import { defineGenerator } from '@kubb/core'
530
537
  * import { jsxRenderer } from '@kubb/renderer-jsx'
531
538
  *
532
539
  * export const myGenerator = defineGenerator<PluginTs>({
540
+ * name: 'types',
533
541
  * renderer: jsxRenderer,
534
- * schema(node, options) {
535
- * return <File baseName="output.ts" path="src/output.ts">...</File>
542
+ * schema(node, ctx) {
543
+ * return (
544
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
545
+ * <Type node={node} resolver={ctx.resolver} />
546
+ * </File>
547
+ * )
536
548
  * },
537
549
  * })
538
550
  * ```
@@ -545,28 +557,40 @@ declare const jsxRenderer: () => {
545
557
  [Symbol.dispose](): void;
546
558
  };
547
559
  /**
548
- * Lightweight renderer factory with no React fiber, scheduler, or work loop.
560
+ * Lightweight renderer that walks the JSX tree in a single recursive pass —
561
+ * no React reconciler, no scheduler. Drop-in replacement for
562
+ * {@link jsxRenderer} at roughly 2–4× the throughput.
549
563
  *
550
- * Walks the JSX element tree in a single recursive pass. All components must be
551
- * pure functions; hooks and class components are not supported. Drop-in
552
- * replacement for {@link jsxRenderer} at approximately 2–4× the speed.
564
+ * Constraints: every component must be a pure function. Hooks, suspense, and
565
+ * class components are not supported.
553
566
  *
554
- * @example Drop-in replacement
555
- * ```ts
567
+ * Use this for generators that produce large amounts of output and do not need
568
+ * React's runtime features. It also exposes `stream()` for incremental file
569
+ * emission.
570
+ *
571
+ * @example Drop-in faster renderer
572
+ * ```tsx
573
+ * import { defineGenerator } from '@kubb/core'
556
574
  * import { jsxRendererSync } from '@kubb/renderer-jsx'
557
575
  *
558
576
  * export const myGenerator = defineGenerator<PluginTs>({
577
+ * name: 'types',
559
578
  * renderer: jsxRendererSync,
560
- * schema(node, options) {
561
- * return <File baseName="output.ts" path="src/output.ts">...</File>
579
+ * schema(node, ctx) {
580
+ * return (
581
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
582
+ * <Type node={node} resolver={ctx.resolver} />
583
+ * </File>
584
+ * )
562
585
  * },
563
586
  * })
564
587
  * ```
565
588
  *
566
589
  * @example Stream files as they are produced
567
- * ```ts
568
- * for await (const file of jsxRendererSync().stream(element)) {
569
- * await writeFile(file)
590
+ * ```tsx
591
+ * const renderer = jsxRendererSync()
592
+ * for (const file of renderer.stream(element)) {
593
+ * await writeFile(file.path, file.sources[0])
570
594
  * }
571
595
  * ```
572
596
  */
package/dist/index.js CHANGED
@@ -18379,19 +18379,29 @@ var SyncRuntime = class {
18379
18379
  //#endregion
18380
18380
  //#region src/createRenderer.tsx
18381
18381
  /**
18382
- * Renderer factory for generators that produce JSX output.
18382
+ * Renderer factory that turns the JSX produced by a generator into
18383
+ * `FileNode`s using React's reconciler under the hood. Pass as the `renderer`
18384
+ * property on `defineGenerator`. Kubb core stays generic, with no hard
18385
+ * dependency on `@kubb/renderer-jsx`.
18383
18386
  *
18384
- * Pass as the `renderer` property of `defineGenerator`. Core drives rendering
18385
- * without a hard dependency on `@kubb/renderer-jsx`.
18387
+ * Use this when generators rely on React features (hooks, suspense, context).
18388
+ * For pure-function components, see {@link jsxRendererSync} for ~2-4× faster
18389
+ * rendering.
18386
18390
  *
18387
- * @example
18388
- * ```ts
18391
+ * @example Wire up a JSX generator
18392
+ * ```tsx
18393
+ * import { defineGenerator } from '@kubb/core'
18389
18394
  * import { jsxRenderer } from '@kubb/renderer-jsx'
18390
18395
  *
18391
18396
  * export const myGenerator = defineGenerator<PluginTs>({
18397
+ * name: 'types',
18392
18398
  * renderer: jsxRenderer,
18393
- * schema(node, options) {
18394
- * return <File baseName="output.ts" path="src/output.ts">...</File>
18399
+ * schema(node, ctx) {
18400
+ * return (
18401
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
18402
+ * <Type node={node} resolver={ctx.resolver} />
18403
+ * </File>
18404
+ * )
18395
18405
  * },
18396
18406
  * })
18397
18407
  * ```
@@ -18417,28 +18427,40 @@ const jsxRenderer = () => {
18417
18427
  };
18418
18428
  };
18419
18429
  /**
18420
- * Lightweight renderer factory with no React fiber, scheduler, or work loop.
18430
+ * Lightweight renderer that walks the JSX tree in a single recursive pass —
18431
+ * no React reconciler, no scheduler. Drop-in replacement for
18432
+ * {@link jsxRenderer} at roughly 2–4× the throughput.
18421
18433
  *
18422
- * Walks the JSX element tree in a single recursive pass. All components must be
18423
- * pure functions; hooks and class components are not supported. Drop-in
18424
- * replacement for {@link jsxRenderer} at approximately 2–4× the speed.
18434
+ * Constraints: every component must be a pure function. Hooks, suspense, and
18435
+ * class components are not supported.
18425
18436
  *
18426
- * @example Drop-in replacement
18427
- * ```ts
18437
+ * Use this for generators that produce large amounts of output and do not need
18438
+ * React's runtime features. It also exposes `stream()` for incremental file
18439
+ * emission.
18440
+ *
18441
+ * @example Drop-in faster renderer
18442
+ * ```tsx
18443
+ * import { defineGenerator } from '@kubb/core'
18428
18444
  * import { jsxRendererSync } from '@kubb/renderer-jsx'
18429
18445
  *
18430
18446
  * export const myGenerator = defineGenerator<PluginTs>({
18447
+ * name: 'types',
18431
18448
  * renderer: jsxRendererSync,
18432
- * schema(node, options) {
18433
- * return <File baseName="output.ts" path="src/output.ts">...</File>
18449
+ * schema(node, ctx) {
18450
+ * return (
18451
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
18452
+ * <Type node={node} resolver={ctx.resolver} />
18453
+ * </File>
18454
+ * )
18434
18455
  * },
18435
18456
  * })
18436
18457
  * ```
18437
18458
  *
18438
18459
  * @example Stream files as they are produced
18439
- * ```ts
18440
- * for await (const file of jsxRendererSync().stream(element)) {
18441
- * await writeFile(file)
18460
+ * ```tsx
18461
+ * const renderer = jsxRendererSync()
18462
+ * for (const file of renderer.stream(element)) {
18463
+ * await writeFile(file.path, file.sources[0])
18442
18464
  * }
18443
18465
  * ```
18444
18466
  */
@@ -1,6 +1,6 @@
1
1
  import { n as __name } from "./chunk-Bb7HlUDG.js";
2
- import { h as KubbReactNode, m as KubbReactElement } from "./types-D3-ni438.js";
3
- import { t as JSX } from "./jsx-namespace-C7dcxEyT.js";
2
+ import { h as KubbReactNode, m as KubbReactElement } from "./types-ChkUbtyQ.js";
3
+ import { t as JSX } from "./jsx-namespace-BW3LepJB.js";
4
4
  import * as _$react from "react";
5
5
  import * as React$1 from "react/jsx-runtime";
6
6
 
@@ -1,5 +1,5 @@
1
1
  import { n as __name } from "./chunk-Bb7HlUDG.js";
2
- import { _ as KubbTextProps, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, l as KubbExportProps, m as KubbReactElement, p as KubbJsxProps, s as KubbArrowFunctionProps, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-D3-ni438.js";
2
+ import { _ as KubbTextProps, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, l as KubbExportProps, m as KubbReactElement, p as KubbJsxProps, s as KubbArrowFunctionProps, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-ChkUbtyQ.js";
3
3
  import React from "react";
4
4
 
5
5
  //#region src/jsx-namespace.d.ts
@@ -36,4 +36,4 @@ declare namespace JSX$1 {
36
36
  }
37
37
  //#endregion
38
38
  export { JSX$1 as t };
39
- //# sourceMappingURL=jsx-namespace-C7dcxEyT.d.ts.map
39
+ //# sourceMappingURL=jsx-namespace-BW3LepJB.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { n as __name } from "./chunk-Bb7HlUDG.js";
2
- import { h as KubbReactNode, m as KubbReactElement } from "./types-D3-ni438.js";
3
- import { t as JSX } from "./jsx-namespace-C7dcxEyT.js";
2
+ import { h as KubbReactNode, m as KubbReactElement } from "./types-ChkUbtyQ.js";
3
+ import { t as JSX } from "./jsx-namespace-BW3LepJB.js";
4
4
  import * as _$react from "react";
5
5
  import * as React$1 from "react/jsx-runtime";
6
6
 
@@ -18,8 +18,9 @@ type Node = {
18
18
  };
19
19
  /**
20
20
  * Allowed attribute value types for DOM elements.
21
+ * `null` signals intentionally empty — the prop was explicitly cleared.
21
22
  */
22
- type DOMNodeAttribute = boolean | string | number | Record<string, unknown> | Array<unknown>;
23
+ type DOMNodeAttribute = boolean | string | number | null | Record<string, unknown> | Array<unknown>;
23
24
  type TextName = '#text';
24
25
  /**
25
26
  * Leaf DOM node containing raw text.
@@ -86,12 +87,12 @@ type KubbTextProps = {
86
87
  * Represents a generated file.
87
88
  */
88
89
  type KubbFileProps = {
89
- id?: string;
90
+ id?: string | null;
90
91
  children?: KubbReactNode;
91
92
  baseName: string;
92
93
  path: string;
93
- override?: boolean;
94
- meta?: FileNode['meta'];
94
+ override?: boolean | null;
95
+ meta?: FileNode['meta'] | null;
95
96
  };
96
97
  /**
97
98
  * Props for the `<kubb-source>` element.
@@ -165,4 +166,4 @@ type JSDoc = {
165
166
  };
166
167
  //#endregion
167
168
  export { KubbTextProps as _, JSDoc as a, TextNode as b, KubbConstProps as c, KubbFunctionProps as d, KubbImportProps as f, KubbSourceProps as g, KubbReactNode as h, ElementNames as i, KubbExportProps as l, KubbReactElement as m, DOMNode as n, Key as o, KubbJsxProps as p, DOMNodeAttribute as r, KubbArrowFunctionProps as s, DOMElement as t, KubbFileProps as u, KubbTypeProps as v, LineBreakProps as y };
168
- //# sourceMappingURL=types-D3-ni438.d.ts.map
169
+ //# sourceMappingURL=types-ChkUbtyQ.d.ts.map
package/dist/types.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as KubbTextProps, a as JSDoc, b as TextNode, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, i as ElementNames, l as KubbExportProps, m as KubbReactElement, n as DOMNode, o as Key, p as KubbJsxProps, r as DOMNodeAttribute, s as KubbArrowFunctionProps, t as DOMElement, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-D3-ni438.js";
1
+ import { _ as KubbTextProps, a as JSDoc, b as TextNode, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, i as ElementNames, l as KubbExportProps, m as KubbReactElement, n as DOMNode, o as Key, p as KubbJsxProps, r as DOMNodeAttribute, s as KubbArrowFunctionProps, t as DOMElement, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-ChkUbtyQ.js";
2
2
  export { DOMElement, DOMNode, DOMNodeAttribute, ElementNames, JSDoc, Key, KubbArrowFunctionProps, KubbConstProps, KubbExportProps, KubbFileProps, KubbFunctionProps, KubbImportProps, KubbJsxProps, KubbReactElement, KubbReactNode, KubbSourceProps, KubbTextProps, KubbTypeProps, LineBreakProps, TextNode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/renderer-jsx",
3
- "version": "5.0.0-beta.21",
3
+ "version": "5.0.0-beta.23",
4
4
  "description": "JSX-based renderer for Kubb. Provides a custom React runtime, reconciler, and built-in components (File, Function, Type, Const) for component-based, type-safe code generation.",
5
5
  "keywords": [
6
6
  "codegen",
@@ -75,7 +75,7 @@
75
75
  "registry": "https://registry.npmjs.org/"
76
76
  },
77
77
  "dependencies": {
78
- "@kubb/ast": "5.0.0-beta.21"
78
+ "@kubb/ast": "5.0.0-beta.23"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@types/react": "^19.2.14",
@@ -99,13 +99,13 @@ function resolveCodeNode(type: string, props: Record<string, unknown>, nodes: Co
99
99
  nodes.push(
100
100
  createFunction({
101
101
  name: props['name'] as string,
102
- params: props['params'] as string | undefined,
103
- export: props['export'] as boolean | undefined,
104
- default: props['default'] as boolean | undefined,
105
- async: props['async'] as boolean | undefined,
106
- generics: props['generics'] as string | undefined,
107
- returnType: props['returnType'] as string | undefined,
108
- JSDoc: props['JSDoc'] as JSDocNode | undefined,
102
+ params: props['params'] as string | null | undefined,
103
+ export: props['export'] as boolean | null | undefined,
104
+ default: props['default'] as boolean | null | undefined,
105
+ async: props['async'] as boolean | null | undefined,
106
+ generics: props['generics'] as string | string[] | null | undefined,
107
+ returnType: props['returnType'] as string | null | undefined,
108
+ JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
109
109
  nodes: collectCodeNodes(props),
110
110
  }),
111
111
  )
@@ -116,14 +116,14 @@ function resolveCodeNode(type: string, props: Record<string, unknown>, nodes: Co
116
116
  nodes.push(
117
117
  createArrowFunction({
118
118
  name: props['name'] as string,
119
- params: props['params'] as string | undefined,
120
- export: props['export'] as boolean | undefined,
121
- default: props['default'] as boolean | undefined,
122
- async: props['async'] as boolean | undefined,
123
- generics: props['generics'] as string | undefined,
124
- returnType: props['returnType'] as string | undefined,
125
- singleLine: props['singleLine'] as boolean | undefined,
126
- JSDoc: props['JSDoc'] as JSDocNode | undefined,
119
+ params: props['params'] as string | null | undefined,
120
+ export: props['export'] as boolean | null | undefined,
121
+ default: props['default'] as boolean | null | undefined,
122
+ async: props['async'] as boolean | null | undefined,
123
+ generics: props['generics'] as string | string[] | null | undefined,
124
+ returnType: props['returnType'] as string | null | undefined,
125
+ singleLine: props['singleLine'] as boolean | null | undefined,
126
+ JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
127
127
  nodes: collectCodeNodes(props),
128
128
  } as Omit<ArrowFunctionNode, 'kind'>),
129
129
  )
@@ -134,10 +134,10 @@ function resolveCodeNode(type: string, props: Record<string, unknown>, nodes: Co
134
134
  nodes.push(
135
135
  createConst({
136
136
  name: props['name'] as string,
137
- type: props['type'] as string | undefined,
138
- export: props['export'] as boolean | undefined,
139
- asConst: props['asConst'] as boolean | undefined,
140
- JSDoc: props['JSDoc'] as JSDocNode | undefined,
137
+ type: props['type'] as string | null | undefined,
138
+ export: props['export'] as boolean | null | undefined,
139
+ asConst: props['asConst'] as boolean | null | undefined,
140
+ JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
141
141
  nodes: collectCodeNodes(props),
142
142
  }),
143
143
  )
@@ -148,8 +148,8 @@ function resolveCodeNode(type: string, props: Record<string, unknown>, nodes: Co
148
148
  nodes.push(
149
149
  createType({
150
150
  name: props['name'] as string,
151
- export: props['export'] as boolean | undefined,
152
- JSDoc: props['JSDoc'] as JSDocNode | undefined,
151
+ export: props['export'] as boolean | null | undefined,
152
+ JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
153
153
  nodes: collectCodeNodes(props),
154
154
  }),
155
155
  )
@@ -202,7 +202,7 @@ function collectFileChildren(element: unknown): FileChildren {
202
202
  createImport({
203
203
  name: props['name'] as ImportNode['name'],
204
204
  path: props['path'] as string,
205
- root: props['root'] as string | undefined,
205
+ root: props['root'] as string | null | undefined,
206
206
  isTypeOnly: toBool(props['isTypeOnly']),
207
207
  isNameSpace: toBool(props['isNameSpace']),
208
208
  }),
@@ -15,26 +15,26 @@ type ConstProps = {
15
15
  * - `false` generates `const name = …`
16
16
  * @default false
17
17
  */
18
- export?: boolean
18
+ export?: boolean | null
19
19
  /**
20
20
  * TypeScript type annotation for the constant, written verbatim after `const name:`.
21
21
  *
22
22
  * @example
23
23
  * `type: 'Pet'` → `const pet: Pet = …`
24
24
  */
25
- type?: string
25
+ type?: string | null
26
26
  /**
27
27
  * JSDoc block to prepend to the constant declaration.
28
28
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
29
29
  */
30
- JSDoc?: JSDoc
30
+ JSDoc?: JSDoc | null
31
31
  /**
32
32
  * Append `as const` after the initialiser, enabling TypeScript const assertions.
33
33
  * - `true` generates `const name = … as const`
34
34
  * - `false` generates `const name = …`
35
35
  * @default false
36
36
  */
37
- asConst?: boolean
37
+ asConst?: boolean | null
38
38
  /**
39
39
  * Child nodes rendered as the initialiser expression of the constant.
40
40
  */
@@ -27,7 +27,7 @@ type BasePropsWithoutBaseName = {
27
27
  * Fully qualified path to the generated file.
28
28
  * Optional when `baseName` is omitted — the component renders its children inline.
29
29
  */
30
- path?: string
30
+ path?: string | null
31
31
  }
32
32
 
33
33
  type BaseProps = BasePropsWithBaseName | BasePropsWithoutBaseName
@@ -38,15 +38,17 @@ type Props<TMeta> = BaseProps & {
38
38
  * Arbitrary metadata attached to the file node.
39
39
  * Used by plugins for barrel generation and custom post-processing.
40
40
  */
41
- meta?: TMeta
41
+ meta?: TMeta | null
42
42
  /**
43
43
  * Text prepended to the generated file content before any source blocks.
44
+ * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
44
45
  */
45
- banner?: string
46
+ banner?: string | null
46
47
  /**
47
48
  * Text appended to the generated file content after all source blocks.
49
+ * Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
48
50
  */
49
- footer?: string
51
+ footer?: string | null
50
52
  /**
51
53
  * Child nodes rendered as the content of this file (source blocks, imports, exports).
52
54
  */
@@ -14,28 +14,28 @@ type Props = {
14
14
  * Requires `export` to also be `true`.
15
15
  * @default false
16
16
  */
17
- default?: boolean
17
+ default?: boolean | null
18
18
  /**
19
19
  * Parameter list written verbatim between the function's parentheses.
20
20
  *
21
21
  * @example
22
22
  * `params: 'petId: string, options?: RequestOptions'`
23
23
  */
24
- params?: string
24
+ params?: string | null
25
25
  /**
26
26
  * Emit the `export` keyword before the function declaration.
27
27
  * - `true` generates `export function name(…) { … }`
28
28
  * - `false` generates `function name(…) { … }`
29
29
  * @default false
30
30
  */
31
- export?: boolean
31
+ export?: boolean | null
32
32
  /**
33
33
  * Emit the `async` keyword, making this an async function.
34
34
  * The return type is automatically wrapped in `Promise<returnType>` when both
35
35
  * `async` and `returnType` are set.
36
36
  * @default false
37
37
  */
38
- async?: boolean
38
+ async?: boolean | null
39
39
  /**
40
40
  * TypeScript generic type parameters written verbatim between `<` and `>`.
41
41
  * Pass an array to emit multiple parameters separated by commas.
@@ -46,7 +46,7 @@ type Props = {
46
46
  * @example Multiple generics
47
47
  * `generics: ['TData', 'TError = unknown']`
48
48
  */
49
- generics?: string | string[]
49
+ generics?: string | string[] | null
50
50
  /**
51
51
  * TypeScript return type annotation written verbatim after `:`.
52
52
  * When `async` is `true`, the value is automatically wrapped in `Promise<…>`.
@@ -54,12 +54,12 @@ type Props = {
54
54
  * @example
55
55
  * `returnType: 'Pet'`
56
56
  */
57
- returnType?: string
57
+ returnType?: string | null
58
58
  /**
59
59
  * JSDoc block to prepend to the function declaration.
60
60
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
61
61
  */
62
- JSDoc?: JSDoc
62
+ JSDoc?: JSDoc | null
63
63
  /**
64
64
  * Child nodes rendered as the body of the function.
65
65
  */
@@ -110,7 +110,7 @@ type ArrowFunctionProps = Props & {
110
110
  * - `false` generates `const name = (…) => { … }`
111
111
  * @default false
112
112
  */
113
- singleLine?: boolean
113
+ singleLine?: boolean | null
114
114
  }
115
115
 
116
116
  /**
@@ -16,12 +16,12 @@ type TypeProps = {
16
16
  * - `false` generates `type Name = …`
17
17
  * @default false
18
18
  */
19
- export?: boolean
19
+ export?: boolean | null
20
20
  /**
21
21
  * JSDoc block to prepend to the type alias declaration.
22
22
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
23
23
  */
24
- JSDoc?: JSDoc
24
+ JSDoc?: JSDoc | null
25
25
  /**
26
26
  * Child nodes rendered as the type expression on the right-hand side of the alias.
27
27
  */
@@ -4,19 +4,29 @@ import { SyncRuntime } from './SyncRuntime.tsx'
4
4
  import type { KubbReactElement } from './types.ts'
5
5
 
6
6
  /**
7
- * Renderer factory for generators that produce JSX output.
7
+ * Renderer factory that turns the JSX produced by a generator into
8
+ * `FileNode`s using React's reconciler under the hood. Pass as the `renderer`
9
+ * property on `defineGenerator`. Kubb core stays generic, with no hard
10
+ * dependency on `@kubb/renderer-jsx`.
8
11
  *
9
- * Pass as the `renderer` property of `defineGenerator`. Core drives rendering
10
- * without a hard dependency on `@kubb/renderer-jsx`.
12
+ * Use this when generators rely on React features (hooks, suspense, context).
13
+ * For pure-function components, see {@link jsxRendererSync} for ~2-4× faster
14
+ * rendering.
11
15
  *
12
- * @example
13
- * ```ts
16
+ * @example Wire up a JSX generator
17
+ * ```tsx
18
+ * import { defineGenerator } from '@kubb/core'
14
19
  * import { jsxRenderer } from '@kubb/renderer-jsx'
15
20
  *
16
21
  * export const myGenerator = defineGenerator<PluginTs>({
22
+ * name: 'types',
17
23
  * renderer: jsxRenderer,
18
- * schema(node, options) {
19
- * return <File baseName="output.ts" path="src/output.ts">...</File>
24
+ * schema(node, ctx) {
25
+ * return (
26
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
27
+ * <Type node={node} resolver={ctx.resolver} />
28
+ * </File>
29
+ * )
20
30
  * },
21
31
  * })
22
32
  * ```
@@ -43,28 +53,40 @@ export const jsxRenderer = () => {
43
53
  }
44
54
 
45
55
  /**
46
- * Lightweight renderer factory with no React fiber, scheduler, or work loop.
56
+ * Lightweight renderer that walks the JSX tree in a single recursive pass —
57
+ * no React reconciler, no scheduler. Drop-in replacement for
58
+ * {@link jsxRenderer} at roughly 2–4× the throughput.
47
59
  *
48
- * Walks the JSX element tree in a single recursive pass. All components must be
49
- * pure functions; hooks and class components are not supported. Drop-in
50
- * replacement for {@link jsxRenderer} at approximately 2–4× the speed.
60
+ * Constraints: every component must be a pure function. Hooks, suspense, and
61
+ * class components are not supported.
51
62
  *
52
- * @example Drop-in replacement
53
- * ```ts
63
+ * Use this for generators that produce large amounts of output and do not need
64
+ * React's runtime features. It also exposes `stream()` for incremental file
65
+ * emission.
66
+ *
67
+ * @example Drop-in faster renderer
68
+ * ```tsx
69
+ * import { defineGenerator } from '@kubb/core'
54
70
  * import { jsxRendererSync } from '@kubb/renderer-jsx'
55
71
  *
56
72
  * export const myGenerator = defineGenerator<PluginTs>({
73
+ * name: 'types',
57
74
  * renderer: jsxRendererSync,
58
- * schema(node, options) {
59
- * return <File baseName="output.ts" path="src/output.ts">...</File>
75
+ * schema(node, ctx) {
76
+ * return (
77
+ * <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
78
+ * <Type node={node} resolver={ctx.resolver} />
79
+ * </File>
80
+ * )
60
81
  * },
61
82
  * })
62
83
  * ```
63
84
  *
64
85
  * @example Stream files as they are produced
65
- * ```ts
66
- * for await (const file of jsxRendererSync().stream(element)) {
67
- * await writeFile(file)
86
+ * ```tsx
87
+ * const renderer = jsxRendererSync()
88
+ * for (const file of renderer.stream(element)) {
89
+ * await writeFile(file.path, file.sources[0])
68
90
  * }
69
91
  * ```
70
92
  */
package/src/types.ts CHANGED
@@ -36,8 +36,9 @@ type Node = {
36
36
 
37
37
  /**
38
38
  * Allowed attribute value types for DOM elements.
39
+ * `null` signals intentionally empty — the prop was explicitly cleared.
39
40
  */
40
- export type DOMNodeAttribute = boolean | string | number | Record<string, unknown> | Array<unknown>
41
+ export type DOMNodeAttribute = boolean | string | number | null | Record<string, unknown> | Array<unknown>
41
42
 
42
43
  type TextName = '#text'
43
44
 
@@ -119,12 +120,12 @@ export type KubbTextProps = {
119
120
  * Represents a generated file.
120
121
  */
121
122
  export type KubbFileProps = {
122
- id?: string
123
+ id?: string | null
123
124
  children?: KubbReactNode
124
125
  baseName: string
125
126
  path: string
126
- override?: boolean
127
- meta?: FileNode['meta']
127
+ override?: boolean | null
128
+ meta?: FileNode['meta'] | null
128
129
  }
129
130
 
130
131
  /**
package/src/utils.ts CHANGED
@@ -59,13 +59,13 @@ function collectCodeNodes(element: DOMElement): CodeNode[] {
59
59
  result.push(
60
60
  createFunction({
61
61
  name: attrs['name'] as string,
62
- params: attrs['params'] as string | undefined,
63
- export: attrs['export'] as boolean | undefined,
64
- default: attrs['default'] as boolean | undefined,
65
- async: attrs['async'] as boolean | undefined,
66
- generics: attrs['generics'] as string | undefined,
67
- returnType: attrs['returnType'] as string | undefined,
68
- JSDoc: attrs['JSDoc'] as JSDocNode | undefined,
62
+ params: attrs['params'] as string | null | undefined,
63
+ export: attrs['export'] as boolean | null | undefined,
64
+ default: attrs['default'] as boolean | null | undefined,
65
+ async: attrs['async'] as boolean | null | undefined,
66
+ generics: attrs['generics'] as string | string[] | null | undefined,
67
+ returnType: attrs['returnType'] as string | null | undefined,
68
+ JSDoc: attrs['JSDoc'] as JSDocNode | null | undefined,
69
69
  nodes: collectCodeNodes(child),
70
70
  }),
71
71
  )
@@ -77,14 +77,14 @@ function collectCodeNodes(element: DOMElement): CodeNode[] {
77
77
  result.push(
78
78
  createArrowFunction({
79
79
  name: attrs['name'] as string,
80
- params: attrs['params'] as string | undefined,
81
- export: attrs['export'] as boolean | undefined,
82
- default: attrs['default'] as boolean | undefined,
83
- async: attrs['async'] as boolean | undefined,
84
- generics: attrs['generics'] as string | undefined,
85
- returnType: attrs['returnType'] as string | undefined,
86
- singleLine: attrs['singleLine'] as boolean | undefined,
87
- JSDoc: attrs['JSDoc'] as JSDocNode | undefined,
80
+ params: attrs['params'] as string | null | undefined,
81
+ export: attrs['export'] as boolean | null | undefined,
82
+ default: attrs['default'] as boolean | null | undefined,
83
+ async: attrs['async'] as boolean | null | undefined,
84
+ generics: attrs['generics'] as string | string[] | null | undefined,
85
+ returnType: attrs['returnType'] as string | null | undefined,
86
+ singleLine: attrs['singleLine'] as boolean | null | undefined,
87
+ JSDoc: attrs['JSDoc'] as JSDocNode | null | undefined,
88
88
  nodes: collectCodeNodes(child),
89
89
  } as Omit<ArrowFunctionNode, 'kind'>),
90
90
  )
@@ -96,10 +96,10 @@ function collectCodeNodes(element: DOMElement): CodeNode[] {
96
96
  result.push(
97
97
  createConst({
98
98
  name: attrs['name'] as string,
99
- type: attrs['type'] as string | undefined,
100
- export: attrs['export'] as boolean | undefined,
101
- asConst: attrs['asConst'] as boolean | undefined,
102
- JSDoc: attrs['JSDoc'] as JSDocNode | undefined,
99
+ type: attrs['type'] as string | null | undefined,
100
+ export: attrs['export'] as boolean | null | undefined,
101
+ asConst: attrs['asConst'] as boolean | null | undefined,
102
+ JSDoc: attrs['JSDoc'] as JSDocNode | null | undefined,
103
103
  nodes: collectCodeNodes(child),
104
104
  }),
105
105
  )
@@ -111,8 +111,8 @@ function collectCodeNodes(element: DOMElement): CodeNode[] {
111
111
  result.push(
112
112
  createType({
113
113
  name: attrs['name'] as string,
114
- export: attrs['export'] as boolean | undefined,
115
- JSDoc: attrs['JSDoc'] as JSDocNode | undefined,
114
+ export: attrs['export'] as boolean | null | undefined,
115
+ JSDoc: attrs['JSDoc'] as JSDocNode | null | undefined,
116
116
  nodes: collectCodeNodes(child),
117
117
  }),
118
118
  )
@@ -168,7 +168,7 @@ function* collectFileEntries(node: DOMElement): Generator<SourceNode | ExportNod
168
168
  yield createImport({
169
169
  name: child.attributes['name'] as ImportNode['name'],
170
170
  path: child.attributes['path'] as string,
171
- root: child.attributes['root'] as string | undefined,
171
+ root: child.attributes['root'] as string | null | undefined,
172
172
  isTypeOnly: toBool(child.attributes['isTypeOnly']),
173
173
  isNameSpace: toBool(child.attributes['isNameSpace']),
174
174
  })