@kubb/cli 5.0.6 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/dist/{Telemetry-Fiymfxez.js → Telemetry-BCTY-Nzq.js} +3 -49
- package/dist/Telemetry-BCTY-Nzq.js.map +1 -0
- package/dist/{Telemetry-D-Jpt27O.cjs → Telemetry-DKfJQxnC.cjs} +8 -60
- package/dist/Telemetry-DKfJQxnC.cjs.map +1 -0
- package/dist/constants-CdxpgX3_.cjs +115 -0
- package/dist/constants-CdxpgX3_.cjs.map +1 -0
- package/dist/constants-DHRspBTo.js +92 -0
- package/dist/constants-DHRspBTo.js.map +1 -0
- package/dist/env-DHaFBZTX.cjs +82 -0
- package/dist/env-DHaFBZTX.cjs.map +1 -0
- package/dist/env-DqPKEL59.js +59 -0
- package/dist/env-DqPKEL59.js.map +1 -0
- package/dist/{errors-CZtH2dKk.cjs → errors-C-wEou02.cjs} +2 -19
- package/dist/errors-C-wEou02.cjs.map +1 -0
- package/dist/errors-C8yNfV7w.js +20 -0
- package/dist/errors-C8yNfV7w.js.map +1 -0
- package/dist/{generate-DcEkxx4R.cjs → generate-Btnbf2_0.cjs} +9 -6
- package/dist/generate-Btnbf2_0.cjs.map +1 -0
- package/dist/{generate-FtWB7SiZ.js → generate-PT8_WDJZ.js} +9 -6
- package/dist/generate-PT8_WDJZ.js.map +1 -0
- package/dist/index.cjs +14 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +15 -10
- package/dist/index.js.map +1 -1
- package/dist/{init-ClG_bvAo.cjs → init-BwuaIvJr.cjs} +3 -3
- package/dist/{init-ClG_bvAo.cjs.map → init-BwuaIvJr.cjs.map} +1 -1
- package/dist/{init-B5G3LIla.js → init-dkS7T-wO.js} +3 -3
- package/dist/{init-B5G3LIla.js.map → init-dkS7T-wO.js.map} +1 -1
- package/dist/{mcp-DOHymcpS.js → mcp-B-GxGgVr.js} +8 -10
- package/dist/mcp-B-GxGgVr.js.map +1 -0
- package/dist/{mcp-ESVy9meL.cjs → mcp-B3B-rE7W.cjs} +8 -10
- package/dist/mcp-B3B-rE7W.cjs.map +1 -0
- package/dist/output-B2V2MN_C.cjs +137 -0
- package/dist/output-B2V2MN_C.cjs.map +1 -0
- package/dist/output-LZvrgF3z.js +89 -0
- package/dist/output-LZvrgF3z.js.map +1 -0
- package/dist/package-CrOAfe1h.js +6 -0
- package/dist/package-CrOAfe1h.js.map +1 -0
- package/dist/{package-CPbMhmPi.cjs → package-Dzjrfs0O.cjs} +2 -2
- package/dist/package-Dzjrfs0O.cjs.map +1 -0
- package/dist/{run-DSgLksGj.js → run-BzvsJ0Ek.js} +80 -112
- package/dist/run-BzvsJ0Ek.js.map +1 -0
- package/dist/run-CHfPmjaA.cjs +283 -0
- package/dist/run-CHfPmjaA.cjs.map +1 -0
- package/dist/{run-FPqeAEF4.cjs → run-DRBqVXX0.cjs} +93 -125
- package/dist/run-DRBqVXX0.cjs.map +1 -0
- package/dist/{run-ChKPZlIB.js → run-DReizVV9.js} +15 -4
- package/dist/run-DReizVV9.js.map +1 -0
- package/dist/run-DUY0lV8l.js +499 -0
- package/dist/run-DUY0lV8l.js.map +1 -0
- package/dist/run-DXPXPj4B.js +281 -0
- package/dist/run-DXPXPj4B.js.map +1 -0
- package/dist/{run-DCfdTu52.js → run-DvRhuqUM.js} +11 -4
- package/dist/run-DvRhuqUM.js.map +1 -0
- package/dist/run-Wkl7oK6Q.cjs +502 -0
- package/dist/run-Wkl7oK6Q.cjs.map +1 -0
- package/dist/{run-BV2tMjuz.cjs → run-aIkuYiQ6.cjs} +15 -4
- package/dist/run-aIkuYiQ6.cjs.map +1 -0
- package/dist/{run-Cs5FunVC.cjs → run-y7oTgJI3.cjs} +11 -4
- package/dist/run-y7oTgJI3.cjs.map +1 -0
- package/dist/studio-DKv2YLJZ.js +77 -0
- package/dist/studio-DKv2YLJZ.js.map +1 -0
- package/dist/studio-PDMxqFN0.cjs +76 -0
- package/dist/studio-PDMxqFN0.cjs.map +1 -0
- package/dist/{run-DzVVS0FV.cjs → utils-B0SrWoNh.cjs} +303 -323
- package/dist/utils-B0SrWoNh.cjs.map +1 -0
- package/dist/{run-D_TXufIV.js → utils-CzoNURwq.js} +274 -364
- package/dist/utils-CzoNURwq.js.map +1 -0
- package/dist/{validate-1sZ8wo6V.cjs → validate-BcB0tFQ6.cjs} +8 -13
- package/dist/validate-BcB0tFQ6.cjs.map +1 -0
- package/dist/{validate-DXT2hYwJ.js → validate-QpkCbIFJ.js} +8 -13
- package/dist/validate-QpkCbIFJ.js.map +1 -0
- package/package.json +15 -9
- package/dist/Telemetry-D-Jpt27O.cjs.map +0 -1
- package/dist/Telemetry-Fiymfxez.js.map +0 -1
- package/dist/errors-CMvLO2NE.js +0 -31
- package/dist/errors-CMvLO2NE.js.map +0 -1
- package/dist/errors-CZtH2dKk.cjs.map +0 -1
- package/dist/generate-DcEkxx4R.cjs.map +0 -1
- package/dist/generate-FtWB7SiZ.js.map +0 -1
- package/dist/mcp-DOHymcpS.js.map +0 -1
- package/dist/mcp-ESVy9meL.cjs.map +0 -1
- package/dist/package-BEDssgn1.js +0 -6
- package/dist/package-BEDssgn1.js.map +0 -1
- package/dist/package-CPbMhmPi.cjs.map +0 -1
- package/dist/run-BV2tMjuz.cjs.map +0 -1
- package/dist/run-ChKPZlIB.js.map +0 -1
- package/dist/run-Cs5FunVC.cjs.map +0 -1
- package/dist/run-DCfdTu52.js.map +0 -1
- package/dist/run-DSgLksGj.js.map +0 -1
- package/dist/run-D_TXufIV.js.map +0 -1
- package/dist/run-DzVVS0FV.cjs.map +0 -1
- package/dist/run-FPqeAEF4.cjs.map +0 -1
- package/dist/tools-DH1a7ZJH.js +0 -152
- package/dist/tools-DH1a7ZJH.js.map +0 -1
- package/dist/tools-bwKAf_r-.cjs +0 -175
- package/dist/tools-bwKAf_r-.cjs.map +0 -1
- package/dist/validate-1sZ8wo6V.cjs.map +0 -1
- package/dist/validate-DXT2hYwJ.js.map +0 -1
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
|
|
2
|
+
const require_errors = require("./errors-C-wEou02.cjs");
|
|
3
|
+
const require_Telemetry = require("./Telemetry-DKfJQxnC.cjs");
|
|
4
|
+
const require_utils = require("./utils-B0SrWoNh.cjs");
|
|
5
|
+
const require_package = require("./package-Dzjrfs0O.cjs");
|
|
6
|
+
const require_output = require("./output-B2V2MN_C.cjs");
|
|
7
|
+
let node_util = require("node:util");
|
|
8
|
+
let node_crypto = require("node:crypto");
|
|
9
|
+
let node_process = require("node:process");
|
|
10
|
+
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
11
|
+
let node_path = require("node:path");
|
|
12
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
13
|
+
let node_fs = require("node:fs");
|
|
14
|
+
let _kubb_core = require("@kubb/core");
|
|
15
|
+
//#region src/runners/generate/run.ts
|
|
16
|
+
/**
|
|
17
|
+
* Runs one formatter or linter pass over the output directory. Returns the failure instead of
|
|
18
|
+
* throwing, so the caller can turn it into a coded diagnostic. Failures never render here:
|
|
19
|
+
* the caller emits them through `Diagnostics.emit`, like every other diagnostic.
|
|
20
|
+
*/
|
|
21
|
+
async function runToolPass({ toolValue, tool, outputPath, logLevel, hooks, onStart, onEnd }) {
|
|
22
|
+
await onStart();
|
|
23
|
+
let resolvedTool = toolValue;
|
|
24
|
+
if (resolvedTool === "auto") {
|
|
25
|
+
const detected = await tool.detect();
|
|
26
|
+
if (!detected) await hooks.callHook("kubb:warn", { message: tool.noToolMessage });
|
|
27
|
+
else {
|
|
28
|
+
resolvedTool = detected;
|
|
29
|
+
await hooks.callHook("kubb:info", { message: `Auto-detected ${tool.label}: ${(0, node_util.styleText)("dim", resolvedTool)}` });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let toolError = null;
|
|
33
|
+
if (resolvedTool && resolvedTool !== "auto" && resolvedTool in tool.map && (0, node_fs.existsSync)(outputPath)) {
|
|
34
|
+
const toolConfig = tool.map[resolvedTool];
|
|
35
|
+
const successMessage = [
|
|
36
|
+
`${tool.successPrefix} with ${(0, node_util.styleText)("dim", resolvedTool)}`,
|
|
37
|
+
logLevel >= _kubb_core.logLevel.info ? `on ${(0, node_util.styleText)("dim", outputPath)}` : void 0,
|
|
38
|
+
"successfully"
|
|
39
|
+
].filter(Boolean).join(" ");
|
|
40
|
+
try {
|
|
41
|
+
const hookId = (0, node_crypto.randomUUID)();
|
|
42
|
+
const hookArgs = toolConfig.args(outputPath);
|
|
43
|
+
const commandWithArgs = [toolConfig.command, ...hookArgs].join(" ");
|
|
44
|
+
await hooks.callHook("kubb:hook:start", {
|
|
45
|
+
id: hookId,
|
|
46
|
+
command: toolConfig.command,
|
|
47
|
+
args: hookArgs
|
|
48
|
+
});
|
|
49
|
+
const result = await require_utils.runHook({
|
|
50
|
+
id: hookId,
|
|
51
|
+
command: toolConfig.command,
|
|
52
|
+
args: hookArgs,
|
|
53
|
+
commandWithArgs,
|
|
54
|
+
hooks
|
|
55
|
+
});
|
|
56
|
+
if (result.success) await hooks.callHook("kubb:success", { message: successMessage });
|
|
57
|
+
else toolError = result.error ?? new Error(toolConfig.errorMessage);
|
|
58
|
+
} catch (caughtError) {
|
|
59
|
+
toolError = require_errors.toError(caughtError);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
await onEnd();
|
|
63
|
+
return toolError;
|
|
64
|
+
}
|
|
65
|
+
async function generate(options) {
|
|
66
|
+
const { input, hooks, logLevel, dryRun = false } = options;
|
|
67
|
+
const hrStart = node_process.default.hrtime();
|
|
68
|
+
const inputPath = input ?? (typeof options.config.input === "string" ? options.config.input : void 0);
|
|
69
|
+
const config = {
|
|
70
|
+
...options.config,
|
|
71
|
+
input: input ?? options.config.input,
|
|
72
|
+
storage: dryRun ? (0, _kubb_core.memoryStorage)() : options.config.storage,
|
|
73
|
+
output: dryRun ? {
|
|
74
|
+
...options.config.output,
|
|
75
|
+
format: false,
|
|
76
|
+
lint: false,
|
|
77
|
+
postGenerate: []
|
|
78
|
+
} : options.config.output
|
|
79
|
+
};
|
|
80
|
+
const processOutput = async ({ config: resolvedConfig, outputPath }) => {
|
|
81
|
+
if (dryRun) return [];
|
|
82
|
+
const outputDiagnostics = [];
|
|
83
|
+
const reportOutputFailure = async (code, label, error) => {
|
|
84
|
+
const diagnostic = outputDiagnostic(code, label, error);
|
|
85
|
+
outputDiagnostics.push(diagnostic);
|
|
86
|
+
await _kubb_core.Diagnostics.emit(hooks, diagnostic);
|
|
87
|
+
};
|
|
88
|
+
const toolPasses = [{
|
|
89
|
+
value: resolvedConfig.output.format,
|
|
90
|
+
code: _kubb_core.Diagnostics.code.formatFailed,
|
|
91
|
+
tool: {
|
|
92
|
+
label: "formatter",
|
|
93
|
+
map: require_utils.formatters,
|
|
94
|
+
detect: () => require_utils.detectTool(require_utils.FORMATTER_PREFERENCE),
|
|
95
|
+
successPrefix: "Formatting",
|
|
96
|
+
noToolMessage: `No formatter found (${require_utils.FORMATTER_PREFERENCE.join(", ")}). Skipping formatting.`
|
|
97
|
+
},
|
|
98
|
+
onStart: () => hooks.callHook("kubb:format:start"),
|
|
99
|
+
onEnd: () => hooks.callHook("kubb:format:end")
|
|
100
|
+
}, {
|
|
101
|
+
value: resolvedConfig.output.lint,
|
|
102
|
+
code: _kubb_core.Diagnostics.code.lintFailed,
|
|
103
|
+
tool: {
|
|
104
|
+
label: "linter",
|
|
105
|
+
map: require_utils.linters,
|
|
106
|
+
detect: () => require_utils.detectTool(require_utils.LINTER_PREFERENCE),
|
|
107
|
+
successPrefix: "Linting",
|
|
108
|
+
noToolMessage: `No linter found (${require_utils.LINTER_PREFERENCE.join(", ")}). Skipping linting.`
|
|
109
|
+
},
|
|
110
|
+
onStart: () => hooks.callHook("kubb:lint:start"),
|
|
111
|
+
onEnd: () => hooks.callHook("kubb:lint:end")
|
|
112
|
+
}];
|
|
113
|
+
for (const pass of toolPasses) {
|
|
114
|
+
if (!pass.value) continue;
|
|
115
|
+
const error = await runToolPass({
|
|
116
|
+
toolValue: pass.value,
|
|
117
|
+
tool: pass.tool,
|
|
118
|
+
onStart: pass.onStart,
|
|
119
|
+
onEnd: pass.onEnd,
|
|
120
|
+
outputPath,
|
|
121
|
+
logLevel,
|
|
122
|
+
hooks
|
|
123
|
+
});
|
|
124
|
+
if (error) await reportOutputFailure(pass.code, pass.tool.label, error);
|
|
125
|
+
}
|
|
126
|
+
if (resolvedConfig.output.postGenerate?.length) {
|
|
127
|
+
await hooks.callHook("kubb:hooks:start");
|
|
128
|
+
const hookResults = await require_utils.runPostGenerate({
|
|
129
|
+
commands: resolvedConfig.output.postGenerate,
|
|
130
|
+
hooks
|
|
131
|
+
});
|
|
132
|
+
for (const hookResult of hookResults) {
|
|
133
|
+
if (hookResult.success) continue;
|
|
134
|
+
await reportOutputFailure(_kubb_core.Diagnostics.code.postGenerateFailed, "Post-generate command", hookResult.error ?? /* @__PURE__ */ new Error("Post-generate command failed"));
|
|
135
|
+
}
|
|
136
|
+
await hooks.callHook("kubb:hooks:end");
|
|
137
|
+
}
|
|
138
|
+
return outputDiagnostics;
|
|
139
|
+
};
|
|
140
|
+
hooks.hook("kubb:generation:end", ({ status }) => {
|
|
141
|
+
if (status === "success") return hooks.callHook("kubb:success", {
|
|
142
|
+
message: "Generation succeeded",
|
|
143
|
+
info: inputPath
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
const kubb = (0, _kubb_core.createKubb)(config, { hooks });
|
|
147
|
+
const result = await kubb.generate({ processOutput });
|
|
148
|
+
if (dryRun) await hooks.callHook("kubb:info", {
|
|
149
|
+
message: "Dry run: no files were written",
|
|
150
|
+
info: `${result.files.length} file(s) would be generated`
|
|
151
|
+
});
|
|
152
|
+
const telemetryPlugins = Array.from(kubb.driver.plugins.values(), (p) => ({
|
|
153
|
+
name: p.name,
|
|
154
|
+
options: p.options
|
|
155
|
+
}));
|
|
156
|
+
await require_Telemetry.sendTelemetry(require_Telemetry.buildTelemetryEvent({
|
|
157
|
+
command: "generate",
|
|
158
|
+
kubbVersion: require_package.version,
|
|
159
|
+
plugins: telemetryPlugins,
|
|
160
|
+
hrStart,
|
|
161
|
+
filesCreated: result.files.length,
|
|
162
|
+
status: result.success ? "success" : "failed"
|
|
163
|
+
}));
|
|
164
|
+
return result.success;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Builds a coded diagnostic for an output-phase failure (formatter, linter, or `done` hook).
|
|
168
|
+
*/
|
|
169
|
+
function outputDiagnostic(code, label, caughtError) {
|
|
170
|
+
const error = require_errors.toError(caughtError);
|
|
171
|
+
return {
|
|
172
|
+
code,
|
|
173
|
+
severity: "error",
|
|
174
|
+
message: `${label} failed: ${error.message}`,
|
|
175
|
+
help: "Check that the tool is installed and that the command and its config are correct.",
|
|
176
|
+
location: { kind: "config" },
|
|
177
|
+
cause: error
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
async function checkForUpdate(hooks) {
|
|
181
|
+
try {
|
|
182
|
+
const data = await (await fetch(require_Telemetry.KUBB_NPM_PACKAGE_URL, { signal: AbortSignal.timeout(require_Telemetry.UPDATE_CHECK_TIMEOUT_MS) })).json();
|
|
183
|
+
if (data.version && require_utils.isNewerVersion(require_package.version, data.version)) await _kubb_core.Diagnostics.emit(hooks, _kubb_core.Diagnostics.update({
|
|
184
|
+
currentVersion: require_package.version,
|
|
185
|
+
latestVersion: data.version
|
|
186
|
+
}));
|
|
187
|
+
} catch {}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Runs the full Kubb generation lifecycle for the given CLI options.
|
|
191
|
+
* Loads configs, sets up the reporters (CLI `--reporter` picks which of `config.reporters` to trigger),
|
|
192
|
+
* checks for a newer version, and calls `generate` for each config entry.
|
|
193
|
+
*/
|
|
194
|
+
async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters, dryRun }) {
|
|
195
|
+
const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
|
|
196
|
+
const hooks = new _kubb_core.Hookable();
|
|
197
|
+
let configs;
|
|
198
|
+
let resolvedConfigPath;
|
|
199
|
+
try {
|
|
200
|
+
const loaded = await require_utils.getConfigs({
|
|
201
|
+
configPath,
|
|
202
|
+
input,
|
|
203
|
+
watch,
|
|
204
|
+
logLevel: logLevelKey
|
|
205
|
+
});
|
|
206
|
+
configs = loaded.configs;
|
|
207
|
+
resolvedConfigPath = loaded.configPath;
|
|
208
|
+
} catch (error) {
|
|
209
|
+
await require_utils.setupReporters(hooks, {
|
|
210
|
+
logLevel,
|
|
211
|
+
reporters: [_kubb_core.cliReporter]
|
|
212
|
+
});
|
|
213
|
+
await hooks.callHook("kubb:error", { error: require_errors.toError(error) });
|
|
214
|
+
node_process.default.exit(1);
|
|
215
|
+
}
|
|
216
|
+
const requestedNames = cliReporters?.length ? cliReporters : ["cli"];
|
|
217
|
+
const available = configs[0]?.reporters ?? [];
|
|
218
|
+
const reporters = require_utils.selectReporters(available, requestedNames);
|
|
219
|
+
await require_utils.setupReporters(hooks, {
|
|
220
|
+
logLevel,
|
|
221
|
+
reporters
|
|
222
|
+
});
|
|
223
|
+
await hooks.callHook("kubb:lifecycle:start", { version: require_package.version });
|
|
224
|
+
await checkForUpdate(hooks);
|
|
225
|
+
try {
|
|
226
|
+
const relativeConfigPath = node_path.default.relative(node_process.default.cwd(), resolvedConfigPath);
|
|
227
|
+
await hooks.callHook("kubb:info", {
|
|
228
|
+
message: "Config loaded",
|
|
229
|
+
info: relativeConfigPath
|
|
230
|
+
});
|
|
231
|
+
await hooks.callHook("kubb:success", {
|
|
232
|
+
message: "Config loaded successfully",
|
|
233
|
+
info: relativeConfigPath
|
|
234
|
+
});
|
|
235
|
+
let anyFailed = false;
|
|
236
|
+
for (const config of configs) {
|
|
237
|
+
const effectiveInput = input ?? config.input;
|
|
238
|
+
const watchPath = typeof effectiveInput === "string" && (0, _kubb_core.getInputKind)(effectiveInput) === "file" ? effectiveInput : void 0;
|
|
239
|
+
if (watchPath && watch) {
|
|
240
|
+
const watchedPaths = [watchPath];
|
|
241
|
+
const build = async (paths) => {
|
|
242
|
+
await generate({
|
|
243
|
+
input,
|
|
244
|
+
config,
|
|
245
|
+
logLevel,
|
|
246
|
+
hooks,
|
|
247
|
+
dryRun
|
|
248
|
+
});
|
|
249
|
+
require_output.logStep((0, node_util.styleText)("yellow", `Watching for changes in ${paths.join(" and ")}`));
|
|
250
|
+
};
|
|
251
|
+
try {
|
|
252
|
+
await build(watchedPaths);
|
|
253
|
+
} catch (buildError) {
|
|
254
|
+
await hooks.callHook("kubb:error", { error: require_errors.toError(buildError) });
|
|
255
|
+
}
|
|
256
|
+
await require_utils.startWatcher(watchedPaths, build, {
|
|
257
|
+
info: require_output.logInfo,
|
|
258
|
+
error: require_output.logError
|
|
259
|
+
});
|
|
260
|
+
} else try {
|
|
261
|
+
if (!await generate({
|
|
262
|
+
input,
|
|
263
|
+
config,
|
|
264
|
+
logLevel,
|
|
265
|
+
hooks,
|
|
266
|
+
dryRun
|
|
267
|
+
})) anyFailed = true;
|
|
268
|
+
} catch (configError) {
|
|
269
|
+
await hooks.callHook("kubb:error", { error: require_errors.toError(configError) });
|
|
270
|
+
anyFailed = true;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
await hooks.callHook("kubb:lifecycle:end");
|
|
274
|
+
if (anyFailed) node_process.default.exit(1);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
await hooks.callHook("kubb:error", { error: require_errors.toError(error) });
|
|
277
|
+
node_process.default.exit(1);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
exports.run = run;
|
|
282
|
+
|
|
283
|
+
//# sourceMappingURL=run-CHfPmjaA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-CHfPmjaA.cjs","names":["styleText","existsSync","logLevelMap","randomUUID","runHook","toError","process","memoryStorage","Diagnostics","formatters","detectTool","FORMATTER_PREFERENCE","linters","LINTER_PREFERENCE","runPostGenerate","createKubb","sendTelemetry","buildTelemetryEvent","version","KUBB_NPM_PACKAGE_URL","UPDATE_CHECK_TIMEOUT_MS","isNewerVersion","Hookable","getConfigs","setupReporters","cliReporter","selectReporters","path","getInputKind","startWatcher","logInfo","logError"],"sources":["../src/runners/generate/run.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto'\nimport { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport {\n Hookable,\n type CLIOptions,\n cliReporter,\n type Config,\n createKubb,\n type Diagnostic,\n Diagnostics,\n getInputKind,\n type KubbHooks,\n logLevel as logLevelMap,\n memoryStorage,\n type ProblemDiagnostic,\n type ReporterName,\n} from '@kubb/core'\nimport { version } from '../../../package.json'\nimport { KUBB_NPM_PACKAGE_URL, UPDATE_CHECK_TIMEOUT_MS } from '../../constants.ts'\nimport { buildTelemetryEvent, sendTelemetry } from '../../Telemetry.ts'\nimport setupReporters, { selectReporters } from '../../loggers/utils.ts'\nimport { logError, logInfo, logStep } from '../../loggers/output.ts'\nimport { getConfigs, isNewerVersion, runHook, runPostGenerate, startWatcher } from './utils.ts'\nimport { FORMATTER_PREFERENCE, LINTER_PREFERENCE } from '@internals/utils'\nimport { detectTool, formatters, linters } from '../../tools.ts'\n\ntype GenerateProps = {\n input?: string\n config: Config\n hooks: Hookable<KubbHooks>\n logLevel: number\n /**\n * When `true`, generates in memory instead of writing to disk, and skips formatting, linting,\n * and post-generate commands.\n */\n dryRun?: boolean\n}\n\ntype ToolMap = typeof formatters | typeof linters\n\n/**\n * Static description of one output tool: its command table, the label and messages the pass logs,\n * and how to auto-detect it. Format and lint differ only in these values.\n */\ntype Tool = {\n label: string\n map: ToolMap\n detect: () => Promise<string | null>\n successPrefix: string\n noToolMessage: string\n}\n\ntype RunToolPassOptions = {\n toolValue: string\n tool: Tool\n outputPath: string\n logLevel: number\n hooks: Hookable<KubbHooks>\n onStart: () => Promise<void> | void\n onEnd: () => Promise<void> | void\n}\n\n/**\n * Runs one formatter or linter pass over the output directory. Returns the failure instead of\n * throwing, so the caller can turn it into a coded diagnostic. Failures never render here:\n * the caller emits them through `Diagnostics.emit`, like every other diagnostic.\n */\nasync function runToolPass({ toolValue, tool, outputPath, logLevel, hooks, onStart, onEnd }: RunToolPassOptions): Promise<Error | null> {\n await onStart()\n\n let resolvedTool = toolValue\n if (resolvedTool === 'auto') {\n const detected = await tool.detect()\n if (!detected) {\n await hooks.callHook('kubb:warn', { message: tool.noToolMessage })\n } else {\n resolvedTool = detected\n await hooks.callHook('kubb:info', { message: `Auto-detected ${tool.label}: ${styleText('dim', resolvedTool)}` })\n }\n }\n\n let toolError: Error | null = null\n\n // Nothing to lint or format when the output dir was never written. Skip so the tool\n // (e.g. oxlint with --no-ignore) doesn't fail with \"No files found to lint\".\n if (resolvedTool && resolvedTool !== 'auto' && resolvedTool in tool.map && existsSync(outputPath)) {\n const toolConfig = tool.map[resolvedTool as keyof ToolMap]\n\n const successMessage = [\n `${tool.successPrefix} with ${styleText('dim', resolvedTool)}`,\n logLevel >= logLevelMap.info ? `on ${styleText('dim', outputPath)}` : undefined,\n 'successfully',\n ]\n .filter(Boolean)\n .join(' ')\n\n try {\n const hookId = randomUUID()\n const hookArgs = toolConfig.args(outputPath)\n const commandWithArgs = [toolConfig.command, ...hookArgs].join(' ')\n\n await hooks.callHook('kubb:hook:start', { id: hookId, command: toolConfig.command, args: hookArgs })\n\n const result = await runHook({ id: hookId, command: toolConfig.command, args: hookArgs, commandWithArgs, hooks })\n\n if (result.success) {\n await hooks.callHook('kubb:success', { message: successMessage })\n } else {\n toolError = result.error ?? new Error(toolConfig.errorMessage)\n }\n } catch (caughtError) {\n toolError = toError(caughtError)\n }\n }\n\n await onEnd()\n\n return toolError\n}\n\nasync function generate(options: GenerateProps): Promise<boolean> {\n const { input, hooks, logLevel, dryRun = false } = options\n\n const hrStart = process.hrtime()\n const inputPath = input ?? (typeof options.config.input === 'string' ? options.config.input : undefined)\n\n const config: Config = {\n ...options.config,\n input: input ?? options.config.input,\n // Dry-run never touches disk, regardless of the config's own storage driver.\n storage: dryRun ? memoryStorage() : options.config.storage,\n // Also keeps core's `hasOutputPasses` false, so dry-run skips the output manifest write too.\n output: dryRun ? { ...options.config.output, format: false, lint: false, postGenerate: [] } : options.config.output,\n }\n\n // The formatter, linter, and post-generate commands run after a successful build. Collect their\n // failures as coded diagnostics so they reach the summary, the json report, and the exit code.\n const processOutput = async ({ config: resolvedConfig, outputPath }: { config: Config; outputPath: string }): Promise<Array<Diagnostic>> => {\n if (dryRun) return []\n\n const outputDiagnostics: Array<Diagnostic> = []\n const reportOutputFailure = async (code: ProblemDiagnostic['code'], label: string, error: Error) => {\n const diagnostic = outputDiagnostic(code, label, error)\n outputDiagnostics.push(diagnostic)\n await Diagnostics.emit(hooks, diagnostic)\n }\n\n // Format and lint are the same pass over the output directory, differing only in the tool\n // table and the hooks they announce themselves with, so run them from one descriptor list.\n const toolPasses = [\n {\n value: resolvedConfig.output.format,\n code: Diagnostics.code.formatFailed,\n tool: {\n label: 'formatter',\n map: formatters,\n detect: () => detectTool(FORMATTER_PREFERENCE),\n successPrefix: 'Formatting',\n noToolMessage: `No formatter found (${FORMATTER_PREFERENCE.join(', ')}). Skipping formatting.`,\n },\n onStart: () => hooks.callHook('kubb:format:start'),\n onEnd: () => hooks.callHook('kubb:format:end'),\n },\n {\n value: resolvedConfig.output.lint,\n code: Diagnostics.code.lintFailed,\n tool: {\n label: 'linter',\n map: linters,\n detect: () => detectTool(LINTER_PREFERENCE),\n successPrefix: 'Linting',\n noToolMessage: `No linter found (${LINTER_PREFERENCE.join(', ')}). Skipping linting.`,\n },\n onStart: () => hooks.callHook('kubb:lint:start'),\n onEnd: () => hooks.callHook('kubb:lint:end'),\n },\n ]\n\n for (const pass of toolPasses) {\n if (!pass.value) continue\n const error = await runToolPass({\n toolValue: pass.value,\n tool: pass.tool,\n onStart: pass.onStart,\n onEnd: pass.onEnd,\n outputPath,\n logLevel,\n hooks,\n })\n if (error) await reportOutputFailure(pass.code, pass.tool.label, error)\n }\n\n if (resolvedConfig.output.postGenerate?.length) {\n await hooks.callHook('kubb:hooks:start')\n const hookResults = await runPostGenerate({ commands: resolvedConfig.output.postGenerate, hooks })\n for (const hookResult of hookResults) {\n if (hookResult.success) continue\n await reportOutputFailure(Diagnostics.code.postGenerateFailed, 'Post-generate command', hookResult.error ?? new Error('Post-generate command failed'))\n }\n await hooks.callHook('kubb:hooks:end')\n }\n\n return outputDiagnostics\n }\n\n hooks.hook('kubb:generation:end', ({ status }) => {\n if (status === 'success') return hooks.callHook('kubb:success', { message: 'Generation succeeded', info: inputPath })\n })\n\n const kubb = createKubb(config, { hooks })\n const result = await kubb.generate({ processOutput })\n\n if (dryRun) {\n await hooks.callHook('kubb:info', { message: 'Dry run: no files were written', info: `${result.files.length} file(s) would be generated` })\n }\n\n const telemetryPlugins = Array.from(kubb.driver.plugins.values(), (p) => ({ name: p.name, options: p.options as Record<string, unknown> }))\n await sendTelemetry(\n buildTelemetryEvent({\n command: 'generate',\n kubbVersion: version,\n plugins: telemetryPlugins,\n hrStart,\n filesCreated: result.files.length,\n status: result.success ? 'success' : 'failed',\n }),\n )\n\n return result.success\n}\n\n/**\n * Builds a coded diagnostic for an output-phase failure (formatter, linter, or `done` hook).\n */\nfunction outputDiagnostic(code: ProblemDiagnostic['code'], label: string, caughtError: unknown): ProblemDiagnostic {\n const error = toError(caughtError)\n return {\n code,\n severity: 'error',\n message: `${label} failed: ${error.message}`,\n help: 'Check that the tool is installed and that the command and its config are correct.',\n location: { kind: 'config' },\n cause: error,\n }\n}\n\ntype GenerateCommandOptions = {\n input?: string\n configPath?: string\n logLevel: string\n watch: boolean\n reporters?: Array<ReporterName>\n dryRun?: boolean\n}\n\nasync function checkForUpdate(hooks: Hookable<KubbHooks>): Promise<void> {\n try {\n const res = await fetch(KUBB_NPM_PACKAGE_URL, { signal: AbortSignal.timeout(UPDATE_CHECK_TIMEOUT_MS) })\n const data = (await res.json()) as { version: string }\n if (data.version && isNewerVersion(version, data.version)) {\n await Diagnostics.emit(hooks, Diagnostics.update({ currentVersion: version, latestVersion: data.version }))\n }\n } catch {\n // Ignore network errors\n }\n}\n\n/**\n * Runs the full Kubb generation lifecycle for the given CLI options.\n * Loads configs, sets up the reporters (CLI `--reporter` picks which of `config.reporters` to trigger),\n * checks for a newer version, and calls `generate` for each config entry.\n */\nexport async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters, dryRun }: GenerateCommandOptions): Promise<void> {\n const logLevel = logLevelMap[logLevelKey as keyof typeof logLevelMap] ?? logLevelMap.info\n const hooks = new Hookable<KubbHooks>()\n\n // Load the config first so `config.reporters` can pick the reporters. A failure here has no\n // reporter installed yet, so fall back to the default `cli` reporter to surface it.\n let configs: Array<Config>\n let resolvedConfigPath: string\n try {\n const loaded = await getConfigs({\n configPath,\n input,\n watch,\n logLevel: logLevelKey as CLIOptions['logLevel'],\n })\n configs = loaded.configs\n resolvedConfigPath = loaded.configPath\n } catch (error) {\n await setupReporters(hooks, { logLevel, reporters: [cliReporter] })\n await hooks.callHook('kubb:error', { error: toError(error) })\n process.exit(1)\n }\n\n // CLI `--reporter` selects which reporters to trigger by name, defaulting to `cli`. The config\n // always carries the available reporters (defineConfig registers the built-ins).\n const requestedNames: Array<ReporterName> = cliReporters?.length ? cliReporters : ['cli']\n const available = configs[0]?.reporters ?? []\n const reporters = selectReporters(available, requestedNames)\n await setupReporters(hooks, { logLevel, reporters })\n\n await hooks.callHook('kubb:lifecycle:start', { version })\n\n await checkForUpdate(hooks)\n\n try {\n const relativeConfigPath = path.relative(process.cwd(), resolvedConfigPath)\n\n await hooks.callHook('kubb:info', { message: 'Config loaded', info: relativeConfigPath })\n await hooks.callHook('kubb:success', { message: 'Config loaded successfully', info: relativeConfigPath })\n\n let anyFailed = false\n for (const config of configs) {\n const effectiveInput = input ?? config.input\n const watchPath = typeof effectiveInput === 'string' && getInputKind(effectiveInput) === 'file' ? effectiveInput : undefined\n if (watchPath && watch) {\n const watchedPaths = [watchPath]\n // Don't removeAll() between builds, that would also drop logger and lifecycle\n // listeners. Plugin listeners are already disposed by safeBuild's dispose()\n // in its finally block, so re-running generate() on the same hooks emitter is safe.\n const build = async (paths: Array<string>) => {\n await generate({ input, config, logLevel, hooks, dryRun })\n logStep(styleText('yellow', `Watching for changes in ${paths.join(' and ')}`))\n }\n\n // The watcher ignores chokidar's startup events, so run the first build here. A failing\n // first build keeps watching, since the user can fix the input and save.\n try {\n await build(watchedPaths)\n } catch (buildError) {\n await hooks.callHook('kubb:error', { error: toError(buildError) })\n }\n\n await startWatcher(watchedPaths, build, { info: logInfo, error: logError })\n } else {\n try {\n const succeeded = await generate({ input, config, logLevel, hooks, dryRun })\n if (!succeeded) anyFailed = true\n } catch (configError) {\n await hooks.callHook('kubb:error', { error: toError(configError) })\n anyFailed = true\n }\n }\n }\n\n await hooks.callHook('kubb:lifecycle:end')\n\n if (anyFailed) {\n process.exit(1)\n }\n } catch (error) {\n await hooks.callHook('kubb:error', { error: toError(error) })\n process.exit(1)\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
|
|
2
|
-
const
|
|
2
|
+
const require_output = require("./output-B2V2MN_C.cjs");
|
|
3
|
+
const require_constants = require("./constants-CdxpgX3_.cjs");
|
|
3
4
|
let node_util = require("node:util");
|
|
4
5
|
let node_process = require("node:process");
|
|
5
6
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
@@ -10,95 +11,6 @@ node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
|
|
|
10
11
|
let _clack_prompts = require("@clack/prompts");
|
|
11
12
|
_clack_prompts = require_rolldown_runtime.__toESM(_clack_prompts, 1);
|
|
12
13
|
let tinyexec = require("tinyexec");
|
|
13
|
-
//#region ../../internals/shared/src/constants.ts
|
|
14
|
-
const KUBB_CONFIG_FILENAME = "kubb.config.ts";
|
|
15
|
-
const KUBB_PACKAGE_NAME = "kubb";
|
|
16
|
-
const initDefaults = {
|
|
17
|
-
inputPath: "./openapi.yaml",
|
|
18
|
-
outputPath: "./src/gen",
|
|
19
|
-
plugins: ["plugin-ts"]
|
|
20
|
-
};
|
|
21
|
-
const availablePlugins = [
|
|
22
|
-
{
|
|
23
|
-
value: "plugin-ts",
|
|
24
|
-
label: "TypeScript",
|
|
25
|
-
hint: "Recommended",
|
|
26
|
-
packageName: "@kubb/plugin-ts",
|
|
27
|
-
importName: "pluginTs",
|
|
28
|
-
category: "types"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
value: "plugin-axios",
|
|
32
|
-
label: "Axios Client",
|
|
33
|
-
packageName: "@kubb/plugin-axios",
|
|
34
|
-
importName: "pluginAxios",
|
|
35
|
-
category: "client"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
value: "plugin-fetch",
|
|
39
|
-
label: "Fetch Client",
|
|
40
|
-
packageName: "@kubb/plugin-fetch",
|
|
41
|
-
importName: "pluginFetch",
|
|
42
|
-
category: "client"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
value: "plugin-react-query",
|
|
46
|
-
label: "React Query / TanStack Query",
|
|
47
|
-
packageName: "@kubb/plugin-react-query",
|
|
48
|
-
importName: "pluginReactQuery",
|
|
49
|
-
category: "framework"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
value: "plugin-vue-query",
|
|
53
|
-
label: "Vue Query",
|
|
54
|
-
packageName: "@kubb/plugin-vue-query",
|
|
55
|
-
importName: "pluginVueQuery",
|
|
56
|
-
category: "framework"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
value: "plugin-zod",
|
|
60
|
-
label: "Zod Schemas",
|
|
61
|
-
packageName: "@kubb/plugin-zod",
|
|
62
|
-
importName: "pluginZod",
|
|
63
|
-
category: "validation"
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
value: "plugin-faker",
|
|
67
|
-
label: "Faker.js Mocks",
|
|
68
|
-
packageName: "@kubb/plugin-faker",
|
|
69
|
-
importName: "pluginFaker",
|
|
70
|
-
category: "mocks"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
value: "plugin-msw",
|
|
74
|
-
label: "MSW Handlers",
|
|
75
|
-
packageName: "@kubb/plugin-msw",
|
|
76
|
-
importName: "pluginMsw",
|
|
77
|
-
category: "mocks"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
value: "plugin-cypress",
|
|
81
|
-
label: "Cypress Tests",
|
|
82
|
-
packageName: "@kubb/plugin-cypress",
|
|
83
|
-
importName: "pluginCypress",
|
|
84
|
-
category: "testing"
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
value: "plugin-mcp",
|
|
88
|
-
label: "MCP Server (AI / Model Context Protocol)",
|
|
89
|
-
packageName: "@kubb/plugin-mcp",
|
|
90
|
-
importName: "pluginMcp",
|
|
91
|
-
category: "ai"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
value: "plugin-redoc",
|
|
95
|
-
label: "ReDoc Documentation",
|
|
96
|
-
packageName: "@kubb/plugin-redoc",
|
|
97
|
-
importName: "pluginRedoc",
|
|
98
|
-
category: "documentation"
|
|
99
|
-
}
|
|
100
|
-
];
|
|
101
|
-
//#endregion
|
|
102
14
|
//#region ../../internals/shared/src/init.ts
|
|
103
15
|
/**
|
|
104
16
|
* Resolves a comma-separated plugin flag (e.g. `--plugins plugin-ts,plugin-zod`) into the
|
|
@@ -108,7 +20,7 @@ const availablePlugins = [
|
|
|
108
20
|
function resolvePlugins(pluginsFlag) {
|
|
109
21
|
if (!pluginsFlag) return [];
|
|
110
22
|
const requested = pluginsFlag.split(",").map((value) => value.trim()).filter(Boolean);
|
|
111
|
-
return availablePlugins.filter((plugin) => requested.includes(plugin.value));
|
|
23
|
+
return require_constants.availablePlugins.filter((plugin) => requested.includes(plugin.value));
|
|
112
24
|
}
|
|
113
25
|
function generateConfigFile({ selectedPlugins, inputPath, outputPath }) {
|
|
114
26
|
return `import { defineConfig } from 'kubb/config'
|
|
@@ -139,6 +51,62 @@ function resolveInstallVersions({ packages, version }) {
|
|
|
139
51
|
return packages.map((name) => name === "kubb" ? `${name}@${version}` : `${name}@${tag}`);
|
|
140
52
|
}
|
|
141
53
|
//#endregion
|
|
54
|
+
//#region src/tools.ts
|
|
55
|
+
/**
|
|
56
|
+
* Metadata for each supported package manager, keyed by its short name.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* packageManagers.pnpm.installCommand // ['add', '-D']
|
|
61
|
+
* packageManagers.npm.lockFile // 'package-lock.json'
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
const packageManagers = {
|
|
65
|
+
pnpm: {
|
|
66
|
+
name: "pnpm",
|
|
67
|
+
lockFile: "pnpm-lock.yaml",
|
|
68
|
+
installCommand: ["add", "-D"]
|
|
69
|
+
},
|
|
70
|
+
yarn: {
|
|
71
|
+
name: "yarn",
|
|
72
|
+
lockFile: "yarn.lock",
|
|
73
|
+
installCommand: ["add", "-D"]
|
|
74
|
+
},
|
|
75
|
+
bun: {
|
|
76
|
+
name: "bun",
|
|
77
|
+
lockFile: "bun.lockb",
|
|
78
|
+
installCommand: ["add", "-d"]
|
|
79
|
+
},
|
|
80
|
+
npm: {
|
|
81
|
+
name: "npm",
|
|
82
|
+
lockFile: "package-lock.json",
|
|
83
|
+
installCommand: ["install", "--save-dev"]
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Detects the active package manager for the given directory.
|
|
88
|
+
* Resolution order: `packageManager` field in `package.json`, then presence of a lock file.
|
|
89
|
+
* Falls back to `npm` when no signal is found.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* detectPackageManager('/my/project') // { name: 'pnpm', lockFile: 'pnpm-lock.yaml', ... }
|
|
94
|
+
* detectPackageManager() // falls back to npm when no lock file is found
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
function detectPackageManager(cwd = process.cwd()) {
|
|
98
|
+
const packageJsonPath = (0, node_path.join)(cwd, "package.json");
|
|
99
|
+
if ((0, node_fs.existsSync)(packageJsonPath)) try {
|
|
100
|
+
const pmField = JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf-8")).packageManager;
|
|
101
|
+
if (typeof pmField === "string") {
|
|
102
|
+
const name = pmField.split("@")[0];
|
|
103
|
+
if (name && name in packageManagers) return packageManagers[name];
|
|
104
|
+
}
|
|
105
|
+
} catch {}
|
|
106
|
+
for (const pm of Object.values(packageManagers)) if ((0, node_fs.existsSync)((0, node_path.join)(cwd, pm.lockFile))) return pm;
|
|
107
|
+
return packageManagers.npm;
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
142
110
|
//#region src/runners/init/utils.ts
|
|
143
111
|
/**
|
|
144
112
|
* Returns `true` when a `package.json` exists at `cwd`.
|
|
@@ -188,18 +156,18 @@ function cancelAndExit(message = "Operation canceled.") {
|
|
|
188
156
|
*/
|
|
189
157
|
async function run({ yes, version, input: inputFlag, output: outputFlag, plugins: pluginsFlag, dryRun }) {
|
|
190
158
|
const cwd = node_process.default.cwd();
|
|
191
|
-
|
|
159
|
+
require_output.logIntro({ title: (0, node_util.styleText)("bgCyan", (0, node_util.styleText)("black", " Kubb Init ")) });
|
|
192
160
|
/**
|
|
193
161
|
* Returns `flag` when provided, the `defaultValue` when `yes` is set,
|
|
194
162
|
* or calls `prompt()` for interactive input. Exits on cancellation.
|
|
195
163
|
*/
|
|
196
164
|
async function resolveOrPrompt(flag, defaultValue, logLabel, prompt) {
|
|
197
165
|
if (flag !== void 0) {
|
|
198
|
-
|
|
166
|
+
require_output.logInfo(`${logLabel}: ${(0, node_util.styleText)("cyan", String(flag))}`);
|
|
199
167
|
return flag;
|
|
200
168
|
}
|
|
201
169
|
if (yes) {
|
|
202
|
-
|
|
170
|
+
require_output.logInfo(`${logLabel}: ${(0, node_util.styleText)("cyan", String(defaultValue))}`);
|
|
203
171
|
return defaultValue;
|
|
204
172
|
}
|
|
205
173
|
const result = await prompt();
|
|
@@ -215,64 +183,64 @@ async function run({ yes, version, input: inputFlag, output: outputFlag, plugins
|
|
|
215
183
|
});
|
|
216
184
|
if (_clack_prompts.isCancel(shouldInit) || !shouldInit) cancelAndExit();
|
|
217
185
|
}
|
|
218
|
-
const packageManager =
|
|
219
|
-
const spinner =
|
|
186
|
+
const packageManager = detectPackageManager(cwd);
|
|
187
|
+
const spinner = require_output.createSpinner();
|
|
220
188
|
spinner.start(`Initializing package.json with ${packageManager.name}`);
|
|
221
189
|
await initPackageJson(cwd, packageManager);
|
|
222
190
|
spinner.stop(`Created package.json with ${packageManager.name}`);
|
|
223
191
|
}
|
|
224
|
-
const packageManager =
|
|
225
|
-
if (hasPackageJson(cwd))
|
|
226
|
-
const inputPath = await resolveOrPrompt(inputFlag, initDefaults.inputPath, "Using input path", () => _clack_prompts.text({
|
|
192
|
+
const packageManager = detectPackageManager(cwd);
|
|
193
|
+
if (hasPackageJson(cwd)) require_output.logInfo(`Detected package manager: ${(0, node_util.styleText)("cyan", packageManager.name)}`);
|
|
194
|
+
const inputPath = await resolveOrPrompt(inputFlag, require_constants.initDefaults.inputPath, "Using input path", () => _clack_prompts.text({
|
|
227
195
|
message: "Where is your OpenAPI specification located?",
|
|
228
|
-
placeholder: initDefaults.inputPath,
|
|
229
|
-
defaultValue: initDefaults.inputPath,
|
|
196
|
+
placeholder: require_constants.initDefaults.inputPath,
|
|
197
|
+
defaultValue: require_constants.initDefaults.inputPath,
|
|
230
198
|
validate: (value) => {
|
|
231
199
|
if (!value) return "Input path is required";
|
|
232
200
|
}
|
|
233
201
|
}));
|
|
234
|
-
const outputPath = await resolveOrPrompt(outputFlag, initDefaults.outputPath, "Using output path", () => _clack_prompts.text({
|
|
202
|
+
const outputPath = await resolveOrPrompt(outputFlag, require_constants.initDefaults.outputPath, "Using output path", () => _clack_prompts.text({
|
|
235
203
|
message: "Where should the generated files be output?",
|
|
236
|
-
placeholder: initDefaults.outputPath,
|
|
237
|
-
defaultValue: initDefaults.outputPath,
|
|
204
|
+
placeholder: require_constants.initDefaults.outputPath,
|
|
205
|
+
defaultValue: require_constants.initDefaults.outputPath,
|
|
238
206
|
validate: (value) => {
|
|
239
207
|
if (!value) return "Output path is required";
|
|
240
208
|
}
|
|
241
209
|
}));
|
|
242
|
-
const defaultPlugins = availablePlugins.filter((p) => initDefaults.plugins.includes(p.value));
|
|
210
|
+
const defaultPlugins = require_constants.availablePlugins.filter((p) => require_constants.initDefaults.plugins.includes(p.value));
|
|
243
211
|
const pluginLabel = (plugins) => (0, node_util.styleText)("cyan", plugins.map((p) => p.label).join(", "));
|
|
244
212
|
const selectedPlugins = await (async () => {
|
|
245
213
|
if (pluginsFlag) {
|
|
246
214
|
const plugins = resolvePlugins(pluginsFlag);
|
|
247
215
|
if (plugins.length === 0) {
|
|
248
|
-
|
|
216
|
+
require_output.logWarn(`No valid plugins found in --plugins value; falling back to default: ${pluginLabel(defaultPlugins)}`);
|
|
249
217
|
return defaultPlugins;
|
|
250
218
|
}
|
|
251
|
-
|
|
219
|
+
require_output.logInfo(`Using plugins: ${pluginLabel(plugins)}`);
|
|
252
220
|
return plugins;
|
|
253
221
|
}
|
|
254
222
|
if (yes) {
|
|
255
|
-
|
|
223
|
+
require_output.logInfo(`Using plugins: ${pluginLabel(defaultPlugins)}`);
|
|
256
224
|
return defaultPlugins;
|
|
257
225
|
}
|
|
258
226
|
const values = await _clack_prompts.multiselect({
|
|
259
227
|
message: "Select plugins to use:",
|
|
260
|
-
options: availablePlugins.map(({ value, label, hint }) => ({
|
|
228
|
+
options: require_constants.availablePlugins.map(({ value, label, hint }) => ({
|
|
261
229
|
value,
|
|
262
230
|
label,
|
|
263
231
|
hint
|
|
264
232
|
})),
|
|
265
|
-
initialValues: [...initDefaults.plugins],
|
|
233
|
+
initialValues: [...require_constants.initDefaults.plugins],
|
|
266
234
|
required: true
|
|
267
235
|
});
|
|
268
236
|
if (_clack_prompts.isCancel(values)) cancelAndExit();
|
|
269
|
-
return availablePlugins.filter((p) => values.includes(p.value));
|
|
237
|
+
return require_constants.availablePlugins.filter((p) => values.includes(p.value));
|
|
270
238
|
})();
|
|
271
239
|
const packagesToInstall = resolveInstallVersions({
|
|
272
|
-
packages: [KUBB_PACKAGE_NAME, ...selectedPlugins.map((p) => p.packageName)],
|
|
240
|
+
packages: [require_constants.KUBB_PACKAGE_NAME, ...selectedPlugins.map((p) => p.packageName)],
|
|
273
241
|
version
|
|
274
242
|
});
|
|
275
|
-
const spinner =
|
|
243
|
+
const spinner = require_output.createSpinner();
|
|
276
244
|
spinner.start(`Installing ${packagesToInstall.length} packages with ${packageManager.name}`);
|
|
277
245
|
try {
|
|
278
246
|
await dryRun.run(() => installPackages(packagesToInstall, packageManager, cwd), { message: `install ${packagesToInstall.length} packages with ${packageManager.name}` });
|
|
@@ -281,35 +249,35 @@ async function run({ yes, version, input: inputFlag, output: outputFlag, plugins
|
|
|
281
249
|
spinner.stop("Installation failed");
|
|
282
250
|
throw error;
|
|
283
251
|
}
|
|
284
|
-
const configSpinner =
|
|
285
|
-
configSpinner.start(`Creating ${KUBB_CONFIG_FILENAME}`);
|
|
252
|
+
const configSpinner = require_output.createSpinner();
|
|
253
|
+
configSpinner.start(`Creating ${require_constants.KUBB_CONFIG_FILENAME}`);
|
|
286
254
|
const configContent = generateConfigFile({
|
|
287
255
|
selectedPlugins,
|
|
288
256
|
inputPath,
|
|
289
257
|
outputPath
|
|
290
258
|
});
|
|
291
|
-
const configPath = node_path.default.join(cwd, KUBB_CONFIG_FILENAME);
|
|
259
|
+
const configPath = node_path.default.join(cwd, require_constants.KUBB_CONFIG_FILENAME);
|
|
292
260
|
if (node_fs.default.existsSync(configPath)) {
|
|
293
|
-
configSpinner.stop(`${KUBB_CONFIG_FILENAME} already exists`);
|
|
261
|
+
configSpinner.stop(`${require_constants.KUBB_CONFIG_FILENAME} already exists`);
|
|
294
262
|
if (!yes) {
|
|
295
263
|
const shouldOverwrite = await _clack_prompts.confirm({
|
|
296
|
-
message: `${KUBB_CONFIG_FILENAME} already exists. Overwrite?`,
|
|
264
|
+
message: `${require_constants.KUBB_CONFIG_FILENAME} already exists. Overwrite?`,
|
|
297
265
|
initialValue: false
|
|
298
266
|
});
|
|
299
267
|
if (_clack_prompts.isCancel(shouldOverwrite) || !shouldOverwrite) cancelAndExit("Keeping existing configuration. Packages have been installed.");
|
|
300
268
|
}
|
|
301
|
-
configSpinner.start(`Overwriting ${KUBB_CONFIG_FILENAME}`);
|
|
269
|
+
configSpinner.start(`Overwriting ${require_constants.KUBB_CONFIG_FILENAME}`);
|
|
302
270
|
}
|
|
303
|
-
await dryRun.run(() => node_fs.default.promises.writeFile(configPath, configContent, "utf-8"), { message: `write ${KUBB_CONFIG_FILENAME}` });
|
|
304
|
-
configSpinner.stop(`Created ${KUBB_CONFIG_FILENAME}`);
|
|
305
|
-
|
|
271
|
+
await dryRun.run(() => node_fs.default.promises.writeFile(configPath, configContent, "utf-8"), { message: `write ${require_constants.KUBB_CONFIG_FILENAME}` });
|
|
272
|
+
configSpinner.stop(`Created ${require_constants.KUBB_CONFIG_FILENAME}`);
|
|
273
|
+
require_output.logOutro((0, node_util.styleText)("green", "✓ All set!") + "\n\n" + (0, node_util.styleText)("dim", "Next steps:") + "\n" + (0, node_util.styleText)("cyan", ` 1. Make sure your OpenAPI spec is at: ${inputPath}`) + "\n" + (0, node_util.styleText)("cyan", " 2. Generate code with: npx kubb generate") + "\n" + (0, node_util.styleText)("cyan", ` 3. Find generated files in: ${outputPath}`) + "\n\n" + (0, node_util.styleText)("dim", `Using ${packageManager.name} • Kubb v${version}`));
|
|
306
274
|
} catch (error) {
|
|
307
|
-
|
|
308
|
-
if (error instanceof Error)
|
|
275
|
+
require_output.logError((0, node_util.styleText)("red", "An error occurred during initialization"));
|
|
276
|
+
if (error instanceof Error) require_output.logError(error.message);
|
|
309
277
|
node_process.default.exit(1);
|
|
310
278
|
}
|
|
311
279
|
}
|
|
312
280
|
//#endregion
|
|
313
281
|
exports.run = run;
|
|
314
282
|
|
|
315
|
-
//# sourceMappingURL=run-
|
|
283
|
+
//# sourceMappingURL=run-DRBqVXX0.cjs.map
|