@kubb/core 5.0.0-beta.19 → 5.0.0-beta.20
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-DXp767s2.cjs → KubbDriver-BXSnJ3qM.cjs} +546 -102
- package/dist/KubbDriver-BXSnJ3qM.cjs.map +1 -0
- package/dist/{PluginDriver-uNex0SAr.js → KubbDriver-Cxii_rBp.js} +522 -96
- package/dist/KubbDriver-Cxii_rBp.js.map +1 -0
- package/dist/{createKubb-BJGymYhe.d.ts → createKubb-Dcmtjqds.d.ts} +32 -62
- package/dist/index.cjs +257 -684
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +248 -675
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +9 -10
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.ts +5 -5
- package/dist/mocks.js +5 -6
- package/dist/mocks.js.map +1 -1
- package/package.json +4 -4
- package/src/{PluginDriver.ts → KubbDriver.ts} +175 -88
- package/src/constants.ts +4 -4
- package/src/createAdapter.ts +0 -8
- package/src/createKubb.ts +293 -469
- package/src/defineGenerator.ts +9 -8
- package/src/definePlugin.ts +5 -5
- package/src/defineResolver.ts +26 -40
- package/src/index.ts +1 -1
- package/src/mocks.ts +8 -8
- package/dist/PluginDriver-DXp767s2.cjs.map +0 -1
- package/dist/PluginDriver-uNex0SAr.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
|
-
import { a as definePlugin, c as DEFAULT_STUDIO_URL, i as defineResolver, l as logLevel, n as applyHookResult, o as DEFAULT_BANNER, r as FileManager, s as DEFAULT_EXTENSION, t as
|
|
2
|
+
import { a as definePlugin, c as DEFAULT_STUDIO_URL, d as forBatches, f as isPromise, i as defineResolver, l as logLevel, n as applyHookResult, o as DEFAULT_BANNER, p as withDrain, r as FileManager, s as DEFAULT_EXTENSION, t as KubbDriver, u as URLPath } from "./KubbDriver-Cxii_rBp.js";
|
|
3
3
|
import { EventEmitter } from "node:events";
|
|
4
4
|
import { access, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
6
|
import * as ast from "@kubb/ast";
|
|
7
|
-
import { collectUsedSchemaNames, extractStringsFromNodes, transform
|
|
7
|
+
import { collectUsedSchemaNames, extractStringsFromNodes, transform } from "@kubb/ast";
|
|
8
8
|
import { version } from "node:process";
|
|
9
9
|
//#region ../../internals/utils/src/errors.ts
|
|
10
10
|
/**
|
|
@@ -248,268 +248,6 @@ async function clean(path) {
|
|
|
248
248
|
});
|
|
249
249
|
}
|
|
250
250
|
//#endregion
|
|
251
|
-
//#region ../../internals/utils/src/promise.ts
|
|
252
|
-
/** Returns `true` when `result` is a thenable `Promise`.
|
|
253
|
-
*
|
|
254
|
-
* @example
|
|
255
|
-
* ```ts
|
|
256
|
-
* isPromise(Promise.resolve(1)) // true
|
|
257
|
-
* isPromise(42) // false
|
|
258
|
-
* ```
|
|
259
|
-
*/
|
|
260
|
-
function isPromise(result) {
|
|
261
|
-
return result !== null && result !== void 0 && typeof result["then"] === "function";
|
|
262
|
-
}
|
|
263
|
-
//#endregion
|
|
264
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
265
|
-
/**
|
|
266
|
-
* JavaScript and Java reserved words.
|
|
267
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
268
|
-
*/
|
|
269
|
-
const reservedWords = new Set([
|
|
270
|
-
"abstract",
|
|
271
|
-
"arguments",
|
|
272
|
-
"boolean",
|
|
273
|
-
"break",
|
|
274
|
-
"byte",
|
|
275
|
-
"case",
|
|
276
|
-
"catch",
|
|
277
|
-
"char",
|
|
278
|
-
"class",
|
|
279
|
-
"const",
|
|
280
|
-
"continue",
|
|
281
|
-
"debugger",
|
|
282
|
-
"default",
|
|
283
|
-
"delete",
|
|
284
|
-
"do",
|
|
285
|
-
"double",
|
|
286
|
-
"else",
|
|
287
|
-
"enum",
|
|
288
|
-
"eval",
|
|
289
|
-
"export",
|
|
290
|
-
"extends",
|
|
291
|
-
"false",
|
|
292
|
-
"final",
|
|
293
|
-
"finally",
|
|
294
|
-
"float",
|
|
295
|
-
"for",
|
|
296
|
-
"function",
|
|
297
|
-
"goto",
|
|
298
|
-
"if",
|
|
299
|
-
"implements",
|
|
300
|
-
"import",
|
|
301
|
-
"in",
|
|
302
|
-
"instanceof",
|
|
303
|
-
"int",
|
|
304
|
-
"interface",
|
|
305
|
-
"let",
|
|
306
|
-
"long",
|
|
307
|
-
"native",
|
|
308
|
-
"new",
|
|
309
|
-
"null",
|
|
310
|
-
"package",
|
|
311
|
-
"private",
|
|
312
|
-
"protected",
|
|
313
|
-
"public",
|
|
314
|
-
"return",
|
|
315
|
-
"short",
|
|
316
|
-
"static",
|
|
317
|
-
"super",
|
|
318
|
-
"switch",
|
|
319
|
-
"synchronized",
|
|
320
|
-
"this",
|
|
321
|
-
"throw",
|
|
322
|
-
"throws",
|
|
323
|
-
"transient",
|
|
324
|
-
"true",
|
|
325
|
-
"try",
|
|
326
|
-
"typeof",
|
|
327
|
-
"var",
|
|
328
|
-
"void",
|
|
329
|
-
"volatile",
|
|
330
|
-
"while",
|
|
331
|
-
"with",
|
|
332
|
-
"yield",
|
|
333
|
-
"Array",
|
|
334
|
-
"Date",
|
|
335
|
-
"hasOwnProperty",
|
|
336
|
-
"Infinity",
|
|
337
|
-
"isFinite",
|
|
338
|
-
"isNaN",
|
|
339
|
-
"isPrototypeOf",
|
|
340
|
-
"length",
|
|
341
|
-
"Math",
|
|
342
|
-
"name",
|
|
343
|
-
"NaN",
|
|
344
|
-
"Number",
|
|
345
|
-
"Object",
|
|
346
|
-
"prototype",
|
|
347
|
-
"String",
|
|
348
|
-
"toString",
|
|
349
|
-
"undefined",
|
|
350
|
-
"valueOf"
|
|
351
|
-
]);
|
|
352
|
-
/**
|
|
353
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* ```ts
|
|
357
|
-
* isValidVarName('status') // true
|
|
358
|
-
* isValidVarName('class') // false (reserved word)
|
|
359
|
-
* isValidVarName('42foo') // false (starts with digit)
|
|
360
|
-
* ```
|
|
361
|
-
*/
|
|
362
|
-
function isValidVarName(name) {
|
|
363
|
-
if (!name || reservedWords.has(name)) return false;
|
|
364
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
365
|
-
}
|
|
366
|
-
//#endregion
|
|
367
|
-
//#region ../../internals/utils/src/urlPath.ts
|
|
368
|
-
/**
|
|
369
|
-
* Parses and transforms an OpenAPI/Swagger path string into various URL formats.
|
|
370
|
-
*
|
|
371
|
-
* @example
|
|
372
|
-
* const p = new URLPath('/pet/{petId}')
|
|
373
|
-
* p.URL // '/pet/:petId'
|
|
374
|
-
* p.template // '`/pet/${petId}`'
|
|
375
|
-
*/
|
|
376
|
-
var URLPath = class {
|
|
377
|
-
/**
|
|
378
|
-
* The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.
|
|
379
|
-
*/
|
|
380
|
-
path;
|
|
381
|
-
#options;
|
|
382
|
-
constructor(path, options = {}) {
|
|
383
|
-
this.path = path;
|
|
384
|
-
this.#options = options;
|
|
385
|
-
}
|
|
386
|
-
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
|
|
387
|
-
*
|
|
388
|
-
* @example
|
|
389
|
-
* ```ts
|
|
390
|
-
* new URLPath('/pet/{petId}').URL // '/pet/:petId'
|
|
391
|
-
* ```
|
|
392
|
-
*/
|
|
393
|
-
get URL() {
|
|
394
|
-
return this.toURLPath();
|
|
395
|
-
}
|
|
396
|
-
/** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
|
|
397
|
-
*
|
|
398
|
-
* @example
|
|
399
|
-
* ```ts
|
|
400
|
-
* new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
|
|
401
|
-
* new URLPath('/pet/{petId}').isURL // false
|
|
402
|
-
* ```
|
|
403
|
-
*/
|
|
404
|
-
get isURL() {
|
|
405
|
-
try {
|
|
406
|
-
return !!new URL(this.path).href;
|
|
407
|
-
} catch {
|
|
408
|
-
return false;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
413
|
-
*
|
|
414
|
-
* @example
|
|
415
|
-
* new URLPath('/pet/{petId}').template // '`/pet/${petId}`'
|
|
416
|
-
* new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
|
|
417
|
-
*/
|
|
418
|
-
get template() {
|
|
419
|
-
return this.toTemplateString();
|
|
420
|
-
}
|
|
421
|
-
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
422
|
-
*
|
|
423
|
-
* @example
|
|
424
|
-
* ```ts
|
|
425
|
-
* new URLPath('/pet/{petId}').object
|
|
426
|
-
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
427
|
-
* ```
|
|
428
|
-
*/
|
|
429
|
-
get object() {
|
|
430
|
-
return this.toObject();
|
|
431
|
-
}
|
|
432
|
-
/** Returns a map of path parameter names, or `undefined` when the path has no parameters.
|
|
433
|
-
*
|
|
434
|
-
* @example
|
|
435
|
-
* ```ts
|
|
436
|
-
* new URLPath('/pet/{petId}').params // { petId: 'petId' }
|
|
437
|
-
* new URLPath('/pet').params // undefined
|
|
438
|
-
* ```
|
|
439
|
-
*/
|
|
440
|
-
get params() {
|
|
441
|
-
return this.getParams();
|
|
442
|
-
}
|
|
443
|
-
#transformParam(raw) {
|
|
444
|
-
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
445
|
-
return this.#options.casing === "camelcase" ? camelCase(param) : param;
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
|
|
449
|
-
*/
|
|
450
|
-
#eachParam(fn) {
|
|
451
|
-
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
452
|
-
const raw = match[1];
|
|
453
|
-
fn(raw, this.#transformParam(raw));
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
toObject({ type = "path", replacer, stringify } = {}) {
|
|
457
|
-
const object = {
|
|
458
|
-
url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
|
|
459
|
-
params: this.getParams()
|
|
460
|
-
};
|
|
461
|
-
if (stringify) {
|
|
462
|
-
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
463
|
-
if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
|
|
464
|
-
return `{ url: '${object.url}' }`;
|
|
465
|
-
}
|
|
466
|
-
return object;
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
470
|
-
* An optional `replacer` can transform each extracted parameter name before interpolation.
|
|
471
|
-
*
|
|
472
|
-
* @example
|
|
473
|
-
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
474
|
-
*/
|
|
475
|
-
toTemplateString({ prefix = "", replacer } = {}) {
|
|
476
|
-
return `\`${prefix}${this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
477
|
-
if (i % 2 === 0) return part;
|
|
478
|
-
const param = this.#transformParam(part);
|
|
479
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
480
|
-
}).join("")}\``;
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
484
|
-
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
485
|
-
* Returns `undefined` when no path parameters are found.
|
|
486
|
-
*
|
|
487
|
-
* @example
|
|
488
|
-
* ```ts
|
|
489
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').getParams()
|
|
490
|
-
* // { petId: 'petId', tagId: 'tagId' }
|
|
491
|
-
* ```
|
|
492
|
-
*/
|
|
493
|
-
getParams(replacer) {
|
|
494
|
-
const params = {};
|
|
495
|
-
this.#eachParam((_raw, param) => {
|
|
496
|
-
const key = replacer ? replacer(param) : param;
|
|
497
|
-
params[key] = key;
|
|
498
|
-
});
|
|
499
|
-
return Object.keys(params).length > 0 ? params : void 0;
|
|
500
|
-
}
|
|
501
|
-
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
502
|
-
*
|
|
503
|
-
* @example
|
|
504
|
-
* ```ts
|
|
505
|
-
* new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
|
-
toURLPath() {
|
|
509
|
-
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
510
|
-
}
|
|
511
|
-
};
|
|
512
|
-
//#endregion
|
|
513
251
|
//#region src/createAdapter.ts
|
|
514
252
|
/**
|
|
515
253
|
* Factory for implementing custom adapters that translate non-OpenAPI specs into Kubb's AST.
|
|
@@ -541,7 +279,7 @@ function createAdapter(build) {
|
|
|
541
279
|
}
|
|
542
280
|
//#endregion
|
|
543
281
|
//#region package.json
|
|
544
|
-
var version$1 = "5.0.0-beta.
|
|
282
|
+
var version$1 = "5.0.0-beta.20";
|
|
545
283
|
//#endregion
|
|
546
284
|
//#region src/createStorage.ts
|
|
547
285
|
/**
|
|
@@ -815,7 +553,6 @@ async function setup(userConfig, options = {}) {
|
|
|
815
553
|
...userConfig,
|
|
816
554
|
root: userConfig.root || process.cwd(),
|
|
817
555
|
parsers: userConfig.parsers ?? [],
|
|
818
|
-
adapter: userConfig.adapter,
|
|
819
556
|
output: {
|
|
820
557
|
format: false,
|
|
821
558
|
lint: false,
|
|
@@ -830,7 +567,7 @@ async function setup(userConfig, options = {}) {
|
|
|
830
567
|
} : void 0,
|
|
831
568
|
plugins: userConfig.plugins ?? []
|
|
832
569
|
};
|
|
833
|
-
const driver = new
|
|
570
|
+
const driver = new KubbDriver(config, { hooks });
|
|
834
571
|
const storage = createSourcesView(config.storage);
|
|
835
572
|
const diagnosticInfo = getDiagnosticInfo();
|
|
836
573
|
await hooks.emit("kubb:debug", {
|
|
@@ -845,6 +582,7 @@ async function setup(userConfig, options = {}) {
|
|
|
845
582
|
` • Storage: ${config.storage.name}`,
|
|
846
583
|
` • Formatter: ${userConfig.output?.format || "none"}`,
|
|
847
584
|
` • Linter: ${userConfig.output?.lint || "none"}`,
|
|
585
|
+
`Running adapter: ${config.adapter?.name || "none"}`,
|
|
848
586
|
"Environment:",
|
|
849
587
|
Object.entries(diagnosticInfo).map(([key, value]) => ` • ${key}: ${value}`).join("\n")
|
|
850
588
|
]
|
|
@@ -870,48 +608,7 @@ async function setup(userConfig, options = {}) {
|
|
|
870
608
|
});
|
|
871
609
|
await config.storage.clear(resolve(config.root, config.output.path));
|
|
872
610
|
}
|
|
873
|
-
|
|
874
|
-
function registerMiddlewareHook(event, middlewareHooks) {
|
|
875
|
-
const handler = middlewareHooks[event];
|
|
876
|
-
if (handler) {
|
|
877
|
-
hooks.on(event, handler);
|
|
878
|
-
middlewareListeners.push([event, handler]);
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
for (const middleware of config.middleware ?? []) for (const event of Object.keys(middleware.hooks)) registerMiddlewareHook(event, middleware.hooks);
|
|
882
|
-
if (config.adapter) {
|
|
883
|
-
const source = inputToAdapterSource(config);
|
|
884
|
-
await hooks.emit("kubb:debug", {
|
|
885
|
-
date: /* @__PURE__ */ new Date(),
|
|
886
|
-
logs: [`Running adapter: ${config.adapter.name}`]
|
|
887
|
-
});
|
|
888
|
-
driver.adapter = config.adapter;
|
|
889
|
-
if (config.adapter.count && config.adapter.stream) {
|
|
890
|
-
const { schemas: schemaCount, operations: operationCount } = await config.adapter.count(source);
|
|
891
|
-
if (schemaCount > 100) {
|
|
892
|
-
driver.inputStreamNode = await config.adapter.stream(source);
|
|
893
|
-
await hooks.emit("kubb:debug", {
|
|
894
|
-
date: /* @__PURE__ */ new Date(),
|
|
895
|
-
logs: [
|
|
896
|
-
`✓ Adapter '${config.adapter.name}' streaming InputStreamNode`,
|
|
897
|
-
` • Schemas: ${schemaCount} (threshold: 100)`,
|
|
898
|
-
` • Operations: ${operationCount}`
|
|
899
|
-
]
|
|
900
|
-
});
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
if (!driver.inputStreamNode) {
|
|
904
|
-
driver.inputNode = await config.adapter.parse(source);
|
|
905
|
-
await hooks.emit("kubb:debug", {
|
|
906
|
-
date: /* @__PURE__ */ new Date(),
|
|
907
|
-
logs: [
|
|
908
|
-
`✓ Adapter '${config.adapter.name}' resolved InputNode`,
|
|
909
|
-
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
910
|
-
` • Operations: ${driver.inputNode.operations.length}`
|
|
911
|
-
]
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
|
-
}
|
|
611
|
+
await driver.setup();
|
|
915
612
|
return {
|
|
916
613
|
config,
|
|
917
614
|
hooks,
|
|
@@ -922,262 +619,6 @@ async function setup(userConfig, options = {}) {
|
|
|
922
619
|
};
|
|
923
620
|
function dispose() {
|
|
924
621
|
driver.dispose();
|
|
925
|
-
for (const [event, handler] of middlewareListeners) hooks.off(event, handler);
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
/**
|
|
929
|
-
* Single-pass fan-out for streaming mode.
|
|
930
|
-
*
|
|
931
|
-
* Iterates `inputStreamNode.schemas` and `.operations` exactly once, distributing each
|
|
932
|
-
* node to every plugin in parallel. This replaces the N-pass-per-plugin pattern (where
|
|
933
|
-
* each plugin got its own `for await` iterator) with a single parse pass fanned to all
|
|
934
|
-
* plugins — eliminating the N×parse-time overhead for multi-plugin builds.
|
|
935
|
-
*
|
|
936
|
-
* Each plugin still gets independent `plugin:start` / `plugin:end` events and its own
|
|
937
|
-
* timing, but the schema and operation nodes are parsed only once total.
|
|
938
|
-
*/
|
|
939
|
-
async function runPluginStreamHooks({ entries, driver, pluginTimings, failedPlugins }) {
|
|
940
|
-
const inputStreamNode = driver.inputStreamNode;
|
|
941
|
-
function resolveRendererFor(gen, state) {
|
|
942
|
-
return gen.renderer === null ? void 0 : gen.renderer ?? state.plugin.renderer ?? state.generatorContext.config.renderer;
|
|
943
|
-
}
|
|
944
|
-
const states = entries.map(({ plugin, context, hrStart }) => {
|
|
945
|
-
const { exclude, include, override } = plugin.options;
|
|
946
|
-
const hasExclude = Array.isArray(exclude) && exclude.length > 0;
|
|
947
|
-
const hasInclude = Array.isArray(include) && include.length > 0;
|
|
948
|
-
const hasOverride = Array.isArray(override) && override.length > 0;
|
|
949
|
-
return {
|
|
950
|
-
plugin,
|
|
951
|
-
generatorContext: {
|
|
952
|
-
...context,
|
|
953
|
-
resolver: driver.getResolver(plugin.name)
|
|
954
|
-
},
|
|
955
|
-
generators: plugin.generators ?? [],
|
|
956
|
-
hrStart,
|
|
957
|
-
failed: false,
|
|
958
|
-
error: void 0,
|
|
959
|
-
optionsAreStatic: !hasExclude && !hasInclude && !hasOverride
|
|
960
|
-
};
|
|
961
|
-
});
|
|
962
|
-
async function dispatchSchema(state, node) {
|
|
963
|
-
if (state.failed) return;
|
|
964
|
-
try {
|
|
965
|
-
const { plugin, generatorContext, generators } = state;
|
|
966
|
-
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
967
|
-
const { exclude, include, override } = plugin.options;
|
|
968
|
-
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
969
|
-
options: plugin.options,
|
|
970
|
-
exclude,
|
|
971
|
-
include,
|
|
972
|
-
override
|
|
973
|
-
});
|
|
974
|
-
if (options === null) return;
|
|
975
|
-
const ctx = {
|
|
976
|
-
...generatorContext,
|
|
977
|
-
options
|
|
978
|
-
};
|
|
979
|
-
for (const gen of generators) {
|
|
980
|
-
if (!gen.schema) continue;
|
|
981
|
-
const raw = gen.schema(transformedNode, ctx);
|
|
982
|
-
const applied = applyHookResult({
|
|
983
|
-
result: isPromise(raw) ? await raw : raw,
|
|
984
|
-
driver,
|
|
985
|
-
rendererFactory: resolveRendererFor(gen, state)
|
|
986
|
-
});
|
|
987
|
-
if (isPromise(applied)) await applied;
|
|
988
|
-
}
|
|
989
|
-
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
990
|
-
} catch (caughtError) {
|
|
991
|
-
state.failed = true;
|
|
992
|
-
state.error = caughtError;
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
async function dispatchOperation(state, node) {
|
|
996
|
-
if (state.failed) return;
|
|
997
|
-
try {
|
|
998
|
-
const { plugin, generatorContext, generators } = state;
|
|
999
|
-
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
1000
|
-
const { exclude, include, override } = plugin.options;
|
|
1001
|
-
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
1002
|
-
options: plugin.options,
|
|
1003
|
-
exclude,
|
|
1004
|
-
include,
|
|
1005
|
-
override
|
|
1006
|
-
});
|
|
1007
|
-
if (options === null) return;
|
|
1008
|
-
const ctx = {
|
|
1009
|
-
...generatorContext,
|
|
1010
|
-
options
|
|
1011
|
-
};
|
|
1012
|
-
for (const gen of generators) {
|
|
1013
|
-
if (!gen.operation) continue;
|
|
1014
|
-
const raw = gen.operation(transformedNode, ctx);
|
|
1015
|
-
const applied = applyHookResult({
|
|
1016
|
-
result: isPromise(raw) ? await raw : raw,
|
|
1017
|
-
driver,
|
|
1018
|
-
rendererFactory: resolveRendererFor(gen, state)
|
|
1019
|
-
});
|
|
1020
|
-
if (isPromise(applied)) await applied;
|
|
1021
|
-
}
|
|
1022
|
-
await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
1023
|
-
} catch (caughtError) {
|
|
1024
|
-
state.failed = true;
|
|
1025
|
-
state.error = caughtError;
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
for await (const node of inputStreamNode.schemas) await Promise.all(states.map((state) => dispatchSchema(state, node)));
|
|
1029
|
-
const collectedOperations = [];
|
|
1030
|
-
for await (const node of inputStreamNode.operations) {
|
|
1031
|
-
collectedOperations.push(node);
|
|
1032
|
-
await Promise.all(states.map((state) => dispatchOperation(state, node)));
|
|
1033
|
-
}
|
|
1034
|
-
for (const state of states) {
|
|
1035
|
-
if (!state.failed) try {
|
|
1036
|
-
const { plugin, generatorContext, generators } = state;
|
|
1037
|
-
const ctx = {
|
|
1038
|
-
...generatorContext,
|
|
1039
|
-
options: plugin.options
|
|
1040
|
-
};
|
|
1041
|
-
for (const gen of generators) {
|
|
1042
|
-
if (!gen.operations) continue;
|
|
1043
|
-
await applyHookResult({
|
|
1044
|
-
result: await gen.operations(collectedOperations, ctx),
|
|
1045
|
-
driver,
|
|
1046
|
-
rendererFactory: resolveRendererFor(gen, state)
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
1050
|
-
} catch (caughtError) {
|
|
1051
|
-
state.failed = true;
|
|
1052
|
-
state.error = caughtError;
|
|
1053
|
-
}
|
|
1054
|
-
const duration = getElapsedMs(state.hrStart);
|
|
1055
|
-
pluginTimings.set(state.plugin.name, duration);
|
|
1056
|
-
await driver.hooks.emit("kubb:plugin:end", {
|
|
1057
|
-
plugin: state.plugin,
|
|
1058
|
-
duration,
|
|
1059
|
-
success: !state.failed,
|
|
1060
|
-
...state.failed && state.error ? { error: state.error } : {},
|
|
1061
|
-
config: driver.config,
|
|
1062
|
-
get files() {
|
|
1063
|
-
return driver.fileManager.files;
|
|
1064
|
-
},
|
|
1065
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1066
|
-
});
|
|
1067
|
-
if (state.failed && state.error) failedPlugins.add({
|
|
1068
|
-
plugin: state.plugin,
|
|
1069
|
-
error: state.error
|
|
1070
|
-
});
|
|
1071
|
-
await driver.hooks.emit("kubb:debug", {
|
|
1072
|
-
date: /* @__PURE__ */ new Date(),
|
|
1073
|
-
logs: [state.failed ? "✗ Plugin start failed" : `✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
/**
|
|
1078
|
-
* Walks the AST and dispatches nodes to a plugin's direct AST hooks
|
|
1079
|
-
* (`schema`, `operation`, `operations`).
|
|
1080
|
-
*
|
|
1081
|
-
* When `include` contains only operation-scoped filters (`tag`, `operationId`, `path`,
|
|
1082
|
-
* `method`, `contentType`) and no `schemaName` filter, the function pre-computes the set
|
|
1083
|
-
* of top-level schema names transitively reachable from the included operations and skips
|
|
1084
|
-
* schemas that fall outside that set. This ensures that component schemas referenced
|
|
1085
|
-
* exclusively by excluded operations are not generated.
|
|
1086
|
-
*/
|
|
1087
|
-
async function runPluginAstHooks(plugin, context) {
|
|
1088
|
-
const { adapter, inputNode, resolver, driver } = context;
|
|
1089
|
-
const { exclude, include, override } = plugin.options;
|
|
1090
|
-
if (!adapter || !inputNode) throw new Error(`[${plugin.name}] No adapter found. Add an OAS adapter (e.g. adapterOas()) before this plugin in your Kubb config.`);
|
|
1091
|
-
function resolveRenderer(gen) {
|
|
1092
|
-
return gen.renderer === null ? void 0 : gen.renderer ?? plugin.renderer ?? context.config.renderer;
|
|
1093
|
-
}
|
|
1094
|
-
const generators = plugin.generators ?? [];
|
|
1095
|
-
const collectedOperations = [];
|
|
1096
|
-
const generatorContext = {
|
|
1097
|
-
...context,
|
|
1098
|
-
resolver: driver.getResolver(plugin.name)
|
|
1099
|
-
};
|
|
1100
|
-
const operationFilterTypes = new Set([
|
|
1101
|
-
"tag",
|
|
1102
|
-
"operationId",
|
|
1103
|
-
"path",
|
|
1104
|
-
"method",
|
|
1105
|
-
"contentType"
|
|
1106
|
-
]);
|
|
1107
|
-
const hasOperationBasedIncludes = include?.some(({ type }) => operationFilterTypes.has(type)) ?? false;
|
|
1108
|
-
const hasSchemaNameIncludes = include?.some(({ type }) => type === "schemaName") ?? false;
|
|
1109
|
-
const allowedSchemaNames = (() => {
|
|
1110
|
-
if (!hasOperationBasedIncludes || hasSchemaNameIncludes) return void 0;
|
|
1111
|
-
return collectUsedSchemaNames(inputNode.operations.filter((op) => resolver.resolveOptions(op, {
|
|
1112
|
-
options: plugin.options,
|
|
1113
|
-
exclude,
|
|
1114
|
-
include,
|
|
1115
|
-
override
|
|
1116
|
-
}) !== null), inputNode.schemas);
|
|
1117
|
-
})();
|
|
1118
|
-
await walk(inputNode, {
|
|
1119
|
-
depth: "shallow",
|
|
1120
|
-
async schema(node) {
|
|
1121
|
-
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
1122
|
-
if (allowedSchemaNames !== void 0 && transformedNode.name && !allowedSchemaNames.has(transformedNode.name)) return;
|
|
1123
|
-
const options = resolver.resolveOptions(transformedNode, {
|
|
1124
|
-
options: plugin.options,
|
|
1125
|
-
exclude,
|
|
1126
|
-
include,
|
|
1127
|
-
override
|
|
1128
|
-
});
|
|
1129
|
-
if (options === null) return;
|
|
1130
|
-
const ctx = {
|
|
1131
|
-
...generatorContext,
|
|
1132
|
-
options
|
|
1133
|
-
};
|
|
1134
|
-
await Promise.all(generators.filter((gen) => gen.schema).map(async (gen) => {
|
|
1135
|
-
return applyHookResult({
|
|
1136
|
-
result: await gen.schema(transformedNode, ctx),
|
|
1137
|
-
driver,
|
|
1138
|
-
rendererFactory: resolveRenderer(gen)
|
|
1139
|
-
});
|
|
1140
|
-
}));
|
|
1141
|
-
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
1142
|
-
},
|
|
1143
|
-
async operation(node) {
|
|
1144
|
-
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
1145
|
-
const options = resolver.resolveOptions(transformedNode, {
|
|
1146
|
-
options: plugin.options,
|
|
1147
|
-
exclude,
|
|
1148
|
-
include,
|
|
1149
|
-
override
|
|
1150
|
-
});
|
|
1151
|
-
if (options === null) return;
|
|
1152
|
-
collectedOperations.push(transformedNode);
|
|
1153
|
-
const ctx = {
|
|
1154
|
-
...generatorContext,
|
|
1155
|
-
options
|
|
1156
|
-
};
|
|
1157
|
-
await Promise.all(generators.filter((gen) => gen.operation).map(async (gen) => {
|
|
1158
|
-
return applyHookResult({
|
|
1159
|
-
result: await gen.operation(transformedNode, ctx),
|
|
1160
|
-
driver,
|
|
1161
|
-
rendererFactory: resolveRenderer(gen)
|
|
1162
|
-
});
|
|
1163
|
-
}));
|
|
1164
|
-
await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
1165
|
-
}
|
|
1166
|
-
});
|
|
1167
|
-
if (collectedOperations.length > 0) {
|
|
1168
|
-
const ctx = {
|
|
1169
|
-
...generatorContext,
|
|
1170
|
-
options: plugin.options
|
|
1171
|
-
};
|
|
1172
|
-
for (const gen of generators) {
|
|
1173
|
-
if (!gen.operations) continue;
|
|
1174
|
-
await applyHookResult({
|
|
1175
|
-
result: await gen.operations(collectedOperations, ctx),
|
|
1176
|
-
driver,
|
|
1177
|
-
rendererFactory: resolveRenderer(gen)
|
|
1178
|
-
});
|
|
1179
|
-
}
|
|
1180
|
-
await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
1181
622
|
}
|
|
1182
623
|
}
|
|
1183
624
|
async function safeBuild(setupResult) {
|
|
@@ -1190,8 +631,8 @@ async function safeBuild(setupResult) {
|
|
|
1190
631
|
const config = driver.config;
|
|
1191
632
|
const writtenPaths = /* @__PURE__ */ new Set();
|
|
1192
633
|
const parsersMap = /* @__PURE__ */ new Map();
|
|
1193
|
-
for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
|
|
1194
634
|
const fileProcessor = new FileProcessor();
|
|
635
|
+
for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
|
|
1195
636
|
async function flushPendingFiles() {
|
|
1196
637
|
const files = driver.fileManager.files.filter((f) => !writtenPaths.has(f.path));
|
|
1197
638
|
if (files.length === 0) return;
|
|
@@ -1204,116 +645,235 @@ async function safeBuild(setupResult) {
|
|
|
1204
645
|
parsers: parsersMap,
|
|
1205
646
|
extension: config.output.extension
|
|
1206
647
|
});
|
|
648
|
+
const queue = [];
|
|
1207
649
|
for (const { file, source, processed, total, percentage } of stream) {
|
|
1208
|
-
await hooks.emit("kubb:file:processing:update", {
|
|
1209
|
-
file,
|
|
1210
|
-
source,
|
|
1211
|
-
processed,
|
|
1212
|
-
total,
|
|
1213
|
-
percentage,
|
|
1214
|
-
config
|
|
1215
|
-
});
|
|
1216
|
-
if (source) await storage.setItem(file.path, source);
|
|
1217
650
|
writtenPaths.add(file.path);
|
|
651
|
+
queue.push((async () => {
|
|
652
|
+
await hooks.emit("kubb:file:processing:update", {
|
|
653
|
+
file,
|
|
654
|
+
source,
|
|
655
|
+
processed,
|
|
656
|
+
total,
|
|
657
|
+
percentage,
|
|
658
|
+
config
|
|
659
|
+
});
|
|
660
|
+
if (source) await storage.setItem(file.path, source);
|
|
661
|
+
})());
|
|
662
|
+
if (queue.length >= 50) await Promise.all(queue.splice(0));
|
|
1218
663
|
}
|
|
664
|
+
await Promise.all(queue);
|
|
1219
665
|
await hooks.emit("kubb:files:processing:end", { files });
|
|
1220
666
|
await hooks.emit("kubb:debug", {
|
|
1221
667
|
date: /* @__PURE__ */ new Date(),
|
|
1222
668
|
logs: [`✓ File write process completed for ${files.length} files`]
|
|
1223
669
|
});
|
|
1224
670
|
}
|
|
671
|
+
async function dispatchOperationsToGenerators(generators, collectedOperations, ctx, rendererFor) {
|
|
672
|
+
for (const gen of generators) {
|
|
673
|
+
if (!gen.operations) continue;
|
|
674
|
+
await applyHookResult({
|
|
675
|
+
result: await gen.operations(collectedOperations, ctx),
|
|
676
|
+
driver,
|
|
677
|
+
rendererFactory: rendererFor(gen)
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Single-pass fan-out: iterates all schemas and operations once, distributing each node
|
|
684
|
+
* to every generator-plugin in parallel. This replaces the N-pass-per-plugin pattern
|
|
685
|
+
* (each plugin getting its own iterator) with one parse pass fanned to all plugins,
|
|
686
|
+
* eliminating the N×parse-time overhead for multi-plugin builds.
|
|
687
|
+
*/
|
|
688
|
+
async function runPlugins(entries) {
|
|
689
|
+
const { schemas, operations } = driver.inputNode;
|
|
690
|
+
const operationFilterTypes = new Set([
|
|
691
|
+
"tag",
|
|
692
|
+
"operationId",
|
|
693
|
+
"path",
|
|
694
|
+
"method",
|
|
695
|
+
"contentType"
|
|
696
|
+
]);
|
|
697
|
+
const states = entries.map(({ plugin, context, hrStart }) => {
|
|
698
|
+
const { exclude, include, override } = plugin.options;
|
|
699
|
+
const hasExclude = Array.isArray(exclude) && exclude.length > 0;
|
|
700
|
+
const hasInclude = Array.isArray(include) && include.length > 0;
|
|
701
|
+
const hasOverride = Array.isArray(override) && override.length > 0;
|
|
702
|
+
return {
|
|
703
|
+
plugin,
|
|
704
|
+
generatorContext: {
|
|
705
|
+
...context,
|
|
706
|
+
resolver: driver.getResolver(plugin.name)
|
|
707
|
+
},
|
|
708
|
+
generators: plugin.generators ?? [],
|
|
709
|
+
hrStart,
|
|
710
|
+
failed: false,
|
|
711
|
+
error: void 0,
|
|
712
|
+
optionsAreStatic: !hasExclude && !hasInclude && !hasOverride,
|
|
713
|
+
allowedSchemaNames: void 0
|
|
714
|
+
};
|
|
715
|
+
});
|
|
716
|
+
const pruningStates = states.filter(({ plugin }) => {
|
|
717
|
+
const { include } = plugin.options;
|
|
718
|
+
return (include?.some(({ type }) => operationFilterTypes.has(type)) ?? false) && !(include?.some(({ type }) => type === "schemaName") ?? false);
|
|
719
|
+
});
|
|
720
|
+
if (pruningStates.length > 0) {
|
|
721
|
+
const allSchemas = [];
|
|
722
|
+
for await (const schema of schemas) allSchemas.push(schema);
|
|
723
|
+
const includedOpsByState = new Map(pruningStates.map((s) => [s, []]));
|
|
724
|
+
for await (const operation of operations) for (const state of pruningStates) {
|
|
725
|
+
const { exclude, include, override } = state.plugin.options;
|
|
726
|
+
if (state.generatorContext.resolver.resolveOptions(operation, {
|
|
727
|
+
options: state.plugin.options,
|
|
728
|
+
exclude,
|
|
729
|
+
include,
|
|
730
|
+
override
|
|
731
|
+
}) !== null) includedOpsByState.get(state)?.push(operation);
|
|
732
|
+
}
|
|
733
|
+
for (const state of pruningStates) state.allowedSchemaNames = collectUsedSchemaNames(includedOpsByState.get(state) ?? [], allSchemas);
|
|
734
|
+
}
|
|
735
|
+
function resolveRendererFor(gen, state) {
|
|
736
|
+
return gen.renderer === null ? void 0 : gen.renderer ?? state.plugin.renderer ?? state.generatorContext.config.renderer;
|
|
737
|
+
}
|
|
738
|
+
async function dispatchSchema(state, node) {
|
|
739
|
+
if (state.failed) return;
|
|
740
|
+
try {
|
|
741
|
+
const { plugin, generatorContext, generators } = state;
|
|
742
|
+
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
743
|
+
if (state.allowedSchemaNames !== void 0 && transformedNode.name && !state.allowedSchemaNames.has(transformedNode.name)) return;
|
|
744
|
+
const { exclude, include, override } = plugin.options;
|
|
745
|
+
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
746
|
+
options: plugin.options,
|
|
747
|
+
exclude,
|
|
748
|
+
include,
|
|
749
|
+
override
|
|
750
|
+
});
|
|
751
|
+
if (options === null) return;
|
|
752
|
+
const ctx = {
|
|
753
|
+
...generatorContext,
|
|
754
|
+
options
|
|
755
|
+
};
|
|
756
|
+
for (const gen of generators) {
|
|
757
|
+
if (!gen.schema) continue;
|
|
758
|
+
const raw = gen.schema(transformedNode, ctx);
|
|
759
|
+
const applied = applyHookResult({
|
|
760
|
+
result: isPromise(raw) ? await raw : raw,
|
|
761
|
+
driver,
|
|
762
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
763
|
+
});
|
|
764
|
+
if (isPromise(applied)) await applied;
|
|
765
|
+
}
|
|
766
|
+
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
767
|
+
} catch (caughtError) {
|
|
768
|
+
state.failed = true;
|
|
769
|
+
state.error = caughtError;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
async function dispatchOperation(state, node) {
|
|
773
|
+
if (state.failed) return;
|
|
774
|
+
try {
|
|
775
|
+
const { plugin, generatorContext, generators } = state;
|
|
776
|
+
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
777
|
+
const { exclude, include, override } = plugin.options;
|
|
778
|
+
const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
|
|
779
|
+
options: plugin.options,
|
|
780
|
+
exclude,
|
|
781
|
+
include,
|
|
782
|
+
override
|
|
783
|
+
});
|
|
784
|
+
if (options === null) return;
|
|
785
|
+
const ctx = {
|
|
786
|
+
...generatorContext,
|
|
787
|
+
options
|
|
788
|
+
};
|
|
789
|
+
for (const gen of generators) {
|
|
790
|
+
if (!gen.operation) continue;
|
|
791
|
+
const raw = gen.operation(transformedNode, ctx);
|
|
792
|
+
const applied = applyHookResult({
|
|
793
|
+
result: isPromise(raw) ? await raw : raw,
|
|
794
|
+
driver,
|
|
795
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
796
|
+
});
|
|
797
|
+
if (isPromise(applied)) await applied;
|
|
798
|
+
}
|
|
799
|
+
await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
800
|
+
} catch (caughtError) {
|
|
801
|
+
state.failed = true;
|
|
802
|
+
state.error = caughtError;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
await forBatches(schemas, (nodes) => Promise.all(nodes.flatMap((n) => states.map((state) => dispatchSchema(state, n)))), {
|
|
806
|
+
concurrency: 8,
|
|
807
|
+
flush: flushPendingFiles
|
|
808
|
+
});
|
|
809
|
+
const collectedOperations = [];
|
|
810
|
+
await forBatches(operations, (nodes) => {
|
|
811
|
+
collectedOperations.push(...nodes);
|
|
812
|
+
return Promise.all(nodes.flatMap((n) => states.map((state) => dispatchOperation(state, n))));
|
|
813
|
+
}, {
|
|
814
|
+
concurrency: 8,
|
|
815
|
+
flush: flushPendingFiles
|
|
816
|
+
});
|
|
817
|
+
for (const state of states) {
|
|
818
|
+
if (!state.failed) try {
|
|
819
|
+
const { plugin, generatorContext, generators } = state;
|
|
820
|
+
await dispatchOperationsToGenerators(generators, collectedOperations, {
|
|
821
|
+
...generatorContext,
|
|
822
|
+
options: plugin.options
|
|
823
|
+
}, (gen) => resolveRendererFor(gen, state));
|
|
824
|
+
} catch (caughtError) {
|
|
825
|
+
state.failed = true;
|
|
826
|
+
state.error = caughtError;
|
|
827
|
+
}
|
|
828
|
+
const duration = getElapsedMs(state.hrStart);
|
|
829
|
+
pluginTimings.set(state.plugin.name, duration);
|
|
830
|
+
await driver.hooks.emit("kubb:plugin:end", {
|
|
831
|
+
plugin: state.plugin,
|
|
832
|
+
duration,
|
|
833
|
+
success: !state.failed,
|
|
834
|
+
...state.failed && state.error ? { error: state.error } : {},
|
|
835
|
+
config: driver.config,
|
|
836
|
+
get files() {
|
|
837
|
+
return driver.fileManager.files;
|
|
838
|
+
},
|
|
839
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
840
|
+
});
|
|
841
|
+
if (state.failed && state.error) failedPlugins.add({
|
|
842
|
+
plugin: state.plugin,
|
|
843
|
+
error: state.error
|
|
844
|
+
});
|
|
845
|
+
await driver.hooks.emit("kubb:debug", {
|
|
846
|
+
date: /* @__PURE__ */ new Date(),
|
|
847
|
+
logs: [state.failed ? "✗ Plugin start failed" : `✓ Plugin started successfully (${formatMs(duration)})`]
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
}
|
|
1225
851
|
try {
|
|
1226
852
|
await driver.emitSetupHooks();
|
|
1227
|
-
if (driver.adapter &&
|
|
853
|
+
if (driver.adapter && driver.inputNode) await hooks.emit("kubb:build:start", {
|
|
1228
854
|
config,
|
|
1229
855
|
adapter: driver.adapter,
|
|
1230
|
-
|
|
1231
|
-
kind: "Input",
|
|
1232
|
-
schemas: [],
|
|
1233
|
-
operations: [],
|
|
1234
|
-
meta: driver.inputStreamNode?.meta
|
|
1235
|
-
},
|
|
856
|
+
meta: driver.inputNode.meta,
|
|
1236
857
|
getPlugin: driver.getPlugin.bind(driver),
|
|
1237
858
|
get files() {
|
|
1238
859
|
return driver.fileManager.files;
|
|
1239
860
|
},
|
|
1240
861
|
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1241
862
|
});
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
for (const plugin of driver.plugins.values()) {
|
|
1245
|
-
const context = driver.getContext(plugin);
|
|
1246
|
-
const hrStart = process.hrtime();
|
|
1247
|
-
await hooks.emit("kubb:plugin:start", { plugin });
|
|
1248
|
-
await hooks.emit("kubb:debug", {
|
|
1249
|
-
date: /* @__PURE__ */ new Date(),
|
|
1250
|
-
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1251
|
-
});
|
|
1252
|
-
if (plugin.generators?.length || driver.hasRegisteredGenerators(plugin.name)) {
|
|
1253
|
-
streamPluginEntries.push({
|
|
1254
|
-
plugin,
|
|
1255
|
-
context,
|
|
1256
|
-
hrStart
|
|
1257
|
-
});
|
|
1258
|
-
continue;
|
|
1259
|
-
}
|
|
1260
|
-
const duration = getElapsedMs(hrStart);
|
|
1261
|
-
pluginTimings.set(plugin.name, duration);
|
|
1262
|
-
await hooks.emit("kubb:plugin:end", {
|
|
1263
|
-
plugin,
|
|
1264
|
-
duration,
|
|
1265
|
-
success: true,
|
|
1266
|
-
config,
|
|
1267
|
-
get files() {
|
|
1268
|
-
return driver.fileManager.files;
|
|
1269
|
-
},
|
|
1270
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1271
|
-
});
|
|
1272
|
-
await hooks.emit("kubb:debug", {
|
|
1273
|
-
date: /* @__PURE__ */ new Date(),
|
|
1274
|
-
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1275
|
-
});
|
|
1276
|
-
}
|
|
1277
|
-
if (streamPluginEntries.length > 0) {
|
|
1278
|
-
await runPluginStreamHooks({
|
|
1279
|
-
entries: streamPluginEntries,
|
|
1280
|
-
driver,
|
|
1281
|
-
pluginTimings,
|
|
1282
|
-
failedPlugins
|
|
1283
|
-
});
|
|
1284
|
-
await flushPendingFiles();
|
|
1285
|
-
}
|
|
1286
|
-
} else for (const plugin of driver.plugins.values()) {
|
|
863
|
+
const generatorPlugins = [];
|
|
864
|
+
for (const plugin of driver.plugins.values()) {
|
|
1287
865
|
const context = driver.getContext(plugin);
|
|
1288
866
|
const hrStart = process.hrtime();
|
|
1289
867
|
try {
|
|
1290
|
-
const timestamp = /* @__PURE__ */ new Date();
|
|
1291
868
|
await hooks.emit("kubb:plugin:start", { plugin });
|
|
1292
|
-
await hooks.emit("kubb:debug", {
|
|
1293
|
-
date: timestamp,
|
|
1294
|
-
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1295
|
-
});
|
|
1296
|
-
if (plugin.generators?.length || driver.hasRegisteredGenerators(plugin.name)) await runPluginAstHooks(plugin, context);
|
|
1297
|
-
const duration = getElapsedMs(hrStart);
|
|
1298
|
-
pluginTimings.set(plugin.name, duration);
|
|
1299
|
-
await hooks.emit("kubb:plugin:end", {
|
|
1300
|
-
plugin,
|
|
1301
|
-
duration,
|
|
1302
|
-
success: true,
|
|
1303
|
-
config,
|
|
1304
|
-
get files() {
|
|
1305
|
-
return driver.fileManager.files;
|
|
1306
|
-
},
|
|
1307
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1308
|
-
});
|
|
1309
869
|
await hooks.emit("kubb:debug", {
|
|
1310
870
|
date: /* @__PURE__ */ new Date(),
|
|
1311
|
-
logs: [
|
|
871
|
+
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1312
872
|
});
|
|
1313
873
|
} catch (caughtError) {
|
|
1314
874
|
const error = caughtError;
|
|
1315
|
-
const errorTimestamp = /* @__PURE__ */ new Date();
|
|
1316
875
|
const duration = getElapsedMs(hrStart);
|
|
876
|
+
pluginTimings.set(plugin.name, duration);
|
|
1317
877
|
await hooks.emit("kubb:plugin:end", {
|
|
1318
878
|
plugin,
|
|
1319
879
|
duration,
|
|
@@ -1325,22 +885,51 @@ async function safeBuild(setupResult) {
|
|
|
1325
885
|
},
|
|
1326
886
|
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1327
887
|
});
|
|
1328
|
-
await hooks.emit("kubb:debug", {
|
|
1329
|
-
date: errorTimestamp,
|
|
1330
|
-
logs: [
|
|
1331
|
-
"✗ Plugin start failed",
|
|
1332
|
-
` • Plugin Name: ${plugin.name}`,
|
|
1333
|
-
` • Error: ${error.constructor.name} - ${error.message}`,
|
|
1334
|
-
" • Stack Trace:",
|
|
1335
|
-
error.stack || "No stack trace available"
|
|
1336
|
-
]
|
|
1337
|
-
});
|
|
1338
888
|
failedPlugins.add({
|
|
1339
889
|
plugin,
|
|
1340
890
|
error
|
|
1341
891
|
});
|
|
892
|
+
continue;
|
|
893
|
+
}
|
|
894
|
+
if (plugin.generators?.length || driver.hasEventGenerators(plugin.name)) {
|
|
895
|
+
generatorPlugins.push({
|
|
896
|
+
plugin,
|
|
897
|
+
context,
|
|
898
|
+
hrStart
|
|
899
|
+
});
|
|
900
|
+
continue;
|
|
1342
901
|
}
|
|
1343
|
-
|
|
902
|
+
const duration = getElapsedMs(hrStart);
|
|
903
|
+
pluginTimings.set(plugin.name, duration);
|
|
904
|
+
await hooks.emit("kubb:plugin:end", {
|
|
905
|
+
plugin,
|
|
906
|
+
duration,
|
|
907
|
+
success: true,
|
|
908
|
+
config,
|
|
909
|
+
get files() {
|
|
910
|
+
return driver.fileManager.files;
|
|
911
|
+
},
|
|
912
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
913
|
+
});
|
|
914
|
+
await hooks.emit("kubb:debug", {
|
|
915
|
+
date: /* @__PURE__ */ new Date(),
|
|
916
|
+
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
if (generatorPlugins.length > 0) if (driver.inputNode) await withDrain(() => runPlugins(generatorPlugins), flushPendingFiles);
|
|
920
|
+
else for (const { plugin, hrStart } of generatorPlugins) {
|
|
921
|
+
const duration = getElapsedMs(hrStart);
|
|
922
|
+
pluginTimings.set(plugin.name, duration);
|
|
923
|
+
await hooks.emit("kubb:plugin:end", {
|
|
924
|
+
plugin,
|
|
925
|
+
duration,
|
|
926
|
+
success: true,
|
|
927
|
+
config,
|
|
928
|
+
get files() {
|
|
929
|
+
return driver.fileManager.files;
|
|
930
|
+
},
|
|
931
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
932
|
+
});
|
|
1344
933
|
}
|
|
1345
934
|
await hooks.emit("kubb:plugins:end", {
|
|
1346
935
|
config,
|
|
@@ -1413,22 +1002,6 @@ function getDiagnosticInfo() {
|
|
|
1413
1002
|
function isInputPath(config) {
|
|
1414
1003
|
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
1415
1004
|
}
|
|
1416
|
-
function inputToAdapterSource(config) {
|
|
1417
|
-
const input = config.input;
|
|
1418
|
-
if (!input) throw new Error("[kubb] input is required when using an adapter. Provide input.path or input.data in your config.");
|
|
1419
|
-
if ("data" in input) return {
|
|
1420
|
-
type: "data",
|
|
1421
|
-
data: input.data
|
|
1422
|
-
};
|
|
1423
|
-
if (new URLPath(input.path).isURL) return {
|
|
1424
|
-
type: "path",
|
|
1425
|
-
path: input.path
|
|
1426
|
-
};
|
|
1427
|
-
return {
|
|
1428
|
-
type: "path",
|
|
1429
|
-
path: resolve(config.root, input.path)
|
|
1430
|
-
};
|
|
1431
|
-
}
|
|
1432
1005
|
/**
|
|
1433
1006
|
* Creates a Kubb instance bound to a single config entry.
|
|
1434
1007
|
*
|
|
@@ -1661,6 +1234,6 @@ const memoryStorage = createStorage(() => {
|
|
|
1661
1234
|
};
|
|
1662
1235
|
});
|
|
1663
1236
|
//#endregion
|
|
1664
|
-
export { AsyncEventEmitter, FileManager, FileProcessor,
|
|
1237
|
+
export { AsyncEventEmitter, FileManager, FileProcessor, KubbDriver, URLPath, ast, createAdapter, createKubb, createRenderer, createStorage, defineGenerator, defineLogger, defineMiddleware, defineParser, definePlugin, defineResolver, fsStorage, isInputPath, logLevel, memoryStorage };
|
|
1665
1238
|
|
|
1666
1239
|
//# sourceMappingURL=index.js.map
|