UNPKG

@kubb/cli

Version:

Command-line interface for Kubb, enabling easy generation of TypeScript, React-Query, Zod, and other code from OpenAPI specifications.

209 lines (203 loc) • 7.24 kB
import * as process3 from 'process'; import process3__default from 'process'; import { setup, safeBuild } from '@kubb/core'; import { LogMapper, createLogger, randomCliColour } from '@kubb/core/logger'; import { SingleBar, Presets } from 'cli-progress'; import { colors } from 'consola/utils'; import { execa } from 'execa'; import { parseArgsStringToArgv } from 'string-argv'; import { Writable } from 'stream'; import path from 'path'; // src/runners/generate.ts var ConsolaWritable = class extends Writable { consola; command; constructor(consola, command, opts) { super(opts); this.command = command; this.consola = consola; } _write(chunk, _encoding, callback) { process3.stdout.write(`${colors.dim(chunk?.toString())}`); callback(); } }; async function executeHooks({ hooks, logger }) { const commands = Array.isArray(hooks.done) ? hooks.done : [hooks.done].filter(Boolean); for (const command of commands) { const consolaWritable = new ConsolaWritable(logger.consola, command); const [cmd, ..._args] = [...parseArgsStringToArgv(command)]; if (!cmd) { continue; } logger?.emit("start", `Executing hook ${logger.logLevel !== LogMapper.silent ? colors.dim(command) : ""}`); await execa(cmd, _args, { detached: true, stdout: logger?.logLevel === LogMapper.silent ? void 0 : ["pipe", consolaWritable], stripFinalNewline: true }); logger?.emit("success", `Executed hook ${logger.logLevel !== LogMapper.silent ? colors.dim(command) : ""}`); } logger?.emit("success", "Executed hooks"); } // src/utils/getErrorCauses.ts function getErrorCauses(errors) { return errors.reduce((prev, error) => { const causedError = error?.cause; if (causedError) { prev = [...prev, ...getErrorCauses([causedError])]; return prev; } prev = [...prev, error]; return prev; }, []).filter(Boolean); } // src/utils/parseHrtimeToSeconds.ts function parseHrtimeToSeconds(hrtime) { const seconds = (hrtime[0] + hrtime[1] / 1e9).toFixed(3); return seconds; } // src/utils/getSummary.ts function getSummary({ pluginManager, filesCreated, status, hrStart, config }) { const logs = /* @__PURE__ */ new Set(); const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(hrStart)); const buildStartPlugins = pluginManager.executed.filter((item) => item.hookName === "buildStart" && item.plugin.name !== "core").map((item) => item.plugin.name); const buildEndPlugins = pluginManager.executed.filter((item) => item.hookName === "buildEnd" && item.plugin.name !== "core").map((item) => item.plugin.name); const failedPlugins = config.plugins?.filter((plugin) => !buildEndPlugins.includes(plugin.name))?.map((plugin) => plugin.name); const pluginsCount = config.plugins?.length || 0; const meta = { plugins: status === "success" ? `${colors.green(`${buildStartPlugins.length} successful`)}, ${pluginsCount} total` : `${colors.red(`${failedPlugins?.length ?? 1} failed`)}, ${pluginsCount} total`, pluginsFailed: status === "failed" ? failedPlugins?.map((name) => randomCliColour(name))?.join(", ") : void 0, filesCreated, time: `${colors.yellow(`${elapsedSeconds}s`)}`, output: path.isAbsolute(config.root) ? path.resolve(config.root, config.output.path) : config.root }; logs.add( [ [`${colors.bold("Plugins:")} ${meta.plugins}`, true], [`${colors.dim("Failed:")} ${meta.pluginsFailed || "none"}`, !!meta.pluginsFailed], [`${colors.bold("Generated:")} ${meta.filesCreated} files in ${meta.time}`, true], [`${colors.bold("Output:")} ${meta.output}`, true] ].map((item) => { if (item.at(1)) { return item.at(0); } return void 0; }).filter(Boolean).join("\n") ); return [...logs]; } // src/runners/generate.ts async function generate({ input, config, progressCache, args }) { const hrStart = process3__default.hrtime(); const logLevel = LogMapper[args.logLevel] || 3; const logger = createLogger({ logLevel, name: config.name }); const { root = process3__default.cwd(), ...userConfig } = config; const inputPath = input ?? ("path" in userConfig.input ? userConfig.input.path : void 0); if (logger.logLevel !== LogMapper.debug) { logger.on("progress_start", ({ id, size, message = "" }) => { logger.consola?.pauseLogs(); const payload = { id, message }; const progressBar = new SingleBar( { format: "{percentage}% {bar} {value}/{total} | {message}", barsize: 30, clearOnComplete: true, emptyOnZero: true }, Presets.shades_grey ); if (!progressCache.has(id)) { progressCache.set(id, progressBar); progressBar.start(size, 1, payload); } }); logger.on("progress_stop", ({ id }) => { progressCache.get(id)?.stop(); logger.consola?.resumeLogs(); }); logger.on("progressed", ({ id, message = "" }) => { const payload = { id, message }; progressCache.get(id)?.increment(1, payload); }); } const definedConfig = { root, ...userConfig, input: inputPath ? { ...userConfig.input, path: inputPath } : userConfig.input, output: { write: true, barrelType: "named", extension: { ".ts": ".ts" }, ...userConfig.output } }; const pluginManager = await setup({ config: definedConfig, logger }); logger.emit("start", `Building ${logger.logLevel !== LogMapper.silent ? colors.dim(inputPath) : ""}`); const { files, error } = await safeBuild({ config: definedConfig, pluginManager, logger }); if (logger.logLevel === LogMapper.debug) { logger.consola?.start("Writing logs"); const logFiles = await logger.writeLogs(); logger.consola?.success(`Written logs: ${logFiles.join("\n")}`); } const summary = getSummary({ filesCreated: files.length, pluginManager, config: definedConfig, status: error ? "failed" : "success", hrStart }); if (error && logger.consola) { logger.consola?.resumeLogs(); logger.consola.error(`Build failed ${logger.logLevel !== LogMapper.silent ? colors.dim(inputPath) : ""}`); logger.consola.box({ title: `${config.name || ""}`, message: summary.join(""), style: { padding: 2, borderColor: "red", borderStyle: "rounded" } }); const errors = getErrorCauses([error]); if (logger.consola && errors.length && logger.logLevel === LogMapper.debug) { errors.forEach((err) => { logger.consola?.error(err); }); } logger.consola?.error(error); process3__default.exit(1); } if (config.hooks) { await executeHooks({ hooks: config.hooks, logger }); } logger.consola?.log(`\u26A1Build completed ${logger.logLevel !== LogMapper.silent ? colors.dim(inputPath) : ""}`); logger.consola?.box({ title: `${config.name || ""}`, message: summary.join(""), style: { padding: 2, borderColor: "green", borderStyle: "rounded" } }); } export { generate }; //# sourceMappingURL=generate-HUWFJ4IA.js.map //# sourceMappingURL=generate-HUWFJ4IA.js.map