@kubb/cli 4.21.2 → 4.22.1

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.
Files changed (44) hide show
  1. package/dist/{generate-DgWO-YRb.js → generate-Bgpw_dcv.js} +6 -648
  2. package/dist/generate-Bgpw_dcv.js.map +1 -0
  3. package/dist/{generate-R5HtGqSp.cjs → generate-BxSL_NKj.cjs} +10 -652
  4. package/dist/generate-BxSL_NKj.cjs.map +1 -0
  5. package/dist/getCosmiConfig-Co29x0Wv.cjs +458 -0
  6. package/dist/getCosmiConfig-Co29x0Wv.cjs.map +1 -0
  7. package/dist/getCosmiConfig-y2n_oW_y.js +438 -0
  8. package/dist/getCosmiConfig-y2n_oW_y.js.map +1 -0
  9. package/dist/index.cjs +9 -7
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.js +9 -7
  12. package/dist/index.js.map +1 -1
  13. package/dist/{init-C9XEA7L6.js → init-CfRtJpHs.js} +3 -3
  14. package/dist/{init-C9XEA7L6.js.map → init-CfRtJpHs.js.map} +1 -1
  15. package/dist/{init-B7j_UJk9.cjs → init-DZzYaf0D.cjs} +3 -3
  16. package/dist/{init-B7j_UJk9.cjs.map → init-DZzYaf0D.cjs.map} +1 -1
  17. package/dist/{mcp-By2JUPa8.js → mcp-BdwwUv36.js} +1 -1
  18. package/dist/{mcp-By2JUPa8.js.map → mcp-BdwwUv36.js.map} +1 -1
  19. package/dist/{mcp-l-_Z-WU6.cjs → mcp-Hy_PYnFp.cjs} +1 -1
  20. package/dist/{mcp-l-_Z-WU6.cjs.map → mcp-Hy_PYnFp.cjs.map} +1 -1
  21. package/dist/package-BQu01PU2.js +6 -0
  22. package/dist/package-BQu01PU2.js.map +1 -0
  23. package/dist/{package-C1biCSPI.cjs → package-Cmbk_MZB.cjs} +2 -2
  24. package/dist/package-Cmbk_MZB.cjs.map +1 -0
  25. package/dist/start-Dtqs_9NV.js +125 -0
  26. package/dist/start-Dtqs_9NV.js.map +1 -0
  27. package/dist/start-iXbqdw8g.cjs +128 -0
  28. package/dist/start-iXbqdw8g.cjs.map +1 -0
  29. package/dist/{validate-DkHCd-Tl.cjs → validate-Cvb5aOEb.cjs} +1 -1
  30. package/dist/{validate-DkHCd-Tl.cjs.map → validate-Cvb5aOEb.cjs.map} +1 -1
  31. package/dist/{validate-0Qu8SxVA.js → validate-YI4YkVTl.js} +1 -1
  32. package/dist/{validate-0Qu8SxVA.js.map → validate-YI4YkVTl.js.map} +1 -1
  33. package/package.json +4 -4
  34. package/src/commands/generate.ts +0 -38
  35. package/src/commands/init.ts +3 -1
  36. package/src/commands/start.ts +149 -0
  37. package/src/index.ts +2 -1
  38. package/dist/generate-DgWO-YRb.js.map +0 -1
  39. package/dist/generate-R5HtGqSp.cjs.map +0 -1
  40. package/dist/package-C1biCSPI.cjs.map +0 -1
  41. package/dist/package-DRskcFXO.js +0 -6
  42. package/dist/package-DRskcFXO.js.map +0 -1
  43. package/src/loggers/streamLogger.ts +0 -93
  44. package/src/utils/streamServer.ts +0 -160
@@ -1,26 +1,21 @@
1
1
  import { t as __name } from "./chunk-jHaXqnEa.js";
2
- import { t as version } from "./package-DRskcFXO.js";
2
+ import { t as version } from "./package-BQu01PU2.js";
3
+ import { n as getConfigs, r as generate, t as getCosmiConfig } from "./getCosmiConfig-y2n_oW_y.js";
3
4
  import { defineCommand, showUsage } from "citty";
