@kubb/core 5.0.0-alpha.4 → 5.0.0-alpha.40
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-BQwm8hDd.cjs +1729 -0
- package/dist/PluginDriver-BQwm8hDd.cjs.map +1 -0
- package/dist/PluginDriver-CgXFtmNP.js +1617 -0
- package/dist/PluginDriver-CgXFtmNP.js.map +1 -0
- package/dist/index.cjs +918 -1898
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +267 -264
- package/dist/index.js +897 -1860
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +164 -0
- package/dist/mocks.cjs.map +1 -0
- package/dist/mocks.d.ts +74 -0
- package/dist/mocks.js +159 -0
- package/dist/mocks.js.map +1 -0
- package/dist/types-PLXOrxov.d.ts +2151 -0
- package/package.json +11 -14
- package/src/FileManager.ts +131 -0
- package/src/FileProcessor.ts +84 -0
- package/src/Kubb.ts +174 -85
- package/src/PluginDriver.ts +941 -0
- package/src/constants.ts +33 -43
- package/src/createAdapter.ts +25 -0
- package/src/createKubb.ts +607 -0
- package/src/createPlugin.ts +31 -0
- package/src/createRenderer.ts +57 -0
- package/src/createStorage.ts +58 -0
- package/src/defineGenerator.ts +88 -100
- package/src/defineLogger.ts +13 -3
- package/src/defineParser.ts +45 -0
- package/src/definePlugin.ts +90 -7
- package/src/defineResolver.ts +453 -0
- package/src/devtools.ts +14 -14
- package/src/index.ts +12 -17
- package/src/mocks.ts +234 -0
- package/src/renderNode.ts +35 -0
- package/src/storages/fsStorage.ts +29 -9
- package/src/storages/memoryStorage.ts +2 -2
- package/src/types.ts +821 -152
- package/src/utils/TreeNode.ts +47 -9
- package/src/utils/diagnostics.ts +4 -1
- package/src/utils/executeStrategies.ts +16 -13
- package/src/utils/getBarrelFiles.ts +88 -15
- package/src/utils/isInputPath.ts +8 -0
- package/src/utils/packageJSON.ts +75 -0
- package/dist/chunk-ByKO4r7w.cjs +0 -38
- package/dist/hooks.cjs +0 -50
- package/dist/hooks.cjs.map +0 -1
- package/dist/hooks.d.ts +0 -49
- package/dist/hooks.js +0 -46
- package/dist/hooks.js.map +0 -1
- package/dist/types-Bbh1o0yW.d.ts +0 -1057
- package/src/BarrelManager.ts +0 -74
- package/src/PackageManager.ts +0 -180
- package/src/PluginManager.ts +0 -668
- package/src/PromiseManager.ts +0 -40
- package/src/build.ts +0 -420
- package/src/config.ts +0 -56
- package/src/defineAdapter.ts +0 -22
- package/src/defineStorage.ts +0 -56
- package/src/errors.ts +0 -1
- package/src/hooks/index.ts +0 -8
- package/src/hooks/useKubb.ts +0 -22
- package/src/hooks/useMode.ts +0 -11
- package/src/hooks/usePlugin.ts +0 -11
- package/src/hooks/usePluginManager.ts +0 -11
- package/src/utils/FunctionParams.ts +0 -155
- package/src/utils/formatters.ts +0 -56
- package/src/utils/getConfigs.ts +0 -30
- package/src/utils/getPlugins.ts +0 -23
- package/src/utils/linters.ts +0 -25
- package/src/utils/resolveOptions.ts +0 -93
package/dist/index.cjs
CHANGED
|
@@ -1,37 +1,21 @@
|
|
|
1
|
-
Object.
|
|
2
|
-
|
|
3
|
-
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
-
});
|
|
5
|
-
const require_chunk = require("./chunk-ByKO4r7w.cjs");
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_PluginDriver = require("./PluginDriver-BQwm8hDd.cjs");
|
|
6
3
|
let node_events = require("node:events");
|
|
7
|
-
let node_util = require("node:util");
|
|
8
|
-
let node_fs = require("node:fs");
|
|
9
4
|
let node_fs_promises = require("node:fs/promises");
|
|
10
5
|
let node_path = require("node:path");
|
|
11
|
-
node_path =
|
|
6
|
+
node_path = require_PluginDriver.__toESM(node_path, 1);
|
|
12
7
|
let _kubb_ast = require("@kubb/ast");
|
|
13
|
-
|
|
14
|
-
let _kubb_react_fabric_parsers = require("@kubb/react-fabric/parsers");
|
|
15
|
-
let _kubb_react_fabric_plugins = require("@kubb/react-fabric/plugins");
|
|
16
|
-
let node_perf_hooks = require("node:perf_hooks");
|
|
17
|
-
let fflate = require("fflate");
|
|
18
|
-
let tinyexec = require("tinyexec");
|
|
8
|
+
_kubb_ast = require_PluginDriver.__toESM(_kubb_ast, 1);
|
|
19
9
|
let node_process = require("node:process");
|
|
20
|
-
|
|
21
|
-
node_module = require_chunk.__toESM(node_module);
|
|
22
|
-
let node_os = require("node:os");
|
|
23
|
-
node_os = require_chunk.__toESM(node_os);
|
|
24
|
-
let node_url = require("node:url");
|
|
25
|
-
let empathic_package = require("empathic/package");
|
|
26
|
-
empathic_package = require_chunk.__toESM(empathic_package);
|
|
27
|
-
let semver = require("semver");
|
|
28
|
-
let remeda = require("remeda");
|
|
29
|
-
//#region ../../internals/utils/dist/index.js
|
|
30
|
-
/** Thrown when a plugin's configuration or input fails validation. */
|
|
31
|
-
var ValidationPluginError = class extends Error {};
|
|
10
|
+
//#region ../../internals/utils/src/errors.ts
|
|
32
11
|
/**
|
|
33
12
|
* Thrown when one or more errors occur during a Kubb build.
|
|
34
13
|
* Carries the full list of underlying errors on `errors`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* throw new BuildError('Build failed', { errors: [err1, err2] })
|
|
18
|
+
* ```
|
|
35
19
|
*/
|
|
36
20
|
var BuildError = class extends Error {
|
|
37
21
|
errors;
|
|
@@ -43,19 +27,34 @@ var BuildError = class extends Error {
|
|
|
43
27
|
};
|
|
44
28
|
/**
|
|
45
29
|
* Coerces an unknown thrown value to an `Error` instance.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
30
|
+
* Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* try { ... } catch(err) {
|
|
35
|
+
* throw new BuildError('Build failed', { cause: toError(err), errors: [] })
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
48
38
|
*/
|
|
49
39
|
function toError(value) {
|
|
50
40
|
return value instanceof Error ? value : new Error(String(value));
|
|
51
41
|
}
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region ../../internals/utils/src/asyncEventEmitter.ts
|
|
52
44
|
/**
|
|
53
|
-
*
|
|
45
|
+
* Typed `EventEmitter` that awaits all async listeners before resolving.
|
|
54
46
|
* Wraps Node's `EventEmitter` with full TypeScript event-map inference.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const emitter = new AsyncEventEmitter<{ build: [name: string] }>()
|
|
51
|
+
* emitter.on('build', async (name) => { console.log(name) })
|
|
52
|
+
* await emitter.emit('build', 'petstore') // all listeners awaited
|
|
53
|
+
* ```
|
|
55
54
|
*/
|
|
56
55
|
var AsyncEventEmitter = class {
|
|
57
56
|
/**
|
|
58
|
-
*
|
|
57
|
+
* Maximum number of listeners per event before Node emits a memory-leak warning.
|
|
59
58
|
* @default 10
|
|
60
59
|
*/
|
|
61
60
|
constructor(maxListener = 10) {
|
|
@@ -63,31 +62,48 @@ var AsyncEventEmitter = class {
|
|
|
63
62
|
}
|
|
64
63
|
#emitter = new node_events.EventEmitter();
|
|
65
64
|
/**
|
|
66
|
-
* Emits
|
|
65
|
+
* Emits `eventName` and awaits all registered listeners sequentially.
|
|
67
66
|
* Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* await emitter.emit('build', 'petstore')
|
|
71
|
+
* ```
|
|
68
72
|
*/
|
|
69
73
|
async emit(eventName, ...eventArgs) {
|
|
70
74
|
const listeners = this.#emitter.listeners(eventName);
|
|
71
75
|
if (listeners.length === 0) return;
|
|
72
|
-
|
|
76
|
+
for (const listener of listeners) try {
|
|
77
|
+
await listener(...eventArgs);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
let serializedArgs;
|
|
73
80
|
try {
|
|
74
|
-
|
|
75
|
-
} catch
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
serializedArgs = JSON.stringify(eventArgs);
|
|
79
|
-
} catch {
|
|
80
|
-
serializedArgs = String(eventArgs);
|
|
81
|
-
}
|
|
82
|
-
throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
|
|
81
|
+
serializedArgs = JSON.stringify(eventArgs);
|
|
82
|
+
} catch {
|
|
83
|
+
serializedArgs = String(eventArgs);
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
+
throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
|
|
86
|
+
}
|
|
85
87
|
}
|
|
86
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Registers a persistent listener for `eventName`.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* emitter.on('build', async (name) => { console.log(name) })
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
87
96
|
on(eventName, handler) {
|
|
88
97
|
this.#emitter.on(eventName, handler);
|
|
89
98
|
}
|
|
90
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Registers a one-shot listener that removes itself after the first invocation.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* emitter.onOnce('build', async (name) => { console.log(name) })
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
91
107
|
onOnce(eventName, handler) {
|
|
92
108
|
const wrapper = (...args) => {
|
|
93
109
|
this.off(eventName, wrapper);
|
|
@@ -95,237 +111,53 @@ var AsyncEventEmitter = class {
|
|
|
95
111
|
};
|
|
96
112
|
this.on(eventName, wrapper);
|
|
97
113
|
}
|
|
98
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* Removes a previously registered listener.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* emitter.off('build', handler)
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
99
122
|
off(eventName, handler) {
|
|
100
123
|
this.#emitter.off(eventName, handler);
|
|
101
124
|
}
|
|
102
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* Returns the number of listeners registered for `eventName`.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* emitter.on('build', handler)
|
|
131
|
+
* emitter.listenerCount('build') // 1
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
listenerCount(eventName) {
|
|
135
|
+
return this.#emitter.listenerCount(eventName);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Removes all listeners from every event channel.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* emitter.removeAll()
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
103
145
|
removeAll() {
|
|
104
146
|
this.#emitter.removeAllListeners();
|
|
105
147
|
}
|
|
106
148
|
};
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region ../../internals/utils/src/time.ts
|
|
107
151
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* and capitalizes each word according to `pascal`.
|
|
111
|
-
*
|
|
112
|
-
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
113
|
-
*/
|
|
114
|
-
function toCamelOrPascal(text, pascal) {
|
|
115
|
-
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
116
|
-
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
117
|
-
if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1);
|
|
118
|
-
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
119
|
-
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Splits `text` on `.` and applies `transformPart` to each segment.
|
|
123
|
-
* The last segment receives `isLast = true`, all earlier segments receive `false`.
|
|
124
|
-
* Segments are joined with `/` to form a file path.
|
|
125
|
-
*/
|
|
126
|
-
function applyToFileParts(text, transformPart) {
|
|
127
|
-
const parts = text.split(".");
|
|
128
|
-
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Converts `text` to camelCase.
|
|
132
|
-
* When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
|
|
152
|
+
* Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.
|
|
153
|
+
* Rounds to 2 decimal places for sub-millisecond precision without noise.
|
|
133
154
|
*
|
|
134
155
|
* @example
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
prefix,
|
|
141
|
-
suffix
|
|
142
|
-
} : {}));
|
|
143
|
-
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
144
|
-
}
|
|
145
|
-
/** Returns a `CLIAdapter` with type inference. Pass a different adapter to `createCLI` to swap the CLI engine. */
|
|
146
|
-
function defineCLIAdapter(adapter) {
|
|
147
|
-
return adapter;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Serializes `CommandDefinition[]` to a plain, JSON-serializable structure.
|
|
151
|
-
* Use to expose CLI capabilities to AI agents or MCP tools.
|
|
152
|
-
*/
|
|
153
|
-
function getCommandSchema(defs) {
|
|
154
|
-
return defs.map(serializeCommand);
|
|
155
|
-
}
|
|
156
|
-
function serializeCommand(def) {
|
|
157
|
-
return {
|
|
158
|
-
name: def.name,
|
|
159
|
-
description: def.description,
|
|
160
|
-
arguments: def.arguments,
|
|
161
|
-
options: serializeOptions(def.options ?? {}),
|
|
162
|
-
subCommands: def.subCommands ? def.subCommands.map(serializeCommand) : []
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
function serializeOptions(options) {
|
|
166
|
-
return Object.entries(options).map(([name, opt]) => {
|
|
167
|
-
return {
|
|
168
|
-
name,
|
|
169
|
-
flags: `${opt.short ? `-${opt.short}, ` : ""}--${name}${opt.type === "string" ? ` <${opt.hint ?? name}>` : ""}`,
|
|
170
|
-
type: opt.type,
|
|
171
|
-
description: opt.description,
|
|
172
|
-
...opt.default !== void 0 ? { default: opt.default } : {},
|
|
173
|
-
...opt.hint ? { hint: opt.hint } : {},
|
|
174
|
-
...opt.enum ? { enum: opt.enum } : {},
|
|
175
|
-
...opt.required ? { required: opt.required } : {}
|
|
176
|
-
};
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
/** Prints formatted help output for a command using its `CommandDefinition`. */
|
|
180
|
-
function renderHelp(def, parentName) {
|
|
181
|
-
const schema = getCommandSchema([def])[0];
|
|
182
|
-
const programName = parentName ? `${parentName} ${schema.name}` : schema.name;
|
|
183
|
-
const argsPart = schema.arguments?.length ? ` ${schema.arguments.join(" ")}` : "";
|
|
184
|
-
const subCmdPart = schema.subCommands.length ? " <command>" : "";
|
|
185
|
-
console.log(`\n${(0, node_util.styleText)("bold", "Usage:")} ${programName}${argsPart}${subCmdPart} [options]\n`);
|
|
186
|
-
if (schema.description) console.log(` ${schema.description}\n`);
|
|
187
|
-
if (schema.subCommands.length) {
|
|
188
|
-
console.log((0, node_util.styleText)("bold", "Commands:"));
|
|
189
|
-
for (const sub of schema.subCommands) console.log(` ${(0, node_util.styleText)("cyan", sub.name.padEnd(16))}${sub.description}`);
|
|
190
|
-
console.log();
|
|
191
|
-
}
|
|
192
|
-
const options = [...schema.options, {
|
|
193
|
-
name: "help",
|
|
194
|
-
flags: "-h, --help",
|
|
195
|
-
type: "boolean",
|
|
196
|
-
description: "Show help"
|
|
197
|
-
}];
|
|
198
|
-
console.log((0, node_util.styleText)("bold", "Options:"));
|
|
199
|
-
for (const opt of options) {
|
|
200
|
-
const flags = (0, node_util.styleText)("cyan", opt.flags.padEnd(30));
|
|
201
|
-
const defaultPart = opt.default !== void 0 ? (0, node_util.styleText)("dim", ` (default: ${opt.default})`) : "";
|
|
202
|
-
console.log(` ${flags}${opt.description}${defaultPart}`);
|
|
203
|
-
}
|
|
204
|
-
console.log();
|
|
205
|
-
}
|
|
206
|
-
function buildParseOptions(def) {
|
|
207
|
-
const result = { help: {
|
|
208
|
-
type: "boolean",
|
|
209
|
-
short: "h"
|
|
210
|
-
} };
|
|
211
|
-
for (const [name, opt] of Object.entries(def.options ?? {})) result[name] = {
|
|
212
|
-
type: opt.type,
|
|
213
|
-
...opt.short ? { short: opt.short } : {},
|
|
214
|
-
...opt.default !== void 0 ? { default: opt.default } : {}
|
|
215
|
-
};
|
|
216
|
-
return result;
|
|
217
|
-
}
|
|
218
|
-
async function runCommand(def, argv, parentName) {
|
|
219
|
-
const parseOptions = buildParseOptions(def);
|
|
220
|
-
let parsed;
|
|
221
|
-
try {
|
|
222
|
-
const result = (0, node_util.parseArgs)({
|
|
223
|
-
args: argv,
|
|
224
|
-
options: parseOptions,
|
|
225
|
-
allowPositionals: true,
|
|
226
|
-
strict: false
|
|
227
|
-
});
|
|
228
|
-
parsed = {
|
|
229
|
-
values: result.values,
|
|
230
|
-
positionals: result.positionals
|
|
231
|
-
};
|
|
232
|
-
} catch {
|
|
233
|
-
renderHelp(def, parentName);
|
|
234
|
-
process.exit(1);
|
|
235
|
-
}
|
|
236
|
-
if (parsed.values["help"]) {
|
|
237
|
-
renderHelp(def, parentName);
|
|
238
|
-
process.exit(0);
|
|
239
|
-
}
|
|
240
|
-
for (const [name, opt] of Object.entries(def.options ?? {})) if (opt.required && parsed.values[name] === void 0) {
|
|
241
|
-
console.error((0, node_util.styleText)("red", `Error: --${name} is required`));
|
|
242
|
-
renderHelp(def, parentName);
|
|
243
|
-
process.exit(1);
|
|
244
|
-
}
|
|
245
|
-
if (!def.run) {
|
|
246
|
-
renderHelp(def, parentName);
|
|
247
|
-
process.exit(0);
|
|
248
|
-
}
|
|
249
|
-
try {
|
|
250
|
-
await def.run(parsed);
|
|
251
|
-
} catch (err) {
|
|
252
|
-
console.error((0, node_util.styleText)("red", `Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
253
|
-
renderHelp(def, parentName);
|
|
254
|
-
process.exit(1);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
function printRootHelp(programName, version, defs) {
|
|
258
|
-
console.log(`\n${(0, node_util.styleText)("bold", "Usage:")} ${programName} <command> [options]\n`);
|
|
259
|
-
console.log(` Kubb generation — v${version}\n`);
|
|
260
|
-
console.log((0, node_util.styleText)("bold", "Commands:"));
|
|
261
|
-
for (const def of defs) console.log(` ${(0, node_util.styleText)("cyan", def.name.padEnd(16))}${def.description}`);
|
|
262
|
-
console.log();
|
|
263
|
-
console.log((0, node_util.styleText)("bold", "Options:"));
|
|
264
|
-
console.log(` ${(0, node_util.styleText)("cyan", "-v, --version".padEnd(30))}Show version number`);
|
|
265
|
-
console.log(` ${(0, node_util.styleText)("cyan", "-h, --help".padEnd(30))}Show help`);
|
|
266
|
-
console.log();
|
|
267
|
-
console.log(`Run ${(0, node_util.styleText)("cyan", `${programName} <command> --help`)} for command-specific help.\n`);
|
|
268
|
-
}
|
|
269
|
-
defineCLIAdapter({
|
|
270
|
-
renderHelp(def, parentName) {
|
|
271
|
-
renderHelp(def, parentName);
|
|
272
|
-
},
|
|
273
|
-
async run(defs, argv, opts) {
|
|
274
|
-
const { programName, defaultCommandName, version } = opts;
|
|
275
|
-
const args = argv.length >= 2 && argv[0]?.includes("node") ? argv.slice(2) : argv;
|
|
276
|
-
if (args[0] === "--version" || args[0] === "-v") {
|
|
277
|
-
console.log(version);
|
|
278
|
-
process.exit(0);
|
|
279
|
-
}
|
|
280
|
-
if (args[0] === "--help" || args[0] === "-h") {
|
|
281
|
-
printRootHelp(programName, version, defs);
|
|
282
|
-
process.exit(0);
|
|
283
|
-
}
|
|
284
|
-
if (args.length === 0) {
|
|
285
|
-
const defaultDef = defs.find((d) => d.name === defaultCommandName);
|
|
286
|
-
if (defaultDef?.run) await runCommand(defaultDef, [], programName);
|
|
287
|
-
else printRootHelp(programName, version, defs);
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
const [first, ...rest] = args;
|
|
291
|
-
const isKnownSubcommand = defs.some((d) => d.name === first);
|
|
292
|
-
let def;
|
|
293
|
-
let commandArgv;
|
|
294
|
-
let parentName;
|
|
295
|
-
if (isKnownSubcommand) {
|
|
296
|
-
def = defs.find((d) => d.name === first);
|
|
297
|
-
commandArgv = rest;
|
|
298
|
-
parentName = programName;
|
|
299
|
-
} else {
|
|
300
|
-
def = defs.find((d) => d.name === defaultCommandName);
|
|
301
|
-
commandArgv = args;
|
|
302
|
-
parentName = programName;
|
|
303
|
-
}
|
|
304
|
-
if (!def) {
|
|
305
|
-
console.error(`Unknown command: ${first}`);
|
|
306
|
-
printRootHelp(programName, version, defs);
|
|
307
|
-
process.exit(1);
|
|
308
|
-
}
|
|
309
|
-
if (def.subCommands?.length) {
|
|
310
|
-
const [subName, ...subRest] = commandArgv;
|
|
311
|
-
const subDef = def.subCommands.find((s) => s.name === subName);
|
|
312
|
-
if (subName === "--help" || subName === "-h") {
|
|
313
|
-
renderHelp(def, parentName);
|
|
314
|
-
process.exit(0);
|
|
315
|
-
}
|
|
316
|
-
if (!subDef) {
|
|
317
|
-
renderHelp(def, parentName);
|
|
318
|
-
process.exit(subName ? 1 : 0);
|
|
319
|
-
}
|
|
320
|
-
await runCommand(subDef, subRest, `${parentName} ${def.name}`);
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
await runCommand(def, commandArgv, parentName);
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
/**
|
|
327
|
-
* Calculates elapsed time in milliseconds from a high-resolution start time.
|
|
328
|
-
* Rounds to 2 decimal places to provide sub-millisecond precision without noise.
|
|
156
|
+
* ```ts
|
|
157
|
+
* const start = process.hrtime()
|
|
158
|
+
* doWork()
|
|
159
|
+
* getElapsedMs(start) // 42.35
|
|
160
|
+
* ```
|
|
329
161
|
*/
|
|
330
162
|
function getElapsedMs(hrStart) {
|
|
331
163
|
const [seconds, nanoseconds] = process.hrtime(hrStart);
|
|
@@ -333,39 +165,22 @@ function getElapsedMs(hrStart) {
|
|
|
333
165
|
return Math.round(ms * 100) / 100;
|
|
334
166
|
}
|
|
335
167
|
/**
|
|
336
|
-
* Converts a millisecond duration into a human-readable string.
|
|
337
|
-
*
|
|
168
|
+
* Converts a millisecond duration into a human-readable string (`ms`, `s`, or `m s`).
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* formatMs(250) // '250ms'
|
|
173
|
+
* formatMs(1500) // '1.50s'
|
|
174
|
+
* formatMs(90000) // '1m 30.0s'
|
|
175
|
+
* ```
|
|
338
176
|
*/
|
|
339
177
|
function formatMs(ms) {
|
|
340
178
|
if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
|
|
341
179
|
if (ms >= 1e3) return `${(ms / 1e3).toFixed(2)}s`;
|
|
342
180
|
return `${Math.round(ms)}ms`;
|
|
343
181
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
* Falls back to `255` for any channel that cannot be parsed.
|
|
347
|
-
*/
|
|
348
|
-
function parseHex(color) {
|
|
349
|
-
const int = Number.parseInt(color.replace("#", ""), 16);
|
|
350
|
-
return Number.isNaN(int) ? {
|
|
351
|
-
r: 255,
|
|
352
|
-
g: 255,
|
|
353
|
-
b: 255
|
|
354
|
-
} : {
|
|
355
|
-
r: int >> 16 & 255,
|
|
356
|
-
g: int >> 8 & 255,
|
|
357
|
-
b: int & 255
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* Returns a function that wraps a string in a 24-bit ANSI true-color escape sequence
|
|
362
|
-
* for the given hex color.
|
|
363
|
-
*/
|
|
364
|
-
function hex(color) {
|
|
365
|
-
const { r, g, b } = parseHex(color);
|
|
366
|
-
return (text) => `\x1b[38;2;${r};${g};${b}m${text}\x1b[0m`;
|
|
367
|
-
}
|
|
368
|
-
hex("#F55A17"), hex("#F5A217"), hex("#F58517"), hex("#B45309"), hex("#FFFFFF"), hex("#adadc6"), hex("#FDA4AF");
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region ../../internals/utils/src/fs.ts
|
|
369
184
|
/**
|
|
370
185
|
* Converts all backslashes to forward slashes.
|
|
371
186
|
* Extended-length Windows paths (`\\?\...`) are left unchanged.
|
|
@@ -375,8 +190,14 @@ function toSlash(p) {
|
|
|
375
190
|
return p.replaceAll("\\", "/");
|
|
376
191
|
}
|
|
377
192
|
/**
|
|
378
|
-
* Returns the relative path from `rootDir` to `filePath`, always using
|
|
379
|
-
*
|
|
193
|
+
* Returns the relative path from `rootDir` to `filePath`, always using forward slashes
|
|
194
|
+
* and prefixed with `./` when not already traversing upward.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'
|
|
199
|
+
* getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'
|
|
200
|
+
* ```
|
|
380
201
|
*/
|
|
381
202
|
function getRelativePath(rootDir, filePath) {
|
|
382
203
|
if (!rootDir || !filePath) throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ""} ${filePath || ""}`);
|
|
@@ -386,43 +207,43 @@ function getRelativePath(rootDir, filePath) {
|
|
|
386
207
|
/**
|
|
387
208
|
* Resolves to `true` when the file or directory at `path` exists.
|
|
388
209
|
* Uses `Bun.file().exists()` when running under Bun, `fs.access` otherwise.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```ts
|
|
213
|
+
* if (await exists('./kubb.config.ts')) {
|
|
214
|
+
* const content = await read('./kubb.config.ts')
|
|
215
|
+
* }
|
|
216
|
+
* ```
|
|
389
217
|
*/
|
|
390
218
|
async function exists(path) {
|
|
391
219
|
if (typeof Bun !== "undefined") return Bun.file(path).exists();
|
|
392
220
|
return (0, node_fs_promises.access)(path).then(() => true, () => false);
|
|
393
221
|
}
|
|
394
222
|
/**
|
|
395
|
-
* Reads the file at `path` as a UTF-8 string.
|
|
396
|
-
* Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.
|
|
397
|
-
*/
|
|
398
|
-
async function read(path) {
|
|
399
|
-
if (typeof Bun !== "undefined") return Bun.file(path).text();
|
|
400
|
-
return (0, node_fs_promises.readFile)(path, { encoding: "utf8" });
|
|
401
|
-
}
|
|
402
|
-
/** Synchronous counterpart of `read`. */
|
|
403
|
-
function readSync(path) {
|
|
404
|
-
return (0, node_fs.readFileSync)(path, { encoding: "utf8" });
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
223
|
* Writes `data` to `path`, trimming leading/trailing whitespace before saving.
|
|
408
|
-
* Skips the write
|
|
409
|
-
* identical to what is already on disk.
|
|
224
|
+
* Skips the write when the trimmed content is empty or identical to what is already on disk.
|
|
410
225
|
* Creates any missing parent directories automatically.
|
|
411
|
-
* When `sanity` is `true`, re-reads the file after writing and throws if the
|
|
412
|
-
*
|
|
226
|
+
* When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* await write('./src/Pet.ts', source) // writes and returns trimmed content
|
|
231
|
+
* await write('./src/Pet.ts', source) // null — file unchanged
|
|
232
|
+
* await write('./src/Pet.ts', ' ') // null — empty content skipped
|
|
233
|
+
* ```
|
|
413
234
|
*/
|
|
414
235
|
async function write(path, data, options = {}) {
|
|
415
236
|
const trimmed = data.trim();
|
|
416
|
-
if (trimmed === "") return
|
|
237
|
+
if (trimmed === "") return null;
|
|
417
238
|
const resolved = (0, node_path.resolve)(path);
|
|
418
239
|
if (typeof Bun !== "undefined") {
|
|
419
240
|
const file = Bun.file(resolved);
|
|
420
|
-
if ((await file.exists() ? await file.text() : null) === trimmed) return
|
|
241
|
+
if ((await file.exists() ? await file.text() : null) === trimmed) return null;
|
|
421
242
|
await Bun.write(resolved, trimmed);
|
|
422
243
|
return trimmed;
|
|
423
244
|
}
|
|
424
245
|
try {
|
|
425
|
-
if (await (0, node_fs_promises.readFile)(resolved, { encoding: "utf-8" }) === trimmed) return
|
|
246
|
+
if (await (0, node_fs_promises.readFile)(resolved, { encoding: "utf-8" }) === trimmed) return null;
|
|
426
247
|
} catch {}
|
|
427
248
|
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(resolved), { recursive: true });
|
|
428
249
|
await (0, node_fs_promises.writeFile)(resolved, trimmed, { encoding: "utf-8" });
|
|
@@ -433,133 +254,22 @@ async function write(path, data, options = {}) {
|
|
|
433
254
|
}
|
|
434
255
|
return trimmed;
|
|
435
256
|
}
|
|
436
|
-
/**
|
|
257
|
+
/**
|
|
258
|
+
* Recursively removes `path`. Silently succeeds when `path` does not exist.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* await clean('./dist')
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
437
265
|
async function clean(path) {
|
|
438
266
|
return (0, node_fs_promises.rm)(path, {
|
|
439
267
|
recursive: true,
|
|
440
268
|
force: true
|
|
441
269
|
});
|
|
442
270
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
* Use this when you need to track usage frequency but always emit the original identifier.
|
|
446
|
-
*/
|
|
447
|
-
function setUniqueName(originalName, data) {
|
|
448
|
-
let used = data[originalName] || 0;
|
|
449
|
-
if (used) {
|
|
450
|
-
data[originalName] = ++used;
|
|
451
|
-
return originalName;
|
|
452
|
-
}
|
|
453
|
-
data[originalName] = 1;
|
|
454
|
-
return originalName;
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* JavaScript and Java reserved words.
|
|
458
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
459
|
-
*/
|
|
460
|
-
const reservedWords = [
|
|
461
|
-
"abstract",
|
|
462
|
-
"arguments",
|
|
463
|
-
"boolean",
|
|
464
|
-
"break",
|
|
465
|
-
"byte",
|
|
466
|
-
"case",
|
|
467
|
-
"catch",
|
|
468
|
-
"char",
|
|
469
|
-
"class",
|
|
470
|
-
"const",
|
|
471
|
-
"continue",
|
|
472
|
-
"debugger",
|
|
473
|
-
"default",
|
|
474
|
-
"delete",
|
|
475
|
-
"do",
|
|
476
|
-
"double",
|
|
477
|
-
"else",
|
|
478
|
-
"enum",
|
|
479
|
-
"eval",
|
|
480
|
-
"export",
|
|
481
|
-
"extends",
|
|
482
|
-
"false",
|
|
483
|
-
"final",
|
|
484
|
-
"finally",
|
|
485
|
-
"float",
|
|
486
|
-
"for",
|
|
487
|
-
"function",
|
|
488
|
-
"goto",
|
|
489
|
-
"if",
|
|
490
|
-
"implements",
|
|
491
|
-
"import",
|
|
492
|
-
"in",
|
|
493
|
-
"instanceof",
|
|
494
|
-
"int",
|
|
495
|
-
"interface",
|
|
496
|
-
"let",
|
|
497
|
-
"long",
|
|
498
|
-
"native",
|
|
499
|
-
"new",
|
|
500
|
-
"null",
|
|
501
|
-
"package",
|
|
502
|
-
"private",
|
|
503
|
-
"protected",
|
|
504
|
-
"public",
|
|
505
|
-
"return",
|
|
506
|
-
"short",
|
|
507
|
-
"static",
|
|
508
|
-
"super",
|
|
509
|
-
"switch",
|
|
510
|
-
"synchronized",
|
|
511
|
-
"this",
|
|
512
|
-
"throw",
|
|
513
|
-
"throws",
|
|
514
|
-
"transient",
|
|
515
|
-
"true",
|
|
516
|
-
"try",
|
|
517
|
-
"typeof",
|
|
518
|
-
"var",
|
|
519
|
-
"void",
|
|
520
|
-
"volatile",
|
|
521
|
-
"while",
|
|
522
|
-
"with",
|
|
523
|
-
"yield",
|
|
524
|
-
"Array",
|
|
525
|
-
"Date",
|
|
526
|
-
"hasOwnProperty",
|
|
527
|
-
"Infinity",
|
|
528
|
-
"isFinite",
|
|
529
|
-
"isNaN",
|
|
530
|
-
"isPrototypeOf",
|
|
531
|
-
"length",
|
|
532
|
-
"Math",
|
|
533
|
-
"name",
|
|
534
|
-
"NaN",
|
|
535
|
-
"Number",
|
|
536
|
-
"Object",
|
|
537
|
-
"prototype",
|
|
538
|
-
"String",
|
|
539
|
-
"toString",
|
|
540
|
-
"undefined",
|
|
541
|
-
"valueOf"
|
|
542
|
-
];
|
|
543
|
-
/**
|
|
544
|
-
* Prefixes a word with `_` when it is a reserved JavaScript/Java identifier
|
|
545
|
-
* or starts with a digit.
|
|
546
|
-
*/
|
|
547
|
-
function transformReservedWord(word) {
|
|
548
|
-
const firstChar = word.charCodeAt(0);
|
|
549
|
-
if (word && (reservedWords.includes(word) || firstChar >= 48 && firstChar <= 57)) return `_${word}`;
|
|
550
|
-
return word;
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
554
|
-
*/
|
|
555
|
-
function isValidVarName(name) {
|
|
556
|
-
try {
|
|
557
|
-
new Function(`var ${name}`);
|
|
558
|
-
} catch {
|
|
559
|
-
return false;
|
|
560
|
-
}
|
|
561
|
-
return true;
|
|
562
|
-
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region ../../internals/utils/src/urlPath.ts
|
|
563
273
|
/**
|
|
564
274
|
* Parses and transforms an OpenAPI/Swagger path string into various URL formats.
|
|
565
275
|
*
|
|
@@ -569,18 +279,33 @@ function isValidVarName(name) {
|
|
|
569
279
|
* p.template // '`/pet/${petId}`'
|
|
570
280
|
*/
|
|
571
281
|
var URLPath = class {
|
|
572
|
-
/**
|
|
282
|
+
/**
|
|
283
|
+
* The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.
|
|
284
|
+
*/
|
|
573
285
|
path;
|
|
574
286
|
#options;
|
|
575
287
|
constructor(path, options = {}) {
|
|
576
288
|
this.path = path;
|
|
577
289
|
this.#options = options;
|
|
578
290
|
}
|
|
579
|
-
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
|
|
291
|
+
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```ts
|
|
295
|
+
* new URLPath('/pet/{petId}').URL // '/pet/:petId'
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
580
298
|
get URL() {
|
|
581
299
|
return this.toURLPath();
|
|
582
300
|
}
|
|
583
|
-
/** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
|
|
301
|
+
/** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
|
|
302
|
+
*
|
|
303
|
+
* @example
|
|
304
|
+
* ```ts
|
|
305
|
+
* new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
|
|
306
|
+
* new URLPath('/pet/{petId}').isURL // false
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
584
309
|
get isURL() {
|
|
585
310
|
try {
|
|
586
311
|
return !!new URL(this.path).href;
|
|
@@ -598,19 +323,35 @@ var URLPath = class {
|
|
|
598
323
|
get template() {
|
|
599
324
|
return this.toTemplateString();
|
|
600
325
|
}
|
|
601
|
-
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
326
|
+
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```ts
|
|
330
|
+
* new URLPath('/pet/{petId}').object
|
|
331
|
+
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
602
334
|
get object() {
|
|
603
335
|
return this.toObject();
|
|
604
336
|
}
|
|
605
|
-
/** Returns a map of path parameter names, or `undefined` when the path has no parameters.
|
|
337
|
+
/** Returns a map of path parameter names, or `undefined` when the path has no parameters.
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* new URLPath('/pet/{petId}').params // { petId: 'petId' }
|
|
342
|
+
* new URLPath('/pet').params // undefined
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
606
345
|
get params() {
|
|
607
346
|
return this.getParams();
|
|
608
347
|
}
|
|
609
348
|
#transformParam(raw) {
|
|
610
|
-
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
611
|
-
return this.#options.casing === "camelcase" ? camelCase(param) : param;
|
|
349
|
+
const param = require_PluginDriver.isValidVarName(raw) ? raw : require_PluginDriver.camelCase(raw);
|
|
350
|
+
return this.#options.casing === "camelcase" ? require_PluginDriver.camelCase(param) : param;
|
|
612
351
|
}
|
|
613
|
-
/**
|
|
352
|
+
/**
|
|
353
|
+
* Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
|
|
354
|
+
*/
|
|
614
355
|
#eachParam(fn) {
|
|
615
356
|
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
616
357
|
const raw = match[1];
|
|
@@ -647,6 +388,12 @@ var URLPath = class {
|
|
|
647
388
|
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
648
389
|
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
649
390
|
* Returns `undefined` when no path parameters are found.
|
|
391
|
+
*
|
|
392
|
+
* @example
|
|
393
|
+
* ```ts
|
|
394
|
+
* new URLPath('/pet/{petId}/tag/{tagId}').getParams()
|
|
395
|
+
* // { petId: 'petId', tagId: 'tagId' }
|
|
396
|
+
* ```
|
|
650
397
|
*/
|
|
651
398
|
getParams(replacer) {
|
|
652
399
|
const params = {};
|
|
@@ -656,837 +403,457 @@ var URLPath = class {
|
|
|
656
403
|
});
|
|
657
404
|
return Object.keys(params).length > 0 ? params : void 0;
|
|
658
405
|
}
|
|
659
|
-
/** Converts the OpenAPI path to Express-style colon syntax
|
|
406
|
+
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```ts
|
|
410
|
+
* new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
660
413
|
toURLPath() {
|
|
661
414
|
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
662
415
|
}
|
|
663
416
|
};
|
|
664
417
|
//#endregion
|
|
665
|
-
//#region src/
|
|
666
|
-
function defineConfig(config) {
|
|
667
|
-
return config;
|
|
668
|
-
}
|
|
418
|
+
//#region src/createAdapter.ts
|
|
669
419
|
/**
|
|
670
|
-
*
|
|
420
|
+
* Creates an adapter factory. Call the returned function with optional options to get the adapter instance.
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* export const myAdapter = createAdapter<MyAdapter>((options) => {
|
|
424
|
+
* return {
|
|
425
|
+
* name: 'my-adapter',
|
|
426
|
+
* options,
|
|
427
|
+
* async parse(source) { ... },
|
|
428
|
+
* }
|
|
429
|
+
* })
|
|
430
|
+
*
|
|
431
|
+
* // instantiate
|
|
432
|
+
* const adapter = myAdapter({ validate: true })
|
|
671
433
|
*/
|
|
672
|
-
function
|
|
673
|
-
return
|
|
434
|
+
function createAdapter(build) {
|
|
435
|
+
return (options) => build(options ?? {});
|
|
674
436
|
}
|
|
675
437
|
//#endregion
|
|
676
|
-
//#region src/
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
};
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
"--write",
|
|
717
|
-
outputPath
|
|
718
|
-
],
|
|
719
|
-
errorMessage: "Prettier not found"
|
|
720
|
-
},
|
|
721
|
-
biome: {
|
|
722
|
-
command: "biome",
|
|
723
|
-
args: (outputPath) => [
|
|
724
|
-
"format",
|
|
725
|
-
"--write",
|
|
726
|
-
outputPath
|
|
727
|
-
],
|
|
728
|
-
errorMessage: "Biome not found"
|
|
729
|
-
},
|
|
730
|
-
oxfmt: {
|
|
731
|
-
command: "oxfmt",
|
|
732
|
-
args: (outputPath) => [outputPath],
|
|
733
|
-
errorMessage: "Oxfmt not found"
|
|
438
|
+
//#region src/FileProcessor.ts
|
|
439
|
+
function joinSources(file) {
|
|
440
|
+
return file.sources.map((item) => (0, _kubb_ast.extractStringsFromNodes)(item.nodes)).filter(Boolean).join("\n\n");
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Converts a single file to a string using the registered parsers.
|
|
444
|
+
* Falls back to joining source values when no matching parser is found.
|
|
445
|
+
*/
|
|
446
|
+
var FileProcessor = class {
|
|
447
|
+
#limit = require_PluginDriver.pLimit(100);
|
|
448
|
+
async parse(file, { parsers, extension } = {}) {
|
|
449
|
+
const parseExtName = extension?.[file.extname] || void 0;
|
|
450
|
+
if (!parsers || !file.extname) return joinSources(file);
|
|
451
|
+
const parser = parsers.get(file.extname);
|
|
452
|
+
if (!parser) return joinSources(file);
|
|
453
|
+
return parser.parse(file, { extname: parseExtName });
|
|
454
|
+
}
|
|
455
|
+
async run(files, { parsers, mode = "sequential", extension, onStart, onEnd, onUpdate } = {}) {
|
|
456
|
+
await onStart?.(files);
|
|
457
|
+
const total = files.length;
|
|
458
|
+
let processed = 0;
|
|
459
|
+
const processOne = async (file) => {
|
|
460
|
+
const source = await this.parse(file, {
|
|
461
|
+
extension,
|
|
462
|
+
parsers
|
|
463
|
+
});
|
|
464
|
+
const currentProcessed = ++processed;
|
|
465
|
+
const percentage = currentProcessed / total * 100;
|
|
466
|
+
await onUpdate?.({
|
|
467
|
+
file,
|
|
468
|
+
source,
|
|
469
|
+
processed: currentProcessed,
|
|
470
|
+
percentage,
|
|
471
|
+
total
|
|
472
|
+
});
|
|
473
|
+
};
|
|
474
|
+
if (mode === "sequential") for (const file of files) await processOne(file);
|
|
475
|
+
else await Promise.all(files.map((file) => this.#limit(() => processOne(file))));
|
|
476
|
+
await onEnd?.(files);
|
|
477
|
+
return files;
|
|
734
478
|
}
|
|
735
479
|
};
|
|
736
480
|
//#endregion
|
|
737
|
-
//#region src/
|
|
481
|
+
//#region src/createStorage.ts
|
|
738
482
|
/**
|
|
739
|
-
*
|
|
740
|
-
*
|
|
741
|
-
* The JSON representation is deflate-compressed with {@link deflateSync} before
|
|
742
|
-
* base64url encoding, which typically reduces payload size by 70–80 % and
|
|
743
|
-
* keeps URLs well within browser and server path-length limits.
|
|
483
|
+
* Creates a storage factory. Call the returned function with optional options to get the storage instance.
|
|
744
484
|
*
|
|
745
|
-
*
|
|
485
|
+
* @example
|
|
486
|
+
* export const memoryStorage = createStorage(() => {
|
|
487
|
+
* const store = new Map<string, string>()
|
|
488
|
+
* return {
|
|
489
|
+
* name: 'memory',
|
|
490
|
+
* async hasItem(key) { return store.has(key) },
|
|
491
|
+
* async getItem(key) { return store.get(key) ?? null },
|
|
492
|
+
* async setItem(key, value) { store.set(key, value) },
|
|
493
|
+
* async removeItem(key) { store.delete(key) },
|
|
494
|
+
* async getKeys(base) {
|
|
495
|
+
* const keys = [...store.keys()]
|
|
496
|
+
* return base ? keys.filter((k) => k.startsWith(base)) : keys
|
|
497
|
+
* },
|
|
498
|
+
* async clear(base) { if (!base) store.clear() },
|
|
499
|
+
* }
|
|
500
|
+
* })
|
|
746
501
|
*/
|
|
747
|
-
function
|
|
748
|
-
|
|
749
|
-
return Buffer.from(compressed).toString("base64url");
|
|
502
|
+
function createStorage(build) {
|
|
503
|
+
return (options) => build(options ?? {});
|
|
750
504
|
}
|
|
505
|
+
//#endregion
|
|
506
|
+
//#region src/storages/fsStorage.ts
|
|
751
507
|
/**
|
|
752
|
-
*
|
|
753
|
-
* When `options.ast` is `true`, navigates to the AST inspector (`/ast`).
|
|
754
|
-
* The `root` is encoded and attached as the `?root=` query parameter so Studio
|
|
755
|
-
* can decode and render it without a round-trip to any server.
|
|
508
|
+
* Detects the filesystem error used to indicate that a path does not exist.
|
|
756
509
|
*/
|
|
757
|
-
function
|
|
758
|
-
return
|
|
510
|
+
function isMissingPathError(error) {
|
|
511
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
759
512
|
}
|
|
760
513
|
/**
|
|
761
|
-
*
|
|
514
|
+
* Built-in filesystem storage driver.
|
|
515
|
+
*
|
|
516
|
+
* This is the default storage when no `storage` option is configured in `output`.
|
|
517
|
+
* Keys are resolved against `process.cwd()`, so root-relative paths such as
|
|
518
|
+
* `src/gen/api/getPets.ts` are written to the correct location without extra configuration.
|
|
519
|
+
*
|
|
520
|
+
* Internally uses the `write` utility from `@internals/utils`, which:
|
|
521
|
+
* - trims leading/trailing whitespace before writing
|
|
522
|
+
* - skips the write when file content is already identical (deduplication)
|
|
523
|
+
* - creates missing parent directories automatically
|
|
524
|
+
* - supports Bun's native file API when running under Bun
|
|
525
|
+
*
|
|
526
|
+
* @example
|
|
527
|
+
* ```ts
|
|
528
|
+
* import { defineConfig, fsStorage } from '@kubb/core'
|
|
762
529
|
*
|
|
763
|
-
*
|
|
530
|
+
* export default defineConfig({
|
|
531
|
+
* input: { path: './petStore.yaml' },
|
|
532
|
+
* output: { path: './src/gen', storage: fsStorage() },
|
|
533
|
+
* })
|
|
534
|
+
* ```
|
|
764
535
|
*/
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
try {
|
|
775
|
-
await (0, tinyexec.x)(cmd, args);
|
|
776
|
-
} catch {
|
|
777
|
-
console.log(`\n ${url}\n`);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
//#endregion
|
|
781
|
-
//#region ../../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
782
|
-
var Node = class {
|
|
783
|
-
value;
|
|
784
|
-
next;
|
|
785
|
-
constructor(value) {
|
|
786
|
-
this.value = value;
|
|
787
|
-
}
|
|
788
|
-
};
|
|
789
|
-
var Queue = class {
|
|
790
|
-
#head;
|
|
791
|
-
#tail;
|
|
792
|
-
#size;
|
|
793
|
-
constructor() {
|
|
794
|
-
this.clear();
|
|
795
|
-
}
|
|
796
|
-
enqueue(value) {
|
|
797
|
-
const node = new Node(value);
|
|
798
|
-
if (this.#head) {
|
|
799
|
-
this.#tail.next = node;
|
|
800
|
-
this.#tail = node;
|
|
801
|
-
} else {
|
|
802
|
-
this.#head = node;
|
|
803
|
-
this.#tail = node;
|
|
804
|
-
}
|
|
805
|
-
this.#size++;
|
|
806
|
-
}
|
|
807
|
-
dequeue() {
|
|
808
|
-
const current = this.#head;
|
|
809
|
-
if (!current) return;
|
|
810
|
-
this.#head = this.#head.next;
|
|
811
|
-
this.#size--;
|
|
812
|
-
if (!this.#head) this.#tail = void 0;
|
|
813
|
-
return current.value;
|
|
814
|
-
}
|
|
815
|
-
peek() {
|
|
816
|
-
if (!this.#head) return;
|
|
817
|
-
return this.#head.value;
|
|
818
|
-
}
|
|
819
|
-
clear() {
|
|
820
|
-
this.#head = void 0;
|
|
821
|
-
this.#tail = void 0;
|
|
822
|
-
this.#size = 0;
|
|
823
|
-
}
|
|
824
|
-
get size() {
|
|
825
|
-
return this.#size;
|
|
826
|
-
}
|
|
827
|
-
*[Symbol.iterator]() {
|
|
828
|
-
let current = this.#head;
|
|
829
|
-
while (current) {
|
|
830
|
-
yield current.value;
|
|
831
|
-
current = current.next;
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
*drain() {
|
|
835
|
-
while (this.#head) yield this.dequeue();
|
|
836
|
-
}
|
|
837
|
-
};
|
|
838
|
-
//#endregion
|
|
839
|
-
//#region ../../node_modules/.pnpm/p-limit@7.3.0/node_modules/p-limit/index.js
|
|
840
|
-
function pLimit(concurrency) {
|
|
841
|
-
let rejectOnClear = false;
|
|
842
|
-
if (typeof concurrency === "object") ({concurrency, rejectOnClear = false} = concurrency);
|
|
843
|
-
validateConcurrency(concurrency);
|
|
844
|
-
if (typeof rejectOnClear !== "boolean") throw new TypeError("Expected `rejectOnClear` to be a boolean");
|
|
845
|
-
const queue = new Queue();
|
|
846
|
-
let activeCount = 0;
|
|
847
|
-
const resumeNext = () => {
|
|
848
|
-
if (activeCount < concurrency && queue.size > 0) {
|
|
849
|
-
activeCount++;
|
|
850
|
-
queue.dequeue().run();
|
|
536
|
+
const fsStorage = createStorage(() => ({
|
|
537
|
+
name: "fs",
|
|
538
|
+
async hasItem(key) {
|
|
539
|
+
try {
|
|
540
|
+
await (0, node_fs_promises.access)((0, node_path.resolve)(key));
|
|
541
|
+
return true;
|
|
542
|
+
} catch (error) {
|
|
543
|
+
if (isMissingPathError(error)) return false;
|
|
544
|
+
throw new Error(`Failed to access storage item "${key}"`, { cause: error });
|
|
851
545
|
}
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
activeCount--;
|
|
855
|
-
resumeNext();
|
|
856
|
-
};
|
|
857
|
-
const run = async (function_, resolve, arguments_) => {
|
|
858
|
-
const result = (async () => function_(...arguments_))();
|
|
859
|
-
resolve(result);
|
|
546
|
+
},
|
|
547
|
+
async getItem(key) {
|
|
860
548
|
try {
|
|
861
|
-
await
|
|
862
|
-
} catch {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
}
|
|
884
|
-
const
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
|
|
899
|
-
return Promise.all(promises);
|
|
900
|
-
} }
|
|
901
|
-
});
|
|
902
|
-
return generator;
|
|
903
|
-
}
|
|
904
|
-
function validateConcurrency(concurrency) {
|
|
905
|
-
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) throw new TypeError("Expected `concurrency` to be a number from 1 and up");
|
|
906
|
-
}
|
|
549
|
+
return await (0, node_fs_promises.readFile)((0, node_path.resolve)(key), "utf8");
|
|
550
|
+
} catch (error) {
|
|
551
|
+
if (isMissingPathError(error)) return null;
|
|
552
|
+
throw new Error(`Failed to read storage item "${key}"`, { cause: error });
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
async setItem(key, value) {
|
|
556
|
+
await write((0, node_path.resolve)(key), value, { sanity: false });
|
|
557
|
+
},
|
|
558
|
+
async removeItem(key) {
|
|
559
|
+
await (0, node_fs_promises.rm)((0, node_path.resolve)(key), { force: true });
|
|
560
|
+
},
|
|
561
|
+
async getKeys(base) {
|
|
562
|
+
const keys = [];
|
|
563
|
+
const resolvedBase = (0, node_path.resolve)(base ?? process.cwd());
|
|
564
|
+
async function walk(dir, prefix) {
|
|
565
|
+
let entries;
|
|
566
|
+
try {
|
|
567
|
+
entries = await (0, node_fs_promises.readdir)(dir, { withFileTypes: true });
|
|
568
|
+
} catch (error) {
|
|
569
|
+
if (isMissingPathError(error)) return;
|
|
570
|
+
throw new Error(`Failed to list storage keys under "${resolvedBase}"`, { cause: error });
|
|
571
|
+
}
|
|
572
|
+
for (const entry of entries) {
|
|
573
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
574
|
+
if (entry.isDirectory()) await walk((0, node_path.join)(dir, entry.name), rel);
|
|
575
|
+
else keys.push(rel);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
await walk(resolvedBase, "");
|
|
579
|
+
return keys;
|
|
580
|
+
},
|
|
581
|
+
async clear(base) {
|
|
582
|
+
if (!base) return;
|
|
583
|
+
await clean((0, node_path.resolve)(base));
|
|
584
|
+
}
|
|
585
|
+
}));
|
|
907
586
|
//#endregion
|
|
908
|
-
//#region
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
function hookSeq(promises) {
|
|
913
|
-
return promises.filter(Boolean).reduce((promise, func) => {
|
|
914
|
-
if (typeof func !== "function") throw new Error("HookSeq needs a function that returns a promise `() => Promise<unknown>`");
|
|
915
|
-
return promise.then((state) => {
|
|
916
|
-
const calledFunc = func(state);
|
|
917
|
-
if (calledFunc) return calledFunc.then(Array.prototype.concat.bind(state));
|
|
918
|
-
return state;
|
|
919
|
-
});
|
|
920
|
-
}, Promise.resolve([]));
|
|
921
|
-
}
|
|
587
|
+
//#region package.json
|
|
588
|
+
var version = "5.0.0-alpha.40";
|
|
589
|
+
//#endregion
|
|
590
|
+
//#region src/utils/diagnostics.ts
|
|
922
591
|
/**
|
|
923
|
-
*
|
|
592
|
+
* Returns a snapshot of the current runtime environment.
|
|
593
|
+
*
|
|
594
|
+
* Useful for attaching context to debug logs and error reports so that
|
|
595
|
+
* issues can be reproduced without manual information gathering.
|
|
924
596
|
*/
|
|
925
|
-
function
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
597
|
+
function getDiagnosticInfo() {
|
|
598
|
+
return {
|
|
599
|
+
nodeVersion: node_process.version,
|
|
600
|
+
KubbVersion: version,
|
|
601
|
+
platform: process.platform,
|
|
602
|
+
arch: process.arch,
|
|
603
|
+
cwd: process.cwd()
|
|
604
|
+
};
|
|
932
605
|
}
|
|
606
|
+
//#endregion
|
|
607
|
+
//#region src/utils/TreeNode.ts
|
|
933
608
|
/**
|
|
934
|
-
*
|
|
609
|
+
* Tree structure used to build per-directory barrel (`index.ts`) files from a
|
|
610
|
+
* flat list of generated {@link FileNode} entries.
|
|
611
|
+
*
|
|
612
|
+
* Each node represents either a directory or a file within the output tree.
|
|
613
|
+
* Use {@link TreeNode.build} to construct a root node from a file list, then
|
|
614
|
+
* traverse with {@link TreeNode.forEach}, {@link TreeNode.leaves}, or the
|
|
615
|
+
* `*Deep` helpers.
|
|
935
616
|
*/
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
#options = {};
|
|
945
|
-
constructor(options = {}) {
|
|
946
|
-
this.#options = options;
|
|
617
|
+
var TreeNode = class TreeNode {
|
|
618
|
+
data;
|
|
619
|
+
parent;
|
|
620
|
+
children = [];
|
|
621
|
+
#cachedLeaves = void 0;
|
|
622
|
+
constructor(data, parent) {
|
|
623
|
+
this.data = data;
|
|
624
|
+
this.parent = parent;
|
|
947
625
|
}
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
if (
|
|
951
|
-
|
|
952
|
-
|
|
626
|
+
addChild(data) {
|
|
627
|
+
const child = new TreeNode(data, this);
|
|
628
|
+
if (!this.children) this.children = [];
|
|
629
|
+
this.children.push(child);
|
|
630
|
+
return child;
|
|
953
631
|
}
|
|
954
|
-
};
|
|
955
|
-
function isPromiseRejectedResult(result) {
|
|
956
|
-
return result.status === "rejected";
|
|
957
|
-
}
|
|
958
|
-
//#endregion
|
|
959
|
-
//#region src/PluginManager.ts
|
|
960
|
-
function getMode(fileOrFolder) {
|
|
961
|
-
if (!fileOrFolder) return "split";
|
|
962
|
-
return (0, node_path.extname)(fileOrFolder) ? "single" : "split";
|
|
963
|
-
}
|
|
964
|
-
var PluginManager = class {
|
|
965
|
-
config;
|
|
966
|
-
options;
|
|
967
632
|
/**
|
|
968
|
-
*
|
|
969
|
-
* the build pipeline after the adapter's `parse()` resolves.
|
|
633
|
+
* Returns the root ancestor of this node, walking up via `parent` links.
|
|
970
634
|
*/
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
#plugins = /* @__PURE__ */ new Set();
|
|
975
|
-
#usedPluginNames = {};
|
|
976
|
-
#promiseManager;
|
|
977
|
-
constructor(config, options) {
|
|
978
|
-
this.config = config;
|
|
979
|
-
this.options = options;
|
|
980
|
-
this.#promiseManager = new PromiseManager({ nullCheck: (state) => !!state?.result });
|
|
981
|
-
[...config.plugins || []].forEach((plugin) => {
|
|
982
|
-
const parsedPlugin = this.#parse(plugin);
|
|
983
|
-
this.#plugins.add(parsedPlugin);
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
get events() {
|
|
987
|
-
return this.options.events;
|
|
988
|
-
}
|
|
989
|
-
getContext(plugin) {
|
|
990
|
-
const plugins = [...this.#plugins];
|
|
991
|
-
const pluginManager = this;
|
|
992
|
-
const baseContext = {
|
|
993
|
-
fabric: this.options.fabric,
|
|
994
|
-
config: this.config,
|
|
995
|
-
plugin,
|
|
996
|
-
events: this.options.events,
|
|
997
|
-
pluginManager: this,
|
|
998
|
-
mode: getMode((0, node_path.resolve)(this.config.root, this.config.output.path)),
|
|
999
|
-
addFile: async (...files) => {
|
|
1000
|
-
await this.options.fabric.addFile(...files);
|
|
1001
|
-
},
|
|
1002
|
-
upsertFile: async (...files) => {
|
|
1003
|
-
await this.options.fabric.upsertFile(...files);
|
|
1004
|
-
},
|
|
1005
|
-
get rootNode() {
|
|
1006
|
-
return pluginManager.rootNode;
|
|
1007
|
-
},
|
|
1008
|
-
get adapter() {
|
|
1009
|
-
return pluginManager.adapter;
|
|
1010
|
-
},
|
|
1011
|
-
openInStudio(options) {
|
|
1012
|
-
if (!pluginManager.config.devtools || pluginManager.#studioIsOpen) return;
|
|
1013
|
-
if (typeof pluginManager.config.devtools !== "object") throw new Error("Devtools must be an object");
|
|
1014
|
-
if (!pluginManager.rootNode || !pluginManager.adapter) throw new Error("adapter is not defined, make sure you have set the parser in kubb.config.ts");
|
|
1015
|
-
pluginManager.#studioIsOpen = true;
|
|
1016
|
-
const studioUrl = pluginManager.config.devtools?.studioUrl ?? "https://studio.kubb.dev";
|
|
1017
|
-
return openInStudio(pluginManager.rootNode, studioUrl, options);
|
|
1018
|
-
}
|
|
1019
|
-
};
|
|
1020
|
-
const mergedExtras = {};
|
|
1021
|
-
for (const p of plugins) if (typeof p.inject === "function") {
|
|
1022
|
-
const result = p.inject.call(baseContext, baseContext);
|
|
1023
|
-
if (result !== null && typeof result === "object") Object.assign(mergedExtras, result);
|
|
1024
|
-
}
|
|
1025
|
-
return {
|
|
1026
|
-
...baseContext,
|
|
1027
|
-
...mergedExtras
|
|
1028
|
-
};
|
|
1029
|
-
}
|
|
1030
|
-
get plugins() {
|
|
1031
|
-
return this.#getSortedPlugins();
|
|
1032
|
-
}
|
|
1033
|
-
getFile({ name, mode, extname, pluginName, options }) {
|
|
1034
|
-
const resolvedName = mode ? mode === "single" ? "" : this.resolveName({
|
|
1035
|
-
name,
|
|
1036
|
-
pluginName,
|
|
1037
|
-
type: "file"
|
|
1038
|
-
}) : name;
|
|
1039
|
-
const path = this.resolvePath({
|
|
1040
|
-
baseName: `${resolvedName}${extname}`,
|
|
1041
|
-
mode,
|
|
1042
|
-
pluginName,
|
|
1043
|
-
options
|
|
1044
|
-
});
|
|
1045
|
-
if (!path) throw new Error(`Filepath should be defined for resolvedName "${resolvedName}" and pluginName "${pluginName}"`);
|
|
1046
|
-
return {
|
|
1047
|
-
path,
|
|
1048
|
-
baseName: (0, node_path.basename)(path),
|
|
1049
|
-
meta: { pluginName },
|
|
1050
|
-
sources: [],
|
|
1051
|
-
imports: [],
|
|
1052
|
-
exports: []
|
|
1053
|
-
};
|
|
635
|
+
get root() {
|
|
636
|
+
if (!this.parent) return this;
|
|
637
|
+
return this.parent.root;
|
|
1054
638
|
}
|
|
1055
|
-
resolvePath = (params) => {
|
|
1056
|
-
const defaultPath = (0, node_path.resolve)((0, node_path.resolve)(this.config.root, this.config.output.path), params.baseName);
|
|
1057
|
-
if (params.pluginName) return this.hookForPluginSync({
|
|
1058
|
-
pluginName: params.pluginName,
|
|
1059
|
-
hookName: "resolvePath",
|
|
1060
|
-
parameters: [
|
|
1061
|
-
params.baseName,
|
|
1062
|
-
params.mode,
|
|
1063
|
-
params.options
|
|
1064
|
-
]
|
|
1065
|
-
})?.at(0) || defaultPath;
|
|
1066
|
-
return this.hookFirstSync({
|
|
1067
|
-
hookName: "resolvePath",
|
|
1068
|
-
parameters: [
|
|
1069
|
-
params.baseName,
|
|
1070
|
-
params.mode,
|
|
1071
|
-
params.options
|
|
1072
|
-
]
|
|
1073
|
-
})?.result || defaultPath;
|
|
1074
|
-
};
|
|
1075
|
-
resolveName = (params) => {
|
|
1076
|
-
if (params.pluginName) {
|
|
1077
|
-
const names = this.hookForPluginSync({
|
|
1078
|
-
pluginName: params.pluginName,
|
|
1079
|
-
hookName: "resolveName",
|
|
1080
|
-
parameters: [params.name.trim(), params.type]
|
|
1081
|
-
});
|
|
1082
|
-
return transformReservedWord([...new Set(names)].at(0) || params.name);
|
|
1083
|
-
}
|
|
1084
|
-
const name = this.hookFirstSync({
|
|
1085
|
-
hookName: "resolveName",
|
|
1086
|
-
parameters: [params.name.trim(), params.type]
|
|
1087
|
-
})?.result;
|
|
1088
|
-
return transformReservedWord(name ?? params.name);
|
|
1089
|
-
};
|
|
1090
639
|
/**
|
|
1091
|
-
*
|
|
640
|
+
* Returns all leaf descendants (nodes with no children) of this node.
|
|
641
|
+
*
|
|
642
|
+
* Results are cached after the first traversal.
|
|
1092
643
|
*/
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
this
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
for (const plugin of plugins) {
|
|
1101
|
-
const result = await this.#execute({
|
|
1102
|
-
strategy: "hookFirst",
|
|
1103
|
-
hookName,
|
|
1104
|
-
parameters,
|
|
1105
|
-
plugin
|
|
1106
|
-
});
|
|
1107
|
-
if (result !== void 0 && result !== null) items.push(result);
|
|
1108
|
-
}
|
|
1109
|
-
this.events.emit("plugins:hook:progress:end", { hookName });
|
|
1110
|
-
return items;
|
|
644
|
+
get leaves() {
|
|
645
|
+
if (!this.children || this.children.length === 0) return [this];
|
|
646
|
+
if (this.#cachedLeaves) return this.#cachedLeaves;
|
|
647
|
+
const leaves = [];
|
|
648
|
+
for (const child of this.children) leaves.push(...child.leaves);
|
|
649
|
+
this.#cachedLeaves = leaves;
|
|
650
|
+
return leaves;
|
|
1111
651
|
}
|
|
1112
652
|
/**
|
|
1113
|
-
*
|
|
653
|
+
* Visits this node and every descendant in depth-first order.
|
|
1114
654
|
*/
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
parameters,
|
|
1121
|
-
plugin
|
|
1122
|
-
});
|
|
1123
|
-
}).filter((x) => x !== null);
|
|
655
|
+
forEach(callback) {
|
|
656
|
+
if (typeof callback !== "function") throw new TypeError("forEach() callback must be a function");
|
|
657
|
+
callback(this);
|
|
658
|
+
for (const child of this.children) child.forEach(callback);
|
|
659
|
+
return this;
|
|
1124
660
|
}
|
|
1125
661
|
/**
|
|
1126
|
-
*
|
|
662
|
+
* Finds the first leaf that satisfies `predicate`, or `undefined` when none match.
|
|
1127
663
|
*/
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
});
|
|
1132
|
-
this.events.emit("plugins:hook:progress:start", {
|
|
1133
|
-
hookName,
|
|
1134
|
-
plugins
|
|
1135
|
-
});
|
|
1136
|
-
const promises = plugins.map((plugin) => {
|
|
1137
|
-
return async () => {
|
|
1138
|
-
const value = await this.#execute({
|
|
1139
|
-
strategy: "hookFirst",
|
|
1140
|
-
hookName,
|
|
1141
|
-
parameters,
|
|
1142
|
-
plugin
|
|
1143
|
-
});
|
|
1144
|
-
return Promise.resolve({
|
|
1145
|
-
plugin,
|
|
1146
|
-
result: value
|
|
1147
|
-
});
|
|
1148
|
-
};
|
|
1149
|
-
});
|
|
1150
|
-
const result = await this.#promiseManager.run("first", promises);
|
|
1151
|
-
this.events.emit("plugins:hook:progress:end", { hookName });
|
|
1152
|
-
return result;
|
|
664
|
+
findDeep(predicate) {
|
|
665
|
+
if (typeof predicate !== "function") throw new TypeError("find() predicate must be a function");
|
|
666
|
+
return this.leaves.find(predicate);
|
|
1153
667
|
}
|
|
1154
668
|
/**
|
|
1155
|
-
*
|
|
669
|
+
* Calls `callback` for every leaf of this node.
|
|
1156
670
|
*/
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
return skipped ? !skipped.has(plugin) : true;
|
|
1161
|
-
});
|
|
1162
|
-
for (const plugin of plugins) {
|
|
1163
|
-
parseResult = {
|
|
1164
|
-
result: this.#executeSync({
|
|
1165
|
-
strategy: "hookFirst",
|
|
1166
|
-
hookName,
|
|
1167
|
-
parameters,
|
|
1168
|
-
plugin
|
|
1169
|
-
}),
|
|
1170
|
-
plugin
|
|
1171
|
-
};
|
|
1172
|
-
if (parseResult?.result != null) break;
|
|
1173
|
-
}
|
|
1174
|
-
return parseResult;
|
|
671
|
+
forEachDeep(callback) {
|
|
672
|
+
if (typeof callback !== "function") throw new TypeError("forEach() callback must be a function");
|
|
673
|
+
this.leaves.forEach(callback);
|
|
1175
674
|
}
|
|
1176
675
|
/**
|
|
1177
|
-
*
|
|
676
|
+
* Returns all leaves that satisfy `callback`.
|
|
1178
677
|
*/
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
this.
|
|
1182
|
-
hookName,
|
|
1183
|
-
plugins
|
|
1184
|
-
});
|
|
1185
|
-
const pluginStartTimes = /* @__PURE__ */ new Map();
|
|
1186
|
-
const promises = plugins.map((plugin) => {
|
|
1187
|
-
return () => {
|
|
1188
|
-
pluginStartTimes.set(plugin, node_perf_hooks.performance.now());
|
|
1189
|
-
return this.#execute({
|
|
1190
|
-
strategy: "hookParallel",
|
|
1191
|
-
hookName,
|
|
1192
|
-
parameters,
|
|
1193
|
-
plugin
|
|
1194
|
-
});
|
|
1195
|
-
};
|
|
1196
|
-
});
|
|
1197
|
-
const results = await this.#promiseManager.run("parallel", promises, { concurrency: this.options.concurrency });
|
|
1198
|
-
results.forEach((result, index) => {
|
|
1199
|
-
if (isPromiseRejectedResult(result)) {
|
|
1200
|
-
const plugin = this.#getSortedPlugins(hookName)[index];
|
|
1201
|
-
if (plugin) {
|
|
1202
|
-
const startTime = pluginStartTimes.get(plugin) ?? node_perf_hooks.performance.now();
|
|
1203
|
-
this.events.emit("error", result.reason, {
|
|
1204
|
-
plugin,
|
|
1205
|
-
hookName,
|
|
1206
|
-
strategy: "hookParallel",
|
|
1207
|
-
duration: Math.round(node_perf_hooks.performance.now() - startTime),
|
|
1208
|
-
parameters
|
|
1209
|
-
});
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
});
|
|
1213
|
-
this.events.emit("plugins:hook:progress:end", { hookName });
|
|
1214
|
-
return results.reduce((acc, result) => {
|
|
1215
|
-
if (result.status === "fulfilled") acc.push(result.value);
|
|
1216
|
-
return acc;
|
|
1217
|
-
}, []);
|
|
678
|
+
filterDeep(callback) {
|
|
679
|
+
if (typeof callback !== "function") throw new TypeError("filter() callback must be a function");
|
|
680
|
+
return this.leaves.filter(callback);
|
|
1218
681
|
}
|
|
1219
682
|
/**
|
|
1220
|
-
*
|
|
683
|
+
* Maps every leaf through `callback` and returns the resulting array.
|
|
1221
684
|
*/
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
this.
|
|
1225
|
-
hookName,
|
|
1226
|
-
plugins
|
|
1227
|
-
});
|
|
1228
|
-
const promises = plugins.map((plugin) => {
|
|
1229
|
-
return () => this.#execute({
|
|
1230
|
-
strategy: "hookSeq",
|
|
1231
|
-
hookName,
|
|
1232
|
-
parameters,
|
|
1233
|
-
plugin
|
|
1234
|
-
});
|
|
1235
|
-
});
|
|
1236
|
-
await this.#promiseManager.run("seq", promises);
|
|
1237
|
-
this.events.emit("plugins:hook:progress:end", { hookName });
|
|
1238
|
-
}
|
|
1239
|
-
#getSortedPlugins(hookName) {
|
|
1240
|
-
const plugins = [...this.#plugins];
|
|
1241
|
-
if (hookName) return plugins.filter((plugin) => hookName in plugin);
|
|
1242
|
-
return plugins.map((plugin) => {
|
|
1243
|
-
if (plugin.pre) {
|
|
1244
|
-
let missingPlugins = plugin.pre.filter((pluginName) => !plugins.find((pluginToFind) => pluginToFind.name === pluginName));
|
|
1245
|
-
if (missingPlugins.includes("plugin-oas") && this.adapter) missingPlugins = missingPlugins.filter((pluginName) => pluginName !== "plugin-oas");
|
|
1246
|
-
if (missingPlugins.length > 0) throw new ValidationPluginError(`The plugin '${plugin.name}' has a pre set that references missing plugins for '${missingPlugins.join(", ")}'`);
|
|
1247
|
-
}
|
|
1248
|
-
return plugin;
|
|
1249
|
-
}).sort((a, b) => {
|
|
1250
|
-
if (b.pre?.includes(a.name)) return 1;
|
|
1251
|
-
if (b.post?.includes(a.name)) return -1;
|
|
1252
|
-
return 0;
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1255
|
-
getPluginByName(pluginName) {
|
|
1256
|
-
return [...this.#plugins].find((item) => item.name === pluginName);
|
|
1257
|
-
}
|
|
1258
|
-
getPluginsByName(hookName, pluginName) {
|
|
1259
|
-
const plugins = [...this.plugins];
|
|
1260
|
-
const pluginByPluginName = plugins.filter((plugin) => hookName in plugin).filter((item) => item.name === pluginName);
|
|
1261
|
-
if (!pluginByPluginName?.length) {
|
|
1262
|
-
const corePlugin = plugins.find((plugin) => plugin.name === "core" && hookName in plugin);
|
|
1263
|
-
return corePlugin ? [corePlugin] : [];
|
|
1264
|
-
}
|
|
1265
|
-
return pluginByPluginName;
|
|
685
|
+
mapDeep(callback) {
|
|
686
|
+
if (typeof callback !== "function") throw new TypeError("map() callback must be a function");
|
|
687
|
+
return this.leaves.map(callback);
|
|
1266
688
|
}
|
|
1267
689
|
/**
|
|
1268
|
-
*
|
|
1269
|
-
*
|
|
1270
|
-
*
|
|
1271
|
-
*
|
|
690
|
+
* Builds a {@link TreeNode} tree from a flat list of files.
|
|
691
|
+
*
|
|
692
|
+
* - Filters to files under `root` (when provided) and skips `.json` files.
|
|
693
|
+
* - Returns `null` when no files match.
|
|
1272
694
|
*/
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
parameters,
|
|
1290
|
-
plugin
|
|
1291
|
-
});
|
|
1292
|
-
const startTime = node_perf_hooks.performance.now();
|
|
1293
|
-
return (async () => {
|
|
1294
|
-
try {
|
|
1295
|
-
const output = typeof hook === "function" ? await Promise.resolve(hook.apply(this.getContext(plugin), parameters ?? [])) : hook;
|
|
1296
|
-
this.#emitProcessingEnd({
|
|
1297
|
-
startTime,
|
|
1298
|
-
output,
|
|
1299
|
-
strategy,
|
|
1300
|
-
hookName,
|
|
1301
|
-
plugin,
|
|
1302
|
-
parameters
|
|
695
|
+
static build(files, root) {
|
|
696
|
+
try {
|
|
697
|
+
const filteredTree = buildDirectoryTree(files, root);
|
|
698
|
+
if (!filteredTree) return null;
|
|
699
|
+
const treeNode = new TreeNode({
|
|
700
|
+
name: filteredTree.name,
|
|
701
|
+
path: filteredTree.path,
|
|
702
|
+
file: filteredTree.file,
|
|
703
|
+
type: require_PluginDriver.PluginDriver.getMode(filteredTree.path)
|
|
704
|
+
});
|
|
705
|
+
const recurse = (node, item) => {
|
|
706
|
+
const subNode = node.addChild({
|
|
707
|
+
name: item.name,
|
|
708
|
+
path: item.path,
|
|
709
|
+
file: item.file,
|
|
710
|
+
type: require_PluginDriver.PluginDriver.getMode(item.path)
|
|
1303
711
|
});
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
this.events.emit("error", error, {
|
|
1307
|
-
plugin,
|
|
1308
|
-
hookName,
|
|
1309
|
-
strategy,
|
|
1310
|
-
duration: Math.round(node_perf_hooks.performance.now() - startTime)
|
|
712
|
+
if (item.children?.length) item.children?.forEach((child) => {
|
|
713
|
+
recurse(subNode, child);
|
|
1311
714
|
});
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
}
|
|
1316
|
-
/**
|
|
1317
|
-
* Run a sync plugin hook and return the result.
|
|
1318
|
-
* @param hookName Name of the plugin hook. Must be in `PluginHooks`.
|
|
1319
|
-
* @param args Arguments passed to the plugin hook.
|
|
1320
|
-
* @param plugin The actual plugin
|
|
1321
|
-
*/
|
|
1322
|
-
#executeSync({ strategy, hookName, parameters, plugin }) {
|
|
1323
|
-
const hook = plugin[hookName];
|
|
1324
|
-
if (!hook) return null;
|
|
1325
|
-
this.events.emit("plugins:hook:processing:start", {
|
|
1326
|
-
strategy,
|
|
1327
|
-
hookName,
|
|
1328
|
-
parameters,
|
|
1329
|
-
plugin
|
|
1330
|
-
});
|
|
1331
|
-
const startTime = node_perf_hooks.performance.now();
|
|
1332
|
-
try {
|
|
1333
|
-
const output = typeof hook === "function" ? hook.apply(this.getContext(plugin), parameters) : hook;
|
|
1334
|
-
this.#emitProcessingEnd({
|
|
1335
|
-
startTime,
|
|
1336
|
-
output,
|
|
1337
|
-
strategy,
|
|
1338
|
-
hookName,
|
|
1339
|
-
plugin,
|
|
1340
|
-
parameters
|
|
715
|
+
};
|
|
716
|
+
filteredTree.children?.forEach((child) => {
|
|
717
|
+
recurse(treeNode, child);
|
|
1341
718
|
});
|
|
1342
|
-
return
|
|
719
|
+
return treeNode;
|
|
1343
720
|
} catch (error) {
|
|
1344
|
-
|
|
1345
|
-
plugin,
|
|
1346
|
-
hookName,
|
|
1347
|
-
strategy,
|
|
1348
|
-
duration: Math.round(node_perf_hooks.performance.now() - startTime)
|
|
1349
|
-
});
|
|
1350
|
-
return null;
|
|
721
|
+
throw new Error("Something went wrong with creating barrel files with the TreeNode class", { cause: error });
|
|
1351
722
|
}
|
|
1352
723
|
}
|
|
1353
|
-
#parse(plugin) {
|
|
1354
|
-
const usedPluginNames = this.#usedPluginNames;
|
|
1355
|
-
setUniqueName(plugin.name, usedPluginNames);
|
|
1356
|
-
const usageCount = usedPluginNames[plugin.name];
|
|
1357
|
-
if (usageCount && usageCount > 1) throw new ValidationPluginError(`Duplicate plugin "${plugin.name}" detected. Each plugin can only be used once. Use a different configuration instead of adding multiple instances of the same plugin.`);
|
|
1358
|
-
return {
|
|
1359
|
-
install() {},
|
|
1360
|
-
...plugin
|
|
1361
|
-
};
|
|
1362
|
-
}
|
|
1363
724
|
};
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
725
|
+
const normalizePath = (p) => p.replaceAll("\\", "/");
|
|
726
|
+
function buildDirectoryTree(files, rootFolder = "") {
|
|
727
|
+
const normalizedRootFolder = normalizePath(rootFolder);
|
|
728
|
+
const rootPrefix = normalizedRootFolder.endsWith("/") ? normalizedRootFolder : `${normalizedRootFolder}/`;
|
|
729
|
+
const filteredFiles = files.filter((file) => {
|
|
730
|
+
const normalizedFilePath = normalizePath(file.path);
|
|
731
|
+
return rootFolder ? normalizedFilePath.startsWith(rootPrefix) && !normalizedFilePath.endsWith(".json") : !normalizedFilePath.endsWith(".json");
|
|
732
|
+
});
|
|
733
|
+
if (filteredFiles.length === 0) return null;
|
|
734
|
+
const root = {
|
|
735
|
+
name: rootFolder || "",
|
|
736
|
+
path: rootFolder || "",
|
|
737
|
+
children: []
|
|
738
|
+
};
|
|
739
|
+
filteredFiles.forEach((file) => {
|
|
740
|
+
const parts = file.path.slice(rootFolder.length).split("/").filter(Boolean);
|
|
741
|
+
let currentLevel = root.children;
|
|
742
|
+
let currentPath = normalizePath(rootFolder);
|
|
743
|
+
parts.forEach((part, index) => {
|
|
744
|
+
currentPath = node_path.default.posix.join(currentPath, part);
|
|
745
|
+
let existingNode = currentLevel.find((node) => node.name === part);
|
|
746
|
+
if (!existingNode) {
|
|
747
|
+
if (index === parts.length - 1) existingNode = {
|
|
748
|
+
name: part,
|
|
749
|
+
file,
|
|
750
|
+
path: currentPath
|
|
751
|
+
};
|
|
752
|
+
else existingNode = {
|
|
753
|
+
name: part,
|
|
754
|
+
path: currentPath,
|
|
755
|
+
children: []
|
|
756
|
+
};
|
|
757
|
+
currentLevel.push(existingNode);
|
|
758
|
+
}
|
|
759
|
+
if (!existingNode.file) currentLevel = existingNode.children;
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
return root;
|
|
1393
763
|
}
|
|
1394
764
|
//#endregion
|
|
1395
|
-
//#region src/
|
|
765
|
+
//#region src/utils/getBarrelFiles.ts
|
|
766
|
+
/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */
|
|
767
|
+
function getBarrelFilesByRoot(root, files) {
|
|
768
|
+
const cachedFiles = /* @__PURE__ */ new Map();
|
|
769
|
+
TreeNode.build(files, root)?.forEach((treeNode) => {
|
|
770
|
+
if (!treeNode?.children || !treeNode.parent?.data.path) return;
|
|
771
|
+
const barrelFile = (0, _kubb_ast.createFile)({
|
|
772
|
+
path: (0, node_path.join)(treeNode.parent?.data.path, "index.ts"),
|
|
773
|
+
baseName: "index.ts",
|
|
774
|
+
exports: [],
|
|
775
|
+
imports: [],
|
|
776
|
+
sources: []
|
|
777
|
+
});
|
|
778
|
+
const previousBarrelFile = cachedFiles.get(barrelFile.path);
|
|
779
|
+
treeNode.leaves.forEach((item) => {
|
|
780
|
+
if (!item.data.name) return;
|
|
781
|
+
(item.data.file?.sources || []).forEach((source) => {
|
|
782
|
+
if (!item.data.file?.path || !source.isIndexable || !source.name) return;
|
|
783
|
+
if (previousBarrelFile?.sources.some((item) => item.name === source.name && item.isTypeOnly === source.isTypeOnly)) return;
|
|
784
|
+
barrelFile.exports.push((0, _kubb_ast.createExport)({
|
|
785
|
+
name: [source.name],
|
|
786
|
+
path: getRelativePath(treeNode.parent?.data.path, item.data.path),
|
|
787
|
+
isTypeOnly: source.isTypeOnly
|
|
788
|
+
}));
|
|
789
|
+
barrelFile.sources.push((0, _kubb_ast.createSource)({
|
|
790
|
+
name: source.name,
|
|
791
|
+
isTypeOnly: source.isTypeOnly,
|
|
792
|
+
isExportable: false,
|
|
793
|
+
isIndexable: false
|
|
794
|
+
}));
|
|
795
|
+
});
|
|
796
|
+
});
|
|
797
|
+
if (previousBarrelFile) {
|
|
798
|
+
previousBarrelFile.sources.push(...barrelFile.sources);
|
|
799
|
+
previousBarrelFile.exports.push(...barrelFile.exports);
|
|
800
|
+
} else cachedFiles.set(barrelFile.path, barrelFile);
|
|
801
|
+
});
|
|
802
|
+
return [...cachedFiles.values()];
|
|
803
|
+
}
|
|
804
|
+
function trimExtName(text) {
|
|
805
|
+
const dotIndex = text.lastIndexOf(".");
|
|
806
|
+
if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
|
|
807
|
+
return text;
|
|
808
|
+
}
|
|
1396
809
|
/**
|
|
1397
|
-
*
|
|
1398
|
-
*
|
|
1399
|
-
* This is the default storage when no `storage` option is configured in `output`.
|
|
1400
|
-
* Keys are resolved against `process.cwd()`, so root-relative paths such as
|
|
1401
|
-
* `src/gen/api/getPets.ts` are written to the correct location without extra configuration.
|
|
1402
|
-
*
|
|
1403
|
-
* Internally uses the `write` utility from `@internals/utils`, which:
|
|
1404
|
-
* - trims leading/trailing whitespace before writing
|
|
1405
|
-
* - skips the write when file content is already identical (deduplication)
|
|
1406
|
-
* - creates missing parent directories automatically
|
|
1407
|
-
* - supports Bun's native file API when running under Bun
|
|
810
|
+
* Generates `index.ts` barrel files for all directories under `root/output.path`.
|
|
1408
811
|
*
|
|
1409
|
-
*
|
|
1410
|
-
*
|
|
1411
|
-
*
|
|
1412
|
-
*
|
|
1413
|
-
* export default defineConfig({
|
|
1414
|
-
* input: { path: './petStore.yaml' },
|
|
1415
|
-
* output: { path: './src/gen', storage: fsStorage() },
|
|
1416
|
-
* })
|
|
1417
|
-
* ```
|
|
812
|
+
* - Returns an empty array when `type` is falsy or `'propagate'`.
|
|
813
|
+
* - Skips generation when the output path itself ends with `index` (already a barrel).
|
|
814
|
+
* - When `type` is `'all'`, strips named exports so every re-export becomes a wildcard (`export * from`).
|
|
815
|
+
* - Attaches `meta` to each barrel file for downstream plugin identification.
|
|
1418
816
|
*/
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
async getKeys(base) {
|
|
1443
|
-
const keys = [];
|
|
1444
|
-
async function walk(dir, prefix) {
|
|
1445
|
-
let entries;
|
|
1446
|
-
try {
|
|
1447
|
-
entries = await (0, node_fs_promises.readdir)(dir, { withFileTypes: true });
|
|
1448
|
-
} catch {
|
|
1449
|
-
return;
|
|
1450
|
-
}
|
|
1451
|
-
for (const entry of entries) {
|
|
1452
|
-
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
1453
|
-
if (entry.isDirectory()) await walk((0, node_path.join)(dir, entry.name), rel);
|
|
1454
|
-
else keys.push(rel);
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
await walk((0, node_path.resolve)(base ?? process.cwd()), "");
|
|
1458
|
-
return keys;
|
|
1459
|
-
},
|
|
1460
|
-
async clear(base) {
|
|
1461
|
-
if (!base) return;
|
|
1462
|
-
await clean((0, node_path.resolve)(base));
|
|
1463
|
-
}
|
|
1464
|
-
}));
|
|
1465
|
-
//#endregion
|
|
1466
|
-
//#region package.json
|
|
1467
|
-
var version = "5.0.0-alpha.4";
|
|
817
|
+
async function getBarrelFiles(files, { type, meta = {}, root, output }) {
|
|
818
|
+
if (!type || type === "propagate") return [];
|
|
819
|
+
const pathToBuildFrom = (0, node_path.join)(root, output.path);
|
|
820
|
+
if (trimExtName(pathToBuildFrom).endsWith("index")) return [];
|
|
821
|
+
const barrelFiles = getBarrelFilesByRoot(pathToBuildFrom, files);
|
|
822
|
+
if (type === "all") return barrelFiles.map((file) => {
|
|
823
|
+
return {
|
|
824
|
+
...file,
|
|
825
|
+
exports: file.exports.map((exportItem) => {
|
|
826
|
+
return {
|
|
827
|
+
...exportItem,
|
|
828
|
+
name: void 0
|
|
829
|
+
};
|
|
830
|
+
})
|
|
831
|
+
};
|
|
832
|
+
});
|
|
833
|
+
return barrelFiles.map((indexFile) => {
|
|
834
|
+
return {
|
|
835
|
+
...indexFile,
|
|
836
|
+
meta
|
|
837
|
+
};
|
|
838
|
+
});
|
|
839
|
+
}
|
|
1468
840
|
//#endregion
|
|
1469
|
-
//#region src/utils/
|
|
841
|
+
//#region src/utils/isInputPath.ts
|
|
1470
842
|
/**
|
|
1471
|
-
*
|
|
843
|
+
* Type guard to check if a given config has an `input.path`.
|
|
1472
844
|
*/
|
|
1473
|
-
function
|
|
1474
|
-
return
|
|
1475
|
-
nodeVersion: node_process.version,
|
|
1476
|
-
KubbVersion: version,
|
|
1477
|
-
platform: process.platform,
|
|
1478
|
-
arch: process.arch,
|
|
1479
|
-
cwd: process.cwd()
|
|
1480
|
-
};
|
|
845
|
+
function isInputPath(config) {
|
|
846
|
+
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
1481
847
|
}
|
|
1482
848
|
//#endregion
|
|
1483
|
-
//#region src/
|
|
849
|
+
//#region src/createKubb.ts
|
|
1484
850
|
async function setup(options) {
|
|
1485
|
-
const { config: userConfig
|
|
851
|
+
const { config: userConfig } = options;
|
|
852
|
+
const hooks = options.hooks ?? new AsyncEventEmitter();
|
|
1486
853
|
const sources = /* @__PURE__ */ new Map();
|
|
1487
854
|
const diagnosticInfo = getDiagnosticInfo();
|
|
1488
|
-
if (Array.isArray(userConfig.input)) await
|
|
1489
|
-
await
|
|
855
|
+
if (Array.isArray(userConfig.input)) await hooks.emit("kubb:warn", "This feature is still under development — use with caution");
|
|
856
|
+
await hooks.emit("kubb:debug", {
|
|
1490
857
|
date: /* @__PURE__ */ new Date(),
|
|
1491
858
|
logs: [
|
|
1492
859
|
"Configuration:",
|
|
@@ -1505,7 +872,7 @@ async function setup(options) {
|
|
|
1505
872
|
try {
|
|
1506
873
|
if (isInputPath(userConfig) && !new URLPath(userConfig.input.path).isURL) {
|
|
1507
874
|
await exists(userConfig.input.path);
|
|
1508
|
-
await
|
|
875
|
+
await hooks.emit("kubb:debug", {
|
|
1509
876
|
date: /* @__PURE__ */ new Date(),
|
|
1510
877
|
logs: [`✓ Input file validated: ${userConfig.input.path}`]
|
|
1511
878
|
});
|
|
@@ -1516,155 +883,193 @@ async function setup(options) {
|
|
|
1516
883
|
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 });
|
|
1517
884
|
}
|
|
1518
885
|
}
|
|
1519
|
-
|
|
1520
|
-
|
|
886
|
+
if (!userConfig.adapter) throw new Error("Adapter should be defined");
|
|
887
|
+
const config = {
|
|
1521
888
|
...userConfig,
|
|
889
|
+
root: userConfig.root || process.cwd(),
|
|
890
|
+
parsers: userConfig.parsers ?? [],
|
|
891
|
+
adapter: userConfig.adapter,
|
|
1522
892
|
output: {
|
|
1523
893
|
write: true,
|
|
1524
894
|
barrelType: "named",
|
|
1525
|
-
extension: DEFAULT_EXTENSION,
|
|
1526
|
-
defaultBanner: DEFAULT_BANNER,
|
|
895
|
+
extension: require_PluginDriver.DEFAULT_EXTENSION,
|
|
896
|
+
defaultBanner: require_PluginDriver.DEFAULT_BANNER,
|
|
1527
897
|
...userConfig.output
|
|
1528
898
|
},
|
|
1529
899
|
devtools: userConfig.devtools ? {
|
|
1530
|
-
studioUrl: DEFAULT_STUDIO_URL,
|
|
900
|
+
studioUrl: require_PluginDriver.DEFAULT_STUDIO_URL,
|
|
1531
901
|
...typeof userConfig.devtools === "boolean" ? {} : userConfig.devtools
|
|
1532
902
|
} : void 0,
|
|
1533
903
|
plugins: userConfig.plugins
|
|
1534
904
|
};
|
|
1535
|
-
const storage =
|
|
1536
|
-
if (
|
|
1537
|
-
await
|
|
905
|
+
const storage = config.output.write === false ? null : config.output.storage ?? fsStorage();
|
|
906
|
+
if (config.output.clean) {
|
|
907
|
+
await hooks.emit("kubb:debug", {
|
|
1538
908
|
date: /* @__PURE__ */ new Date(),
|
|
1539
|
-
logs: ["Cleaning output directories", ` • Output: ${
|
|
909
|
+
logs: ["Cleaning output directories", ` • Output: ${config.output.path}`]
|
|
1540
910
|
});
|
|
1541
|
-
await storage?.clear((0, node_path.resolve)(
|
|
911
|
+
await storage?.clear((0, node_path.resolve)(config.root, config.output.path));
|
|
1542
912
|
}
|
|
1543
|
-
const
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
fabric.context.on("files:processing:start", (files) => {
|
|
1547
|
-
events.emit("files:processing:start", files);
|
|
1548
|
-
events.emit("debug", {
|
|
1549
|
-
date: /* @__PURE__ */ new Date(),
|
|
1550
|
-
logs: [`Writing ${files.length} files...`]
|
|
1551
|
-
});
|
|
1552
|
-
});
|
|
1553
|
-
fabric.context.on("file:processing:update", async (params) => {
|
|
1554
|
-
const { file, source } = params;
|
|
1555
|
-
await events.emit("file:processing:update", {
|
|
1556
|
-
...params,
|
|
1557
|
-
config: definedConfig,
|
|
1558
|
-
source
|
|
1559
|
-
});
|
|
1560
|
-
if (source) {
|
|
1561
|
-
const key = (0, node_path.relative)((0, node_path.resolve)(definedConfig.root), file.path);
|
|
1562
|
-
await storage?.setItem(key, source);
|
|
1563
|
-
sources.set(file.path, source);
|
|
1564
|
-
}
|
|
913
|
+
const driver = new require_PluginDriver.PluginDriver(config, {
|
|
914
|
+
hooks,
|
|
915
|
+
concurrency: 15
|
|
1565
916
|
});
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
}
|
|
917
|
+
const adapter = config.adapter;
|
|
918
|
+
if (!adapter) throw new Error("No adapter configured. Please provide an adapter in your kubb.config.ts.");
|
|
919
|
+
const source = inputToAdapterSource(config);
|
|
920
|
+
await hooks.emit("kubb:debug", {
|
|
921
|
+
date: /* @__PURE__ */ new Date(),
|
|
922
|
+
logs: [`Running adapter: ${adapter.name}`]
|
|
1572
923
|
});
|
|
1573
|
-
|
|
924
|
+
driver.adapter = adapter;
|
|
925
|
+
driver.inputNode = await adapter.parse(source);
|
|
926
|
+
await hooks.emit("kubb:debug", {
|
|
1574
927
|
date: /* @__PURE__ */ new Date(),
|
|
1575
928
|
logs: [
|
|
1576
|
-
|
|
1577
|
-
` •
|
|
1578
|
-
` •
|
|
929
|
+
`✓ Adapter '${adapter.name}' resolved InputNode`,
|
|
930
|
+
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
931
|
+
` • Operations: ${driver.inputNode.operations.length}`
|
|
1579
932
|
]
|
|
1580
933
|
});
|
|
1581
|
-
const pluginManager = new PluginManager(definedConfig, {
|
|
1582
|
-
fabric,
|
|
1583
|
-
events,
|
|
1584
|
-
concurrency: 15
|
|
1585
|
-
});
|
|
1586
|
-
if (definedConfig.adapter) {
|
|
1587
|
-
const source = inputToAdapterSource(definedConfig);
|
|
1588
|
-
await events.emit("debug", {
|
|
1589
|
-
date: /* @__PURE__ */ new Date(),
|
|
1590
|
-
logs: [`Running adapter: ${definedConfig.adapter.name}`]
|
|
1591
|
-
});
|
|
1592
|
-
pluginManager.adapter = definedConfig.adapter;
|
|
1593
|
-
pluginManager.rootNode = await definedConfig.adapter.parse(source);
|
|
1594
|
-
await events.emit("debug", {
|
|
1595
|
-
date: /* @__PURE__ */ new Date(),
|
|
1596
|
-
logs: [
|
|
1597
|
-
`✓ Adapter '${definedConfig.adapter.name}' resolved RootNode`,
|
|
1598
|
-
` • Schemas: ${pluginManager.rootNode.schemas.length}`,
|
|
1599
|
-
` • Operations: ${pluginManager.rootNode.operations.length}`
|
|
1600
|
-
]
|
|
1601
|
-
});
|
|
1602
|
-
}
|
|
1603
934
|
return {
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
sources
|
|
935
|
+
config,
|
|
936
|
+
hooks,
|
|
937
|
+
driver,
|
|
938
|
+
sources,
|
|
939
|
+
storage
|
|
1608
940
|
};
|
|
1609
941
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
942
|
+
/**
|
|
943
|
+
* Walks the AST and dispatches nodes to a plugin's direct AST hooks
|
|
944
|
+
* (`schema`, `operation`, `operations`).
|
|
945
|
+
*/
|
|
946
|
+
async function runPluginAstHooks(plugin, context) {
|
|
947
|
+
const { adapter, inputNode, resolver, driver } = context;
|
|
948
|
+
const { exclude, include, override } = plugin.options;
|
|
949
|
+
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.`);
|
|
950
|
+
function resolveRenderer(gen) {
|
|
951
|
+
return gen.renderer === null ? void 0 : gen.renderer ?? plugin.renderer ?? context.config.renderer;
|
|
952
|
+
}
|
|
953
|
+
const generators = plugin.generators ?? [];
|
|
954
|
+
const collectedOperations = [];
|
|
955
|
+
const generatorContext = {
|
|
956
|
+
...context,
|
|
957
|
+
resolver: driver.getResolver(plugin.name)
|
|
1625
958
|
};
|
|
959
|
+
await (0, _kubb_ast.walk)(inputNode, {
|
|
960
|
+
depth: "shallow",
|
|
961
|
+
async schema(node) {
|
|
962
|
+
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
963
|
+
const options = resolver.resolveOptions(transformedNode, {
|
|
964
|
+
options: plugin.options,
|
|
965
|
+
exclude,
|
|
966
|
+
include,
|
|
967
|
+
override
|
|
968
|
+
});
|
|
969
|
+
if (options === null) return;
|
|
970
|
+
const ctx = {
|
|
971
|
+
...generatorContext,
|
|
972
|
+
options
|
|
973
|
+
};
|
|
974
|
+
for (const gen of generators) {
|
|
975
|
+
if (!gen.schema) continue;
|
|
976
|
+
await require_PluginDriver.applyHookResult(await gen.schema(transformedNode, ctx), driver, resolveRenderer(gen));
|
|
977
|
+
}
|
|
978
|
+
await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
|
|
979
|
+
},
|
|
980
|
+
async operation(node) {
|
|
981
|
+
const transformedNode = plugin.transformer ? (0, _kubb_ast.transform)(node, plugin.transformer) : node;
|
|
982
|
+
const options = resolver.resolveOptions(transformedNode, {
|
|
983
|
+
options: plugin.options,
|
|
984
|
+
exclude,
|
|
985
|
+
include,
|
|
986
|
+
override
|
|
987
|
+
});
|
|
988
|
+
if (options !== null) {
|
|
989
|
+
collectedOperations.push(transformedNode);
|
|
990
|
+
const ctx = {
|
|
991
|
+
...generatorContext,
|
|
992
|
+
options
|
|
993
|
+
};
|
|
994
|
+
for (const gen of generators) {
|
|
995
|
+
if (!gen.operation) continue;
|
|
996
|
+
await require_PluginDriver.applyHookResult(await gen.operation(transformedNode, ctx), driver, resolveRenderer(gen));
|
|
997
|
+
}
|
|
998
|
+
await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
if (collectedOperations.length > 0) {
|
|
1003
|
+
const ctx = {
|
|
1004
|
+
...generatorContext,
|
|
1005
|
+
options: plugin.options
|
|
1006
|
+
};
|
|
1007
|
+
for (const gen of generators) {
|
|
1008
|
+
if (!gen.operations) continue;
|
|
1009
|
+
await require_PluginDriver.applyHookResult(await gen.operations(collectedOperations, ctx), driver, resolveRenderer(gen));
|
|
1010
|
+
}
|
|
1011
|
+
await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
|
|
1012
|
+
}
|
|
1626
1013
|
}
|
|
1627
|
-
async function safeBuild(
|
|
1628
|
-
const {
|
|
1014
|
+
async function safeBuild(setupResult) {
|
|
1015
|
+
const { driver, hooks, sources, storage } = setupResult;
|
|
1629
1016
|
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1630
1017
|
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1631
|
-
const config =
|
|
1018
|
+
const config = driver.config;
|
|
1632
1019
|
try {
|
|
1633
|
-
|
|
1634
|
-
|
|
1020
|
+
await driver.emitSetupHooks();
|
|
1021
|
+
if (driver.adapter && driver.inputNode) await hooks.emit("kubb:build:start", {
|
|
1022
|
+
config,
|
|
1023
|
+
adapter: driver.adapter,
|
|
1024
|
+
inputNode: driver.inputNode,
|
|
1025
|
+
getPlugin: (name) => driver.getPlugin(name)
|
|
1026
|
+
});
|
|
1027
|
+
for (const plugin of driver.plugins.values()) {
|
|
1028
|
+
const context = driver.getContext(plugin);
|
|
1635
1029
|
const hrStart = process.hrtime();
|
|
1636
|
-
const
|
|
1030
|
+
const { output } = plugin.options ?? {};
|
|
1031
|
+
const root = (0, node_path.resolve)(config.root, config.output.path);
|
|
1637
1032
|
try {
|
|
1638
1033
|
const timestamp = /* @__PURE__ */ new Date();
|
|
1639
|
-
await
|
|
1640
|
-
await
|
|
1034
|
+
await hooks.emit("kubb:plugin:start", plugin);
|
|
1035
|
+
await hooks.emit("kubb:debug", {
|
|
1641
1036
|
date: timestamp,
|
|
1642
|
-
logs: ["
|
|
1037
|
+
logs: ["Starting plugin...", ` • Plugin Name: ${plugin.name}`]
|
|
1643
1038
|
});
|
|
1644
|
-
await
|
|
1039
|
+
await plugin.buildStart.call(context);
|
|
1040
|
+
if (plugin.generators?.length || driver.hasRegisteredGenerators(plugin.name)) await runPluginAstHooks(plugin, context);
|
|
1041
|
+
if (output) {
|
|
1042
|
+
const barrelFiles = await getBarrelFiles(driver.fileManager.files, {
|
|
1043
|
+
type: output.barrelType ?? "named",
|
|
1044
|
+
root,
|
|
1045
|
+
output,
|
|
1046
|
+
meta: { pluginName: plugin.name }
|
|
1047
|
+
});
|
|
1048
|
+
await context.upsertFile(...barrelFiles);
|
|
1049
|
+
}
|
|
1645
1050
|
const duration = getElapsedMs(hrStart);
|
|
1646
1051
|
pluginTimings.set(plugin.name, duration);
|
|
1647
|
-
await
|
|
1052
|
+
await hooks.emit("kubb:plugin:end", plugin, {
|
|
1648
1053
|
duration,
|
|
1649
1054
|
success: true
|
|
1650
1055
|
});
|
|
1651
|
-
await
|
|
1056
|
+
await hooks.emit("kubb:debug", {
|
|
1652
1057
|
date: /* @__PURE__ */ new Date(),
|
|
1653
|
-
logs: [`✓ Plugin
|
|
1058
|
+
logs: [`✓ Plugin started successfully (${formatMs(duration)})`]
|
|
1654
1059
|
});
|
|
1655
1060
|
} catch (caughtError) {
|
|
1656
1061
|
const error = caughtError;
|
|
1657
1062
|
const errorTimestamp = /* @__PURE__ */ new Date();
|
|
1658
1063
|
const duration = getElapsedMs(hrStart);
|
|
1659
|
-
await
|
|
1064
|
+
await hooks.emit("kubb:plugin:end", plugin, {
|
|
1660
1065
|
duration,
|
|
1661
1066
|
success: false,
|
|
1662
1067
|
error
|
|
1663
1068
|
});
|
|
1664
|
-
await
|
|
1069
|
+
await hooks.emit("kubb:debug", {
|
|
1665
1070
|
date: errorTimestamp,
|
|
1666
1071
|
logs: [
|
|
1667
|
-
"✗ Plugin
|
|
1072
|
+
"✗ Plugin start failed",
|
|
1668
1073
|
` • Plugin Name: ${plugin.name}`,
|
|
1669
1074
|
` • Error: ${error.constructor.name} - ${error.message}`,
|
|
1670
1075
|
" • Stack Trace:",
|
|
@@ -1678,9 +1083,9 @@ async function safeBuild(options, overrides) {
|
|
|
1678
1083
|
}
|
|
1679
1084
|
}
|
|
1680
1085
|
if (config.output.barrelType) {
|
|
1681
|
-
const rootPath = (0, node_path.resolve)((0, node_path.resolve)(config.root), config.output.path, BARREL_FILENAME);
|
|
1086
|
+
const rootPath = (0, node_path.resolve)((0, node_path.resolve)(config.root), config.output.path, require_PluginDriver.BARREL_FILENAME);
|
|
1682
1087
|
const rootDir = (0, node_path.dirname)(rootPath);
|
|
1683
|
-
await
|
|
1088
|
+
await hooks.emit("kubb:debug", {
|
|
1684
1089
|
date: /* @__PURE__ */ new Date(),
|
|
1685
1090
|
logs: [
|
|
1686
1091
|
"Generating barrel file",
|
|
@@ -1688,59 +1093,118 @@ async function safeBuild(options, overrides) {
|
|
|
1688
1093
|
` • Path: ${rootPath}`
|
|
1689
1094
|
]
|
|
1690
1095
|
});
|
|
1691
|
-
const barrelFiles =
|
|
1096
|
+
const barrelFiles = driver.fileManager.files.filter((file) => {
|
|
1692
1097
|
return file.sources.some((source) => source.isIndexable);
|
|
1693
1098
|
});
|
|
1694
|
-
await
|
|
1099
|
+
await hooks.emit("kubb:debug", {
|
|
1695
1100
|
date: /* @__PURE__ */ new Date(),
|
|
1696
1101
|
logs: [`Found ${barrelFiles.length} indexable files for barrel export`]
|
|
1697
1102
|
});
|
|
1698
|
-
const existingBarrel =
|
|
1699
|
-
const rootFile = {
|
|
1103
|
+
const existingBarrel = driver.fileManager.files.find((f) => f.path === rootPath);
|
|
1104
|
+
const rootFile = (0, _kubb_ast.createFile)({
|
|
1700
1105
|
path: rootPath,
|
|
1701
|
-
baseName: BARREL_FILENAME,
|
|
1106
|
+
baseName: require_PluginDriver.BARREL_FILENAME,
|
|
1702
1107
|
exports: buildBarrelExports({
|
|
1703
1108
|
barrelFiles,
|
|
1704
1109
|
rootDir,
|
|
1705
1110
|
existingExports: new Set(existingBarrel?.exports?.flatMap((e) => Array.isArray(e.name) ? e.name : [e.name]).filter((n) => Boolean(n)) ?? []),
|
|
1706
1111
|
config,
|
|
1707
|
-
|
|
1708
|
-
}),
|
|
1112
|
+
driver
|
|
1113
|
+
}).map((e) => (0, _kubb_ast.createExport)(e)),
|
|
1709
1114
|
sources: [],
|
|
1710
1115
|
imports: [],
|
|
1711
1116
|
meta: {}
|
|
1712
|
-
};
|
|
1713
|
-
|
|
1714
|
-
await
|
|
1117
|
+
});
|
|
1118
|
+
driver.fileManager.upsert(rootFile);
|
|
1119
|
+
await hooks.emit("kubb:debug", {
|
|
1715
1120
|
date: /* @__PURE__ */ new Date(),
|
|
1716
1121
|
logs: [`✓ Generated barrel file (${rootFile.exports?.length || 0} exports)`]
|
|
1717
1122
|
});
|
|
1718
1123
|
}
|
|
1719
|
-
const files =
|
|
1720
|
-
|
|
1124
|
+
const files = driver.fileManager.files;
|
|
1125
|
+
const parsersMap = /* @__PURE__ */ new Map();
|
|
1126
|
+
for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
|
|
1127
|
+
const fileProcessor = new FileProcessor();
|
|
1128
|
+
await hooks.emit("kubb:debug", {
|
|
1129
|
+
date: /* @__PURE__ */ new Date(),
|
|
1130
|
+
logs: [`Writing ${files.length} files...`]
|
|
1131
|
+
});
|
|
1132
|
+
await fileProcessor.run(files, {
|
|
1133
|
+
parsers: parsersMap,
|
|
1134
|
+
extension: config.output.extension,
|
|
1135
|
+
onStart: async (processingFiles) => {
|
|
1136
|
+
await hooks.emit("kubb:files:processing:start", processingFiles);
|
|
1137
|
+
},
|
|
1138
|
+
onUpdate: async ({ file, source, processed, total, percentage }) => {
|
|
1139
|
+
await hooks.emit("kubb:file:processing:update", {
|
|
1140
|
+
file,
|
|
1141
|
+
source,
|
|
1142
|
+
processed,
|
|
1143
|
+
total,
|
|
1144
|
+
percentage,
|
|
1145
|
+
config
|
|
1146
|
+
});
|
|
1147
|
+
if (source) {
|
|
1148
|
+
await storage?.setItem(file.path, source);
|
|
1149
|
+
sources.set(file.path, source);
|
|
1150
|
+
}
|
|
1151
|
+
},
|
|
1152
|
+
onEnd: async (processedFiles) => {
|
|
1153
|
+
await hooks.emit("kubb:files:processing:end", processedFiles);
|
|
1154
|
+
await hooks.emit("kubb:debug", {
|
|
1155
|
+
date: /* @__PURE__ */ new Date(),
|
|
1156
|
+
logs: [`✓ File write process completed for ${processedFiles.length} files`]
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
});
|
|
1160
|
+
for (const plugin of driver.plugins.values()) if (plugin.buildEnd) {
|
|
1161
|
+
const context = driver.getContext(plugin);
|
|
1162
|
+
await plugin.buildEnd.call(context);
|
|
1163
|
+
}
|
|
1164
|
+
await hooks.emit("kubb:build:end", {
|
|
1165
|
+
files,
|
|
1166
|
+
config,
|
|
1167
|
+
outputDir: (0, node_path.resolve)(config.root, config.output.path)
|
|
1168
|
+
});
|
|
1721
1169
|
return {
|
|
1722
1170
|
failedPlugins,
|
|
1723
|
-
fabric,
|
|
1724
1171
|
files,
|
|
1725
|
-
|
|
1172
|
+
driver,
|
|
1726
1173
|
pluginTimings,
|
|
1727
1174
|
sources
|
|
1728
1175
|
};
|
|
1729
1176
|
} catch (error) {
|
|
1730
1177
|
return {
|
|
1731
1178
|
failedPlugins,
|
|
1732
|
-
fabric,
|
|
1733
1179
|
files: [],
|
|
1734
|
-
|
|
1180
|
+
driver,
|
|
1735
1181
|
pluginTimings,
|
|
1736
1182
|
error,
|
|
1737
1183
|
sources
|
|
1738
1184
|
};
|
|
1185
|
+
} finally {
|
|
1186
|
+
driver.dispose();
|
|
1739
1187
|
}
|
|
1740
1188
|
}
|
|
1741
|
-
function
|
|
1189
|
+
async function build(setupResult) {
|
|
1190
|
+
const { files, driver, failedPlugins, pluginTimings, error, sources } = await safeBuild(setupResult);
|
|
1191
|
+
if (error) throw error;
|
|
1192
|
+
if (failedPlugins.size > 0) {
|
|
1193
|
+
const errors = [...failedPlugins].map(({ error }) => error);
|
|
1194
|
+
throw new BuildError(`Build Error with ${failedPlugins.size} failed plugins`, { errors });
|
|
1195
|
+
}
|
|
1196
|
+
return {
|
|
1197
|
+
failedPlugins,
|
|
1198
|
+
files,
|
|
1199
|
+
driver,
|
|
1200
|
+
pluginTimings,
|
|
1201
|
+
error: void 0,
|
|
1202
|
+
sources
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
function buildBarrelExports({ barrelFiles, rootDir, existingExports, config, driver }) {
|
|
1742
1206
|
const pluginNameMap = /* @__PURE__ */ new Map();
|
|
1743
|
-
for (const plugin of
|
|
1207
|
+
for (const plugin of driver.plugins.values()) pluginNameMap.set(plugin.name, plugin);
|
|
1744
1208
|
return barrelFiles.flatMap((file) => {
|
|
1745
1209
|
const containsOnlyTypes = file.sources?.every((source) => source.isTypeOnly);
|
|
1746
1210
|
return (file.sources ?? []).flatMap((source) => {
|
|
@@ -1750,179 +1214,169 @@ function buildBarrelExports({ barrelFiles, rootDir, existingExports, config, plu
|
|
|
1750
1214
|
if (!pluginOptions || pluginOptions.output?.barrelType === false) return [];
|
|
1751
1215
|
const exportName = config.output.barrelType === "all" ? void 0 : source.name ? [source.name] : void 0;
|
|
1752
1216
|
if (exportName?.some((n) => existingExports.has(n))) return [];
|
|
1753
|
-
return [{
|
|
1217
|
+
return [(0, _kubb_ast.createExport)({
|
|
1754
1218
|
name: exportName,
|
|
1755
1219
|
path: getRelativePath(rootDir, file.path),
|
|
1756
1220
|
isTypeOnly: config.output.barrelType === "all" ? containsOnlyTypes : source.isTypeOnly
|
|
1757
|
-
}];
|
|
1221
|
+
})];
|
|
1758
1222
|
});
|
|
1759
1223
|
});
|
|
1760
1224
|
}
|
|
1761
|
-
/**
|
|
1762
|
-
* Maps the resolved `Config['input']` shape into an `AdapterSource` that
|
|
1763
|
-
* the adapter's `parse()` can consume.
|
|
1764
|
-
*/
|
|
1765
1225
|
function inputToAdapterSource(config) {
|
|
1766
1226
|
if (Array.isArray(config.input)) return {
|
|
1767
1227
|
type: "paths",
|
|
1768
|
-
paths: config.input.map((i) => (0, node_path.resolve)(config.root, i.path))
|
|
1228
|
+
paths: config.input.map((i) => new URLPath(i.path).isURL ? i.path : (0, node_path.resolve)(config.root, i.path))
|
|
1769
1229
|
};
|
|
1770
1230
|
if ("data" in config.input) return {
|
|
1771
1231
|
type: "data",
|
|
1772
1232
|
data: config.input.data
|
|
1773
1233
|
};
|
|
1234
|
+
if (new URLPath(config.input.path).isURL) return {
|
|
1235
|
+
type: "path",
|
|
1236
|
+
path: config.input.path
|
|
1237
|
+
};
|
|
1774
1238
|
return {
|
|
1775
1239
|
type: "path",
|
|
1776
1240
|
path: (0, node_path.resolve)(config.root, config.input.path)
|
|
1777
1241
|
};
|
|
1778
1242
|
}
|
|
1779
|
-
//#endregion
|
|
1780
|
-
//#region src/defineAdapter.ts
|
|
1781
1243
|
/**
|
|
1782
|
-
*
|
|
1244
|
+
* Creates a Kubb instance bound to a single config entry.
|
|
1245
|
+
*
|
|
1246
|
+
* The instance holds shared state (`hooks`, `sources`, `driver`, `config`) across the
|
|
1247
|
+
* `setup → build` lifecycle. Attach event listeners to `kubb.hooks` before
|
|
1248
|
+
* calling `setup()` or `build()`.
|
|
1783
1249
|
*
|
|
1784
1250
|
* @example
|
|
1785
1251
|
* ```ts
|
|
1786
|
-
*
|
|
1787
|
-
*
|
|
1788
|
-
*
|
|
1789
|
-
*
|
|
1790
|
-
* options: { validate, dateType, ... },
|
|
1791
|
-
* parse(source) { ... },
|
|
1792
|
-
* }
|
|
1252
|
+
* const kubb = createKubb({ config })
|
|
1253
|
+
*
|
|
1254
|
+
* kubb.hooks.on('kubb:plugin:end', (plugin, { duration }) => {
|
|
1255
|
+
* console.log(`${plugin.name} completed in ${duration}ms`)
|
|
1793
1256
|
* })
|
|
1257
|
+
*
|
|
1258
|
+
* const { files, failedPlugins } = await kubb.safeBuild()
|
|
1794
1259
|
* ```
|
|
1795
1260
|
*/
|
|
1796
|
-
function
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
if (generator.type === "react") return {
|
|
1803
|
-
version: "2",
|
|
1804
|
-
Operations() {
|
|
1805
|
-
return null;
|
|
1261
|
+
function createKubb(options) {
|
|
1262
|
+
const hooks = options.hooks ?? new AsyncEventEmitter();
|
|
1263
|
+
let setupResult;
|
|
1264
|
+
const instance = {
|
|
1265
|
+
get hooks() {
|
|
1266
|
+
return hooks;
|
|
1806
1267
|
},
|
|
1807
|
-
|
|
1808
|
-
return
|
|
1268
|
+
get sources() {
|
|
1269
|
+
return setupResult?.sources ?? /* @__PURE__ */ new Map();
|
|
1809
1270
|
},
|
|
1810
|
-
|
|
1811
|
-
return
|
|
1271
|
+
get driver() {
|
|
1272
|
+
return setupResult?.driver;
|
|
1812
1273
|
},
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
return {
|
|
1816
|
-
version: "2",
|
|
1817
|
-
async operations() {
|
|
1818
|
-
return [];
|
|
1274
|
+
get config() {
|
|
1275
|
+
return setupResult?.config;
|
|
1819
1276
|
},
|
|
1820
|
-
async
|
|
1821
|
-
|
|
1277
|
+
async setup() {
|
|
1278
|
+
setupResult = await setup({
|
|
1279
|
+
config: options.config,
|
|
1280
|
+
hooks
|
|
1281
|
+
});
|
|
1822
1282
|
},
|
|
1823
|
-
async
|
|
1824
|
-
|
|
1283
|
+
async build() {
|
|
1284
|
+
if (!setupResult) await instance.setup();
|
|
1285
|
+
return build(setupResult);
|
|
1825
1286
|
},
|
|
1826
|
-
|
|
1287
|
+
async safeBuild() {
|
|
1288
|
+
if (!setupResult) await instance.setup();
|
|
1289
|
+
return safeBuild(setupResult);
|
|
1290
|
+
}
|
|
1827
1291
|
};
|
|
1292
|
+
return instance;
|
|
1293
|
+
}
|
|
1294
|
+
//#endregion
|
|
1295
|
+
//#region src/createRenderer.ts
|
|
1296
|
+
/**
|
|
1297
|
+
* Creates a renderer factory for use in generator definitions.
|
|
1298
|
+
*
|
|
1299
|
+
* Wrap your renderer factory function with this helper to register it as the
|
|
1300
|
+
* renderer for a generator. Core will call this factory once per render cycle
|
|
1301
|
+
* to obtain a fresh renderer instance.
|
|
1302
|
+
*
|
|
1303
|
+
* @example
|
|
1304
|
+
* ```ts
|
|
1305
|
+
* // packages/renderer-jsx/src/index.ts
|
|
1306
|
+
* export const jsxRenderer = createRenderer(() => {
|
|
1307
|
+
* const runtime = new Runtime()
|
|
1308
|
+
* return {
|
|
1309
|
+
* async render(element) { await runtime.render(element) },
|
|
1310
|
+
* get files() { return runtime.nodes },
|
|
1311
|
+
* unmount(error) { runtime.unmount(error) },
|
|
1312
|
+
* }
|
|
1313
|
+
* })
|
|
1314
|
+
*
|
|
1315
|
+
* // packages/plugin-zod/src/generators/zodGenerator.tsx
|
|
1316
|
+
* import { jsxRenderer } from '@kubb/renderer-jsx'
|
|
1317
|
+
* export const zodGenerator = defineGenerator<PluginZod>({
|
|
1318
|
+
* name: 'zod',
|
|
1319
|
+
* renderer: jsxRenderer,
|
|
1320
|
+
* schema(node, options) { return <File ...>...</File> },
|
|
1321
|
+
* })
|
|
1322
|
+
* ```
|
|
1323
|
+
*/
|
|
1324
|
+
function createRenderer(factory) {
|
|
1325
|
+
return factory;
|
|
1326
|
+
}
|
|
1327
|
+
//#endregion
|
|
1328
|
+
//#region src/defineGenerator.ts
|
|
1329
|
+
/**
|
|
1330
|
+
* Defines a generator. Returns the object as-is with correct `this` typings.
|
|
1331
|
+
* `applyHookResult` handles renderer elements and `File[]` uniformly using
|
|
1332
|
+
* the generator's declared `renderer` factory.
|
|
1333
|
+
*/
|
|
1334
|
+
function defineGenerator(generator) {
|
|
1335
|
+
return generator;
|
|
1828
1336
|
}
|
|
1829
1337
|
//#endregion
|
|
1830
1338
|
//#region src/defineLogger.ts
|
|
1339
|
+
/**
|
|
1340
|
+
* Wraps a logger definition into a typed {@link Logger}.
|
|
1341
|
+
*
|
|
1342
|
+
* @example
|
|
1343
|
+
* export const myLogger = defineLogger({
|
|
1344
|
+
* name: 'my-logger',
|
|
1345
|
+
* install(context, options) {
|
|
1346
|
+
* context.on('kubb:info', (message) => console.log('ℹ', message))
|
|
1347
|
+
* context.on('kubb:error', (error) => console.error('✗', error.message))
|
|
1348
|
+
* },
|
|
1349
|
+
* })
|
|
1350
|
+
*/
|
|
1831
1351
|
function defineLogger(logger) {
|
|
1832
|
-
return
|
|
1352
|
+
return logger;
|
|
1833
1353
|
}
|
|
1834
1354
|
//#endregion
|
|
1835
|
-
//#region src/
|
|
1355
|
+
//#region src/defineParser.ts
|
|
1836
1356
|
/**
|
|
1837
|
-
*
|
|
1357
|
+
* Defines a parser with type safety.
|
|
1358
|
+
*
|
|
1359
|
+
* Use this function to create parsers that transform generated files to strings
|
|
1360
|
+
* based on their extension.
|
|
1361
|
+
*
|
|
1362
|
+
* @example
|
|
1363
|
+
* ```ts
|
|
1364
|
+
* import { defineParser } from '@kubb/core'
|
|
1365
|
+
*
|
|
1366
|
+
* export const jsonParser = defineParser({
|
|
1367
|
+
* name: 'json',
|
|
1368
|
+
* extNames: ['.json'],
|
|
1369
|
+
* parse(file) {
|
|
1370
|
+
* const { extractStringsFromNodes } = await import('@kubb/ast')
|
|
1371
|
+
* return file.sources.map((s) => extractStringsFromNodes(s.nodes ?? [])).join('\n')
|
|
1372
|
+
* },
|
|
1373
|
+
* })
|
|
1374
|
+
* ```
|
|
1838
1375
|
*/
|
|
1839
|
-
function
|
|
1840
|
-
return
|
|
1376
|
+
function defineParser(parser) {
|
|
1377
|
+
return parser;
|
|
1841
1378
|
}
|
|
1842
1379
|
//#endregion
|
|
1843
|
-
//#region src/PackageManager.ts
|
|
1844
|
-
var PackageManager = class PackageManager {
|
|
1845
|
-
static #cache = {};
|
|
1846
|
-
#cwd;
|
|
1847
|
-
constructor(workspace) {
|
|
1848
|
-
if (workspace) this.#cwd = workspace;
|
|
1849
|
-
}
|
|
1850
|
-
set workspace(workspace) {
|
|
1851
|
-
this.#cwd = workspace;
|
|
1852
|
-
}
|
|
1853
|
-
get workspace() {
|
|
1854
|
-
return this.#cwd;
|
|
1855
|
-
}
|
|
1856
|
-
normalizeDirectory(directory) {
|
|
1857
|
-
const lastChar = directory[directory.length - 1];
|
|
1858
|
-
if (lastChar && !PATH_SEPARATORS.includes(lastChar)) return `${directory}/`;
|
|
1859
|
-
return directory;
|
|
1860
|
-
}
|
|
1861
|
-
getLocation(path) {
|
|
1862
|
-
let location = path;
|
|
1863
|
-
if (this.#cwd) location = node_module.default.createRequire(this.normalizeDirectory(this.#cwd)).resolve(path);
|
|
1864
|
-
return location;
|
|
1865
|
-
}
|
|
1866
|
-
async import(path) {
|
|
1867
|
-
let location = this.getLocation(path);
|
|
1868
|
-
if (node_os.default.platform() === "win32") location = (0, node_url.pathToFileURL)(location).href;
|
|
1869
|
-
const module = await import(location);
|
|
1870
|
-
return module?.default ?? module;
|
|
1871
|
-
}
|
|
1872
|
-
async getPackageJSON() {
|
|
1873
|
-
const pkgPath = empathic_package.up({ cwd: this.#cwd });
|
|
1874
|
-
if (!pkgPath) return;
|
|
1875
|
-
const json = await read(pkgPath);
|
|
1876
|
-
return JSON.parse(json);
|
|
1877
|
-
}
|
|
1878
|
-
getPackageJSONSync() {
|
|
1879
|
-
const pkgPath = empathic_package.up({ cwd: this.#cwd });
|
|
1880
|
-
if (!pkgPath) return;
|
|
1881
|
-
const json = readSync(pkgPath);
|
|
1882
|
-
return JSON.parse(json);
|
|
1883
|
-
}
|
|
1884
|
-
static setVersion(dependency, version) {
|
|
1885
|
-
PackageManager.#cache[dependency] = version;
|
|
1886
|
-
}
|
|
1887
|
-
#match(packageJSON, dependency) {
|
|
1888
|
-
const dependencies = {
|
|
1889
|
-
...packageJSON.dependencies || {},
|
|
1890
|
-
...packageJSON.devDependencies || {}
|
|
1891
|
-
};
|
|
1892
|
-
if (typeof dependency === "string" && dependencies[dependency]) return dependencies[dependency];
|
|
1893
|
-
const matchedDependency = Object.keys(dependencies).find((dep) => dep.match(dependency));
|
|
1894
|
-
return matchedDependency ? dependencies[matchedDependency] : void 0;
|
|
1895
|
-
}
|
|
1896
|
-
async getVersion(dependency) {
|
|
1897
|
-
if (typeof dependency === "string" && PackageManager.#cache[dependency]) return PackageManager.#cache[dependency];
|
|
1898
|
-
const packageJSON = await this.getPackageJSON();
|
|
1899
|
-
if (!packageJSON) return;
|
|
1900
|
-
return this.#match(packageJSON, dependency);
|
|
1901
|
-
}
|
|
1902
|
-
getVersionSync(dependency) {
|
|
1903
|
-
if (typeof dependency === "string" && PackageManager.#cache[dependency]) return PackageManager.#cache[dependency];
|
|
1904
|
-
const packageJSON = this.getPackageJSONSync();
|
|
1905
|
-
if (!packageJSON) return;
|
|
1906
|
-
return this.#match(packageJSON, dependency);
|
|
1907
|
-
}
|
|
1908
|
-
async isValid(dependency, version) {
|
|
1909
|
-
const packageVersion = await this.getVersion(dependency);
|
|
1910
|
-
if (!packageVersion) return false;
|
|
1911
|
-
if (packageVersion === version) return true;
|
|
1912
|
-
const semVer = (0, semver.coerce)(packageVersion);
|
|
1913
|
-
if (!semVer) return false;
|
|
1914
|
-
return (0, semver.satisfies)(semVer, version);
|
|
1915
|
-
}
|
|
1916
|
-
isValidSync(dependency, version) {
|
|
1917
|
-
const packageVersion = this.getVersionSync(dependency);
|
|
1918
|
-
if (!packageVersion) return false;
|
|
1919
|
-
if (packageVersion === version) return true;
|
|
1920
|
-
const semVer = (0, semver.coerce)(packageVersion);
|
|
1921
|
-
if (!semVer) return false;
|
|
1922
|
-
return (0, semver.satisfies)(semVer, version);
|
|
1923
|
-
}
|
|
1924
|
-
};
|
|
1925
|
-
//#endregion
|
|
1926
1380
|
//#region src/storages/memoryStorage.ts
|
|
1927
1381
|
/**
|
|
1928
1382
|
* In-memory storage driver. Useful for testing and dry-run scenarios where
|
|
@@ -1941,7 +1395,7 @@ var PackageManager = class PackageManager {
|
|
|
1941
1395
|
* })
|
|
1942
1396
|
* ```
|
|
1943
1397
|
*/
|
|
1944
|
-
const memoryStorage =
|
|
1398
|
+
const memoryStorage = createStorage(() => {
|
|
1945
1399
|
const store = /* @__PURE__ */ new Map();
|
|
1946
1400
|
return {
|
|
1947
1401
|
name: "memory",
|
|
@@ -1971,463 +1425,29 @@ const memoryStorage = defineStorage(() => {
|
|
|
1971
1425
|
};
|
|
1972
1426
|
});
|
|
1973
1427
|
//#endregion
|
|
1974
|
-
//#region src/utils/FunctionParams.ts
|
|
1975
|
-
/**
|
|
1976
|
-
* @deprecated
|
|
1977
|
-
*/
|
|
1978
|
-
var FunctionParams = class FunctionParams {
|
|
1979
|
-
#items = [];
|
|
1980
|
-
get items() {
|
|
1981
|
-
return this.#items.flat();
|
|
1982
|
-
}
|
|
1983
|
-
add(item) {
|
|
1984
|
-
if (!item) return this;
|
|
1985
|
-
if (Array.isArray(item)) {
|
|
1986
|
-
item.filter((x) => x !== void 0).forEach((it) => {
|
|
1987
|
-
this.#items.push(it);
|
|
1988
|
-
});
|
|
1989
|
-
return this;
|
|
1990
|
-
}
|
|
1991
|
-
this.#items.push(item);
|
|
1992
|
-
return this;
|
|
1993
|
-
}
|
|
1994
|
-
static #orderItems(items) {
|
|
1995
|
-
return (0, remeda.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"]);
|
|
1996
|
-
}
|
|
1997
|
-
static #addParams(acc, item) {
|
|
1998
|
-
const { enabled = true, name, type, required = true, ...rest } = item;
|
|
1999
|
-
if (!enabled) return acc;
|
|
2000
|
-
if (!name) {
|
|
2001
|
-
acc.push(`${type}${rest.default ? ` = ${rest.default}` : ""}`);
|
|
2002
|
-
return acc;
|
|
2003
|
-
}
|
|
2004
|
-
const parameterName = name.startsWith("{") ? name : camelCase(name);
|
|
2005
|
-
if (type) if (required) acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ""}`);
|
|
2006
|
-
else acc.push(`${parameterName}?: ${type}`);
|
|
2007
|
-
else acc.push(`${parameterName}`);
|
|
2008
|
-
return acc;
|
|
2009
|
-
}
|
|
2010
|
-
static toObject(items) {
|
|
2011
|
-
let type = [];
|
|
2012
|
-
let name = [];
|
|
2013
|
-
const enabled = items.every((item) => item.enabled) ? items.at(0)?.enabled : true;
|
|
2014
|
-
const required = items.every((item) => item.required) ?? true;
|
|
2015
|
-
items.forEach((item) => {
|
|
2016
|
-
name = FunctionParams.#addParams(name, {
|
|
2017
|
-
...item,
|
|
2018
|
-
type: void 0
|
|
2019
|
-
});
|
|
2020
|
-
if (items.some((item) => item.type)) type = FunctionParams.#addParams(type, item);
|
|
2021
|
-
});
|
|
2022
|
-
return {
|
|
2023
|
-
name: `{ ${name.join(", ")} }`,
|
|
2024
|
-
type: type.length ? `{ ${type.join("; ")} }` : void 0,
|
|
2025
|
-
enabled,
|
|
2026
|
-
required
|
|
2027
|
-
};
|
|
2028
|
-
}
|
|
2029
|
-
toObject() {
|
|
2030
|
-
const items = FunctionParams.#orderItems(this.#items).flat();
|
|
2031
|
-
return FunctionParams.toObject(items);
|
|
2032
|
-
}
|
|
2033
|
-
static toString(items) {
|
|
2034
|
-
return FunctionParams.#orderItems(items).reduce((acc, item) => {
|
|
2035
|
-
if (Array.isArray(item)) {
|
|
2036
|
-
if (item.length <= 0) return acc;
|
|
2037
|
-
const subItems = FunctionParams.#orderItems(item);
|
|
2038
|
-
const objectItem = FunctionParams.toObject(subItems);
|
|
2039
|
-
return FunctionParams.#addParams(acc, objectItem);
|
|
2040
|
-
}
|
|
2041
|
-
return FunctionParams.#addParams(acc, item);
|
|
2042
|
-
}, []).join(", ");
|
|
2043
|
-
}
|
|
2044
|
-
toString() {
|
|
2045
|
-
const items = FunctionParams.#orderItems(this.#items);
|
|
2046
|
-
return FunctionParams.toString(items);
|
|
2047
|
-
}
|
|
2048
|
-
};
|
|
2049
|
-
//#endregion
|
|
2050
|
-
//#region src/utils/formatters.ts
|
|
2051
|
-
/**
|
|
2052
|
-
* Check if a formatter command is available in the system.
|
|
2053
|
-
*
|
|
2054
|
-
* @param formatter - The formatter to check ('biome', 'prettier', or 'oxfmt')
|
|
2055
|
-
* @returns Promise that resolves to true if the formatter is available, false otherwise
|
|
2056
|
-
*
|
|
2057
|
-
* @remarks
|
|
2058
|
-
* This function checks availability by running `<formatter> --version` command.
|
|
2059
|
-
* All supported formatters (biome, prettier, oxfmt) implement the --version flag.
|
|
2060
|
-
*/
|
|
2061
|
-
async function isFormatterAvailable(formatter) {
|
|
2062
|
-
try {
|
|
2063
|
-
await (0, tinyexec.x)(formatter, ["--version"], { nodeOptions: { stdio: "ignore" } });
|
|
2064
|
-
return true;
|
|
2065
|
-
} catch {
|
|
2066
|
-
return false;
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
/**
|
|
2070
|
-
* Detect which formatter is available in the system.
|
|
2071
|
-
*
|
|
2072
|
-
* @returns Promise that resolves to the first available formatter or undefined if none are found
|
|
2073
|
-
*
|
|
2074
|
-
* @remarks
|
|
2075
|
-
* Checks in order of preference: biome, oxfmt, prettier.
|
|
2076
|
-
* Uses the `--version` flag to detect if each formatter command is available.
|
|
2077
|
-
* This is a reliable method as all supported formatters implement this flag.
|
|
2078
|
-
*
|
|
2079
|
-
* @example
|
|
2080
|
-
* ```typescript
|
|
2081
|
-
* const formatter = await detectFormatter()
|
|
2082
|
-
* if (formatter) {
|
|
2083
|
-
* console.log(`Using ${formatter} for formatting`)
|
|
2084
|
-
* } else {
|
|
2085
|
-
* console.log('No formatter found')
|
|
2086
|
-
* }
|
|
2087
|
-
* ```
|
|
2088
|
-
*/
|
|
2089
|
-
async function detectFormatter() {
|
|
2090
|
-
for (const formatter of [
|
|
2091
|
-
"biome",
|
|
2092
|
-
"oxfmt",
|
|
2093
|
-
"prettier"
|
|
2094
|
-
]) if (await isFormatterAvailable(formatter)) return formatter;
|
|
2095
|
-
}
|
|
2096
|
-
//#endregion
|
|
2097
|
-
//#region src/utils/TreeNode.ts
|
|
2098
|
-
var TreeNode = class TreeNode {
|
|
2099
|
-
data;
|
|
2100
|
-
parent;
|
|
2101
|
-
children = [];
|
|
2102
|
-
#cachedLeaves = void 0;
|
|
2103
|
-
constructor(data, parent) {
|
|
2104
|
-
this.data = data;
|
|
2105
|
-
this.parent = parent;
|
|
2106
|
-
}
|
|
2107
|
-
addChild(data) {
|
|
2108
|
-
const child = new TreeNode(data, this);
|
|
2109
|
-
if (!this.children) this.children = [];
|
|
2110
|
-
this.children.push(child);
|
|
2111
|
-
return child;
|
|
2112
|
-
}
|
|
2113
|
-
get root() {
|
|
2114
|
-
if (!this.parent) return this;
|
|
2115
|
-
return this.parent.root;
|
|
2116
|
-
}
|
|
2117
|
-
get leaves() {
|
|
2118
|
-
if (!this.children || this.children.length === 0) return [this];
|
|
2119
|
-
if (this.#cachedLeaves) return this.#cachedLeaves;
|
|
2120
|
-
const leaves = [];
|
|
2121
|
-
for (const child of this.children) leaves.push(...child.leaves);
|
|
2122
|
-
this.#cachedLeaves = leaves;
|
|
2123
|
-
return leaves;
|
|
2124
|
-
}
|
|
2125
|
-
forEach(callback) {
|
|
2126
|
-
if (typeof callback !== "function") throw new TypeError("forEach() callback must be a function");
|
|
2127
|
-
callback(this);
|
|
2128
|
-
for (const child of this.children) child.forEach(callback);
|
|
2129
|
-
return this;
|
|
2130
|
-
}
|
|
2131
|
-
findDeep(predicate) {
|
|
2132
|
-
if (typeof predicate !== "function") throw new TypeError("find() predicate must be a function");
|
|
2133
|
-
return this.leaves.find(predicate);
|
|
2134
|
-
}
|
|
2135
|
-
forEachDeep(callback) {
|
|
2136
|
-
if (typeof callback !== "function") throw new TypeError("forEach() callback must be a function");
|
|
2137
|
-
this.leaves.forEach(callback);
|
|
2138
|
-
}
|
|
2139
|
-
filterDeep(callback) {
|
|
2140
|
-
if (typeof callback !== "function") throw new TypeError("filter() callback must be a function");
|
|
2141
|
-
return this.leaves.filter(callback);
|
|
2142
|
-
}
|
|
2143
|
-
mapDeep(callback) {
|
|
2144
|
-
if (typeof callback !== "function") throw new TypeError("map() callback must be a function");
|
|
2145
|
-
return this.leaves.map(callback);
|
|
2146
|
-
}
|
|
2147
|
-
static build(files, root) {
|
|
2148
|
-
try {
|
|
2149
|
-
const filteredTree = buildDirectoryTree(files, root);
|
|
2150
|
-
if (!filteredTree) return null;
|
|
2151
|
-
const treeNode = new TreeNode({
|
|
2152
|
-
name: filteredTree.name,
|
|
2153
|
-
path: filteredTree.path,
|
|
2154
|
-
file: filteredTree.file,
|
|
2155
|
-
type: getMode(filteredTree.path)
|
|
2156
|
-
});
|
|
2157
|
-
const recurse = (node, item) => {
|
|
2158
|
-
const subNode = node.addChild({
|
|
2159
|
-
name: item.name,
|
|
2160
|
-
path: item.path,
|
|
2161
|
-
file: item.file,
|
|
2162
|
-
type: getMode(item.path)
|
|
2163
|
-
});
|
|
2164
|
-
if (item.children?.length) item.children?.forEach((child) => {
|
|
2165
|
-
recurse(subNode, child);
|
|
2166
|
-
});
|
|
2167
|
-
};
|
|
2168
|
-
filteredTree.children?.forEach((child) => {
|
|
2169
|
-
recurse(treeNode, child);
|
|
2170
|
-
});
|
|
2171
|
-
return treeNode;
|
|
2172
|
-
} catch (error) {
|
|
2173
|
-
throw new Error("Something went wrong with creating barrel files with the TreeNode class", { cause: error });
|
|
2174
|
-
}
|
|
2175
|
-
}
|
|
2176
|
-
};
|
|
2177
|
-
const normalizePath = (p) => p.replaceAll("\\", "/");
|
|
2178
|
-
function buildDirectoryTree(files, rootFolder = "") {
|
|
2179
|
-
const normalizedRootFolder = normalizePath(rootFolder);
|
|
2180
|
-
const rootPrefix = normalizedRootFolder.endsWith("/") ? normalizedRootFolder : `${normalizedRootFolder}/`;
|
|
2181
|
-
const filteredFiles = files.filter((file) => {
|
|
2182
|
-
const normalizedFilePath = normalizePath(file.path);
|
|
2183
|
-
return rootFolder ? normalizedFilePath.startsWith(rootPrefix) && !normalizedFilePath.endsWith(".json") : !normalizedFilePath.endsWith(".json");
|
|
2184
|
-
});
|
|
2185
|
-
if (filteredFiles.length === 0) return null;
|
|
2186
|
-
const root = {
|
|
2187
|
-
name: rootFolder || "",
|
|
2188
|
-
path: rootFolder || "",
|
|
2189
|
-
children: []
|
|
2190
|
-
};
|
|
2191
|
-
filteredFiles.forEach((file) => {
|
|
2192
|
-
const parts = file.path.slice(rootFolder.length).split("/").filter(Boolean);
|
|
2193
|
-
let currentLevel = root.children;
|
|
2194
|
-
let currentPath = normalizePath(rootFolder);
|
|
2195
|
-
parts.forEach((part, index) => {
|
|
2196
|
-
currentPath = node_path.default.posix.join(currentPath, part);
|
|
2197
|
-
let existingNode = currentLevel.find((node) => node.name === part);
|
|
2198
|
-
if (!existingNode) {
|
|
2199
|
-
if (index === parts.length - 1) existingNode = {
|
|
2200
|
-
name: part,
|
|
2201
|
-
file,
|
|
2202
|
-
path: currentPath
|
|
2203
|
-
};
|
|
2204
|
-
else existingNode = {
|
|
2205
|
-
name: part,
|
|
2206
|
-
path: currentPath,
|
|
2207
|
-
children: []
|
|
2208
|
-
};
|
|
2209
|
-
currentLevel.push(existingNode);
|
|
2210
|
-
}
|
|
2211
|
-
if (!existingNode.file) currentLevel = existingNode.children;
|
|
2212
|
-
});
|
|
2213
|
-
});
|
|
2214
|
-
return root;
|
|
2215
|
-
}
|
|
2216
|
-
//#endregion
|
|
2217
|
-
//#region src/BarrelManager.ts
|
|
2218
|
-
/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */
|
|
2219
|
-
var BarrelManager = class {
|
|
2220
|
-
getFiles({ files: generatedFiles, root }) {
|
|
2221
|
-
const cachedFiles = /* @__PURE__ */ new Map();
|
|
2222
|
-
TreeNode.build(generatedFiles, root)?.forEach((treeNode) => {
|
|
2223
|
-
if (!treeNode || !treeNode.children || !treeNode.parent?.data.path) return;
|
|
2224
|
-
const barrelFile = {
|
|
2225
|
-
path: (0, node_path.join)(treeNode.parent?.data.path, "index.ts"),
|
|
2226
|
-
baseName: "index.ts",
|
|
2227
|
-
exports: [],
|
|
2228
|
-
imports: [],
|
|
2229
|
-
sources: []
|
|
2230
|
-
};
|
|
2231
|
-
const previousBarrelFile = cachedFiles.get(barrelFile.path);
|
|
2232
|
-
treeNode.leaves.forEach((item) => {
|
|
2233
|
-
if (!item.data.name) return;
|
|
2234
|
-
(item.data.file?.sources || []).forEach((source) => {
|
|
2235
|
-
if (!item.data.file?.path || !source.isIndexable || !source.name) return;
|
|
2236
|
-
if (previousBarrelFile?.sources.some((item) => item.name === source.name && item.isTypeOnly === source.isTypeOnly)) return;
|
|
2237
|
-
barrelFile.exports.push({
|
|
2238
|
-
name: [source.name],
|
|
2239
|
-
path: getRelativePath(treeNode.parent?.data.path, item.data.path),
|
|
2240
|
-
isTypeOnly: source.isTypeOnly
|
|
2241
|
-
});
|
|
2242
|
-
barrelFile.sources.push({
|
|
2243
|
-
name: source.name,
|
|
2244
|
-
isTypeOnly: source.isTypeOnly,
|
|
2245
|
-
value: "",
|
|
2246
|
-
isExportable: false,
|
|
2247
|
-
isIndexable: false
|
|
2248
|
-
});
|
|
2249
|
-
});
|
|
2250
|
-
});
|
|
2251
|
-
if (previousBarrelFile) {
|
|
2252
|
-
previousBarrelFile.sources.push(...barrelFile.sources);
|
|
2253
|
-
previousBarrelFile.exports?.push(...barrelFile.exports || []);
|
|
2254
|
-
} else cachedFiles.set(barrelFile.path, barrelFile);
|
|
2255
|
-
});
|
|
2256
|
-
return [...cachedFiles.values()];
|
|
2257
|
-
}
|
|
2258
|
-
};
|
|
2259
|
-
//#endregion
|
|
2260
|
-
//#region src/utils/getBarrelFiles.ts
|
|
2261
|
-
function trimExtName(text) {
|
|
2262
|
-
const dotIndex = text.lastIndexOf(".");
|
|
2263
|
-
if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
|
|
2264
|
-
return text;
|
|
2265
|
-
}
|
|
2266
|
-
async function getBarrelFiles(files, { type, meta = {}, root, output }) {
|
|
2267
|
-
if (!type || type === "propagate") return [];
|
|
2268
|
-
const barrelManager = new BarrelManager();
|
|
2269
|
-
const pathToBuildFrom = (0, node_path.join)(root, output.path);
|
|
2270
|
-
if (trimExtName(pathToBuildFrom).endsWith("index")) return [];
|
|
2271
|
-
const barrelFiles = barrelManager.getFiles({
|
|
2272
|
-
files,
|
|
2273
|
-
root: pathToBuildFrom,
|
|
2274
|
-
meta
|
|
2275
|
-
});
|
|
2276
|
-
if (type === "all") return barrelFiles.map((file) => {
|
|
2277
|
-
return {
|
|
2278
|
-
...file,
|
|
2279
|
-
exports: file.exports?.map((exportItem) => {
|
|
2280
|
-
return {
|
|
2281
|
-
...exportItem,
|
|
2282
|
-
name: void 0
|
|
2283
|
-
};
|
|
2284
|
-
})
|
|
2285
|
-
};
|
|
2286
|
-
});
|
|
2287
|
-
return barrelFiles.map((indexFile) => {
|
|
2288
|
-
return {
|
|
2289
|
-
...indexFile,
|
|
2290
|
-
meta
|
|
2291
|
-
};
|
|
2292
|
-
});
|
|
2293
|
-
}
|
|
2294
|
-
//#endregion
|
|
2295
|
-
//#region src/utils/getPlugins.ts
|
|
2296
|
-
function isJSONPlugins(plugins) {
|
|
2297
|
-
return Array.isArray(plugins) && plugins.some((plugin) => Array.isArray(plugin) && typeof plugin[0] === "string");
|
|
2298
|
-
}
|
|
2299
|
-
function isObjectPlugins(plugins) {
|
|
2300
|
-
return plugins instanceof Object && !Array.isArray(plugins);
|
|
2301
|
-
}
|
|
2302
|
-
function getPlugins(plugins) {
|
|
2303
|
-
if (isObjectPlugins(plugins)) throw new Error("Object plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json");
|
|
2304
|
-
if (isJSONPlugins(plugins)) throw new Error("JSON plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json");
|
|
2305
|
-
return Promise.resolve(plugins);
|
|
2306
|
-
}
|
|
2307
|
-
//#endregion
|
|
2308
|
-
//#region src/utils/getConfigs.ts
|
|
2309
|
-
/**
|
|
2310
|
-
* Converting UserConfig to Config Array without a change in the object beside the JSON convert.
|
|
2311
|
-
*/
|
|
2312
|
-
async function getConfigs(config, args) {
|
|
2313
|
-
let userConfigs = await (typeof config === "function" ? Promise.resolve(config(args)) : Promise.resolve(config));
|
|
2314
|
-
if (!Array.isArray(userConfigs)) userConfigs = [userConfigs];
|
|
2315
|
-
const results = [];
|
|
2316
|
-
for (const item of userConfigs) {
|
|
2317
|
-
const plugins = item.plugins ? await getPlugins(item.plugins) : void 0;
|
|
2318
|
-
results.push({
|
|
2319
|
-
...item,
|
|
2320
|
-
plugins
|
|
2321
|
-
});
|
|
2322
|
-
}
|
|
2323
|
-
return results;
|
|
2324
|
-
}
|
|
2325
|
-
//#endregion
|
|
2326
|
-
//#region src/utils/linters.ts
|
|
2327
|
-
async function isLinterAvailable(linter) {
|
|
2328
|
-
try {
|
|
2329
|
-
await (0, tinyexec.x)(linter, ["--version"], { nodeOptions: { stdio: "ignore" } });
|
|
2330
|
-
return true;
|
|
2331
|
-
} catch {
|
|
2332
|
-
return false;
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
async function detectLinter() {
|
|
2336
|
-
for (const linter of [
|
|
2337
|
-
"biome",
|
|
2338
|
-
"oxlint",
|
|
2339
|
-
"eslint"
|
|
2340
|
-
]) if (await isLinterAvailable(linter)) return linter;
|
|
2341
|
-
}
|
|
2342
|
-
//#endregion
|
|
2343
|
-
//#region src/utils/resolveOptions.ts
|
|
2344
|
-
function matchesOperationPattern(node, type, pattern) {
|
|
2345
|
-
switch (type) {
|
|
2346
|
-
case "tag": return node.tags.some((tag) => !!tag.match(pattern));
|
|
2347
|
-
case "operationId": return !!node.operationId.match(pattern);
|
|
2348
|
-
case "path": return !!node.path.match(pattern);
|
|
2349
|
-
case "method": return !!node.method.toLowerCase().match(pattern);
|
|
2350
|
-
default: return false;
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
function matchesSchemaPattern(node, type, pattern) {
|
|
2354
|
-
switch (type) {
|
|
2355
|
-
case "schemaName": return node.name ? !!node.name.match(pattern) : false;
|
|
2356
|
-
default: return null;
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
/**
|
|
2360
|
-
* Resolves the effective plugin options for a given AST node by applying
|
|
2361
|
-
* `exclude`, `include`, and `override` rules from the plugin configuration.
|
|
2362
|
-
*
|
|
2363
|
-
* Returns `null` when the node is excluded or not matched by `include`.
|
|
2364
|
-
* Returns the merged options (base options merged with any matching `override`) otherwise.
|
|
2365
|
-
*
|
|
2366
|
-
* Supported filter types for `OperationNode`: `tag`, `operationId`, `path`, `method`.
|
|
2367
|
-
* Supported filter types for `SchemaNode`: `schemaName`.
|
|
2368
|
-
*
|
|
2369
|
-
* @example
|
|
2370
|
-
* const resolved = resolveOptions(operationNode, { options, exclude, include, override })
|
|
2371
|
-
* if (!resolved) return // excluded
|
|
2372
|
-
*/
|
|
2373
|
-
function resolveOptions(node, { options, exclude = [], include, override = [] }) {
|
|
2374
|
-
if ((0, _kubb_ast.isOperationNode)(node)) {
|
|
2375
|
-
if (exclude.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) return null;
|
|
2376
|
-
if (include && !include.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) return null;
|
|
2377
|
-
const overrideOptions = override.find(({ type, pattern }) => matchesOperationPattern(node, type, pattern))?.options;
|
|
2378
|
-
return {
|
|
2379
|
-
...options,
|
|
2380
|
-
...overrideOptions
|
|
2381
|
-
};
|
|
2382
|
-
}
|
|
2383
|
-
if ((0, _kubb_ast.isSchemaNode)(node)) {
|
|
2384
|
-
if (exclude.some(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)) return null;
|
|
2385
|
-
if (include) {
|
|
2386
|
-
const applicable = include.map(({ type, pattern }) => matchesSchemaPattern(node, type, pattern)).filter((r) => r !== null);
|
|
2387
|
-
if (applicable.length > 0 && !applicable.includes(true)) return null;
|
|
2388
|
-
}
|
|
2389
|
-
const overrideOptions = override.find(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)?.options;
|
|
2390
|
-
return {
|
|
2391
|
-
...options,
|
|
2392
|
-
...overrideOptions
|
|
2393
|
-
};
|
|
2394
|
-
}
|
|
2395
|
-
return options;
|
|
2396
|
-
}
|
|
2397
|
-
//#endregion
|
|
2398
1428
|
exports.AsyncEventEmitter = AsyncEventEmitter;
|
|
2399
|
-
exports.
|
|
2400
|
-
exports.
|
|
2401
|
-
exports.
|
|
2402
|
-
exports.PromiseManager = PromiseManager;
|
|
1429
|
+
exports.FileManager = require_PluginDriver.FileManager;
|
|
1430
|
+
exports.FileProcessor = FileProcessor;
|
|
1431
|
+
exports.PluginDriver = require_PluginDriver.PluginDriver;
|
|
2403
1432
|
exports.URLPath = URLPath;
|
|
2404
|
-
exports
|
|
2405
|
-
exports.default = build;
|
|
2406
|
-
exports.defineAdapter = defineAdapter;
|
|
2407
|
-
exports.defineConfig = defineConfig;
|
|
2408
|
-
exports.defineGenerator = defineGenerator;
|
|
2409
|
-
exports.defineLogger = defineLogger;
|
|
2410
|
-
exports.definePlugin = definePlugin;
|
|
2411
|
-
Object.defineProperty(exports, "definePrinter", {
|
|
1433
|
+
Object.defineProperty(exports, "ast", {
|
|
2412
1434
|
enumerable: true,
|
|
2413
1435
|
get: function() {
|
|
2414
|
-
return _kubb_ast
|
|
1436
|
+
return _kubb_ast;
|
|
2415
1437
|
}
|
|
2416
1438
|
});
|
|
2417
|
-
exports.
|
|
2418
|
-
exports.
|
|
2419
|
-
exports.
|
|
2420
|
-
exports.
|
|
1439
|
+
exports.createAdapter = createAdapter;
|
|
1440
|
+
exports.createKubb = createKubb;
|
|
1441
|
+
exports.createRenderer = createRenderer;
|
|
1442
|
+
exports.createStorage = createStorage;
|
|
1443
|
+
exports.defineGenerator = defineGenerator;
|
|
1444
|
+
exports.defineLogger = defineLogger;
|
|
1445
|
+
exports.defineParser = defineParser;
|
|
1446
|
+
exports.definePlugin = require_PluginDriver.definePlugin;
|
|
1447
|
+
exports.defineResolver = require_PluginDriver.defineResolver;
|
|
2421
1448
|
exports.fsStorage = fsStorage;
|
|
2422
|
-
exports.getBarrelFiles = getBarrelFiles;
|
|
2423
|
-
exports.getConfigs = getConfigs;
|
|
2424
|
-
exports.getMode = getMode;
|
|
2425
1449
|
exports.isInputPath = isInputPath;
|
|
2426
|
-
exports.
|
|
2427
|
-
exports.logLevel = logLevel;
|
|
1450
|
+
exports.logLevel = require_PluginDriver.logLevel;
|
|
2428
1451
|
exports.memoryStorage = memoryStorage;
|
|
2429
|
-
exports.resolveOptions = resolveOptions;
|
|
2430
|
-
exports.safeBuild = safeBuild;
|
|
2431
|
-
exports.setup = setup;
|
|
2432
1452
|
|
|
2433
1453
|
//# sourceMappingURL=index.cjs.map
|