@kubb/renderer-jsx 5.0.0-beta.22 → 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,7 +149,7 @@ 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
155
  * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
@@ -295,28 +295,28 @@ type Props$1 = {
295
295
  * Requires `export` to also be `true`.
296
296
  * @default false
297
297
  */
298
- default?: boolean;
298
+ default?: boolean | null;
299
299
  /**
300
300
  * Parameter list written verbatim between the function's parentheses.
301
301
  *
302
302
  * @example
303
303
  * `params: 'petId: string, options?: RequestOptions'`
304
304
  */
305
- params?: string;
305
+ params?: string | null;
306
306
  /**
307
307
  * Emit the `export` keyword before the function declaration.
308
308
  * - `true` generates `export function name(…) { … }`
309
309
  * - `false` generates `function name(…) { … }`
310
310
  * @default false
311
311
  */
312
- export?: boolean;
312
+ export?: boolean | null;
313
313
  /**
314
314
  * Emit the `async` keyword, making this an async function.
315
315
  * The return type is automatically wrapped in `Promise<returnType>` when both
316
316
  * `async` and `returnType` are set.
317
317
  * @default false
318
318
  */
319
- async?: boolean;
319
+ async?: boolean | null;
320
320
  /**
321
321
  * TypeScript generic type parameters written verbatim between `<` and `>`.
322
322
  * Pass an array to emit multiple parameters separated by commas.
@@ -327,7 +327,7 @@ type Props$1 = {
327
327
  * @example Multiple generics
328
328
  * `generics: ['TData', 'TError = unknown']`
329
329
  */
330
- generics?: string | string[];
330
+ generics?: string | string[] | null;
331
331
  /**
332
332
  * TypeScript return type annotation written verbatim after `:`.
333
333
  * When `async` is `true`, the value is automatically wrapped in `Promise<…>`.
@@ -335,12 +335,12 @@ type Props$1 = {
335
335
  * @example
336
336
  * `returnType: 'Pet'`
337
337
  */
338
- returnType?: string;
338
+ returnType?: string | null;
339
339
  /**
340
340
  * JSDoc block to prepend to the function declaration.
341
341
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
342
342
  */
343
- JSDoc?: JSDoc;
343
+ JSDoc?: JSDoc | null;
344
344
  /**
345
345
  * Child nodes rendered as the body of the function.
346
346
  */
@@ -374,7 +374,7 @@ type ArrowFunctionProps = Props$1 & {
374
374
  * - `false` generates `const name = (…) => { … }`
375
375
  * @default false
376
376
  */
377
- singleLine?: boolean;
377
+ singleLine?: boolean | null;
378
378
  };
379
379
  /**
380
380
  * Generates an arrow function expression assigned to a `const`.
@@ -480,12 +480,12 @@ type TypeProps = {
480
480
  * - `false` generates `type Name = …`
481
481
  * @default false
482
482
  */
483
- export?: boolean;
483
+ export?: boolean | null;
484
484
  /**
485
485
  * JSDoc block to prepend to the type alias declaration.
486
486
  * Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
487
487
  */
488
- JSDoc?: JSDoc;
488
+ JSDoc?: JSDoc | null;
489
489
  /**
490
490
  * Child nodes rendered as the type expression on the right-hand side of the alias.
491
491
  */
@@ -522,19 +522,29 @@ declare namespace Type {
522
522
  //#endregion
523
523
  //#region src/createRenderer.d.ts
524
524
  /**
525
- * 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`.
526
529
  *
527
- * Pass as the `renderer` property of `defineGenerator`. Core drives rendering
528
- * 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.
529
533
  *
530
- * @example
531
- * ```ts
534
+ * @example Wire up a JSX generator
535
+ * ```tsx
536
+ * import { defineGenerator } from '@kubb/core'
532
537
  * import { jsxRenderer } from '@kubb/renderer-jsx'
533
538
  *
534
539
  * export const myGenerator = defineGenerator<PluginTs>({
540
+ * name: 'types',
535
541
  * renderer: jsxRenderer,
536
- * schema(node, options) {
537
- * 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
+ * )
538
548
  * },
539
549
  * })
540
550
  * ```
@@ -547,28 +557,40 @@ declare const jsxRenderer: () => {
547
557
  [Symbol.dispose](): void;
548
558
  };
549
559
  /**
550
- * 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.
551
563
  *
552
- * Walks the JSX element tree in a single recursive pass. All components must be
553
- * pure functions; hooks and class components are not supported. Drop-in
554
- * 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.
555
566
  *
556
- * @example Drop-in replacement
557
- * ```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'
558
574
  * import { jsxRendererSync } from '@kubb/renderer-jsx'
559
575
  *
560
576
  * export const myGenerator = defineGenerator<PluginTs>({
577
+ * name: 'types',
561
578
  * renderer: jsxRendererSync,
562
- * schema(node, options) {
563
- * 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
+ * )
564
585
  * },
565
586
  * })
566
587
  * ```
567
588
  *
568
589
  * @example Stream files as they are produced
569
- * ```ts
570
- * for await (const file of jsxRendererSync().stream(element)) {
571
- * 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])
572
594
  * }
573
595
  * ```
574
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.22",
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.22"
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,7 +38,7 @@ 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
44
  * Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
@@ -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
  })