4
5
  import path, { relative, resolve } from "node:path";
5
6
  import * as process$2 from "node:process";
6
7
  import process$1 from "node:process";
7
8
  import * as clack from "@clack/prompts";
8
- import { LogLevel, PromiseManager, defineLogger, isInputPath, safeBuild, setup } from "@kubb/core";
9
- import { AsyncEventEmitter, executeIfOnline, formatHrtime, formatMs, isPromise, serializePluginOptions } from "@kubb/core/utils";
9
+ import { LogLevel, PromiseManager, defineLogger, isInputPath } from "@kubb/core";
10
+ import { AsyncEventEmitter, executeIfOnline, formatHrtime, formatMs } from "@kubb/core/utils";
10
11
  import getLatestVersion from "latest-version";
11
12
  import pc from "picocolors";
12
13
  import { lt } from "semver";
13
- import { execa, execaCommand } from "execa";
14
+ import { execa } from "execa";
14
15
  import gradientString from "gradient-string";
15
16
  import seedrandom from "seedrandom";
16
17
  import { Writable } from "node:stream";
17
18
  import { write } from "@kubb/core/fs";
18
- import { createHash } from "node:crypto";
19
- import { parseArgsStringToArgv } from "string-argv";
20
- import { cosmiconfig } from "cosmiconfig";
21
- import { createJiti } from "jiti";
22
- import { readFileSync } from "node:fs";
23
- import { createServer } from "node:http";
24
19
 
25
20
  //#region src/utils/formatMsWithColor.ts
