@kubb/core 5.0.0-beta.20 → 5.0.0-beta.21
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/{KubbDriver-BXSnJ3qM.cjs → KubbDriver-BBRa5CH2.cjs} +745 -105
- package/dist/KubbDriver-BBRa5CH2.cjs.map +1 -0
- package/dist/{KubbDriver-Cxii_rBp.js → KubbDriver-Cq1isv2P.js} +723 -89
- package/dist/KubbDriver-Cq1isv2P.js.map +1 -0
- package/dist/{createKubb-Dcmtjqds.d.ts → createKubb-CYrw_xaR.d.ts} +91 -89
- package/dist/index.cjs +138 -762
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +136 -761
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +4 -4
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +4 -4
- package/dist/mocks.js.map +1 -1
- package/package.json +4 -4
- package/src/FileManager.ts +65 -60
- package/src/FileProcessor.ts +11 -0
- package/src/KubbDriver.ts +356 -28
- package/src/createKubb.ts +144 -646
- package/src/createRenderer.ts +10 -0
- package/src/defineResolver.ts +7 -7
- package/src/mocks.ts +3 -3
- package/src/types.ts +2 -1
- package/dist/KubbDriver-BXSnJ3qM.cjs.map +0 -1
- package/dist/KubbDriver-Cxii_rBp.js.map +0 -1
|
@@ -24,11 +24,155 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
//#endregion
|
|
27
|
+
let node_events = require("node:events");
|
|
27
28
|
let node_path = require("node:path");
|
|
28
29
|
node_path = __toESM(node_path, 1);
|
|
29
30
|
let _kubb_ast = require("@kubb/ast");
|
|
30
31
|
let fflate = require("fflate");
|
|
31
32
|
let tinyexec = require("tinyexec");
|
|
33
|
+
//#region ../../internals/utils/src/errors.ts
|
|
34
|
+
/**
|
|
35
|
+
* Thrown when one or more errors occur during a Kubb build.
|
|
36
|
+
* Carries the full list of underlying errors on `errors`.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* throw new BuildError('Build failed', { errors: [err1, err2] })
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
var BuildError = class extends Error {
|
|
44
|
+
errors;
|
|
45
|
+
constructor(message, options) {
|
|
46
|
+
super(message, { cause: options.cause });
|
|
47
|
+
this.name = "BuildError";
|
|
48
|
+
this.errors = options.errors;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Coerces an unknown thrown value to an `Error` instance.
|
|
53
|
+
* Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* try { ... } catch(err) {
|
|
58
|
+
* throw new BuildError('Build failed', { cause: toError(err), errors: [] })
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
function toError(value) {
|
|
63
|
+
return value instanceof Error ? value : new Error(String(value));
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region ../../internals/utils/src/asyncEventEmitter.ts
|
|
67
|
+
/**
|
|
68
|
+
* Typed `EventEmitter` that awaits all async listeners before resolving.
|
|
69
|
+
* Wraps Node's `EventEmitter` with full TypeScript event-map inference.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* const emitter = new AsyncEventEmitter<{ build: [name: string] }>()
|
|
74
|
+
* emitter.on('build', async (name) => { console.log(name) })
|
|
75
|
+
* await emitter.emit('build', 'petstore') // all listeners awaited
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
var AsyncEventEmitter = class {
|
|
79
|
+
/**
|
|
80
|
+
* Maximum number of listeners per event before Node emits a memory-leak warning.
|
|
81
|
+
* @default 10
|
|
82
|
+
*/
|
|
83
|
+
constructor(maxListener = 10) {
|
|
84
|
+
this.#emitter.setMaxListeners(maxListener);
|
|
85
|
+
}
|
|
86
|
+
#emitter = new node_events.EventEmitter();
|
|
87
|
+
/**
|
|
88
|
+
* Emits `eventName` and awaits all registered listeners sequentially.
|
|
89
|
+
* Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* await emitter.emit('build', 'petstore')
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
emit(eventName, ...eventArgs) {
|
|
97
|
+
const listeners = this.#emitter.listeners(eventName);
|
|
98
|
+
if (listeners.length === 0) return;
|
|
99
|
+
return this.#emitAll(eventName, listeners, eventArgs);
|
|
100
|
+
}
|
|
101
|
+
async #emitAll(eventName, listeners, eventArgs) {
|
|
102
|
+
for (const listener of listeners) try {
|
|
103
|
+
await listener(...eventArgs);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
let serializedArgs;
|
|
106
|
+
try {
|
|
107
|
+
serializedArgs = JSON.stringify(eventArgs);
|
|
108
|
+
} catch {
|
|
109
|
+
serializedArgs = String(eventArgs);
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Registers a persistent listener for `eventName`.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* emitter.on('build', async (name) => { console.log(name) })
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
on(eventName, handler) {
|
|
123
|
+
this.#emitter.on(eventName, handler);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Registers a one-shot listener that removes itself after the first invocation.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* emitter.onOnce('build', async (name) => { console.log(name) })
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
onOnce(eventName, handler) {
|
|
134
|
+
const wrapper = (...args) => {
|
|
135
|
+
this.off(eventName, wrapper);
|
|
136
|
+
return handler(...args);
|
|
137
|
+
};
|
|
138
|
+
this.on(eventName, wrapper);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Removes a previously registered listener.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* emitter.off('build', handler)
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
off(eventName, handler) {
|
|
149
|
+
this.#emitter.off(eventName, handler);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Returns the number of listeners registered for `eventName`.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```ts
|
|
156
|
+
* emitter.on('build', handler)
|
|
157
|
+
* emitter.listenerCount('build') // 1
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
listenerCount(eventName) {
|
|
161
|
+
return this.#emitter.listenerCount(eventName);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Removes all listeners from every event channel.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* emitter.removeAll()
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
removeAll() {
|
|
172
|
+
this.#emitter.removeAllListeners();
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
//#endregion
|
|
32
176
|
//#region ../../internals/utils/src/casing.ts
|
|
33
177
|
/**
|
|
34
178
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -93,6 +237,39 @@ function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
|
|
|
93
237
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
|
|
94
238
|
}
|
|
95
239
|
//#endregion
|
|
240
|
+
//#region ../../internals/utils/src/time.ts
|
|
241
|
+
/**
|
|
242
|
+
* Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.
|
|
243
|
+
* Rounds to 2 decimal places for sub-millisecond precision without noise.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```ts
|
|
247
|
+
* const start = process.hrtime()
|
|
248
|
+
* doWork()
|
|
249
|
+
* getElapsedMs(start) // 42.35
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
function getElapsedMs(hrStart) {
|
|
253
|
+
const [seconds, nanoseconds] = process.hrtime(hrStart);
|
|
254
|
+
const ms = seconds * 1e3 + nanoseconds / 1e6;
|
|
255
|
+
return Math.round(ms * 100) / 100;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Converts a millisecond duration into a human-readable string (`ms`, `s`, or `m s`).
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* formatMs(250) // '250ms'
|
|
263
|
+
* formatMs(1500) // '1.50s'
|
|
264
|
+
* formatMs(90000) // '1m 30.0s'
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
function formatMs(ms) {
|
|
268
|
+
if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
|
|
269
|
+
if (ms >= 1e3) return `${(ms / 1e3).toFixed(2)}s`;
|
|
270
|
+
return `${Math.round(ms)}ms`;
|
|
271
|
+
}
|
|
272
|
+
//#endregion
|
|
96
273
|
//#region ../../internals/utils/src/promise.ts
|
|
97
274
|
function* chunks(arr, size) {
|
|
98
275
|
for (let i = 0; i < arr.length; i += size) yield arr.slice(i, i + size);
|
|
@@ -135,22 +312,6 @@ async function forBatches(source, process, options) {
|
|
|
135
312
|
if (flush) await flush();
|
|
136
313
|
}
|
|
137
314
|
}
|
|
138
|
-
/**
|
|
139
|
-
* Runs `work`, passing `flush` as its periodic-flush callback, then calls
|
|
140
|
-
* `flush` once more to drain any items that did not cross a flush boundary.
|
|
141
|
-
*
|
|
142
|
-
* @example
|
|
143
|
-
* ```ts
|
|
144
|
-
* await withDrain(
|
|
145
|
-
* (flush) => processItems(items, { flush }),
|
|
146
|
-
* () => writeRemainingFiles(),
|
|
147
|
-
* )
|
|
148
|
-
* ```
|
|
149
|
-
*/
|
|
150
|
-
async function withDrain(work, flush) {
|
|
151
|
-
await work(flush);
|
|
152
|
-
await flush();
|
|
153
|
-
}
|
|
154
315
|
/** Returns `true` when `result` is a thenable `Promise`.
|
|
155
316
|
*
|
|
156
317
|
* @example
|
|
@@ -813,13 +974,13 @@ function buildDefaultBanner({ title, description, version, config }) {
|
|
|
813
974
|
* @example Disabled default banner
|
|
814
975
|
* ```ts
|
|
815
976
|
* defaultResolveBanner(undefined, { config: { output: { defaultBanner: false }, ...config } })
|
|
816
|
-
* // →
|
|
977
|
+
* // → null
|
|
817
978
|
* ```
|
|
818
979
|
*/
|
|
819
980
|
function defaultResolveBanner(meta, { output, config }) {
|
|
820
981
|
if (typeof output?.banner === "function") return output.banner(meta);
|
|
821
982
|
if (typeof output?.banner === "string") return output.banner;
|
|
822
|
-
if (config.output.defaultBanner === false) return;
|
|
983
|
+
if (config.output.defaultBanner === false) return null;
|
|
823
984
|
return buildDefaultBanner({
|
|
824
985
|
title: meta?.title,
|
|
825
986
|
version: meta?.version,
|
|
@@ -848,6 +1009,7 @@ function defaultResolveBanner(meta, { output, config }) {
|
|
|
848
1009
|
function defaultResolveFooter(meta, { output }) {
|
|
849
1010
|
if (typeof output?.footer === "function") return output.footer(meta);
|
|
850
1011
|
if (typeof output?.footer === "string") return output.footer;
|
|
1012
|
+
return null;
|
|
851
1013
|
}
|
|
852
1014
|
/**
|
|
853
1015
|
* Defines a resolver for a plugin, injecting built-in defaults for name casing,
|
|
@@ -958,111 +1120,241 @@ function mergeFile(a, b) {
|
|
|
958
1120
|
...a,
|
|
959
1121
|
banner: b.banner,
|
|
960
1122
|
footer: b.footer,
|
|
961
|
-
sources:
|
|
962
|
-
imports:
|
|
963
|
-
exports:
|
|
1123
|
+
sources: a.sources.length ? b.sources.length ? [...a.sources, ...b.sources] : a.sources : b.sources,
|
|
1124
|
+
imports: a.imports.length ? b.imports.length ? [...a.imports, ...b.imports] : a.imports : b.imports,
|
|
1125
|
+
exports: a.exports.length ? b.exports.length ? [...a.exports, ...b.exports] : a.exports : b.exports
|
|
964
1126
|
};
|
|
965
1127
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return
|
|
1128
|
+
function isIndexPath(path) {
|
|
1129
|
+
return path.endsWith("/index.ts") || path === "index.ts";
|
|
1130
|
+
}
|
|
1131
|
+
function compareFiles(a, b) {
|
|
1132
|
+
const lenDiff = a.path.length - b.path.length;
|
|
1133
|
+
if (lenDiff !== 0) return lenDiff;
|
|
1134
|
+
const aIsIndex = isIndexPath(a.path);
|
|
1135
|
+
const bIsIndex = isIndexPath(b.path);
|
|
1136
|
+
if (aIsIndex && !bIsIndex) return 1;
|
|
1137
|
+
if (!aIsIndex && bIsIndex) return -1;
|
|
1138
|
+
return 0;
|
|
977
1139
|
}
|
|
978
1140
|
/**
|
|
979
|
-
* In-memory file store for generated files.
|
|
980
|
-
*
|
|
981
|
-
*
|
|
982
|
-
* The `files` getter returns all stored files sorted by path length (shortest first).
|
|
1141
|
+
* In-memory file store for generated files. Files sharing a `path` are merged
|
|
1142
|
+
* (sources/imports/exports concatenated). The `files` getter is sorted by
|
|
1143
|
+
* path length (barrel `index.ts` last within a bucket).
|
|
983
1144
|
*
|
|
984
1145
|
* @example
|
|
985
1146
|
* ```ts
|
|
986
|
-
* import { FileManager } from '@kubb/core'
|
|
987
|
-
*
|
|
988
1147
|
* const manager = new FileManager()
|
|
989
1148
|
* manager.upsert(myFile)
|
|
990
|
-
*
|
|
1149
|
+
* manager.files // sorted view
|
|
991
1150
|
* ```
|
|
992
1151
|
*/
|
|
993
1152
|
var FileManager = class {
|
|
994
1153
|
#cache = /* @__PURE__ */ new Map();
|
|
995
|
-
#
|
|
1154
|
+
#sorted = null;
|
|
1155
|
+
#onUpsert = null;
|
|
996
1156
|
/**
|
|
997
|
-
*
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1157
|
+
* Registers a callback invoked with the resolved {@link FileNode} on every
|
|
1158
|
+
* `add` / `upsert`. Used by the build loop to track newly written files
|
|
1159
|
+
* without keeping its own scan-based diff. Single subscriber by design —
|
|
1160
|
+
* setting again replaces the previous callback. Pass `null` to detach.
|
|
1000
1161
|
*/
|
|
1162
|
+
setOnUpsert(callback) {
|
|
1163
|
+
this.#onUpsert = callback;
|
|
1164
|
+
}
|
|
1001
1165
|
add(...files) {
|
|
1002
1166
|
return this.#store(files, false);
|
|
1003
1167
|
}
|
|
1004
|
-
/**
|
|
1005
|
-
* Adds or merges one or more files.
|
|
1006
|
-
* If a file with the same path already exists in the cache, its
|
|
1007
|
-
* sources/imports/exports are merged into the incoming file.
|
|
1008
|
-
*/
|
|
1009
1168
|
upsert(...files) {
|
|
1010
1169
|
return this.#store(files, true);
|
|
1011
1170
|
}
|
|
1012
1171
|
#store(files, mergeExisting) {
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const
|
|
1017
|
-
|
|
1018
|
-
|
|
1172
|
+
const batch = files.length > 1 ? this.#dedupe(files) : files;
|
|
1173
|
+
const resolved = [];
|
|
1174
|
+
for (const file of batch) {
|
|
1175
|
+
const existing = this.#cache.get(file.path);
|
|
1176
|
+
const merged = existing && mergeExisting ? (0, _kubb_ast.createFile)(mergeFile(existing, file)) : file;
|
|
1177
|
+
this.#cache.set(merged.path, merged);
|
|
1178
|
+
resolved.push(merged);
|
|
1179
|
+
this.#onUpsert?.(merged);
|
|
1019
1180
|
}
|
|
1020
|
-
this.#
|
|
1021
|
-
return
|
|
1181
|
+
if (resolved.length > 0) this.#sorted = null;
|
|
1182
|
+
return resolved;
|
|
1183
|
+
}
|
|
1184
|
+
#dedupe(files) {
|
|
1185
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1186
|
+
for (const file of files) {
|
|
1187
|
+
const prev = seen.get(file.path);
|
|
1188
|
+
seen.set(file.path, prev ? mergeFile(prev, file) : file);
|
|
1189
|
+
}
|
|
1190
|
+
return [...seen.values()];
|
|
1022
1191
|
}
|
|
1023
1192
|
getByPath(path) {
|
|
1024
1193
|
return this.#cache.get(path) ?? null;
|
|
1025
1194
|
}
|
|
1026
1195
|
deleteByPath(path) {
|
|
1027
|
-
this.#cache.delete(path);
|
|
1028
|
-
this.#
|
|
1196
|
+
if (!this.#cache.delete(path)) return;
|
|
1197
|
+
this.#sorted = null;
|
|
1029
1198
|
}
|
|
1030
1199
|
clear() {
|
|
1031
1200
|
this.#cache.clear();
|
|
1032
|
-
this.#
|
|
1201
|
+
this.#sorted = null;
|
|
1033
1202
|
}
|
|
1034
1203
|
/**
|
|
1035
|
-
* Releases all stored files. Called by the core after `kubb:build:end
|
|
1036
|
-
* free the per-plugin FileNode caches for the rest of the process lifetime.
|
|
1204
|
+
* Releases all stored files. Called by the core after `kubb:build:end`.
|
|
1037
1205
|
*/
|
|
1038
1206
|
dispose() {
|
|
1039
1207
|
this.clear();
|
|
1208
|
+
this.#onUpsert = null;
|
|
1040
1209
|
}
|
|
1041
1210
|
[Symbol.dispose]() {
|
|
1042
1211
|
this.dispose();
|
|
1043
1212
|
}
|
|
1044
1213
|
/**
|
|
1045
|
-
* All stored files
|
|
1214
|
+
* All stored files in stable sort order (shortest path first, barrel files
|
|
1215
|
+
* last within a length bucket). Returns a cached view — do not mutate.
|
|
1046
1216
|
*/
|
|
1047
1217
|
get files() {
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1218
|
+
return this.#sorted ??= [...this.#cache.values()].sort(compareFiles);
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
//#endregion
|
|
1222
|
+
//#region src/FileProcessor.ts
|
|
1223
|
+
function joinSources(file) {
|
|
1224
|
+
const sources = file.sources;
|
|
1225
|
+
if (sources.length === 0) return "";
|
|
1226
|
+
const parts = [];
|
|
1227
|
+
for (const source of sources) {
|
|
1228
|
+
const s = (0, _kubb_ast.extractStringsFromNodes)(source.nodes);
|
|
1229
|
+
if (s) parts.push(s);
|
|
1230
|
+
}
|
|
1231
|
+
return parts.join("\n\n");
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Converts a single file to a string using the registered parsers.
|
|
1235
|
+
* Falls back to joining source values when no matching parser is found.
|
|
1236
|
+
*
|
|
1237
|
+
* @internal
|
|
1238
|
+
*/
|
|
1239
|
+
var FileProcessor = class {
|
|
1240
|
+
events = new AsyncEventEmitter();
|
|
1241
|
+
parse(file, { parsers, extension } = {}) {
|
|
1242
|
+
const parseExtName = extension?.[file.extname] || void 0;
|
|
1243
|
+
if (!parsers || !file.extname) return joinSources(file);
|
|
1244
|
+
const parser = parsers.get(file.extname);
|
|
1245
|
+
if (!parser) return joinSources(file);
|
|
1246
|
+
return parser.parse(file, { extname: parseExtName });
|
|
1247
|
+
}
|
|
1248
|
+
*stream(files, options = {}) {
|
|
1249
|
+
const total = files.length;
|
|
1250
|
+
if (total === 0) return;
|
|
1251
|
+
let processed = 0;
|
|
1252
|
+
for (const file of files) {
|
|
1253
|
+
const source = this.parse(file, options);
|
|
1254
|
+
processed++;
|
|
1255
|
+
yield {
|
|
1256
|
+
file,
|
|
1257
|
+
source,
|
|
1258
|
+
processed,
|
|
1259
|
+
total,
|
|
1260
|
+
percentage: processed / total * 100
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
async run(files, options = {}) {
|
|
1265
|
+
await this.events.emit("start", files);
|
|
1266
|
+
for (const { file, source, processed, total, percentage } of this.stream(files, options)) await this.events.emit("update", {
|
|
1267
|
+
file,
|
|
1268
|
+
source,
|
|
1269
|
+
processed,
|
|
1270
|
+
percentage,
|
|
1271
|
+
total
|
|
1057
1272
|
});
|
|
1058
|
-
|
|
1273
|
+
await this.events.emit("end", files);
|
|
1274
|
+
return files;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Clears all registered event listeners.
|
|
1278
|
+
*/
|
|
1279
|
+
dispose() {
|
|
1280
|
+
this.events.removeAll();
|
|
1281
|
+
}
|
|
1282
|
+
[Symbol.dispose]() {
|
|
1283
|
+
this.dispose();
|
|
1059
1284
|
}
|
|
1060
1285
|
};
|
|
1061
1286
|
//#endregion
|
|
1287
|
+
//#region \0@oxc-project+runtime@0.129.0/helpers/usingCtx.js
|
|
1288
|
+
function _usingCtx() {
|
|
1289
|
+
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
1290
|
+
var n = Error();
|
|
1291
|
+
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
1292
|
+
};
|
|
1293
|
+
var e = {};
|
|
1294
|
+
var n = [];
|
|
1295
|
+
function using(r, e) {
|
|
1296
|
+
if (null != e) {
|
|
1297
|
+
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
1298
|
+
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
1299
|
+
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
1300
|
+
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
1301
|
+
t && (o = function o() {
|
|
1302
|
+
try {
|
|
1303
|
+
t.call(e);
|
|
1304
|
+
} catch (r) {
|
|
1305
|
+
return Promise.reject(r);
|
|
1306
|
+
}
|
|
1307
|
+
}), n.push({
|
|
1308
|
+
v: e,
|
|
1309
|
+
d: o,
|
|
1310
|
+
a: r
|
|
1311
|
+
});
|
|
1312
|
+
} else r && n.push({
|
|
1313
|
+
d: e,
|
|
1314
|
+
a: r
|
|
1315
|
+
});
|
|
1316
|
+
return e;
|
|
1317
|
+
}
|
|
1318
|
+
return {
|
|
1319
|
+
e,
|
|
1320
|
+
u: using.bind(null, !1),
|
|
1321
|
+
a: using.bind(null, !0),
|
|
1322
|
+
d: function d() {
|
|
1323
|
+
var o;
|
|
1324
|
+
var t = this.e;
|
|
1325
|
+
var s = 0;
|
|
1326
|
+
function next() {
|
|
1327
|
+
for (; o = n.pop();) try {
|
|
1328
|
+
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
1329
|
+
if (o.d) {
|
|
1330
|
+
var r = o.d.call(o.v);
|
|
1331
|
+
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
1332
|
+
} else s |= 1;
|
|
1333
|
+
} catch (r) {
|
|
1334
|
+
return err(r);
|
|
1335
|
+
}
|
|
1336
|
+
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
1337
|
+
if (t !== e) throw t;
|
|
1338
|
+
}
|
|
1339
|
+
function err(n) {
|
|
1340
|
+
return t = t !== e ? new r(n, t) : n, next();
|
|
1341
|
+
}
|
|
1342
|
+
return next();
|
|
1343
|
+
}
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
//#endregion
|
|
1062
1347
|
//#region src/KubbDriver.ts
|
|
1063
1348
|
function enforceOrder(enforce) {
|
|
1064
1349
|
return enforce === "pre" ? -1 : enforce === "post" ? 1 : 0;
|
|
1065
1350
|
}
|
|
1351
|
+
const OPERATION_FILTER_TYPES = new Set([
|
|
1352
|
+
"tag",
|
|
1353
|
+
"operationId",
|
|
1354
|
+
"path",
|
|
1355
|
+
"method",
|
|
1356
|
+
"contentType"
|
|
1357
|
+
]);
|
|
1066
1358
|
var KubbDriver = class KubbDriver {
|
|
1067
1359
|
config;
|
|
1068
1360
|
options;
|
|
@@ -1082,8 +1374,8 @@ var KubbDriver = class KubbDriver {
|
|
|
1082
1374
|
* The streaming `InputStreamNode` produced by the adapter.
|
|
1083
1375
|
* Always set after adapter setup — parse-only adapters are wrapped automatically.
|
|
1084
1376
|
*/
|
|
1085
|
-
inputNode =
|
|
1086
|
-
adapter =
|
|
1377
|
+
inputNode = null;
|
|
1378
|
+
adapter = null;
|
|
1087
1379
|
/**
|
|
1088
1380
|
* Studio session state, kept together so `dispose()` can reset it atomically.
|
|
1089
1381
|
*
|
|
@@ -1094,9 +1386,9 @@ var KubbDriver = class KubbDriver {
|
|
|
1094
1386
|
* per studio session, even when `openInStudio()` is called multiple times.
|
|
1095
1387
|
*/
|
|
1096
1388
|
#studio = {
|
|
1097
|
-
source:
|
|
1389
|
+
source: null,
|
|
1098
1390
|
isOpen: false,
|
|
1099
|
-
inputNode:
|
|
1391
|
+
inputNode: null
|
|
1100
1392
|
};
|
|
1101
1393
|
#middlewareListeners = [];
|
|
1102
1394
|
/**
|
|
@@ -1105,6 +1397,7 @@ var KubbDriver = class KubbDriver {
|
|
|
1105
1397
|
* add files; this property gives direct read/write access when needed.
|
|
1106
1398
|
*/
|
|
1107
1399
|
fileManager = new FileManager();
|
|
1400
|
+
#fileProcessor = new FileProcessor();
|
|
1108
1401
|
plugins = /* @__PURE__ */ new Map();
|
|
1109
1402
|
/**
|
|
1110
1403
|
* Tracks which plugins have generators registered via `addGenerator()` (event-based path).
|
|
@@ -1117,7 +1410,7 @@ var KubbDriver = class KubbDriver {
|
|
|
1117
1410
|
constructor(config, options) {
|
|
1118
1411
|
this.config = config;
|
|
1119
1412
|
this.options = options;
|
|
1120
|
-
this.adapter = config.adapter;
|
|
1413
|
+
this.adapter = config.adapter ?? null;
|
|
1121
1414
|
}
|
|
1122
1415
|
async setup() {
|
|
1123
1416
|
const normalized = this.config.plugins.map((rawPlugin) => this.#normalizePlugin(rawPlugin));
|
|
@@ -1328,6 +1621,334 @@ var KubbDriver = class KubbDriver {
|
|
|
1328
1621
|
return this.#eventGeneratorPlugins.has(pluginName);
|
|
1329
1622
|
}
|
|
1330
1623
|
/**
|
|
1624
|
+
* Runs the full plugin pipeline. Returns timings/failures collected so far even
|
|
1625
|
+
* when an outer hook throws — the orchestrator preserves partial state by capturing
|
|
1626
|
+
* the error into `error` instead of propagating.
|
|
1627
|
+
*/
|
|
1628
|
+
async run({ storage }) {
|
|
1629
|
+
const hooks = this.hooks;
|
|
1630
|
+
const config = this.config;
|
|
1631
|
+
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1632
|
+
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1633
|
+
const parsersMap = /* @__PURE__ */ new Map();
|
|
1634
|
+
for (const parser of config.parsers) if (parser.extNames) for (const ext of parser.extNames) parsersMap.set(ext, parser);
|
|
1635
|
+
const pendingFiles = /* @__PURE__ */ new Map();
|
|
1636
|
+
this.fileManager.setOnUpsert((file) => {
|
|
1637
|
+
pendingFiles.set(file.path, file);
|
|
1638
|
+
});
|
|
1639
|
+
try {
|
|
1640
|
+
const flushPending = async () => {
|
|
1641
|
+
if (pendingFiles.size === 0) return;
|
|
1642
|
+
const files = [...pendingFiles.values()];
|
|
1643
|
+
pendingFiles.clear();
|
|
1644
|
+
await hooks.emit("kubb:debug", {
|
|
1645
|
+
date: /* @__PURE__ */ new Date(),
|
|
1646
|
+
logs: [`Writing ${files.length} files...`]
|
|
1647
|
+
});
|
|
1648
|
+
await hooks.emit("kubb:files:processing:start", { files });
|
|
1649
|
+
const items = [...this.#fileProcessor.stream(files, {
|
|
1650
|
+
parsers: parsersMap,
|
|
1651
|
+
extension: config.output.extension
|
|
1652
|
+
})];
|
|
1653
|
+
await hooks.emit("kubb:files:processing:update", { files: items.map(({ file, source, processed, total, percentage }) => ({
|
|
1654
|
+
file,
|
|
1655
|
+
source,
|
|
1656
|
+
processed,
|
|
1657
|
+
total,
|
|
1658
|
+
percentage,
|
|
1659
|
+
config
|
|
1660
|
+
})) });
|
|
1661
|
+
const queue = [];
|
|
1662
|
+
for (const { file, source } of items) if (source) {
|
|
1663
|
+
queue.push(storage.setItem(file.path, source));
|
|
1664
|
+
if (queue.length >= 50) await Promise.all(queue.splice(0));
|
|
1665
|
+
}
|
|
1666
|
+
await Promise.all(queue);
|
|
1667
|
+
await hooks.emit("kubb:files:processing:end", { files });
|
|
1668
|
+
await hooks.emit("kubb:debug", {
|
|
1669
|
+
date: /* @__PURE__ */ new Date(),
|
|
1670
|
+
logs: [`✓ File write process completed for ${files.length} files`]
|
|
1671
|
+
});
|
|
1672
|
+
};
|
|
1673
|
+
await this.emitSetupHooks();
|
|
1674
|
+
if (this.adapter && this.inputNode) await hooks.emit("kubb:build:start", Object.assign({
|
|
1675
|
+
config,
|
|
1676
|
+
adapter: this.adapter,
|
|
1677
|
+
meta: this.inputNode.meta,
|
|
1678
|
+
getPlugin: this.getPlugin.bind(this)
|
|
1679
|
+
}, this.#filesPayload()));
|
|
1680
|
+
const generatorPlugins = [];
|
|
1681
|
+
for (const plugin of this.plugins.values()) {
|
|
1682
|
+
const context = this.getContext(plugin);
|
|
1683
|
+
const hrStart = process.hrtime();
|
|
1684
|
+
try {
|
|
1685
|
+
await hooks.emit("kubb:plugin:start", { plugin });
|
|
1686
|
+
await hooks.emit("kubb:debug", {
|
|
1687
|
+
date: /* @__PURE__ */ new Date(),
|
|
1688
|
+
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1689
|
+
});
|
|
1690
|
+
} catch (caughtError) {
|
|
1691
|
+
const error = caughtError;
|
|
1692
|
+
const duration = getElapsedMs(hrStart);
|
|
1693
|
+
pluginTimings.set(plugin.name, duration);
|
|
1694
|
+
await this.#emitPluginEnd({
|
|
1695
|
+
plugin,
|
|
1696
|
+
duration,
|
|
1697
|
+
success: false,
|
|
1698
|
+
error
|
|
1699
|
+
});
|
|
1700
|
+
failedPlugins.add({
|
|
1701
|
+
plugin,
|
|
1702
|
+
error
|
|
1703
|
+
});
|
|
1704
|
+
continue;
|
|
1705
|
+
}
|
|
1706
|
+
if (plugin.generators?.length || this.hasEventGenerators(plugin.name)) {
|
|
1707
|
+
generatorPlugins.push({
|
|
1708
|
+
plugin,
|
|
1709
|
+
context,
|
|
1710
|
+
hrStart
|
|
1711
|
+
});
|
|
1712
|
+
continue;
|
|
1713
|
+
}
|
|
1714
|
+
const duration = getElapsedMs(hrStart);
|
|
1715
|
+
pluginTimings.set(plugin.name, duration);
|
|
1716
|
+
await this.#emitPluginEnd({
|
|
1717
|
+
plugin,
|
|
1718
|
+
duration,
|
|
1719
|
+
success: true
|
|
1720
|
+
});
|
|
1721
|
+
await hooks.emit("kubb:debug", {
|
|
1722
|
+
date: /* @__PURE__ */ new Date(),
|
|
1723
|
+
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
if (generatorPlugins.length > 0) if (this.inputNode) {
|
|
1727
|
+
const { timings, failed } = await this.#runGenerators(generatorPlugins, flushPending);
|
|
1728
|
+
await flushPending();
|
|
1729
|
+
for (const [name, duration] of timings) pluginTimings.set(name, duration);
|
|
1730
|
+
for (const entry of failed) failedPlugins.add(entry);
|
|
1731
|
+
} else for (const { plugin, hrStart } of generatorPlugins) {
|
|
1732
|
+
const duration = getElapsedMs(hrStart);
|
|
1733
|
+
pluginTimings.set(plugin.name, duration);
|
|
1734
|
+
await this.#emitPluginEnd({
|
|
1735
|
+
plugin,
|
|
1736
|
+
duration,
|
|
1737
|
+
success: true
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1740
|
+
await hooks.emit("kubb:plugins:end", Object.assign({ config }, this.#filesPayload()));
|
|
1741
|
+
await flushPending();
|
|
1742
|
+
const files = this.fileManager.files;
|
|
1743
|
+
await hooks.emit("kubb:build:end", {
|
|
1744
|
+
files,
|
|
1745
|
+
config,
|
|
1746
|
+
outputDir: (0, node_path.resolve)(config.root, config.output.path)
|
|
1747
|
+
});
|
|
1748
|
+
return {
|
|
1749
|
+
failedPlugins,
|
|
1750
|
+
pluginTimings
|
|
1751
|
+
};
|
|
1752
|
+
} catch (caughtError) {
|
|
1753
|
+
return {
|
|
1754
|
+
failedPlugins,
|
|
1755
|
+
pluginTimings,
|
|
1756
|
+
error: caughtError
|
|
1757
|
+
};
|
|
1758
|
+
} finally {
|
|
1759
|
+
this.fileManager.setOnUpsert(null);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
#filesPayload() {
|
|
1763
|
+
const driver = this;
|
|
1764
|
+
return {
|
|
1765
|
+
get files() {
|
|
1766
|
+
return driver.fileManager.files;
|
|
1767
|
+
},
|
|
1768
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
#emitPluginEnd({ plugin, duration, success, error }) {
|
|
1772
|
+
return this.hooks.emit("kubb:plugin:end", Object.assign({
|
|
1773
|
+
plugin,
|
|
1774
|
+
duration,
|
|
1775
|
+
success,
|
|
1776
|
+
...error ? { error } : {},
|
|
1777
|
+
config: this.config
|
|
1778
|
+
}, this.#filesPayload()));
|
|
1779
|
+
}
|
|
1780
|
+
async #runGenerators(entries, flushPending) {
|
|
1781
|
+
const timings = /* @__PURE__ */ new Map();
|
|
1782
|
+
const failed = /* @__PURE__ */ new Set();
|
|
1783
|
+
const driver = this;
|
|
1784
|
+
const { schemas, operations } = this.inputNode;
|
|
1785
|
+
const states = entries.map(({ plugin, context, hrStart }) => {
|
|
1786
|
+
const { exclude, include, override } = plugin.options;
|
|
1787
|
+
const hasExclude = Array.isArray(exclude) && exclude.length > 0;
|
|
1788
|
+
const hasInclude = Array.isArray(include) && include.length > 0;
|
|
1789
|
+
const hasOverride = Array.isArray(override) && override.length > 0;
|
|
1790
|
+
return {
|
|
1791
|
+
plugin,
|
|
1792
|
+
generatorContext: {
|
|
1793
|
+
...context,
|
|
1794
|
+
resolver: this.getResolver(plugin.name)
|
|
1795
|
+
},
|
|
1796
|
+
generators: plugin.generators ?? [],
|
|
1797
|
+
hrStart,
|
|
1798
|
+
failed: false,
|
|
1799
|
+
error: null,
|
|
1800
|
+
optionsAreStatic: !hasExclude && !hasInclude && !hasOverride,
|
|
1801
|
+
allowedSchemaNames: null
|
|
1802
|
+
};
|
|
1803
|
+
});
|
|
1804
|
+
const emitsSchemaHook = this.hooks.listenerCount("kubb:generate:schema") > 0;
|
|
1805
|
+
const emitsOperationHook = this.hooks.listenerCount("kubb:generate:operation") > 0;
|
|
1806
|
+
const pruningStates = states.filter(({ plugin }) => {
|
|
1807
|
+
const { include } = plugin.options;
|
|
1808
|
+
return (include?.some(({ type }) => OPERATION_FILTER_TYPES.has(type)) ?? false) && !(include?.some(({ type }) => type === "schemaName") ?? false);
|
|
1809
|
+
});
|
|
1810
|
+
if (pruningStates.length > 0) {
|
|
1811
|
+
const allSchemas = [];
|
|
1812
|
+
for await (const schema of schemas) allSchemas.push(schema);
|
|
1813
|
+
const includedOpsByState = new Map(pruningStates.map((s) => [s, []]));
|
|
1814
|
+
for await (const operation of operations) for (const state of pruningStates) {
|
|
1815
|
+
const { exclude, include, override } = state.plugin.options;
|
|
1816
|
+
if (state.generatorContext.resolver.resolveOptions(operation, {
|
|
1817
|
+
options: state.plugin.options,
|
|
1818
|
+
exclude,
|
|
1819
|
+
include,
|
|
1820
|
+
override
|
|
1821
|
+
}) !== null) includedOpsByState.get(state)?.push(operation);
|
|
1822
|
+
}
|
|
1823
|
+
for (const state of pruningStates) {
|
|
1824
|
+
state.allowedSchemaNames = (0, _kubb_ast.collectUsedSchemaNames)(includedOpsByState.get(state) ?? [], allSchemas);
|
|
1825
|
+
includedOpsByState.delete(state);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
const resolveRendererFor = (gen, state) => gen.renderer === null ? void 0 : gen.renderer ?? state.plugin.renderer ?? state.generatorContext.config.renderer;
|
|
1829
|
+
const dispatchSchema = async (state, node) => {
|
|
1830
|
+
if (state.failed) return;
|
|
1831
|
+
try {
|
|
1832
|
+
const { plugin, generatorContext, generators } = state;
|
|
1833
|
+
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
1834
|
+
if (state.allowedSchemaNames !== null && transformedNode.name && !state.allowedSchemaNames.has(transformedNode.name)) return;
|
|
1835
|
+
const { exclude, include, override } = plugin.options;
|
|
1836
|
+
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
1837
|
+
options: plugin.options,
|
|
1838
|
+
exclude,
|
|
1839
|
+
include,
|
|
1840
|
+
override
|
|
1841
|
+
});
|
|
1842
|
+
if (options === null) return;
|
|
1843
|
+
const ctx = {
|
|
1844
|
+
...generatorContext,
|
|
1845
|
+
options
|
|
1846
|
+
};
|
|
1847
|
+
for (const gen of generators) {
|
|
1848
|
+
if (!gen.schema) continue;
|
|
1849
|
+
const raw = gen.schema(transformedNode, ctx);
|
|
1850
|
+
const applied = applyHookResult({
|
|
1851
|
+
result: isPromise(raw) ? await raw : raw,
|
|
1852
|
+
driver,
|
|
1853
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
1854
|
+
});
|
|
1855
|
+
if (isPromise(applied)) await applied;
|
|
1856
|
+
}
|
|
1857
|
+
if (emitsSchemaHook) await this.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
1858
|
+
} catch (caughtError) {
|
|
1859
|
+
state.failed = true;
|
|
1860
|
+
state.error = caughtError;
|
|
1861
|
+
}
|
|
1862
|
+
};
|
|
1863
|
+
const dispatchOperation = async (state, node) => {
|
|
1864
|
+
if (state.failed) return;
|
|
1865
|
+
try {
|
|
1866
|
+
const { plugin, generatorContext, generators } = state;
|
|
1867
|
+
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
1868
|
+
const { exclude, include, override } = plugin.options;
|
|
1869
|
+
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
1870
|
+
options: plugin.options,
|
|
1871
|
+
exclude,
|
|
1872
|
+
include,
|
|
1873
|
+
override
|
|
1874
|
+
});
|
|
1875
|
+
if (options === null) return;
|
|
1876
|
+
const ctx = {
|
|
1877
|
+
...generatorContext,
|
|
1878
|
+
options
|
|
1879
|
+
};
|
|
1880
|
+
for (const gen of generators) {
|
|
1881
|
+
if (!gen.operation) continue;
|
|
1882
|
+
const raw = gen.operation(transformedNode, ctx);
|
|
1883
|
+
const applied = applyHookResult({
|
|
1884
|
+
result: isPromise(raw) ? await raw : raw,
|
|
1885
|
+
driver,
|
|
1886
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
1887
|
+
});
|
|
1888
|
+
if (isPromise(applied)) await applied;
|
|
1889
|
+
}
|
|
1890
|
+
if (emitsOperationHook) await this.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
1891
|
+
} catch (caughtError) {
|
|
1892
|
+
state.failed = true;
|
|
1893
|
+
state.error = caughtError;
|
|
1894
|
+
}
|
|
1895
|
+
};
|
|
1896
|
+
const needsCollectedOperations = this.hooks.listenerCount("kubb:generate:operations") > 0 || states.some((s) => s.generators.some((g) => !!g.operations));
|
|
1897
|
+
const collectedOperations = needsCollectedOperations ? [] : void 0;
|
|
1898
|
+
await forBatches(schemas, (nodes) => Promise.all(nodes.flatMap((n) => states.map((state) => dispatchSchema(state, n)))), {
|
|
1899
|
+
concurrency: 8,
|
|
1900
|
+
flush: flushPending
|
|
1901
|
+
});
|
|
1902
|
+
await forBatches(operations, (nodes) => {
|
|
1903
|
+
if (needsCollectedOperations) collectedOperations.push(...nodes);
|
|
1904
|
+
return Promise.all(nodes.flatMap((n) => states.map((state) => dispatchOperation(state, n))));
|
|
1905
|
+
}, {
|
|
1906
|
+
concurrency: 8,
|
|
1907
|
+
flush: flushPending
|
|
1908
|
+
});
|
|
1909
|
+
for (const state of states) {
|
|
1910
|
+
if (!state.failed && needsCollectedOperations) try {
|
|
1911
|
+
const { plugin, generatorContext, generators } = state;
|
|
1912
|
+
const ctx = {
|
|
1913
|
+
...generatorContext,
|
|
1914
|
+
options: plugin.options
|
|
1915
|
+
};
|
|
1916
|
+
for (const gen of generators) {
|
|
1917
|
+
if (!gen.operations) continue;
|
|
1918
|
+
await applyHookResult({
|
|
1919
|
+
result: await gen.operations(collectedOperations, ctx),
|
|
1920
|
+
driver,
|
|
1921
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
1922
|
+
});
|
|
1923
|
+
}
|
|
1924
|
+
await this.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
1925
|
+
} catch (caughtError) {
|
|
1926
|
+
state.failed = true;
|
|
1927
|
+
state.error = caughtError;
|
|
1928
|
+
}
|
|
1929
|
+
const duration = getElapsedMs(state.hrStart);
|
|
1930
|
+
timings.set(state.plugin.name, duration);
|
|
1931
|
+
await this.#emitPluginEnd({
|
|
1932
|
+
plugin: state.plugin,
|
|
1933
|
+
duration,
|
|
1934
|
+
success: !state.failed,
|
|
1935
|
+
error: state.failed && state.error ? state.error : void 0
|
|
1936
|
+
});
|
|
1937
|
+
if (state.failed && state.error) failed.add({
|
|
1938
|
+
plugin: state.plugin,
|
|
1939
|
+
error: state.error
|
|
1940
|
+
});
|
|
1941
|
+
await this.hooks.emit("kubb:debug", {
|
|
1942
|
+
date: /* @__PURE__ */ new Date(),
|
|
1943
|
+
logs: [state.failed ? "✗ Plugin start failed" : `✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
return {
|
|
1947
|
+
timings,
|
|
1948
|
+
failed
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
/**
|
|
1331
1952
|
* Unregisters all plugin lifecycle listeners from the shared event emitter.
|
|
1332
1953
|
* Called at the end of a build to prevent listener leaks across repeated builds.
|
|
1333
1954
|
*
|
|
@@ -1340,11 +1961,12 @@ var KubbDriver = class KubbDriver {
|
|
|
1340
1961
|
this.#resolvers.clear();
|
|
1341
1962
|
this.#defaultResolvers.clear();
|
|
1342
1963
|
this.fileManager.dispose();
|
|
1343
|
-
this.
|
|
1964
|
+
this.#fileProcessor.dispose();
|
|
1965
|
+
this.inputNode = null;
|
|
1344
1966
|
this.#studio = {
|
|
1345
|
-
source:
|
|
1967
|
+
source: null,
|
|
1346
1968
|
isOpen: false,
|
|
1347
|
-
inputNode:
|
|
1969
|
+
inputNode: null
|
|
1348
1970
|
};
|
|
1349
1971
|
for (const [event, handler] of this.#middlewareListeners) this.hooks.off(event, handler);
|
|
1350
1972
|
}
|
|
@@ -1464,10 +2086,15 @@ function applyHookResult({ result, driver, rendererFactory }) {
|
|
|
1464
2086
|
}
|
|
1465
2087
|
if (!rendererFactory) return;
|
|
1466
2088
|
const renderer = rendererFactory();
|
|
1467
|
-
if (renderer.stream) {
|
|
1468
|
-
|
|
1469
|
-
|
|
2089
|
+
if (renderer.stream) try {
|
|
2090
|
+
var _usingCtx$1 = _usingCtx();
|
|
2091
|
+
const r = _usingCtx$1.u(renderer);
|
|
2092
|
+
for (const file of r.stream(result)) driver.fileManager.upsert(file);
|
|
1470
2093
|
return;
|
|
2094
|
+
} catch (_) {
|
|
2095
|
+
_usingCtx$1.e = _;
|
|
2096
|
+
} finally {
|
|
2097
|
+
_usingCtx$1.d();
|
|
1471
2098
|
}
|
|
1472
2099
|
return applyAsyncRender({
|
|
1473
2100
|
renderer,
|
|
@@ -1476,9 +2103,16 @@ function applyHookResult({ result, driver, rendererFactory }) {
|
|
|
1476
2103
|
});
|
|
1477
2104
|
}
|
|
1478
2105
|
async function applyAsyncRender({ renderer, result, driver }) {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
2106
|
+
try {
|
|
2107
|
+
var _usingCtx3 = _usingCtx();
|
|
2108
|
+
const r = _usingCtx3.u(renderer);
|
|
2109
|
+
await r.render(result);
|
|
2110
|
+
driver.fileManager.upsert(...r.files);
|
|
2111
|
+
} catch (_) {
|
|
2112
|
+
_usingCtx3.e = _;
|
|
2113
|
+
} finally {
|
|
2114
|
+
_usingCtx3.d();
|
|
2115
|
+
}
|
|
1482
2116
|
}
|
|
1483
2117
|
function inputToAdapterSource(config) {
|
|
1484
2118
|
const input = config.input;
|
|
@@ -1497,6 +2131,18 @@ function inputToAdapterSource(config) {
|
|
|
1497
2131
|
};
|
|
1498
2132
|
}
|
|
1499
2133
|
//#endregion
|
|
2134
|
+
Object.defineProperty(exports, "AsyncEventEmitter", {
|
|
2135
|
+
enumerable: true,
|
|
2136
|
+
get: function() {
|
|
2137
|
+
return AsyncEventEmitter;
|
|
2138
|
+
}
|
|
2139
|
+
});
|
|
2140
|
+
Object.defineProperty(exports, "BuildError", {
|
|
2141
|
+
enumerable: true,
|
|
2142
|
+
get: function() {
|
|
2143
|
+
return BuildError;
|
|
2144
|
+
}
|
|
2145
|
+
});
|
|
1500
2146
|
Object.defineProperty(exports, "DEFAULT_BANNER", {
|
|
1501
2147
|
enumerable: true,
|
|
1502
2148
|
get: function() {
|
|
@@ -1521,6 +2167,12 @@ Object.defineProperty(exports, "FileManager", {
|
|
|
1521
2167
|
return FileManager;
|
|
1522
2168
|
}
|
|
1523
2169
|
});
|
|
2170
|
+
Object.defineProperty(exports, "FileProcessor", {
|
|
2171
|
+
enumerable: true,
|
|
2172
|
+
get: function() {
|
|
2173
|
+
return FileProcessor;
|
|
2174
|
+
}
|
|
2175
|
+
});
|
|
1524
2176
|
Object.defineProperty(exports, "KubbDriver", {
|
|
1525
2177
|
enumerable: true,
|
|
1526
2178
|
get: function() {
|
|
@@ -1545,6 +2197,12 @@ Object.defineProperty(exports, "__toESM", {
|
|
|
1545
2197
|
return __toESM;
|
|
1546
2198
|
}
|
|
1547
2199
|
});
|
|
2200
|
+
Object.defineProperty(exports, "_usingCtx", {
|
|
2201
|
+
enumerable: true,
|
|
2202
|
+
get: function() {
|
|
2203
|
+
return _usingCtx;
|
|
2204
|
+
}
|
|
2205
|
+
});
|
|
1548
2206
|
Object.defineProperty(exports, "applyHookResult", {
|
|
1549
2207
|
enumerable: true,
|
|
1550
2208
|
get: function() {
|
|
@@ -1563,29 +2221,11 @@ Object.defineProperty(exports, "defineResolver", {
|
|
|
1563
2221
|
return defineResolver;
|
|
1564
2222
|
}
|
|
1565
2223
|
});
|
|
1566
|
-
Object.defineProperty(exports, "forBatches", {
|
|
1567
|
-
enumerable: true,
|
|
1568
|
-
get: function() {
|
|
1569
|
-
return forBatches;
|
|
1570
|
-
}
|
|
1571
|
-
});
|
|
1572
|
-
Object.defineProperty(exports, "isPromise", {
|
|
1573
|
-
enumerable: true,
|
|
1574
|
-
get: function() {
|
|
1575
|
-
return isPromise;
|
|
1576
|
-
}
|
|
1577
|
-
});
|
|
1578
2224
|
Object.defineProperty(exports, "logLevel", {
|
|
1579
2225
|
enumerable: true,
|
|
1580
2226
|
get: function() {
|
|
1581
2227
|
return logLevel;
|
|
1582
2228
|
}
|
|
1583
2229
|
});
|
|
1584
|
-
Object.defineProperty(exports, "withDrain", {
|
|
1585
|
-
enumerable: true,
|
|
1586
|
-
get: function() {
|
|
1587
|
-
return withDrain;
|
|
1588
|
-
}
|
|
1589
|
-
});
|
|
1590
2230
|
|
|
1591
|
-
//# sourceMappingURL=KubbDriver-
|
|
2231
|
+
//# sourceMappingURL=KubbDriver-BBRa5CH2.cjs.map
|