@kubb/core 5.0.0-beta.20 → 5.0.0-beta.22
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-DLha_xyo.cjs} +759 -108
- package/dist/KubbDriver-DLha_xyo.cjs.map +1 -0
- package/dist/{KubbDriver-Cxii_rBp.js → KubbDriver-l31wllgN.js} +737 -92
- package/dist/KubbDriver-l31wllgN.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 +3 -3
- 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 +368 -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
|
|
@@ -430,12 +591,13 @@ var URLPath = class {
|
|
|
430
591
|
* @example
|
|
431
592
|
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
432
593
|
*/
|
|
433
|
-
toTemplateString({ prefix
|
|
434
|
-
|
|
594
|
+
toTemplateString({ prefix, replacer } = {}) {
|
|
595
|
+
const result = this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
435
596
|
if (i % 2 === 0) return part;
|
|
436
597
|
const param = this.#transformParam(part);
|
|
437
598
|
return `\${${replacer ? replacer(param) : param}}`;
|
|
438
|
-
}).join("")
|
|
599
|
+
}).join("");
|
|
600
|
+
return `\`${prefix ?? ""}${result}\``;
|
|
439
601
|
}
|
|
440
602
|
/**
|
|
441
603
|
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
@@ -813,13 +975,13 @@ function buildDefaultBanner({ title, description, version, config }) {
|
|
|
813
975
|
* @example Disabled default banner
|
|
814
976
|
* ```ts
|
|
815
977
|
* defaultResolveBanner(undefined, { config: { output: { defaultBanner: false }, ...config } })
|
|
816
|
-
* // →
|
|
978
|
+
* // → null
|
|
817
979
|
* ```
|
|
818
980
|
*/
|
|
819
981
|
function defaultResolveBanner(meta, { output, config }) {
|
|
820
982
|
if (typeof output?.banner === "function") return output.banner(meta);
|
|
821
983
|
if (typeof output?.banner === "string") return output.banner;
|
|
822
|
-
if (config.output.defaultBanner === false) return;
|
|
984
|
+
if (config.output.defaultBanner === false) return null;
|
|
823
985
|
return buildDefaultBanner({
|
|
824
986
|
title: meta?.title,
|
|
825
987
|
version: meta?.version,
|
|
@@ -848,6 +1010,7 @@ function defaultResolveBanner(meta, { output, config }) {
|
|
|
848
1010
|
function defaultResolveFooter(meta, { output }) {
|
|
849
1011
|
if (typeof output?.footer === "function") return output.footer(meta);
|
|
850
1012
|
if (typeof output?.footer === "string") return output.footer;
|
|
1013
|
+
return null;
|
|
851
1014
|
}
|
|
852
1015
|
/**
|
|
853
1016
|
* Defines a resolver for a plugin, injecting built-in defaults for name casing,
|
|
@@ -958,111 +1121,241 @@ function mergeFile(a, b) {
|
|
|
958
1121
|
...a,
|
|
959
1122
|
banner: b.banner,
|
|
960
1123
|
footer: b.footer,
|
|
961
|
-
sources:
|
|
962
|
-
imports:
|
|
963
|
-
exports:
|
|
1124
|
+
sources: a.sources.length ? b.sources.length ? [...a.sources, ...b.sources] : a.sources : b.sources,
|
|
1125
|
+
imports: a.imports.length ? b.imports.length ? [...a.imports, ...b.imports] : a.imports : b.imports,
|
|
1126
|
+
exports: a.exports.length ? b.exports.length ? [...a.exports, ...b.exports] : a.exports : b.exports
|
|
964
1127
|
};
|
|
965
1128
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return
|
|
1129
|
+
function isIndexPath(path) {
|
|
1130
|
+
return path.endsWith("/index.ts") || path === "index.ts";
|
|
1131
|
+
}
|
|
1132
|
+
function compareFiles(a, b) {
|
|
1133
|
+
const lenDiff = a.path.length - b.path.length;
|
|
1134
|
+
if (lenDiff !== 0) return lenDiff;
|
|
1135
|
+
const aIsIndex = isIndexPath(a.path);
|
|
1136
|
+
const bIsIndex = isIndexPath(b.path);
|
|
1137
|
+
if (aIsIndex && !bIsIndex) return 1;
|
|
1138
|
+
if (!aIsIndex && bIsIndex) return -1;
|
|
1139
|
+
return 0;
|
|
977
1140
|
}
|
|
978
1141
|
/**
|
|
979
|
-
* In-memory file store for generated files.
|
|
980
|
-
*
|
|
981
|
-
*
|
|
982
|
-
* The `files` getter returns all stored files sorted by path length (shortest first).
|
|
1142
|
+
* In-memory file store for generated files. Files sharing a `path` are merged
|
|
1143
|
+
* (sources/imports/exports concatenated). The `files` getter is sorted by
|
|
1144
|
+
* path length (barrel `index.ts` last within a bucket).
|
|
983
1145
|
*
|
|
984
1146
|
* @example
|
|
985
1147
|
* ```ts
|
|
986
|
-
* import { FileManager } from '@kubb/core'
|
|
987
|
-
*
|
|
988
1148
|
* const manager = new FileManager()
|
|
989
1149
|
* manager.upsert(myFile)
|
|
990
|
-
*
|
|
1150
|
+
* manager.files // sorted view
|
|
991
1151
|
* ```
|
|
992
1152
|
*/
|
|
993
1153
|
var FileManager = class {
|
|
994
1154
|
#cache = /* @__PURE__ */ new Map();
|
|
995
|
-
#
|
|
1155
|
+
#sorted = null;
|
|
1156
|
+
#onUpsert = null;
|
|
996
1157
|
/**
|
|
997
|
-
*
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1158
|
+
* Registers a callback invoked with the resolved {@link FileNode} on every
|
|
1159
|
+
* `add` / `upsert`. Used by the build loop to track newly written files
|
|
1160
|
+
* without keeping its own scan-based diff. Single subscriber by design —
|
|
1161
|
+
* setting again replaces the previous callback. Pass `null` to detach.
|
|
1000
1162
|
*/
|
|
1163
|
+
setOnUpsert(callback) {
|
|
1164
|
+
this.#onUpsert = callback;
|
|
1165
|
+
}
|
|
1001
1166
|
add(...files) {
|
|
1002
1167
|
return this.#store(files, false);
|
|
1003
1168
|
}
|
|
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
1169
|
upsert(...files) {
|
|
1010
1170
|
return this.#store(files, true);
|
|
1011
1171
|
}
|
|
1012
1172
|
#store(files, mergeExisting) {
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const
|
|
1017
|
-
|
|
1018
|
-
|
|
1173
|
+
const batch = files.length > 1 ? this.#dedupe(files) : files;
|
|
1174
|
+
const resolved = [];
|
|
1175
|
+
for (const file of batch) {
|
|
1176
|
+
const existing = this.#cache.get(file.path);
|
|
1177
|
+
const merged = existing && mergeExisting ? (0, _kubb_ast.createFile)(mergeFile(existing, file)) : (0, _kubb_ast.createFile)(file);
|
|
1178
|
+
this.#cache.set(merged.path, merged);
|
|
1179
|
+
resolved.push(merged);
|
|
1180
|
+
this.#onUpsert?.(merged);
|
|
1181
|
+
}
|
|
1182
|
+
if (resolved.length > 0) this.#sorted = null;
|
|
1183
|
+
return resolved;
|
|
1184
|
+
}
|
|
1185
|
+
#dedupe(files) {
|
|
1186
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1187
|
+
for (const file of files) {
|
|
1188
|
+
const prev = seen.get(file.path);
|
|
1189
|
+
seen.set(file.path, prev ? mergeFile(prev, file) : file);
|
|
1019
1190
|
}
|
|
1020
|
-
|
|
1021
|
-
return resolvedFiles;
|
|
1191
|
+
return [...seen.values()];
|
|
1022
1192
|
}
|
|
1023
1193
|
getByPath(path) {
|
|
1024
1194
|
return this.#cache.get(path) ?? null;
|
|
1025
1195
|
}
|
|
1026
1196
|
deleteByPath(path) {
|
|
1027
|
-
this.#cache.delete(path);
|
|
1028
|
-
this.#
|
|
1197
|
+
if (!this.#cache.delete(path)) return;
|
|
1198
|
+
this.#sorted = null;
|
|
1029
1199
|
}
|
|
1030
1200
|
clear() {
|
|
1031
1201
|
this.#cache.clear();
|
|
1032
|
-
this.#
|
|
1202
|
+
this.#sorted = null;
|
|
1033
1203
|
}
|
|
1034
1204
|
/**
|
|
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.
|
|
1205
|
+
* Releases all stored files. Called by the core after `kubb:build:end`.
|
|
1037
1206
|
*/
|
|
1038
1207
|
dispose() {
|
|
1039
1208
|
this.clear();
|
|
1209
|
+
this.#onUpsert = null;
|
|
1040
1210
|
}
|
|
1041
1211
|
[Symbol.dispose]() {
|
|
1042
1212
|
this.dispose();
|
|
1043
1213
|
}
|
|
1044
1214
|
/**
|
|
1045
|
-
* All stored files
|
|
1215
|
+
* All stored files in stable sort order (shortest path first, barrel files
|
|
1216
|
+
* last within a length bucket). Returns a cached view — do not mutate.
|
|
1046
1217
|
*/
|
|
1047
1218
|
get files() {
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1219
|
+
return this.#sorted ??= [...this.#cache.values()].sort(compareFiles);
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
//#endregion
|
|
1223
|
+
//#region src/FileProcessor.ts
|
|
1224
|
+
function joinSources(file) {
|
|
1225
|
+
const sources = file.sources;
|
|
1226
|
+
if (sources.length === 0) return "";
|
|
1227
|
+
const parts = [];
|
|
1228
|
+
for (const source of sources) {
|
|
1229
|
+
const s = (0, _kubb_ast.extractStringsFromNodes)(source.nodes);
|
|
1230
|
+
if (s) parts.push(s);
|
|
1231
|
+
}
|
|
1232
|
+
return parts.join("\n\n");
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Converts a single file to a string using the registered parsers.
|
|
1236
|
+
* Falls back to joining source values when no matching parser is found.
|
|
1237
|
+
*
|
|
1238
|
+
* @internal
|
|
1239
|
+
*/
|
|
1240
|
+
var FileProcessor = class {
|
|
1241
|
+
events = new AsyncEventEmitter();
|
|
1242
|
+
parse(file, { parsers, extension } = {}) {
|
|
1243
|
+
const parseExtName = extension?.[file.extname] || void 0;
|
|
1244
|
+
if (!parsers || !file.extname) return joinSources(file);
|
|
1245
|
+
const parser = parsers.get(file.extname);
|
|
1246
|
+
if (!parser) return joinSources(file);
|
|
1247
|
+
return parser.parse(file, { extname: parseExtName });
|
|
1248
|
+
}
|
|
1249
|
+
*stream(files, options = {}) {
|
|
1250
|
+
const total = files.length;
|
|
1251
|
+
if (total === 0) return;
|
|
1252
|
+
let processed = 0;
|
|
1253
|
+
for (const file of files) {
|
|
1254
|
+
const source = this.parse(file, options);
|
|
1255
|
+
processed++;
|
|
1256
|
+
yield {
|
|
1257
|
+
file,
|
|
1258
|
+
source,
|
|
1259
|
+
processed,
|
|
1260
|
+
total,
|
|
1261
|
+
percentage: processed / total * 100
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
async run(files, options = {}) {
|
|
1266
|
+
await this.events.emit("start", files);
|
|
1267
|
+
for (const { file, source, processed, total, percentage } of this.stream(files, options)) await this.events.emit("update", {
|
|
1268
|
+
file,
|
|
1269
|
+
source,
|
|
1270
|
+
processed,
|
|
1271
|
+
percentage,
|
|
1272
|
+
total
|
|
1057
1273
|
});
|
|
1058
|
-
|
|
1274
|
+
await this.events.emit("end", files);
|
|
1275
|
+
return files;
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Clears all registered event listeners.
|
|
1279
|
+
*/
|
|
1280
|
+
dispose() {
|
|
1281
|
+
this.events.removeAll();
|
|
1282
|
+
}
|
|
1283
|
+
[Symbol.dispose]() {
|
|
1284
|
+
this.dispose();
|
|
1059
1285
|
}
|
|
1060
1286
|
};
|
|
1061
1287
|
//#endregion
|
|
1288
|
+
//#region \0@oxc-project+runtime@0.129.0/helpers/usingCtx.js
|
|
1289
|
+
function _usingCtx() {
|
|
1290
|
+
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
1291
|
+
var n = Error();
|
|
1292
|
+
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
1293
|
+
};
|
|
1294
|
+
var e = {};
|
|
1295
|
+
var n = [];
|
|
1296
|
+
function using(r, e) {
|
|
1297
|
+
if (null != e) {
|
|
1298
|
+
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
1299
|
+
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
1300
|
+
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
1301
|
+
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
1302
|
+
t && (o = function o() {
|
|
1303
|
+
try {
|
|
1304
|
+
t.call(e);
|
|
1305
|
+
} catch (r) {
|
|
1306
|
+
return Promise.reject(r);
|
|
1307
|
+
}
|
|
1308
|
+
}), n.push({
|
|
1309
|
+
v: e,
|
|
1310
|
+
d: o,
|
|
1311
|
+
a: r
|
|
1312
|
+
});
|
|
1313
|
+
} else r && n.push({
|
|
1314
|
+
d: e,
|
|
1315
|
+
a: r
|
|
1316
|
+
});
|
|
1317
|
+
return e;
|
|
1318
|
+
}
|
|
1319
|
+
return {
|
|
1320
|
+
e,
|
|
1321
|
+
u: using.bind(null, !1),
|
|
1322
|
+
a: using.bind(null, !0),
|
|
1323
|
+
d: function d() {
|
|
1324
|
+
var o;
|
|
1325
|
+
var t = this.e;
|
|
1326
|
+
var s = 0;
|
|
1327
|
+
function next() {
|
|
1328
|
+
for (; o = n.pop();) try {
|
|
1329
|
+
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
1330
|
+
if (o.d) {
|
|
1331
|
+
var r = o.d.call(o.v);
|
|
1332
|
+
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
1333
|
+
} else s |= 1;
|
|
1334
|
+
} catch (r) {
|
|
1335
|
+
return err(r);
|
|
1336
|
+
}
|
|
1337
|
+
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
1338
|
+
if (t !== e) throw t;
|
|
1339
|
+
}
|
|
1340
|
+
function err(n) {
|
|
1341
|
+
return t = t !== e ? new r(n, t) : n, next();
|
|
1342
|
+
}
|
|
1343
|
+
return next();
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
//#endregion
|
|
1062
1348
|
//#region src/KubbDriver.ts
|
|
1063
1349
|
function enforceOrder(enforce) {
|
|
1064
1350
|
return enforce === "pre" ? -1 : enforce === "post" ? 1 : 0;
|
|
1065
1351
|
}
|
|
1352
|
+
const OPERATION_FILTER_TYPES = new Set([
|
|
1353
|
+
"tag",
|
|
1354
|
+
"operationId",
|
|
1355
|
+
"path",
|
|
1356
|
+
"method",
|
|
1357
|
+
"contentType"
|
|
1358
|
+
]);
|
|
1066
1359
|
var KubbDriver = class KubbDriver {
|
|
1067
1360
|
config;
|
|
1068
1361
|
options;
|
|
@@ -1082,8 +1375,8 @@ var KubbDriver = class KubbDriver {
|
|
|
1082
1375
|
* The streaming `InputStreamNode` produced by the adapter.
|
|
1083
1376
|
* Always set after adapter setup — parse-only adapters are wrapped automatically.
|
|
1084
1377
|
*/
|
|
1085
|
-
inputNode =
|
|
1086
|
-
adapter =
|
|
1378
|
+
inputNode = null;
|
|
1379
|
+
adapter = null;
|
|
1087
1380
|
/**
|
|
1088
1381
|
* Studio session state, kept together so `dispose()` can reset it atomically.
|
|
1089
1382
|
*
|
|
@@ -1094,9 +1387,9 @@ var KubbDriver = class KubbDriver {
|
|
|
1094
1387
|
* per studio session, even when `openInStudio()` is called multiple times.
|
|
1095
1388
|
*/
|
|
1096
1389
|
#studio = {
|
|
1097
|
-
source:
|
|
1390
|
+
source: null,
|
|
1098
1391
|
isOpen: false,
|
|
1099
|
-
inputNode:
|
|
1392
|
+
inputNode: null
|
|
1100
1393
|
};
|
|
1101
1394
|
#middlewareListeners = [];
|
|
1102
1395
|
/**
|
|
@@ -1105,6 +1398,7 @@ var KubbDriver = class KubbDriver {
|
|
|
1105
1398
|
* add files; this property gives direct read/write access when needed.
|
|
1106
1399
|
*/
|
|
1107
1400
|
fileManager = new FileManager();
|
|
1401
|
+
#fileProcessor = new FileProcessor();
|
|
1108
1402
|
plugins = /* @__PURE__ */ new Map();
|
|
1109
1403
|
/**
|
|
1110
1404
|
* Tracks which plugins have generators registered via `addGenerator()` (event-based path).
|
|
@@ -1117,7 +1411,7 @@ var KubbDriver = class KubbDriver {
|
|
|
1117
1411
|
constructor(config, options) {
|
|
1118
1412
|
this.config = config;
|
|
1119
1413
|
this.options = options;
|
|
1120
|
-
this.adapter = config.adapter;
|
|
1414
|
+
this.adapter = config.adapter ?? null;
|
|
1121
1415
|
}
|
|
1122
1416
|
async setup() {
|
|
1123
1417
|
const normalized = this.config.plugins.map((rawPlugin) => this.#normalizePlugin(rawPlugin));
|
|
@@ -1328,6 +1622,344 @@ var KubbDriver = class KubbDriver {
|
|
|
1328
1622
|
return this.#eventGeneratorPlugins.has(pluginName);
|
|
1329
1623
|
}
|
|
1330
1624
|
/**
|
|
1625
|
+
* Runs the full plugin pipeline. Returns timings/failures collected so far even
|
|
1626
|
+
* when an outer hook throws — the orchestrator preserves partial state by capturing
|
|
1627
|
+
* the error into `error` instead of propagating.
|
|
1628
|
+
*/
|
|
1629
|
+
async run({ storage }) {
|
|
1630
|
+
const hooks = this.hooks;
|
|
1631
|
+
const config = this.config;
|
|
1632
|
+
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1633
|
+
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1634
|
+
const parsersMap = /* @__PURE__ */ new Map();
|
|
1635
|
+
for (const parser of config.parsers) if (parser.extNames) for (const ext of parser.extNames) parsersMap.set(ext, parser);
|
|
1636
|
+
const pendingFiles = /* @__PURE__ */ new Map();
|
|
1637
|
+
this.fileManager.setOnUpsert((file) => {
|
|
1638
|
+
pendingFiles.set(file.path, file);
|
|
1639
|
+
});
|
|
1640
|
+
try {
|
|
1641
|
+
const flushPending = async () => {
|
|
1642
|
+
if (pendingFiles.size === 0) return;
|
|
1643
|
+
const files = [...pendingFiles.values()];
|
|
1644
|
+
pendingFiles.clear();
|
|
1645
|
+
await hooks.emit("kubb:debug", {
|
|
1646
|
+
date: /* @__PURE__ */ new Date(),
|
|
1647
|
+
logs: [`Writing ${files.length} files...`]
|
|
1648
|
+
});
|
|
1649
|
+
await hooks.emit("kubb:files:processing:start", { files });
|
|
1650
|
+
const items = [...this.#fileProcessor.stream(files, {
|
|
1651
|
+
parsers: parsersMap,
|
|
1652
|
+
extension: config.output.extension
|
|
1653
|
+
})];
|
|
1654
|
+
await hooks.emit("kubb:files:processing:update", { files: items.map(({ file, source, processed, total, percentage }) => ({
|
|
1655
|
+
file,
|
|
1656
|
+
source,
|
|
1657
|
+
processed,
|
|
1658
|
+
total,
|
|
1659
|
+
percentage,
|
|
1660
|
+
config
|
|
1661
|
+
})) });
|
|
1662
|
+
const queue = [];
|
|
1663
|
+
for (const { file, source } of items) if (source) {
|
|
1664
|
+
queue.push(storage.setItem(file.path, source));
|
|
1665
|
+
if (queue.length >= 50) await Promise.all(queue.splice(0));
|
|
1666
|
+
}
|
|
1667
|
+
await Promise.all(queue);
|
|
1668
|
+
await hooks.emit("kubb:files:processing:end", { files });
|
|
1669
|
+
await hooks.emit("kubb:debug", {
|
|
1670
|
+
date: /* @__PURE__ */ new Date(),
|
|
1671
|
+
logs: [`✓ File write process completed for ${files.length} files`]
|
|
1672
|
+
});
|
|
1673
|
+
};
|
|
1674
|
+
await this.emitSetupHooks();
|
|
1675
|
+
if (this.adapter && this.inputNode) await hooks.emit("kubb:build:start", Object.assign({
|
|
1676
|
+
config,
|
|
1677
|
+
adapter: this.adapter,
|
|
1678
|
+
meta: this.inputNode.meta,
|
|
1679
|
+
getPlugin: this.getPlugin.bind(this)
|
|
1680
|
+
}, this.#filesPayload()));
|
|
1681
|
+
const generatorPlugins = [];
|
|
1682
|
+
for (const plugin of this.plugins.values()) {
|
|
1683
|
+
const context = this.getContext(plugin);
|
|
1684
|
+
const hrStart = process.hrtime();
|
|
1685
|
+
try {
|
|
1686
|
+
await hooks.emit("kubb:plugin:start", { plugin });
|
|
1687
|
+
await hooks.emit("kubb:debug", {
|
|
1688
|
+
date: /* @__PURE__ */ new Date(),
|
|
1689
|
+
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1690
|
+
});
|
|
1691
|
+
} catch (caughtError) {
|
|
1692
|
+
const error = caughtError;
|
|
1693
|
+
const duration = getElapsedMs(hrStart);
|
|
1694
|
+
pluginTimings.set(plugin.name, duration);
|
|
1695
|
+
await this.#emitPluginEnd({
|
|
1696
|
+
plugin,
|
|
1697
|
+
duration,
|
|
1698
|
+
success: false,
|
|
1699
|
+
error
|
|
1700
|
+
});
|
|
1701
|
+
failedPlugins.add({
|
|
1702
|
+
plugin,
|
|
1703
|
+
error
|
|
1704
|
+
});
|
|
1705
|
+
continue;
|
|
1706
|
+
}
|
|
1707
|
+
if (plugin.generators?.length || this.hasEventGenerators(plugin.name)) {
|
|
1708
|
+
generatorPlugins.push({
|
|
1709
|
+
plugin,
|
|
1710
|
+
context,
|
|
1711
|
+
hrStart
|
|
1712
|
+
});
|
|
1713
|
+
continue;
|
|
1714
|
+
}
|
|
1715
|
+
const duration = getElapsedMs(hrStart);
|
|
1716
|
+
pluginTimings.set(plugin.name, duration);
|
|
1717
|
+
await this.#emitPluginEnd({
|
|
1718
|
+
plugin,
|
|
1719
|
+
duration,
|
|
1720
|
+
success: true
|
|
1721
|
+
});
|
|
1722
|
+
await hooks.emit("kubb:debug", {
|
|
1723
|
+
date: /* @__PURE__ */ new Date(),
|
|
1724
|
+
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
if (generatorPlugins.length > 0) if (this.inputNode) {
|
|
1728
|
+
const { timings, failed } = await this.#runGenerators(generatorPlugins, flushPending);
|
|
1729
|
+
await flushPending();
|
|
1730
|
+
for (const [name, duration] of timings) pluginTimings.set(name, duration);
|
|
1731
|
+
for (const entry of failed) failedPlugins.add(entry);
|
|
1732
|
+
} else for (const { plugin, hrStart } of generatorPlugins) {
|
|
1733
|
+
const duration = getElapsedMs(hrStart);
|
|
1734
|
+
pluginTimings.set(plugin.name, duration);
|
|
1735
|
+
await this.#emitPluginEnd({
|
|
1736
|
+
plugin,
|
|
1737
|
+
duration,
|
|
1738
|
+
success: true
|
|
1739
|
+
});
|
|
1740
|
+
}
|
|
1741
|
+
await hooks.emit("kubb:plugins:end", Object.assign({ config }, this.#filesPayload()));
|
|
1742
|
+
await flushPending();
|
|
1743
|
+
const files = this.fileManager.files;
|
|
1744
|
+
await hooks.emit("kubb:build:end", {
|
|
1745
|
+
files,
|
|
1746
|
+
config,
|
|
1747
|
+
outputDir: (0, node_path.resolve)(config.root, config.output.path)
|
|
1748
|
+
});
|
|
1749
|
+
return {
|
|
1750
|
+
failedPlugins,
|
|
1751
|
+
pluginTimings
|
|
1752
|
+
};
|
|
1753
|
+
} catch (caughtError) {
|
|
1754
|
+
return {
|
|
1755
|
+
failedPlugins,
|
|
1756
|
+
pluginTimings,
|
|
1757
|
+
error: caughtError
|
|
1758
|
+
};
|
|
1759
|
+
} finally {
|
|
1760
|
+
this.fileManager.setOnUpsert(null);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
#filesPayload() {
|
|
1764
|
+
const driver = this;
|
|
1765
|
+
return {
|
|
1766
|
+
get files() {
|
|
1767
|
+
return driver.fileManager.files;
|
|
1768
|
+
},
|
|
1769
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
#emitPluginEnd({ plugin, duration, success, error }) {
|
|
1773
|
+
return this.hooks.emit("kubb:plugin:end", Object.assign({
|
|
1774
|
+
plugin,
|
|
1775
|
+
duration,
|
|
1776
|
+
success,
|
|
1777
|
+
...error ? { error } : {},
|
|
1778
|
+
config: this.config
|
|
1779
|
+
}, this.#filesPayload()));
|
|
1780
|
+
}
|
|
1781
|
+
async #runGenerators(entries, flushPending) {
|
|
1782
|
+
const timings = /* @__PURE__ */ new Map();
|
|
1783
|
+
const failed = /* @__PURE__ */ new Set();
|
|
1784
|
+
const driver = this;
|
|
1785
|
+
const { schemas, operations } = this.inputNode;
|
|
1786
|
+
const states = entries.map(({ plugin, context, hrStart }) => {
|
|
1787
|
+
const { exclude, include, override } = plugin.options;
|
|
1788
|
+
const hasExclude = Array.isArray(exclude) && exclude.length > 0;
|
|
1789
|
+
const hasInclude = Array.isArray(include) && include.length > 0;
|
|
1790
|
+
const hasOverride = Array.isArray(override) && override.length > 0;
|
|
1791
|
+
return {
|
|
1792
|
+
plugin,
|
|
1793
|
+
generatorContext: {
|
|
1794
|
+
...context,
|
|
1795
|
+
resolver: this.getResolver(plugin.name)
|
|
1796
|
+
},
|
|
1797
|
+
generators: plugin.generators ?? [],
|
|
1798
|
+
hrStart,
|
|
1799
|
+
failed: false,
|
|
1800
|
+
error: null,
|
|
1801
|
+
optionsAreStatic: !hasExclude && !hasInclude && !hasOverride,
|
|
1802
|
+
allowedSchemaNames: null
|
|
1803
|
+
};
|
|
1804
|
+
});
|
|
1805
|
+
const emitsSchemaHook = this.hooks.listenerCount("kubb:generate:schema") > 0;
|
|
1806
|
+
const emitsOperationHook = this.hooks.listenerCount("kubb:generate:operation") > 0;
|
|
1807
|
+
const pruningStates = states.filter(({ plugin }) => {
|
|
1808
|
+
const { include } = plugin.options;
|
|
1809
|
+
return (include?.some(({ type }) => OPERATION_FILTER_TYPES.has(type)) ?? false) && !(include?.some(({ type }) => type === "schemaName") ?? false);
|
|
1810
|
+
});
|
|
1811
|
+
if (pruningStates.length > 0) {
|
|
1812
|
+
const allSchemas = [];
|
|
1813
|
+
for await (const schema of schemas) allSchemas.push(schema);
|
|
1814
|
+
const includedOpsByState = new Map(pruningStates.map((s) => [s, []]));
|
|
1815
|
+
for await (const operation of operations) for (const state of pruningStates) {
|
|
1816
|
+
const { exclude, include, override } = state.plugin.options;
|
|
1817
|
+
if (state.generatorContext.resolver.resolveOptions(operation, {
|
|
1818
|
+
options: state.plugin.options,
|
|
1819
|
+
exclude,
|
|
1820
|
+
include,
|
|
1821
|
+
override
|
|
1822
|
+
}) !== null) includedOpsByState.get(state)?.push(operation);
|
|
1823
|
+
}
|
|
1824
|
+
for (const state of pruningStates) {
|
|
1825
|
+
state.allowedSchemaNames = (0, _kubb_ast.collectUsedSchemaNames)(includedOpsByState.get(state) ?? [], allSchemas);
|
|
1826
|
+
includedOpsByState.delete(state);
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
const resolveRendererFor = (gen, state) => gen.renderer === null ? void 0 : gen.renderer ?? state.plugin.renderer ?? state.generatorContext.config.renderer;
|
|
1830
|
+
const dispatchSchema = async (state, node) => {
|
|
1831
|
+
if (state.failed) return;
|
|
1832
|
+
try {
|
|
1833
|
+
const { plugin, generatorContext, generators } = state;
|
|
1834
|
+
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
1835
|
+
if (state.allowedSchemaNames !== null && transformedNode.name && !state.allowedSchemaNames.has(transformedNode.name)) return;
|
|
1836
|
+
const { exclude, include, override } = plugin.options;
|
|
1837
|
+
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
1838
|
+
options: plugin.options,
|
|
1839
|
+
exclude,
|
|
1840
|
+
include,
|
|
1841
|
+
override
|
|
1842
|
+
});
|
|
1843
|
+
if (options === null) return;
|
|
1844
|
+
const ctx = {
|
|
1845
|
+
...generatorContext,
|
|
1846
|
+
options
|
|
1847
|
+
};
|
|
1848
|
+
for (const gen of generators) {
|
|
1849
|
+
if (!gen.schema) continue;
|
|
1850
|
+
const raw = gen.schema(transformedNode, ctx);
|
|
1851
|
+
const applied = applyHookResult({
|
|
1852
|
+
result: isPromise(raw) ? await raw : raw,
|
|
1853
|
+
driver,
|
|
1854
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
1855
|
+
});
|
|
1856
|
+
if (isPromise(applied)) await applied;
|
|
1857
|
+
}
|
|
1858
|
+
if (emitsSchemaHook) await this.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
1859
|
+
} catch (caughtError) {
|
|
1860
|
+
state.failed = true;
|
|
1861
|
+
state.error = caughtError;
|
|
1862
|
+
}
|
|
1863
|
+
};
|
|
1864
|
+
const dispatchOperation = async (state, node) => {
|
|
1865
|
+
if (state.failed) return;
|
|
1866
|
+
try {
|
|
1867
|
+
const { plugin, generatorContext, generators } = state;
|
|
1868
|
+
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
1869
|
+
const { exclude, include, override } = plugin.options;
|
|
1870
|
+
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
1871
|
+
options: plugin.options,
|
|
1872
|
+
exclude,
|
|
1873
|
+
include,
|
|
1874
|
+
override
|
|
1875
|
+
});
|
|
1876
|
+
if (options === null) return;
|
|
1877
|
+
const ctx = {
|
|
1878
|
+
...generatorContext,
|
|
1879
|
+
options
|
|
1880
|
+
};
|
|
1881
|
+
for (const gen of generators) {
|
|
1882
|
+
if (!gen.operation) continue;
|
|
1883
|
+
const raw = gen.operation(transformedNode, ctx);
|
|
1884
|
+
const applied = applyHookResult({
|
|
1885
|
+
result: isPromise(raw) ? await raw : raw,
|
|
1886
|
+
driver,
|
|
1887
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
1888
|
+
});
|
|
1889
|
+
if (isPromise(applied)) await applied;
|
|
1890
|
+
}
|
|
1891
|
+
if (emitsOperationHook) await this.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
1892
|
+
} catch (caughtError) {
|
|
1893
|
+
state.failed = true;
|
|
1894
|
+
state.error = caughtError;
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
const needsCollectedOperations = this.hooks.listenerCount("kubb:generate:operations") > 0 || states.some((s) => s.generators.some((g) => !!g.operations));
|
|
1898
|
+
const collectedOperations = needsCollectedOperations ? [] : void 0;
|
|
1899
|
+
await forBatches(schemas, (nodes) => Promise.all(nodes.flatMap((n) => states.map((state) => dispatchSchema(state, n)))), {
|
|
1900
|
+
concurrency: 8,
|
|
1901
|
+
flush: flushPending
|
|
1902
|
+
});
|
|
1903
|
+
await forBatches(operations, (nodes) => {
|
|
1904
|
+
if (needsCollectedOperations) collectedOperations.push(...nodes);
|
|
1905
|
+
return Promise.all(nodes.flatMap((n) => states.map((state) => dispatchOperation(state, n))));
|
|
1906
|
+
}, {
|
|
1907
|
+
concurrency: 8,
|
|
1908
|
+
flush: flushPending
|
|
1909
|
+
});
|
|
1910
|
+
for (const state of states) {
|
|
1911
|
+
if (!state.failed && needsCollectedOperations) try {
|
|
1912
|
+
const { plugin, generatorContext, generators } = state;
|
|
1913
|
+
const ctx = {
|
|
1914
|
+
...generatorContext,
|
|
1915
|
+
options: plugin.options
|
|
1916
|
+
};
|
|
1917
|
+
const pluginOperations = state.optionsAreStatic ? collectedOperations : collectedOperations.filter((node) => {
|
|
1918
|
+
const transformed = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
1919
|
+
const { exclude, include, override } = plugin.options;
|
|
1920
|
+
return generatorContext.resolver.resolveOptions(transformed, {
|
|
1921
|
+
options: plugin.options,
|
|
1922
|
+
exclude,
|
|
1923
|
+
include,
|
|
1924
|
+
override
|
|
1925
|
+
}) !== null;
|
|
1926
|
+
});
|
|
1927
|
+
for (const gen of generators) {
|
|
1928
|
+
if (!gen.operations) continue;
|
|
1929
|
+
await applyHookResult({
|
|
1930
|
+
result: await gen.operations(pluginOperations, ctx),
|
|
1931
|
+
driver,
|
|
1932
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
await this.hooks.emit("kubb:generate:operations", pluginOperations, ctx);
|
|
1936
|
+
} catch (caughtError) {
|
|
1937
|
+
state.failed = true;
|
|
1938
|
+
state.error = caughtError;
|
|
1939
|
+
}
|
|
1940
|
+
const duration = getElapsedMs(state.hrStart);
|
|
1941
|
+
timings.set(state.plugin.name, duration);
|
|
1942
|
+
await this.#emitPluginEnd({
|
|
1943
|
+
plugin: state.plugin,
|
|
1944
|
+
duration,
|
|
1945
|
+
success: !state.failed,
|
|
1946
|
+
error: state.failed && state.error ? state.error : void 0
|
|
1947
|
+
});
|
|
1948
|
+
if (state.failed && state.error) failed.add({
|
|
1949
|
+
plugin: state.plugin,
|
|
1950
|
+
error: state.error
|
|
1951
|
+
});
|
|
1952
|
+
await this.hooks.emit("kubb:debug", {
|
|
1953
|
+
date: /* @__PURE__ */ new Date(),
|
|
1954
|
+
logs: [state.failed ? "✗ Plugin start failed" : `✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
return {
|
|
1958
|
+
timings,
|
|
1959
|
+
failed
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1331
1963
|
* Unregisters all plugin lifecycle listeners from the shared event emitter.
|
|
1332
1964
|
* Called at the end of a build to prevent listener leaks across repeated builds.
|
|
1333
1965
|
*
|
|
@@ -1340,11 +1972,12 @@ var KubbDriver = class KubbDriver {
|
|
|
1340
1972
|
this.#resolvers.clear();
|
|
1341
1973
|
this.#defaultResolvers.clear();
|
|
1342
1974
|
this.fileManager.dispose();
|
|
1343
|
-
this.
|
|
1975
|
+
this.#fileProcessor.dispose();
|
|
1976
|
+
this.inputNode = null;
|
|
1344
1977
|
this.#studio = {
|
|
1345
|
-
source:
|
|
1978
|
+
source: null,
|
|
1346
1979
|
isOpen: false,
|
|
1347
|
-
inputNode:
|
|
1980
|
+
inputNode: null
|
|
1348
1981
|
};
|
|
1349
1982
|
for (const [event, handler] of this.#middlewareListeners) this.hooks.off(event, handler);
|
|
1350
1983
|
}
|
|
@@ -1464,10 +2097,15 @@ function applyHookResult({ result, driver, rendererFactory }) {
|
|
|
1464
2097
|
}
|
|
1465
2098
|
if (!rendererFactory) return;
|
|
1466
2099
|
const renderer = rendererFactory();
|
|
1467
|
-
if (renderer.stream) {
|
|
1468
|
-
|
|
1469
|
-
|
|
2100
|
+
if (renderer.stream) try {
|
|
2101
|
+
var _usingCtx$1 = _usingCtx();
|
|
2102
|
+
const r = _usingCtx$1.u(renderer);
|
|
2103
|
+
for (const file of r.stream(result)) driver.fileManager.upsert(file);
|
|
1470
2104
|
return;
|
|
2105
|
+
} catch (_) {
|
|
2106
|
+
_usingCtx$1.e = _;
|
|
2107
|
+
} finally {
|
|
2108
|
+
_usingCtx$1.d();
|
|
1471
2109
|
}
|
|
1472
2110
|
return applyAsyncRender({
|
|
1473
2111
|
renderer,
|
|
@@ -1476,9 +2114,16 @@ function applyHookResult({ result, driver, rendererFactory }) {
|
|
|
1476
2114
|
});
|
|
1477
2115
|
}
|
|
1478
2116
|
async function applyAsyncRender({ renderer, result, driver }) {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
2117
|
+
try {
|
|
2118
|
+
var _usingCtx3 = _usingCtx();
|
|
2119
|
+
const r = _usingCtx3.u(renderer);
|
|
2120
|
+
await r.render(result);
|
|
2121
|
+
driver.fileManager.upsert(...r.files);
|
|
2122
|
+
} catch (_) {
|
|
2123
|
+
_usingCtx3.e = _;
|
|
2124
|
+
} finally {
|
|
2125
|
+
_usingCtx3.d();
|
|
2126
|
+
}
|
|
1482
2127
|
}
|
|
1483
2128
|
function inputToAdapterSource(config) {
|
|
1484
2129
|
const input = config.input;
|
|
@@ -1497,6 +2142,18 @@ function inputToAdapterSource(config) {
|
|
|
1497
2142
|
};
|
|
1498
2143
|
}
|
|
1499
2144
|
//#endregion
|
|
2145
|
+
Object.defineProperty(exports, "AsyncEventEmitter", {
|
|
2146
|
+
enumerable: true,
|
|
2147
|
+
get: function() {
|
|
2148
|
+
return AsyncEventEmitter;
|
|
2149
|
+
}
|
|
2150
|
+
});
|
|
2151
|
+
Object.defineProperty(exports, "BuildError", {
|
|
2152
|
+
enumerable: true,
|
|
2153
|
+
get: function() {
|
|
2154
|
+
return BuildError;
|
|
2155
|
+
}
|
|
2156
|
+
});
|
|
1500
2157
|
Object.defineProperty(exports, "DEFAULT_BANNER", {
|
|
1501
2158
|
enumerable: true,
|
|
1502
2159
|
get: function() {
|
|
@@ -1521,6 +2178,12 @@ Object.defineProperty(exports, "FileManager", {
|
|
|
1521
2178
|
return FileManager;
|
|
1522
2179
|
}
|
|
1523
2180
|
});
|
|
2181
|
+
Object.defineProperty(exports, "FileProcessor", {
|
|
2182
|
+
enumerable: true,
|
|
2183
|
+
get: function() {
|
|
2184
|
+
return FileProcessor;
|
|
2185
|
+
}
|
|
2186
|
+
});
|
|
1524
2187
|
Object.defineProperty(exports, "KubbDriver", {
|
|
1525
2188
|
enumerable: true,
|
|
1526
2189
|
get: function() {
|
|
@@ -1545,6 +2208,12 @@ Object.defineProperty(exports, "__toESM", {
|
|
|
1545
2208
|
return __toESM;
|
|
1546
2209
|
}
|
|
1547
2210
|
});
|
|
2211
|
+
Object.defineProperty(exports, "_usingCtx", {
|
|
2212
|
+
enumerable: true,
|
|
2213
|
+
get: function() {
|
|
2214
|
+
return _usingCtx;
|
|
2215
|
+
}
|
|
2216
|
+
});
|
|
1548
2217
|
Object.defineProperty(exports, "applyHookResult", {
|
|
1549
2218
|
enumerable: true,
|
|
1550
2219
|
get: function() {
|
|
@@ -1563,29 +2232,11 @@ Object.defineProperty(exports, "defineResolver", {
|
|
|
1563
2232
|
return defineResolver;
|
|
1564
2233
|
}
|
|
1565
2234
|
});
|
|
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
2235
|
Object.defineProperty(exports, "logLevel", {
|
|
1579
2236
|
enumerable: true,
|
|
1580
2237
|
get: function() {
|
|
1581
2238
|
return logLevel;
|
|
1582
2239
|
}
|
|
1583
2240
|
});
|
|
1584
|
-
Object.defineProperty(exports, "withDrain", {
|
|
1585
|
-
enumerable: true,
|
|
1586
|
-
get: function() {
|
|
1587
|
-
return withDrain;
|
|
1588
|
-
}
|
|
1589
|
-
});
|
|
1590
2241
|
|
|
1591
|
-
//# sourceMappingURL=KubbDriver-
|
|
2242
|
+
//# sourceMappingURL=KubbDriver-DLha_xyo.cjs.map
|