26
21
  /**
@@ -1129,614 +1124,6 @@ async function setupLogger(context, { logLevel }) {
1129
1124
  return cleanup;
1130
1125
  }
1131
1126
 
1132
- //#endregion
1133
- //#region src/utils/detectFormatter.ts
1134
- /**
1135
- * Check if a formatter command is available in the system.
1136
- *
1137
- * @param formatter - The formatter to check ('biome', 'prettier', or 'oxfmt')
1138
- * @returns Promise that resolves to true if the formatter is available, false otherwise
1139
- *
1140
- * @remarks
1141
- * This function checks availability by running `<formatter> --version` command.
1142
- * All supported formatters (biome, prettier, oxfmt) implement the --version flag.
1143
- */
1144
- async function isFormatterAvailable(formatter) {
1145
- try {
1146
- await execaCommand(`${formatter} --version`, { stdio: "ignore" });
1147
- return true;
1148
- } catch {
1149
- return false;
1150
- }
1151
- }
1152
- /**
1153
- * Detect which formatter is available in the system.
1154
- *
1155
- * @returns Promise that resolves to the first available formatter or undefined if none are found
1156
- *
1157
- * @remarks
1158
- * Checks in order of preference: biome, oxfmt, prettier.
1159
- * Uses the `--version` flag to detect if each formatter command is available.
1160
- * This is a reliable method as all supported formatters implement this flag.
1161
- *
1162
- * @example
1163
- * ```typescript
1164
- * const formatter = await detectFormatter()
1165
- * if (formatter) {
1166
- * console.log(`Using ${formatter} for formatting`)
1167
- * } else {
1168
- * console.log('No formatter found')
1169
- * }
1170
- * ```
1171
- */
1172
- async function detectFormatter() {
1173
- for (const formatter of [
1174
- "biome",
1175
- "oxfmt",
1176
- "prettier"
1177
- ]) if (await isFormatterAvailable(formatter)) return formatter;
1178
- }
1179
-
1180
- //#endregion
1181
- //#region src/utils/detectLinter.ts
1182
- /**
1183
- * Check if a linter command is available in the system.
1184
- *
1185
- * @param linter - The linter to check ('biome', 'oxlint', or 'eslint')
1186
- * @returns Promise that resolves to true if the linter is available, false otherwise
1187
- *
1188
- * @remarks
1189
- * This function checks availability by running `<linter> --version` command.
1190
- * All supported linters (biome, oxlint, eslint) implement the --version flag.
1191
- */
1192
- async function isLinterAvailable(linter) {
1193
- try {
1194
- await execaCommand(`${linter} --version`, { stdio: "ignore" });
1195
- return true;
1196
- } catch {
1197
- return false;
1198
- }
1199
- }
1200
- /**
1201
- * Detect which linter is available in the system.
1202
- *
1203
- * @returns Promise that resolves to the first available linter or undefined if none are found
1204
- *
1205
- * @remarks
1206
- * Checks in order of preference: biome, oxlint, eslint.
1207
- * Uses the `--version` flag to detect if each linter command is available.
1208
- * This is a reliable method as all supported linters implement this flag.
1209
- *
1210
- * @example
1211
- * ```typescript
1212
- * const linter = await detectLinter()
1213
- * if (linter) {
1214
- * console.log(`Using ${linter} for linting`)
1215
- * } else {
1216
- * console.log('No linter found')
1217
- * }
1218
- * ```
1219
- */
1220
- async function detectLinter() {
1221
- for (const linter of [
1222
- "biome",
1223
- "oxlint",
1224
- "eslint"
1225
- ]) if (await isLinterAvailable(linter)) return linter;
1226
- }
1227
-
1228
- //#endregion
1229
- //#region src/utils/executeHooks.ts
1230
- async function executeHooks({ hooks, events }) {
1231
- const commands = Array.isArray(hooks.done) ? hooks.done : [hooks.done].filter(Boolean);
1232
- for (const command$1 of commands) {
1233
- const [cmd, ...args] = [...parseArgsStringToArgv(command$1)];
1234
- if (!cmd) continue;
1235
- const hookId = createHash("sha256").update(command$1).digest("hex");
1236
- await events.emit("hook:start", {
1237
- id: hookId,
1238
- command: cmd,
1239
- args
1240
- });
1241
- await events.onOnce("hook:end", async ({ success, error }) => {
1242
- if (!success) throw error;
1243
- await events.emit("success", `${pc.dim(command$1)} successfully executed`);
1244
- });
1245
- }
1246
- }
1247
-
1248
- //#endregion
1249
- //#region src/utils/formatters.ts
1250
- const formatters = {
1251
- prettier: {
1252
- command: "prettier",
1253
- args: (outputPath) => [
1254
- "--ignore-unknown",
1255
- "--write",
1256
- outputPath
1257
- ],
1258
- errorMessage: "Prettier not found"
1259
- },
1260
- biome: {
1261
- command: "biome",
1262
- args: (outputPath) => [
1263
- "format",
1264
- "--write",
1265
- outputPath
1266
- ],
1267
- errorMessage: "Biome not found"
1268
- },
1269
- oxfmt: {
1270
- command: "oxfmt",
1271
- args: (outputPath) => [outputPath],
1272
- errorMessage: "Oxfmt not found"
1273
- }
1274
- };
1275
-
1276
- //#endregion
1277
- //#region src/runners/generate.ts
1278
- async function generate({ input, config: userConfig, events, logLevel }) {
1279
- const inputPath = input ?? ("path" in userConfig.input ? userConfig.input.path : void 0);
1280
- const hrStart = process$1.hrtime();
1281
- const config = {
1282
- ...userConfig,
1283
- root: userConfig.root || process$1.cwd(),
1284
- input: inputPath ? {
1285
- ...userConfig.input,
1286
- path: inputPath
1287
- } : userConfig.input,
1288
- output: {
1289
- write: true,
1290
- barrelType: "named",
1291
- extension: { ".ts": ".ts" },
1292
- format: "prettier",
1293
- ...userConfig.output
1294
- }
1295
- };
1296
- await events.emit("generation:start", config);
1297
- await events.emit("info", config.name ? `Setup generation ${pc.bold(config.name)}` : "Setup generation", inputPath);
1298
- const { sources, fabric, pluginManager } = await setup({
1299
- config,
1300
- events
1301
- });
1302
- await events.emit("info", config.name ? `Build generation ${pc.bold(config.name)}` : "Build generation", inputPath);
1303
- const { files, failedPlugins, pluginTimings, error } = await safeBuild({
1304
- config,
1305
- events
1306
- }, {
1307
- pluginManager,
1308
- fabric,
1309
- events,
1310
- sources
1311
- });
1312
- await events.emit("info", "Load summary");
1313
- if (failedPlugins.size > 0 || error) {
1314
- [error, ...Array.from(failedPlugins).filter((it) => it.error).map((it) => it.error)].filter(Boolean).forEach((err) => {
1315
- events.emit("error", err);
1316
- });
1317
- await events.emit("generation:end", config, files, sources);
1318
- await events.emit("generation:summary", config, {
1319
- failedPlugins,
1320
- filesCreated: files.length,
1321
- status: failedPlugins.size > 0 || error ? "failed" : "success",
1322
- hrStart,
1323
- pluginTimings: logLevel >= LogLevel.verbose ? pluginTimings : void 0
1324
- });
1325
- process$1.exit(1);
1326
- }
1327
- await events.emit("success", "Generation successfully", inputPath);
1328
- await events.emit("generation:end", config, files, sources);
1329
- if (config.output.format) {
1330
- await events.emit("format:start");
1331
- let formatter = config.output.format;
1332
- if (formatter === "auto") {
1333
- const detectedFormatter = await detectFormatter();
1334
- if (!detectedFormatter) await events.emit("warn", "No formatter found (biome, prettier, or oxfmt). Skipping formatting.");
1335
- else {
1336
- formatter = detectedFormatter;
1337
- await events.emit("info", `Auto-detected formatter: ${pc.dim(formatter)}`);
1338
- }
1339
- }
1340
- if (formatter && formatter !== "auto" && formatter in formatters) {
1341
- const formatterConfig = formatters[formatter];
1342
- const outputPath = path.resolve(config.root, config.output.path);
1343
- try {
1344
- const hookId = createHash("sha256").update([config.name, formatter].filter(Boolean).join("-")).digest("hex");
1345
- await events.emit("hook:start", {
1346
- id: hookId,
1347
- command: formatterConfig.command,
1348
- args: formatterConfig.args(outputPath)
1349
- });
1350
- await events.onOnce("hook:end", async ({ success, error: error$1 }) => {
1351
- if (!success) throw error$1;
1352
- await events.emit("success", [
1353
- `Formatting with ${pc.dim(formatter)}`,
1354
- logLevel >= LogLevel.info ? `on ${pc.dim(outputPath)}` : void 0,
1355
- "successfully"
1356
- ].filter(Boolean).join(" "));
1357
- });
1358
- } catch (caughtError) {
1359
- const error$1 = new Error(formatterConfig.errorMessage);
1360
- error$1.cause = caughtError;
1361
- await events.emit("error", error$1);
1362
- }
1363
- }
1364
- await events.emit("format:end");
1365
- }
1366
- if (config.output.lint) {
1367
- await events.emit("lint:start");
1368
- let linter = config.output.lint;
1369
- if (linter === "auto") {
1370
- const detectedLinter = await detectLinter();
1371
- if (!detectedLinter) await events.emit("warn", "No linter found (biome, oxlint, or eslint). Skipping linting.");
1372
- else {
1373
- linter = detectedLinter;
1374
- await events.emit("info", `Auto-detected linter: ${pc.dim(linter)}`);
1375
- }
1376
- }
1377
- if (linter && linter !== "auto") {
1378
- await events.emit("info", [`Linting with ${pc.dim(linter)}`, logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(config.root, config.output.path))}` : void 0].filter(Boolean).join(" "));
1379
- if (linter === "eslint") try {
1380
- const hookId = createHash("sha256").update([config.name, linter].filter(Boolean).join("-")).digest("hex");
1381
- await events.emit("hook:start", {
1382
- id: hookId,
1383
- command: "eslint",
1384
- args: [path.resolve(config.root, config.output.path), "--fix"]
1385
- });
1386
- await events.onOnce("hook:end", async ({ success, error: error$1 }) => {
1387
- if (!success) throw error$1;
1388
- await events.emit("success", [
1389
- `Linted with ${pc.dim(linter)}`,
1390
- logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(config.root, config.output.path))}` : void 0,
1391
- "successfully"
1392
- ].filter(Boolean).join(" "));
1393
- });
1394
- } catch (caughtError) {
1395
- const error$1 = /* @__PURE__ */ new Error("Eslint not found");
1396
- error$1.cause = caughtError;
1397
- await events.emit("error", error$1);
1398
- }
1399
- if (linter === "biome") try {
1400
- const hookId = createHash("sha256").update([config.name, linter].filter(Boolean).join("-")).digest("hex");
1401
- await events.emit("hook:start", {
1402
- id: hookId,
1403
- command: "biome",
1404
- args: [
1405
- "lint",
1406
- "--fix",
1407
- path.resolve(config.root, config.output.path)
1408
- ]
1409
- });
1410
- await events.onOnce("hook:end", async ({ success, error: error$1 }) => {
1411
- if (!success) throw error$1;
1412
- await events.emit("success", [
1413
- `Linted with ${pc.dim(linter)}`,
1414
- logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(config.root, config.output.path))}` : void 0,
1415
- "successfully"
1416
- ].filter(Boolean).join(" "));
1417
- });
1418
- } catch (caughtError) {
1419
- const error$1 = /* @__PURE__ */ new Error("Biome not found");
1420
- error$1.cause = caughtError;
1421
- await events.emit("error", error$1);
1422
- }
1423
- if (linter === "oxlint") try {
1424
- const hookId = createHash("sha256").update([config.name, linter].filter(Boolean).join("-")).digest("hex");
1425
- await events.emit("hook:start", {
1426
- id: hookId,
1427
- command: "oxlint",
1428
- args: ["--fix", path.resolve(config.root, config.output.path)]
1429
- });
1430
- await events.onOnce("hook:end", async ({ success, error: error$1 }) => {
1431
- if (!success) throw error$1;
1432
- await events.emit("success", [
1433
- `Linted with ${pc.dim(linter)}`,
1434
- logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(config.root, config.output.path))}` : void 0,
1435
- "successfully"
1436
- ].filter(Boolean).join(" "));
1437
- });
1438
- } catch (caughtError) {
1439
- const error$1 = /* @__PURE__ */ new Error("Oxlint not found");
1440
- error$1.cause = caughtError;
1441
- await events.emit("error", error$1);
1442
- }
1443
- }
1444
- await events.emit("lint:end");
1445
- }
1446
- if (config.hooks) {
1447
- await events.emit("hooks:start");
1448
- await executeHooks({
1449
- hooks: config.hooks,
1450
- events
1451
- });
1452
- await events.emit("hooks:end");
1453
- }
1454
- await events.emit("generation:summary", config, {
1455
- failedPlugins,
1456
- filesCreated: files.length,
1457
- status: failedPlugins.size > 0 || error ? "failed" : "success",
1458
- hrStart,
1459
- pluginTimings
1460
- });
1461
- }
1462
-
1463
- //#endregion
1464
- //#region src/utils/getPlugins.ts
1465
- function isJSONPlugins(plugins) {
1466
- return !!plugins?.some((plugin) => {
1467
- return Array.isArray(plugin) && typeof plugin?.at(0) === "string";
1468
- });
1469
- }
1470
- function isObjectPlugins(plugins) {
1471
- return plugins instanceof Object && !Array.isArray(plugins);
1472
- }
1473
- function getPlugins(plugins) {
1474
- if (isObjectPlugins(plugins)) throw new Error("Object plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json");
1475
- if (isJSONPlugins(plugins)) throw new Error("JSON plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json");
1476
- return Promise.resolve(plugins);
1477
- }
1478
-
1479
- //#endregion
1480
- //#region src/utils/getConfigs.ts
1481
- /**
1482
- * Converting UserConfig to Config Array without a change in the object beside the JSON convert.
1483
- */
1484
- async function getConfigs(result, args) {
1485
- const config = result?.config;
1486
- let kubbUserConfig = Promise.resolve(config);
1487
- if (typeof config === "function") {
1488
- const possiblePromise = config(args);
1489
- if (isPromise(possiblePromise)) kubbUserConfig = possiblePromise;
1490
- kubbUserConfig = Promise.resolve(possiblePromise);
1491
- }
1492
- let JSONConfig = await kubbUserConfig;
1493
- if (!Array.isArray(JSONConfig)) JSONConfig = [JSONConfig];
1494
- const results = [];
1495
- for (const item of JSONConfig) {
1496
- const plugins = item.plugins ? await getPlugins(item.plugins) : void 0;
1497
- results.push({
1498
- ...item,
1499
- plugins
1500
- });
1501
- }
1502
- return results;
1503
- }
1504
-
1505
- //#endregion
1506
- //#region src/utils/getCosmiConfig.ts
1507
- const tsLoader = async (configFile) => {
1508
- return await createJiti(configFile, {
1509
- jsx: {
1510
- runtime: "automatic",
1511
- importSource: "@kubb/react-fabric"
1512
- },
1513
- sourceMaps: true,
1514
- interopDefault: true
1515
- }).import(configFile, { default: true });
1516
- };
1517
- async function getCosmiConfig(moduleName, config) {
1518
- let result;
1519
- const searchPlaces = [
1520
- "package.json",
1521
- `.${moduleName}rc`,
1522
- `.${moduleName}rc.json`,
1523
- `.${moduleName}rc.yaml`,
1524
- `.${moduleName}rc.yml`,
1525
- `.${moduleName}rc.ts`,
1526
- `.${moduleName}rc.js`,
1527
- `.${moduleName}rc.mjs`,
1528
- `.${moduleName}rc.cjs`,
1529
- `${moduleName}.config.ts`,
1530
- `${moduleName}.config.js`,
1531
- `${moduleName}.config.mjs`,
1532
- `${moduleName}.config.cjs`
1533
- ];
1534
- const explorer = cosmiconfig(moduleName, {
1535
- cache: false,
1536
- searchPlaces: [
1537
- ...searchPlaces.map((searchPlace) => {
1538
- return `.config/${searchPlace}`;
1539
- }),
1540
- ...searchPlaces.map((searchPlace) => {
1541
- return `configs/${searchPlace}`;
1542
- }),
1543
- ...searchPlaces
1544
- ],
1545
- loaders: { ".ts": tsLoader }
1546
- });
1547
- try {
1548
- result = config ? await explorer.load(config) : await explorer.search();
1549
- } catch (error) {
1550
- throw new Error("Config failed loading", { cause: error });
1551
- }
1552
- if (result?.isEmpty || !result || !result.config) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
1553
- return result;
1554
- }
1555
-
1556
- //#endregion
1557
- //#region src/loggers/streamLogger.ts
1558
- /**
1559
- * Stream logger for SSE (Server-Sent Events) streaming
1560
- * Sends Kubb events to HTTP client via SSE protocol
1561
- */
1562
- function createStreamLogger(res) {
1563
- return defineLogger({
1564
- name: "stream",
1565
- install(context, options) {
1566
- const logLevel = options?.logLevel || LogLevel.info;
1567
- const state = { res };
1568
- function send(type, ...data) {
1569
- if (!state.res.destroyed) state.res.write(`data: ${JSON.stringify({
1570
- type,
1571
- data
1572
- })}\n\n`);
1573
- }
1574
- context.on("plugin:start", (plugin) => {
1575
- send("plugin:start", { name: plugin.name });
1576
- });
1577
- context.on("plugin:end", (plugin, { duration, success }) => {
1578
- send("plugin:end", { name: plugin.name }, {
1579
- duration,
1580
- success
1581
- });
1582
- });
1583
- context.on("files:processing:start", (files) => {
1584
- send("files:processing:start", { total: files.length });
1585
- });
1586
- context.on("file:processing:update", ({ file, processed, total, percentage, config }) => {
1587
- send("file:processing:update", {
1588
- file: file.path ? relative(config.root, file.path) : file.baseName || "unknown",
1589
- processed,
1590
- total,
1591
- percentage
1592
- });
1593
- });
1594
- context.on("files:processing:end", (files) => {
1595
- send("files:processing:end", { total: files.length });
1596
- });
1597
- context.on("info", (message, info) => {
1598
- if (logLevel <= LogLevel.silent) return;
1599
- send("info", message, info);
1600
- });
1601
- context.on("success", (message, info) => {
1602
- if (logLevel <= LogLevel.silent) return;
1603
- send("success", message, info);
1604
- });
1605
- context.on("warn", (message, info) => {
1606
- if (logLevel < LogLevel.warn) return;
1607
- send("warn", message, info);
1608
- });
1609
- context.on("error", (error) => {
1610
- send("error", {
1611
- message: error.message,
1612
- stack: logLevel >= LogLevel.debug ? error.stack : void 0
1613
- });
1614
- });
1615
- context.on("generation:start", (config) => {
1616
- send("generation:start", {
1617
- name: config.name,
1618
- plugins: config.plugins?.length || 0
1619
- });
1620
- });
1621
- context.on("generation:end", (config, files, sources) => {
1622
- send("generation:end", config, files, Object.fromEntries(sources));
1623
- });
1624
- }
1625
- });
1626
- }
1627
-
1628
- //#endregion
1629
- //#region src/utils/streamServer.ts
1630
- async function startStreamServer({ port, host, configPath, config, input, args }) {
1631
- const server = createServer(async (req, res) => {
1632
- res.setHeader("Access-Control-Allow-Origin", "*");
1633
- res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
1634
- res.setHeader("Access-Control-Allow-Headers", "Content-Type");
1635
- if (req.method === "OPTIONS") {
1636
- res.writeHead(204);
1637
- res.end();
1638
- return;
1639
- }
1640
- if (req.url === "/api/health" && req.method === "GET") {
1641
- res.writeHead(200, { "Content-Type": "application/json" });
1642
- const body = {
1643
- status: "ok",
1644
- version,
1645
- configPath: path.relative(process$1.cwd(), configPath)
1646
- };
1647
- res.end(JSON.stringify(body));
1648
- return;
1649
- }
1650
- if (req.url === "/api/info" && req.method === "GET") {
1651
- res.writeHead(200, { "Content-Type": "application/json" });
1652
- let specContent;
1653
- if (config && "path" in config.input) {
1654
- const specPath = path.resolve(process$1.cwd(), config.root, config.input.path);
1655
- try {
1656
- specContent = readFileSync(specPath, "utf-8");
1657
- } catch {}
1658
- }
1659
- const body = {
1660
- version,
1661
- configPath: path.relative(process$1.cwd(), configPath),
1662
- spec: specContent,
1663
- config: {
1664
- name: config.name,
1665
- root: config.root,
1666
- input: { path: "path" in config.input ? config.input.path : void 0 },
1667
- output: {
1668
- path: config.output.path,
1669
- write: config.output.write,
1670
- extension: config.output.extension,
1671
- barrelType: config.output.barrelType
1672
- },
1673
- plugins: config.plugins?.map((plugin) => ({
1674
- name: `@kubb/${plugin.name}`,
1675
- options: serializePluginOptions(plugin.options)
1676
- }))
1677
- }
1678
- };
1679
- res.end(JSON.stringify(body));
1680
- return;
1681
- }
1682
- if (req.url === "/api/stream" && req.method === "POST") {
1683
- await handleGenerate(res, config, input, args);
1684
- return;
1685
- }
1686
- res.writeHead(404, { "Content-Type": "application/json" });
1687
- res.end(JSON.stringify({ error: "Not found" }));
1688
- });
1689
- server.listen(port, host, () => {
1690
- const address = server.address();
1691
- const serverUrl = `http://${host}:${typeof address === "object" && address ? address.port : port}`;
1692
- clack.log.success(pc.green(`Stream server started on ${pc.bold(serverUrl)}`));
1693
- clack.log.info(pc.dim(`Config: ${path.relative(process$1.cwd(), configPath)}`));
1694
- clack.log.info(pc.dim(`Connect: ${serverUrl}/api/info`));
1695
- clack.log.info(pc.dim(`Stream: ${serverUrl}/api/stream`));
1696
- clack.log.info(pc.dim(`Health: ${serverUrl}/api/health`));
1697
- clack.log.step(pc.yellow("Waiting for requests... (Press Ctrl+C to stop)"));
1698
- });
1699
- process$1.on("SIGINT", () => {
1700
- clack.log.info("Shutting down stream server...");
1701
- server.close(() => {
1702
- clack.log.success("Server stopped");
1703
- process$1.exit(0);
1704
- });
1705
- });
1706
- }
1707
- async function handleGenerate(res, config, input, args) {
1708
- const events = new AsyncEventEmitter();
1709
- const logLevel = LogLevel[args.logLevel] || 3;
1710
- res.writeHead(200, {
1711
- "Content-Type": "text/event-stream",
1712
- "Cache-Control": "no-cache",
1713
- Connection: "keep-alive"
1714
- });
1715
- function send(type, ...data) {
1716
- res.write(`data: ${JSON.stringify({
1717
- type,
1718
- data
1719
- })}\n\n`);
1720
- }
1721
- await createStreamLogger(res).install(events, { logLevel });
1722
- try {
1723
- await generate({
1724
- input,
1725
- config,
1726
- logLevel,
1727
- events
1728
- });
1729
- send("lifecycle:end");
1730
- } catch (error) {
1731
- send("error", {
1732
- message: error instanceof Error ? error.message : "Unknown error",
1733
- stack: error instanceof Error ? error.stack : void 0
1734
- });
1735
- } finally {
1736
- res.end();
1737
- }
1738
- }
1739
-
1740
1127
  //#endregion
