@kubb/core 5.0.0-beta.10 → 5.0.0-beta.11
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/{PluginDriver-Cu1Kj9S-.cjs → PluginDriver-C1OsqGBJ.cjs} +12 -1
- package/dist/PluginDriver-C1OsqGBJ.cjs.map +1 -0
- package/dist/{PluginDriver-D8Z0Htid.js → PluginDriver-CGypdXHg.js} +12 -1
- package/dist/PluginDriver-CGypdXHg.js.map +1 -0
- package/dist/{createKubb-ALdb8lmq.d.ts → createKubb-BSfMDBwR.d.ts} +145 -51
- package/dist/index.cjs +140 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -45
- package/dist/index.js +140 -92
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +1 -1
- package/package.json +4 -4
- package/src/FileManager.ts +8 -0
- package/src/FileProcessor.ts +12 -7
- package/src/PluginDriver.ts +9 -0
- package/src/constants.ts +5 -1
- package/src/createKubb.ts +183 -69
- package/src/types.ts +1 -0
- package/dist/PluginDriver-Cu1Kj9S-.cjs.map +0 -1
- package/dist/PluginDriver-D8Z0Htid.js.map +0 -1
package/dist/mocks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
|
-
import { n as applyHookResult, r as FileManager, t as PluginDriver } from "./PluginDriver-
|
|
2
|
+
import { n as applyHookResult, r as FileManager, t as PluginDriver } from "./PluginDriver-CGypdXHg.js";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { transform } from "@kubb/ast";
|
|
5
5
|
//#region src/mocks.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/core",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.11",
|
|
4
4
|
"description": "Core engine for Kubb's plugin-based code generation system. Provides the plugin driver, file manager, defineConfig, and build orchestration used by every Kubb plugin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"code-generator",
|
|
@@ -58,15 +58,15 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"fflate": "^0.8.2",
|
|
60
60
|
"tinyexec": "^1.1.2",
|
|
61
|
-
"@kubb/ast": "5.0.0-beta.
|
|
61
|
+
"@kubb/ast": "5.0.0-beta.11"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"p-limit": "^7.3.0",
|
|
65
65
|
"@internals/utils": "0.0.0",
|
|
66
|
-
"@kubb/renderer-jsx": "5.0.0-beta.
|
|
66
|
+
"@kubb/renderer-jsx": "5.0.0-beta.11"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@kubb/renderer-jsx": "5.0.0-beta.
|
|
69
|
+
"@kubb/renderer-jsx": "5.0.0-beta.11"
|
|
70
70
|
},
|
|
71
71
|
"size-limit": [
|
|
72
72
|
{
|
package/src/FileManager.ts
CHANGED
|
@@ -91,6 +91,14 @@ export class FileManager {
|
|
|
91
91
|
this.#filesCache = null
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Releases all stored files. Called by the core after `kubb:build:end` to
|
|
96
|
+
* free the per-plugin FileNode caches for the rest of the process lifetime.
|
|
97
|
+
*/
|
|
98
|
+
dispose(): void {
|
|
99
|
+
this.clear()
|
|
100
|
+
}
|
|
101
|
+
|
|
94
102
|
/**
|
|
95
103
|
* All stored files, sorted by path length (shorter paths first).
|
|
96
104
|
*/
|
package/src/FileProcessor.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CodeNode, FileNode } from '@kubb/ast'
|
|
2
2
|
import { extractStringsFromNodes } from '@kubb/ast'
|
|
3
|
+
import { AsyncEventEmitter } from '@internals/utils'
|
|
3
4
|
import pLimit from 'p-limit'
|
|
4
5
|
import { PARALLEL_CONCURRENCY_LIMIT } from './constants.ts'
|
|
5
6
|
import type { Parser } from './defineParser.ts'
|
|
@@ -14,9 +15,12 @@ type RunOptions = ParseOptions & {
|
|
|
14
15
|
* @default 'sequential'
|
|
15
16
|
*/
|
|
16
17
|
mode?: 'sequential' | 'parallel'
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type FileProcessorEvents = {
|
|
21
|
+
start: [files: Array<FileNode>]
|
|
22
|
+
update: [params: { file: FileNode; source?: string; processed: number; total: number; percentage: number }]
|
|
23
|
+
end: [files: Array<FileNode>]
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
function joinSources(file: FileNode): string {
|
|
@@ -33,6 +37,7 @@ function joinSources(file: FileNode): string {
|
|
|
33
37
|
* @internal
|
|
34
38
|
*/
|
|
35
39
|
export class FileProcessor {
|
|
40
|
+
readonly events = new AsyncEventEmitter<FileProcessorEvents>()
|
|
36
41
|
readonly #limit = pLimit(PARALLEL_CONCURRENCY_LIMIT)
|
|
37
42
|
|
|
38
43
|
async parse(file: FileNode, { parsers, extension }: ParseOptions = {}): Promise<string> {
|
|
@@ -51,8 +56,8 @@ export class FileProcessor {
|
|
|
51
56
|
return parser.parse(file, { extname: parseExtName })
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
async run(files: Array<FileNode>, { parsers, mode = 'sequential', extension
|
|
55
|
-
await
|
|
59
|
+
async run(files: Array<FileNode>, { parsers, mode = 'sequential', extension }: RunOptions = {}): Promise<Array<FileNode>> {
|
|
60
|
+
await this.events.emit('start', files)
|
|
56
61
|
|
|
57
62
|
const total = files.length
|
|
58
63
|
let processed = 0
|
|
@@ -62,7 +67,7 @@ export class FileProcessor {
|
|
|
62
67
|
const currentProcessed = ++processed
|
|
63
68
|
const percentage = (currentProcessed / total) * 100
|
|
64
69
|
|
|
65
|
-
await
|
|
70
|
+
await this.events.emit('update', {
|
|
66
71
|
file,
|
|
67
72
|
source,
|
|
68
73
|
processed: currentProcessed,
|
|
@@ -79,7 +84,7 @@ export class FileProcessor {
|
|
|
79
84
|
await Promise.all(files.map((file) => this.#limit(() => processOne(file))))
|
|
80
85
|
}
|
|
81
86
|
|
|
82
|
-
await
|
|
87
|
+
await this.events.emit('end', files)
|
|
83
88
|
|
|
84
89
|
return files
|
|
85
90
|
}
|
package/src/PluginDriver.ts
CHANGED
|
@@ -284,6 +284,15 @@ export class PluginDriver {
|
|
|
284
284
|
}
|
|
285
285
|
this.#hookListeners.clear()
|
|
286
286
|
this.#pluginsWithEventGenerators.clear()
|
|
287
|
+
// Release resolver closures — the driver is rebuilt for each build() call
|
|
288
|
+
// so there is no value in retaining these maps after disposal.
|
|
289
|
+
this.#resolvers.clear()
|
|
290
|
+
this.#defaultResolvers.clear()
|
|
291
|
+
// Release the parsed adapter graph and the FileNode cache once the build
|
|
292
|
+
// has finished; the returned `BuildOutput.files` array still references
|
|
293
|
+
// any FileNodes the caller needs to inspect.
|
|
294
|
+
this.fileManager.dispose()
|
|
295
|
+
this.inputNode = undefined
|
|
287
296
|
}
|
|
288
297
|
|
|
289
298
|
#trackHookListener(event: keyof KubbHooks, handler: (...args: never[]) => void | Promise<void>): void {
|
package/src/constants.ts
CHANGED
|
@@ -7,8 +7,12 @@ export const DEFAULT_STUDIO_URL = 'https://kubb.studio' as const
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Maximum number of files processed in parallel by FileProcessor.
|
|
10
|
+
*
|
|
11
|
+
* Capped at 16 to bound the number of CodeNode trees that are alive simultaneously
|
|
12
|
+
* during rendering; I/O latency is the real bottleneck so higher values offer no
|
|
13
|
+
* meaningful throughput improvement.
|
|
10
14
|
*/
|
|
11
|
-
export const PARALLEL_CONCURRENCY_LIMIT =
|
|
15
|
+
export const PARALLEL_CONCURRENCY_LIMIT = 16
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* Default banner style written at the top of every generated file.
|
package/src/createKubb.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { version as KubbVersion } from '../package.json'
|
|
|
8
8
|
import { DEFAULT_BANNER, DEFAULT_EXTENSION, DEFAULT_STUDIO_URL } from './constants.ts'
|
|
9
9
|
import type { Adapter, AdapterSource } from './createAdapter.ts'
|
|
10
10
|
import type { RendererFactory } from './createRenderer.ts'
|
|
11
|
-
import type
|
|
11
|
+
import { createStorage, type Storage } from './createStorage.ts'
|
|
12
12
|
import type { GeneratorContext, Generator } from './defineGenerator.ts'
|
|
13
13
|
import type { Middleware } from './defineMiddleware.ts'
|
|
14
14
|
import type { Parser } from './defineParser.ts'
|
|
@@ -570,8 +570,25 @@ export type KubbGenerationStartContext = {
|
|
|
570
570
|
|
|
571
571
|
export type KubbGenerationEndContext = {
|
|
572
572
|
config: Config
|
|
573
|
-
|
|
574
|
-
|
|
573
|
+
/**
|
|
574
|
+
* Read-only view of the files Kubb wrote during this build.
|
|
575
|
+
*
|
|
576
|
+
* Keys are scoped to this run; files from earlier builds are not included.
|
|
577
|
+
* Reads go directly to `config.storage`, so nothing is buffered in memory.
|
|
578
|
+
*
|
|
579
|
+
* @example Read a generated file
|
|
580
|
+
* ```ts
|
|
581
|
+
* const code = await storage.getItem('/src/gen/pet.ts')
|
|
582
|
+
* ```
|
|
583
|
+
*
|
|
584
|
+
* @example Walk every generated file
|
|
585
|
+
* ```ts
|
|
586
|
+
* for (const path of await storage.getKeys()) {
|
|
587
|
+
* const code = await storage.getItem(path)
|
|
588
|
+
* }
|
|
589
|
+
* ```
|
|
590
|
+
*/
|
|
591
|
+
storage: Storage
|
|
575
592
|
}
|
|
576
593
|
|
|
577
594
|
export type KubbGenerationSummaryContext = {
|
|
@@ -683,9 +700,22 @@ export type BuildOutput = {
|
|
|
683
700
|
pluginTimings: Map<string, number>
|
|
684
701
|
error?: Error
|
|
685
702
|
/**
|
|
686
|
-
*
|
|
703
|
+
* Read-only view of every file written during this build.
|
|
704
|
+
*
|
|
705
|
+
* Keys are limited to this run. Reads go straight to `config.storage`,
|
|
706
|
+
* so nothing extra is held in memory.
|
|
707
|
+
*
|
|
708
|
+
* @example Read a generated file
|
|
709
|
+
* ```ts
|
|
710
|
+
* const code = await buildOutput.storage.getItem('/src/gen/pet.ts')
|
|
711
|
+
* ```
|
|
712
|
+
*
|
|
713
|
+
* @example List all generated file paths
|
|
714
|
+
* ```ts
|
|
715
|
+
* const paths = await buildOutput.storage.getKeys()
|
|
716
|
+
* ```
|
|
687
717
|
*/
|
|
688
|
-
|
|
718
|
+
storage: Storage
|
|
689
719
|
}
|
|
690
720
|
|
|
691
721
|
/**
|
|
@@ -700,17 +730,34 @@ export type Kubb = {
|
|
|
700
730
|
*/
|
|
701
731
|
readonly hooks: AsyncEventEmitter<KubbHooks>
|
|
702
732
|
/**
|
|
703
|
-
*
|
|
733
|
+
* Read-only view of the files from the most recent `build()` or `safeBuild()` call.
|
|
734
|
+
* Only populated after the build completes.
|
|
735
|
+
*
|
|
736
|
+
* Keys are scoped to the current run. Reads go straight to `config.storage`,
|
|
737
|
+
* so nothing extra is held in memory.
|
|
738
|
+
*
|
|
739
|
+
* @example Read a generated file
|
|
740
|
+
* ```ts
|
|
741
|
+
* const { storage } = await kubb.safeBuild()
|
|
742
|
+
* const code = await storage.getItem('/src/gen/pet.ts')
|
|
743
|
+
* ```
|
|
744
|
+
*
|
|
745
|
+
* @example Walk every generated file
|
|
746
|
+
* ```ts
|
|
747
|
+
* for (const path of await kubb.storage.getKeys()) {
|
|
748
|
+
* const code = await kubb.storage.getItem(path)
|
|
749
|
+
* }
|
|
750
|
+
* ```
|
|
704
751
|
*/
|
|
705
|
-
readonly
|
|
752
|
+
readonly storage: Storage
|
|
706
753
|
/**
|
|
707
754
|
* Plugin driver managing all plugins. Available after `setup()` completes.
|
|
708
755
|
*/
|
|
709
|
-
readonly driver: PluginDriver
|
|
756
|
+
readonly driver: PluginDriver
|
|
710
757
|
/**
|
|
711
758
|
* Resolved configuration with defaults applied. Available after `setup()` completes.
|
|
712
759
|
*/
|
|
713
|
-
readonly config: Config
|
|
760
|
+
readonly config: Config
|
|
714
761
|
/**
|
|
715
762
|
* Resolves config and initializes the driver. `build()` calls this automatically.
|
|
716
763
|
*/
|
|
@@ -728,10 +775,51 @@ export type Kubb = {
|
|
|
728
775
|
type SetupResult = {
|
|
729
776
|
hooks: AsyncEventEmitter<KubbHooks>
|
|
730
777
|
driver: PluginDriver
|
|
731
|
-
|
|
778
|
+
storage: Storage
|
|
732
779
|
config: Config
|
|
733
780
|
}
|
|
734
781
|
|
|
782
|
+
/**
|
|
783
|
+
* Builds a `Storage` view scoped to the file paths produced by the current build.
|
|
784
|
+
*
|
|
785
|
+
* Reads delegate to the underlying `storage` (typically `fsStorage()`) so source bytes
|
|
786
|
+
* stay where they were written instead of being held in an extra in-memory map.
|
|
787
|
+
* Writing via `setItem` stores the content in the underlying storage and registers the
|
|
788
|
+
* key so subsequent reads and `getKeys` are scoped to this build's output.
|
|
789
|
+
*/
|
|
790
|
+
function createSourcesView(storage: Storage): Storage {
|
|
791
|
+
const paths = new Set<string>()
|
|
792
|
+
return createStorage(() => ({
|
|
793
|
+
name: `${storage.name}:sources`,
|
|
794
|
+
async hasItem(key: string) {
|
|
795
|
+
return paths.has(key) && (await storage.hasItem(key))
|
|
796
|
+
},
|
|
797
|
+
async getItem(key: string) {
|
|
798
|
+
return paths.has(key) ? storage.getItem(key) : null
|
|
799
|
+
},
|
|
800
|
+
async setItem(key: string, value: string) {
|
|
801
|
+
paths.add(key)
|
|
802
|
+
await storage.setItem(key, value)
|
|
803
|
+
},
|
|
804
|
+
async removeItem(key: string) {
|
|
805
|
+
paths.delete(key)
|
|
806
|
+
await storage.removeItem(key)
|
|
807
|
+
},
|
|
808
|
+
async getKeys(base?: string) {
|
|
809
|
+
if (!base) return [...paths]
|
|
810
|
+
const result: Array<string> = []
|
|
811
|
+
for (const key of paths) {
|
|
812
|
+
if (key.startsWith(base)) result.push(key)
|
|
813
|
+
}
|
|
814
|
+
return result
|
|
815
|
+
},
|
|
816
|
+
async clear() {
|
|
817
|
+
paths.clear()
|
|
818
|
+
await storage.clear()
|
|
819
|
+
},
|
|
820
|
+
}))()
|
|
821
|
+
}
|
|
822
|
+
|
|
735
823
|
async function setup(userConfig: UserConfig, options: SetupOptions = {}): Promise<SetupResult> {
|
|
736
824
|
const hooks = options.hooks ?? new AsyncEventEmitter<KubbHooks>()
|
|
737
825
|
const config: Config = {
|
|
@@ -758,7 +846,7 @@ async function setup(userConfig: UserConfig, options: SetupOptions = {}): Promis
|
|
|
758
846
|
const driver = new PluginDriver(config, {
|
|
759
847
|
hooks,
|
|
760
848
|
})
|
|
761
|
-
const
|
|
849
|
+
const storage: Storage = createSourcesView(config.storage)
|
|
762
850
|
const diagnosticInfo = getDiagnosticInfo()
|
|
763
851
|
|
|
764
852
|
await hooks.emit('kubb:debug', {
|
|
@@ -851,7 +939,7 @@ async function setup(userConfig: UserConfig, options: SetupOptions = {}): Promis
|
|
|
851
939
|
config,
|
|
852
940
|
hooks,
|
|
853
941
|
driver,
|
|
854
|
-
|
|
942
|
+
storage,
|
|
855
943
|
}
|
|
856
944
|
}
|
|
857
945
|
|
|
@@ -965,11 +1053,69 @@ async function runPluginAstHooks(plugin: NormalizedPlugin, context: GeneratorCon
|
|
|
965
1053
|
}
|
|
966
1054
|
|
|
967
1055
|
async function safeBuild(setupResult: SetupResult): Promise<BuildOutput> {
|
|
968
|
-
const { driver, hooks,
|
|
1056
|
+
const { driver, hooks, storage } = setupResult
|
|
969
1057
|
|
|
970
1058
|
const failedPlugins = new Set<{ plugin: Plugin; error: Error }>()
|
|
971
1059
|
const pluginTimings = new Map<string, number>()
|
|
972
1060
|
const config = driver.config
|
|
1061
|
+
const writtenPaths = new Set<string>()
|
|
1062
|
+
const parsersMap = new Map<FileNode['extname'], Parser>()
|
|
1063
|
+
for (const parser of config.parsers) {
|
|
1064
|
+
if (parser.extNames) {
|
|
1065
|
+
for (const extname of parser.extNames) {
|
|
1066
|
+
parsersMap.set(extname, parser)
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
const fileProcessor = new FileProcessor()
|
|
1071
|
+
|
|
1072
|
+
fileProcessor.events.on('start', async (processingFiles) => {
|
|
1073
|
+
await hooks.emit('kubb:files:processing:start', { files: processingFiles })
|
|
1074
|
+
})
|
|
1075
|
+
|
|
1076
|
+
fileProcessor.events.on('update', async ({ file, source, processed, total, percentage }) => {
|
|
1077
|
+
await hooks.emit('kubb:file:processing:update', {
|
|
1078
|
+
file,
|
|
1079
|
+
source,
|
|
1080
|
+
processed,
|
|
1081
|
+
total,
|
|
1082
|
+
percentage,
|
|
1083
|
+
config,
|
|
1084
|
+
})
|
|
1085
|
+
if (source) {
|
|
1086
|
+
await storage.setItem(file.path, source)
|
|
1087
|
+
}
|
|
1088
|
+
})
|
|
1089
|
+
|
|
1090
|
+
fileProcessor.events.on('end', async (processed) => {
|
|
1091
|
+
await hooks.emit('kubb:files:processing:end', { files: processed })
|
|
1092
|
+
await hooks.emit('kubb:debug', {
|
|
1093
|
+
date: new Date(),
|
|
1094
|
+
logs: [`✓ File write process completed for ${processed.length} files`],
|
|
1095
|
+
})
|
|
1096
|
+
})
|
|
1097
|
+
|
|
1098
|
+
async function flushPendingFiles(): Promise<void> {
|
|
1099
|
+
const files = driver.fileManager.files.filter((f) => !writtenPaths.has(f.path))
|
|
1100
|
+
if (files.length === 0) {
|
|
1101
|
+
return
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
await hooks.emit('kubb:debug', {
|
|
1105
|
+
date: new Date(),
|
|
1106
|
+
logs: [`Writing ${files.length} files...`],
|
|
1107
|
+
})
|
|
1108
|
+
|
|
1109
|
+
await fileProcessor.run(files, {
|
|
1110
|
+
parsers: parsersMap,
|
|
1111
|
+
mode: 'parallel',
|
|
1112
|
+
extension: config.output.extension,
|
|
1113
|
+
})
|
|
1114
|
+
|
|
1115
|
+
for (const file of files) {
|
|
1116
|
+
writtenPaths.add(file.path)
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
973
1119
|
|
|
974
1120
|
try {
|
|
975
1121
|
await driver.emitSetupHooks()
|
|
@@ -1018,6 +1164,8 @@ async function safeBuild(setupResult: SetupResult): Promise<BuildOutput> {
|
|
|
1018
1164
|
upsertFile: (...files) => driver.fileManager.upsert(...files),
|
|
1019
1165
|
})
|
|
1020
1166
|
|
|
1167
|
+
await flushPendingFiles()
|
|
1168
|
+
|
|
1021
1169
|
await hooks.emit('kubb:debug', {
|
|
1022
1170
|
date: new Date(),
|
|
1023
1171
|
logs: [`✓ Plugin started successfully (${formatMs(duration)})`],
|
|
@@ -1039,6 +1187,8 @@ async function safeBuild(setupResult: SetupResult): Promise<BuildOutput> {
|
|
|
1039
1187
|
upsertFile: (...files) => driver.fileManager.upsert(...files),
|
|
1040
1188
|
})
|
|
1041
1189
|
|
|
1190
|
+
await flushPendingFiles()
|
|
1191
|
+
|
|
1042
1192
|
await hooks.emit('kubb:debug', {
|
|
1043
1193
|
date: errorTimestamp,
|
|
1044
1194
|
logs: [
|
|
@@ -1062,54 +1212,9 @@ async function safeBuild(setupResult: SetupResult): Promise<BuildOutput> {
|
|
|
1062
1212
|
upsertFile: (...files) => driver.fileManager.upsert(...files),
|
|
1063
1213
|
})
|
|
1064
1214
|
|
|
1065
|
-
|
|
1215
|
+
await flushPendingFiles()
|
|
1066
1216
|
|
|
1067
|
-
const
|
|
1068
|
-
for (const parser of config.parsers) {
|
|
1069
|
-
if (parser.extNames) {
|
|
1070
|
-
for (const extname of parser.extNames) {
|
|
1071
|
-
parsersMap.set(extname, parser)
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
const fileProcessor = new FileProcessor()
|
|
1077
|
-
|
|
1078
|
-
await hooks.emit('kubb:debug', {
|
|
1079
|
-
date: new Date(),
|
|
1080
|
-
logs: [`Writing ${files.length} files...`],
|
|
1081
|
-
})
|
|
1082
|
-
|
|
1083
|
-
await fileProcessor.run(files, {
|
|
1084
|
-
parsers: parsersMap,
|
|
1085
|
-
mode: 'parallel',
|
|
1086
|
-
extension: config.output.extension,
|
|
1087
|
-
onStart: async (processingFiles) => {
|
|
1088
|
-
await hooks.emit('kubb:files:processing:start', { files: processingFiles })
|
|
1089
|
-
},
|
|
1090
|
-
onUpdate: async ({ file, source, processed, total, percentage }) => {
|
|
1091
|
-
await hooks.emit('kubb:file:processing:update', {
|
|
1092
|
-
file,
|
|
1093
|
-
source,
|
|
1094
|
-
processed,
|
|
1095
|
-
total,
|
|
1096
|
-
percentage,
|
|
1097
|
-
config,
|
|
1098
|
-
})
|
|
1099
|
-
if (source) {
|
|
1100
|
-
await config.storage.setItem(file.path, source)
|
|
1101
|
-
|
|
1102
|
-
sources.set(file.path, source)
|
|
1103
|
-
}
|
|
1104
|
-
},
|
|
1105
|
-
onEnd: async (processedFiles) => {
|
|
1106
|
-
await hooks.emit('kubb:files:processing:end', { files: processedFiles })
|
|
1107
|
-
await hooks.emit('kubb:debug', {
|
|
1108
|
-
date: new Date(),
|
|
1109
|
-
logs: [`✓ File write process completed for ${processedFiles.length} files`],
|
|
1110
|
-
})
|
|
1111
|
-
},
|
|
1112
|
-
})
|
|
1217
|
+
const files = driver.fileManager.files
|
|
1113
1218
|
|
|
1114
1219
|
await hooks.emit('kubb:build:end', {
|
|
1115
1220
|
files,
|
|
@@ -1122,7 +1227,7 @@ async function safeBuild(setupResult: SetupResult): Promise<BuildOutput> {
|
|
|
1122
1227
|
files,
|
|
1123
1228
|
driver,
|
|
1124
1229
|
pluginTimings,
|
|
1125
|
-
|
|
1230
|
+
storage,
|
|
1126
1231
|
}
|
|
1127
1232
|
} catch (error) {
|
|
1128
1233
|
return {
|
|
@@ -1131,7 +1236,7 @@ async function safeBuild(setupResult: SetupResult): Promise<BuildOutput> {
|
|
|
1131
1236
|
driver,
|
|
1132
1237
|
pluginTimings,
|
|
1133
1238
|
error: error as Error,
|
|
1134
|
-
|
|
1239
|
+
storage,
|
|
1135
1240
|
}
|
|
1136
1241
|
} finally {
|
|
1137
1242
|
driver.dispose()
|
|
@@ -1139,7 +1244,7 @@ async function safeBuild(setupResult: SetupResult): Promise<BuildOutput> {
|
|
|
1139
1244
|
}
|
|
1140
1245
|
|
|
1141
1246
|
async function build(setupResult: SetupResult): Promise<BuildOutput> {
|
|
1142
|
-
const { files, driver, failedPlugins, pluginTimings, error,
|
|
1247
|
+
const { files, driver, failedPlugins, pluginTimings, error, storage } = await safeBuild(setupResult)
|
|
1143
1248
|
|
|
1144
1249
|
if (error) {
|
|
1145
1250
|
throw error
|
|
@@ -1157,7 +1262,7 @@ async function build(setupResult: SetupResult): Promise<BuildOutput> {
|
|
|
1157
1262
|
driver,
|
|
1158
1263
|
pluginTimings,
|
|
1159
1264
|
error: undefined,
|
|
1160
|
-
|
|
1265
|
+
storage,
|
|
1161
1266
|
}
|
|
1162
1267
|
}
|
|
1163
1268
|
|
|
@@ -1213,7 +1318,7 @@ type CreateKubbOptions = {
|
|
|
1213
1318
|
* Creates a Kubb instance bound to a single config entry.
|
|
1214
1319
|
*
|
|
1215
1320
|
* Accepts a user-facing config shape and resolves it to a full {@link Config} during
|
|
1216
|
-
* `setup()`. The instance then holds shared state (`hooks`, `
|
|
1321
|
+
* `setup()`. The instance then holds shared state (`hooks`, `storage`, `driver`, `config`)
|
|
1217
1322
|
* across the `setup → build` lifecycle. Attach event listeners to `kubb.hooks` before
|
|
1218
1323
|
* calling `setup()` or `build()`.
|
|
1219
1324
|
*
|
|
@@ -1236,14 +1341,23 @@ export function createKubb(userConfig: UserConfig, options: CreateKubbOptions =
|
|
|
1236
1341
|
get hooks() {
|
|
1237
1342
|
return hooks
|
|
1238
1343
|
},
|
|
1239
|
-
get
|
|
1240
|
-
|
|
1344
|
+
get storage() {
|
|
1345
|
+
if (!setupResult) {
|
|
1346
|
+
throw new Error('[kubb] setup() must be called before accessing storage')
|
|
1347
|
+
}
|
|
1348
|
+
return setupResult.storage
|
|
1241
1349
|
},
|
|
1242
1350
|
get driver() {
|
|
1243
|
-
|
|
1351
|
+
if (!setupResult) {
|
|
1352
|
+
throw new Error('[kubb] setup() must be called before accessing driver')
|
|
1353
|
+
}
|
|
1354
|
+
return setupResult.driver
|
|
1244
1355
|
},
|
|
1245
1356
|
get config() {
|
|
1246
|
-
|
|
1357
|
+
if (!setupResult) {
|
|
1358
|
+
throw new Error('[kubb] setup() must be called before accessing config')
|
|
1359
|
+
}
|
|
1360
|
+
return setupResult.config
|
|
1247
1361
|
},
|
|
1248
1362
|
async setup() {
|
|
1249
1363
|
setupResult = await setup(userConfig, { hooks })
|
package/src/types.ts
CHANGED
|
@@ -32,6 +32,7 @@ export type {
|
|
|
32
32
|
} from './createKubb.ts'
|
|
33
33
|
export type { Renderer, RendererFactory } from './createRenderer.ts'
|
|
34
34
|
export type { Storage } from './createStorage.ts'
|
|
35
|
+
export type { FileProcessorEvents } from './FileProcessor.ts'
|
|
35
36
|
export type { Generator, GeneratorContext } from './defineGenerator.ts'
|
|
36
37
|
export type { Logger, LoggerContext, LoggerOptions, UserLogger } from './defineLogger.ts'
|
|
37
38
|
export type { Middleware } from './defineMiddleware.ts'
|