@kubb/core 5.0.0-beta.57 → 5.0.0-beta.59
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/{diagnostics-Bf2bC8lV.d.ts → diagnostics-B-UZnFqP.d.ts} +54 -68
- package/dist/index.cjs +34 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +34 -28
- package/dist/index.js.map +1 -1
- package/dist/{memoryStorage-skOz0dXZ.cjs → memoryStorage-CUj1hrxa.cjs} +9 -7
- package/dist/memoryStorage-CUj1hrxa.cjs.map +1 -0
- package/dist/{memoryStorage-B0W-w994.js → memoryStorage-CWFzAz4o.js} +7 -6
- package/dist/memoryStorage-CWFzAz4o.js.map +1 -0
- package/dist/mocks.cjs +1 -2
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.ts +1 -2
- package/dist/mocks.js +1 -2
- package/dist/mocks.js.map +1 -1
- package/package.json +4 -4
- package/src/FileManager.ts +2 -2
- package/src/FileProcessor.ts +1 -1
- package/src/KubbDriver.ts +13 -6
- package/src/createAdapter.ts +5 -6
- package/src/createRenderer.ts +3 -4
- package/src/createReporter.ts +1 -1
- package/src/createStorage.ts +4 -4
- package/src/defineGenerator.ts +2 -2
- package/src/defineParser.ts +3 -2
- package/src/definePlugin.ts +13 -18
- package/src/defineResolver.ts +7 -6
- package/src/diagnostics.ts +8 -11
- package/src/index.ts +1 -0
- package/src/mocks.ts +0 -1
- package/src/reporters/cliReporter.ts +1 -1
- package/src/types.ts +9 -15
- package/dist/memoryStorage-B0W-w994.js.map +0 -1
- package/dist/memoryStorage-skOz0dXZ.cjs.map +0 -1
package/src/createStorage.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Backend that persists generated files. Kubb ships with `fsStorage` (writes
|
|
3
3
|
* to disk) and `memoryStorage` (keeps everything in RAM). Implement this
|
|
4
|
-
* interface to write
|
|
4
|
+
* interface to write somewhere else, such as S3 or a database.
|
|
5
5
|
*/
|
|
6
6
|
export type Storage = {
|
|
7
7
|
/**
|
|
@@ -42,9 +42,9 @@ export type Storage = {
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Defines a custom storage backend. The builder receives user options and
|
|
45
|
-
* returns a `Storage` implementation. Kubb ships with filesystem and
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* returns a `Storage` implementation. Kubb ships with filesystem and in-memory
|
|
46
|
+
* storages. A custom backend writes generated files elsewhere, such as cloud
|
|
47
|
+
* storage or a database.
|
|
48
48
|
*
|
|
49
49
|
* @example In-memory storage (the built-in implementation)
|
|
50
50
|
* ```ts
|
package/src/defineGenerator.ts
CHANGED
|
@@ -117,8 +117,8 @@ export type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFacto
|
|
|
117
117
|
* Declares a named generator unit that walks the AST and emits files.
|
|
118
118
|
*
|
|
119
119
|
* Each method (`schema`, `operation`, `operations`) is called for the matching node type.
|
|
120
|
-
*
|
|
121
|
-
*
|
|
120
|
+
* JSX-based generators require a `renderer` factory. Return `Array<FileNode>` directly, or call
|
|
121
|
+
* `ctx.upsertFile()` manually and return `null` to bypass rendering.
|
|
122
122
|
*
|
|
123
123
|
* @note Generators are consumed by plugins and registered via `ctx.addGenerator()` in `kubb:plugin:setup`.
|
|
124
124
|
*
|
package/src/defineParser.ts
CHANGED
|
@@ -40,14 +40,15 @@ export type Parser<TMeta extends object = object, TNode = unknown> = {
|
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```ts
|
|
43
|
-
* import { defineParser
|
|
43
|
+
* import { defineParser } from '@kubb/core'
|
|
44
|
+
* import { extractStringsFromNodes } from '@kubb/ast/utils'
|
|
44
45
|
*
|
|
45
46
|
* export const jsonParser = defineParser({
|
|
46
47
|
* name: 'json',
|
|
47
48
|
* extNames: ['.json'],
|
|
48
49
|
* parse(file) {
|
|
49
50
|
* return file.sources
|
|
50
|
-
* .map((source) =>
|
|
51
|
+
* .map((source) => extractStringsFromNodes(source.nodes ?? []))
|
|
51
52
|
* .join('\n')
|
|
52
53
|
* },
|
|
53
54
|
* print(...nodes) {
|
package/src/definePlugin.ts
CHANGED
|
@@ -6,9 +6,9 @@ import { Diagnostics } from './diagnostics.ts'
|
|
|
6
6
|
import type { Config, KubbHooks } from './types.ts'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Reads a type from a registry, falling back to `{}` when the key is absent. Lets
|
|
10
|
+
* `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry` be augmented without
|
|
11
|
+
* touching core.
|
|
12
12
|
*
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
@@ -92,7 +92,7 @@ export type Group = {
|
|
|
92
92
|
* files into per-group subdirectories.
|
|
93
93
|
*
|
|
94
94
|
* Intersect into a plugin's `Options` type instead of declaring `output` and
|
|
95
|
-
* `group` directly
|
|
95
|
+
* `group` directly, since `mode` lives inside `output` while `group` is its sibling.
|
|
96
96
|
* The generic keeps a plugin's extended `Output` shape intact.
|
|
97
97
|
*
|
|
98
98
|
* @example
|
|
@@ -201,9 +201,8 @@ type ByContentType = {
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
/**
|
|
204
|
-
* Filter that skips matching operations or schemas during generation
|
|
205
|
-
*
|
|
206
|
-
* not want code generated for.
|
|
204
|
+
* Filter that skips matching operations or schemas during generation, for example
|
|
205
|
+
* deprecated endpoints or internal-only schemas.
|
|
207
206
|
*
|
|
208
207
|
* @example
|
|
209
208
|
* ```ts
|
|
@@ -283,8 +282,8 @@ export type PluginFactoryOptions<
|
|
|
283
282
|
}
|
|
284
283
|
|
|
285
284
|
/**
|
|
286
|
-
* Context
|
|
287
|
-
*
|
|
285
|
+
* Context passed to a plugin's `kubb:plugin:setup` handler, where it registers generators and
|
|
286
|
+
* sets its resolver, transformer, and options.
|
|
288
287
|
*/
|
|
289
288
|
export type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
290
289
|
/**
|
|
@@ -325,11 +324,8 @@ export type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = Plugi
|
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
/**
|
|
328
|
-
* A plugin object produced by `definePlugin`.
|
|
329
|
-
*
|
|
330
|
-
* (matching Astro's integration naming convention).
|
|
331
|
-
*
|
|
332
|
-
* @template TFactory - The plugin's `PluginFactoryOptions` type.
|
|
327
|
+
* A plugin object produced by `definePlugin`. Its lifecycle handlers live under a single
|
|
328
|
+
* `hooks` property rather than flat methods.
|
|
333
329
|
*/
|
|
334
330
|
export type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
335
331
|
/**
|
|
@@ -367,8 +363,8 @@ export type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions>
|
|
|
367
363
|
}
|
|
368
364
|
|
|
369
365
|
/**
|
|
370
|
-
* Normalized plugin after setup, with runtime fields populated.
|
|
371
|
-
*
|
|
366
|
+
* Normalized plugin after setup, with runtime fields populated. Internal only. Plugins use the
|
|
367
|
+
* public `Plugin` type.
|
|
372
368
|
*
|
|
373
369
|
* @internal
|
|
374
370
|
*/
|
|
@@ -409,8 +405,7 @@ export type KubbPluginEndContext = {
|
|
|
409
405
|
|
|
410
406
|
/**
|
|
411
407
|
* Wraps a plugin factory and returns a function that accepts user options and
|
|
412
|
-
* yields a
|
|
413
|
-
* `hooks` object (inspired by Astro integrations).
|
|
408
|
+
* yields a typed `Plugin`. Lifecycle handlers go inside a single `hooks` object.
|
|
414
409
|
*
|
|
415
410
|
* Pass a `PluginFactoryOptions` type parameter to get a typed `ctx` inside
|
|
416
411
|
* `kubb:plugin:setup`. Plugin names should follow the `plugin-<feature>`
|
package/src/defineResolver.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
import { camelCase, pascalCase, toFilePath } from '@internals/utils'
|
|
3
3
|
import type { FileNode, InputMeta, Node, OperationNode, SchemaNode } from '@kubb/ast'
|
|
4
|
-
import {
|
|
4
|
+
import { operationDef, schemaDef } from '@kubb/ast'
|
|
5
|
+
import * as factory from '@kubb/ast/factory'
|
|
5
6
|
import { Diagnostics } from './diagnostics.ts'
|
|
6
7
|
import type { PluginFactoryOptions } from './definePlugin.ts'
|
|
7
8
|
import type { Config, Group, Output } from './types.ts'
|
|
@@ -376,8 +377,8 @@ function defaultResolveOptions<TOptions>(node: Node, { options, exclude = [], in
|
|
|
376
377
|
/**
|
|
377
378
|
* Default path resolver used by `defineResolver`.
|
|
378
379
|
*
|
|
379
|
-
* - `mode: 'file'`
|
|
380
|
-
* - `mode: 'directory'` (default)
|
|
380
|
+
* - `mode: 'file'` resolves directly to `output.path` (the full file path, extension included).
|
|
381
|
+
* - `mode: 'directory'` (default) resolves to `output.path/{baseName}`, or into a
|
|
381
382
|
* subdirectory when `group` and a `tag`/`path` value are provided.
|
|
382
383
|
*
|
|
383
384
|
* A custom `group.name` function overrides the default subdirectory naming.
|
|
@@ -499,7 +500,7 @@ export function defaultResolveFile(this: Resolver, { name, extname, tag, path: g
|
|
|
499
500
|
const baseName = `${resolvedName}${extname}` as FileNode['baseName']
|
|
500
501
|
const filePath = this.resolvePath({ baseName, tag, path: groupPath }, context)
|
|
501
502
|
|
|
502
|
-
return createFile({
|
|
503
|
+
return factory.createFile({
|
|
503
504
|
path: filePath,
|
|
504
505
|
baseName: path.basename(filePath) as `${string}.${string}`,
|
|
505
506
|
meta: {
|
|
@@ -661,8 +662,8 @@ export function defaultResolveFooter(meta: InputMeta | undefined, { output, file
|
|
|
661
662
|
* - `resolveFile` builds the full `FileNode`.
|
|
662
663
|
* - `resolveBanner` and `resolveFooter` produce the top and bottom of file text.
|
|
663
664
|
*
|
|
664
|
-
* Methods in the returned object can call sibling resolver methods via `this
|
|
665
|
-
*
|
|
665
|
+
* Methods in the returned object can call sibling resolver methods via `this`.
|
|
666
|
+
* A custom rule can delegate to a default, for example `this.default(name, 'type')`.
|
|
666
667
|
*
|
|
667
668
|
* @example Basic resolver with naming helpers
|
|
668
669
|
* ```ts
|
package/src/diagnostics.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { type DiagnosticCode, diagnosticCode } from './constants.ts'
|
|
|
7
7
|
import type { KubbHooks } from './types.ts'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Docs major, derived from the package version so the link tracks the published major.
|
|
10
|
+
* Docs major version, derived from the package version so the link tracks the published major.
|
|
11
11
|
*/
|
|
12
12
|
const docsMajor = version.split('.')[0] ?? '5'
|
|
13
13
|
|
|
@@ -19,9 +19,8 @@ export type DiagnosticSeverity = 'error' | 'warning' | 'info'
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* A human-readable explanation of a diagnostic code: a short title, what triggers it, and how
|
|
22
|
-
* to resolve it. This is the
|
|
23
|
-
*
|
|
24
|
-
* {@link DiagnosticCode}, so adding a code without documenting it fails the build.
|
|
22
|
+
* to resolve it. This is the source of truth the kubb.dev `/diagnostics/<slug>` pages mirror, so
|
|
23
|
+
* every code stays documented in one place. Adding a code without documenting it fails the build.
|
|
25
24
|
*/
|
|
26
25
|
export type DiagnosticDoc = {
|
|
27
26
|
/**
|
|
@@ -83,9 +82,7 @@ export type ProblemCode = Exclude<DiagnosticCode, typeof diagnosticCode.performa
|
|
|
83
82
|
|
|
84
83
|
/**
|
|
85
84
|
* A build problem collected during a run, gathered into the result instead of
|
|
86
|
-
* aborting on the first failure.
|
|
87
|
-
* `severity`, a `message`, and optionally a `location` into the source document,
|
|
88
|
-
* a `help`, the `plugin` that produced it, and the `cause` it wraps.
|
|
85
|
+
* aborting on the first failure.
|
|
89
86
|
*/
|
|
90
87
|
export type ProblemDiagnostic = {
|
|
91
88
|
/**
|
|
@@ -114,9 +111,9 @@ export type ProblemDiagnostic = {
|
|
|
114
111
|
}
|
|
115
112
|
|
|
116
113
|
/**
|
|
117
|
-
* A per-plugin performance record, built with {@link Diagnostics.performance}.
|
|
118
|
-
*
|
|
119
|
-
*
|
|
114
|
+
* A per-plugin performance record, built with {@link Diagnostics.performance}. The `performance`
|
|
115
|
+
* kind keeps it out of the problem list. It feeds the per-plugin timing bars, and reporters sum
|
|
116
|
+
* these into the run total.
|
|
120
117
|
*/
|
|
121
118
|
export type PerformanceDiagnostic = {
|
|
122
119
|
kind: 'performance'
|
|
@@ -135,7 +132,7 @@ export type PerformanceDiagnostic = {
|
|
|
135
132
|
|
|
136
133
|
/**
|
|
137
134
|
* A notice that a newer Kubb version is available on npm, built with {@link Diagnostics.update}.
|
|
138
|
-
* It
|
|
135
|
+
* It renders like any info diagnostic.
|
|
139
136
|
*/
|
|
140
137
|
export type UpdateDiagnostic = {
|
|
141
138
|
kind: 'update'
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { AsyncEventEmitter, Url } from '@internals/utils'
|
|
2
|
+
// `@kubb/ast` re-exported as the `ast` namespace. Node constructors are reached as `ast.factory.createX`.
|
|
2
3
|
export * as ast from '@kubb/ast'
|
|
3
4
|
export { createAdapter } from './createAdapter.ts'
|
|
4
5
|
export { Diagnostics } from './diagnostics.ts'
|
package/src/mocks.ts
CHANGED
|
@@ -11,7 +11,6 @@ import { memoryStorage } from './storages/memoryStorage.ts'
|
|
|
11
11
|
import type { Adapter, AdapterFactoryOptions, Config, Generator, GeneratorContext, NormalizedPlugin, PluginFactoryOptions, RendererFactory } from './types.ts'
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
|
|
15
14
|
* Creates a minimal `PluginDriver` mock for unit tests.
|
|
16
15
|
*/
|
|
17
16
|
export function createMockedPluginDriver(options: { name?: string; plugin?: NormalizedPlugin; config?: Config } = {}): KubbDriver {
|
|
@@ -73,7 +73,7 @@ function renderSummary(lines: ReadonlyArray<string>, { title, status }: { title:
|
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* The default `cli` reporter. Renders the {@link Report} for each config as it finishes, independent
|
|
76
|
-
* of the live logger view. Suppressed at `silent
|
|
76
|
+
* of the live logger view. Suppressed at `silent`. The `verbose` level adds the per-plugin timings.
|
|
77
77
|
*/
|
|
78
78
|
export const cliReporter = createReporter({
|
|
79
79
|
name: 'cli',
|
package/src/types.ts
CHANGED
|
@@ -10,9 +10,9 @@ import type { KubbPluginEndContext, KubbPluginSetupContext, KubbPluginStartConte
|
|
|
10
10
|
import type { KubbDriver } from './KubbDriver.ts'
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* without
|
|
13
|
+
* Extracts a type from a registry, falling back to `{}` when the key doesn't exist.
|
|
14
|
+
* Lets plugins augment `Kubb.ConfigOptionsRegistry` and `Kubb.PluginOptionsRegistry`
|
|
15
|
+
* without changing core.
|
|
16
16
|
*
|
|
17
17
|
* @internal
|
|
18
18
|
*/
|
|
@@ -137,7 +137,6 @@ export type Config<TInput = Input> = {
|
|
|
137
137
|
* Remove every file in the output directory before the build, so stale output isn't mixed
|
|
138
138
|
* with new files. Leave `false` to preserve manual edits in the output directory.
|
|
139
139
|
*
|
|
140
|
-
* @default false
|
|
141
140
|
* @example
|
|
142
141
|
* ```ts
|
|
143
142
|
* clean: true // wipes ./src/gen/* before generating
|
|
@@ -148,7 +147,6 @@ export type Config<TInput = Input> = {
|
|
|
148
147
|
* Format the generated files after generation. `'auto'` runs the first formatter it finds
|
|
149
148
|
* (oxfmt, biome, or prettier), a named tool forces that one, and `false` skips formatting.
|
|
150
149
|
*
|
|
151
|
-
* @default false
|
|
152
150
|
* @example
|
|
153
151
|
* ```ts
|
|
154
152
|
* format: 'auto' // auto-detect prettier, biome, or oxfmt
|
|
@@ -161,7 +159,6 @@ export type Config<TInput = Input> = {
|
|
|
161
159
|
* Lint the generated files after generation. `'auto'` runs the first linter it finds
|
|
162
160
|
* (oxlint, biome, or eslint), a named tool forces that one, and `false` skips linting.
|
|
163
161
|
*
|
|
164
|
-
* @default false
|
|
165
162
|
* @example
|
|
166
163
|
* ```ts
|
|
167
164
|
* lint: 'auto' // auto-detect oxlint, biome, or eslint
|
|
@@ -199,7 +196,6 @@ export type Config<TInput = Input> = {
|
|
|
199
196
|
* Overwrite existing files when `true`, skip files that already exist when `false`. Individual
|
|
200
197
|
* plugins can override it. Keep `false` to avoid clobbering local edits in the output folder.
|
|
201
198
|
*
|
|
202
|
-
* @default false
|
|
203
199
|
* @example
|
|
204
200
|
* ```ts
|
|
205
201
|
* override: true // regenerate everything, even existing files
|
|
@@ -245,10 +241,9 @@ export type Config<TInput = Input> = {
|
|
|
245
241
|
*/
|
|
246
242
|
plugins: Array<Plugin>
|
|
247
243
|
/**
|
|
248
|
-
* Lifecycle hooks that
|
|
244
|
+
* Lifecycle hooks that run external tools (prettier, eslint, a custom script) on build events.
|
|
249
245
|
*
|
|
250
|
-
*
|
|
251
|
-
* Currently supports the `done` hook which fires after all plugins complete.
|
|
246
|
+
* Currently supports the `done` hook, which fires after all plugins complete.
|
|
252
247
|
*
|
|
253
248
|
* @example
|
|
254
249
|
* ```ts
|
|
@@ -261,11 +256,10 @@ export type Config<TInput = Input> = {
|
|
|
261
256
|
*/
|
|
262
257
|
hooks?: {
|
|
263
258
|
/**
|
|
264
|
-
* Command(s) to run after all plugins
|
|
259
|
+
* Command(s) to run after all plugins finish generating, for post-processing the output.
|
|
265
260
|
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* Commands are executed relative to the `root` directory.
|
|
261
|
+
* Pass a single command string, or an array to run them in sequence.
|
|
262
|
+
* Commands run relative to the `root` directory.
|
|
269
263
|
*
|
|
270
264
|
* @example
|
|
271
265
|
* ```ts
|
|
@@ -762,7 +756,7 @@ export type CLIOptions = {
|
|
|
762
756
|
|
|
763
757
|
/**
|
|
764
758
|
* All accepted forms of a Kubb configuration.
|
|
765
|
-
* Accepts `Config`/`Config[]`/promise or a factory (optionally receiving `TCliOptions
|
|
759
|
+
* Accepts `Config`/`Config[]`/promise or a factory (optionally receiving `TCliOptions`).
|
|
766
760
|
*/
|
|
767
761
|
export type PossibleConfig<TCliOptions = undefined> =
|
|
768
762
|
| PossiblePromise<Config | Array<Config>>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"memoryStorage-B0W-w994.js","names":["#emitter","NodeEventEmitter","#emitAll","#cache","#store","#dedupe","#sorted","#parsers","#storage","#extension","#pending","#runningFlush","#processAndWrite"],"sources":["../../../internals/utils/src/errors.ts","../../../internals/utils/src/asyncEventEmitter.ts","../../../internals/utils/src/casing.ts","../src/constants.ts","../src/createStorage.ts","../src/FileManager.ts","../src/FileProcessor.ts","../src/storages/memoryStorage.ts"],"sourcesContent":["/**\n * Thrown when one or more errors occur during a Kubb build.\n * Carries the full list of underlying errors on `errors`.\n *\n * @example\n * ```ts\n * throw new BuildError('Build failed', { errors: [err1, err2] })\n * ```\n */\nexport class BuildError extends Error {\n errors: Array<Error>\n\n constructor(message: string, options: { cause?: Error; errors: Array<Error> }) {\n super(message, { cause: options.cause })\n this.name = 'BuildError'\n this.errors = options.errors\n }\n}\n\n/**\n * Coerces an unknown thrown value to an `Error` instance.\n * Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.\n *\n * @example\n * ```ts\n * try { ... } catch(err) {\n * throw new BuildError('Build failed', { cause: toError(err), errors: [] })\n * }\n * ```\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value))\n}\n\n/**\n * Extracts a human-readable message from any thrown value.\n *\n * @example\n * ```ts\n * getErrorMessage(new Error('oops')) // 'oops'\n * getErrorMessage('plain string') // 'plain string'\n * ```\n */\nexport function getErrorMessage(value: unknown): string {\n return value instanceof Error ? value.message : String(value)\n}\n\n/**\n * Extracts the `.cause` of an `Error` as an `Error`, or `undefined` when absent or not an `Error`.\n *\n * @example\n * ```ts\n * const cause = toCause(buildError) // Error | undefined\n * ```\n */\nexport function toCause(error: Error): Error | undefined {\n return error.cause instanceof Error ? error.cause : undefined\n}\n","import { EventEmitter as NodeEventEmitter } from 'node:events'\nimport { toError } from './errors.ts'\n\n/**\n * A function that can be registered as an event listener, synchronous or async.\n */\ntype AsyncListener<TArgs extends Array<unknown>> = (...args: TArgs) => void | Promise<void>\n\n/**\n * Typed `EventEmitter` that awaits all async listeners before resolving.\n * Wraps Node's `EventEmitter` with full TypeScript event-map inference.\n *\n * @example\n * ```ts\n * const emitter = new AsyncEventEmitter<{ build: [name: string] }>()\n * emitter.on('build', async (name) => { console.log(name) })\n * await emitter.emit('build', 'petstore') // all listeners awaited\n * ```\n */\nexport class AsyncEventEmitter<TEvents extends { [K in keyof TEvents]: Array<unknown> }> {\n /**\n * Maximum number of listeners per event before Node emits a memory-leak warning.\n * @default 10\n */\n constructor(maxListener = 10) {\n this.#emitter.setMaxListeners(maxListener)\n }\n\n #emitter = new NodeEventEmitter()\n\n /**\n * Emits `eventName` and awaits all registered listeners sequentially.\n * Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.\n *\n * @example\n * ```ts\n * await emitter.emit('build', 'petstore')\n * ```\n */\n emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> | void {\n const listeners = this.#emitter.listeners(eventName) as Array<AsyncListener<TEvents[TEventName]>>\n\n if (listeners.length === 0) {\n return\n }\n\n return this.#emitAll(eventName, listeners, eventArgs)\n }\n\n async #emitAll<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n listeners: Array<AsyncListener<TEvents[TEventName]>>,\n eventArgs: TEvents[TEventName],\n ): Promise<void> {\n for (const listener of listeners) {\n try {\n await listener(...eventArgs)\n } catch (err) {\n let serializedArgs: string\n try {\n serializedArgs = JSON.stringify(eventArgs)\n } catch {\n serializedArgs = String(eventArgs)\n }\n throw new Error(`Error in async listener for \"${eventName}\" with eventArgs ${serializedArgs}`, { cause: toError(err) })\n }\n }\n }\n\n /**\n * Registers a persistent listener for `eventName`.\n *\n * @example\n * ```ts\n * emitter.on('build', async (name) => { console.log(name) })\n * ```\n */\n on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void {\n this.#emitter.on(eventName, handler as AsyncListener<Array<unknown>>)\n }\n\n /**\n * Registers a one-shot listener that removes itself after the first invocation.\n *\n * @example\n * ```ts\n * emitter.onOnce('build', async (name) => { console.log(name) })\n * ```\n */\n onOnce<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void {\n const wrapper: AsyncListener<TEvents[TEventName]> = (...args) => {\n this.off(eventName, wrapper)\n return handler(...args)\n }\n this.on(eventName, wrapper)\n }\n\n /**\n * Removes a previously registered listener.\n *\n * @example\n * ```ts\n * emitter.off('build', handler)\n * ```\n */\n off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void {\n this.#emitter.off(eventName, handler as AsyncListener<Array<unknown>>)\n }\n\n /**\n * Returns the number of listeners registered for `eventName`.\n *\n * @example\n * ```ts\n * emitter.on('build', handler)\n * emitter.listenerCount('build') // 1\n * ```\n */\n listenerCount<TEventName extends keyof TEvents & string>(eventName: TEventName): number {\n return this.#emitter.listenerCount(eventName)\n }\n\n /**\n * Raises or lowers the per-event listener ceiling before Node warns about a memory leak.\n * Set this above the expected listener count when many listeners attach by design.\n *\n * @example\n * ```ts\n * emitter.setMaxListeners(40)\n * ```\n */\n setMaxListeners(max: number): void {\n this.#emitter.setMaxListeners(max)\n }\n\n /**\n * Returns the current per-event listener ceiling.\n */\n getMaxListeners(): number {\n return this.#emitter.getMaxListeners()\n }\n\n /**\n * Removes all listeners from every event channel.\n *\n * @example\n * ```ts\n * emitter.removeAll()\n * ```\n */\n removeAll(): void {\n this.#emitter.removeAllListeners()\n }\n}\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n","/**\n * Number of file writes to batch in parallel during `flushPendingFiles`.\n */\nexport const STREAM_FLUSH_EVERY = 50\n\n/**\n * Maximum number of █ characters in a plugin timing bar.\n */\nexport const SUMMARY_MAX_BAR_LENGTH = 10 as const\n\n/**\n * Divides elapsed milliseconds into bar-length units (1 block per 100 ms).\n */\nexport const SUMMARY_TIME_SCALE_DIVISOR = 100 as const\n\n/**\n * Number of schema/operation nodes to dispatch concurrently during generation.\n */\nexport const SCHEMA_PARALLEL = 8\n\n/**\n * Upper bound of hook listeners a single plugin can add to one event (its schema, operation,\n * and operations generators, plus lifecycle hooks). Used to size the hooks emitter's\n * max-listener ceiling so a multi-generator plugin set does not trip Node's leak warning.\n */\nexport const HOOK_LISTENERS_PER_PLUGIN = 4\n\n/**\n * Plugin `include` filter types that select operations directly. When one of these is set\n * without a `schemaName` include, the generate phase pre-scans operations to compute the set\n * of schemas they reach, so unreachable schemas can be pruned for that plugin.\n */\nexport const OPERATION_FILTER_TYPES: ReadonlySet<string> = new Set(['tag', 'operationId', 'path', 'method', 'contentType'])\n\n/**\n * Stable codes Kubb attaches to a `Diagnostic`. Each maps to a known failure mode\n * and stays stable so it can be referenced in tooling and (later) docs. Reference\n * these instead of inlining the string at a throw site.\n */\nexport const diagnosticCode = {\n /**\n * Fallback for an unstructured error with no specific code.\n */\n unknown: 'KUBB_UNKNOWN',\n /**\n * The `input.path` file or URL could not be read.\n */\n inputNotFound: 'KUBB_INPUT_NOT_FOUND',\n /**\n * An adapter was configured without an `input`.\n */\n inputRequired: 'KUBB_INPUT_REQUIRED',\n /**\n * A `$ref` (or equivalent reference) could not be resolved in the source document.\n */\n refNotFound: 'KUBB_REF_NOT_FOUND',\n /**\n * A server variable value is not allowed by its `enum`.\n */\n invalidServerVariable: 'KUBB_INVALID_SERVER_VARIABLE',\n /**\n * A required plugin is missing from the config.\n */\n pluginNotFound: 'KUBB_PLUGIN_NOT_FOUND',\n /**\n * A plugin threw while generating.\n */\n pluginFailed: 'KUBB_PLUGIN_FAILED',\n /**\n * A plugin reported a non-fatal warning through `ctx.warn`.\n */\n pluginWarning: 'KUBB_PLUGIN_WARNING',\n /**\n * A plugin reported an informational message through `ctx.info`.\n */\n pluginInfo: 'KUBB_PLUGIN_INFO',\n /**\n * A schema uses a `format` Kubb does not map to a specific type. Reserved for\n * adapters to emit as a `warning`.\n */\n unsupportedFormat: 'KUBB_UNSUPPORTED_FORMAT',\n /**\n * A referenced schema or operation is marked `deprecated`. Reserved for adapters\n * to emit as an `info`.\n */\n deprecated: 'KUBB_DEPRECATED',\n /**\n * An adapter is required but the config has none. The build cannot read the input\n * without one.\n */\n adapterRequired: 'KUBB_ADAPTER_REQUIRED',\n /**\n * A resolved output path escapes the output directory, which can stem from a path\n * traversal in the spec or a misconfigured `group.name`.\n */\n pathTraversal: 'KUBB_PATH_TRAVERSAL',\n /**\n * A plugin's options are invalid, for example `output.mode: 'file'` paired with a `group` option.\n */\n invalidPluginOptions: 'KUBB_INVALID_PLUGIN_OPTIONS',\n /**\n * A post-generate shell hook (`hooks.done`) exited with a failure.\n */\n hookFailed: 'KUBB_HOOK_FAILED',\n /**\n * The formatter pass over the generated files failed.\n */\n formatFailed: 'KUBB_FORMAT_FAILED',\n /**\n * The linter pass over the generated files failed.\n */\n lintFailed: 'KUBB_LINT_FAILED',\n /**\n * Not a failure. Carries a plugin's elapsed time, summed into the run total.\n */\n performance: 'KUBB_PERFORMANCE',\n /**\n * Not a failure. A newer Kubb version is available on npm.\n */\n updateAvailable: 'KUBB_UPDATE_AVAILABLE',\n} as const\n\n/**\n * Union of the stable {@link diagnosticCode} values.\n */\nexport type DiagnosticCode = (typeof diagnosticCode)[keyof typeof diagnosticCode]\n","/**\n * Backend that persists generated files. Kubb ships with `fsStorage` (writes\n * to disk) and `memoryStorage` (keeps everything in RAM). Implement this\n * interface to write to S3, a database, or any other target.\n */\nexport type Storage = {\n /**\n * Identifier used in logs and diagnostics (`'fs'`, `'memory'`, `'s3'`).\n */\n readonly name: string\n /**\n * Returns `true` when an entry for `key` exists.\n */\n hasItem(key: string): Promise<boolean>\n /**\n * Reads the stored string. Returns `null` when the key is missing.\n */\n getItem(key: string): Promise<string | null>\n /**\n * Stores `value` under `key`, creating any required structure (directories,\n * buckets, ...).\n */\n setItem(key: string, value: string): Promise<void>\n /**\n * Deletes the entry for `key`. No-op when the key does not exist.\n */\n removeItem(key: string): Promise<void>\n /**\n * Returns every key. Pass `base` to filter to keys starting with that prefix.\n */\n getKeys(base?: string): Promise<Array<string>>\n /**\n * Removes every entry. Pass `base` to scope the wipe to a key prefix.\n */\n clear(base?: string): Promise<void>\n /**\n * Optional teardown hook called after the build completes. Use to flush\n * buffers, close connections, or release file locks.\n */\n dispose?(): Promise<void>\n}\n\n/**\n * Defines a custom storage backend. The builder receives user options and\n * returns a `Storage` implementation. Kubb ships with filesystem and\n * in-memory storages, reach for this when you need to write generated files\n * elsewhere (cloud storage, a database, a remote API).\n *\n * @example In-memory storage (the built-in implementation)\n * ```ts\n * import { createStorage } from '@kubb/core'\n *\n * export const memoryStorage = createStorage(() => {\n * const store = new Map<string, string>()\n *\n * return {\n * name: 'memory',\n * async hasItem(key) {\n * return store.has(key)\n * },\n * async getItem(key) {\n * return store.get(key) ?? null\n * },\n * async setItem(key, value) {\n * store.set(key, value)\n * },\n * async removeItem(key) {\n * store.delete(key)\n * },\n * async getKeys(base) {\n * const keys = [...store.keys()]\n * return base ? keys.filter((k) => k.startsWith(base)) : keys\n * },\n * async clear(base) {\n * if (!base) store.clear()\n * },\n * }\n * })\n * ```\n */\nexport function createStorage<TOptions = Record<string, never>>(build: (options: TOptions) => Storage): (options?: TOptions) => Storage {\n return (options) => build(options ?? ({} as TOptions))\n}\n","import { AsyncEventEmitter } from '@internals/utils'\nimport type { FileNode } from '@kubb/ast'\nimport { createFile } from '@kubb/ast'\n\n/**\n * Hooks fired by a `FileManager`.\n *\n * - `upsert` fires once per resolved file added through `add` or `upsert`.\n */\nexport type FileManagerHooks = {\n upsert: [file: FileNode]\n}\n\nfunction mergeFile<TMeta extends object = object>(a: FileNode<TMeta>, b: FileNode<TMeta>): FileNode<TMeta> {\n return {\n ...a,\n // Incoming file (b) takes precedence for banner/footer so a barrel file (whose\n // banner/footer the barrel plugin resolves last) wins over a plugin-generated\n // file at the same path.\n banner: b.banner,\n footer: b.footer,\n sources: a.sources.length ? (b.sources.length ? [...a.sources, ...b.sources] : a.sources) : b.sources,\n imports: a.imports.length ? (b.imports.length ? [...a.imports, ...b.imports] : a.imports) : b.imports,\n exports: a.exports.length ? (b.exports.length ? [...a.exports, ...b.exports] : a.exports) : b.exports,\n }\n}\n\nfunction isIndexPath(path: string): boolean {\n return path.endsWith('/index.ts') || path === 'index.ts'\n}\n\n// Sort order: shortest path first. Within a length bucket, index.ts barrels last.\nfunction compareFiles(a: FileNode, b: FileNode): number {\n const lenDiff = a.path.length - b.path.length\n if (lenDiff !== 0) return lenDiff\n const aIsIndex = isIndexPath(a.path)\n const bIsIndex = isIndexPath(b.path)\n if (aIsIndex && !bIsIndex) return 1\n if (!aIsIndex && bIsIndex) return -1\n return 0\n}\n\n/**\n * In-memory file store for generated files. Files sharing a `path` are merged\n * (sources/imports/exports concatenated). The `files` getter is sorted by\n * path length (barrel `index.ts` last within a bucket).\n *\n * @example\n * ```ts\n * const manager = new FileManager()\n * manager.upsert(myFile)\n * manager.files // sorted view\n * ```\n */\nexport class FileManager {\n /**\n * Subscribe to file-store changes. Listeners on `upsert` see each resolved file as it lands\n * through `add` or `upsert`.\n */\n readonly hooks = new AsyncEventEmitter<FileManagerHooks>()\n readonly #cache = new Map<string, FileNode>()\n // Cached sorted view. Null means stale and rebuilt lazily on next `files` read.\n // Nulled (not mutated) on every write so callers holding a prior reference\n // keep their snapshot, `dispose()` must not silently empty an array the\n // consumer already holds.\n #sorted: Array<FileNode> | null = null\n\n add(...files: Array<FileNode>): Array<FileNode> {\n return this.#store(files, false)\n }\n\n upsert(...files: Array<FileNode>): Array<FileNode> {\n return this.#store(files, true)\n }\n\n #store(files: ReadonlyArray<FileNode>, mergeExisting: boolean): Array<FileNode> {\n const batch = files.length > 1 ? this.#dedupe(files) : files\n const resolved: Array<FileNode> = []\n\n for (const file of batch) {\n const existing = this.#cache.get(file.path)\n const merged = existing && mergeExisting ? createFile(mergeFile(existing, file)) : createFile(file)\n this.#cache.set(merged.path, merged)\n resolved.push(merged)\n this.hooks.emit('upsert', merged)\n }\n\n if (resolved.length > 0) this.#sorted = null\n return resolved\n }\n\n // Merges same-path entries within a batch so the cache update loop stays\n // uniform. Only called for multi-file batches.\n #dedupe(files: ReadonlyArray<FileNode>): Array<FileNode> {\n const seen = new Map<string, FileNode>()\n for (const file of files) {\n const prev = seen.get(file.path)\n seen.set(file.path, prev ? mergeFile(prev, file) : file)\n }\n return [...seen.values()]\n }\n\n getByPath(path: string): FileNode | null {\n return this.#cache.get(path) ?? null\n }\n\n deleteByPath(path: string): void {\n if (!this.#cache.delete(path)) return\n this.#sorted = null\n }\n\n clear(): void {\n this.#cache.clear()\n this.#sorted = null\n }\n\n /**\n * Releases all stored files and clears every `hooks` listener. Called by the core after\n * `kubb:build:end`.\n */\n dispose(): void {\n this.clear()\n this.hooks.removeAll()\n }\n\n [Symbol.dispose](): void {\n this.dispose()\n }\n\n /**\n * All stored files in stable sort order (shortest path first, barrel files\n * last within a length bucket). Returns a cached view, do not mutate.\n */\n get files(): Array<FileNode> {\n return (this.#sorted ??= [...this.#cache.values()].sort(compareFiles))\n }\n}\n","import { AsyncEventEmitter } from '@internals/utils'\nimport type { CodeNode, FileNode } from '@kubb/ast'\nimport { extractStringsFromNodes } from '@kubb/ast'\nimport { STREAM_FLUSH_EVERY } from './constants.ts'\nimport type { Storage } from './createStorage.ts'\nimport type { Parser } from './defineParser.ts'\n\n/**\n * Hooks fired by a `FileProcessor`.\n *\n * - `start` opens a batch, from `run` or a queue flush.\n * - `update` fires once per file as it is converted.\n * - `end` closes a batch.\n * - `enqueue` fires for every `enqueue` call.\n * - `drain` fires when `drain()` empties the queue with no in-flight batch left.\n */\nexport type FileProcessorHooks = {\n start: [files: Array<FileNode>]\n update: [params: { file: FileNode; source?: string; processed: number; total: number; percentage: number }]\n end: [files: Array<FileNode>]\n enqueue: [file: FileNode]\n drain: []\n}\n\n/**\n * Per-file progress record yielded by `stream` and surfaced through the `update` event.\n */\nexport type ParsedFile = {\n file: FileNode\n source: string\n processed: number\n total: number\n percentage: number\n}\n\ntype FileProcessorOptions = {\n /**\n * Storage destination for queued writes.\n */\n storage: Storage\n /**\n * Parsers indexed by file extension.\n */\n parsers?: Map<FileNode['extname'], Parser>\n /**\n * Output extname per source extname, applied during conversion.\n */\n extension?: Record<FileNode['extname'], FileNode['extname'] | ''>\n}\n\nfunction joinSources(file: FileNode): string {\n const sources = file.sources\n if (sources.length === 0) return ''\n const parts: Array<string> = []\n for (const source of sources) {\n const text = extractStringsFromNodes(source.nodes as Array<CodeNode>)\n if (text) parts.push(text)\n }\n return parts.join('\\n\\n')\n}\n\n/**\n * Turns `FileNode`s into source strings and writes them to storage.\n *\n * Two modes share the same instance. Stateless mode (`parse`, `stream`, `run`) just runs the\n * conversion. Queue mode (`enqueue`, `flush`, `drain`) buffers files deduped by path and\n * writes each batch through storage with up to `STREAM_FLUSH_EVERY` requests in flight.\n *\n * `flush` does not wait for its batch to finish, so dispatch can overlap with IO. The next\n * `flush` or `drain` picks the in-flight batch up. `drain` blocks until everything has been\n * written and is meant for the end of a build.\n *\n * To surface build-level hook signals (`kubb:files:processing:*` and friends) subscribe to\n * `hooks` and re-emit on the kubb bus.\n */\nexport class FileProcessor {\n readonly hooks = new AsyncEventEmitter<FileProcessorHooks>()\n readonly #parsers: Map<FileNode['extname'], Parser> | null\n readonly #storage: Storage\n readonly #extension: Record<FileNode['extname'], FileNode['extname'] | ''> | null\n readonly #pending = new Map<string, FileNode>()\n #runningFlush: Promise<void> | null = null\n\n constructor(options: FileProcessorOptions) {\n this.#parsers = options.parsers ?? null\n this.#storage = options.storage\n this.#extension = options.extension ?? null\n }\n\n /**\n * Files waiting in the queue.\n */\n get size(): number {\n return this.#pending.size\n }\n\n parse(file: FileNode): string {\n const parsers = this.#parsers\n const parseExtName = this.#extension?.[file.extname] || undefined\n\n if (!parsers || !file.extname) {\n return joinSources(file)\n }\n\n const parser = parsers.get(file.extname)\n\n if (!parser) {\n return joinSources(file)\n }\n\n return parser.parse(file, { extname: parseExtName })\n }\n\n *stream(files: ReadonlyArray<FileNode>): Generator<ParsedFile> {\n const total = files.length\n if (total === 0) return\n\n let processed = 0\n for (const file of files) {\n const source = this.parse(file)\n processed++\n\n yield { file, source, processed, total, percentage: (processed / total) * 100 }\n }\n }\n\n async run(files: Array<FileNode>): Promise<Array<FileNode>> {\n await this.hooks.emit('start', files)\n\n for (const { file, source, processed, total, percentage } of this.stream(files)) {\n await this.hooks.emit('update', { file, source, processed, percentage, total })\n }\n\n await this.hooks.emit('end', files)\n\n return files\n }\n\n /**\n * Adds a file to the next flush. A later `enqueue` for the same path replaces the previous\n * entry, matching `FileManager.upsert`. Fires the `enqueue` event.\n */\n enqueue(file: FileNode): void {\n this.#pending.set(file.path, file)\n this.hooks.emit('enqueue', file)\n }\n\n /**\n * Starts processing the queued files. Waits for any previous flush to finish (so two\n * batches never run together) and then returns without waiting for the new one. The next\n * `flush` or `drain` picks up the in-flight task.\n */\n async flush(): Promise<void> {\n if (this.#runningFlush) await this.#runningFlush\n if (this.#pending.size === 0) return\n\n const batch = [...this.#pending.values()]\n this.#pending.clear()\n\n this.#runningFlush = this.#processAndWrite(batch).finally(() => {\n this.#runningFlush = null\n })\n }\n\n /**\n * Waits for the in-flight flush and writes any files still queued. Fires the `drain` event\n * when both are done.\n */\n async drain(): Promise<void> {\n if (this.#runningFlush) await this.#runningFlush\n\n if (this.#pending.size > 0) {\n const batch = [...this.#pending.values()]\n this.#pending.clear()\n await this.#processAndWrite(batch)\n }\n\n await this.hooks.emit('drain')\n }\n\n async #processAndWrite(files: Array<FileNode>): Promise<void> {\n const storage = this.#storage\n\n await this.hooks.emit('start', files)\n\n // Single pass: each file's write starts right after its `update` fires, so IO overlaps\n // parsing and the batch never holds every rendered source in memory at once.\n const queue: Array<Promise<void>> = []\n for (const item of this.stream(files)) {\n await this.hooks.emit('update', item)\n if (item.source) {\n queue.push(storage.setItem(item.file.path, item.source))\n if (queue.length >= STREAM_FLUSH_EVERY) await Promise.all(queue.splice(0))\n }\n }\n await Promise.all(queue)\n\n await this.hooks.emit('end', files)\n }\n\n /**\n * Clears every listener and the pending queue.\n */\n dispose(): void {\n this.hooks.removeAll()\n this.#pending.clear()\n }\n\n [Symbol.dispose](): void {\n this.dispose()\n }\n}\n","import { createStorage } from '../createStorage.ts'\n\n/**\n * In-memory storage driver. Useful for testing and dry-run scenarios where\n * generated output should be captured without touching the filesystem.\n *\n * All data lives in a `Map` scoped to the storage instance and is discarded\n * when the instance is garbage-collected.\n *\n * @example\n * ```ts\n * import { memoryStorage } from '@kubb/core'\n * import { defineConfig } from 'kubb'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * storage: memoryStorage(),\n * })\n * ```\n */\nexport const memoryStorage = createStorage(() => {\n const store = new Map<string, string>()\n\n return {\n name: 'memory',\n async hasItem(key: string) {\n return store.has(key)\n },\n async getItem(key: string) {\n return store.get(key) ?? null\n },\n async setItem(key: string, value: string) {\n store.set(key, value)\n },\n async removeItem(key: string) {\n store.delete(key)\n },\n async getKeys(base?: string) {\n const keys = [...store.keys()]\n return base ? keys.filter((k) => k.startsWith(base)) : keys\n },\n async clear(base?: string) {\n if (!base) {\n store.clear()\n return\n }\n for (const key of store.keys()) {\n if (key.startsWith(base)) {\n store.delete(key)\n }\n }\n },\n }\n})\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"memoryStorage-skOz0dXZ.cjs","names":["#emitter","NodeEventEmitter","#emitAll","#cache","#store","#dedupe","#sorted","#parsers","#storage","#extension","#pending","#runningFlush","#processAndWrite"],"sources":["../../../internals/utils/src/errors.ts","../../../internals/utils/src/asyncEventEmitter.ts","../../../internals/utils/src/casing.ts","../src/constants.ts","../src/createStorage.ts","../src/FileManager.ts","../src/FileProcessor.ts","../src/storages/memoryStorage.ts"],"sourcesContent":["/**\n * Thrown when one or more errors occur during a Kubb build.\n * Carries the full list of underlying errors on `errors`.\n *\n * @example\n * ```ts\n * throw new BuildError('Build failed', { errors: [err1, err2] })\n * ```\n */\nexport class BuildError extends Error {\n errors: Array<Error>\n\n constructor(message: string, options: { cause?: Error; errors: Array<Error> }) {\n super(message, { cause: options.cause })\n this.name = 'BuildError'\n this.errors = options.errors\n }\n}\n\n/**\n * Coerces an unknown thrown value to an `Error` instance.\n * Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.\n *\n * @example\n * ```ts\n * try { ... } catch(err) {\n * throw new BuildError('Build failed', { cause: toError(err), errors: [] })\n * }\n * ```\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value))\n}\n\n/**\n * Extracts a human-readable message from any thrown value.\n *\n * @example\n * ```ts\n * getErrorMessage(new Error('oops')) // 'oops'\n * getErrorMessage('plain string') // 'plain string'\n * ```\n */\nexport function getErrorMessage(value: unknown): string {\n return value instanceof Error ? value.message : String(value)\n}\n\n/**\n * Extracts the `.cause` of an `Error` as an `Error`, or `undefined` when absent or not an `Error`.\n *\n * @example\n * ```ts\n * const cause = toCause(buildError) // Error | undefined\n * ```\n */\nexport function toCause(error: Error): Error | undefined {\n return error.cause instanceof Error ? error.cause : undefined\n}\n","import { EventEmitter as NodeEventEmitter } from 'node:events'\nimport { toError } from './errors.ts'\n\n/**\n * A function that can be registered as an event listener, synchronous or async.\n */\ntype AsyncListener<TArgs extends Array<unknown>> = (...args: TArgs) => void | Promise<void>\n\n/**\n * Typed `EventEmitter` that awaits all async listeners before resolving.\n * Wraps Node's `EventEmitter` with full TypeScript event-map inference.\n *\n * @example\n * ```ts\n * const emitter = new AsyncEventEmitter<{ build: [name: string] }>()\n * emitter.on('build', async (name) => { console.log(name) })\n * await emitter.emit('build', 'petstore') // all listeners awaited\n * ```\n */\nexport class AsyncEventEmitter<TEvents extends { [K in keyof TEvents]: Array<unknown> }> {\n /**\n * Maximum number of listeners per event before Node emits a memory-leak warning.\n * @default 10\n */\n constructor(maxListener = 10) {\n this.#emitter.setMaxListeners(maxListener)\n }\n\n #emitter = new NodeEventEmitter()\n\n /**\n * Emits `eventName` and awaits all registered listeners sequentially.\n * Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.\n *\n * @example\n * ```ts\n * await emitter.emit('build', 'petstore')\n * ```\n */\n emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> | void {\n const listeners = this.#emitter.listeners(eventName) as Array<AsyncListener<TEvents[TEventName]>>\n\n if (listeners.length === 0) {\n return\n }\n\n return this.#emitAll(eventName, listeners, eventArgs)\n }\n\n async #emitAll<TEventName extends keyof TEvents & string>(\n eventName: TEventName,\n listeners: Array<AsyncListener<TEvents[TEventName]>>,\n eventArgs: TEvents[TEventName],\n ): Promise<void> {\n for (const listener of listeners) {\n try {\n await listener(...eventArgs)\n } catch (err) {\n let serializedArgs: string\n try {\n serializedArgs = JSON.stringify(eventArgs)\n } catch {\n serializedArgs = String(eventArgs)\n }\n throw new Error(`Error in async listener for \"${eventName}\" with eventArgs ${serializedArgs}`, { cause: toError(err) })\n }\n }\n }\n\n /**\n * Registers a persistent listener for `eventName`.\n *\n * @example\n * ```ts\n * emitter.on('build', async (name) => { console.log(name) })\n * ```\n */\n on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void {\n this.#emitter.on(eventName, handler as AsyncListener<Array<unknown>>)\n }\n\n /**\n * Registers a one-shot listener that removes itself after the first invocation.\n *\n * @example\n * ```ts\n * emitter.onOnce('build', async (name) => { console.log(name) })\n * ```\n */\n onOnce<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void {\n const wrapper: AsyncListener<TEvents[TEventName]> = (...args) => {\n this.off(eventName, wrapper)\n return handler(...args)\n }\n this.on(eventName, wrapper)\n }\n\n /**\n * Removes a previously registered listener.\n *\n * @example\n * ```ts\n * emitter.off('build', handler)\n * ```\n */\n off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: AsyncListener<TEvents[TEventName]>): void {\n this.#emitter.off(eventName, handler as AsyncListener<Array<unknown>>)\n }\n\n /**\n * Returns the number of listeners registered for `eventName`.\n *\n * @example\n * ```ts\n * emitter.on('build', handler)\n * emitter.listenerCount('build') // 1\n * ```\n */\n listenerCount<TEventName extends keyof TEvents & string>(eventName: TEventName): number {\n return this.#emitter.listenerCount(eventName)\n }\n\n /**\n * Raises or lowers the per-event listener ceiling before Node warns about a memory leak.\n * Set this above the expected listener count when many listeners attach by design.\n *\n * @example\n * ```ts\n * emitter.setMaxListeners(40)\n * ```\n */\n setMaxListeners(max: number): void {\n this.#emitter.setMaxListeners(max)\n }\n\n /**\n * Returns the current per-event listener ceiling.\n */\n getMaxListeners(): number {\n return this.#emitter.getMaxListeners()\n }\n\n /**\n * Removes all listeners from every event channel.\n *\n * @example\n * ```ts\n * emitter.removeAll()\n * ```\n */\n removeAll(): void {\n this.#emitter.removeAllListeners()\n }\n}\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n","/**\n * Number of file writes to batch in parallel during `flushPendingFiles`.\n */\nexport const STREAM_FLUSH_EVERY = 50\n\n/**\n * Maximum number of █ characters in a plugin timing bar.\n */\nexport const SUMMARY_MAX_BAR_LENGTH = 10 as const\n\n/**\n * Divides elapsed milliseconds into bar-length units (1 block per 100 ms).\n */\nexport const SUMMARY_TIME_SCALE_DIVISOR = 100 as const\n\n/**\n * Number of schema/operation nodes to dispatch concurrently during generation.\n */\nexport const SCHEMA_PARALLEL = 8\n\n/**\n * Upper bound of hook listeners a single plugin can add to one event (its schema, operation,\n * and operations generators, plus lifecycle hooks). Used to size the hooks emitter's\n * max-listener ceiling so a multi-generator plugin set does not trip Node's leak warning.\n */\nexport const HOOK_LISTENERS_PER_PLUGIN = 4\n\n/**\n * Plugin `include` filter types that select operations directly. When one of these is set\n * without a `schemaName` include, the generate phase pre-scans operations to compute the set\n * of schemas they reach, so unreachable schemas can be pruned for that plugin.\n */\nexport const OPERATION_FILTER_TYPES: ReadonlySet<string> = new Set(['tag', 'operationId', 'path', 'method', 'contentType'])\n\n/**\n * Stable codes Kubb attaches to a `Diagnostic`. Each maps to a known failure mode\n * and stays stable so it can be referenced in tooling and (later) docs. Reference\n * these instead of inlining the string at a throw site.\n */\nexport const diagnosticCode = {\n /**\n * Fallback for an unstructured error with no specific code.\n */\n unknown: 'KUBB_UNKNOWN',\n /**\n * The `input.path` file or URL could not be read.\n */\n inputNotFound: 'KUBB_INPUT_NOT_FOUND',\n /**\n * An adapter was configured without an `input`.\n */\n inputRequired: 'KUBB_INPUT_REQUIRED',\n /**\n * A `$ref` (or equivalent reference) could not be resolved in the source document.\n */\n refNotFound: 'KUBB_REF_NOT_FOUND',\n /**\n * A server variable value is not allowed by its `enum`.\n */\n invalidServerVariable: 'KUBB_INVALID_SERVER_VARIABLE',\n /**\n * A required plugin is missing from the config.\n */\n pluginNotFound: 'KUBB_PLUGIN_NOT_FOUND',\n /**\n * A plugin threw while generating.\n */\n pluginFailed: 'KUBB_PLUGIN_FAILED',\n /**\n * A plugin reported a non-fatal warning through `ctx.warn`.\n */\n pluginWarning: 'KUBB_PLUGIN_WARNING',\n /**\n * A plugin reported an informational message through `ctx.info`.\n */\n pluginInfo: 'KUBB_PLUGIN_INFO',\n /**\n * A schema uses a `format` Kubb does not map to a specific type. Reserved for\n * adapters to emit as a `warning`.\n */\n unsupportedFormat: 'KUBB_UNSUPPORTED_FORMAT',\n /**\n * A referenced schema or operation is marked `deprecated`. Reserved for adapters\n * to emit as an `info`.\n */\n deprecated: 'KUBB_DEPRECATED',\n /**\n * An adapter is required but the config has none. The build cannot read the input\n * without one.\n */\n adapterRequired: 'KUBB_ADAPTER_REQUIRED',\n /**\n * A resolved output path escapes the output directory, which can stem from a path\n * traversal in the spec or a misconfigured `group.name`.\n */\n pathTraversal: 'KUBB_PATH_TRAVERSAL',\n /**\n * A plugin's options are invalid, for example `output.mode: 'file'` paired with a `group` option.\n */\n invalidPluginOptions: 'KUBB_INVALID_PLUGIN_OPTIONS',\n /**\n * A post-generate shell hook (`hooks.done`) exited with a failure.\n */\n hookFailed: 'KUBB_HOOK_FAILED',\n /**\n * The formatter pass over the generated files failed.\n */\n formatFailed: 'KUBB_FORMAT_FAILED',\n /**\n * The linter pass over the generated files failed.\n */\n lintFailed: 'KUBB_LINT_FAILED',\n /**\n * Not a failure. Carries a plugin's elapsed time, summed into the run total.\n */\n performance: 'KUBB_PERFORMANCE',\n /**\n * Not a failure. A newer Kubb version is available on npm.\n */\n updateAvailable: 'KUBB_UPDATE_AVAILABLE',\n} as const\n\n/**\n * Union of the stable {@link diagnosticCode} values.\n */\nexport type DiagnosticCode = (typeof diagnosticCode)[keyof typeof diagnosticCode]\n","/**\n * Backend that persists generated files. Kubb ships with `fsStorage` (writes\n * to disk) and `memoryStorage` (keeps everything in RAM). Implement this\n * interface to write to S3, a database, or any other target.\n */\nexport type Storage = {\n /**\n * Identifier used in logs and diagnostics (`'fs'`, `'memory'`, `'s3'`).\n */\n readonly name: string\n /**\n * Returns `true` when an entry for `key` exists.\n */\n hasItem(key: string): Promise<boolean>\n /**\n * Reads the stored string. Returns `null` when the key is missing.\n */\n getItem(key: string): Promise<string | null>\n /**\n * Stores `value` under `key`, creating any required structure (directories,\n * buckets, ...).\n */\n setItem(key: string, value: string): Promise<void>\n /**\n * Deletes the entry for `key`. No-op when the key does not exist.\n */\n removeItem(key: string): Promise<void>\n /**\n * Returns every key. Pass `base` to filter to keys starting with that prefix.\n */\n getKeys(base?: string): Promise<Array<string>>\n /**\n * Removes every entry. Pass `base` to scope the wipe to a key prefix.\n */\n clear(base?: string): Promise<void>\n /**\n * Optional teardown hook called after the build completes. Use to flush\n * buffers, close connections, or release file locks.\n */\n dispose?(): Promise<void>\n}\n\n/**\n * Defines a custom storage backend. The builder receives user options and\n * returns a `Storage` implementation. Kubb ships with filesystem and\n * in-memory storages, reach for this when you need to write generated files\n * elsewhere (cloud storage, a database, a remote API).\n *\n * @example In-memory storage (the built-in implementation)\n * ```ts\n * import { createStorage } from '@kubb/core'\n *\n * export const memoryStorage = createStorage(() => {\n * const store = new Map<string, string>()\n *\n * return {\n * name: 'memory',\n * async hasItem(key) {\n * return store.has(key)\n * },\n * async getItem(key) {\n * return store.get(key) ?? null\n * },\n * async setItem(key, value) {\n * store.set(key, value)\n * },\n * async removeItem(key) {\n * store.delete(key)\n * },\n * async getKeys(base) {\n * const keys = [...store.keys()]\n * return base ? keys.filter((k) => k.startsWith(base)) : keys\n * },\n * async clear(base) {\n * if (!base) store.clear()\n * },\n * }\n * })\n * ```\n */\nexport function createStorage<TOptions = Record<string, never>>(build: (options: TOptions) => Storage): (options?: TOptions) => Storage {\n return (options) => build(options ?? ({} as TOptions))\n}\n","import { AsyncEventEmitter } from '@internals/utils'\nimport type { FileNode } from '@kubb/ast'\nimport { createFile } from '@kubb/ast'\n\n/**\n * Hooks fired by a `FileManager`.\n *\n * - `upsert` fires once per resolved file added through `add` or `upsert`.\n */\nexport type FileManagerHooks = {\n upsert: [file: FileNode]\n}\n\nfunction mergeFile<TMeta extends object = object>(a: FileNode<TMeta>, b: FileNode<TMeta>): FileNode<TMeta> {\n return {\n ...a,\n // Incoming file (b) takes precedence for banner/footer so a barrel file (whose\n // banner/footer the barrel plugin resolves last) wins over a plugin-generated\n // file at the same path.\n banner: b.banner,\n footer: b.footer,\n sources: a.sources.length ? (b.sources.length ? [...a.sources, ...b.sources] : a.sources) : b.sources,\n imports: a.imports.length ? (b.imports.length ? [...a.imports, ...b.imports] : a.imports) : b.imports,\n exports: a.exports.length ? (b.exports.length ? [...a.exports, ...b.exports] : a.exports) : b.exports,\n }\n}\n\nfunction isIndexPath(path: string): boolean {\n return path.endsWith('/index.ts') || path === 'index.ts'\n}\n\n// Sort order: shortest path first. Within a length bucket, index.ts barrels last.\nfunction compareFiles(a: FileNode, b: FileNode): number {\n const lenDiff = a.path.length - b.path.length\n if (lenDiff !== 0) return lenDiff\n const aIsIndex = isIndexPath(a.path)\n const bIsIndex = isIndexPath(b.path)\n if (aIsIndex && !bIsIndex) return 1\n if (!aIsIndex && bIsIndex) return -1\n return 0\n}\n\n/**\n * In-memory file store for generated files. Files sharing a `path` are merged\n * (sources/imports/exports concatenated). The `files` getter is sorted by\n * path length (barrel `index.ts` last within a bucket).\n *\n * @example\n * ```ts\n * const manager = new FileManager()\n * manager.upsert(myFile)\n * manager.files // sorted view\n * ```\n */\nexport class FileManager {\n /**\n * Subscribe to file-store changes. Listeners on `upsert` see each resolved file as it lands\n * through `add` or `upsert`.\n */\n readonly hooks = new AsyncEventEmitter<FileManagerHooks>()\n readonly #cache = new Map<string, FileNode>()\n // Cached sorted view. Null means stale and rebuilt lazily on next `files` read.\n // Nulled (not mutated) on every write so callers holding a prior reference\n // keep their snapshot, `dispose()` must not silently empty an array the\n // consumer already holds.\n #sorted: Array<FileNode> | null = null\n\n add(...files: Array<FileNode>): Array<FileNode> {\n return this.#store(files, false)\n }\n\n upsert(...files: Array<FileNode>): Array<FileNode> {\n return this.#store(files, true)\n }\n\n #store(files: ReadonlyArray<FileNode>, mergeExisting: boolean): Array<FileNode> {\n const batch = files.length > 1 ? this.#dedupe(files) : files\n const resolved: Array<FileNode> = []\n\n for (const file of batch) {\n const existing = this.#cache.get(file.path)\n const merged = existing && mergeExisting ? createFile(mergeFile(existing, file)) : createFile(file)\n this.#cache.set(merged.path, merged)\n resolved.push(merged)\n this.hooks.emit('upsert', merged)\n }\n\n if (resolved.length > 0) this.#sorted = null\n return resolved\n }\n\n // Merges same-path entries within a batch so the cache update loop stays\n // uniform. Only called for multi-file batches.\n #dedupe(files: ReadonlyArray<FileNode>): Array<FileNode> {\n const seen = new Map<string, FileNode>()\n for (const file of files) {\n const prev = seen.get(file.path)\n seen.set(file.path, prev ? mergeFile(prev, file) : file)\n }\n return [...seen.values()]\n }\n\n getByPath(path: string): FileNode | null {\n return this.#cache.get(path) ?? null\n }\n\n deleteByPath(path: string): void {\n if (!this.#cache.delete(path)) return\n this.#sorted = null\n }\n\n clear(): void {\n this.#cache.clear()\n this.#sorted = null\n }\n\n /**\n * Releases all stored files and clears every `hooks` listener. Called by the core after\n * `kubb:build:end`.\n */\n dispose(): void {\n this.clear()\n this.hooks.removeAll()\n }\n\n [Symbol.dispose](): void {\n this.dispose()\n }\n\n /**\n * All stored files in stable sort order (shortest path first, barrel files\n * last within a length bucket). Returns a cached view, do not mutate.\n */\n get files(): Array<FileNode> {\n return (this.#sorted ??= [...this.#cache.values()].sort(compareFiles))\n }\n}\n","import { AsyncEventEmitter } from '@internals/utils'\nimport type { CodeNode, FileNode } from '@kubb/ast'\nimport { extractStringsFromNodes } from '@kubb/ast'\nimport { STREAM_FLUSH_EVERY } from './constants.ts'\nimport type { Storage } from './createStorage.ts'\nimport type { Parser } from './defineParser.ts'\n\n/**\n * Hooks fired by a `FileProcessor`.\n *\n * - `start` opens a batch, from `run` or a queue flush.\n * - `update` fires once per file as it is converted.\n * - `end` closes a batch.\n * - `enqueue` fires for every `enqueue` call.\n * - `drain` fires when `drain()` empties the queue with no in-flight batch left.\n */\nexport type FileProcessorHooks = {\n start: [files: Array<FileNode>]\n update: [params: { file: FileNode; source?: string; processed: number; total: number; percentage: number }]\n end: [files: Array<FileNode>]\n enqueue: [file: FileNode]\n drain: []\n}\n\n/**\n * Per-file progress record yielded by `stream` and surfaced through the `update` event.\n */\nexport type ParsedFile = {\n file: FileNode\n source: string\n processed: number\n total: number\n percentage: number\n}\n\ntype FileProcessorOptions = {\n /**\n * Storage destination for queued writes.\n */\n storage: Storage\n /**\n * Parsers indexed by file extension.\n */\n parsers?: Map<FileNode['extname'], Parser>\n /**\n * Output extname per source extname, applied during conversion.\n */\n extension?: Record<FileNode['extname'], FileNode['extname'] | ''>\n}\n\nfunction joinSources(file: FileNode): string {\n const sources = file.sources\n if (sources.length === 0) return ''\n const parts: Array<string> = []\n for (const source of sources) {\n const text = extractStringsFromNodes(source.nodes as Array<CodeNode>)\n if (text) parts.push(text)\n }\n return parts.join('\\n\\n')\n}\n\n/**\n * Turns `FileNode`s into source strings and writes them to storage.\n *\n * Two modes share the same instance. Stateless mode (`parse`, `stream`, `run`) just runs the\n * conversion. Queue mode (`enqueue`, `flush`, `drain`) buffers files deduped by path and\n * writes each batch through storage with up to `STREAM_FLUSH_EVERY` requests in flight.\n *\n * `flush` does not wait for its batch to finish, so dispatch can overlap with IO. The next\n * `flush` or `drain` picks the in-flight batch up. `drain` blocks until everything has been\n * written and is meant for the end of a build.\n *\n * To surface build-level hook signals (`kubb:files:processing:*` and friends) subscribe to\n * `hooks` and re-emit on the kubb bus.\n */\nexport class FileProcessor {\n readonly hooks = new AsyncEventEmitter<FileProcessorHooks>()\n readonly #parsers: Map<FileNode['extname'], Parser> | null\n readonly #storage: Storage\n readonly #extension: Record<FileNode['extname'], FileNode['extname'] | ''> | null\n readonly #pending = new Map<string, FileNode>()\n #runningFlush: Promise<void> | null = null\n\n constructor(options: FileProcessorOptions) {\n this.#parsers = options.parsers ?? null\n this.#storage = options.storage\n this.#extension = options.extension ?? null\n }\n\n /**\n * Files waiting in the queue.\n */\n get size(): number {\n return this.#pending.size\n }\n\n parse(file: FileNode): string {\n const parsers = this.#parsers\n const parseExtName = this.#extension?.[file.extname] || undefined\n\n if (!parsers || !file.extname) {\n return joinSources(file)\n }\n\n const parser = parsers.get(file.extname)\n\n if (!parser) {\n return joinSources(file)\n }\n\n return parser.parse(file, { extname: parseExtName })\n }\n\n *stream(files: ReadonlyArray<FileNode>): Generator<ParsedFile> {\n const total = files.length\n if (total === 0) return\n\n let processed = 0\n for (const file of files) {\n const source = this.parse(file)\n processed++\n\n yield { file, source, processed, total, percentage: (processed / total) * 100 }\n }\n }\n\n async run(files: Array<FileNode>): Promise<Array<FileNode>> {\n await this.hooks.emit('start', files)\n\n for (const { file, source, processed, total, percentage } of this.stream(files)) {\n await this.hooks.emit('update', { file, source, processed, percentage, total })\n }\n\n await this.hooks.emit('end', files)\n\n return files\n }\n\n /**\n * Adds a file to the next flush. A later `enqueue` for the same path replaces the previous\n * entry, matching `FileManager.upsert`. Fires the `enqueue` event.\n */\n enqueue(file: FileNode): void {\n this.#pending.set(file.path, file)\n this.hooks.emit('enqueue', file)\n }\n\n /**\n * Starts processing the queued files. Waits for any previous flush to finish (so two\n * batches never run together) and then returns without waiting for the new one. The next\n * `flush` or `drain` picks up the in-flight task.\n */\n async flush(): Promise<void> {\n if (this.#runningFlush) await this.#runningFlush\n if (this.#pending.size === 0) return\n\n const batch = [...this.#pending.values()]\n this.#pending.clear()\n\n this.#runningFlush = this.#processAndWrite(batch).finally(() => {\n this.#runningFlush = null\n })\n }\n\n /**\n * Waits for the in-flight flush and writes any files still queued. Fires the `drain` event\n * when both are done.\n */\n async drain(): Promise<void> {\n if (this.#runningFlush) await this.#runningFlush\n\n if (this.#pending.size > 0) {\n const batch = [...this.#pending.values()]\n this.#pending.clear()\n await this.#processAndWrite(batch)\n }\n\n await this.hooks.emit('drain')\n }\n\n async #processAndWrite(files: Array<FileNode>): Promise<void> {\n const storage = this.#storage\n\n await this.hooks.emit('start', files)\n\n // Single pass: each file's write starts right after its `update` fires, so IO overlaps\n // parsing and the batch never holds every rendered source in memory at once.\n const queue: Array<Promise<void>> = []\n for (const item of this.stream(files)) {\n await this.hooks.emit('update', item)\n if (item.source) {\n queue.push(storage.setItem(item.file.path, item.source))\n if (queue.length >= STREAM_FLUSH_EVERY) await Promise.all(queue.splice(0))\n }\n }\n await Promise.all(queue)\n\n await this.hooks.emit('end', files)\n }\n\n /**\n * Clears every listener and the pending queue.\n */\n dispose(): void {\n this.hooks.removeAll()\n this.#pending.clear()\n }\n\n [Symbol.dispose](): void {\n this.dispose()\n }\n}\n","import { createStorage } from '../createStorage.ts'\n\n/**\n * In-memory storage driver. Useful for testing and dry-run scenarios where\n * generated output should be captured without touching the filesystem.\n *\n * All data lives in a `Map` scoped to the storage instance and is discarded\n * when the instance is garbage-collected.\n *\n * @example\n * ```ts\n * import { memoryStorage } from '@kubb/core'\n * import { defineConfig } from 'kubb'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * storage: memoryStorage(),\n * })\n * ```\n */\nexport const memoryStorage = createStorage(() => {\n const store = new Map<string, string>()\n\n return {\n name: 'memory',\n async hasItem(key: string) {\n return store.has(key)\n },\n async getItem(key: string) {\n return store.get(key) ?? null\n },\n async setItem(key: string, value: string) {\n store.set(key, value)\n },\n async removeItem(key: string) {\n store.delete(key)\n },\n async getKeys(base?: string) {\n const keys = [...store.keys()]\n return base ? keys.filter((k) => k.startsWith(base)) : keys\n },\n async clear(base?: string) {\n if (!base) {\n store.clear()\n return\n }\n for (const key of store.keys()) {\n if (key.startsWith(base)) {\n store.delete(key)\n }\n }\n },\n }\n})\n"],"mappings":"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"}
|