1741
1128
  //#region src/utils/watcher.ts
1742
1129
  async function startWatcher(path$1, cb) {
@@ -1798,21 +1185,6 @@ const command = defineCommand({
1798
1185
  alias: "s",
1799
1186
  default: false
1800
1187
  },
1801
- stream: {
1802
- type: "boolean",
1803
- description: "Start HTTP server with SSE streaming",
1804
- default: false
1805
- },
1806
- port: {
1807
- type: "string",
1808
- description: "Port for stream server (requires --stream). If not specified, an available port is automatically selected.",
1809
- alias: "p"
1810
- },
1811
- host: {
1812
- type: "string",
1813
- description: "Host for stream server (requires --stream)",
1814
- default: "localhost"
1815
- },
1816
1188
  help: {
1817
1189
  type: "boolean",
1818
1190
  description: "Show help",
@@ -1838,20 +1210,6 @@ const command = defineCommand({
1838
1210
  try {
1839
1211
  const result = await getCosmiConfig("kubb", args.config);
1840
1212
  const configs = await getConfigs(result, args);
1841
- if (args.stream) {
1842
- if (configs.length > 1) clack.log.warn(pc.yellow("Stream mode only supports a single configuration. Only the first config will be used."));
1843
- const port = args.port ? Number.parseInt(args.port, 10) : 0;
1844
- const host = args.host;
1845
- await startStreamServer({
1846
- port,
1847
- host,
1848
- configPath: result.filepath,
1849
- config: configs[0],
1850
- input,
1851
- args
1852
- });
1853
- return;
1854
- }
1855
1213
  await events.emit("config:start");
1856
1214
  await events.emit("info", "Config loaded", path.relative(process$2.cwd(), result.filepath));
1857
1215
  await events.emit("success", "Config loaded successfully", path.relative(process$2.cwd(), result.filepath));
@@ -1891,4 +1249,4 @@ var generate_default = command;
1891
1249
 
1892
1250
  //#endregion
1893
1251
  export { generate_default as default };
1894
- //# sourceMappingURL=generate-DgWO-YRb.js.map
1252
+ //# sourceMappingURL=generate-Bgpw_dcv.js.map