@kubb/renderer-jsx 5.0.0-beta.62 → 5.0.0-beta.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +23 -25
- package/dist/index.d.ts +23 -32
- package/dist/index.js +21 -24
- package/dist/jsx-dev-runtime.cjs +1 -1
- package/dist/jsx-dev-runtime.d.ts +2 -2
- package/dist/jsx-runtime.cjs +32 -5
- package/dist/jsx-runtime.d.ts +4 -5
- package/dist/jsx-runtime.js +1 -1
- package/dist/{jsx-runtime-3ncySO6L.cjs → rolldown-runtime-Bx3C2hgW.cjs} +0 -51
- package/dist/{types-UI1cZVah.d.ts → types-CC4v2M00.d.ts} +2 -2
- package/dist/types.d.ts +1 -1
- package/package.json +2 -3
- package/src/SyncRuntime.tsx +0 -298
- package/src/components/Callout.tsx +0 -59
- package/src/components/Const.tsx +0 -72
- package/src/components/File.tsx +0 -188
- package/src/components/Frontmatter.tsx +0 -38
- package/src/components/Function.tsx +0 -152
- package/src/components/Heading.tsx +0 -34
- package/src/components/Jsx.tsx +0 -34
- package/src/components/List.tsx +0 -40
- package/src/components/Paragraph.tsx +0 -28
- package/src/components/Type.tsx +0 -66
- package/src/constants.ts +0 -9
- package/src/createRenderer.tsx +0 -56
- package/src/globals.ts +0 -42
- package/src/index.ts +0 -11
- package/src/jsx-dev-runtime.ts +0 -8
- package/src/jsx-namespace.d.ts +0 -60
- package/src/jsx-runtime.ts +0 -28
- package/src/types.ts +0 -123
- /package/dist/{chunk-C0LytTxp.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/src/SyncRuntime.tsx
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
import type { ArrowFunctionNode, CodeNode, ExportNode, FileNode, ImportNode, JSDocNode, SourceNode } from '@kubb/ast'
|
|
2
|
-
import * as factory from '@kubb/ast/factory'
|
|
3
|
-
import { KUBB_ARROW_FUNCTION, KUBB_CONST, KUBB_EXPORT, KUBB_FILE, KUBB_FUNCTION, KUBB_IMPORT, KUBB_JSX, KUBB_SOURCE, KUBB_TYPE } from './constants.ts'
|
|
4
|
-
import { Fragment } from './jsx-runtime.ts'
|
|
5
|
-
import type { KubbReactElement } from './types.ts'
|
|
6
|
-
|
|
7
|
-
type OnText = (text: string) => void
|
|
8
|
-
type OnHost = (type: string, props: Record<string, unknown>) => void
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Walks `element`, resolving arrays, Fragments, and function components
|
|
12
|
-
* transparently, then calls `onText` for primitive values and `onHost` for
|
|
13
|
-
* every host element encountered. Pure function components are called
|
|
14
|
-
* synchronously. Hooks and class components are not supported.
|
|
15
|
-
*/
|
|
16
|
-
function walkElement(element: unknown, onText: OnText, onHost: OnHost): void {
|
|
17
|
-
if (element == null || typeof element === 'boolean') return
|
|
18
|
-
|
|
19
|
-
if (typeof element === 'string' || typeof element === 'number' || typeof element === 'bigint') {
|
|
20
|
-
onText(String(element))
|
|
21
|
-
return
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (Array.isArray(element)) {
|
|
25
|
-
for (const child of element) walkElement(child, onText, onHost)
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (typeof element === 'object' && '$$typeof' in element) {
|
|
30
|
-
const el = element as unknown as KubbReactElement
|
|
31
|
-
const { type } = el
|
|
32
|
-
const props = el.props as Record<string, unknown>
|
|
33
|
-
|
|
34
|
-
if (type === Fragment) {
|
|
35
|
-
walkElement(props['children'], onText, onHost)
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
if (typeof type === 'function') {
|
|
39
|
-
walkElement((type as (p: unknown) => unknown)(props), onText, onHost)
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
if (typeof type === 'string') {
|
|
43
|
-
onHost(type, props)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function toBool(val: unknown): boolean {
|
|
49
|
-
return (val ?? false) as boolean
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function collectCodeNodes(props: Record<string, unknown>): Array<CodeNode> {
|
|
53
|
-
const nodes: Array<CodeNode> = []
|
|
54
|
-
collectCode(props['children'], nodes)
|
|
55
|
-
return nodes
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function collectCode(element: unknown, nodes: Array<CodeNode>): void {
|
|
59
|
-
walkElement(
|
|
60
|
-
element,
|
|
61
|
-
(text) => {
|
|
62
|
-
if (text.trim()) nodes.push(factory.createText(text))
|
|
63
|
-
},
|
|
64
|
-
(type, props) => resolveCodeNode(type, props, nodes),
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function resolveCodeNode(type: string, props: Record<string, unknown>, nodes: Array<CodeNode>): void {
|
|
69
|
-
if (type === 'br') {
|
|
70
|
-
nodes.push(factory.createBreak())
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (type === KUBB_JSX) {
|
|
75
|
-
let value = ''
|
|
76
|
-
walkElement(
|
|
77
|
-
props['children'],
|
|
78
|
-
(t) => {
|
|
79
|
-
value += t
|
|
80
|
-
},
|
|
81
|
-
() => {},
|
|
82
|
-
)
|
|
83
|
-
if (value) nodes.push(factory.createJsx(value))
|
|
84
|
-
return
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (type === KUBB_FUNCTION) {
|
|
88
|
-
nodes.push(
|
|
89
|
-
factory.createFunction({
|
|
90
|
-
name: props['name'] as string,
|
|
91
|
-
params: props['params'] as string | null | undefined,
|
|
92
|
-
export: props['export'] as boolean | null | undefined,
|
|
93
|
-
default: props['default'] as boolean | null | undefined,
|
|
94
|
-
async: props['async'] as boolean | null | undefined,
|
|
95
|
-
generics: props['generics'] as string | Array<string> | null | undefined,
|
|
96
|
-
returnType: props['returnType'] as string | null | undefined,
|
|
97
|
-
JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
|
|
98
|
-
nodes: collectCodeNodes(props),
|
|
99
|
-
}),
|
|
100
|
-
)
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (type === KUBB_ARROW_FUNCTION) {
|
|
105
|
-
nodes.push(
|
|
106
|
-
factory.createArrowFunction({
|
|
107
|
-
name: props['name'] as string,
|
|
108
|
-
params: props['params'] as string | null | undefined,
|
|
109
|
-
export: props['export'] as boolean | null | undefined,
|
|
110
|
-
default: props['default'] as boolean | null | undefined,
|
|
111
|
-
async: props['async'] as boolean | null | undefined,
|
|
112
|
-
generics: props['generics'] as string | Array<string> | null | undefined,
|
|
113
|
-
returnType: props['returnType'] as string | null | undefined,
|
|
114
|
-
singleLine: props['singleLine'] as boolean | null | undefined,
|
|
115
|
-
JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
|
|
116
|
-
nodes: collectCodeNodes(props),
|
|
117
|
-
} as Omit<ArrowFunctionNode, 'kind'>),
|
|
118
|
-
)
|
|
119
|
-
return
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (type === KUBB_CONST) {
|
|
123
|
-
nodes.push(
|
|
124
|
-
factory.createConst({
|
|
125
|
-
name: props['name'] as string,
|
|
126
|
-
type: props['type'] as string | null | undefined,
|
|
127
|
-
export: props['export'] as boolean | null | undefined,
|
|
128
|
-
asConst: props['asConst'] as boolean | null | undefined,
|
|
129
|
-
JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
|
|
130
|
-
nodes: collectCodeNodes(props),
|
|
131
|
-
}),
|
|
132
|
-
)
|
|
133
|
-
return
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (type === KUBB_TYPE) {
|
|
137
|
-
nodes.push(
|
|
138
|
-
factory.createType({
|
|
139
|
-
name: props['name'] as string,
|
|
140
|
-
export: props['export'] as boolean | null | undefined,
|
|
141
|
-
JSDoc: props['JSDoc'] as JSDocNode | null | undefined,
|
|
142
|
-
nodes: collectCodeNodes(props),
|
|
143
|
-
}),
|
|
144
|
-
)
|
|
145
|
-
return
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
type FileChildren = { sources: Array<SourceNode>; exports: Array<ExportNode>; imports: Array<ImportNode> }
|
|
150
|
-
|
|
151
|
-
function collectFileChildren(element: unknown): FileChildren {
|
|
152
|
-
const sources: Array<SourceNode> = []
|
|
153
|
-
const exports: Array<ExportNode> = []
|
|
154
|
-
const imports: Array<ImportNode> = []
|
|
155
|
-
|
|
156
|
-
walkElement(
|
|
157
|
-
element,
|
|
158
|
-
(text) => {
|
|
159
|
-
if (text.trim()) {
|
|
160
|
-
throw new Error(`[react] '${text}' should be part of <File.Source> component when using the <File/> component`)
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
(type, props) => {
|
|
164
|
-
if (type === KUBB_SOURCE) {
|
|
165
|
-
sources.push(
|
|
166
|
-
factory.createSource({
|
|
167
|
-
name: props['name']?.toString(),
|
|
168
|
-
isTypeOnly: toBool(props['isTypeOnly']),
|
|
169
|
-
isExportable: toBool(props['isExportable']),
|
|
170
|
-
isIndexable: toBool(props['isIndexable']),
|
|
171
|
-
nodes: collectCodeNodes(props),
|
|
172
|
-
}),
|
|
173
|
-
)
|
|
174
|
-
return
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (type === KUBB_EXPORT) {
|
|
178
|
-
exports.push(
|
|
179
|
-
factory.createExport({
|
|
180
|
-
name: props['name'] as ExportNode['name'],
|
|
181
|
-
path: props['path'] as string,
|
|
182
|
-
isTypeOnly: toBool(props['isTypeOnly']),
|
|
183
|
-
asAlias: toBool(props['asAlias']),
|
|
184
|
-
}),
|
|
185
|
-
)
|
|
186
|
-
return
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (type === KUBB_IMPORT) {
|
|
190
|
-
imports.push(
|
|
191
|
-
factory.createImport({
|
|
192
|
-
name: props['name'] as ImportNode['name'],
|
|
193
|
-
path: props['path'] as string,
|
|
194
|
-
root: props['root'] as string | null | undefined,
|
|
195
|
-
isTypeOnly: toBool(props['isTypeOnly']),
|
|
196
|
-
isNameSpace: toBool(props['isNameSpace']),
|
|
197
|
-
}),
|
|
198
|
-
)
|
|
199
|
-
return
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const nested = collectFileChildren(props['children'])
|
|
203
|
-
sources.push(...nested.sources)
|
|
204
|
-
exports.push(...nested.exports)
|
|
205
|
-
imports.push(...nested.imports)
|
|
206
|
-
},
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
return { sources, exports, imports }
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function* walkFiles(element: unknown): Generator<FileNode> {
|
|
213
|
-
if (element == null || typeof element === 'boolean') return
|
|
214
|
-
|
|
215
|
-
if (typeof element === 'string' || typeof element === 'number' || typeof element === 'bigint') return
|
|
216
|
-
|
|
217
|
-
if (Array.isArray(element)) {
|
|
218
|
-
for (const child of element) yield* walkFiles(child)
|
|
219
|
-
return
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (typeof element === 'object' && '$$typeof' in element) {
|
|
223
|
-
const el = element as unknown as KubbReactElement
|
|
224
|
-
const { type } = el
|
|
225
|
-
const props = el.props as Record<string, unknown>
|
|
226
|
-
|
|
227
|
-
if (type === Fragment) {
|
|
228
|
-
yield* walkFiles(props['children'])
|
|
229
|
-
return
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (typeof type === 'function') {
|
|
233
|
-
yield* walkFiles((type as (p: unknown) => unknown)(props))
|
|
234
|
-
return
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (typeof type === 'string') {
|
|
238
|
-
if (type === KUBB_FILE && props['baseName'] !== undefined && props['path'] !== undefined) {
|
|
239
|
-
const { sources, exports, imports } = collectFileChildren(props['children'])
|
|
240
|
-
yield {
|
|
241
|
-
baseName: props['baseName'],
|
|
242
|
-
path: props['path'],
|
|
243
|
-
meta: props['meta'] || {},
|
|
244
|
-
footer: props['footer'],
|
|
245
|
-
banner: props['banner'],
|
|
246
|
-
sources,
|
|
247
|
-
exports,
|
|
248
|
-
imports,
|
|
249
|
-
} as FileNode
|
|
250
|
-
} else {
|
|
251
|
-
yield* walkFiles(props['children'])
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Synchronous JSX renderer that walks the element tree in a single pass,
|
|
259
|
-
* producing {@link FileNode} objects directly without an intermediate virtual
|
|
260
|
-
* DOM. No React fiber, scheduler, or work loop is involved.
|
|
261
|
-
*
|
|
262
|
-
* All components must be pure functions. Hooks and class components are not
|
|
263
|
-
* supported. Produces identical output to the React-backed {@link Runtime} at
|
|
264
|
-
* approximately 2, 4× the speed and a fraction of the allocations.
|
|
265
|
-
*/
|
|
266
|
-
export class SyncRuntime {
|
|
267
|
-
/**
|
|
268
|
-
* Accumulated {@link FileNode} results from every {@link render} call.
|
|
269
|
-
*/
|
|
270
|
-
nodes: Array<FileNode> = []
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Walks `element` synchronously, converts every `<kubb-file>` subtree into
|
|
274
|
-
* a {@link FileNode} with no intermediate virtual DOM, and appends the results
|
|
275
|
-
* to {@link nodes}.
|
|
276
|
-
*/
|
|
277
|
-
render(element: KubbReactElement): void {
|
|
278
|
-
for (const file of walkFiles(element)) {
|
|
279
|
-
this.nodes.push(file)
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Walks `element` synchronously and yields each {@link FileNode} as it is
|
|
285
|
-
* produced, without buffering into an intermediate array first. Callers can
|
|
286
|
-
* begin processing each file before the rest of the element tree is traversed.
|
|
287
|
-
*
|
|
288
|
-
* @example
|
|
289
|
-
* ```ts
|
|
290
|
-
* for (const file of runtime.stream(element)) {
|
|
291
|
-
* await writeFile(file)
|
|
292
|
-
* }
|
|
293
|
-
* ```
|
|
294
|
-
*/
|
|
295
|
-
*stream(element: KubbReactElement): Generator<FileNode> {
|
|
296
|
-
yield* walkFiles(element)
|
|
297
|
-
}
|
|
298
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { Key, KubbReactElement } from '../types.ts'
|
|
2
|
-
|
|
3
|
-
const CALLOUT_LABEL = {
|
|
4
|
-
tip: 'TIP',
|
|
5
|
-
note: 'NOTE',
|
|
6
|
-
important: 'IMPORTANT',
|
|
7
|
-
warning: 'WARNING',
|
|
8
|
-
caution: 'CAUTION',
|
|
9
|
-
} as const
|
|
10
|
-
|
|
11
|
-
export type CalloutType = keyof typeof CALLOUT_LABEL
|
|
12
|
-
|
|
13
|
-
type Props = {
|
|
14
|
-
key?: Key
|
|
15
|
-
/**
|
|
16
|
-
* Callout kind. Maps to the uppercase label inside the `> [!TYPE]` marker.
|
|
17
|
-
*/
|
|
18
|
-
type: CalloutType
|
|
19
|
-
/**
|
|
20
|
-
* Optional title rendered on the same line as the marker.
|
|
21
|
-
*/
|
|
22
|
-
title?: string | null
|
|
23
|
-
/**
|
|
24
|
-
* Body text. Each line is quoted with `> ` so multi-line content stays
|
|
25
|
-
* inside the callout block.
|
|
26
|
-
*/
|
|
27
|
-
children: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Renders a GitHub-style alert callout, portable across GitHub, GitLab,
|
|
32
|
-
* VitePress, Obsidian, and MDX.
|
|
33
|
-
*
|
|
34
|
-
* Emits a `<File.Source>` block containing `> [!TYPE] Title` followed by the
|
|
35
|
-
* body with every line prefixed by `> `.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```tsx
|
|
39
|
-
* <Callout type="tip">Run `kubb start --watch` to keep the generator hot.</Callout>
|
|
40
|
-
* // > [!TIP]
|
|
41
|
-
* // > Run `kubb start --watch` to keep the generator hot.
|
|
42
|
-
*
|
|
43
|
-
* <Callout type="warning" title="Heads up">Breaking change in v6.</Callout>
|
|
44
|
-
* // > [!WARNING] Heads up
|
|
45
|
-
* // > Breaking change in v6.
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
export function Callout({ type, title, children }: Props): KubbReactElement {
|
|
49
|
-
const label = CALLOUT_LABEL[type]
|
|
50
|
-
const header = title ? `> [!${label}] ${title}` : `> [!${label}]`
|
|
51
|
-
const quoted = children
|
|
52
|
-
.trimEnd()
|
|
53
|
-
.split('\n')
|
|
54
|
-
.map((line) => (line.length > 0 ? `> ${line}` : '>'))
|
|
55
|
-
.join('\n')
|
|
56
|
-
return <kubb-source name="callout">{`${header}\n${quoted}`}</kubb-source>
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
Callout.displayName = 'Callout'
|
package/src/components/Const.tsx
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { JSDoc, Key, KubbReactElement, KubbReactNode } from '../types.ts'
|
|
2
|
-
|
|
3
|
-
type ConstProps = {
|
|
4
|
-
key?: Key
|
|
5
|
-
/**
|
|
6
|
-
* Identifier of the generated constant declaration.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* `name: 'petSchema'`
|
|
10
|
-
*/
|
|
11
|
-
name: string
|
|
12
|
-
/**
|
|
13
|
-
* Emit the `export` keyword before the `const` declaration.
|
|
14
|
-
* - `true` generates `export const name = …`
|
|
15
|
-
* - `false` generates `const name = …`
|
|
16
|
-
* @default false
|
|
17
|
-
*/
|
|
18
|
-
export?: boolean | null
|
|
19
|
-
/**
|
|
20
|
-
* TypeScript type annotation for the constant, written verbatim after `const name:`.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* `type: 'Pet'` → `const pet: Pet = …`
|
|
24
|
-
*/
|
|
25
|
-
type?: string | null
|
|
26
|
-
/**
|
|
27
|
-
* JSDoc block to prepend to the constant declaration.
|
|
28
|
-
* Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
|
|
29
|
-
*/
|
|
30
|
-
JSDoc?: JSDoc | null
|
|
31
|
-
/**
|
|
32
|
-
* Append `as const` after the initialiser, enabling TypeScript const assertions.
|
|
33
|
-
* - `true` generates `const name = … as const`
|
|
34
|
-
* - `false` generates `const name = …`
|
|
35
|
-
* @default false
|
|
36
|
-
*/
|
|
37
|
-
asConst?: boolean | null
|
|
38
|
-
/**
|
|
39
|
-
* Child nodes rendered as the initialiser expression of the constant.
|
|
40
|
-
*/
|
|
41
|
-
children?: KubbReactNode
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Generates a TypeScript constant declaration.
|
|
46
|
-
*
|
|
47
|
-
* @example Named export with type annotation
|
|
48
|
-
* ```tsx
|
|
49
|
-
* <Const export name="petSchema" type="z.ZodType<Pet>">
|
|
50
|
-
* {`z.object({ id: z.number() })`}
|
|
51
|
-
* </Const>
|
|
52
|
-
* // export const petSchema: z.ZodType<Pet> = z.object({ id: z.number() })
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* @example With JSDoc and const assertion
|
|
56
|
-
* ```tsx
|
|
57
|
-
* <Const name="HTTP_METHODS" asConst JSDoc={{ comments: ['@description Supported HTTP methods.'] }}>
|
|
58
|
-
* {`['GET', 'POST', 'PUT', 'DELETE']`}
|
|
59
|
-
* </Const>
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
export function Const({ children, ...props }: ConstProps): KubbReactElement {
|
|
63
|
-
const { name, export: canExport, type, JSDoc, asConst } = props
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<kubb-const name={name} type={type} export={canExport} asConst={asConst} JSDoc={JSDoc}>
|
|
67
|
-
{children}
|
|
68
|
-
</kubb-const>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
Const.displayName = 'Const'
|
package/src/components/File.tsx
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import type { ExportNode, ImportNode, SourceNode } from '@kubb/ast'
|
|
2
|
-
import type { Key, KubbReactElement, KubbReactNode } from '../types.ts'
|
|
3
|
-
|
|
4
|
-
type BasePropsWithBaseName = {
|
|
5
|
-
/**
|
|
6
|
-
* Base file name including extension, derived from the input path.
|
|
7
|
-
* Based on UNIX basename convention: `${name}${extname}`.
|
|
8
|
-
*
|
|
9
|
-
* @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* `baseName: 'petStore.ts'`
|
|
13
|
-
*/
|
|
14
|
-
baseName: `${string}.${string}`
|
|
15
|
-
/**
|
|
16
|
-
* Fully qualified path to the generated file.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* `path: 'src/models/petStore.ts'`
|
|
20
|
-
*/
|
|
21
|
-
path: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
type BasePropsWithoutBaseName = {
|
|
25
|
-
baseName?: never
|
|
26
|
-
/**
|
|
27
|
-
* Fully qualified path to the generated file.
|
|
28
|
-
* Optional when `baseName` is omitted, the component renders its children inline.
|
|
29
|
-
*/
|
|
30
|
-
path?: string | null
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type BaseProps = BasePropsWithBaseName | BasePropsWithoutBaseName
|
|
34
|
-
|
|
35
|
-
type Props<TMeta> = BaseProps & {
|
|
36
|
-
key?: Key
|
|
37
|
-
/**
|
|
38
|
-
* Arbitrary metadata attached to the file node.
|
|
39
|
-
* Used by plugins for barrel generation and custom post-processing.
|
|
40
|
-
*/
|
|
41
|
-
meta?: TMeta | null
|
|
42
|
-
/**
|
|
43
|
-
* Text prepended to the generated file content before any source blocks.
|
|
44
|
-
* Accepts `null` so `resolver.resolveBanner()` results can be passed directly.
|
|
45
|
-
*/
|
|
46
|
-
banner?: string | null
|
|
47
|
-
/**
|
|
48
|
-
* Text appended to the generated file content after all source blocks.
|
|
49
|
-
* Accepts `null` so `resolver.resolveFooter()` results can be passed directly.
|
|
50
|
-
*/
|
|
51
|
-
footer?: string | null
|
|
52
|
-
/**
|
|
53
|
-
* Child nodes rendered as the content of this file (source blocks, imports, exports).
|
|
54
|
-
*/
|
|
55
|
-
children?: KubbReactNode
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Declares a generated file entry to be collected by the renderer.
|
|
60
|
-
*
|
|
61
|
-
* When both `baseName` and `path` are provided, the component registers a new
|
|
62
|
-
* `FileNode` and passes its children through as source blocks.
|
|
63
|
-
* When either is omitted the children are rendered inline without creating a file entry.
|
|
64
|
-
*
|
|
65
|
-
* @example Basic file with a source block
|
|
66
|
-
* ```tsx
|
|
67
|
-
* <File baseName="petStore.ts" path="src/models/petStore.ts">
|
|
68
|
-
* <File.Source name="Pet" isExportable isIndexable>
|
|
69
|
-
* {`export type Pet = { id: number; name: string }`}
|
|
70
|
-
* </File.Source>
|
|
71
|
-
* </File>
|
|
72
|
-
* ```
|
|
73
|
-
*/
|
|
74
|
-
export function File<TMeta extends object = object>({ children, ...props }: Props<TMeta>): KubbReactElement {
|
|
75
|
-
const { baseName, path } = props
|
|
76
|
-
|
|
77
|
-
if (!baseName || !path) {
|
|
78
|
-
return <>{children}</>
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return <kubb-file {...props}>{children}</kubb-file>
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
File.displayName = 'File'
|
|
85
|
-
|
|
86
|
-
type FileSourceProps = Omit<SourceNode, 'kind' | 'value'> & {
|
|
87
|
-
key?: Key
|
|
88
|
-
/**
|
|
89
|
-
* Child nodes rendered as the source content of this block.
|
|
90
|
-
*/
|
|
91
|
-
children?: KubbReactNode
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Marks a block of source text to be associated with the enclosing {@link File}.
|
|
96
|
-
*
|
|
97
|
-
* Children are treated as the source string. When `isExportable` is `true` the
|
|
98
|
-
* `name` is used for deduplication and barrel generation.
|
|
99
|
-
*
|
|
100
|
-
* @example Exportable, indexable source block
|
|
101
|
-
* ```tsx
|
|
102
|
-
* <File.Source name="Pet" isExportable isIndexable>
|
|
103
|
-
* {`export type Pet = { id: number; name: string }`}
|
|
104
|
-
* </File.Source>
|
|
105
|
-
* ```
|
|
106
|
-
*
|
|
107
|
-
* @example Type-only source block
|
|
108
|
-
* ```tsx
|
|
109
|
-
* <File.Source name="PetId" isTypeOnly isExportable>
|
|
110
|
-
* {`export type PetId = string`}
|
|
111
|
-
* </File.Source>
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
|
-
function FileSource({ children, ...props }: FileSourceProps): KubbReactElement {
|
|
115
|
-
const { name, isExportable, isIndexable, isTypeOnly } = props
|
|
116
|
-
|
|
117
|
-
return (
|
|
118
|
-
<kubb-source name={name} isTypeOnly={isTypeOnly} isExportable={isExportable} isIndexable={isIndexable}>
|
|
119
|
-
{children}
|
|
120
|
-
</kubb-source>
|
|
121
|
-
)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
FileSource.displayName = 'FileSource'
|
|
125
|
-
|
|
126
|
-
type FileExportProps = Omit<ExportNode, 'kind'> & { key?: Key }
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Declares an export entry for the enclosing {@link File}.
|
|
130
|
-
*
|
|
131
|
-
* The export is collected by the renderer and emitted at the top of the generated file.
|
|
132
|
-
*
|
|
133
|
-
* @example Named export
|
|
134
|
-
* ```tsx
|
|
135
|
-
* <File.Export name={['Pet']} path="./models/petStore" />
|
|
136
|
-
* // export { Pet } from './models/petStore'
|
|
137
|
-
* ```
|
|
138
|
-
*
|
|
139
|
-
* @example Type-only wildcard export
|
|
140
|
-
* ```tsx
|
|
141
|
-
* <File.Export path="./models/petStore" isTypeOnly />
|
|
142
|
-
* // export type * from './models/petStore'
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
function FileExport(props: FileExportProps): KubbReactElement {
|
|
146
|
-
const { name, path, isTypeOnly, asAlias } = props
|
|
147
|
-
|
|
148
|
-
return <kubb-export name={name} path={path} isTypeOnly={isTypeOnly} asAlias={asAlias} />
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
FileExport.displayName = 'FileExport'
|
|
152
|
-
|
|
153
|
-
type FileImportProps = Omit<ImportNode, 'kind'> & { key?: Key }
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Declares an import entry for the enclosing {@link File}.
|
|
157
|
-
*
|
|
158
|
-
* The import is collected by the renderer and emitted at the top of the generated file.
|
|
159
|
-
*
|
|
160
|
-
* @example Named import
|
|
161
|
-
* ```tsx
|
|
162
|
-
* <File.Import name={['useState']} path="react" />
|
|
163
|
-
* // import { useState } from 'react'
|
|
164
|
-
* ```
|
|
165
|
-
*
|
|
166
|
-
* @example Type-only import
|
|
167
|
-
* ```tsx
|
|
168
|
-
* <File.Import name={['Pet']} path="./models" isTypeOnly />
|
|
169
|
-
* // import type { Pet } from './models'
|
|
170
|
-
* ```
|
|
171
|
-
*
|
|
172
|
-
* @example Namespace import
|
|
173
|
-
* ```tsx
|
|
174
|
-
* <File.Import name="z" path="zod" isNameSpace />
|
|
175
|
-
* // import * as z from 'zod'
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
function FileImport(props: FileImportProps): KubbReactElement {
|
|
179
|
-
const { name, root, path, isTypeOnly, isNameSpace } = props
|
|
180
|
-
|
|
181
|
-
return <kubb-import name={name} root={root} path={path} isNameSpace={isNameSpace} isTypeOnly={isTypeOnly} />
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
FileImport.displayName = 'FileImport'
|
|
185
|
-
|
|
186
|
-
File.Export = FileExport
|
|
187
|
-
File.Import = FileImport
|
|
188
|
-
File.Source = FileSource
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { stringify } from 'yaml'
|
|
2
|
-
import type { Key, KubbReactElement } from '../types.ts'
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
key?: Key
|
|
6
|
-
/**
|
|
7
|
-
* Plain object serialized as YAML between `---` fences.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* `data: { title: 'Pets', layout: 'doc' }`
|
|
11
|
-
*/
|
|
12
|
-
data: Record<string, unknown>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Emits a YAML frontmatter envelope at the top of a generated markdown file.
|
|
17
|
-
*
|
|
18
|
-
* Renders a `<File.Source>` block containing `---\n<yaml>\n---`. Place it as
|
|
19
|
-
* the first child of `<File>` so it appears at the top of the output. Pair with
|
|
20
|
-
* `parserMd` to write `.md` files that downstream tooling (VitePress, MDX,
|
|
21
|
-
* static-site generators) treats as frontmatter.
|
|
22
|
-
*
|
|
23
|
-
* @example Page frontmatter at the top of a generated markdown file
|
|
24
|
-
* ```tsx
|
|
25
|
-
* <File baseName="pets.md" path="src/pets.md">
|
|
26
|
-
* <Frontmatter data={{ title: 'Pets', layout: 'doc' }} />
|
|
27
|
-
* <File.Source>
|
|
28
|
-
* {'# Pets\n\nList of pets.'}
|
|
29
|
-
* </File.Source>
|
|
30
|
-
* </File>
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export function Frontmatter({ data }: Props): KubbReactElement {
|
|
34
|
-
const envelope = `---\n${stringify(data).trimEnd()}\n---`
|
|
35
|
-
return <kubb-source name="frontmatter">{envelope}</kubb-source>
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
Frontmatter.displayName = 'Frontmatter'
|