@kubb/core 5.0.0-beta.2 → 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/README.md +8 -38
- package/dist/{PluginDriver-BXibeQk-.cjs → KubbDriver-BXSnJ3qM.cjs} +719 -164
- package/dist/KubbDriver-BXSnJ3qM.cjs.map +1 -0
- package/dist/{PluginDriver-DV3p2Hky.js → KubbDriver-Cxii_rBp.js} +693 -162
- package/dist/KubbDriver-Cxii_rBp.js.map +1 -0
- package/dist/{types-CC09VtBt.d.ts → createKubb-Dcmtjqds.d.ts} +1395 -1238
- package/dist/index.cjs +556 -785
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -185
- package/dist/index.js +551 -783
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +30 -21
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.ts +5 -5
- package/dist/mocks.js +29 -20
- package/dist/mocks.js.map +1 -1
- package/package.json +6 -18
- package/src/FileManager.ts +12 -0
- package/src/FileProcessor.ts +37 -38
- package/src/{PluginDriver.ts → KubbDriver.ts} +249 -86
- package/src/constants.ts +11 -6
- package/src/createAdapter.ts +84 -1
- package/src/createKubb.ts +1336 -297
- package/src/createRenderer.ts +23 -22
- package/src/defineGenerator.ts +96 -7
- package/src/defineLogger.ts +42 -3
- package/src/defineMiddleware.ts +1 -1
- package/src/defineParser.ts +1 -1
- package/src/definePlugin.ts +304 -8
- package/src/defineResolver.ts +268 -147
- package/src/devtools.ts +8 -1
- package/src/index.ts +2 -2
- package/src/mocks.ts +11 -14
- package/src/storages/fsStorage.ts +13 -37
- package/src/types.ts +38 -1292
- package/dist/PluginDriver-BXibeQk-.cjs.map +0 -1
- package/dist/PluginDriver-DV3p2Hky.js.map +0 -1
- package/src/Kubb.ts +0 -300
- package/src/renderNode.ts +0 -35
- package/src/utils/diagnostics.ts +0 -18
- package/src/utils/isInputPath.ts +0 -10
- package/src/utils/packageJSON.ts +0 -99
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
2
|
+
const require_KubbDriver = require("./KubbDriver-BXSnJ3qM.cjs");
|
|
3
3
|
let node_events = require("node:events");
|
|
4
4
|
let node_fs_promises = require("node:fs/promises");
|
|
5
5
|
let node_path = require("node:path");
|
|
6
6
|
let _kubb_ast = require("@kubb/ast");
|
|
7
|
-
_kubb_ast =
|
|
7
|
+
_kubb_ast = require_KubbDriver.__toESM(_kubb_ast, 1);
|
|
8
8
|
let node_process = require("node:process");
|
|
9
9
|
//#region ../../internals/utils/src/errors.ts
|
|
10
10
|
/**
|
|
@@ -69,9 +69,12 @@ var AsyncEventEmitter = class {
|
|
|
69
69
|
* await emitter.emit('build', 'petstore')
|
|
70
70
|
* ```
|
|
71
71
|
*/
|
|
72
|
-
|
|
72
|
+
emit(eventName, ...eventArgs) {
|
|
73
73
|
const listeners = this.#emitter.listeners(eventName);
|
|
74
74
|
if (listeners.length === 0) return;
|
|
75
|
+
return this.#emitAll(eventName, listeners, eventArgs);
|
|
76
|
+
}
|
|
77
|
+
async #emitAll(eventName, listeners, eventArgs) {
|
|
75
78
|
for (const listener of listeners) try {
|
|
76
79
|
await listener(...eventArgs);
|
|
77
80
|
} catch (err) {
|
|
@@ -245,255 +248,6 @@ async function clean(path) {
|
|
|
245
248
|
});
|
|
246
249
|
}
|
|
247
250
|
//#endregion
|
|
248
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
249
|
-
/**
|
|
250
|
-
* JavaScript and Java reserved words.
|
|
251
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
252
|
-
*/
|
|
253
|
-
const reservedWords = new Set([
|
|
254
|
-
"abstract",
|
|
255
|
-
"arguments",
|
|
256
|
-
"boolean",
|
|
257
|
-
"break",
|
|
258
|
-
"byte",
|
|
259
|
-
"case",
|
|
260
|
-
"catch",
|
|
261
|
-
"char",
|
|
262
|
-
"class",
|
|
263
|
-
"const",
|
|
264
|
-
"continue",
|
|
265
|
-
"debugger",
|
|
266
|
-
"default",
|
|
267
|
-
"delete",
|
|
268
|
-
"do",
|
|
269
|
-
"double",
|
|
270
|
-
"else",
|
|
271
|
-
"enum",
|
|
272
|
-
"eval",
|
|
273
|
-
"export",
|
|
274
|
-
"extends",
|
|
275
|
-
"false",
|
|
276
|
-
"final",
|
|
277
|
-
"finally",
|
|
278
|
-
"float",
|
|
279
|
-
"for",
|
|
280
|
-
"function",
|
|
281
|
-
"goto",
|
|
282
|
-
"if",
|
|
283
|
-
"implements",
|
|
284
|
-
"import",
|
|
285
|
-
"in",
|
|
286
|
-
"instanceof",
|
|
287
|
-
"int",
|
|
288
|
-
"interface",
|
|
289
|
-
"let",
|
|
290
|
-
"long",
|
|
291
|
-
"native",
|
|
292
|
-
"new",
|
|
293
|
-
"null",
|
|
294
|
-
"package",
|
|
295
|
-
"private",
|
|
296
|
-
"protected",
|
|
297
|
-
"public",
|
|
298
|
-
"return",
|
|
299
|
-
"short",
|
|
300
|
-
"static",
|
|
301
|
-
"super",
|
|
302
|
-
"switch",
|
|
303
|
-
"synchronized",
|
|
304
|
-
"this",
|
|
305
|
-
"throw",
|
|
306
|
-
"throws",
|
|
307
|
-
"transient",
|
|
308
|
-
"true",
|
|
309
|
-
"try",
|
|
310
|
-
"typeof",
|
|
311
|
-
"var",
|
|
312
|
-
"void",
|
|
313
|
-
"volatile",
|
|
314
|
-
"while",
|
|
315
|
-
"with",
|
|
316
|
-
"yield",
|
|
317
|
-
"Array",
|
|
318
|
-
"Date",
|
|
319
|
-
"hasOwnProperty",
|
|
320
|
-
"Infinity",
|
|
321
|
-
"isFinite",
|
|
322
|
-
"isNaN",
|
|
323
|
-
"isPrototypeOf",
|
|
324
|
-
"length",
|
|
325
|
-
"Math",
|
|
326
|
-
"name",
|
|
327
|
-
"NaN",
|
|
328
|
-
"Number",
|
|
329
|
-
"Object",
|
|
330
|
-
"prototype",
|
|
331
|
-
"String",
|
|
332
|
-
"toString",
|
|
333
|
-
"undefined",
|
|
334
|
-
"valueOf"
|
|
335
|
-
]);
|
|
336
|
-
/**
|
|
337
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
338
|
-
*
|
|
339
|
-
* @example
|
|
340
|
-
* ```ts
|
|
341
|
-
* isValidVarName('status') // true
|
|
342
|
-
* isValidVarName('class') // false (reserved word)
|
|
343
|
-
* isValidVarName('42foo') // false (starts with digit)
|
|
344
|
-
* ```
|
|
345
|
-
*/
|
|
346
|
-
function isValidVarName(name) {
|
|
347
|
-
if (!name || reservedWords.has(name)) return false;
|
|
348
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
349
|
-
}
|
|
350
|
-
//#endregion
|
|
351
|
-
//#region ../../internals/utils/src/urlPath.ts
|
|
352
|
-
/**
|
|
353
|
-
* Parses and transforms an OpenAPI/Swagger path string into various URL formats.
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* const p = new URLPath('/pet/{petId}')
|
|
357
|
-
* p.URL // '/pet/:petId'
|
|
358
|
-
* p.template // '`/pet/${petId}`'
|
|
359
|
-
*/
|
|
360
|
-
var URLPath = class {
|
|
361
|
-
/**
|
|
362
|
-
* The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.
|
|
363
|
-
*/
|
|
364
|
-
path;
|
|
365
|
-
#options;
|
|
366
|
-
constructor(path, options = {}) {
|
|
367
|
-
this.path = path;
|
|
368
|
-
this.#options = options;
|
|
369
|
-
}
|
|
370
|
-
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
|
|
371
|
-
*
|
|
372
|
-
* @example
|
|
373
|
-
* ```ts
|
|
374
|
-
* new URLPath('/pet/{petId}').URL // '/pet/:petId'
|
|
375
|
-
* ```
|
|
376
|
-
*/
|
|
377
|
-
get URL() {
|
|
378
|
-
return this.toURLPath();
|
|
379
|
-
}
|
|
380
|
-
/** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
|
|
381
|
-
*
|
|
382
|
-
* @example
|
|
383
|
-
* ```ts
|
|
384
|
-
* new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
|
|
385
|
-
* new URLPath('/pet/{petId}').isURL // false
|
|
386
|
-
* ```
|
|
387
|
-
*/
|
|
388
|
-
get isURL() {
|
|
389
|
-
try {
|
|
390
|
-
return !!new URL(this.path).href;
|
|
391
|
-
} catch {
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
397
|
-
*
|
|
398
|
-
* @example
|
|
399
|
-
* new URLPath('/pet/{petId}').template // '`/pet/${petId}`'
|
|
400
|
-
* new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
|
|
401
|
-
*/
|
|
402
|
-
get template() {
|
|
403
|
-
return this.toTemplateString();
|
|
404
|
-
}
|
|
405
|
-
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
406
|
-
*
|
|
407
|
-
* @example
|
|
408
|
-
* ```ts
|
|
409
|
-
* new URLPath('/pet/{petId}').object
|
|
410
|
-
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
411
|
-
* ```
|
|
412
|
-
*/
|
|
413
|
-
get object() {
|
|
414
|
-
return this.toObject();
|
|
415
|
-
}
|
|
416
|
-
/** Returns a map of path parameter names, or `undefined` when the path has no parameters.
|
|
417
|
-
*
|
|
418
|
-
* @example
|
|
419
|
-
* ```ts
|
|
420
|
-
* new URLPath('/pet/{petId}').params // { petId: 'petId' }
|
|
421
|
-
* new URLPath('/pet').params // undefined
|
|
422
|
-
* ```
|
|
423
|
-
*/
|
|
424
|
-
get params() {
|
|
425
|
-
return this.getParams();
|
|
426
|
-
}
|
|
427
|
-
#transformParam(raw) {
|
|
428
|
-
const param = isValidVarName(raw) ? raw : require_PluginDriver.camelCase(raw);
|
|
429
|
-
return this.#options.casing === "camelcase" ? require_PluginDriver.camelCase(param) : param;
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
|
|
433
|
-
*/
|
|
434
|
-
#eachParam(fn) {
|
|
435
|
-
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
436
|
-
const raw = match[1];
|
|
437
|
-
fn(raw, this.#transformParam(raw));
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
toObject({ type = "path", replacer, stringify } = {}) {
|
|
441
|
-
const object = {
|
|
442
|
-
url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
|
|
443
|
-
params: this.getParams()
|
|
444
|
-
};
|
|
445
|
-
if (stringify) {
|
|
446
|
-
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
447
|
-
if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
|
|
448
|
-
return `{ url: '${object.url}' }`;
|
|
449
|
-
}
|
|
450
|
-
return object;
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
454
|
-
* An optional `replacer` can transform each extracted parameter name before interpolation.
|
|
455
|
-
*
|
|
456
|
-
* @example
|
|
457
|
-
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
458
|
-
*/
|
|
459
|
-
toTemplateString({ prefix = "", replacer } = {}) {
|
|
460
|
-
return `\`${prefix}${this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
461
|
-
if (i % 2 === 0) return part;
|
|
462
|
-
const param = this.#transformParam(part);
|
|
463
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
464
|
-
}).join("")}\``;
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
468
|
-
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
469
|
-
* Returns `undefined` when no path parameters are found.
|
|
470
|
-
*
|
|
471
|
-
* @example
|
|
472
|
-
* ```ts
|
|
473
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').getParams()
|
|
474
|
-
* // { petId: 'petId', tagId: 'tagId' }
|
|
475
|
-
* ```
|
|
476
|
-
*/
|
|
477
|
-
getParams(replacer) {
|
|
478
|
-
const params = {};
|
|
479
|
-
this.#eachParam((_raw, param) => {
|
|
480
|
-
const key = replacer ? replacer(param) : param;
|
|
481
|
-
params[key] = key;
|
|
482
|
-
});
|
|
483
|
-
return Object.keys(params).length > 0 ? params : void 0;
|
|
484
|
-
}
|
|
485
|
-
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
486
|
-
*
|
|
487
|
-
* @example
|
|
488
|
-
* ```ts
|
|
489
|
-
* new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
|
|
490
|
-
* ```
|
|
491
|
-
*/
|
|
492
|
-
toURLPath() {
|
|
493
|
-
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
//#endregion
|
|
497
251
|
//#region src/createAdapter.ts
|
|
498
252
|
/**
|
|
499
253
|
* Factory for implementing custom adapters that translate non-OpenAPI specs into Kubb's AST.
|
|
@@ -524,177 +278,8 @@ function createAdapter(build) {
|
|
|
524
278
|
return (options) => build(options ?? {});
|
|
525
279
|
}
|
|
526
280
|
//#endregion
|
|
527
|
-
//#region
|
|
528
|
-
var
|
|
529
|
-
value;
|
|
530
|
-
next;
|
|
531
|
-
constructor(value) {
|
|
532
|
-
this.value = value;
|
|
533
|
-
}
|
|
534
|
-
};
|
|
535
|
-
var Queue = class {
|
|
536
|
-
#head;
|
|
537
|
-
#tail;
|
|
538
|
-
#size;
|
|
539
|
-
constructor() {
|
|
540
|
-
this.clear();
|
|
541
|
-
}
|
|
542
|
-
enqueue(value) {
|
|
543
|
-
const node = new Node(value);
|
|
544
|
-
if (this.#head) {
|
|
545
|
-
this.#tail.next = node;
|
|
546
|
-
this.#tail = node;
|
|
547
|
-
} else {
|
|
548
|
-
this.#head = node;
|
|
549
|
-
this.#tail = node;
|
|
550
|
-
}
|
|
551
|
-
this.#size++;
|
|
552
|
-
}
|
|
553
|
-
dequeue() {
|
|
554
|
-
const current = this.#head;
|
|
555
|
-
if (!current) return;
|
|
556
|
-
this.#head = this.#head.next;
|
|
557
|
-
this.#size--;
|
|
558
|
-
if (!this.#head) this.#tail = void 0;
|
|
559
|
-
return current.value;
|
|
560
|
-
}
|
|
561
|
-
peek() {
|
|
562
|
-
if (!this.#head) return;
|
|
563
|
-
return this.#head.value;
|
|
564
|
-
}
|
|
565
|
-
clear() {
|
|
566
|
-
this.#head = void 0;
|
|
567
|
-
this.#tail = void 0;
|
|
568
|
-
this.#size = 0;
|
|
569
|
-
}
|
|
570
|
-
get size() {
|
|
571
|
-
return this.#size;
|
|
572
|
-
}
|
|
573
|
-
*[Symbol.iterator]() {
|
|
574
|
-
let current = this.#head;
|
|
575
|
-
while (current) {
|
|
576
|
-
yield current.value;
|
|
577
|
-
current = current.next;
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
*drain() {
|
|
581
|
-
while (this.#head) yield this.dequeue();
|
|
582
|
-
}
|
|
583
|
-
};
|
|
584
|
-
//#endregion
|
|
585
|
-
//#region ../../node_modules/.pnpm/p-limit@7.3.0/node_modules/p-limit/index.js
|
|
586
|
-
function pLimit(concurrency) {
|
|
587
|
-
let rejectOnClear = false;
|
|
588
|
-
if (typeof concurrency === "object") ({concurrency, rejectOnClear = false} = concurrency);
|
|
589
|
-
validateConcurrency(concurrency);
|
|
590
|
-
if (typeof rejectOnClear !== "boolean") throw new TypeError("Expected `rejectOnClear` to be a boolean");
|
|
591
|
-
const queue = new Queue();
|
|
592
|
-
let activeCount = 0;
|
|
593
|
-
const resumeNext = () => {
|
|
594
|
-
if (activeCount < concurrency && queue.size > 0) {
|
|
595
|
-
activeCount++;
|
|
596
|
-
queue.dequeue().run();
|
|
597
|
-
}
|
|
598
|
-
};
|
|
599
|
-
const next = () => {
|
|
600
|
-
activeCount--;
|
|
601
|
-
resumeNext();
|
|
602
|
-
};
|
|
603
|
-
const run = async (function_, resolve, arguments_) => {
|
|
604
|
-
const result = (async () => function_(...arguments_))();
|
|
605
|
-
resolve(result);
|
|
606
|
-
try {
|
|
607
|
-
await result;
|
|
608
|
-
} catch {}
|
|
609
|
-
next();
|
|
610
|
-
};
|
|
611
|
-
const enqueue = (function_, resolve, reject, arguments_) => {
|
|
612
|
-
const queueItem = { reject };
|
|
613
|
-
new Promise((internalResolve) => {
|
|
614
|
-
queueItem.run = internalResolve;
|
|
615
|
-
queue.enqueue(queueItem);
|
|
616
|
-
}).then(run.bind(void 0, function_, resolve, arguments_));
|
|
617
|
-
if (activeCount < concurrency) resumeNext();
|
|
618
|
-
};
|
|
619
|
-
const generator = (function_, ...arguments_) => new Promise((resolve, reject) => {
|
|
620
|
-
enqueue(function_, resolve, reject, arguments_);
|
|
621
|
-
});
|
|
622
|
-
Object.defineProperties(generator, {
|
|
623
|
-
activeCount: { get: () => activeCount },
|
|
624
|
-
pendingCount: { get: () => queue.size },
|
|
625
|
-
clearQueue: { value() {
|
|
626
|
-
if (!rejectOnClear) {
|
|
627
|
-
queue.clear();
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
const abortError = AbortSignal.abort().reason;
|
|
631
|
-
while (queue.size > 0) queue.dequeue().reject(abortError);
|
|
632
|
-
} },
|
|
633
|
-
concurrency: {
|
|
634
|
-
get: () => concurrency,
|
|
635
|
-
set(newConcurrency) {
|
|
636
|
-
validateConcurrency(newConcurrency);
|
|
637
|
-
concurrency = newConcurrency;
|
|
638
|
-
queueMicrotask(() => {
|
|
639
|
-
while (activeCount < concurrency && queue.size > 0) resumeNext();
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
},
|
|
643
|
-
map: { async value(iterable, function_) {
|
|
644
|
-
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
645
|
-
return Promise.all(promises);
|
|
646
|
-
} }
|
|
647
|
-
});
|
|
648
|
-
return generator;
|
|
649
|
-
}
|
|
650
|
-
function validateConcurrency(concurrency) {
|
|
651
|
-
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
652
|
-
}
|
|
653
|
-
//#endregion
|
|
654
|
-
//#region src/FileProcessor.ts
|
|
655
|
-
function joinSources(file) {
|
|
656
|
-
return file.sources.map((item) => (0, _kubb_ast.extractStringsFromNodes)(item.nodes)).filter(Boolean).join("\n\n");
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Converts a single file to a string using the registered parsers.
|
|
660
|
-
* Falls back to joining source values when no matching parser is found.
|
|
661
|
-
*
|
|
662
|
-
* @internal
|
|
663
|
-
*/
|
|
664
|
-
var FileProcessor = class {
|
|
665
|
-
#limit = pLimit(100);
|
|
666
|
-
async parse(file, { parsers, extension } = {}) {
|
|
667
|
-
const parseExtName = extension?.[file.extname] || void 0;
|
|
668
|
-
if (!parsers || !file.extname) return joinSources(file);
|
|
669
|
-
const parser = parsers.get(file.extname);
|
|
670
|
-
if (!parser) return joinSources(file);
|
|
671
|
-
return parser.parse(file, { extname: parseExtName });
|
|
672
|
-
}
|
|
673
|
-
async run(files, { parsers, mode = "sequential", extension, onStart, onEnd, onUpdate } = {}) {
|
|
674
|
-
await onStart?.(files);
|
|
675
|
-
const total = files.length;
|
|
676
|
-
let processed = 0;
|
|
677
|
-
const processOne = async (file) => {
|
|
678
|
-
const source = await this.parse(file, {
|
|
679
|
-
extension,
|
|
680
|
-
parsers
|
|
681
|
-
});
|
|
682
|
-
const currentProcessed = ++processed;
|
|
683
|
-
const percentage = currentProcessed / total * 100;
|
|
684
|
-
await onUpdate?.({
|
|
685
|
-
file,
|
|
686
|
-
source,
|
|
687
|
-
processed: currentProcessed,
|
|
688
|
-
percentage,
|
|
689
|
-
total
|
|
690
|
-
});
|
|
691
|
-
};
|
|
692
|
-
if (mode === "sequential") for (const file of files) await processOne(file);
|
|
693
|
-
else await Promise.all(files.map((file) => this.#limit(() => processOne(file))));
|
|
694
|
-
await onEnd?.(files);
|
|
695
|
-
return files;
|
|
696
|
-
}
|
|
697
|
-
};
|
|
281
|
+
//#region package.json
|
|
282
|
+
var version = "5.0.0-beta.20";
|
|
698
283
|
//#endregion
|
|
699
284
|
//#region src/createStorage.ts
|
|
700
285
|
/**
|
|
@@ -733,13 +318,63 @@ function createStorage(build) {
|
|
|
733
318
|
return (options) => build(options ?? {});
|
|
734
319
|
}
|
|
735
320
|
//#endregion
|
|
736
|
-
//#region src/
|
|
321
|
+
//#region src/FileProcessor.ts
|
|
322
|
+
function joinSources(file) {
|
|
323
|
+
const sources = file.sources;
|
|
324
|
+
if (sources.length === 0) return "";
|
|
325
|
+
const parts = [];
|
|
326
|
+
for (const source of sources) {
|
|
327
|
+
const s = (0, _kubb_ast.extractStringsFromNodes)(source.nodes);
|
|
328
|
+
if (s) parts.push(s);
|
|
329
|
+
}
|
|
330
|
+
return parts.join("\n\n");
|
|
331
|
+
}
|
|
737
332
|
/**
|
|
738
|
-
*
|
|
333
|
+
* Converts a single file to a string using the registered parsers.
|
|
334
|
+
* Falls back to joining source values when no matching parser is found.
|
|
335
|
+
*
|
|
336
|
+
* @internal
|
|
739
337
|
*/
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
}
|
|
338
|
+
var FileProcessor = class {
|
|
339
|
+
events = new AsyncEventEmitter();
|
|
340
|
+
parse(file, { parsers, extension } = {}) {
|
|
341
|
+
const parseExtName = extension?.[file.extname] || void 0;
|
|
342
|
+
if (!parsers || !file.extname) return joinSources(file);
|
|
343
|
+
const parser = parsers.get(file.extname);
|
|
344
|
+
if (!parser) return joinSources(file);
|
|
345
|
+
return parser.parse(file, { extname: parseExtName });
|
|
346
|
+
}
|
|
347
|
+
*stream(files, options = {}) {
|
|
348
|
+
const total = files.length;
|
|
349
|
+
if (total === 0) return;
|
|
350
|
+
let processed = 0;
|
|
351
|
+
for (const file of files) {
|
|
352
|
+
const source = this.parse(file, options);
|
|
353
|
+
processed++;
|
|
354
|
+
yield {
|
|
355
|
+
file,
|
|
356
|
+
source,
|
|
357
|
+
processed,
|
|
358
|
+
total,
|
|
359
|
+
percentage: processed / total * 100
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async run(files, options = {}) {
|
|
364
|
+
await this.events.emit("start", files);
|
|
365
|
+
for (const { file, source, processed, total, percentage } of this.stream(files, options)) await this.events.emit("update", {
|
|
366
|
+
file,
|
|
367
|
+
source,
|
|
368
|
+
processed,
|
|
369
|
+
percentage,
|
|
370
|
+
total
|
|
371
|
+
});
|
|
372
|
+
await this.events.emit("end", files);
|
|
373
|
+
return files;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
//#endregion
|
|
377
|
+
//#region src/storages/fsStorage.ts
|
|
743
378
|
/**
|
|
744
379
|
* Built-in filesystem storage driver.
|
|
745
380
|
*
|
|
@@ -771,17 +406,15 @@ const fsStorage = createStorage(() => ({
|
|
|
771
406
|
try {
|
|
772
407
|
await (0, node_fs_promises.access)((0, node_path.resolve)(key));
|
|
773
408
|
return true;
|
|
774
|
-
} catch (
|
|
775
|
-
|
|
776
|
-
throw new Error(`Failed to access storage item "${key}"`, { cause: error });
|
|
409
|
+
} catch (_error) {
|
|
410
|
+
return false;
|
|
777
411
|
}
|
|
778
412
|
},
|
|
779
413
|
async getItem(key) {
|
|
780
414
|
try {
|
|
781
415
|
return await (0, node_fs_promises.readFile)((0, node_path.resolve)(key), "utf8");
|
|
782
|
-
} catch (
|
|
783
|
-
|
|
784
|
-
throw new Error(`Failed to read storage item "${key}"`, { cause: error });
|
|
416
|
+
} catch (_error) {
|
|
417
|
+
return null;
|
|
785
418
|
}
|
|
786
419
|
},
|
|
787
420
|
async setItem(key, value) {
|
|
@@ -791,23 +424,22 @@ const fsStorage = createStorage(() => ({
|
|
|
791
424
|
await (0, node_fs_promises.rm)((0, node_path.resolve)(key), { force: true });
|
|
792
425
|
},
|
|
793
426
|
async getKeys(base) {
|
|
794
|
-
const keys = [];
|
|
795
427
|
const resolvedBase = (0, node_path.resolve)(base ?? process.cwd());
|
|
796
|
-
async function walk(dir, prefix) {
|
|
428
|
+
async function* walk(dir, prefix) {
|
|
797
429
|
let entries;
|
|
798
430
|
try {
|
|
799
431
|
entries = await (0, node_fs_promises.readdir)(dir, { withFileTypes: true });
|
|
800
|
-
} catch (
|
|
801
|
-
|
|
802
|
-
throw new Error(`Failed to list storage keys under "${resolvedBase}"`, { cause: error });
|
|
432
|
+
} catch (_error) {
|
|
433
|
+
return;
|
|
803
434
|
}
|
|
804
435
|
for (const entry of entries) {
|
|
805
436
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
806
|
-
if (entry.isDirectory())
|
|
807
|
-
else
|
|
437
|
+
if (entry.isDirectory()) yield* walk((0, node_path.join)(dir, entry.name), rel);
|
|
438
|
+
else yield rel;
|
|
808
439
|
}
|
|
809
440
|
}
|
|
810
|
-
|
|
441
|
+
const keys = [];
|
|
442
|
+
for await (const key of walk(resolvedBase, "")) keys.push(key);
|
|
811
443
|
return keys;
|
|
812
444
|
},
|
|
813
445
|
async clear(base) {
|
|
@@ -816,37 +448,128 @@ const fsStorage = createStorage(() => ({
|
|
|
816
448
|
}
|
|
817
449
|
}));
|
|
818
450
|
//#endregion
|
|
819
|
-
//#region
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
451
|
+
//#region \0@oxc-project+runtime@0.129.0/helpers/usingCtx.js
|
|
452
|
+
function _usingCtx() {
|
|
453
|
+
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
454
|
+
var n = Error();
|
|
455
|
+
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
456
|
+
};
|
|
457
|
+
var e = {};
|
|
458
|
+
var n = [];
|
|
459
|
+
function using(r, e) {
|
|
460
|
+
if (null != e) {
|
|
461
|
+
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
462
|
+
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
463
|
+
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
464
|
+
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
465
|
+
t && (o = function o() {
|
|
466
|
+
try {
|
|
467
|
+
t.call(e);
|
|
468
|
+
} catch (r) {
|
|
469
|
+
return Promise.reject(r);
|
|
470
|
+
}
|
|
471
|
+
}), n.push({
|
|
472
|
+
v: e,
|
|
473
|
+
d: o,
|
|
474
|
+
a: r
|
|
475
|
+
});
|
|
476
|
+
} else r && n.push({
|
|
477
|
+
d: e,
|
|
478
|
+
a: r
|
|
479
|
+
});
|
|
480
|
+
return e;
|
|
481
|
+
}
|
|
830
482
|
return {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
483
|
+
e,
|
|
484
|
+
u: using.bind(null, !1),
|
|
485
|
+
a: using.bind(null, !0),
|
|
486
|
+
d: function d() {
|
|
487
|
+
var o;
|
|
488
|
+
var t = this.e;
|
|
489
|
+
var s = 0;
|
|
490
|
+
function next() {
|
|
491
|
+
for (; o = n.pop();) try {
|
|
492
|
+
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
493
|
+
if (o.d) {
|
|
494
|
+
var r = o.d.call(o.v);
|
|
495
|
+
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
496
|
+
} else s |= 1;
|
|
497
|
+
} catch (r) {
|
|
498
|
+
return err(r);
|
|
499
|
+
}
|
|
500
|
+
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
501
|
+
if (t !== e) throw t;
|
|
502
|
+
}
|
|
503
|
+
function err(n) {
|
|
504
|
+
return t = t !== e ? new r(n, t) : n, next();
|
|
505
|
+
}
|
|
506
|
+
return next();
|
|
507
|
+
}
|
|
836
508
|
};
|
|
837
509
|
}
|
|
838
510
|
//#endregion
|
|
839
|
-
//#region src/utils/isInputPath.ts
|
|
840
|
-
function isInputPath(config) {
|
|
841
|
-
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
842
|
-
}
|
|
843
|
-
//#endregion
|
|
844
511
|
//#region src/createKubb.ts
|
|
512
|
+
/**
|
|
513
|
+
* Builds a `Storage` view scoped to the file paths produced by the current build.
|
|
514
|
+
*
|
|
515
|
+
* Reads delegate to the underlying `storage` (typically `fsStorage()`) so source bytes
|
|
516
|
+
* stay where they were written instead of being held in an extra in-memory map.
|
|
517
|
+
* Writing via `setItem` stores the content in the underlying storage and registers the
|
|
518
|
+
* key so subsequent reads and `getKeys` are scoped to this build's output.
|
|
519
|
+
*/
|
|
520
|
+
function createSourcesView(storage) {
|
|
521
|
+
const paths = /* @__PURE__ */ new Set();
|
|
522
|
+
return createStorage(() => ({
|
|
523
|
+
name: `${storage.name}:sources`,
|
|
524
|
+
async hasItem(key) {
|
|
525
|
+
return paths.has(key) && await storage.hasItem(key);
|
|
526
|
+
},
|
|
527
|
+
async getItem(key) {
|
|
528
|
+
return paths.has(key) ? storage.getItem(key) : null;
|
|
529
|
+
},
|
|
530
|
+
async setItem(key, value) {
|
|
531
|
+
paths.add(key);
|
|
532
|
+
await storage.setItem(key, value);
|
|
533
|
+
},
|
|
534
|
+
async removeItem(key) {
|
|
535
|
+
paths.delete(key);
|
|
536
|
+
await storage.removeItem(key);
|
|
537
|
+
},
|
|
538
|
+
async getKeys(base) {
|
|
539
|
+
if (!base) return [...paths];
|
|
540
|
+
const result = [];
|
|
541
|
+
for (const key of paths) if (key.startsWith(base)) result.push(key);
|
|
542
|
+
return result;
|
|
543
|
+
},
|
|
544
|
+
async clear() {
|
|
545
|
+
paths.clear();
|
|
546
|
+
await storage.clear();
|
|
547
|
+
}
|
|
548
|
+
}))();
|
|
549
|
+
}
|
|
845
550
|
async function setup(userConfig, options = {}) {
|
|
846
551
|
const hooks = options.hooks ?? new AsyncEventEmitter();
|
|
847
|
-
const
|
|
552
|
+
const config = {
|
|
553
|
+
...userConfig,
|
|
554
|
+
root: userConfig.root || process.cwd(),
|
|
555
|
+
parsers: userConfig.parsers ?? [],
|
|
556
|
+
output: {
|
|
557
|
+
format: false,
|
|
558
|
+
lint: false,
|
|
559
|
+
extension: require_KubbDriver.DEFAULT_EXTENSION,
|
|
560
|
+
defaultBanner: require_KubbDriver.DEFAULT_BANNER,
|
|
561
|
+
...userConfig.output
|
|
562
|
+
},
|
|
563
|
+
storage: userConfig.storage ?? fsStorage(),
|
|
564
|
+
devtools: userConfig.devtools ? {
|
|
565
|
+
studioUrl: require_KubbDriver.DEFAULT_STUDIO_URL,
|
|
566
|
+
...typeof userConfig.devtools === "boolean" ? {} : userConfig.devtools
|
|
567
|
+
} : void 0,
|
|
568
|
+
plugins: userConfig.plugins ?? []
|
|
569
|
+
};
|
|
570
|
+
const driver = new require_KubbDriver.KubbDriver(config, { hooks });
|
|
571
|
+
const storage = createSourcesView(config.storage);
|
|
848
572
|
const diagnosticInfo = getDiagnosticInfo();
|
|
849
|
-
if (Array.isArray(userConfig.input)) await hooks.emit("kubb:warn", { message: "This feature is still under development — use with caution" });
|
|
850
573
|
await hooks.emit("kubb:debug", {
|
|
851
574
|
date: /* @__PURE__ */ new Date(),
|
|
852
575
|
logs: [
|
|
@@ -856,15 +579,16 @@ async function setup(userConfig, options = {}) {
|
|
|
856
579
|
` • Output: ${userConfig.output?.path || "not specified"}`,
|
|
857
580
|
` • Plugins: ${userConfig.plugins?.length || 0}`,
|
|
858
581
|
"Output Settings:",
|
|
859
|
-
` • Storage: ${
|
|
582
|
+
` • Storage: ${config.storage.name}`,
|
|
860
583
|
` • Formatter: ${userConfig.output?.format || "none"}`,
|
|
861
584
|
` • Linter: ${userConfig.output?.lint || "none"}`,
|
|
585
|
+
`Running adapter: ${config.adapter?.name || "none"}`,
|
|
862
586
|
"Environment:",
|
|
863
587
|
Object.entries(diagnosticInfo).map(([key, value]) => ` • ${key}: ${value}`).join("\n")
|
|
864
588
|
]
|
|
865
589
|
});
|
|
866
590
|
try {
|
|
867
|
-
if (isInputPath(userConfig) && !new URLPath(userConfig.input.path).isURL) {
|
|
591
|
+
if (isInputPath(userConfig) && !new require_KubbDriver.URLPath(userConfig.input.path).isURL) {
|
|
868
592
|
await exists(userConfig.input.path);
|
|
869
593
|
await hooks.emit("kubb:debug", {
|
|
870
594
|
date: /* @__PURE__ */ new Date(),
|
|
@@ -877,188 +601,304 @@ async function setup(userConfig, options = {}) {
|
|
|
877
601
|
throw new Error(`Cannot read file/URL defined in \`input.path\` or set with \`kubb generate PATH\` in the CLI of your Kubb config ${userConfig.input.path}`, { cause: error });
|
|
878
602
|
}
|
|
879
603
|
}
|
|
880
|
-
if (!userConfig.adapter) throw new Error("Adapter should be defined");
|
|
881
|
-
const config = {
|
|
882
|
-
...userConfig,
|
|
883
|
-
root: userConfig.root || process.cwd(),
|
|
884
|
-
parsers: userConfig.parsers ?? [],
|
|
885
|
-
adapter: userConfig.adapter,
|
|
886
|
-
output: {
|
|
887
|
-
format: false,
|
|
888
|
-
lint: false,
|
|
889
|
-
write: true,
|
|
890
|
-
extension: require_PluginDriver.DEFAULT_EXTENSION,
|
|
891
|
-
defaultBanner: require_PluginDriver.DEFAULT_BANNER,
|
|
892
|
-
...userConfig.output
|
|
893
|
-
},
|
|
894
|
-
devtools: userConfig.devtools ? {
|
|
895
|
-
studioUrl: require_PluginDriver.DEFAULT_STUDIO_URL,
|
|
896
|
-
...typeof userConfig.devtools === "boolean" ? {} : userConfig.devtools
|
|
897
|
-
} : void 0,
|
|
898
|
-
plugins: userConfig.plugins
|
|
899
|
-
};
|
|
900
|
-
const storage = config.output.write === false ? null : config.storage ?? fsStorage();
|
|
901
604
|
if (config.output.clean) {
|
|
902
605
|
await hooks.emit("kubb:debug", {
|
|
903
606
|
date: /* @__PURE__ */ new Date(),
|
|
904
607
|
logs: ["Cleaning output directories", ` • Output: ${config.output.path}`]
|
|
905
608
|
});
|
|
906
|
-
await storage
|
|
609
|
+
await config.storage.clear((0, node_path.resolve)(config.root, config.output.path));
|
|
907
610
|
}
|
|
908
|
-
|
|
909
|
-
function registerMiddlewareHook(event, middlewareHooks) {
|
|
910
|
-
const handler = middlewareHooks[event];
|
|
911
|
-
if (handler) hooks.on(event, handler);
|
|
912
|
-
}
|
|
913
|
-
for (const middleware of config.middleware ?? []) for (const event of Object.keys(middleware.hooks)) registerMiddlewareHook(event, middleware.hooks);
|
|
914
|
-
const adapter = config.adapter;
|
|
915
|
-
if (!adapter) throw new Error("No adapter configured. Please provide an adapter in your kubb.config.ts.");
|
|
916
|
-
const source = inputToAdapterSource(config);
|
|
917
|
-
await hooks.emit("kubb:debug", {
|
|
918
|
-
date: /* @__PURE__ */ new Date(),
|
|
919
|
-
logs: [`Running adapter: ${adapter.name}`]
|
|
920
|
-
});
|
|
921
|
-
driver.adapter = adapter;
|
|
922
|
-
driver.inputNode = await adapter.parse(source);
|
|
923
|
-
await hooks.emit("kubb:debug", {
|
|
924
|
-
date: /* @__PURE__ */ new Date(),
|
|
925
|
-
logs: [
|
|
926
|
-
`✓ Adapter '${adapter.name}' resolved InputNode`,
|
|
927
|
-
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
928
|
-
` • Operations: ${driver.inputNode.operations.length}`
|
|
929
|
-
]
|
|
930
|
-
});
|
|
611
|
+
await driver.setup();
|
|
931
612
|
return {
|
|
932
613
|
config,
|
|
933
614
|
hooks,
|
|
934
615
|
driver,
|
|
935
|
-
|
|
936
|
-
|
|
616
|
+
storage,
|
|
617
|
+
dispose,
|
|
618
|
+
[Symbol.dispose]: dispose
|
|
937
619
|
};
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
* Walks the AST and dispatches nodes to a plugin's direct AST hooks
|
|
941
|
-
* (`schema`, `operation`, `operations`).
|
|
942
|
-
*
|
|
943
|
-
* When `include` contains only operation-scoped filters (`tag`, `operationId`, `path`,
|
|
944
|
-
* `method`, `contentType`) and no `schemaName` filter, the function pre-computes the set
|
|
945
|
-
* of top-level schema names transitively reachable from the included operations and skips
|
|
946
|
-
* schemas that fall outside that set. This ensures that component schemas referenced
|
|
947
|
-
* exclusively by excluded operations are not generated.
|
|
948
|
-
*/
|
|
949
|
-
async function runPluginAstHooks(plugin, context) {
|
|
950
|
-
const { adapter, inputNode, resolver, driver } = context;
|
|
951
|
-
const { exclude, include, override } = plugin.options;
|
|
952
|
-
if (!adapter || !inputNode) throw new Error(`[${plugin.name}] No adapter found. Add an OAS adapter (e.g. pluginOas()) before this plugin in your Kubb config.`);
|
|
953
|
-
function resolveRenderer(gen) {
|
|
954
|
-
return gen.renderer === null ? void 0 : gen.renderer ?? plugin.renderer ?? context.config.renderer;
|
|
620
|
+
function dispose() {
|
|
621
|
+
driver.dispose();
|
|
955
622
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
include,
|
|
976
|
-
override
|
|
977
|
-
}) !== null), inputNode.schemas);
|
|
978
|
-
await (0, _kubb_ast.walk)(inputNode, {
|
|
979
|
-
depth: "shallow",
|
|
980
|
-
async schema(node) {
|
|
981
|
-
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
982
|
-
if (allowedSchemaNames !== void 0 && transformedNode.name && !allowedSchemaNames.has(transformedNode.name)) return;
|
|
983
|
-
const options = resolver.resolveOptions(transformedNode, {
|
|
984
|
-
options: plugin.options,
|
|
985
|
-
exclude,
|
|
986
|
-
include,
|
|
987
|
-
override
|
|
623
|
+
}
|
|
624
|
+
async function safeBuild(setupResult) {
|
|
625
|
+
try {
|
|
626
|
+
var _usingCtx$1 = _usingCtx();
|
|
627
|
+
_usingCtx$1.u(setupResult);
|
|
628
|
+
const { driver, hooks, storage } = setupResult;
|
|
629
|
+
const failedPlugins = /* @__PURE__ */ new Set();
|
|
630
|
+
const pluginTimings = /* @__PURE__ */ new Map();
|
|
631
|
+
const config = driver.config;
|
|
632
|
+
const writtenPaths = /* @__PURE__ */ new Set();
|
|
633
|
+
const parsersMap = /* @__PURE__ */ new Map();
|
|
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);
|
|
636
|
+
async function flushPendingFiles() {
|
|
637
|
+
const files = driver.fileManager.files.filter((f) => !writtenPaths.has(f.path));
|
|
638
|
+
if (files.length === 0) return;
|
|
639
|
+
await hooks.emit("kubb:debug", {
|
|
640
|
+
date: /* @__PURE__ */ new Date(),
|
|
641
|
+
logs: [`Writing ${files.length} files...`]
|
|
988
642
|
});
|
|
989
|
-
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
};
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
643
|
+
await hooks.emit("kubb:files:processing:start", { files });
|
|
644
|
+
const stream = fileProcessor.stream(files, {
|
|
645
|
+
parsers: parsersMap,
|
|
646
|
+
extension: config.output.extension
|
|
647
|
+
});
|
|
648
|
+
const queue = [];
|
|
649
|
+
for (const { file, source, processed, total, percentage } of stream) {
|
|
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));
|
|
997
663
|
}
|
|
998
|
-
await
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
options: plugin.options,
|
|
1004
|
-
exclude,
|
|
1005
|
-
include,
|
|
1006
|
-
override
|
|
664
|
+
await Promise.all(queue);
|
|
665
|
+
await hooks.emit("kubb:files:processing:end", { files });
|
|
666
|
+
await hooks.emit("kubb:debug", {
|
|
667
|
+
date: /* @__PURE__ */ new Date(),
|
|
668
|
+
logs: [`✓ File write process completed for ${files.length} files`]
|
|
1007
669
|
});
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
670
|
+
}
|
|
671
|
+
async function dispatchOperationsToGenerators(generators, collectedOperations, ctx, rendererFor) {
|
|
672
|
+
for (const gen of generators) {
|
|
673
|
+
if (!gen.operations) continue;
|
|
674
|
+
await require_KubbDriver.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
|
|
1013
714
|
};
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
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);
|
|
1017
732
|
}
|
|
1018
|
-
|
|
733
|
+
for (const state of pruningStates) state.allowedSchemaNames = (0, _kubb_ast.collectUsedSchemaNames)(includedOpsByState.get(state) ?? [], allSchemas);
|
|
1019
734
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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 ? (0, _kubb_ast.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 = require_KubbDriver.applyHookResult({
|
|
760
|
+
result: require_KubbDriver.isPromise(raw) ? await raw : raw,
|
|
761
|
+
driver,
|
|
762
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
763
|
+
});
|
|
764
|
+
if (require_KubbDriver.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 ? (0, _kubb_ast.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 = require_KubbDriver.applyHookResult({
|
|
793
|
+
result: require_KubbDriver.isPromise(raw) ? await raw : raw,
|
|
794
|
+
driver,
|
|
795
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
796
|
+
});
|
|
797
|
+
if (require_KubbDriver.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 require_KubbDriver.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 require_KubbDriver.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
|
|
1060
844
|
});
|
|
1061
|
-
|
|
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
|
+
}
|
|
851
|
+
try {
|
|
852
|
+
await driver.emitSetupHooks();
|
|
853
|
+
if (driver.adapter && driver.inputNode) await hooks.emit("kubb:build:start", {
|
|
854
|
+
config,
|
|
855
|
+
adapter: driver.adapter,
|
|
856
|
+
meta: driver.inputNode.meta,
|
|
857
|
+
getPlugin: driver.getPlugin.bind(driver),
|
|
858
|
+
get files() {
|
|
859
|
+
return driver.fileManager.files;
|
|
860
|
+
},
|
|
861
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
862
|
+
});
|
|
863
|
+
const generatorPlugins = [];
|
|
864
|
+
for (const plugin of driver.plugins.values()) {
|
|
865
|
+
const context = driver.getContext(plugin);
|
|
866
|
+
const hrStart = process.hrtime();
|
|
867
|
+
try {
|
|
868
|
+
await hooks.emit("kubb:plugin:start", { plugin });
|
|
869
|
+
await hooks.emit("kubb:debug", {
|
|
870
|
+
date: /* @__PURE__ */ new Date(),
|
|
871
|
+
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
872
|
+
});
|
|
873
|
+
} catch (caughtError) {
|
|
874
|
+
const error = caughtError;
|
|
875
|
+
const duration = getElapsedMs(hrStart);
|
|
876
|
+
pluginTimings.set(plugin.name, duration);
|
|
877
|
+
await hooks.emit("kubb:plugin:end", {
|
|
878
|
+
plugin,
|
|
879
|
+
duration,
|
|
880
|
+
success: false,
|
|
881
|
+
error,
|
|
882
|
+
config,
|
|
883
|
+
get files() {
|
|
884
|
+
return driver.fileManager.files;
|
|
885
|
+
},
|
|
886
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
887
|
+
});
|
|
888
|
+
failedPlugins.add({
|
|
889
|
+
plugin,
|
|
890
|
+
error
|
|
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;
|
|
901
|
+
}
|
|
1062
902
|
const duration = getElapsedMs(hrStart);
|
|
1063
903
|
pluginTimings.set(plugin.name, duration);
|
|
1064
904
|
await hooks.emit("kubb:plugin:end", {
|
|
@@ -1075,107 +915,61 @@ async function safeBuild(setupResult) {
|
|
|
1075
915
|
date: /* @__PURE__ */ new Date(),
|
|
1076
916
|
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1077
917
|
});
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
|
|
918
|
+
}
|
|
919
|
+
if (generatorPlugins.length > 0) if (driver.inputNode) await require_KubbDriver.withDrain(() => runPlugins(generatorPlugins), flushPendingFiles);
|
|
920
|
+
else for (const { plugin, hrStart } of generatorPlugins) {
|
|
1081
921
|
const duration = getElapsedMs(hrStart);
|
|
922
|
+
pluginTimings.set(plugin.name, duration);
|
|
1082
923
|
await hooks.emit("kubb:plugin:end", {
|
|
1083
924
|
plugin,
|
|
1084
925
|
duration,
|
|
1085
|
-
success:
|
|
1086
|
-
error,
|
|
926
|
+
success: true,
|
|
1087
927
|
config,
|
|
1088
928
|
get files() {
|
|
1089
929
|
return driver.fileManager.files;
|
|
1090
930
|
},
|
|
1091
931
|
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1092
932
|
});
|
|
1093
|
-
await hooks.emit("kubb:debug", {
|
|
1094
|
-
date: errorTimestamp,
|
|
1095
|
-
logs: [
|
|
1096
|
-
"✗ Plugin start failed",
|
|
1097
|
-
` • Plugin Name: ${plugin.name}`,
|
|
1098
|
-
` • Error: ${error.constructor.name} - ${error.message}`,
|
|
1099
|
-
" • Stack Trace:",
|
|
1100
|
-
error.stack || "No stack trace available"
|
|
1101
|
-
]
|
|
1102
|
-
});
|
|
1103
|
-
failedPlugins.add({
|
|
1104
|
-
plugin,
|
|
1105
|
-
error
|
|
1106
|
-
});
|
|
1107
933
|
}
|
|
934
|
+
await hooks.emit("kubb:plugins:end", {
|
|
935
|
+
config,
|
|
936
|
+
get files() {
|
|
937
|
+
return driver.fileManager.files;
|
|
938
|
+
},
|
|
939
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
940
|
+
});
|
|
941
|
+
await flushPendingFiles();
|
|
942
|
+
const files = driver.fileManager.files;
|
|
943
|
+
await hooks.emit("kubb:build:end", {
|
|
944
|
+
files,
|
|
945
|
+
config,
|
|
946
|
+
outputDir: (0, node_path.resolve)(config.root, config.output.path)
|
|
947
|
+
});
|
|
948
|
+
return {
|
|
949
|
+
failedPlugins,
|
|
950
|
+
files,
|
|
951
|
+
driver,
|
|
952
|
+
pluginTimings,
|
|
953
|
+
storage
|
|
954
|
+
};
|
|
955
|
+
} catch (error) {
|
|
956
|
+
return {
|
|
957
|
+
failedPlugins,
|
|
958
|
+
files: [],
|
|
959
|
+
driver,
|
|
960
|
+
pluginTimings,
|
|
961
|
+
error,
|
|
962
|
+
storage
|
|
963
|
+
};
|
|
1108
964
|
}
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
get files() {
|
|
1112
|
-
return driver.fileManager.files;
|
|
1113
|
-
},
|
|
1114
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1115
|
-
});
|
|
1116
|
-
const files = driver.fileManager.files;
|
|
1117
|
-
const parsersMap = /* @__PURE__ */ new Map();
|
|
1118
|
-
for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
|
|
1119
|
-
const fileProcessor = new FileProcessor();
|
|
1120
|
-
await hooks.emit("kubb:debug", {
|
|
1121
|
-
date: /* @__PURE__ */ new Date(),
|
|
1122
|
-
logs: [`Writing ${files.length} files...`]
|
|
1123
|
-
});
|
|
1124
|
-
await fileProcessor.run(files, {
|
|
1125
|
-
parsers: parsersMap,
|
|
1126
|
-
extension: config.output.extension,
|
|
1127
|
-
onStart: async (processingFiles) => {
|
|
1128
|
-
await hooks.emit("kubb:files:processing:start", { files: processingFiles });
|
|
1129
|
-
},
|
|
1130
|
-
onUpdate: async ({ file, source, processed, total, percentage }) => {
|
|
1131
|
-
await hooks.emit("kubb:file:processing:update", {
|
|
1132
|
-
file,
|
|
1133
|
-
source,
|
|
1134
|
-
processed,
|
|
1135
|
-
total,
|
|
1136
|
-
percentage,
|
|
1137
|
-
config
|
|
1138
|
-
});
|
|
1139
|
-
if (source) {
|
|
1140
|
-
await storage?.setItem(file.path, source);
|
|
1141
|
-
sources.set(file.path, source);
|
|
1142
|
-
}
|
|
1143
|
-
},
|
|
1144
|
-
onEnd: async (processedFiles) => {
|
|
1145
|
-
await hooks.emit("kubb:files:processing:end", { files: processedFiles });
|
|
1146
|
-
await hooks.emit("kubb:debug", {
|
|
1147
|
-
date: /* @__PURE__ */ new Date(),
|
|
1148
|
-
logs: [`✓ File write process completed for ${processedFiles.length} files`]
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
});
|
|
1152
|
-
await hooks.emit("kubb:build:end", {
|
|
1153
|
-
files,
|
|
1154
|
-
config,
|
|
1155
|
-
outputDir: (0, node_path.resolve)(config.root, config.output.path)
|
|
1156
|
-
});
|
|
1157
|
-
return {
|
|
1158
|
-
failedPlugins,
|
|
1159
|
-
files,
|
|
1160
|
-
driver,
|
|
1161
|
-
pluginTimings,
|
|
1162
|
-
sources
|
|
1163
|
-
};
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
return {
|
|
1166
|
-
failedPlugins,
|
|
1167
|
-
files: [],
|
|
1168
|
-
driver,
|
|
1169
|
-
pluginTimings,
|
|
1170
|
-
error,
|
|
1171
|
-
sources
|
|
1172
|
-
};
|
|
965
|
+
} catch (_) {
|
|
966
|
+
_usingCtx$1.e = _;
|
|
1173
967
|
} finally {
|
|
1174
|
-
|
|
968
|
+
_usingCtx$1.d();
|
|
1175
969
|
}
|
|
1176
970
|
}
|
|
1177
971
|
async function build(setupResult) {
|
|
1178
|
-
const { files, driver, failedPlugins, pluginTimings, error,
|
|
972
|
+
const { files, driver, failedPlugins, pluginTimings, error, storage } = await safeBuild(setupResult);
|
|
1179
973
|
if (error) throw error;
|
|
1180
974
|
if (failedPlugins.size > 0) {
|
|
1181
975
|
const errors = [...failedPlugins].map(({ error }) => error);
|
|
@@ -1187,32 +981,32 @@ async function build(setupResult) {
|
|
|
1187
981
|
driver,
|
|
1188
982
|
pluginTimings,
|
|
1189
983
|
error: void 0,
|
|
1190
|
-
|
|
984
|
+
storage
|
|
1191
985
|
};
|
|
1192
986
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
data: config.input.data
|
|
1201
|
-
};
|
|
1202
|
-
if (new URLPath(config.input.path).isURL) return {
|
|
1203
|
-
type: "path",
|
|
1204
|
-
path: config.input.path
|
|
1205
|
-
};
|
|
987
|
+
/**
|
|
988
|
+
* Returns a snapshot of the current runtime environment.
|
|
989
|
+
*
|
|
990
|
+
* Useful for attaching context to debug logs and error reports so that
|
|
991
|
+
* issues can be reproduced without manual information gathering.
|
|
992
|
+
*/
|
|
993
|
+
function getDiagnosticInfo() {
|
|
1206
994
|
return {
|
|
1207
|
-
|
|
1208
|
-
|
|
995
|
+
nodeVersion: node_process.version,
|
|
996
|
+
KubbVersion: version,
|
|
997
|
+
platform: process.platform,
|
|
998
|
+
arch: process.arch,
|
|
999
|
+
cwd: process.cwd()
|
|
1209
1000
|
};
|
|
1210
1001
|
}
|
|
1002
|
+
function isInputPath(config) {
|
|
1003
|
+
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
1004
|
+
}
|
|
1211
1005
|
/**
|
|
1212
1006
|
* Creates a Kubb instance bound to a single config entry.
|
|
1213
1007
|
*
|
|
1214
1008
|
* Accepts a user-facing config shape and resolves it to a full {@link Config} during
|
|
1215
|
-
* `setup()`. The instance then holds shared state (`hooks`, `
|
|
1009
|
+
* `setup()`. The instance then holds shared state (`hooks`, `storage`, `driver`, `config`)
|
|
1216
1010
|
* across the `setup → build` lifecycle. Attach event listeners to `kubb.hooks` before
|
|
1217
1011
|
* calling `setup()` or `build()`.
|
|
1218
1012
|
*
|
|
@@ -1234,14 +1028,17 @@ function createKubb(userConfig, options = {}) {
|
|
|
1234
1028
|
get hooks() {
|
|
1235
1029
|
return hooks;
|
|
1236
1030
|
},
|
|
1237
|
-
get
|
|
1238
|
-
|
|
1031
|
+
get storage() {
|
|
1032
|
+
if (!setupResult) throw new Error("[kubb] setup() must be called before accessing storage");
|
|
1033
|
+
return setupResult.storage;
|
|
1239
1034
|
},
|
|
1240
1035
|
get driver() {
|
|
1241
|
-
|
|
1036
|
+
if (!setupResult) throw new Error("[kubb] setup() must be called before accessing driver");
|
|
1037
|
+
return setupResult.driver;
|
|
1242
1038
|
},
|
|
1243
1039
|
get config() {
|
|
1244
|
-
|
|
1040
|
+
if (!setupResult) throw new Error("[kubb] setup() must be called before accessing config");
|
|
1041
|
+
return setupResult.config;
|
|
1245
1042
|
},
|
|
1246
1043
|
async setup() {
|
|
1247
1044
|
setupResult = await setup(userConfig, { hooks });
|
|
@@ -1260,15 +1057,10 @@ function createKubb(userConfig, options = {}) {
|
|
|
1260
1057
|
//#endregion
|
|
1261
1058
|
//#region src/createRenderer.ts
|
|
1262
1059
|
/**
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1265
|
-
* Wrap your renderer factory function with this helper to register it as the
|
|
1266
|
-
* renderer for a generator. Core will call this factory once per render cycle
|
|
1267
|
-
* to obtain a fresh renderer instance.
|
|
1060
|
+
* Wraps a renderer factory for use in generator definitions.
|
|
1268
1061
|
*
|
|
1269
1062
|
* @example
|
|
1270
1063
|
* ```ts
|
|
1271
|
-
* // packages/renderer-jsx/src/index.ts
|
|
1272
1064
|
* export const jsxRenderer = createRenderer(() => {
|
|
1273
1065
|
* const runtime = new Runtime()
|
|
1274
1066
|
* return {
|
|
@@ -1277,14 +1069,6 @@ function createKubb(userConfig, options = {}) {
|
|
|
1277
1069
|
* unmount(error) { runtime.unmount(error) },
|
|
1278
1070
|
* }
|
|
1279
1071
|
* })
|
|
1280
|
-
*
|
|
1281
|
-
* // packages/plugin-zod/src/generators/zodGenerator.tsx
|
|
1282
|
-
* import { jsxRenderer } from '@kubb/renderer-jsx'
|
|
1283
|
-
* export const zodGenerator = defineGenerator<PluginZod>({
|
|
1284
|
-
* name: 'zod',
|
|
1285
|
-
* renderer: jsxRenderer,
|
|
1286
|
-
* schema(node, options) { return <File ...>...</File> },
|
|
1287
|
-
* })
|
|
1288
1072
|
* ```
|
|
1289
1073
|
*/
|
|
1290
1074
|
function createRenderer(factory) {
|
|
@@ -1305,7 +1089,11 @@ function defineGenerator(generator) {
|
|
|
1305
1089
|
/**
|
|
1306
1090
|
* Wraps a logger definition into a typed {@link Logger}.
|
|
1307
1091
|
*
|
|
1308
|
-
*
|
|
1092
|
+
* The optional second type parameter `TInstallReturn` allows loggers to return
|
|
1093
|
+
* a value from `install` — for example, a sink factory that the caller can
|
|
1094
|
+
* forward to hook execution.
|
|
1095
|
+
*
|
|
1096
|
+
* @example Basic logger
|
|
1309
1097
|
* ```ts
|
|
1310
1098
|
* export const myLogger = defineLogger({
|
|
1311
1099
|
* name: 'my-logger',
|
|
@@ -1315,6 +1103,17 @@ function defineGenerator(generator) {
|
|
|
1315
1103
|
* },
|
|
1316
1104
|
* })
|
|
1317
1105
|
* ```
|
|
1106
|
+
*
|
|
1107
|
+
* @example Logger that returns a hook sink factory
|
|
1108
|
+
* ```ts
|
|
1109
|
+
* export const myLogger = defineLogger<LoggerOptions, HookSinkFactory>({
|
|
1110
|
+
* name: 'my-logger',
|
|
1111
|
+
* install(context, options) {
|
|
1112
|
+
* // … register event handlers …
|
|
1113
|
+
* return (commandWithArgs) => ({ onStdout: console.log })
|
|
1114
|
+
* },
|
|
1115
|
+
* })
|
|
1116
|
+
* ```
|
|
1318
1117
|
*/
|
|
1319
1118
|
function defineLogger(logger) {
|
|
1320
1119
|
return logger;
|
|
@@ -1385,34 +1184,6 @@ function defineParser(parser) {
|
|
|
1385
1184
|
return parser;
|
|
1386
1185
|
}
|
|
1387
1186
|
//#endregion
|
|
1388
|
-
//#region src/definePlugin.ts
|
|
1389
|
-
/**
|
|
1390
|
-
* Wraps a factory function and returns a typed `Plugin` with lifecycle handlers grouped under `hooks`.
|
|
1391
|
-
*
|
|
1392
|
-
* Handlers live in a single `hooks` object (inspired by Astro integrations).
|
|
1393
|
-
* All lifecycle events from `KubbHooks` are available for subscription.
|
|
1394
|
-
*
|
|
1395
|
-
* @note For real plugins, use a `PluginFactoryOptions` type parameter to get type-safe context in `kubb:plugin:setup`.
|
|
1396
|
-
* Plugin names should follow the convention `plugin-<feature>` (e.g., `plugin-react-query`, `plugin-zod`).
|
|
1397
|
-
*
|
|
1398
|
-
* @example
|
|
1399
|
-
* ```ts
|
|
1400
|
-
* import { definePlugin } from '@kubb/core'
|
|
1401
|
-
*
|
|
1402
|
-
* export const pluginTs = definePlugin((options: { prefix?: string } = {}) => ({
|
|
1403
|
-
* name: 'plugin-ts',
|
|
1404
|
-
* hooks: {
|
|
1405
|
-
* 'kubb:plugin:setup'(ctx) {
|
|
1406
|
-
* ctx.setResolver(resolverTs)
|
|
1407
|
-
* },
|
|
1408
|
-
* },
|
|
1409
|
-
* }))
|
|
1410
|
-
* ```
|
|
1411
|
-
*/
|
|
1412
|
-
function definePlugin(factory) {
|
|
1413
|
-
return (options) => factory(options ?? {});
|
|
1414
|
-
}
|
|
1415
|
-
//#endregion
|
|
1416
1187
|
//#region src/storages/memoryStorage.ts
|
|
1417
1188
|
/**
|
|
1418
1189
|
* In-memory storage driver. Useful for testing and dry-run scenarios where
|
|
@@ -1464,10 +1235,10 @@ const memoryStorage = createStorage(() => {
|
|
|
1464
1235
|
});
|
|
1465
1236
|
//#endregion
|
|
1466
1237
|
exports.AsyncEventEmitter = AsyncEventEmitter;
|
|
1467
|
-
exports.FileManager =
|
|
1238
|
+
exports.FileManager = require_KubbDriver.FileManager;
|
|
1468
1239
|
exports.FileProcessor = FileProcessor;
|
|
1469
|
-
exports.
|
|
1470
|
-
exports.URLPath = URLPath;
|
|
1240
|
+
exports.KubbDriver = require_KubbDriver.KubbDriver;
|
|
1241
|
+
exports.URLPath = require_KubbDriver.URLPath;
|
|
1471
1242
|
Object.defineProperty(exports, "ast", {
|
|
1472
1243
|
enumerable: true,
|
|
1473
1244
|
get: function() {
|
|
@@ -1482,11 +1253,11 @@ exports.defineGenerator = defineGenerator;
|
|
|
1482
1253
|
exports.defineLogger = defineLogger;
|
|
1483
1254
|
exports.defineMiddleware = defineMiddleware;
|
|
1484
1255
|
exports.defineParser = defineParser;
|
|
1485
|
-
exports.definePlugin = definePlugin;
|
|
1486
|
-
exports.defineResolver =
|
|
1256
|
+
exports.definePlugin = require_KubbDriver.definePlugin;
|
|
1257
|
+
exports.defineResolver = require_KubbDriver.defineResolver;
|
|
1487
1258
|
exports.fsStorage = fsStorage;
|
|
1488
1259
|
exports.isInputPath = isInputPath;
|
|
1489
|
-
exports.logLevel =
|
|
1260
|
+
exports.logLevel = require_KubbDriver.logLevel;
|
|
1490
1261
|
exports.memoryStorage = memoryStorage;
|
|
1491
1262
|
|
|
1492
1263
|
//# sourceMappingURL=index.cjs.map
|