@kubb/core 5.0.0-alpha.31 → 5.0.0-alpha.33
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-D0dY_hpJ.d.ts → PluginDriver-BBi_41VF.d.ts} +113 -224
- package/dist/chunk--u3MIqq1.js +8 -0
- package/dist/{chunk-MlS0t1Af.cjs → chunk-ByKO4r7w.cjs} +0 -15
- package/dist/hooks.cjs +5 -8
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +3 -3
- package/dist/hooks.js +5 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +460 -279
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +73 -24
- package/dist/index.js +461 -276
- package/dist/index.js.map +1 -1
- package/package.json +5 -7
- package/src/FileManager.ts +131 -0
- package/src/FileProcessor.ts +84 -0
- package/src/Kubb.ts +6 -6
- package/src/PluginDriver.ts +29 -24
- package/src/build.ts +89 -108
- package/src/constants.ts +7 -2
- package/src/defineGenerator.ts +13 -18
- package/src/defineParser.ts +8 -21
- package/src/defineResolver.ts +18 -19
- package/src/devtools.ts +14 -14
- package/src/hooks/useDriver.ts +2 -4
- package/src/hooks/useMode.ts +3 -6
- package/src/hooks/usePlugin.ts +2 -4
- package/src/index.ts +3 -2
- package/src/renderNode.tsx +15 -12
- package/src/types.ts +47 -50
- package/src/utils/TreeNode.ts +7 -7
- package/src/utils/getBarrelFiles.ts +28 -25
- package/src/utils/getFunctionParams.ts +247 -0
- package/dist/chunk-O_arW02_.js +0 -17
- package/src/KubbFile.ts +0 -143
package/dist/index.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { t as
|
|
1
|
+
import { t as __name } from "./chunk--u3MIqq1.js";
|
|
2
2
|
import { EventEmitter } from "node:events";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { access, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
5
|
-
import path, { basename, dirname, extname, join, posix,
|
|
6
|
-
import { composeTransformers, composeTransformers as composeTransformers$1, definePrinter, isOperationNode, isSchemaNode, transform, walk } from "@kubb/ast";
|
|
7
|
-
import { Fabric, createFabric, createReactFabric } from "@kubb/react-fabric";
|
|
8
|
-
import { fsPlugin } from "@kubb/react-fabric/plugins";
|
|
5
|
+
import path, { basename, dirname, extname, join, posix, resolve } from "node:path";
|
|
6
|
+
import { composeTransformers, composeTransformers as composeTransformers$1, createExport, createFile, createSource, definePrinter, extractStringsFromNodes, isOperationNode, isSchemaNode, transform, walk } from "@kubb/ast";
|
|
9
7
|
import { performance } from "node:perf_hooks";
|
|
10
8
|
import { deflateSync } from "fflate";
|
|
11
9
|
import { x } from "tinyexec";
|
|
12
|
-
import {
|
|
10
|
+
import { createRenderer } from "@kubb/renderer-jsx";
|
|
11
|
+
import { Fragment, jsx } from "@kubb/renderer-jsx/jsx-runtime";
|
|
13
12
|
import { version } from "node:process";
|
|
14
13
|
import { sortBy } from "remeda";
|
|
15
14
|
import * as pkg from "empathic/package";
|
|
@@ -333,6 +332,24 @@ async function clean(path) {
|
|
|
333
332
|
});
|
|
334
333
|
}
|
|
335
334
|
//#endregion
|
|
335
|
+
//#region ../../internals/utils/src/string.ts
|
|
336
|
+
/**
|
|
337
|
+
* Strips the file extension from a path or file name.
|
|
338
|
+
* Only removes the last `.ext` segment when the dot is not part of a directory name.
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* trimExtName('petStore.ts') // 'petStore'
|
|
342
|
+
* trimExtName('/src/models/pet.ts') // '/src/models/pet'
|
|
343
|
+
* trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'
|
|
344
|
+
* trimExtName('noExtension') // 'noExtension'
|
|
345
|
+
*/
|
|
346
|
+
function trimExtName$1(text) {
|
|
347
|
+
const dotIndex = text.lastIndexOf(".");
|
|
348
|
+
if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
|
|
349
|
+
return text;
|
|
350
|
+
}
|
|
351
|
+
__name(trimExtName$1, "trimExtName");
|
|
352
|
+
//#endregion
|
|
336
353
|
//#region ../../internals/utils/src/promise.ts
|
|
337
354
|
/** Returns `true` when `result` is a rejected `Promise.allSettled` result with a typed `reason`.
|
|
338
355
|
*
|
|
@@ -705,78 +722,6 @@ const formatters = {
|
|
|
705
722
|
}
|
|
706
723
|
};
|
|
707
724
|
//#endregion
|
|
708
|
-
//#region src/defineParser.ts
|
|
709
|
-
/**
|
|
710
|
-
* Defines a parser with type safety.
|
|
711
|
-
*
|
|
712
|
-
* Use this function to create parsers that transform generated files to strings
|
|
713
|
-
* based on their extension.
|
|
714
|
-
*
|
|
715
|
-
* @example
|
|
716
|
-
* ```ts
|
|
717
|
-
* import { defineParser } from '@kubb/core'
|
|
718
|
-
*
|
|
719
|
-
* export const jsonParser = defineParser({
|
|
720
|
-
* name: 'json',
|
|
721
|
-
* extNames: ['.json'],
|
|
722
|
-
* parse(file) {
|
|
723
|
-
* return file.sources.map((s) => s.value).join('\n')
|
|
724
|
-
* },
|
|
725
|
-
* })
|
|
726
|
-
* ```
|
|
727
|
-
*/
|
|
728
|
-
function defineParser(parser) {
|
|
729
|
-
return {
|
|
730
|
-
install() {},
|
|
731
|
-
type: "parser",
|
|
732
|
-
...parser
|
|
733
|
-
};
|
|
734
|
-
}
|
|
735
|
-
//#endregion
|
|
736
|
-
//#region src/devtools.ts
|
|
737
|
-
/**
|
|
738
|
-
* Encodes a `RootNode` as a compressed, URL-safe string.
|
|
739
|
-
*
|
|
740
|
-
* The JSON representation is deflate-compressed with {@link deflateSync} before
|
|
741
|
-
* base64url encoding, which typically reduces payload size by 70–80 % and
|
|
742
|
-
* keeps URLs well within browser and server path-length limits.
|
|
743
|
-
*
|
|
744
|
-
* Use {@link decodeAst} to reverse.
|
|
745
|
-
*/
|
|
746
|
-
function encodeAst(root) {
|
|
747
|
-
const compressed = deflateSync(new TextEncoder().encode(JSON.stringify(root)));
|
|
748
|
-
return Buffer.from(compressed).toString("base64url");
|
|
749
|
-
}
|
|
750
|
-
/**
|
|
751
|
-
* Constructs the Kubb Studio URL for the given `RootNode`.
|
|
752
|
-
* When `options.ast` is `true`, navigates to the AST inspector (`/ast`).
|
|
753
|
-
* The `root` is encoded and attached as the `?root=` query parameter so Studio
|
|
754
|
-
* can decode and render it without a round-trip to any server.
|
|
755
|
-
*/
|
|
756
|
-
function getStudioUrl(root, studioUrl, options = {}) {
|
|
757
|
-
return `${studioUrl.replace(/\/$/, "")}${options.ast ? "/ast" : ""}?root=${encodeAst(root)}`;
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Opens the Kubb Studio URL for the given `RootNode` in the default browser —
|
|
761
|
-
*
|
|
762
|
-
* Falls back to printing the URL if the browser cannot be launched.
|
|
763
|
-
*/
|
|
764
|
-
async function openInStudio(root, studioUrl, options = {}) {
|
|
765
|
-
const url = getStudioUrl(root, studioUrl, options);
|
|
766
|
-
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
767
|
-
const args = process.platform === "win32" ? [
|
|
768
|
-
"/c",
|
|
769
|
-
"start",
|
|
770
|
-
"",
|
|
771
|
-
url
|
|
772
|
-
] : [url];
|
|
773
|
-
try {
|
|
774
|
-
await x(cmd, args);
|
|
775
|
-
} catch {
|
|
776
|
-
console.log(`\n ${url}\n`);
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
//#endregion
|
|
780
725
|
//#region ../../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
781
726
|
var Node = class {
|
|
782
727
|
value;
|
|
@@ -904,6 +849,194 @@ function validateConcurrency(concurrency) {
|
|
|
904
849
|
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
905
850
|
}
|
|
906
851
|
//#endregion
|
|
852
|
+
//#region src/FileProcessor.ts
|
|
853
|
+
function joinSources(file) {
|
|
854
|
+
return file.sources.map((item) => extractStringsFromNodes(item.nodes)).filter(Boolean).join("\n\n");
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Converts a single file to a string using the registered parsers.
|
|
858
|
+
* Falls back to joining source values when no matching parser is found.
|
|
859
|
+
*/
|
|
860
|
+
var FileProcessor = class {
|
|
861
|
+
#limit = pLimit(100);
|
|
862
|
+
async parse(file, { parsers, extension } = {}) {
|
|
863
|
+
const parseExtName = extension?.[file.extname] || void 0;
|
|
864
|
+
if (!parsers || !file.extname) return joinSources(file);
|
|
865
|
+
const parser = parsers.get(file.extname);
|
|
866
|
+
if (!parser) return joinSources(file);
|
|
867
|
+
return parser.parse(file, { extname: parseExtName });
|
|
868
|
+
}
|
|
869
|
+
async run(files, { parsers, mode = "sequential", extension, onStart, onEnd, onUpdate } = {}) {
|
|
870
|
+
await onStart?.(files);
|
|
871
|
+
const total = files.length;
|
|
872
|
+
let processed = 0;
|
|
873
|
+
const processOne = async (file) => {
|
|
874
|
+
const source = await this.parse(file, {
|
|
875
|
+
extension,
|
|
876
|
+
parsers
|
|
877
|
+
});
|
|
878
|
+
const currentProcessed = ++processed;
|
|
879
|
+
const percentage = currentProcessed / total * 100;
|
|
880
|
+
await onUpdate?.({
|
|
881
|
+
file,
|
|
882
|
+
source,
|
|
883
|
+
processed: currentProcessed,
|
|
884
|
+
percentage,
|
|
885
|
+
total
|
|
886
|
+
});
|
|
887
|
+
};
|
|
888
|
+
if (mode === "sequential") for (const file of files) await processOne(file);
|
|
889
|
+
else await Promise.all(files.map((file) => this.#limit(() => processOne(file))));
|
|
890
|
+
await onEnd?.(files);
|
|
891
|
+
return files;
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
//#endregion
|
|
895
|
+
//#region src/devtools.ts
|
|
896
|
+
/**
|
|
897
|
+
* Encodes an `InputNode` as a compressed, URL-safe string.
|
|
898
|
+
*
|
|
899
|
+
* The JSON representation is deflate-compressed with {@link deflateSync} before
|
|
900
|
+
* base64url encoding, which typically reduces payload size by 70–80 % and
|
|
901
|
+
* keeps URLs well within browser and server path-length limits.
|
|
902
|
+
*
|
|
903
|
+
* Use {@link decodeAst} to reverse.
|
|
904
|
+
*/
|
|
905
|
+
function encodeAst(input) {
|
|
906
|
+
const compressed = deflateSync(new TextEncoder().encode(JSON.stringify(input)));
|
|
907
|
+
return Buffer.from(compressed).toString("base64url");
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Constructs the Kubb Studio URL for the given `InputNode`.
|
|
911
|
+
* When `options.ast` is `true`, navigates to the AST inspector (`/ast`).
|
|
912
|
+
* The `input` is encoded and attached as the `?root=` query parameter so Studio
|
|
913
|
+
* can decode and render it without a round-trip to any server.
|
|
914
|
+
*/
|
|
915
|
+
function getStudioUrl(input, studioUrl, options = {}) {
|
|
916
|
+
return `${studioUrl.replace(/\/$/, "")}${options.ast ? "/ast" : ""}?root=${encodeAst(input)}`;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Opens the Kubb Studio URL for the given `InputNode` in the default browser —
|
|
920
|
+
*
|
|
921
|
+
* Falls back to printing the URL if the browser cannot be launched.
|
|
922
|
+
*/
|
|
923
|
+
async function openInStudio(input, studioUrl, options = {}) {
|
|
924
|
+
const url = getStudioUrl(input, studioUrl, options);
|
|
925
|
+
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
926
|
+
const args = process.platform === "win32" ? [
|
|
927
|
+
"/c",
|
|
928
|
+
"start",
|
|
929
|
+
"",
|
|
930
|
+
url
|
|
931
|
+
] : [url];
|
|
932
|
+
try {
|
|
933
|
+
await x(cmd, args);
|
|
934
|
+
} catch {
|
|
935
|
+
console.log(`\n ${url}\n`);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
//#endregion
|
|
939
|
+
//#region src/FileManager.ts
|
|
940
|
+
function mergeFile(a, b) {
|
|
941
|
+
return {
|
|
942
|
+
...a,
|
|
943
|
+
sources: [...a.sources || [], ...b.sources || []],
|
|
944
|
+
imports: [...a.imports || [], ...b.imports || []],
|
|
945
|
+
exports: [...a.exports || [], ...b.exports || []]
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* In-memory file store for generated files.
|
|
950
|
+
*
|
|
951
|
+
* Files with the same `path` are merged — sources, imports, and exports are concatenated.
|
|
952
|
+
* The `files` getter returns all stored files sorted by path length (shortest first).
|
|
953
|
+
*
|
|
954
|
+
* @example
|
|
955
|
+
* ```ts
|
|
956
|
+
* import { FileManager } from '@kubb/core'
|
|
957
|
+
*
|
|
958
|
+
* const manager = new FileManager()
|
|
959
|
+
* manager.upsert(myFile)
|
|
960
|
+
* console.log(manager.files) // all stored files
|
|
961
|
+
* ```
|
|
962
|
+
*/
|
|
963
|
+
var FileManager = class {
|
|
964
|
+
#cache = /* @__PURE__ */ new Map();
|
|
965
|
+
#filesCache = null;
|
|
966
|
+
/**
|
|
967
|
+
* Adds one or more files. Files with the same path are merged — sources, imports,
|
|
968
|
+
* and exports from all calls with the same path are concatenated together.
|
|
969
|
+
*/
|
|
970
|
+
add(...files) {
|
|
971
|
+
const resolvedFiles = [];
|
|
972
|
+
const mergedFiles = /* @__PURE__ */ new Map();
|
|
973
|
+
files.forEach((file) => {
|
|
974
|
+
const existing = mergedFiles.get(file.path);
|
|
975
|
+
if (existing) mergedFiles.set(file.path, mergeFile(existing, file));
|
|
976
|
+
else mergedFiles.set(file.path, file);
|
|
977
|
+
});
|
|
978
|
+
for (const file of mergedFiles.values()) {
|
|
979
|
+
const resolvedFile = createFile(file);
|
|
980
|
+
this.#cache.set(resolvedFile.path, resolvedFile);
|
|
981
|
+
this.#filesCache = null;
|
|
982
|
+
resolvedFiles.push(resolvedFile);
|
|
983
|
+
}
|
|
984
|
+
return resolvedFiles;
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Adds or merges one or more files.
|
|
988
|
+
* If a file with the same path already exists, its sources/imports/exports are merged together.
|
|
989
|
+
*/
|
|
990
|
+
upsert(...files) {
|
|
991
|
+
const resolvedFiles = [];
|
|
992
|
+
const mergedFiles = /* @__PURE__ */ new Map();
|
|
993
|
+
files.forEach((file) => {
|
|
994
|
+
const existing = mergedFiles.get(file.path);
|
|
995
|
+
if (existing) mergedFiles.set(file.path, mergeFile(existing, file));
|
|
996
|
+
else mergedFiles.set(file.path, file);
|
|
997
|
+
});
|
|
998
|
+
for (const file of mergedFiles.values()) {
|
|
999
|
+
const existing = this.#cache.get(file.path);
|
|
1000
|
+
const resolvedFile = createFile(existing ? mergeFile(existing, file) : file);
|
|
1001
|
+
this.#cache.set(resolvedFile.path, resolvedFile);
|
|
1002
|
+
this.#filesCache = null;
|
|
1003
|
+
resolvedFiles.push(resolvedFile);
|
|
1004
|
+
}
|
|
1005
|
+
return resolvedFiles;
|
|
1006
|
+
}
|
|
1007
|
+
getByPath(path) {
|
|
1008
|
+
return this.#cache.get(path) ?? null;
|
|
1009
|
+
}
|
|
1010
|
+
deleteByPath(path) {
|
|
1011
|
+
this.#cache.delete(path);
|
|
1012
|
+
this.#filesCache = null;
|
|
1013
|
+
}
|
|
1014
|
+
clear() {
|
|
1015
|
+
this.#cache.clear();
|
|
1016
|
+
this.#filesCache = null;
|
|
1017
|
+
}
|
|
1018
|
+
/**
|
|
1019
|
+
* All stored files, sorted by path length (shorter paths first).
|
|
1020
|
+
* Barrel/index files (e.g. index.ts) are sorted last within each length bucket.
|
|
1021
|
+
*/
|
|
1022
|
+
get files() {
|
|
1023
|
+
if (this.#filesCache) return this.#filesCache;
|
|
1024
|
+
const keys = [...this.#cache.keys()].sort((a, b) => {
|
|
1025
|
+
if (a.length !== b.length) return a.length - b.length;
|
|
1026
|
+
const aIsIndex = trimExtName$1(a).endsWith("index");
|
|
1027
|
+
if (aIsIndex !== trimExtName$1(b).endsWith("index")) return aIsIndex ? 1 : -1;
|
|
1028
|
+
return 0;
|
|
1029
|
+
});
|
|
1030
|
+
const files = [];
|
|
1031
|
+
for (const key of keys) {
|
|
1032
|
+
const file = this.#cache.get(key);
|
|
1033
|
+
if (file) files.push(file);
|
|
1034
|
+
}
|
|
1035
|
+
this.#filesCache = files;
|
|
1036
|
+
return files;
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
//#endregion
|
|
907
1040
|
//#region src/utils/executeStrategies.ts
|
|
908
1041
|
/**
|
|
909
1042
|
* Runs promise functions in sequence, threading each result into the next call.
|
|
@@ -970,12 +1103,18 @@ var PluginDriver = class {
|
|
|
970
1103
|
config;
|
|
971
1104
|
options;
|
|
972
1105
|
/**
|
|
973
|
-
* The universal `@kubb/ast` `
|
|
1106
|
+
* The universal `@kubb/ast` `InputNode` produced by the adapter, set by
|
|
974
1107
|
* the build pipeline after the adapter's `parse()` resolves.
|
|
975
1108
|
*/
|
|
976
|
-
|
|
1109
|
+
inputNode = void 0;
|
|
977
1110
|
adapter = void 0;
|
|
978
1111
|
#studioIsOpen = false;
|
|
1112
|
+
/**
|
|
1113
|
+
* Central file store for all generated files.
|
|
1114
|
+
* Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
|
|
1115
|
+
* add files; this property gives direct read/write access when needed.
|
|
1116
|
+
*/
|
|
1117
|
+
fileManager = new FileManager();
|
|
979
1118
|
plugins = /* @__PURE__ */ new Map();
|
|
980
1119
|
constructor(config, options) {
|
|
981
1120
|
this.config = config;
|
|
@@ -1000,7 +1139,6 @@ var PluginDriver = class {
|
|
|
1000
1139
|
getContext(plugin) {
|
|
1001
1140
|
const driver = this;
|
|
1002
1141
|
const baseContext = {
|
|
1003
|
-
fabric: driver.options.fabric,
|
|
1004
1142
|
config: driver.config,
|
|
1005
1143
|
get root() {
|
|
1006
1144
|
return resolve(driver.config.root, driver.config.output.path);
|
|
@@ -1014,13 +1152,13 @@ var PluginDriver = class {
|
|
|
1014
1152
|
requirePlugin: driver.requirePlugin.bind(driver),
|
|
1015
1153
|
driver,
|
|
1016
1154
|
addFile: async (...files) => {
|
|
1017
|
-
|
|
1155
|
+
driver.fileManager.add(...files);
|
|
1018
1156
|
},
|
|
1019
1157
|
upsertFile: async (...files) => {
|
|
1020
|
-
|
|
1158
|
+
driver.fileManager.upsert(...files);
|
|
1021
1159
|
},
|
|
1022
|
-
get
|
|
1023
|
-
return driver.
|
|
1160
|
+
get inputNode() {
|
|
1161
|
+
return driver.inputNode;
|
|
1024
1162
|
},
|
|
1025
1163
|
get adapter() {
|
|
1026
1164
|
return driver.adapter;
|
|
@@ -1043,10 +1181,10 @@ var PluginDriver = class {
|
|
|
1043
1181
|
openInStudio(options) {
|
|
1044
1182
|
if (!driver.config.devtools || driver.#studioIsOpen) return;
|
|
1045
1183
|
if (typeof driver.config.devtools !== "object") throw new Error("Devtools must be an object");
|
|
1046
|
-
if (!driver.
|
|
1184
|
+
if (!driver.inputNode || !driver.adapter) throw new Error("adapter is not defined, make sure you have set the parser in kubb.config.ts");
|
|
1047
1185
|
driver.#studioIsOpen = true;
|
|
1048
1186
|
const studioUrl = driver.config.devtools?.studioUrl ?? "https://studio.kubb.dev";
|
|
1049
|
-
return openInStudio(driver.
|
|
1187
|
+
return openInStudio(driver.inputNode, studioUrl, options);
|
|
1050
1188
|
}
|
|
1051
1189
|
};
|
|
1052
1190
|
const mergedExtras = {};
|
|
@@ -1075,14 +1213,14 @@ var PluginDriver = class {
|
|
|
1075
1213
|
options
|
|
1076
1214
|
});
|
|
1077
1215
|
if (!path) throw new Error(`Filepath should be defined for resolvedName "${resolvedName}" and pluginName "${pluginName}"`);
|
|
1078
|
-
return {
|
|
1216
|
+
return createFile({
|
|
1079
1217
|
path,
|
|
1080
1218
|
baseName: basename(path),
|
|
1081
1219
|
meta: { pluginName },
|
|
1082
1220
|
sources: [],
|
|
1083
1221
|
imports: [],
|
|
1084
1222
|
exports: []
|
|
1085
|
-
};
|
|
1223
|
+
});
|
|
1086
1224
|
}
|
|
1087
1225
|
/**
|
|
1088
1226
|
* @deprecated use resolvers context instead
|
|
@@ -1366,20 +1504,20 @@ var PluginDriver = class {
|
|
|
1366
1504
|
/**
|
|
1367
1505
|
* Handles the return value of a plugin AST hook or generator method.
|
|
1368
1506
|
*
|
|
1369
|
-
* - React element → rendered via
|
|
1370
|
-
* - `Array<
|
|
1507
|
+
* - React element → rendered via renderer-jsx, files stored in `driver.fileManager`
|
|
1508
|
+
* - `Array<FileNode>` → upserted directly into `driver.fileManager`
|
|
1371
1509
|
* - `void` / `null` / `undefined` → no-op (plugin handled it via `this.upsertFile`)
|
|
1372
1510
|
*/
|
|
1373
|
-
async function applyHookResult(result,
|
|
1511
|
+
async function applyHookResult(result, driver) {
|
|
1374
1512
|
if (!result) return;
|
|
1375
1513
|
if (Array.isArray(result)) {
|
|
1376
|
-
|
|
1514
|
+
driver.fileManager.upsert(...result);
|
|
1377
1515
|
return;
|
|
1378
1516
|
}
|
|
1379
|
-
const
|
|
1380
|
-
await
|
|
1381
|
-
|
|
1382
|
-
|
|
1517
|
+
const renderer = createRenderer();
|
|
1518
|
+
await renderer.render(/* @__PURE__ */ jsx(Fragment, { children: result }));
|
|
1519
|
+
driver.fileManager.upsert(...renderer.files);
|
|
1520
|
+
renderer.unmount();
|
|
1383
1521
|
}
|
|
1384
1522
|
//#endregion
|
|
1385
1523
|
//#region src/createStorage.ts
|
|
@@ -1479,7 +1617,7 @@ const fsStorage = createStorage(() => ({
|
|
|
1479
1617
|
}));
|
|
1480
1618
|
//#endregion
|
|
1481
1619
|
//#region package.json
|
|
1482
|
-
var version$1 = "5.0.0-alpha.
|
|
1620
|
+
var version$1 = "5.0.0-alpha.33";
|
|
1483
1621
|
//#endregion
|
|
1484
1622
|
//#region src/utils/diagnostics.ts
|
|
1485
1623
|
/**
|
|
@@ -1501,7 +1639,7 @@ function getDiagnosticInfo() {
|
|
|
1501
1639
|
//#region src/utils/TreeNode.ts
|
|
1502
1640
|
/**
|
|
1503
1641
|
* Tree structure used to build per-directory barrel (`index.ts`) files from a
|
|
1504
|
-
* flat list of generated {@link
|
|
1642
|
+
* flat list of generated {@link FileNode} entries.
|
|
1505
1643
|
*
|
|
1506
1644
|
* Each node represents either a directory or a file within the output tree.
|
|
1507
1645
|
* Use {@link TreeNode.build} to construct a root node from a file list, then
|
|
@@ -1662,36 +1800,35 @@ function getBarrelFilesByRoot(root, files) {
|
|
|
1662
1800
|
const cachedFiles = /* @__PURE__ */ new Map();
|
|
1663
1801
|
TreeNode.build(files, root)?.forEach((treeNode) => {
|
|
1664
1802
|
if (!treeNode?.children || !treeNode.parent?.data.path) return;
|
|
1665
|
-
const barrelFile = {
|
|
1803
|
+
const barrelFile = createFile({
|
|
1666
1804
|
path: join(treeNode.parent?.data.path, "index.ts"),
|
|
1667
1805
|
baseName: "index.ts",
|
|
1668
1806
|
exports: [],
|
|
1669
1807
|
imports: [],
|
|
1670
1808
|
sources: []
|
|
1671
|
-
};
|
|
1809
|
+
});
|
|
1672
1810
|
const previousBarrelFile = cachedFiles.get(barrelFile.path);
|
|
1673
1811
|
treeNode.leaves.forEach((item) => {
|
|
1674
1812
|
if (!item.data.name) return;
|
|
1675
1813
|
(item.data.file?.sources || []).forEach((source) => {
|
|
1676
1814
|
if (!item.data.file?.path || !source.isIndexable || !source.name) return;
|
|
1677
1815
|
if (previousBarrelFile?.sources.some((item) => item.name === source.name && item.isTypeOnly === source.isTypeOnly)) return;
|
|
1678
|
-
barrelFile.exports.push({
|
|
1816
|
+
barrelFile.exports.push(createExport({
|
|
1679
1817
|
name: [source.name],
|
|
1680
1818
|
path: getRelativePath(treeNode.parent?.data.path, item.data.path),
|
|
1681
1819
|
isTypeOnly: source.isTypeOnly
|
|
1682
|
-
});
|
|
1683
|
-
barrelFile.sources.push({
|
|
1820
|
+
}));
|
|
1821
|
+
barrelFile.sources.push(createSource({
|
|
1684
1822
|
name: source.name,
|
|
1685
1823
|
isTypeOnly: source.isTypeOnly,
|
|
1686
|
-
value: "",
|
|
1687
1824
|
isExportable: false,
|
|
1688
1825
|
isIndexable: false
|
|
1689
|
-
});
|
|
1826
|
+
}));
|
|
1690
1827
|
});
|
|
1691
1828
|
});
|
|
1692
1829
|
if (previousBarrelFile) {
|
|
1693
1830
|
previousBarrelFile.sources.push(...barrelFile.sources);
|
|
1694
|
-
previousBarrelFile.exports
|
|
1831
|
+
previousBarrelFile.exports.push(...barrelFile.exports);
|
|
1695
1832
|
} else cachedFiles.set(barrelFile.path, barrelFile);
|
|
1696
1833
|
});
|
|
1697
1834
|
return [...cachedFiles.values()];
|
|
@@ -1717,7 +1854,7 @@ async function getBarrelFiles(files, { type, meta = {}, root, output }) {
|
|
|
1717
1854
|
if (type === "all") return barrelFiles.map((file) => {
|
|
1718
1855
|
return {
|
|
1719
1856
|
...file,
|
|
1720
|
-
exports: file.exports
|
|
1857
|
+
exports: file.exports.map((exportItem) => {
|
|
1721
1858
|
return {
|
|
1722
1859
|
...exportItem,
|
|
1723
1860
|
name: void 0
|
|
@@ -1747,8 +1884,7 @@ function isInputPath(config) {
|
|
|
1747
1884
|
*
|
|
1748
1885
|
* - Validates the input path (when applicable).
|
|
1749
1886
|
* - Applies config defaults (`root`, `output.*`, `devtools`).
|
|
1750
|
-
* -
|
|
1751
|
-
* - Runs the adapter (if configured) to produce the universal `RootNode`.
|
|
1887
|
+
* - Runs the adapter (if configured) to produce the universal `InputNode`.
|
|
1752
1888
|
* When no adapter is supplied and `@kubb/adapter-oas` is installed as an
|
|
1753
1889
|
*
|
|
1754
1890
|
* Pass the returned {@link SetupResult} directly to {@link safeBuild} or {@link build}
|
|
@@ -1816,53 +1952,7 @@ async function setup(options) {
|
|
|
1816
1952
|
});
|
|
1817
1953
|
await storage?.clear(resolve(config.root, config.output.path));
|
|
1818
1954
|
}
|
|
1819
|
-
const fabric = createFabric();
|
|
1820
|
-
fabric.use(fsPlugin);
|
|
1821
|
-
for (const parser of config.parsers) fabric.use(parser);
|
|
1822
|
-
fabric.use(defineParser({
|
|
1823
|
-
name: "fallback",
|
|
1824
|
-
extNames: void 0,
|
|
1825
|
-
parse(file) {
|
|
1826
|
-
return file.sources.map((item) => item.value).filter((value) => value != null).join("\n\n");
|
|
1827
|
-
}
|
|
1828
|
-
}));
|
|
1829
|
-
fabric.context.on("files:processing:start", (files) => {
|
|
1830
|
-
events.emit("files:processing:start", files);
|
|
1831
|
-
events.emit("debug", {
|
|
1832
|
-
date: /* @__PURE__ */ new Date(),
|
|
1833
|
-
logs: [`Writing ${files.length} files...`]
|
|
1834
|
-
});
|
|
1835
|
-
});
|
|
1836
|
-
fabric.context.on("file:processing:update", async (params) => {
|
|
1837
|
-
const { file, source } = params;
|
|
1838
|
-
await events.emit("file:processing:update", {
|
|
1839
|
-
...params,
|
|
1840
|
-
config,
|
|
1841
|
-
source
|
|
1842
|
-
});
|
|
1843
|
-
if (source) {
|
|
1844
|
-
const key = relative(resolve(config.root), file.path);
|
|
1845
|
-
await storage?.setItem(key, source);
|
|
1846
|
-
sources.set(file.path, source);
|
|
1847
|
-
}
|
|
1848
|
-
});
|
|
1849
|
-
fabric.context.on("files:processing:end", async (files) => {
|
|
1850
|
-
await events.emit("files:processing:end", files);
|
|
1851
|
-
await events.emit("debug", {
|
|
1852
|
-
date: /* @__PURE__ */ new Date(),
|
|
1853
|
-
logs: [`✓ File write process completed for ${files.length} files`]
|
|
1854
|
-
});
|
|
1855
|
-
});
|
|
1856
|
-
await events.emit("debug", {
|
|
1857
|
-
date: /* @__PURE__ */ new Date(),
|
|
1858
|
-
logs: [
|
|
1859
|
-
"✓ Fabric initialized",
|
|
1860
|
-
` • Storage: ${storage ? storage.name : "disabled (dry-run)"}`,
|
|
1861
|
-
` • Barrel type: ${config.output.barrelType || "none"}`
|
|
1862
|
-
]
|
|
1863
|
-
});
|
|
1864
1955
|
const driver = new PluginDriver(config, {
|
|
1865
|
-
fabric,
|
|
1866
1956
|
events,
|
|
1867
1957
|
concurrency: 15
|
|
1868
1958
|
});
|
|
@@ -1874,21 +1964,21 @@ async function setup(options) {
|
|
|
1874
1964
|
logs: [`Running adapter: ${adapter.name}`]
|
|
1875
1965
|
});
|
|
1876
1966
|
driver.adapter = adapter;
|
|
1877
|
-
driver.
|
|
1967
|
+
driver.inputNode = await adapter.parse(source);
|
|
1878
1968
|
await events.emit("debug", {
|
|
1879
1969
|
date: /* @__PURE__ */ new Date(),
|
|
1880
1970
|
logs: [
|
|
1881
|
-
`✓ Adapter '${adapter.name}' resolved
|
|
1882
|
-
` • Schemas: ${driver.
|
|
1883
|
-
` • Operations: ${driver.
|
|
1971
|
+
`✓ Adapter '${adapter.name}' resolved InputNode`,
|
|
1972
|
+
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
1973
|
+
` • Operations: ${driver.inputNode.operations.length}`
|
|
1884
1974
|
]
|
|
1885
1975
|
});
|
|
1886
1976
|
return {
|
|
1887
1977
|
config,
|
|
1888
1978
|
events,
|
|
1889
|
-
fabric,
|
|
1890
1979
|
driver,
|
|
1891
|
-
sources
|
|
1980
|
+
sources,
|
|
1981
|
+
storage
|
|
1892
1982
|
};
|
|
1893
1983
|
}
|
|
1894
1984
|
/**
|
|
@@ -1898,7 +1988,7 @@ async function setup(options) {
|
|
|
1898
1988
|
* Pass an existing {@link SetupResult} via `overrides` to skip the setup phase.
|
|
1899
1989
|
*/
|
|
1900
1990
|
async function build(options, overrides) {
|
|
1901
|
-
const {
|
|
1991
|
+
const { files, driver, failedPlugins, pluginTimings, error, sources } = await safeBuild(options, overrides);
|
|
1902
1992
|
if (error) throw error;
|
|
1903
1993
|
if (failedPlugins.size > 0) {
|
|
1904
1994
|
const errors = [...failedPlugins].map(({ error }) => error);
|
|
@@ -1906,7 +1996,6 @@ async function build(options, overrides) {
|
|
|
1906
1996
|
}
|
|
1907
1997
|
return {
|
|
1908
1998
|
failedPlugins,
|
|
1909
|
-
fabric,
|
|
1910
1999
|
files,
|
|
1911
2000
|
driver,
|
|
1912
2001
|
pluginTimings,
|
|
@@ -1921,15 +2010,15 @@ async function build(options, overrides) {
|
|
|
1921
2010
|
* - Each hook accepts a single handler **or an array** — all entries are called in sequence.
|
|
1922
2011
|
* - Nodes that are excluded by `exclude`/`include` plugin options are skipped automatically.
|
|
1923
2012
|
* - Return values are handled via `applyHookResult`: React elements are rendered,
|
|
1924
|
-
* `
|
|
2013
|
+
* `FileNode[]` are written via upsert, and `void` is a no-op (manual handling).
|
|
1925
2014
|
* - Barrel files are generated automatically when `output.barrelType` is set.
|
|
1926
2015
|
*/
|
|
1927
2016
|
async function runPluginAstHooks(plugin, context) {
|
|
1928
|
-
const { adapter,
|
|
2017
|
+
const { adapter, inputNode, resolver, driver } = context;
|
|
1929
2018
|
const { exclude, include, override } = plugin.options;
|
|
1930
|
-
if (!adapter || !
|
|
2019
|
+
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.`);
|
|
1931
2020
|
const collectedOperations = [];
|
|
1932
|
-
await walk(
|
|
2021
|
+
await walk(inputNode, {
|
|
1933
2022
|
depth: "shallow",
|
|
1934
2023
|
async schema(node) {
|
|
1935
2024
|
if (!plugin.schema) return;
|
|
@@ -1941,7 +2030,7 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1941
2030
|
override
|
|
1942
2031
|
});
|
|
1943
2032
|
if (options === null) return;
|
|
1944
|
-
await applyHookResult(await plugin.schema.call(context, transformedNode, options),
|
|
2033
|
+
await applyHookResult(await plugin.schema.call(context, transformedNode, options), driver);
|
|
1945
2034
|
},
|
|
1946
2035
|
async operation(node) {
|
|
1947
2036
|
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
@@ -1953,24 +2042,24 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1953
2042
|
});
|
|
1954
2043
|
if (options !== null) {
|
|
1955
2044
|
collectedOperations.push(transformedNode);
|
|
1956
|
-
if (plugin.operation) await applyHookResult(await plugin.operation.call(context, transformedNode, options),
|
|
2045
|
+
if (plugin.operation) await applyHookResult(await plugin.operation.call(context, transformedNode, options), driver);
|
|
1957
2046
|
}
|
|
1958
2047
|
}
|
|
1959
2048
|
});
|
|
1960
|
-
if (plugin.operations && collectedOperations.length > 0) await applyHookResult(await plugin.operations.call(context, collectedOperations, plugin.options),
|
|
2049
|
+
if (plugin.operations && collectedOperations.length > 0) await applyHookResult(await plugin.operations.call(context, collectedOperations, plugin.options), driver);
|
|
1961
2050
|
}
|
|
1962
2051
|
/**
|
|
1963
2052
|
* Runs a full Kubb build and captures errors instead of throwing.
|
|
1964
2053
|
*
|
|
1965
2054
|
* - Installs each plugin in order, recording failures in `failedPlugins`.
|
|
1966
2055
|
* - Generates the root barrel file when `output.barrelType` is set.
|
|
1967
|
-
* - Writes all files through
|
|
2056
|
+
* - Writes all files through the driver's FileManager and FileProcessor.
|
|
1968
2057
|
*
|
|
1969
2058
|
* Returns a {@link BuildOutput} even on failure — inspect `error` and
|
|
1970
2059
|
* `failedPlugins` to determine whether the build succeeded.
|
|
1971
2060
|
*/
|
|
1972
2061
|
async function safeBuild(options, overrides) {
|
|
1973
|
-
const {
|
|
2062
|
+
const { driver, events, sources, storage } = overrides ? overrides : await setup(options);
|
|
1974
2063
|
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1975
2064
|
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1976
2065
|
const config = driver.config;
|
|
@@ -1990,7 +2079,7 @@ async function safeBuild(options, overrides) {
|
|
|
1990
2079
|
await plugin.buildStart.call(context);
|
|
1991
2080
|
if (plugin.schema || plugin.operation || plugin.operations) await runPluginAstHooks(plugin, context);
|
|
1992
2081
|
if (output) {
|
|
1993
|
-
const barrelFiles = await getBarrelFiles(
|
|
2082
|
+
const barrelFiles = await getBarrelFiles(driver.fileManager.files, {
|
|
1994
2083
|
type: output.barrelType ?? "named",
|
|
1995
2084
|
root,
|
|
1996
2085
|
output,
|
|
@@ -2044,15 +2133,15 @@ async function safeBuild(options, overrides) {
|
|
|
2044
2133
|
` • Path: ${rootPath}`
|
|
2045
2134
|
]
|
|
2046
2135
|
});
|
|
2047
|
-
const barrelFiles =
|
|
2136
|
+
const barrelFiles = driver.fileManager.files.filter((file) => {
|
|
2048
2137
|
return file.sources.some((source) => source.isIndexable);
|
|
2049
2138
|
});
|
|
2050
2139
|
await events.emit("debug", {
|
|
2051
2140
|
date: /* @__PURE__ */ new Date(),
|
|
2052
2141
|
logs: [`Found ${barrelFiles.length} indexable files for barrel export`]
|
|
2053
2142
|
});
|
|
2054
|
-
const existingBarrel =
|
|
2055
|
-
const rootFile = {
|
|
2143
|
+
const existingBarrel = driver.fileManager.files.find((f) => f.path === rootPath);
|
|
2144
|
+
const rootFile = createFile({
|
|
2056
2145
|
path: rootPath,
|
|
2057
2146
|
baseName: BARREL_FILENAME,
|
|
2058
2147
|
exports: buildBarrelExports({
|
|
@@ -2061,26 +2150,59 @@ async function safeBuild(options, overrides) {
|
|
|
2061
2150
|
existingExports: new Set(existingBarrel?.exports?.flatMap((e) => Array.isArray(e.name) ? e.name : [e.name]).filter((n) => Boolean(n)) ?? []),
|
|
2062
2151
|
config,
|
|
2063
2152
|
driver
|
|
2064
|
-
}),
|
|
2153
|
+
}).map((e) => createExport(e)),
|
|
2065
2154
|
sources: [],
|
|
2066
2155
|
imports: [],
|
|
2067
2156
|
meta: {}
|
|
2068
|
-
};
|
|
2069
|
-
|
|
2157
|
+
});
|
|
2158
|
+
driver.fileManager.upsert(rootFile);
|
|
2070
2159
|
await events.emit("debug", {
|
|
2071
2160
|
date: /* @__PURE__ */ new Date(),
|
|
2072
2161
|
logs: [`✓ Generated barrel file (${rootFile.exports?.length || 0} exports)`]
|
|
2073
2162
|
});
|
|
2074
2163
|
}
|
|
2075
|
-
const files =
|
|
2076
|
-
|
|
2164
|
+
const files = driver.fileManager.files;
|
|
2165
|
+
const parsersMap = /* @__PURE__ */ new Map();
|
|
2166
|
+
for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
|
|
2167
|
+
const fileProcessor = new FileProcessor();
|
|
2168
|
+
await events.emit("debug", {
|
|
2169
|
+
date: /* @__PURE__ */ new Date(),
|
|
2170
|
+
logs: [`Writing ${files.length} files...`]
|
|
2171
|
+
});
|
|
2172
|
+
await fileProcessor.run(files, {
|
|
2173
|
+
parsers: parsersMap,
|
|
2174
|
+
extension: config.output.extension,
|
|
2175
|
+
onStart: async (processingFiles) => {
|
|
2176
|
+
await events.emit("files:processing:start", processingFiles);
|
|
2177
|
+
},
|
|
2178
|
+
onUpdate: async ({ file, source, processed, total, percentage }) => {
|
|
2179
|
+
await events.emit("file:processing:update", {
|
|
2180
|
+
file,
|
|
2181
|
+
source,
|
|
2182
|
+
processed,
|
|
2183
|
+
total,
|
|
2184
|
+
percentage,
|
|
2185
|
+
config
|
|
2186
|
+
});
|
|
2187
|
+
if (source) {
|
|
2188
|
+
await storage?.setItem(file.path, source);
|
|
2189
|
+
sources.set(file.path, source);
|
|
2190
|
+
}
|
|
2191
|
+
},
|
|
2192
|
+
onEnd: async (processedFiles) => {
|
|
2193
|
+
await events.emit("files:processing:end", processedFiles);
|
|
2194
|
+
await events.emit("debug", {
|
|
2195
|
+
date: /* @__PURE__ */ new Date(),
|
|
2196
|
+
logs: [`✓ File write process completed for ${processedFiles.length} files`]
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
});
|
|
2077
2200
|
for (const plugin of driver.plugins.values()) if (plugin.buildEnd) {
|
|
2078
2201
|
const context = driver.getContext(plugin);
|
|
2079
2202
|
await plugin.buildEnd.call(context);
|
|
2080
2203
|
}
|
|
2081
2204
|
return {
|
|
2082
2205
|
failedPlugins,
|
|
2083
|
-
fabric,
|
|
2084
2206
|
files,
|
|
2085
2207
|
driver,
|
|
2086
2208
|
pluginTimings,
|
|
@@ -2089,7 +2211,6 @@ async function safeBuild(options, overrides) {
|
|
|
2089
2211
|
} catch (error) {
|
|
2090
2212
|
return {
|
|
2091
2213
|
failedPlugins,
|
|
2092
|
-
fabric,
|
|
2093
2214
|
files: [],
|
|
2094
2215
|
driver,
|
|
2095
2216
|
pluginTimings,
|
|
@@ -2110,11 +2231,11 @@ function buildBarrelExports({ barrelFiles, rootDir, existingExports, config, dri
|
|
|
2110
2231
|
if (!pluginOptions || pluginOptions.output?.barrelType === false) return [];
|
|
2111
2232
|
const exportName = config.output.barrelType === "all" ? void 0 : source.name ? [source.name] : void 0;
|
|
2112
2233
|
if (exportName?.some((n) => existingExports.has(n))) return [];
|
|
2113
|
-
return [{
|
|
2234
|
+
return [createExport({
|
|
2114
2235
|
name: exportName,
|
|
2115
2236
|
path: getRelativePath(rootDir, file.path),
|
|
2116
2237
|
isTypeOnly: config.output.barrelType === "all" ? containsOnlyTypes : source.isTypeOnly
|
|
2117
|
-
}];
|
|
2238
|
+
})];
|
|
2118
2239
|
});
|
|
2119
2240
|
});
|
|
2120
2241
|
}
|
|
@@ -2226,19 +2347,19 @@ function mergeGenerators(generators) {
|
|
|
2226
2347
|
async schema(node, options) {
|
|
2227
2348
|
for (const gen of generators) {
|
|
2228
2349
|
if (!gen.schema) continue;
|
|
2229
|
-
await applyHookResult(await gen.schema.call(this, node, options), this.
|
|
2350
|
+
await applyHookResult(await gen.schema.call(this, node, options), this.driver);
|
|
2230
2351
|
}
|
|
2231
2352
|
},
|
|
2232
2353
|
async operation(node, options) {
|
|
2233
2354
|
for (const gen of generators) {
|
|
2234
2355
|
if (!gen.operation) continue;
|
|
2235
|
-
await applyHookResult(await gen.operation.call(this, node, options), this.
|
|
2356
|
+
await applyHookResult(await gen.operation.call(this, node, options), this.driver);
|
|
2236
2357
|
}
|
|
2237
2358
|
},
|
|
2238
2359
|
async operations(nodes, options) {
|
|
2239
2360
|
for (const gen of generators) {
|
|
2240
2361
|
if (!gen.operations) continue;
|
|
2241
|
-
await applyHookResult(await gen.operations.call(this, nodes, options), this.
|
|
2362
|
+
await applyHookResult(await gen.operations.call(this, nodes, options), this.driver);
|
|
2242
2363
|
}
|
|
2243
2364
|
}
|
|
2244
2365
|
};
|
|
@@ -2261,6 +2382,31 @@ function defineLogger(logger) {
|
|
|
2261
2382
|
return logger;
|
|
2262
2383
|
}
|
|
2263
2384
|
//#endregion
|
|
2385
|
+
//#region src/defineParser.ts
|
|
2386
|
+
/**
|
|
2387
|
+
* Defines a parser with type safety.
|
|
2388
|
+
*
|
|
2389
|
+
* Use this function to create parsers that transform generated files to strings
|
|
2390
|
+
* based on their extension.
|
|
2391
|
+
*
|
|
2392
|
+
* @example
|
|
2393
|
+
* ```ts
|
|
2394
|
+
* import { defineParser } from '@kubb/core'
|
|
2395
|
+
*
|
|
2396
|
+
* export const jsonParser = defineParser({
|
|
2397
|
+
* name: 'json',
|
|
2398
|
+
* extNames: ['.json'],
|
|
2399
|
+
* parse(file) {
|
|
2400
|
+
* const { extractStringsFromNodes } = await import('@kubb/ast')
|
|
2401
|
+
* return file.sources.map((s) => extractStringsFromNodes(s.nodes ?? [])).join('\n')
|
|
2402
|
+
* },
|
|
2403
|
+
* })
|
|
2404
|
+
* ```
|
|
2405
|
+
*/
|
|
2406
|
+
function defineParser(parser) {
|
|
2407
|
+
return parser;
|
|
2408
|
+
}
|
|
2409
|
+
//#endregion
|
|
2264
2410
|
//#region src/definePresets.ts
|
|
2265
2411
|
/**
|
|
2266
2412
|
* Creates a typed presets registry object — a named collection of {@link Preset} entries.
|
|
@@ -2414,7 +2560,7 @@ function defaultResolvePath({ baseName, pathMode, tag, path: groupPath }, { root
|
|
|
2414
2560
|
/**
|
|
2415
2561
|
* Default file resolver used by `defineResolver`.
|
|
2416
2562
|
*
|
|
2417
|
-
* Resolves a `
|
|
2563
|
+
* Resolves a `FileNode` by combining name resolution (`resolver.default`) with
|
|
2418
2564
|
* path resolution (`resolver.resolvePath`). The resolved file always has empty
|
|
2419
2565
|
* `sources`, `imports`, and `exports` arrays — consumers populate those separately.
|
|
2420
2566
|
*
|
|
@@ -2447,14 +2593,14 @@ function defaultResolveFile({ name, extname, tag, path: groupPath }, context) {
|
|
|
2447
2593
|
tag,
|
|
2448
2594
|
path: groupPath
|
|
2449
2595
|
}, context);
|
|
2450
|
-
return {
|
|
2596
|
+
return createFile({
|
|
2451
2597
|
path: filePath,
|
|
2452
2598
|
baseName: path.basename(filePath),
|
|
2453
2599
|
meta: { pluginName: this.pluginName },
|
|
2454
2600
|
sources: [],
|
|
2455
2601
|
imports: [],
|
|
2456
2602
|
exports: []
|
|
2457
|
-
};
|
|
2603
|
+
});
|
|
2458
2604
|
}
|
|
2459
2605
|
/**
|
|
2460
2606
|
* Generates the default "Generated by Kubb" banner from config and optional node metadata.
|
|
@@ -2506,13 +2652,13 @@ function buildDefaultBanner({ title, description, version, config }) {
|
|
|
2506
2652
|
*
|
|
2507
2653
|
* @example Function banner with node
|
|
2508
2654
|
* ```ts
|
|
2509
|
-
* defaultResolveBanner(
|
|
2655
|
+
* defaultResolveBanner(inputNode, { output: { banner: (node) => `// v${node.version}` }, config })
|
|
2510
2656
|
* // → '// v3.0.0'
|
|
2511
2657
|
* ```
|
|
2512
2658
|
*
|
|
2513
2659
|
* @example No user banner — Kubb notice with OAS metadata
|
|
2514
2660
|
* ```ts
|
|
2515
|
-
* defaultResolveBanner(
|
|
2661
|
+
* defaultResolveBanner(inputNode, { config })
|
|
2516
2662
|
* // → '/** Generated by Kubb ... Title: Pet Store ... *\/'
|
|
2517
2663
|
* ```
|
|
2518
2664
|
*
|
|
@@ -2548,7 +2694,7 @@ function defaultResolveBanner(node, { output, config }) {
|
|
|
2548
2694
|
*
|
|
2549
2695
|
* @example Function footer with node
|
|
2550
2696
|
* ```ts
|
|
2551
|
-
* defaultResolveFooter(
|
|
2697
|
+
* defaultResolveFooter(inputNode, { output: { footer: (node) => `// ${node.title}` }, config })
|
|
2552
2698
|
* // → '// Pet Store'
|
|
2553
2699
|
* ```
|
|
2554
2700
|
*/
|
|
@@ -2564,7 +2710,7 @@ function defaultResolveFooter(node, { output }) {
|
|
|
2564
2710
|
* - `default` — name casing strategy (camelCase / PascalCase)
|
|
2565
2711
|
* - `resolveOptions` — include/exclude/override filtering
|
|
2566
2712
|
* - `resolvePath` — output path computation
|
|
2567
|
-
* - `resolveFile` — full `
|
|
2713
|
+
* - `resolveFile` — full `FileNode` construction
|
|
2568
2714
|
*
|
|
2569
2715
|
* Methods in the builder have access to `this` (the full resolver object), so they
|
|
2570
2716
|
* can call other resolver methods without circular imports.
|
|
@@ -2614,9 +2760,6 @@ function defineResolver(build) {
|
|
|
2614
2760
|
};
|
|
2615
2761
|
}
|
|
2616
2762
|
//#endregion
|
|
2617
|
-
//#region src/KubbFile.ts
|
|
2618
|
-
var KubbFile_exports = /* @__PURE__ */ __exportAll({});
|
|
2619
|
-
//#endregion
|
|
2620
2763
|
//#region src/storages/memoryStorage.ts
|
|
2621
2764
|
/**
|
|
2622
2765
|
* In-memory storage driver. Useful for testing and dry-run scenarios where
|
|
@@ -2665,82 +2808,6 @@ const memoryStorage = createStorage(() => {
|
|
|
2665
2808
|
};
|
|
2666
2809
|
});
|
|
2667
2810
|
//#endregion
|
|
2668
|
-
//#region src/utils/FunctionParams.ts
|
|
2669
|
-
/**
|
|
2670
|
-
* @deprecated use ast package instead
|
|
2671
|
-
*/
|
|
2672
|
-
var FunctionParams = class FunctionParams {
|
|
2673
|
-
#items = [];
|
|
2674
|
-
get items() {
|
|
2675
|
-
return this.#items.flat();
|
|
2676
|
-
}
|
|
2677
|
-
add(item) {
|
|
2678
|
-
if (!item) return this;
|
|
2679
|
-
if (Array.isArray(item)) {
|
|
2680
|
-
item.filter((x) => x !== void 0).forEach((it) => {
|
|
2681
|
-
this.#items.push(it);
|
|
2682
|
-
});
|
|
2683
|
-
return this;
|
|
2684
|
-
}
|
|
2685
|
-
this.#items.push(item);
|
|
2686
|
-
return this;
|
|
2687
|
-
}
|
|
2688
|
-
static #orderItems(items) {
|
|
2689
|
-
return sortBy(items.filter(Boolean), [(item) => Array.isArray(item), "desc"], [(item) => !Array.isArray(item) && item.default !== void 0, "asc"], [(item) => Array.isArray(item) || (item.required ?? true), "desc"]);
|
|
2690
|
-
}
|
|
2691
|
-
static #addParams(acc, item) {
|
|
2692
|
-
const { enabled = true, name, type, required = true, ...rest } = item;
|
|
2693
|
-
if (!enabled) return acc;
|
|
2694
|
-
if (!name) {
|
|
2695
|
-
acc.push(`${type}${rest.default ? ` = ${rest.default}` : ""}`);
|
|
2696
|
-
return acc;
|
|
2697
|
-
}
|
|
2698
|
-
const parameterName = name.startsWith("{") ? name : camelCase(name);
|
|
2699
|
-
if (type) if (required) acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ""}`);
|
|
2700
|
-
else acc.push(`${parameterName}?: ${type}`);
|
|
2701
|
-
else acc.push(`${parameterName}`);
|
|
2702
|
-
return acc;
|
|
2703
|
-
}
|
|
2704
|
-
static toObject(items) {
|
|
2705
|
-
let type = [];
|
|
2706
|
-
let name = [];
|
|
2707
|
-
const enabled = items.every((item) => item.enabled) ? items.at(0)?.enabled : true;
|
|
2708
|
-
const required = items.every((item) => item.required) ?? true;
|
|
2709
|
-
items.forEach((item) => {
|
|
2710
|
-
name = FunctionParams.#addParams(name, {
|
|
2711
|
-
...item,
|
|
2712
|
-
type: void 0
|
|
2713
|
-
});
|
|
2714
|
-
if (items.some((item) => item.type)) type = FunctionParams.#addParams(type, item);
|
|
2715
|
-
});
|
|
2716
|
-
return {
|
|
2717
|
-
name: `{ ${name.join(", ")} }`,
|
|
2718
|
-
type: type.length ? `{ ${type.join("; ")} }` : void 0,
|
|
2719
|
-
enabled,
|
|
2720
|
-
required
|
|
2721
|
-
};
|
|
2722
|
-
}
|
|
2723
|
-
toObject() {
|
|
2724
|
-
const items = FunctionParams.#orderItems(this.#items).flat();
|
|
2725
|
-
return FunctionParams.toObject(items);
|
|
2726
|
-
}
|
|
2727
|
-
static toString(items) {
|
|
2728
|
-
return FunctionParams.#orderItems(items).reduce((acc, item) => {
|
|
2729
|
-
if (Array.isArray(item)) {
|
|
2730
|
-
if (item.length <= 0) return acc;
|
|
2731
|
-
const subItems = FunctionParams.#orderItems(item);
|
|
2732
|
-
const objectItem = FunctionParams.toObject(subItems);
|
|
2733
|
-
return FunctionParams.#addParams(acc, objectItem);
|
|
2734
|
-
}
|
|
2735
|
-
return FunctionParams.#addParams(acc, item);
|
|
2736
|
-
}, []).join(", ");
|
|
2737
|
-
}
|
|
2738
|
-
toString() {
|
|
2739
|
-
const items = FunctionParams.#orderItems(this.#items);
|
|
2740
|
-
return FunctionParams.toString(items);
|
|
2741
|
-
}
|
|
2742
|
-
};
|
|
2743
|
-
//#endregion
|
|
2744
2811
|
//#region src/utils/formatters.ts
|
|
2745
2812
|
/**
|
|
2746
2813
|
* Returns `true` when the given formatter is installed and callable.
|
|
@@ -2796,6 +2863,124 @@ async function getConfigs(config, args) {
|
|
|
2796
2863
|
}));
|
|
2797
2864
|
}
|
|
2798
2865
|
//#endregion
|
|
2866
|
+
//#region src/utils/getFunctionParams.ts
|
|
2867
|
+
function order(items) {
|
|
2868
|
+
return sortBy(items.filter(Boolean), ([_key, item]) => {
|
|
2869
|
+
if (item?.children) return 0;
|
|
2870
|
+
if (item?.optional) return 1;
|
|
2871
|
+
if (item?.default) return 2;
|
|
2872
|
+
return 0;
|
|
2873
|
+
});
|
|
2874
|
+
}
|
|
2875
|
+
function parseChild(key, item, options) {
|
|
2876
|
+
const entries = order(Object.entries(item.children));
|
|
2877
|
+
const types = [];
|
|
2878
|
+
const names = [];
|
|
2879
|
+
const optional = entries.every(([_key, item]) => item?.optional || !!item?.default);
|
|
2880
|
+
entries.forEach(([key, entryItem]) => {
|
|
2881
|
+
if (entryItem) {
|
|
2882
|
+
const name = parseItem(key, {
|
|
2883
|
+
...entryItem,
|
|
2884
|
+
type: void 0
|
|
2885
|
+
}, options);
|
|
2886
|
+
if (entryItem.children) {
|
|
2887
|
+
const subTypes = Object.entries(entryItem.children).map(([key]) => {
|
|
2888
|
+
return key;
|
|
2889
|
+
}).join(", ");
|
|
2890
|
+
if (subTypes) names.push(`${name}: { ${subTypes} }`);
|
|
2891
|
+
else names.push(name);
|
|
2892
|
+
} else if (options.type === "call" && options.transformName) names.push(`${key}: ${name}`);
|
|
2893
|
+
else names.push(name);
|
|
2894
|
+
if (entries.some(([_key, item]) => item?.type)) types.push(parseItem(key, {
|
|
2895
|
+
...entryItem,
|
|
2896
|
+
default: void 0
|
|
2897
|
+
}, options));
|
|
2898
|
+
}
|
|
2899
|
+
});
|
|
2900
|
+
const name = item.mode === "inline" ? key : names.length ? `{ ${names.join(", ")} }` : void 0;
|
|
2901
|
+
const type = item.type ? item.type : types.length ? `{ ${types.join("; ")} }` : void 0;
|
|
2902
|
+
if (!name) return null;
|
|
2903
|
+
return parseItem(name, {
|
|
2904
|
+
type,
|
|
2905
|
+
default: item.default,
|
|
2906
|
+
optional: !item.default ? optional : void 0
|
|
2907
|
+
}, options);
|
|
2908
|
+
}
|
|
2909
|
+
function parseItem(name, item, options) {
|
|
2910
|
+
const acc = [];
|
|
2911
|
+
const transformedName = options.transformName ? options.transformName(name) : name;
|
|
2912
|
+
const transformedType = options.transformType && item.type ? options.transformType(item.type) : item.type;
|
|
2913
|
+
if (options.type === "object") return transformedName;
|
|
2914
|
+
if (options.type === "objectValue") return item.value ? `${transformedName}: ${item.value}` : transformedName;
|
|
2915
|
+
if (item.type && options.type === "constructor") if (item.optional) if (transformedName.startsWith("{")) acc.push(`${transformedName}: ${transformedType} = {}`);
|
|
2916
|
+
else acc.push(`${transformedName}?: ${transformedType}`);
|
|
2917
|
+
else acc.push(`${transformedName}: ${transformedType}${item.default ? ` = ${item.default}` : ""}`);
|
|
2918
|
+
else if (item.default && options.type === "constructor") acc.push(`${transformedName} = ${item.default}`);
|
|
2919
|
+
else if (item.value) acc.push(`${transformedName} : ${item.value}`);
|
|
2920
|
+
else if (item.mode === "inlineSpread") acc.push(`... ${transformedName}`);
|
|
2921
|
+
else acc.push(transformedName);
|
|
2922
|
+
return acc[0];
|
|
2923
|
+
}
|
|
2924
|
+
function getFunctionParams(params, options) {
|
|
2925
|
+
return order(Object.entries(params)).reduce((acc, [key, item]) => {
|
|
2926
|
+
if (!item) return acc;
|
|
2927
|
+
if (item.children) {
|
|
2928
|
+
if (Object.keys(item.children).length === 0) return acc;
|
|
2929
|
+
if (item.mode === "inlineSpread") return [...acc, getFunctionParams(item.children, options)];
|
|
2930
|
+
const parsedItem = parseChild(key, item, options);
|
|
2931
|
+
if (!parsedItem) return acc;
|
|
2932
|
+
return [...acc, parsedItem];
|
|
2933
|
+
}
|
|
2934
|
+
const parsedItem = parseItem(key, item, options);
|
|
2935
|
+
return [...acc, parsedItem];
|
|
2936
|
+
}, []).join(", ");
|
|
2937
|
+
}
|
|
2938
|
+
/**
|
|
2939
|
+
* @deprecated use @kubb/ast
|
|
2940
|
+
*/
|
|
2941
|
+
function createFunctionParams(params) {
|
|
2942
|
+
return params;
|
|
2943
|
+
}
|
|
2944
|
+
/**
|
|
2945
|
+
* @deprecated use @kubb/ast
|
|
2946
|
+
*/
|
|
2947
|
+
var FunctionParams = class FunctionParams {
|
|
2948
|
+
#params;
|
|
2949
|
+
static factory(params) {
|
|
2950
|
+
return new FunctionParams(params);
|
|
2951
|
+
}
|
|
2952
|
+
constructor(params) {
|
|
2953
|
+
this.#params = params;
|
|
2954
|
+
}
|
|
2955
|
+
get params() {
|
|
2956
|
+
return this.#params;
|
|
2957
|
+
}
|
|
2958
|
+
get flatParams() {
|
|
2959
|
+
const flatter = (acc, [key, item]) => {
|
|
2960
|
+
if (item?.children) return Object.entries(item.children).reduce(flatter, acc);
|
|
2961
|
+
if (item) acc[key] = item;
|
|
2962
|
+
return acc;
|
|
2963
|
+
};
|
|
2964
|
+
return Object.entries(this.#params).reduce(flatter, {});
|
|
2965
|
+
}
|
|
2966
|
+
toCall({ transformName, transformType } = {}) {
|
|
2967
|
+
return getFunctionParams(this.#params, {
|
|
2968
|
+
type: "call",
|
|
2969
|
+
transformName,
|
|
2970
|
+
transformType
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
toObject() {
|
|
2974
|
+
return getFunctionParams(this.#params, { type: "object" });
|
|
2975
|
+
}
|
|
2976
|
+
toObjectValue() {
|
|
2977
|
+
return getFunctionParams(this.#params, { type: "objectValue" });
|
|
2978
|
+
}
|
|
2979
|
+
toConstructor() {
|
|
2980
|
+
return getFunctionParams(this.#params, { type: "constructor" });
|
|
2981
|
+
}
|
|
2982
|
+
};
|
|
2983
|
+
//#endregion
|
|
2799
2984
|
//#region src/utils/getPreset.ts
|
|
2800
2985
|
/**
|
|
2801
2986
|
* Returns a copy of `defaults` where each function in `userOverrides` is wrapped
|
|
@@ -2919,6 +3104,6 @@ function satisfiesDependency(dependency, version, cwd) {
|
|
|
2919
3104
|
return satisfies(semVer, version);
|
|
2920
3105
|
}
|
|
2921
3106
|
//#endregion
|
|
2922
|
-
export { AsyncEventEmitter, FunctionParams,
|
|
3107
|
+
export { AsyncEventEmitter, FunctionParams, PluginDriver, URLPath, build, build as default, buildDefaultBanner, composeTransformers, createAdapter, createFunctionParams, createPlugin, createStorage, defaultResolveBanner, defaultResolveFile, defaultResolveFooter, defaultResolveOptions, defaultResolvePath, defineConfig, defineGenerator, defineLogger, defineParser, definePresets, definePrinter, defineResolver, detectFormatter, detectLinter, formatters, fsStorage, getBarrelFiles, getConfigs, getFunctionParams, getMode, getPreset, isInputPath, linters, logLevel, memoryStorage, mergeGenerators, safeBuild, satisfiesDependency, setup };
|
|
2923
3108
|
|
|
2924
3109
|
//# sourceMappingURL=index.js.map
|