@kubb/core 5.0.0-alpha.30 → 5.0.0-alpha.32
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-D110FoJ-.d.ts → PluginDriver-nm7tvGs9.d.ts} +336 -73
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +2 -3
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +374 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +26 -149
- package/dist/index.js +377 -185
- package/dist/index.js.map +1 -1
- package/package.json +2 -4
- package/src/FileManager.ts +131 -0
- package/src/FileProcessor.ts +83 -0
- package/src/Kubb.ts +5 -5
- package/src/PluginDriver.ts +29 -23
- package/src/build.ts +118 -111
- package/src/constants.ts +7 -2
- package/src/{config.ts → defineConfig.ts} +2 -8
- package/src/defineGenerator.ts +12 -13
- package/src/defineParser.ts +57 -0
- package/src/defineResolver.ts +18 -22
- package/src/devtools.ts +14 -14
- package/src/hooks/useMode.ts +2 -3
- package/src/index.ts +3 -3
- package/src/renderNode.tsx +8 -7
- package/src/types.ts +103 -56
- package/src/utils/TreeNode.ts +7 -7
- package/src/utils/getBarrelFiles.ts +30 -28
- package/src/utils/getConfigs.ts +1 -1
- package/src/utils/isInputPath.ts +8 -0
package/dist/index.cjs
CHANGED
|
@@ -9,12 +9,10 @@ let node_fs_promises = require("node:fs/promises");
|
|
|
9
9
|
let node_path = require("node:path");
|
|
10
10
|
node_path = require_chunk.__toESM(node_path);
|
|
11
11
|
let _kubb_ast = require("@kubb/ast");
|
|
12
|
-
let _kubb_react_fabric = require("@kubb/react-fabric");
|
|
13
|
-
let _kubb_react_fabric_parsers = require("@kubb/react-fabric/parsers");
|
|
14
|
-
let _kubb_react_fabric_plugins = require("@kubb/react-fabric/plugins");
|
|
15
12
|
let node_perf_hooks = require("node:perf_hooks");
|
|
16
13
|
let fflate = require("fflate");
|
|
17
14
|
let tinyexec = require("tinyexec");
|
|
15
|
+
let _kubb_react_fabric = require("@kubb/react-fabric");
|
|
18
16
|
let _kubb_react_fabric_jsx_runtime = require("@kubb/react-fabric/jsx-runtime");
|
|
19
17
|
let node_process = require("node:process");
|
|
20
18
|
let remeda = require("remeda");
|
|
@@ -340,6 +338,24 @@ async function clean(path) {
|
|
|
340
338
|
});
|
|
341
339
|
}
|
|
342
340
|
//#endregion
|
|
341
|
+
//#region ../../internals/utils/src/string.ts
|
|
342
|
+
/**
|
|
343
|
+
* Strips the file extension from a path or file name.
|
|
344
|
+
* Only removes the last `.ext` segment when the dot is not part of a directory name.
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* trimExtName('petStore.ts') // 'petStore'
|
|
348
|
+
* trimExtName('/src/models/pet.ts') // '/src/models/pet'
|
|
349
|
+
* trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'
|
|
350
|
+
* trimExtName('noExtension') // 'noExtension'
|
|
351
|
+
*/
|
|
352
|
+
function trimExtName$1(text) {
|
|
353
|
+
const dotIndex = text.lastIndexOf(".");
|
|
354
|
+
if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
|
|
355
|
+
return text;
|
|
356
|
+
}
|
|
357
|
+
require_chunk.__name(trimExtName$1, "trimExtName");
|
|
358
|
+
//#endregion
|
|
343
359
|
//#region ../../internals/utils/src/promise.ts
|
|
344
360
|
/** Returns `true` when `result` is a rejected `Promise.allSettled` result with a typed `reason`.
|
|
345
361
|
*
|
|
@@ -621,17 +637,6 @@ var URLPath = class {
|
|
|
621
637
|
}
|
|
622
638
|
};
|
|
623
639
|
//#endregion
|
|
624
|
-
//#region src/config.ts
|
|
625
|
-
function defineConfig(config) {
|
|
626
|
-
return config;
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* Type guard to check if a given config has an `input.path`.
|
|
630
|
-
*/
|
|
631
|
-
function isInputPath(config) {
|
|
632
|
-
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
633
|
-
}
|
|
634
|
-
//#endregion
|
|
635
640
|
//#region src/constants.ts
|
|
636
641
|
/**
|
|
637
642
|
* Base URL for the Kubb Studio web app.
|
|
@@ -723,50 +728,6 @@ const formatters = {
|
|
|
723
728
|
}
|
|
724
729
|
};
|
|
725
730
|
//#endregion
|
|
726
|
-
//#region src/devtools.ts
|
|
727
|
-
/**
|
|
728
|
-
* Encodes a `RootNode` as a compressed, URL-safe string.
|
|
729
|
-
*
|
|
730
|
-
* The JSON representation is deflate-compressed with {@link deflateSync} before
|
|
731
|
-
* base64url encoding, which typically reduces payload size by 70–80 % and
|
|
732
|
-
* keeps URLs well within browser and server path-length limits.
|
|
733
|
-
*
|
|
734
|
-
* Use {@link decodeAst} to reverse.
|
|
735
|
-
*/
|
|
736
|
-
function encodeAst(root) {
|
|
737
|
-
const compressed = (0, fflate.deflateSync)(new TextEncoder().encode(JSON.stringify(root)));
|
|
738
|
-
return Buffer.from(compressed).toString("base64url");
|
|
739
|
-
}
|
|
740
|
-
/**
|
|
741
|
-
* Constructs the Kubb Studio URL for the given `RootNode`.
|
|
742
|
-
* When `options.ast` is `true`, navigates to the AST inspector (`/ast`).
|
|
743
|
-
* The `root` is encoded and attached as the `?root=` query parameter so Studio
|
|
744
|
-
* can decode and render it without a round-trip to any server.
|
|
745
|
-
*/
|
|
746
|
-
function getStudioUrl(root, studioUrl, options = {}) {
|
|
747
|
-
return `${studioUrl.replace(/\/$/, "")}${options.ast ? "/ast" : ""}?root=${encodeAst(root)}`;
|
|
748
|
-
}
|
|
749
|
-
/**
|
|
750
|
-
* Opens the Kubb Studio URL for the given `RootNode` in the default browser —
|
|
751
|
-
*
|
|
752
|
-
* Falls back to printing the URL if the browser cannot be launched.
|
|
753
|
-
*/
|
|
754
|
-
async function openInStudio(root, studioUrl, options = {}) {
|
|
755
|
-
const url = getStudioUrl(root, studioUrl, options);
|
|
756
|
-
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
757
|
-
const args = process.platform === "win32" ? [
|
|
758
|
-
"/c",
|
|
759
|
-
"start",
|
|
760
|
-
"",
|
|
761
|
-
url
|
|
762
|
-
] : [url];
|
|
763
|
-
try {
|
|
764
|
-
await (0, tinyexec.x)(cmd, args);
|
|
765
|
-
} catch {
|
|
766
|
-
console.log(`\n ${url}\n`);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
//#endregion
|
|
770
731
|
//#region ../../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
771
732
|
var Node = class {
|
|
772
733
|
value;
|
|
@@ -894,6 +855,194 @@ function validateConcurrency(concurrency) {
|
|
|
894
855
|
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
895
856
|
}
|
|
896
857
|
//#endregion
|
|
858
|
+
//#region src/FileProcessor.ts
|
|
859
|
+
function joinSources(file) {
|
|
860
|
+
return file.sources.map((item) => item.value).filter((value) => value != null).join("\n\n");
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* Converts a single file to a string using the registered parsers.
|
|
864
|
+
* Falls back to joining source values when no matching parser is found.
|
|
865
|
+
*/
|
|
866
|
+
var FileProcessor = class {
|
|
867
|
+
#limit = pLimit(100);
|
|
868
|
+
async parse(file, { parsers, extension } = {}) {
|
|
869
|
+
const parseExtName = extension?.[file.extname] || void 0;
|
|
870
|
+
if (!parsers || !file.extname) return joinSources(file);
|
|
871
|
+
const parser = parsers.get(file.extname);
|
|
872
|
+
if (!parser) return joinSources(file);
|
|
873
|
+
return parser.parse(file, { extname: parseExtName });
|
|
874
|
+
}
|
|
875
|
+
async run(files, { parsers, mode = "sequential", extension, onStart, onEnd, onUpdate } = {}) {
|
|
876
|
+
await onStart?.(files);
|
|
877
|
+
const total = files.length;
|
|
878
|
+
let processed = 0;
|
|
879
|
+
const processOne = async (file) => {
|
|
880
|
+
const source = await this.parse(file, {
|
|
881
|
+
extension,
|
|
882
|
+
parsers
|
|
883
|
+
});
|
|
884
|
+
const currentProcessed = ++processed;
|
|
885
|
+
const percentage = currentProcessed / total * 100;
|
|
886
|
+
await onUpdate?.({
|
|
887
|
+
file,
|
|
888
|
+
source,
|
|
889
|
+
processed: currentProcessed,
|
|
890
|
+
percentage,
|
|
891
|
+
total
|
|
892
|
+
});
|
|
893
|
+
};
|
|
894
|
+
if (mode === "sequential") for (const file of files) await processOne(file);
|
|
895
|
+
else await Promise.all(files.map((file) => this.#limit(() => processOne(file))));
|
|
896
|
+
await onEnd?.(files);
|
|
897
|
+
return files;
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
//#endregion
|
|
901
|
+
//#region src/devtools.ts
|
|
902
|
+
/**
|
|
903
|
+
* Encodes an `InputNode` as a compressed, URL-safe string.
|
|
904
|
+
*
|
|
905
|
+
* The JSON representation is deflate-compressed with {@link deflateSync} before
|
|
906
|
+
* base64url encoding, which typically reduces payload size by 70–80 % and
|
|
907
|
+
* keeps URLs well within browser and server path-length limits.
|
|
908
|
+
*
|
|
909
|
+
* Use {@link decodeAst} to reverse.
|
|
910
|
+
*/
|
|
911
|
+
function encodeAst(input) {
|
|
912
|
+
const compressed = (0, fflate.deflateSync)(new TextEncoder().encode(JSON.stringify(input)));
|
|
913
|
+
return Buffer.from(compressed).toString("base64url");
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Constructs the Kubb Studio URL for the given `InputNode`.
|
|
917
|
+
* When `options.ast` is `true`, navigates to the AST inspector (`/ast`).
|
|
918
|
+
* The `input` is encoded and attached as the `?root=` query parameter so Studio
|
|
919
|
+
* can decode and render it without a round-trip to any server.
|
|
920
|
+
*/
|
|
921
|
+
function getStudioUrl(input, studioUrl, options = {}) {
|
|
922
|
+
return `${studioUrl.replace(/\/$/, "")}${options.ast ? "/ast" : ""}?root=${encodeAst(input)}`;
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Opens the Kubb Studio URL for the given `InputNode` in the default browser —
|
|
926
|
+
*
|
|
927
|
+
* Falls back to printing the URL if the browser cannot be launched.
|
|
928
|
+
*/
|
|
929
|
+
async function openInStudio(input, studioUrl, options = {}) {
|
|
930
|
+
const url = getStudioUrl(input, studioUrl, options);
|
|
931
|
+
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
932
|
+
const args = process.platform === "win32" ? [
|
|
933
|
+
"/c",
|
|
934
|
+
"start",
|
|
935
|
+
"",
|
|
936
|
+
url
|
|
937
|
+
] : [url];
|
|
938
|
+
try {
|
|
939
|
+
await (0, tinyexec.x)(cmd, args);
|
|
940
|
+
} catch {
|
|
941
|
+
console.log(`\n ${url}\n`);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
//#endregion
|
|
945
|
+
//#region src/FileManager.ts
|
|
946
|
+
function mergeFile(a, b) {
|
|
947
|
+
return {
|
|
948
|
+
...a,
|
|
949
|
+
sources: [...a.sources || [], ...b.sources || []],
|
|
950
|
+
imports: [...a.imports || [], ...b.imports || []],
|
|
951
|
+
exports: [...a.exports || [], ...b.exports || []]
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* In-memory file store for generated files.
|
|
956
|
+
*
|
|
957
|
+
* Files with the same `path` are merged — sources, imports, and exports are concatenated.
|
|
958
|
+
* The `files` getter returns all stored files sorted by path length (shortest first).
|
|
959
|
+
*
|
|
960
|
+
* @example
|
|
961
|
+
* ```ts
|
|
962
|
+
* import { FileManager } from '@kubb/core'
|
|
963
|
+
*
|
|
964
|
+
* const manager = new FileManager()
|
|
965
|
+
* manager.upsert(myFile)
|
|
966
|
+
* console.log(manager.files) // all stored files
|
|
967
|
+
* ```
|
|
968
|
+
*/
|
|
969
|
+
var FileManager = class {
|
|
970
|
+
#cache = /* @__PURE__ */ new Map();
|
|
971
|
+
#filesCache = null;
|
|
972
|
+
/**
|
|
973
|
+
* Adds one or more files. Files with the same path are merged — sources, imports,
|
|
974
|
+
* and exports from all calls with the same path are concatenated together.
|
|
975
|
+
*/
|
|
976
|
+
add(...files) {
|
|
977
|
+
const resolvedFiles = [];
|
|
978
|
+
const mergedFiles = /* @__PURE__ */ new Map();
|
|
979
|
+
files.forEach((file) => {
|
|
980
|
+
const existing = mergedFiles.get(file.path);
|
|
981
|
+
if (existing) mergedFiles.set(file.path, mergeFile(existing, file));
|
|
982
|
+
else mergedFiles.set(file.path, file);
|
|
983
|
+
});
|
|
984
|
+
for (const file of mergedFiles.values()) {
|
|
985
|
+
const resolvedFile = (0, _kubb_ast.createFile)(file);
|
|
986
|
+
this.#cache.set(resolvedFile.path, resolvedFile);
|
|
987
|
+
this.#filesCache = null;
|
|
988
|
+
resolvedFiles.push(resolvedFile);
|
|
989
|
+
}
|
|
990
|
+
return resolvedFiles;
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Adds or merges one or more files.
|
|
994
|
+
* If a file with the same path already exists, its sources/imports/exports are merged together.
|
|
995
|
+
*/
|
|
996
|
+
upsert(...files) {
|
|
997
|
+
const resolvedFiles = [];
|
|
998
|
+
const mergedFiles = /* @__PURE__ */ new Map();
|
|
999
|
+
files.forEach((file) => {
|
|
1000
|
+
const existing = mergedFiles.get(file.path);
|
|
1001
|
+
if (existing) mergedFiles.set(file.path, mergeFile(existing, file));
|
|
1002
|
+
else mergedFiles.set(file.path, file);
|
|
1003
|
+
});
|
|
1004
|
+
for (const file of mergedFiles.values()) {
|
|
1005
|
+
const existing = this.#cache.get(file.path);
|
|
1006
|
+
const resolvedFile = (0, _kubb_ast.createFile)(existing ? mergeFile(existing, file) : file);
|
|
1007
|
+
this.#cache.set(resolvedFile.path, resolvedFile);
|
|
1008
|
+
this.#filesCache = null;
|
|
1009
|
+
resolvedFiles.push(resolvedFile);
|
|
1010
|
+
}
|
|
1011
|
+
return resolvedFiles;
|
|
1012
|
+
}
|
|
1013
|
+
getByPath(path) {
|
|
1014
|
+
return this.#cache.get(path) ?? null;
|
|
1015
|
+
}
|
|
1016
|
+
deleteByPath(path) {
|
|
1017
|
+
this.#cache.delete(path);
|
|
1018
|
+
this.#filesCache = null;
|
|
1019
|
+
}
|
|
1020
|
+
clear() {
|
|
1021
|
+
this.#cache.clear();
|
|
1022
|
+
this.#filesCache = null;
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* All stored files, sorted by path length (shorter paths first).
|
|
1026
|
+
* Barrel/index files (e.g. index.ts) are sorted last within each length bucket.
|
|
1027
|
+
*/
|
|
1028
|
+
get files() {
|
|
1029
|
+
if (this.#filesCache) return this.#filesCache;
|
|
1030
|
+
const keys = [...this.#cache.keys()].sort((a, b) => {
|
|
1031
|
+
if (a.length !== b.length) return a.length - b.length;
|
|
1032
|
+
const aIsIndex = trimExtName$1(a).endsWith("index");
|
|
1033
|
+
if (aIsIndex !== trimExtName$1(b).endsWith("index")) return aIsIndex ? 1 : -1;
|
|
1034
|
+
return 0;
|
|
1035
|
+
});
|
|
1036
|
+
const files = [];
|
|
1037
|
+
for (const key of keys) {
|
|
1038
|
+
const file = this.#cache.get(key);
|
|
1039
|
+
if (file) files.push(file);
|
|
1040
|
+
}
|
|
1041
|
+
this.#filesCache = files;
|
|
1042
|
+
return files;
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
//#endregion
|
|
897
1046
|
//#region src/utils/executeStrategies.ts
|
|
898
1047
|
/**
|
|
899
1048
|
* Runs promise functions in sequence, threading each result into the next call.
|
|
@@ -960,12 +1109,18 @@ var PluginDriver = class {
|
|
|
960
1109
|
config;
|
|
961
1110
|
options;
|
|
962
1111
|
/**
|
|
963
|
-
* The universal `@kubb/ast` `
|
|
1112
|
+
* The universal `@kubb/ast` `InputNode` produced by the adapter, set by
|
|
964
1113
|
* the build pipeline after the adapter's `parse()` resolves.
|
|
965
1114
|
*/
|
|
966
|
-
|
|
1115
|
+
inputNode = void 0;
|
|
967
1116
|
adapter = void 0;
|
|
968
1117
|
#studioIsOpen = false;
|
|
1118
|
+
/**
|
|
1119
|
+
* Central file store for all generated files.
|
|
1120
|
+
* Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
|
|
1121
|
+
* add files; this property gives direct read/write access when needed.
|
|
1122
|
+
*/
|
|
1123
|
+
fileManager = new FileManager();
|
|
969
1124
|
plugins = /* @__PURE__ */ new Map();
|
|
970
1125
|
constructor(config, options) {
|
|
971
1126
|
this.config = config;
|
|
@@ -990,7 +1145,6 @@ var PluginDriver = class {
|
|
|
990
1145
|
getContext(plugin) {
|
|
991
1146
|
const driver = this;
|
|
992
1147
|
const baseContext = {
|
|
993
|
-
fabric: driver.options.fabric,
|
|
994
1148
|
config: driver.config,
|
|
995
1149
|
get root() {
|
|
996
1150
|
return (0, node_path.resolve)(driver.config.root, driver.config.output.path);
|
|
@@ -1004,13 +1158,13 @@ var PluginDriver = class {
|
|
|
1004
1158
|
requirePlugin: driver.requirePlugin.bind(driver),
|
|
1005
1159
|
driver,
|
|
1006
1160
|
addFile: async (...files) => {
|
|
1007
|
-
|
|
1161
|
+
driver.fileManager.add(...files);
|
|
1008
1162
|
},
|
|
1009
1163
|
upsertFile: async (...files) => {
|
|
1010
|
-
|
|
1164
|
+
driver.fileManager.upsert(...files);
|
|
1011
1165
|
},
|
|
1012
|
-
get
|
|
1013
|
-
return driver.
|
|
1166
|
+
get inputNode() {
|
|
1167
|
+
return driver.inputNode;
|
|
1014
1168
|
},
|
|
1015
1169
|
get adapter() {
|
|
1016
1170
|
return driver.adapter;
|
|
@@ -1033,10 +1187,10 @@ var PluginDriver = class {
|
|
|
1033
1187
|
openInStudio(options) {
|
|
1034
1188
|
if (!driver.config.devtools || driver.#studioIsOpen) return;
|
|
1035
1189
|
if (typeof driver.config.devtools !== "object") throw new Error("Devtools must be an object");
|
|
1036
|
-
if (!driver.
|
|
1190
|
+
if (!driver.inputNode || !driver.adapter) throw new Error("adapter is not defined, make sure you have set the parser in kubb.config.ts");
|
|
1037
1191
|
driver.#studioIsOpen = true;
|
|
1038
1192
|
const studioUrl = driver.config.devtools?.studioUrl ?? "https://studio.kubb.dev";
|
|
1039
|
-
return openInStudio(driver.
|
|
1193
|
+
return openInStudio(driver.inputNode, studioUrl, options);
|
|
1040
1194
|
}
|
|
1041
1195
|
};
|
|
1042
1196
|
const mergedExtras = {};
|
|
@@ -1065,14 +1219,14 @@ var PluginDriver = class {
|
|
|
1065
1219
|
options
|
|
1066
1220
|
});
|
|
1067
1221
|
if (!path) throw new Error(`Filepath should be defined for resolvedName "${resolvedName}" and pluginName "${pluginName}"`);
|
|
1068
|
-
return {
|
|
1222
|
+
return (0, _kubb_ast.createFile)({
|
|
1069
1223
|
path,
|
|
1070
1224
|
baseName: (0, node_path.basename)(path),
|
|
1071
1225
|
meta: { pluginName },
|
|
1072
1226
|
sources: [],
|
|
1073
1227
|
imports: [],
|
|
1074
1228
|
exports: []
|
|
1075
|
-
};
|
|
1229
|
+
});
|
|
1076
1230
|
}
|
|
1077
1231
|
/**
|
|
1078
1232
|
* @deprecated use resolvers context instead
|
|
@@ -1356,19 +1510,19 @@ var PluginDriver = class {
|
|
|
1356
1510
|
/**
|
|
1357
1511
|
* Handles the return value of a plugin AST hook or generator method.
|
|
1358
1512
|
*
|
|
1359
|
-
* - React element → rendered via an isolated react-fabric context, files
|
|
1360
|
-
* - `Array<
|
|
1513
|
+
* - React element → rendered via an isolated react-fabric context, files stored in `driver.fileManager`
|
|
1514
|
+
* - `Array<FileNode>` → upserted directly into `driver.fileManager`
|
|
1361
1515
|
* - `void` / `null` / `undefined` → no-op (plugin handled it via `this.upsertFile`)
|
|
1362
1516
|
*/
|
|
1363
|
-
async function applyHookResult(result,
|
|
1517
|
+
async function applyHookResult(result, driver) {
|
|
1364
1518
|
if (!result) return;
|
|
1365
1519
|
if (Array.isArray(result)) {
|
|
1366
|
-
|
|
1520
|
+
driver.fileManager.upsert(...result);
|
|
1367
1521
|
return;
|
|
1368
1522
|
}
|
|
1369
1523
|
const fabricChild = (0, _kubb_react_fabric.createReactFabric)();
|
|
1370
1524
|
await fabricChild.render(/* @__PURE__ */ (0, _kubb_react_fabric_jsx_runtime.jsx)(_kubb_react_fabric.Fabric, { children: result }));
|
|
1371
|
-
|
|
1525
|
+
driver.fileManager.upsert(...fabricChild.files);
|
|
1372
1526
|
fabricChild.unmount();
|
|
1373
1527
|
}
|
|
1374
1528
|
//#endregion
|
|
@@ -1469,7 +1623,7 @@ const fsStorage = createStorage(() => ({
|
|
|
1469
1623
|
}));
|
|
1470
1624
|
//#endregion
|
|
1471
1625
|
//#region package.json
|
|
1472
|
-
var version = "5.0.0-alpha.
|
|
1626
|
+
var version = "5.0.0-alpha.32";
|
|
1473
1627
|
//#endregion
|
|
1474
1628
|
//#region src/utils/diagnostics.ts
|
|
1475
1629
|
/**
|
|
@@ -1491,7 +1645,7 @@ function getDiagnosticInfo() {
|
|
|
1491
1645
|
//#region src/utils/TreeNode.ts
|
|
1492
1646
|
/**
|
|
1493
1647
|
* Tree structure used to build per-directory barrel (`index.ts`) files from a
|
|
1494
|
-
* flat list of generated {@link
|
|
1648
|
+
* flat list of generated {@link FileNode} entries.
|
|
1495
1649
|
*
|
|
1496
1650
|
* Each node represents either a directory or a file within the output tree.
|
|
1497
1651
|
* Use {@link TreeNode.build} to construct a root node from a file list, then
|
|
@@ -1652,36 +1806,36 @@ function getBarrelFilesByRoot(root, files) {
|
|
|
1652
1806
|
const cachedFiles = /* @__PURE__ */ new Map();
|
|
1653
1807
|
TreeNode.build(files, root)?.forEach((treeNode) => {
|
|
1654
1808
|
if (!treeNode?.children || !treeNode.parent?.data.path) return;
|
|
1655
|
-
const barrelFile = {
|
|
1809
|
+
const barrelFile = (0, _kubb_ast.createFile)({
|
|
1656
1810
|
path: (0, node_path.join)(treeNode.parent?.data.path, "index.ts"),
|
|
1657
1811
|
baseName: "index.ts",
|
|
1658
1812
|
exports: [],
|
|
1659
1813
|
imports: [],
|
|
1660
1814
|
sources: []
|
|
1661
|
-
};
|
|
1815
|
+
});
|
|
1662
1816
|
const previousBarrelFile = cachedFiles.get(barrelFile.path);
|
|
1663
1817
|
treeNode.leaves.forEach((item) => {
|
|
1664
1818
|
if (!item.data.name) return;
|
|
1665
1819
|
(item.data.file?.sources || []).forEach((source) => {
|
|
1666
1820
|
if (!item.data.file?.path || !source.isIndexable || !source.name) return;
|
|
1667
1821
|
if (previousBarrelFile?.sources.some((item) => item.name === source.name && item.isTypeOnly === source.isTypeOnly)) return;
|
|
1668
|
-
barrelFile.exports.push({
|
|
1822
|
+
barrelFile.exports.push((0, _kubb_ast.createExport)({
|
|
1669
1823
|
name: [source.name],
|
|
1670
1824
|
path: getRelativePath(treeNode.parent?.data.path, item.data.path),
|
|
1671
1825
|
isTypeOnly: source.isTypeOnly
|
|
1672
|
-
});
|
|
1673
|
-
barrelFile.sources.push({
|
|
1826
|
+
}));
|
|
1827
|
+
barrelFile.sources.push((0, _kubb_ast.createSource)({
|
|
1674
1828
|
name: source.name,
|
|
1675
1829
|
isTypeOnly: source.isTypeOnly,
|
|
1676
1830
|
value: "",
|
|
1677
1831
|
isExportable: false,
|
|
1678
1832
|
isIndexable: false
|
|
1679
|
-
});
|
|
1833
|
+
}));
|
|
1680
1834
|
});
|
|
1681
1835
|
});
|
|
1682
1836
|
if (previousBarrelFile) {
|
|
1683
1837
|
previousBarrelFile.sources.push(...barrelFile.sources);
|
|
1684
|
-
previousBarrelFile.exports
|
|
1838
|
+
previousBarrelFile.exports.push(...barrelFile.exports);
|
|
1685
1839
|
} else cachedFiles.set(barrelFile.path, barrelFile);
|
|
1686
1840
|
});
|
|
1687
1841
|
return [...cachedFiles.values()];
|
|
@@ -1707,7 +1861,7 @@ async function getBarrelFiles(files, { type, meta = {}, root, output }) {
|
|
|
1707
1861
|
if (type === "all") return barrelFiles.map((file) => {
|
|
1708
1862
|
return {
|
|
1709
1863
|
...file,
|
|
1710
|
-
exports: file.exports
|
|
1864
|
+
exports: file.exports.map((exportItem) => {
|
|
1711
1865
|
return {
|
|
1712
1866
|
...exportItem,
|
|
1713
1867
|
name: void 0
|
|
@@ -1723,6 +1877,14 @@ async function getBarrelFiles(files, { type, meta = {}, root, output }) {
|
|
|
1723
1877
|
});
|
|
1724
1878
|
}
|
|
1725
1879
|
//#endregion
|
|
1880
|
+
//#region src/utils/isInputPath.ts
|
|
1881
|
+
/**
|
|
1882
|
+
* Type guard to check if a given config has an `input.path`.
|
|
1883
|
+
*/
|
|
1884
|
+
function isInputPath(config) {
|
|
1885
|
+
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
1886
|
+
}
|
|
1887
|
+
//#endregion
|
|
1726
1888
|
//#region src/build.ts
|
|
1727
1889
|
/**
|
|
1728
1890
|
* Initializes all Kubb infrastructure for a build without executing any plugins.
|
|
@@ -1730,7 +1892,8 @@ async function getBarrelFiles(files, { type, meta = {}, root, output }) {
|
|
|
1730
1892
|
* - Validates the input path (when applicable).
|
|
1731
1893
|
* - Applies config defaults (`root`, `output.*`, `devtools`).
|
|
1732
1894
|
* - Creates the Fabric instance and wires storage, format, and lint hooks.
|
|
1733
|
-
* - Runs the adapter (if configured) to produce the universal `
|
|
1895
|
+
* - Runs the adapter (if configured) to produce the universal `InputNode`.
|
|
1896
|
+
* When no adapter is supplied and `@kubb/adapter-oas` is installed as an
|
|
1734
1897
|
*
|
|
1735
1898
|
* Pass the returned {@link SetupResult} directly to {@link safeBuild} or {@link build}
|
|
1736
1899
|
* via the `overrides` argument to reuse the same infrastructure across multiple runs.
|
|
@@ -1770,9 +1933,12 @@ async function setup(options) {
|
|
|
1770
1933
|
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 });
|
|
1771
1934
|
}
|
|
1772
1935
|
}
|
|
1773
|
-
|
|
1936
|
+
if (!userConfig.adapter) throw new Error("Adapter should be defined");
|
|
1937
|
+
const config = {
|
|
1774
1938
|
root: userConfig.root || process.cwd(),
|
|
1775
1939
|
...userConfig,
|
|
1940
|
+
parsers: userConfig.parsers ?? [],
|
|
1941
|
+
adapter: userConfig.adapter,
|
|
1776
1942
|
output: {
|
|
1777
1943
|
write: true,
|
|
1778
1944
|
barrelType: "named",
|
|
@@ -1786,79 +1952,41 @@ async function setup(options) {
|
|
|
1786
1952
|
} : void 0,
|
|
1787
1953
|
plugins: userConfig.plugins
|
|
1788
1954
|
};
|
|
1789
|
-
const storage =
|
|
1790
|
-
if (
|
|
1955
|
+
const storage = config.output.write === false ? null : config.output.storage ?? fsStorage();
|
|
1956
|
+
if (config.output.clean) {
|
|
1791
1957
|
await events.emit("debug", {
|
|
1792
1958
|
date: /* @__PURE__ */ new Date(),
|
|
1793
|
-
logs: ["Cleaning output directories", ` • Output: ${
|
|
1959
|
+
logs: ["Cleaning output directories", ` • Output: ${config.output.path}`]
|
|
1794
1960
|
});
|
|
1795
|
-
await storage?.clear((0, node_path.resolve)(
|
|
1796
|
-
}
|
|
1797
|
-
const
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
fabric.context.on("files:processing:start", (files) => {
|
|
1801
|
-
events.emit("files:processing:start", files);
|
|
1802
|
-
events.emit("debug", {
|
|
1803
|
-
date: /* @__PURE__ */ new Date(),
|
|
1804
|
-
logs: [`Writing ${files.length} files...`]
|
|
1805
|
-
});
|
|
1806
|
-
});
|
|
1807
|
-
fabric.context.on("file:processing:update", async (params) => {
|
|
1808
|
-
const { file, source } = params;
|
|
1809
|
-
await events.emit("file:processing:update", {
|
|
1810
|
-
...params,
|
|
1811
|
-
config: definedConfig,
|
|
1812
|
-
source
|
|
1813
|
-
});
|
|
1814
|
-
if (source) {
|
|
1815
|
-
const key = (0, node_path.relative)((0, node_path.resolve)(definedConfig.root), file.path);
|
|
1816
|
-
await storage?.setItem(key, source);
|
|
1817
|
-
sources.set(file.path, source);
|
|
1818
|
-
}
|
|
1961
|
+
await storage?.clear((0, node_path.resolve)(config.root, config.output.path));
|
|
1962
|
+
}
|
|
1963
|
+
const driver = new PluginDriver(config, {
|
|
1964
|
+
events,
|
|
1965
|
+
concurrency: 15
|
|
1819
1966
|
});
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
}
|
|
1967
|
+
const adapter = config.adapter;
|
|
1968
|
+
if (!adapter) throw new Error("No adapter configured. Please provide an adapter in your kubb.config.ts.");
|
|
1969
|
+
const source = inputToAdapterSource(config);
|
|
1970
|
+
await events.emit("debug", {
|
|
1971
|
+
date: /* @__PURE__ */ new Date(),
|
|
1972
|
+
logs: [`Running adapter: ${adapter.name}`]
|
|
1826
1973
|
});
|
|
1974
|
+
driver.adapter = adapter;
|
|
1975
|
+
driver.inputNode = await adapter.parse(source);
|
|
1827
1976
|
await events.emit("debug", {
|
|
1828
1977
|
date: /* @__PURE__ */ new Date(),
|
|
1829
1978
|
logs: [
|
|
1830
|
-
|
|
1831
|
-
` •
|
|
1832
|
-
` •
|
|
1979
|
+
`✓ Adapter '${adapter.name}' resolved InputNode`,
|
|
1980
|
+
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
1981
|
+
` • Operations: ${driver.inputNode.operations.length}`
|
|
1833
1982
|
]
|
|
1834
1983
|
});
|
|
1835
|
-
const pluginDriver = new PluginDriver(definedConfig, {
|
|
1836
|
-
fabric,
|
|
1837
|
-
events,
|
|
1838
|
-
concurrency: 15
|
|
1839
|
-
});
|
|
1840
|
-
if (definedConfig.adapter) {
|
|
1841
|
-
const source = inputToAdapterSource(definedConfig);
|
|
1842
|
-
await events.emit("debug", {
|
|
1843
|
-
date: /* @__PURE__ */ new Date(),
|
|
1844
|
-
logs: [`Running adapter: ${definedConfig.adapter.name}`]
|
|
1845
|
-
});
|
|
1846
|
-
pluginDriver.adapter = definedConfig.adapter;
|
|
1847
|
-
pluginDriver.rootNode = await definedConfig.adapter.parse(source);
|
|
1848
|
-
await events.emit("debug", {
|
|
1849
|
-
date: /* @__PURE__ */ new Date(),
|
|
1850
|
-
logs: [
|
|
1851
|
-
`✓ Adapter '${definedConfig.adapter.name}' resolved RootNode`,
|
|
1852
|
-
` • Schemas: ${pluginDriver.rootNode.schemas.length}`,
|
|
1853
|
-
` • Operations: ${pluginDriver.rootNode.operations.length}`
|
|
1854
|
-
]
|
|
1855
|
-
});
|
|
1856
|
-
}
|
|
1857
1984
|
return {
|
|
1985
|
+
config,
|
|
1858
1986
|
events,
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1987
|
+
driver,
|
|
1988
|
+
sources,
|
|
1989
|
+
storage
|
|
1862
1990
|
};
|
|
1863
1991
|
}
|
|
1864
1992
|
/**
|
|
@@ -1868,7 +1996,7 @@ async function setup(options) {
|
|
|
1868
1996
|
* Pass an existing {@link SetupResult} via `overrides` to skip the setup phase.
|
|
1869
1997
|
*/
|
|
1870
1998
|
async function build(options, overrides) {
|
|
1871
|
-
const {
|
|
1999
|
+
const { files, driver, failedPlugins, pluginTimings, error, sources } = await safeBuild(options, overrides);
|
|
1872
2000
|
if (error) throw error;
|
|
1873
2001
|
if (failedPlugins.size > 0) {
|
|
1874
2002
|
const errors = [...failedPlugins].map(({ error }) => error);
|
|
@@ -1876,7 +2004,6 @@ async function build(options, overrides) {
|
|
|
1876
2004
|
}
|
|
1877
2005
|
return {
|
|
1878
2006
|
failedPlugins,
|
|
1879
|
-
fabric,
|
|
1880
2007
|
files,
|
|
1881
2008
|
driver,
|
|
1882
2009
|
pluginTimings,
|
|
@@ -1891,15 +2018,15 @@ async function build(options, overrides) {
|
|
|
1891
2018
|
* - Each hook accepts a single handler **or an array** — all entries are called in sequence.
|
|
1892
2019
|
* - Nodes that are excluded by `exclude`/`include` plugin options are skipped automatically.
|
|
1893
2020
|
* - Return values are handled via `applyHookResult`: React elements are rendered,
|
|
1894
|
-
* `
|
|
2021
|
+
* `FileNode[]` are written via upsert, and `void` is a no-op (manual handling).
|
|
1895
2022
|
* - Barrel files are generated automatically when `output.barrelType` is set.
|
|
1896
2023
|
*/
|
|
1897
2024
|
async function runPluginAstHooks(plugin, context) {
|
|
1898
|
-
const { adapter,
|
|
2025
|
+
const { adapter, inputNode, resolver, driver } = context;
|
|
1899
2026
|
const { exclude, include, override } = plugin.options;
|
|
1900
|
-
if (!adapter || !
|
|
2027
|
+
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.`);
|
|
1901
2028
|
const collectedOperations = [];
|
|
1902
|
-
await (0, _kubb_ast.walk)(
|
|
2029
|
+
await (0, _kubb_ast.walk)(inputNode, {
|
|
1903
2030
|
depth: "shallow",
|
|
1904
2031
|
async schema(node) {
|
|
1905
2032
|
if (!plugin.schema) return;
|
|
@@ -1911,7 +2038,7 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1911
2038
|
override
|
|
1912
2039
|
});
|
|
1913
2040
|
if (options === null) return;
|
|
1914
|
-
await applyHookResult(await plugin.schema.call(context, transformedNode, options),
|
|
2041
|
+
await applyHookResult(await plugin.schema.call(context, transformedNode, options), driver);
|
|
1915
2042
|
},
|
|
1916
2043
|
async operation(node) {
|
|
1917
2044
|
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
@@ -1923,24 +2050,24 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1923
2050
|
});
|
|
1924
2051
|
if (options !== null) {
|
|
1925
2052
|
collectedOperations.push(transformedNode);
|
|
1926
|
-
if (plugin.operation) await applyHookResult(await plugin.operation.call(context, transformedNode, options),
|
|
2053
|
+
if (plugin.operation) await applyHookResult(await plugin.operation.call(context, transformedNode, options), driver);
|
|
1927
2054
|
}
|
|
1928
2055
|
}
|
|
1929
2056
|
});
|
|
1930
|
-
if (plugin.operations && collectedOperations.length > 0) await applyHookResult(await plugin.operations.call(context, collectedOperations, plugin.options),
|
|
2057
|
+
if (plugin.operations && collectedOperations.length > 0) await applyHookResult(await plugin.operations.call(context, collectedOperations, plugin.options), driver);
|
|
1931
2058
|
}
|
|
1932
2059
|
/**
|
|
1933
2060
|
* Runs a full Kubb build and captures errors instead of throwing.
|
|
1934
2061
|
*
|
|
1935
2062
|
* - Installs each plugin in order, recording failures in `failedPlugins`.
|
|
1936
2063
|
* - Generates the root barrel file when `output.barrelType` is set.
|
|
1937
|
-
* - Writes all files through
|
|
2064
|
+
* - Writes all files through the driver's FileManager and FileProcessor.
|
|
1938
2065
|
*
|
|
1939
2066
|
* Returns a {@link BuildOutput} even on failure — inspect `error` and
|
|
1940
2067
|
* `failedPlugins` to determine whether the build succeeded.
|
|
1941
2068
|
*/
|
|
1942
2069
|
async function safeBuild(options, overrides) {
|
|
1943
|
-
const {
|
|
2070
|
+
const { driver, events, sources, storage } = overrides ? overrides : await setup(options);
|
|
1944
2071
|
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1945
2072
|
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1946
2073
|
const config = driver.config;
|
|
@@ -1960,7 +2087,7 @@ async function safeBuild(options, overrides) {
|
|
|
1960
2087
|
await plugin.buildStart.call(context);
|
|
1961
2088
|
if (plugin.schema || plugin.operation || plugin.operations) await runPluginAstHooks(plugin, context);
|
|
1962
2089
|
if (output) {
|
|
1963
|
-
const barrelFiles = await getBarrelFiles(
|
|
2090
|
+
const barrelFiles = await getBarrelFiles(driver.fileManager.files, {
|
|
1964
2091
|
type: output.barrelType ?? "named",
|
|
1965
2092
|
root,
|
|
1966
2093
|
output,
|
|
@@ -2014,15 +2141,15 @@ async function safeBuild(options, overrides) {
|
|
|
2014
2141
|
` • Path: ${rootPath}`
|
|
2015
2142
|
]
|
|
2016
2143
|
});
|
|
2017
|
-
const barrelFiles =
|
|
2144
|
+
const barrelFiles = driver.fileManager.files.filter((file) => {
|
|
2018
2145
|
return file.sources.some((source) => source.isIndexable);
|
|
2019
2146
|
});
|
|
2020
2147
|
await events.emit("debug", {
|
|
2021
2148
|
date: /* @__PURE__ */ new Date(),
|
|
2022
2149
|
logs: [`Found ${barrelFiles.length} indexable files for barrel export`]
|
|
2023
2150
|
});
|
|
2024
|
-
const existingBarrel =
|
|
2025
|
-
const rootFile = {
|
|
2151
|
+
const existingBarrel = driver.fileManager.files.find((f) => f.path === rootPath);
|
|
2152
|
+
const rootFile = (0, _kubb_ast.createFile)({
|
|
2026
2153
|
path: rootPath,
|
|
2027
2154
|
baseName: BARREL_FILENAME,
|
|
2028
2155
|
exports: buildBarrelExports({
|
|
@@ -2031,26 +2158,59 @@ async function safeBuild(options, overrides) {
|
|
|
2031
2158
|
existingExports: new Set(existingBarrel?.exports?.flatMap((e) => Array.isArray(e.name) ? e.name : [e.name]).filter((n) => Boolean(n)) ?? []),
|
|
2032
2159
|
config,
|
|
2033
2160
|
driver
|
|
2034
|
-
}),
|
|
2161
|
+
}).map((e) => (0, _kubb_ast.createExport)(e)),
|
|
2035
2162
|
sources: [],
|
|
2036
2163
|
imports: [],
|
|
2037
2164
|
meta: {}
|
|
2038
|
-
};
|
|
2039
|
-
|
|
2165
|
+
});
|
|
2166
|
+
driver.fileManager.upsert(rootFile);
|
|
2040
2167
|
await events.emit("debug", {
|
|
2041
2168
|
date: /* @__PURE__ */ new Date(),
|
|
2042
2169
|
logs: [`✓ Generated barrel file (${rootFile.exports?.length || 0} exports)`]
|
|
2043
2170
|
});
|
|
2044
2171
|
}
|
|
2045
|
-
const files =
|
|
2046
|
-
|
|
2172
|
+
const files = driver.fileManager.files;
|
|
2173
|
+
const parsersMap = /* @__PURE__ */ new Map();
|
|
2174
|
+
for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
|
|
2175
|
+
const fileProcessor = new FileProcessor();
|
|
2176
|
+
await events.emit("debug", {
|
|
2177
|
+
date: /* @__PURE__ */ new Date(),
|
|
2178
|
+
logs: [`Writing ${files.length} files...`]
|
|
2179
|
+
});
|
|
2180
|
+
await fileProcessor.run(files, {
|
|
2181
|
+
parsers: parsersMap,
|
|
2182
|
+
extension: config.output.extension,
|
|
2183
|
+
onStart: async (processingFiles) => {
|
|
2184
|
+
await events.emit("files:processing:start", processingFiles);
|
|
2185
|
+
},
|
|
2186
|
+
onUpdate: async ({ file, source, processed, total, percentage }) => {
|
|
2187
|
+
await events.emit("file:processing:update", {
|
|
2188
|
+
file,
|
|
2189
|
+
source,
|
|
2190
|
+
processed,
|
|
2191
|
+
total,
|
|
2192
|
+
percentage,
|
|
2193
|
+
config
|
|
2194
|
+
});
|
|
2195
|
+
if (source) {
|
|
2196
|
+
await storage?.setItem(file.path, source);
|
|
2197
|
+
sources.set(file.path, source);
|
|
2198
|
+
}
|
|
2199
|
+
},
|
|
2200
|
+
onEnd: async (processedFiles) => {
|
|
2201
|
+
await events.emit("files:processing:end", processedFiles);
|
|
2202
|
+
await events.emit("debug", {
|
|
2203
|
+
date: /* @__PURE__ */ new Date(),
|
|
2204
|
+
logs: [`✓ File write process completed for ${processedFiles.length} files`]
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
});
|
|
2047
2208
|
for (const plugin of driver.plugins.values()) if (plugin.buildEnd) {
|
|
2048
2209
|
const context = driver.getContext(plugin);
|
|
2049
2210
|
await plugin.buildEnd.call(context);
|
|
2050
2211
|
}
|
|
2051
2212
|
return {
|
|
2052
2213
|
failedPlugins,
|
|
2053
|
-
fabric,
|
|
2054
2214
|
files,
|
|
2055
2215
|
driver,
|
|
2056
2216
|
pluginTimings,
|
|
@@ -2059,7 +2219,6 @@ async function safeBuild(options, overrides) {
|
|
|
2059
2219
|
} catch (error) {
|
|
2060
2220
|
return {
|
|
2061
2221
|
failedPlugins,
|
|
2062
|
-
fabric,
|
|
2063
2222
|
files: [],
|
|
2064
2223
|
driver,
|
|
2065
2224
|
pluginTimings,
|
|
@@ -2080,11 +2239,11 @@ function buildBarrelExports({ barrelFiles, rootDir, existingExports, config, dri
|
|
|
2080
2239
|
if (!pluginOptions || pluginOptions.output?.barrelType === false) return [];
|
|
2081
2240
|
const exportName = config.output.barrelType === "all" ? void 0 : source.name ? [source.name] : void 0;
|
|
2082
2241
|
if (exportName?.some((n) => existingExports.has(n))) return [];
|
|
2083
|
-
return [{
|
|
2242
|
+
return [(0, _kubb_ast.createExport)({
|
|
2084
2243
|
name: exportName,
|
|
2085
2244
|
path: getRelativePath(rootDir, file.path),
|
|
2086
2245
|
isTypeOnly: config.output.barrelType === "all" ? containsOnlyTypes : source.isTypeOnly
|
|
2087
|
-
}];
|
|
2246
|
+
})];
|
|
2088
2247
|
});
|
|
2089
2248
|
});
|
|
2090
2249
|
}
|
|
@@ -2154,6 +2313,11 @@ function createPlugin(build) {
|
|
|
2154
2313
|
return (options) => build(options ?? {});
|
|
2155
2314
|
}
|
|
2156
2315
|
//#endregion
|
|
2316
|
+
//#region src/defineConfig.ts
|
|
2317
|
+
function defineConfig(config) {
|
|
2318
|
+
return config;
|
|
2319
|
+
}
|
|
2320
|
+
//#endregion
|
|
2157
2321
|
//#region src/defineGenerator.ts
|
|
2158
2322
|
/**
|
|
2159
2323
|
* Defines a generator. Returns the object as-is with correct `this` typings.
|
|
@@ -2191,19 +2355,19 @@ function mergeGenerators(generators) {
|
|
|
2191
2355
|
async schema(node, options) {
|
|
2192
2356
|
for (const gen of generators) {
|
|
2193
2357
|
if (!gen.schema) continue;
|
|
2194
|
-
await applyHookResult(await gen.schema.call(this, node, options), this.
|
|
2358
|
+
await applyHookResult(await gen.schema.call(this, node, options), this.driver);
|
|
2195
2359
|
}
|
|
2196
2360
|
},
|
|
2197
2361
|
async operation(node, options) {
|
|
2198
2362
|
for (const gen of generators) {
|
|
2199
2363
|
if (!gen.operation) continue;
|
|
2200
|
-
await applyHookResult(await gen.operation.call(this, node, options), this.
|
|
2364
|
+
await applyHookResult(await gen.operation.call(this, node, options), this.driver);
|
|
2201
2365
|
}
|
|
2202
2366
|
},
|
|
2203
2367
|
async operations(nodes, options) {
|
|
2204
2368
|
for (const gen of generators) {
|
|
2205
2369
|
if (!gen.operations) continue;
|
|
2206
|
-
await applyHookResult(await gen.operations.call(this, nodes, options), this.
|
|
2370
|
+
await applyHookResult(await gen.operations.call(this, nodes, options), this.driver);
|
|
2207
2371
|
}
|
|
2208
2372
|
}
|
|
2209
2373
|
};
|
|
@@ -2226,6 +2390,34 @@ function defineLogger(logger) {
|
|
|
2226
2390
|
return logger;
|
|
2227
2391
|
}
|
|
2228
2392
|
//#endregion
|
|
2393
|
+
//#region src/defineParser.ts
|
|
2394
|
+
/**
|
|
2395
|
+
* Defines a parser with type safety.
|
|
2396
|
+
*
|
|
2397
|
+
* Use this function to create parsers that transform generated files to strings
|
|
2398
|
+
* based on their extension.
|
|
2399
|
+
*
|
|
2400
|
+
* @example
|
|
2401
|
+
* ```ts
|
|
2402
|
+
* import { defineParser } from '@kubb/core'
|
|
2403
|
+
*
|
|
2404
|
+
* export const jsonParser = defineParser({
|
|
2405
|
+
* name: 'json',
|
|
2406
|
+
* extNames: ['.json'],
|
|
2407
|
+
* parse(file) {
|
|
2408
|
+
* return file.sources.map((s) => s.value).join('\n')
|
|
2409
|
+
* },
|
|
2410
|
+
* })
|
|
2411
|
+
* ```
|
|
2412
|
+
*/
|
|
2413
|
+
function defineParser(parser) {
|
|
2414
|
+
return {
|
|
2415
|
+
install() {},
|
|
2416
|
+
type: "parser",
|
|
2417
|
+
...parser
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
//#endregion
|
|
2229
2421
|
//#region src/definePresets.ts
|
|
2230
2422
|
/**
|
|
2231
2423
|
* Creates a typed presets registry object — a named collection of {@link Preset} entries.
|
|
@@ -2379,7 +2571,7 @@ function defaultResolvePath({ baseName, pathMode, tag, path: groupPath }, { root
|
|
|
2379
2571
|
/**
|
|
2380
2572
|
* Default file resolver used by `defineResolver`.
|
|
2381
2573
|
*
|
|
2382
|
-
* Resolves a `
|
|
2574
|
+
* Resolves a `FileNode` by combining name resolution (`resolver.default`) with
|
|
2383
2575
|
* path resolution (`resolver.resolvePath`). The resolved file always has empty
|
|
2384
2576
|
* `sources`, `imports`, and `exports` arrays — consumers populate those separately.
|
|
2385
2577
|
*
|
|
@@ -2412,14 +2604,14 @@ function defaultResolveFile({ name, extname, tag, path: groupPath }, context) {
|
|
|
2412
2604
|
tag,
|
|
2413
2605
|
path: groupPath
|
|
2414
2606
|
}, context);
|
|
2415
|
-
return {
|
|
2607
|
+
return (0, _kubb_ast.createFile)({
|
|
2416
2608
|
path: filePath,
|
|
2417
2609
|
baseName: node_path.default.basename(filePath),
|
|
2418
2610
|
meta: { pluginName: this.pluginName },
|
|
2419
2611
|
sources: [],
|
|
2420
2612
|
imports: [],
|
|
2421
2613
|
exports: []
|
|
2422
|
-
};
|
|
2614
|
+
});
|
|
2423
2615
|
}
|
|
2424
2616
|
/**
|
|
2425
2617
|
* Generates the default "Generated by Kubb" banner from config and optional node metadata.
|
|
@@ -2471,13 +2663,13 @@ function buildDefaultBanner({ title, description, version, config }) {
|
|
|
2471
2663
|
*
|
|
2472
2664
|
* @example Function banner with node
|
|
2473
2665
|
* ```ts
|
|
2474
|
-
* defaultResolveBanner(
|
|
2666
|
+
* defaultResolveBanner(inputNode, { output: { banner: (node) => `// v${node.version}` }, config })
|
|
2475
2667
|
* // → '// v3.0.0'
|
|
2476
2668
|
* ```
|
|
2477
2669
|
*
|
|
2478
2670
|
* @example No user banner — Kubb notice with OAS metadata
|
|
2479
2671
|
* ```ts
|
|
2480
|
-
* defaultResolveBanner(
|
|
2672
|
+
* defaultResolveBanner(inputNode, { config })
|
|
2481
2673
|
* // → '/** Generated by Kubb ... Title: Pet Store ... *\/'
|
|
2482
2674
|
* ```
|
|
2483
2675
|
*
|
|
@@ -2513,7 +2705,7 @@ function defaultResolveBanner(node, { output, config }) {
|
|
|
2513
2705
|
*
|
|
2514
2706
|
* @example Function footer with node
|
|
2515
2707
|
* ```ts
|
|
2516
|
-
* defaultResolveFooter(
|
|
2708
|
+
* defaultResolveFooter(inputNode, { output: { footer: (node) => `// ${node.title}` }, config })
|
|
2517
2709
|
* // → '// Pet Store'
|
|
2518
2710
|
* ```
|
|
2519
2711
|
*/
|
|
@@ -2529,7 +2721,7 @@ function defaultResolveFooter(node, { output }) {
|
|
|
2529
2721
|
* - `default` — name casing strategy (camelCase / PascalCase)
|
|
2530
2722
|
* - `resolveOptions` — include/exclude/override filtering
|
|
2531
2723
|
* - `resolvePath` — output path computation
|
|
2532
|
-
* - `resolveFile` — full `
|
|
2724
|
+
* - `resolveFile` — full `FileNode` construction
|
|
2533
2725
|
*
|
|
2534
2726
|
* Methods in the builder have access to `this` (the full resolver object), so they
|
|
2535
2727
|
* can call other resolver methods without circular imports.
|
|
@@ -2905,6 +3097,7 @@ exports.defaultResolvePath = defaultResolvePath;
|
|
|
2905
3097
|
exports.defineConfig = defineConfig;
|
|
2906
3098
|
exports.defineGenerator = defineGenerator;
|
|
2907
3099
|
exports.defineLogger = defineLogger;
|
|
3100
|
+
exports.defineParser = defineParser;
|
|
2908
3101
|
exports.definePresets = definePresets;
|
|
2909
3102
|
Object.defineProperty(exports, "definePrinter", {
|
|
2910
3103
|
enumerable: true,
|