@kubb/core 5.0.0-beta.17 → 5.0.0-beta.19
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-C5hyNJfM.cjs → PluginDriver-DXp767s2.cjs} +77 -27
- package/dist/PluginDriver-DXp767s2.cjs.map +1 -0
- package/dist/{PluginDriver-CT33kVoQ.js → PluginDriver-uNex0SAr.js} +77 -27
- package/dist/PluginDriver-uNex0SAr.js.map +1 -0
- package/dist/{createKubb-ZgT1MTxG.d.ts → createKubb-BJGymYhe.d.ts} +224 -92
- package/dist/index.cjs +409 -291
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +409 -291
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +25 -13
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +25 -13
- package/dist/mocks.js.map +1 -1
- package/package.json +5 -5
- package/src/FileManager.ts +4 -0
- package/src/FileProcessor.ts +15 -16
- package/src/PluginDriver.ts +37 -10
- package/src/createKubb.ts +371 -179
- package/src/createRenderer.ts +23 -22
- package/src/defineParser.ts +1 -1
- package/src/defineResolver.ts +62 -60
- package/src/mocks.ts +3 -3
- package/dist/PluginDriver-C5hyNJfM.cjs.map +0 -1
- package/dist/PluginDriver-CT33kVoQ.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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 PluginDriver, u as camelCase } from "./PluginDriver-
|
|
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 PluginDriver, u as camelCase } from "./PluginDriver-uNex0SAr.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";
|
|
@@ -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,6 +248,19 @@ async function clean(path) {
|
|
|
245
248
|
});
|
|
246
249
|
}
|
|
247
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
|
|
248
264
|
//#region ../../internals/utils/src/reserved.ts
|
|
249
265
|
/**
|
|
250
266
|
* JavaScript and Java reserved words.
|
|
@@ -525,7 +541,7 @@ function createAdapter(build) {
|
|
|
525
541
|
}
|
|
526
542
|
//#endregion
|
|
527
543
|
//#region package.json
|
|
528
|
-
var version$1 = "5.0.0-beta.
|
|
544
|
+
var version$1 = "5.0.0-beta.19";
|
|
529
545
|
//#endregion
|
|
530
546
|
//#region src/createStorage.ts
|
|
531
547
|
/**
|
|
@@ -566,7 +582,14 @@ function createStorage(build) {
|
|
|
566
582
|
//#endregion
|
|
567
583
|
//#region src/FileProcessor.ts
|
|
568
584
|
function joinSources(file) {
|
|
569
|
-
|
|
585
|
+
const sources = file.sources;
|
|
586
|
+
if (sources.length === 0) return "";
|
|
587
|
+
const parts = [];
|
|
588
|
+
for (const source of sources) {
|
|
589
|
+
const s = extractStringsFromNodes(source.nodes);
|
|
590
|
+
if (s) parts.push(s);
|
|
591
|
+
}
|
|
592
|
+
return parts.join("\n\n");
|
|
570
593
|
}
|
|
571
594
|
/**
|
|
572
595
|
* Converts a single file to a string using the registered parsers.
|
|
@@ -576,25 +599,19 @@ function joinSources(file) {
|
|
|
576
599
|
*/
|
|
577
600
|
var FileProcessor = class {
|
|
578
601
|
events = new AsyncEventEmitter();
|
|
579
|
-
|
|
602
|
+
parse(file, { parsers, extension } = {}) {
|
|
580
603
|
const parseExtName = extension?.[file.extname] || void 0;
|
|
581
604
|
if (!parsers || !file.extname) return joinSources(file);
|
|
582
605
|
const parser = parsers.get(file.extname);
|
|
583
606
|
if (!parser) return joinSources(file);
|
|
584
607
|
return parser.parse(file, { extname: parseExtName });
|
|
585
608
|
}
|
|
586
|
-
|
|
587
|
-
* Streams parsed files one at a time as each is processed.
|
|
588
|
-
*
|
|
589
|
-
* Unlike `run()`, files are yielded immediately after parsing rather than batched.
|
|
590
|
-
* Storage writes can begin as soon as the first file is ready, keeping peak
|
|
591
|
-
* memory proportional to one file at a time instead of the full batch.
|
|
592
|
-
*/
|
|
593
|
-
async *stream(files, options = {}) {
|
|
609
|
+
*stream(files, options = {}) {
|
|
594
610
|
const total = files.length;
|
|
611
|
+
if (total === 0) return;
|
|
595
612
|
let processed = 0;
|
|
596
613
|
for (const file of files) {
|
|
597
|
-
const source =
|
|
614
|
+
const source = this.parse(file, options);
|
|
598
615
|
processed++;
|
|
599
616
|
yield {
|
|
600
617
|
file,
|
|
@@ -607,7 +624,7 @@ var FileProcessor = class {
|
|
|
607
624
|
}
|
|
608
625
|
async run(files, options = {}) {
|
|
609
626
|
await this.events.emit("start", files);
|
|
610
|
-
for
|
|
627
|
+
for (const { file, source, processed, total, percentage } of this.stream(files, options)) await this.events.emit("update", {
|
|
611
628
|
file,
|
|
612
629
|
source,
|
|
613
630
|
processed,
|
|
@@ -693,6 +710,66 @@ const fsStorage = createStorage(() => ({
|
|
|
693
710
|
}
|
|
694
711
|
}));
|
|
695
712
|
//#endregion
|
|
713
|
+
//#region \0@oxc-project+runtime@0.129.0/helpers/usingCtx.js
|
|
714
|
+
function _usingCtx() {
|
|
715
|
+
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
716
|
+
var n = Error();
|
|
717
|
+
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
718
|
+
};
|
|
719
|
+
var e = {};
|
|
720
|
+
var n = [];
|
|
721
|
+
function using(r, e) {
|
|
722
|
+
if (null != e) {
|
|
723
|
+
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
724
|
+
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
725
|
+
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
726
|
+
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
727
|
+
t && (o = function o() {
|
|
728
|
+
try {
|
|
729
|
+
t.call(e);
|
|
730
|
+
} catch (r) {
|
|
731
|
+
return Promise.reject(r);
|
|
732
|
+
}
|
|
733
|
+
}), n.push({
|
|
734
|
+
v: e,
|
|
735
|
+
d: o,
|
|
736
|
+
a: r
|
|
737
|
+
});
|
|
738
|
+
} else r && n.push({
|
|
739
|
+
d: e,
|
|
740
|
+
a: r
|
|
741
|
+
});
|
|
742
|
+
return e;
|
|
743
|
+
}
|
|
744
|
+
return {
|
|
745
|
+
e,
|
|
746
|
+
u: using.bind(null, !1),
|
|
747
|
+
a: using.bind(null, !0),
|
|
748
|
+
d: function d() {
|
|
749
|
+
var o;
|
|
750
|
+
var t = this.e;
|
|
751
|
+
var s = 0;
|
|
752
|
+
function next() {
|
|
753
|
+
for (; o = n.pop();) try {
|
|
754
|
+
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
755
|
+
if (o.d) {
|
|
756
|
+
var r = o.d.call(o.v);
|
|
757
|
+
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
758
|
+
} else s |= 1;
|
|
759
|
+
} catch (r) {
|
|
760
|
+
return err(r);
|
|
761
|
+
}
|
|
762
|
+
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
763
|
+
if (t !== e) throw t;
|
|
764
|
+
}
|
|
765
|
+
function err(n) {
|
|
766
|
+
return t = t !== e ? new r(n, t) : n, next();
|
|
767
|
+
}
|
|
768
|
+
return next();
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
//#endregion
|
|
696
773
|
//#region src/createKubb.ts
|
|
697
774
|
/**
|
|
698
775
|
* Builds a `Storage` view scoped to the file paths produced by the current build.
|
|
@@ -821,18 +898,9 @@ async function setup(userConfig, options = {}) {
|
|
|
821
898
|
` • Operations: ${operationCount}`
|
|
822
899
|
]
|
|
823
900
|
});
|
|
824
|
-
} else {
|
|
825
|
-
driver.inputNode = await config.adapter.parse(source);
|
|
826
|
-
await hooks.emit("kubb:debug", {
|
|
827
|
-
date: /* @__PURE__ */ new Date(),
|
|
828
|
-
logs: [
|
|
829
|
-
`✓ Adapter '${config.adapter.name}' resolved InputNode`,
|
|
830
|
-
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
831
|
-
` • Operations: ${driver.inputNode.operations.length}`
|
|
832
|
-
]
|
|
833
|
-
});
|
|
834
901
|
}
|
|
835
|
-
}
|
|
902
|
+
}
|
|
903
|
+
if (!driver.inputStreamNode) {
|
|
836
904
|
driver.inputNode = await config.adapter.parse(source);
|
|
837
905
|
await hooks.emit("kubb:debug", {
|
|
838
906
|
date: /* @__PURE__ */ new Date(),
|
|
@@ -849,11 +917,13 @@ async function setup(userConfig, options = {}) {
|
|
|
849
917
|
hooks,
|
|
850
918
|
driver,
|
|
851
919
|
storage,
|
|
852
|
-
dispose
|
|
853
|
-
|
|
854
|
-
for (const [event, handler] of middlewareListeners) hooks.off(event, handler);
|
|
855
|
-
}
|
|
920
|
+
dispose,
|
|
921
|
+
[Symbol.dispose]: dispose
|
|
856
922
|
};
|
|
923
|
+
function dispose() {
|
|
924
|
+
driver.dispose();
|
|
925
|
+
for (const [event, handler] of middlewareListeners) hooks.off(event, handler);
|
|
926
|
+
}
|
|
857
927
|
}
|
|
858
928
|
/**
|
|
859
929
|
* Single-pass fan-out for streaming mode.
|
|
@@ -866,84 +936,101 @@ async function setup(userConfig, options = {}) {
|
|
|
866
936
|
* Each plugin still gets independent `plugin:start` / `plugin:end` events and its own
|
|
867
937
|
* timing, but the schema and operation nodes are parsed only once total.
|
|
868
938
|
*/
|
|
869
|
-
async function runPluginStreamHooks(
|
|
939
|
+
async function runPluginStreamHooks({ entries, driver, pluginTimings, failedPlugins }) {
|
|
940
|
+
const inputStreamNode = driver.inputStreamNode;
|
|
870
941
|
function resolveRendererFor(gen, state) {
|
|
871
942
|
return gen.renderer === null ? void 0 : gen.renderer ?? state.plugin.renderer ?? state.generatorContext.config.renderer;
|
|
872
943
|
}
|
|
873
|
-
const states = entries.map(({ plugin, context, hrStart }) =>
|
|
874
|
-
plugin
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
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)
|
|
897
986
|
});
|
|
898
|
-
if (
|
|
899
|
-
const ctx = {
|
|
900
|
-
...generatorContext,
|
|
901
|
-
options
|
|
902
|
-
};
|
|
903
|
-
for (const gen of generators) {
|
|
904
|
-
if (!gen.schema) continue;
|
|
905
|
-
await applyHookResult(await gen.schema(transformedNode, ctx), driver, resolveRendererFor(gen, state));
|
|
906
|
-
}
|
|
907
|
-
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
908
|
-
} catch (caughtError) {
|
|
909
|
-
state.failed = true;
|
|
910
|
-
state.error = caughtError;
|
|
987
|
+
if (isPromise(applied)) await applied;
|
|
911
988
|
}
|
|
989
|
+
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
990
|
+
} catch (caughtError) {
|
|
991
|
+
state.failed = true;
|
|
992
|
+
state.error = caughtError;
|
|
912
993
|
}
|
|
913
|
-
schemasProcessed++;
|
|
914
|
-
if (schemasProcessed % 50 === 0) await flushPendingFiles();
|
|
915
994
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
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)
|
|
930
1019
|
});
|
|
931
|
-
if (
|
|
932
|
-
const ctx = {
|
|
933
|
-
...generatorContext,
|
|
934
|
-
options
|
|
935
|
-
};
|
|
936
|
-
for (const gen of generators) {
|
|
937
|
-
if (!gen.operation) continue;
|
|
938
|
-
await applyHookResult(await gen.operation(transformedNode, ctx), driver, resolveRendererFor(gen, state));
|
|
939
|
-
}
|
|
940
|
-
await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
941
|
-
} catch (caughtError) {
|
|
942
|
-
state.failed = true;
|
|
943
|
-
state.error = caughtError;
|
|
1020
|
+
if (isPromise(applied)) await applied;
|
|
944
1021
|
}
|
|
1022
|
+
await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
1023
|
+
} catch (caughtError) {
|
|
1024
|
+
state.failed = true;
|
|
1025
|
+
state.error = caughtError;
|
|
945
1026
|
}
|
|
946
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
|
+
}
|
|
947
1034
|
for (const state of states) {
|
|
948
1035
|
if (!state.failed) try {
|
|
949
1036
|
const { plugin, generatorContext, generators } = state;
|
|
@@ -953,7 +1040,11 @@ async function runPluginStreamHooks(inputStreamNode, entries, driver, hooks, con
|
|
|
953
1040
|
};
|
|
954
1041
|
for (const gen of generators) {
|
|
955
1042
|
if (!gen.operations) continue;
|
|
956
|
-
await applyHookResult(
|
|
1043
|
+
await applyHookResult({
|
|
1044
|
+
result: await gen.operations(collectedOperations, ctx),
|
|
1045
|
+
driver,
|
|
1046
|
+
rendererFactory: resolveRendererFor(gen, state)
|
|
1047
|
+
});
|
|
957
1048
|
}
|
|
958
1049
|
await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
959
1050
|
} catch (caughtError) {
|
|
@@ -962,12 +1053,12 @@ async function runPluginStreamHooks(inputStreamNode, entries, driver, hooks, con
|
|
|
962
1053
|
}
|
|
963
1054
|
const duration = getElapsedMs(state.hrStart);
|
|
964
1055
|
pluginTimings.set(state.plugin.name, duration);
|
|
965
|
-
await hooks.emit("kubb:plugin:end", {
|
|
1056
|
+
await driver.hooks.emit("kubb:plugin:end", {
|
|
966
1057
|
plugin: state.plugin,
|
|
967
1058
|
duration,
|
|
968
1059
|
success: !state.failed,
|
|
969
1060
|
...state.failed && state.error ? { error: state.error } : {},
|
|
970
|
-
config,
|
|
1061
|
+
config: driver.config,
|
|
971
1062
|
get files() {
|
|
972
1063
|
return driver.fileManager.files;
|
|
973
1064
|
},
|
|
@@ -977,13 +1068,22 @@ async function runPluginStreamHooks(inputStreamNode, entries, driver, hooks, con
|
|
|
977
1068
|
plugin: state.plugin,
|
|
978
1069
|
error: state.error
|
|
979
1070
|
});
|
|
980
|
-
await hooks.emit("kubb:debug", {
|
|
1071
|
+
await driver.hooks.emit("kubb:debug", {
|
|
981
1072
|
date: /* @__PURE__ */ new Date(),
|
|
982
1073
|
logs: [state.failed ? "✗ Plugin start failed" : `✓ Plugin started successfully (${formatMs(duration)})`]
|
|
983
1074
|
});
|
|
984
1075
|
}
|
|
985
|
-
await flushPendingFiles();
|
|
986
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
|
+
*/
|
|
987
1087
|
async function runPluginAstHooks(plugin, context) {
|
|
988
1088
|
const { adapter, inputNode, resolver, driver } = context;
|
|
989
1089
|
const { exclude, include, override } = plugin.options;
|
|
@@ -1006,13 +1106,15 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1006
1106
|
]);
|
|
1007
1107
|
const hasOperationBasedIncludes = include?.some(({ type }) => operationFilterTypes.has(type)) ?? false;
|
|
1008
1108
|
const hasSchemaNameIncludes = include?.some(({ type }) => type === "schemaName") ?? false;
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
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
|
+
})();
|
|
1016
1118
|
await walk(inputNode, {
|
|
1017
1119
|
depth: "shallow",
|
|
1018
1120
|
async schema(node) {
|
|
@@ -1029,7 +1131,13 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1029
1131
|
...generatorContext,
|
|
1030
1132
|
options
|
|
1031
1133
|
};
|
|
1032
|
-
await Promise.all(generators.filter((gen) => gen.schema).map(
|
|
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
|
+
}));
|
|
1033
1141
|
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
1034
1142
|
},
|
|
1035
1143
|
async operation(node) {
|
|
@@ -1040,15 +1148,20 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1040
1148
|
include,
|
|
1041
1149
|
override
|
|
1042
1150
|
});
|
|
1043
|
-
if (options
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
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);
|
|
1052
1165
|
}
|
|
1053
1166
|
});
|
|
1054
1167
|
if (collectedOperations.length > 0) {
|
|
@@ -1058,84 +1171,129 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1058
1171
|
};
|
|
1059
1172
|
for (const gen of generators) {
|
|
1060
1173
|
if (!gen.operations) continue;
|
|
1061
|
-
await applyHookResult(
|
|
1174
|
+
await applyHookResult({
|
|
1175
|
+
result: await gen.operations(collectedOperations, ctx),
|
|
1176
|
+
driver,
|
|
1177
|
+
rendererFactory: resolveRenderer(gen)
|
|
1178
|
+
});
|
|
1062
1179
|
}
|
|
1063
1180
|
await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
1064
1181
|
}
|
|
1065
1182
|
}
|
|
1066
1183
|
async function safeBuild(setupResult) {
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
const
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1184
|
+
try {
|
|
1185
|
+
var _usingCtx$1 = _usingCtx();
|
|
1186
|
+
_usingCtx$1.u(setupResult);
|
|
1187
|
+
const { driver, hooks, storage } = setupResult;
|
|
1188
|
+
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1189
|
+
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1190
|
+
const config = driver.config;
|
|
1191
|
+
const writtenPaths = /* @__PURE__ */ new Set();
|
|
1192
|
+
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
|
+
const fileProcessor = new FileProcessor();
|
|
1195
|
+
async function flushPendingFiles() {
|
|
1196
|
+
const files = driver.fileManager.files.filter((f) => !writtenPaths.has(f.path));
|
|
1197
|
+
if (files.length === 0) return;
|
|
1198
|
+
await hooks.emit("kubb:debug", {
|
|
1199
|
+
date: /* @__PURE__ */ new Date(),
|
|
1200
|
+
logs: [`Writing ${files.length} files...`]
|
|
1201
|
+
});
|
|
1202
|
+
await hooks.emit("kubb:files:processing:start", { files });
|
|
1203
|
+
const stream = fileProcessor.stream(files, {
|
|
1204
|
+
parsers: parsersMap,
|
|
1205
|
+
extension: config.output.extension
|
|
1206
|
+
});
|
|
1207
|
+
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
|
+
writtenPaths.add(file.path);
|
|
1218
|
+
}
|
|
1219
|
+
await hooks.emit("kubb:files:processing:end", { files });
|
|
1220
|
+
await hooks.emit("kubb:debug", {
|
|
1221
|
+
date: /* @__PURE__ */ new Date(),
|
|
1222
|
+
logs: [`✓ File write process completed for ${files.length} files`]
|
|
1095
1223
|
});
|
|
1096
|
-
if (source) await storage.setItem(file.path, source);
|
|
1097
|
-
writtenPaths.add(file.path);
|
|
1098
1224
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1225
|
+
try {
|
|
1226
|
+
await driver.emitSetupHooks();
|
|
1227
|
+
if (driver.adapter && (driver.inputNode || driver.inputStreamNode)) await hooks.emit("kubb:build:start", {
|
|
1228
|
+
config,
|
|
1229
|
+
adapter: driver.adapter,
|
|
1230
|
+
inputNode: driver.inputNode ?? {
|
|
1231
|
+
kind: "Input",
|
|
1232
|
+
schemas: [],
|
|
1233
|
+
operations: [],
|
|
1234
|
+
meta: driver.inputStreamNode?.meta
|
|
1235
|
+
},
|
|
1236
|
+
getPlugin: driver.getPlugin.bind(driver),
|
|
1237
|
+
get files() {
|
|
1238
|
+
return driver.fileManager.files;
|
|
1239
|
+
},
|
|
1240
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1241
|
+
});
|
|
1242
|
+
if (driver.inputStreamNode) {
|
|
1243
|
+
const streamPluginEntries = [];
|
|
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()) {
|
|
1126
1287
|
const context = driver.getContext(plugin);
|
|
1127
1288
|
const hrStart = process.hrtime();
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
context
|
|
1136
|
-
hrStart
|
|
1137
|
-
});
|
|
1138
|
-
else {
|
|
1289
|
+
try {
|
|
1290
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
1291
|
+
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);
|
|
1139
1297
|
const duration = getElapsedMs(hrStart);
|
|
1140
1298
|
pluginTimings.set(plugin.name, duration);
|
|
1141
1299
|
await hooks.emit("kubb:plugin:end", {
|
|
@@ -1152,100 +1310,73 @@ async function safeBuild(setupResult) {
|
|
|
1152
1310
|
date: /* @__PURE__ */ new Date(),
|
|
1153
1311
|
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1154
1312
|
});
|
|
1313
|
+
} catch (caughtError) {
|
|
1314
|
+
const error = caughtError;
|
|
1315
|
+
const errorTimestamp = /* @__PURE__ */ new Date();
|
|
1316
|
+
const duration = getElapsedMs(hrStart);
|
|
1317
|
+
await hooks.emit("kubb:plugin:end", {
|
|
1318
|
+
plugin,
|
|
1319
|
+
duration,
|
|
1320
|
+
success: false,
|
|
1321
|
+
error,
|
|
1322
|
+
config,
|
|
1323
|
+
get files() {
|
|
1324
|
+
return driver.fileManager.files;
|
|
1325
|
+
},
|
|
1326
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1327
|
+
});
|
|
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
|
+
failedPlugins.add({
|
|
1339
|
+
plugin,
|
|
1340
|
+
error
|
|
1341
|
+
});
|
|
1155
1342
|
}
|
|
1343
|
+
await flushPendingFiles();
|
|
1156
1344
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
await hooks.emit("kubb:debug", {
|
|
1165
|
-
date: timestamp,
|
|
1166
|
-
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1167
|
-
});
|
|
1168
|
-
if (plugin.generators?.length || driver.hasRegisteredGenerators(plugin.name)) await runPluginAstHooks(plugin, context);
|
|
1169
|
-
const duration = getElapsedMs(hrStart);
|
|
1170
|
-
pluginTimings.set(plugin.name, duration);
|
|
1171
|
-
await hooks.emit("kubb:plugin:end", {
|
|
1172
|
-
plugin,
|
|
1173
|
-
duration,
|
|
1174
|
-
success: true,
|
|
1175
|
-
config,
|
|
1176
|
-
get files() {
|
|
1177
|
-
return driver.fileManager.files;
|
|
1178
|
-
},
|
|
1179
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1180
|
-
});
|
|
1181
|
-
await hooks.emit("kubb:debug", {
|
|
1182
|
-
date: /* @__PURE__ */ new Date(),
|
|
1183
|
-
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1184
|
-
});
|
|
1185
|
-
} catch (caughtError) {
|
|
1186
|
-
const error = caughtError;
|
|
1187
|
-
const errorTimestamp = /* @__PURE__ */ new Date();
|
|
1188
|
-
const duration = getElapsedMs(hrStart);
|
|
1189
|
-
await hooks.emit("kubb:plugin:end", {
|
|
1190
|
-
plugin,
|
|
1191
|
-
duration,
|
|
1192
|
-
success: false,
|
|
1193
|
-
error,
|
|
1194
|
-
config,
|
|
1195
|
-
get files() {
|
|
1196
|
-
return driver.fileManager.files;
|
|
1197
|
-
},
|
|
1198
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1199
|
-
});
|
|
1200
|
-
await hooks.emit("kubb:debug", {
|
|
1201
|
-
date: errorTimestamp,
|
|
1202
|
-
logs: [
|
|
1203
|
-
"✗ Plugin start failed",
|
|
1204
|
-
` • Plugin Name: ${plugin.name}`,
|
|
1205
|
-
` • Error: ${error.constructor.name} - ${error.message}`,
|
|
1206
|
-
" • Stack Trace:",
|
|
1207
|
-
error.stack || "No stack trace available"
|
|
1208
|
-
]
|
|
1209
|
-
});
|
|
1210
|
-
failedPlugins.add({
|
|
1211
|
-
plugin,
|
|
1212
|
-
error
|
|
1213
|
-
});
|
|
1214
|
-
}
|
|
1345
|
+
await hooks.emit("kubb:plugins:end", {
|
|
1346
|
+
config,
|
|
1347
|
+
get files() {
|
|
1348
|
+
return driver.fileManager.files;
|
|
1349
|
+
},
|
|
1350
|
+
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1351
|
+
});
|
|
1215
1352
|
await flushPendingFiles();
|
|
1353
|
+
const files = driver.fileManager.files;
|
|
1354
|
+
await hooks.emit("kubb:build:end", {
|
|
1355
|
+
files,
|
|
1356
|
+
config,
|
|
1357
|
+
outputDir: resolve(config.root, config.output.path)
|
|
1358
|
+
});
|
|
1359
|
+
return {
|
|
1360
|
+
failedPlugins,
|
|
1361
|
+
files,
|
|
1362
|
+
driver,
|
|
1363
|
+
pluginTimings,
|
|
1364
|
+
storage
|
|
1365
|
+
};
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
return {
|
|
1368
|
+
failedPlugins,
|
|
1369
|
+
files: [],
|
|
1370
|
+
driver,
|
|
1371
|
+
pluginTimings,
|
|
1372
|
+
error,
|
|
1373
|
+
storage
|
|
1374
|
+
};
|
|
1216
1375
|
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
get files() {
|
|
1220
|
-
return driver.fileManager.files;
|
|
1221
|
-
},
|
|
1222
|
-
upsertFile: (...files) => driver.fileManager.upsert(...files)
|
|
1223
|
-
});
|
|
1224
|
-
await flushPendingFiles();
|
|
1225
|
-
const files = driver.fileManager.files;
|
|
1226
|
-
await hooks.emit("kubb:build:end", {
|
|
1227
|
-
files,
|
|
1228
|
-
config,
|
|
1229
|
-
outputDir: resolve(config.root, config.output.path)
|
|
1230
|
-
});
|
|
1231
|
-
return {
|
|
1232
|
-
failedPlugins,
|
|
1233
|
-
files,
|
|
1234
|
-
driver,
|
|
1235
|
-
pluginTimings,
|
|
1236
|
-
storage
|
|
1237
|
-
};
|
|
1238
|
-
} catch (error) {
|
|
1239
|
-
return {
|
|
1240
|
-
failedPlugins,
|
|
1241
|
-
files: [],
|
|
1242
|
-
driver,
|
|
1243
|
-
pluginTimings,
|
|
1244
|
-
error,
|
|
1245
|
-
storage
|
|
1246
|
-
};
|
|
1376
|
+
} catch (_) {
|
|
1377
|
+
_usingCtx$1.e = _;
|
|
1247
1378
|
} finally {
|
|
1248
|
-
|
|
1379
|
+
_usingCtx$1.d();
|
|
1249
1380
|
}
|
|
1250
1381
|
}
|
|
1251
1382
|
async function build(setupResult) {
|
|
@@ -1353,15 +1484,10 @@ function createKubb(userConfig, options = {}) {
|
|
|
1353
1484
|
//#endregion
|
|
1354
1485
|
//#region src/createRenderer.ts
|
|
1355
1486
|
/**
|
|
1356
|
-
*
|
|
1357
|
-
*
|
|
1358
|
-
* Wrap your renderer factory function with this helper to register it as the
|
|
1359
|
-
* renderer for a generator. Core will call this factory once per render cycle
|
|
1360
|
-
* to obtain a fresh renderer instance.
|
|
1487
|
+
* Wraps a renderer factory for use in generator definitions.
|
|
1361
1488
|
*
|
|
1362
1489
|
* @example
|
|
1363
1490
|
* ```ts
|
|
1364
|
-
* // packages/renderer-jsx/src/index.ts
|
|
1365
1491
|
* export const jsxRenderer = createRenderer(() => {
|
|
1366
1492
|
* const runtime = new Runtime()
|
|
1367
1493
|
* return {
|
|
@@ -1370,14 +1496,6 @@ function createKubb(userConfig, options = {}) {
|
|
|
1370
1496
|
* unmount(error) { runtime.unmount(error) },
|
|
1371
1497
|
* }
|
|
1372
1498
|
* })
|
|
1373
|
-
*
|
|
1374
|
-
* // packages/plugin-zod/src/generators/zodGenerator.tsx
|
|
1375
|
-
* import { jsxRenderer } from '@kubb/renderer-jsx'
|
|
1376
|
-
* export const zodGenerator = defineGenerator<PluginZod>({
|
|
1377
|
-
* name: 'zod',
|
|
1378
|
-
* renderer: jsxRenderer,
|
|
1379
|
-
* schema(node, options) { return <File ...>...</File> },
|
|
1380
|
-
* })
|
|
1381
1499
|
* ```
|
|
1382
1500
|
*/
|
|
1383
1501
|
function createRenderer(factory) {
|