@kubb/react-fabric 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,6 +21,282 @@
21
21
  </div>
22
22
  <br />
23
23
 
24
+ Kubb Fabric is a language-agnostic toolkit for generating code and files using JSX and TypeScript.
25
+ It offers a lightweight layer for file generation while orchestrating the overall process of creating and managing files.
26
+
27
+ > [!WARNING]
28
+ > Fabric is under active development. Until a stable 1.0 release, minor versions may occasionally include breaking changes. Please check release notes and PR titles for breaking changes.
29
+
30
+ # Features
31
+
32
+ - 🎨 Declarative file generation — Create files effortlessly using JSX or JavaScript syntax.
33
+ - 📦 Cross-runtime support — Works seamlessly with Node.js and Bun.
34
+ - 🧩 Built-in debugging utilities — Simplify development and inspect generation flows with ease.
35
+ - ⚡ Fast and lightweight — Minimal overhead, maximum performance.
36
+
37
+ ## Write a TypeScript file
38
+
39
+ Below is a minimal example showing how `createApp` works together with plugins and parsers via `app.use`.
40
+
41
+ ```ts
42
+ import { createApp } from '@kubb/fabric-core'
43
+ import { fsPlugin } from '@kubb/fabric-core/plugins'
44
+ import { typescriptParser, createParser } from '@kubb/fabric-core/parsers'
45
+
46
+ const app = createApp()
47
+
48
+ app.use(fsPlugin, {
49
+ dryRun: false,
50
+ onBeforeWrite: (path, data) => {
51
+ console.log('About to write:', path)
52
+ },
53
+ clean: { path: './generated' },
54
+ })
55
+
56
+ app.use(typescriptParser)
57
+
58
+ await app.addFile({
59
+ baseName: 'index.ts',
60
+ path: './generated/index.ts',
61
+ sources: [
62
+ { value: 'export const x = 1', isExportable: true },
63
+ ],
64
+ })
65
+
66
+ await app.write()
67
+
68
+ ```
69
+
70
+ # API Reference
71
+
72
+ ## Core
73
+ ### `createApp(options?): App`
74
+ Returns an app instance with:
75
+ - `app.use(pluginOrParser, ...options) => App` — register plugins and parsers.
76
+ - `app.addFile(...files)` — queue in-memory files to generate.
77
+ - `app.files` — getter with all queued files.
78
+ - `app.context` — internal context holding events, options, FileManager, installed plugins/parsers.
79
+
80
+ ### `defineApp(instance?): () => App`
81
+ Factory to create your own `createApp` with an optional bootstrap `instance(app)` called on creation.
82
+
83
+ ### App events (emitted by the core during processing)
84
+ - `start`
85
+ - `end`
86
+ - `render { app }`
87
+ - `file:add { files }`
88
+ - `write:start { files }`
89
+ - `write:end { files }`
90
+ - `file:start { file, index, total }`
91
+ - `file:end { file, index, total }`
92
+ - `process:start { files }`
93
+ - `process:progress { file, source, processed, percentage, total }`
94
+ - `process:end { files }`
95
+
96
+
97
+ ## Plugins
98
+ #### `fsPlugin`
99
+ Writes files to disk on `process:progress`, supports dry runs and cleaning an output folder before writing.
100
+
101
+ ```
102
+ import { fsPlugin } from '@kubb/fabric-core/plugins'
103
+ ```
104
+
105
+ | Option | Type | Default | Description |
106
+ |---|----------------------------------------------------------------------|---|-----------------------------------------------------------------------|
107
+ | dryRun | `boolean` | `false` | If true, do not write files to disk. |
108
+ | onBeforeWrite | `(path: string, data: string \| undefined) => void \| Promise<void>` | — | Called right before each file write on `process:progress`. |
109
+ | clean | `{ path: string }` | — | If provided, removes the directory at `path` before writing any files. |
110
+
111
+ Injected `app.write` options (via `fsPlugin`):
112
+
113
+ | Option | Type | Default | Description |
114
+ |---|----------------------------------|---|---|
115
+ | extension | `Record<Extname, Extname \| ''>` | — | Maps input file extensions to output extensions. When set, the matching parser (by extNames) is used. |
116
+
117
+ #### `barrelPlugin`
118
+ Generates `index.ts` barrel files per folder at `process:end`. `writeEntry` creates a single entry barrel at `root`.
119
+
120
+ ```
121
+ import { barrelPlugin } from '@kubb/fabric-core/plugins'
122
+ ```
123
+
124
+ | Option | Type | Default | Description |
125
+ |---|--------------------------------------------|---|---|
126
+ | root | `string` | — | Root directory to generate barrel files for. |
127
+ | mode | `'all' \| 'named' \| 'propagate' \| false` | — | Controls how exports are generated: all exports, only named exports, propagate (skip barrels), or disabled. |
128
+ | dryRun | `boolean` | `false` | If true, computes barrels but skips writing. |
129
+
130
+ Injected `app.writeEntry` parameters (via `barrelPlugin`):
131
+
132
+ | Param | Type | Description |
133
+ |---|--------------------------------------------|---|
134
+ | root | `string` | Root directory where the entry `index.ts` should be created. |
135
+ | mode | `'all' \| 'named' \| 'propagate' \| false` | Controls which export style to use for the entry barrel. |
136
+
137
+ #### `progressPlugin`
138
+ Shows a CLI progress bar by listening to core events.
139
+
140
+ ```
141
+ import { progressPlugin } from '@kubb/fabric-core/plugins'
142
+ ```
143
+
144
+ | Option | Type | Default | Description |
145
+ |---|---|---|-----------------------------------------------------------------------------------------|
146
+ | — | — | — | This plugin has no options, it displays a CLI progress bar by listening to core events. |
147
+
148
+
149
+ #### `graphPlugin`
150
+ Shows a graph of all files
151
+
152
+ ```
153
+ import { graphPlugin } from '@kubb/fabric-core/plugins'
154
+ ```
155
+
156
+ | Option | Type | Default | Description |
157
+ |--------|-----------|---------|-----------------------------------------------|
158
+ | root | `string` | | Root directory where to start searching from. |
159
+ | open | `boolean` | false | Open a webpage with the generated graph |
160
+
161
+
162
+ #### `reactPlugin`
163
+ Enables rendering React components to the terminal or to a string. Useful for CLI UIs and templating.
164
+
165
+ ```
166
+ import { reactPlugin } from '@kubb/react-fabric/plugins'
167
+ ```
168
+
169
+ | Option | Type | Default | Description |
170
+ |---|---|---|---|
171
+ | stdout | `NodeJS.WriteStream` | — | Optional output stream used to print the rendered content while the app is running. If set, the output is written progressively. |
172
+ | stdin | `NodeJS.ReadStream` | — | Optional input stream for interactive components. |
173
+ | stderr | `NodeJS.WriteStream` | — | Optional error output stream. |
174
+ | debug | `boolean` | — | When true, logs render/unmount information to the console to aid debugging. |
175
+
176
+ Injected methods (via `reactPlugin`):
177
+
178
+ | Method | Signature | Description |
179
+ |---|---|----------------------------------------------------------------------------------------------------|
180
+ | `render` | `(App: React.ElementType) => Promise<void> \| void` | Render a React component tree to the terminal and emit the core `start` event. |
181
+ | `renderToString` | `(App: React.ElementType) => Promise<string> \| string` | Render a React component tree and return the final output as a string (without writing to stdout). |
182
+ | `waitUntilExit` | `() => Promise<void>` | Wait until the rendered app exits, resolves when unmounted and emits the core `end` event. |
183
+
184
+ #### `createPlugin`
185
+
186
+ Factory to declare a plugin that can be registered via `app.use`.
187
+
188
+ | Field | Required | Description |
189
+ |---|---|---------------------------------------------------------------------------------------------------------------------------|
190
+ | `name` | Yes | String identifier of your plugin. |
191
+ | `install(app, options)` | Yes | Called when the plugin is registered. You can subscribe to core events and perform side effects here. |
192
+ | `inject?(app, options)` | No | Return synchronously the runtime methods/properties to merge into `app` (e.g. `write`, `render`). This must not be async. |
193
+
194
+ Example:
195
+
196
+ ```ts
197
+ import { createApp } from '@kubb/fabric-core'
198
+ import { createPlugin } from '@kubb/fabric-core/plugins'
199
+
200
+ const helloPlugin = createPlugin<{ name?: string }, { sayHello: (msg?: string) => void }>({
201
+ name: 'helloPlugin',
202
+ install(app, options) {
203
+ app.context.events.on('start', () => {
204
+ console.log('App started')
205
+ })
206
+ },
207
+ inject(app, options) {
208
+ return {
209
+ sayHello(msg = options?.name ?? 'world') {
210
+ console.log(`Hello ${msg}!`)
211
+ },
212
+ }
213
+ },
214
+ })
215
+
216
+ const app = createApp()
217
+ await app.use(helloPlugin, { name: 'Fabric' })
218
+ app.sayHello() // -> Hello Fabric!
219
+ ```
220
+
221
+ ## Parsers
222
+ #### `typescriptParser`
223
+
224
+ Prints TS/JS imports/exports and sources, supports extname mapping for generated import/export paths.
225
+
226
+ ```
227
+ import { typescriptParser } from '@kubb/fabric-core/parsers'
228
+ ```
229
+
230
+ | Option | Type | Default | Description |
231
+ |---|---|---|---------------------------------------------------------------------------------------------|
232
+ | file | `KubbFile.File` | -| File that will be used to be parsed. |
233
+ | extname | `string` | `'.ts'` | Extension to use when emitting import/export paths (e.g., rewrite `./file` to `./file.ts`). |
234
+
235
+ #### `tsxParser`
236
+
237
+ Delegates to `typescriptParser` with TSX printing settings.
238
+
239
+ ```
240
+ import { tsxParser } from '@kubb/fabric-core/parsers'
241
+ ```
242
+
243
+ | Option | Type | Default | Description |
244
+ |---|---|---|---|
245
+ | file | `KubbFile.File` | -| File that will be used to be parsed. |
246
+ | extname | `string` | `'.tsx'` | Extension to use when emitting import/export paths for TSX/JSX files. |
247
+
248
+ #### `defaultParser`
249
+
250
+ Fallback parser used when no extension mapping is provided to `app.write`.
251
+
252
+ ```
253
+ import { defaultParser } @kubb/fabric-core/parsers`
254
+ ```
255
+
256
+ | Option | Type | Default | Description |
257
+ |---|---|---|--------------------------------------------------------------------------|
258
+ | file | `KubbFile.File` | -| File that will be used to be parsed. |
259
+
260
+ #### `createParser`
261
+ Factory to declare a parser that can be registered via `app.use` and selected by `extNames` during `app.write`.
262
+
263
+ | Field | Required | Description |
264
+ |---|---|-----------------------------------------------------------------------------------------------------------------|
265
+ | `name` | Yes | String identifier of your parser. |
266
+ | `extNames` | Yes | List of file extensions this parser can handle (e.g. ['.ts']). Use `undefined` for the default parser fallback. |
267
+ | `install(app, options)` | No | Optional setup when the parser is registered (subscribe to events, set state, etc.). |
268
+ | `parse(file, { extname })` | Yes | Must return the final string that will be written for the given file. |
269
+
270
+ Example:
271
+
272
+ ```ts
273
+ import { createApp } from '@kubb/fabric-core'
274
+ import { createParser } from '@kubb/fabric-core/parsers'
275
+
276
+ const vueParser = createParser<{ banner?: string }>({
277
+ name: 'vueParser',
278
+ extNames: ['.vue'],
279
+ async install(app, options) {
280
+ // Optional setup
281
+ },
282
+ async parse(file, { extname }) {
283
+ const banner = file.options?.banner ?? ''
284
+ const sources = file.sources.map(s => s.value).join('\n')
285
+ return `${banner}\n${sources}`
286
+ },
287
+ })
288
+
289
+ const app = createApp()
290
+ app.use(vueParser)
291
+ app.use(fsPlugin); // make it possible to write to the filesystem
292
+
293
+ app.write({ extension: { '.vue': '.ts' } })
294
+ ```
295
+
296
+ > [!NOTE]
297
+ > - `app.use` accepts both plugins and parsers. The `fsPlugin` handles I/O and adds `app.write`. Parsers decide how files are converted to strings for specific extensions.
298
+ > - When extension mapping is provided to `app.write`, Fabric picks a parser whose `extNames` include the file’s extension. Otherwise, the default parser is used.
299
+
24
300
  ## Supporting Kubb
25
301
 
26
302
  Kubb uses an MIT-licensed open source project with its ongoing development made possible entirely by the support of Sponsors. If you would like to become a sponsor, please consider:
@@ -15393,11 +15393,11 @@ var Runtime = class {
15393
15393
  const originalError = console.error;
15394
15394
  console.error = (data) => {
15395
15395
  const message = typeof data === "string" ? data : data === null || data === void 0 ? void 0 : data.message;
15396
- if (message.match(/Encountered two children with the same key/gi)) return;
15397
- if (message.match(/React will try to recreat/gi)) return;
15398
- if (message.match(/Each child in a list should have a unique/gi)) return;
15399
- if (message.match(/The above error occurred in the <KubbErrorBoundary/gi)) return;
15400
- if (message.match(/A React Element from an older version of React was render/gi)) return;
15396
+ if (message === null || message === void 0 ? void 0 : message.match(/Encountered two children with the same key/gi)) return;
15397
+ if (message === null || message === void 0 ? void 0 : message.match(/React will try to recreat/gi)) return;
15398
+ if (message === null || message === void 0 ? void 0 : message.match(/Each child in a list should have a unique/gi)) return;
15399
+ if (message === null || message === void 0 ? void 0 : message.match(/The above error occurred in the <KubbErrorBoundary/gi)) return;
15400
+ if (message === null || message === void 0 ? void 0 : message.match(/A React Element from an older version of React was render/gi)) return;
15401
15401
  originalError(data);
15402
15402
  };
15403
15403
  const logRecoverableError = typeof reportError === "function" ? reportError : console.error;
@@ -15479,4 +15479,4 @@ async function _getOutput(node) {
15479
15479
 
15480
15480
  //#endregion
15481
15481
  export { Root as a, _classPrivateFieldInitSpec as i, _classPrivateFieldGet2 as n, RootContext as o, _classPrivateFieldSet2 as r, Runtime as t };
15482
- //# sourceMappingURL=Runtime-DWlDUeLZ.js.map
15482
+ //# sourceMappingURL=Runtime-CatKeybQ.js.map