@kubb/cli 5.12.4 → 5.12.6
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/{Telemetry-CstxHeyx.js → Telemetry-Bjn0mrII.js} +2 -2
- package/dist/{Telemetry-CstxHeyx.js.map → Telemetry-Bjn0mrII.js.map} +1 -1
- package/dist/{Telemetry-BkicoE-Z.cjs → Telemetry-CnmBUj6w.cjs} +2 -2
- package/dist/{Telemetry-BkicoE-Z.cjs.map → Telemetry-CnmBUj6w.cjs.map} +1 -1
- package/dist/{background-70s5rqtb.cjs → background-B0GVKZGZ.cjs} +2 -2
- package/dist/{background-70s5rqtb.cjs.map → background-B0GVKZGZ.cjs.map} +1 -1
- package/dist/{background-CPq1NAJT.js → background-BdcvoIOa.js} +2 -2
- package/dist/{background-CPq1NAJT.js.map → background-BdcvoIOa.js.map} +1 -1
- package/dist/{background-Dwiy0N4c.js → background-BeAXQscS.js} +1 -1
- package/dist/{config-Bh00Hwpw.js → config-BD5d6yQG.js} +8 -2
- package/dist/config-BD5d6yQG.js.map +1 -0
- package/dist/{config-D63Gum4F.cjs → config-CsRWusL0.cjs} +8 -2
- package/dist/config-CsRWusL0.cjs.map +1 -0
- package/dist/config-CueFKxKs.js +1 -0
- package/dist/index.cjs +19 -19
- package/dist/index.js +19 -19
- package/dist/{registry-BRWRpTro.js → registry-D1QHBcNK.js} +3 -3
- package/dist/{registry-BRWRpTro.js.map → registry-D1QHBcNK.js.map} +1 -1
- package/dist/{registry-C0e_AKBs.cjs → registry-DsAPRl9s.cjs} +3 -3
- package/dist/{registry-C0e_AKBs.cjs.map → registry-DsAPRl9s.cjs.map} +1 -1
- package/dist/{reporters-B4bdZbKM.js → reporters-CqYdEotX.js} +4 -4
- package/dist/{reporters-B4bdZbKM.js.map → reporters-CqYdEotX.js.map} +1 -1
- package/dist/{reporters-BCr1sLhx.cjs → reporters-D9P1Fj5L.cjs} +4 -4
- package/dist/{reporters-BCr1sLhx.cjs.map → reporters-D9P1Fj5L.cjs.map} +1 -1
- package/dist/{run-DAiTuC3q.js → run-BAav-oJX.js} +8 -8
- package/dist/{run-DAiTuC3q.js.map → run-BAav-oJX.js.map} +1 -1
- package/dist/{run-D9ji3RFo.js → run-BeTIeaKr.js} +2 -2
- package/dist/{run-D9ji3RFo.js.map → run-BeTIeaKr.js.map} +1 -1
- package/dist/{run-BBbDMKQV.js → run-Bu3NVhF_.js} +5 -5
- package/dist/{run-BBbDMKQV.js.map → run-Bu3NVhF_.js.map} +1 -1
- package/dist/{run-DKY7q4MO.cjs → run-CiL76_Ox.cjs} +8 -8
- package/dist/{run-DKY7q4MO.cjs.map → run-CiL76_Ox.cjs.map} +1 -1
- package/dist/{run-BTCJEgx1.js → run-DKSzq1gZ.js} +7 -7
- package/dist/{run-BTCJEgx1.js.map → run-DKSzq1gZ.js.map} +1 -1
- package/dist/{run-ybmOzOWQ.cjs → run-DRd-hex3.cjs} +5 -5
- package/dist/{run-ybmOzOWQ.cjs.map → run-DRd-hex3.cjs.map} +1 -1
- package/dist/{run-n6CWcR7D.js → run-DSqcCfzJ.js} +1 -1
- package/dist/{run-Bep5DR9M.cjs → run-u1kyLMfG.cjs} +2 -2
- package/dist/{run-Bep5DR9M.cjs.map → run-u1kyLMfG.cjs.map} +1 -1
- package/dist/{run-DeCB4qsZ.cjs → run-zM8LuA9X.cjs} +7 -7
- package/dist/{run-DeCB4qsZ.cjs.map → run-zM8LuA9X.cjs.map} +1 -1
- package/dist/{snapshot-CFFW4xh5.cjs → snapshot-BmTdkg9_.cjs} +6 -6
- package/dist/{snapshot-CFFW4xh5.cjs.map → snapshot-BmTdkg9_.cjs.map} +1 -1
- package/dist/{snapshot-C67BxRxn.js → snapshot-o_BPMJIu.js} +6 -6
- package/dist/{snapshot-C67BxRxn.js.map → snapshot-o_BPMJIu.js.map} +1 -1
- package/dist/{status-vo86HTqZ.cjs → status-C47VdG48.cjs} +3 -3
- package/dist/{status-vo86HTqZ.cjs.map → status-C47VdG48.cjs.map} +1 -1
- package/dist/{status-C0SdSTAE.js → status-DKnQ4Uty.js} +3 -3
- package/dist/{status-C0SdSTAE.js.map → status-DKnQ4Uty.js.map} +1 -1
- package/dist/studioWorker.js +2 -2
- package/dist/{summary-CCEwKLOi.cjs → summary-WFRQVDNp.cjs} +3 -3
- package/dist/{summary-CCEwKLOi.cjs.map → summary-WFRQVDNp.cjs.map} +1 -1
- package/dist/{summary-JL96aI9h.js → summary-rD3DP405.js} +3 -3
- package/dist/{summary-JL96aI9h.js.map → summary-rD3DP405.js.map} +1 -1
- package/dist/{text-ul0IR1pq.js → text-BbK3UX0I.js} +2 -2
- package/dist/{text-ul0IR1pq.js.map → text-BbK3UX0I.js.map} +1 -1
- package/dist/{text-BFXVEEQp.cjs → text-DOD7hw-U.cjs} +2 -2
- package/dist/{text-BFXVEEQp.cjs.map → text-DOD7hw-U.cjs.map} +1 -1
- package/dist/{utils-A-f-U1E7.cjs → utils-0MRBnDLb.cjs} +3 -3
- package/dist/{utils-A-f-U1E7.cjs.map → utils-0MRBnDLb.cjs.map} +1 -1
- package/dist/{utils-BZYbuZTD.js → utils-DnkrY3vN.js} +3 -3
- package/dist/{utils-BZYbuZTD.js.map → utils-DnkrY3vN.js.map} +1 -1
- package/package.json +7 -7
- package/dist/config-Bh00Hwpw.js.map +0 -1
- package/dist/config-D63Gum4F.cjs.map +0 -1
- package/dist/config-iVdOcpro.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporters-BCr1sLhx.cjs","names":["logLevelMap","styleText","styleText","process","formatMsWithColor","getElapsedMs","styleText","logLevelMap","styleText","logLevelMap","process","relative","Diagnostics","styleText","getInputKind","resolve","read","pluralize","pluralize","relative","styleText","styleText","logLevelMap","toPermissionFlag","process","getElapsedMs","Diagnostics","pluralize","formatMs","process","formatMs","getElapsedMs","styleText","pluralize","formatBar","formatMsWithColor","defaultWriter","createCliReporter","logLevelMap","resolve","readOutputFiles","isPathInside","readFile","process","createOutputManifest","cacheStorage","diffOutput"],"sources":["../src/loggers/features/context.ts","../src/loggers/features/generation.ts","../src/loggers/features/phases.ts","../src/loggers/specFrame.ts","../src/loggers/features/problems.ts","../src/loggers/features/progress.ts","../src/loggers/features/session.ts","../src/loggers/features/spinner.ts","../src/loggers/features/walk.ts","../src/loggers/features/index.ts","../src/loggers/reporters.ts"],"sourcesContent":["import { styleText } from 'node:util'\nimport { type Config, type Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport type { LoggerWriter } from '../types.ts'\n\n/**\n * What `installLogger` shares with its features: the writer, the verbosity flags, and the two\n * run-wide flags a feature flips for the others to read.\n */\nexport type LoggerContext = {\n hooks: Hookable<KubbHooks>\n writer: LoggerWriter\n logLevel: number\n silent: boolean\n human: boolean\n /** Set once a rich `kubb studio` session connects: each run then shows as one job line. */\n session: boolean\n /** Whether a config's group is open, so a problem can wait for its end. */\n groupOpen: boolean\n /** Prefixes a `[HH:MM:SS]` timestamp at verbose and above. */\n text: (message: string) => string\n /** `✓ message info`, with the info dimmed. */\n line: (symbol: string, message: string, info?: string) => string\n /** Registers a per-run hook. In a Studio session the job line stands for the whole run, so these stay quiet. */\n onRun: <Name extends keyof KubbHooks & string>(name: Name, fn: (...args: KubbHooks[Name]) => unknown) => () => void\n}\n\nexport function createLoggerContext({ hooks, writer, logLevel }: { hooks: Hookable<KubbHooks>; writer: LoggerWriter; logLevel: number }): LoggerContext {\n const text = (message: string) => (logLevel >= logLevelMap.verbose ? `${styleText('dim', `[${clock()}]`)} ${message}` : message)\n const ctx: LoggerContext = {\n hooks,\n writer,\n logLevel,\n silent: logLevel <= logLevelMap.silent,\n human: writer.audience === 'human',\n session: false,\n groupOpen: false,\n text,\n line: (symbol, message, info) => text([symbol, message, info && styleText('dim', info)].filter(Boolean).join(' ')),\n onRun(name, fn) {\n return hooks.hook(name, (...args) => (ctx.session ? undefined : fn(...args)))\n },\n }\n return ctx\n}\n\n/** `HH:MM:SS` in 24-hour time. */\nexport function clock(date = new Date()): string {\n return date.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' })\n}\n\n/** Display path for a config's input: the string form, or its `path` field when the input is an object. */\nexport function getInputPath(config: Config): string | undefined {\n const { input } = config\n if (typeof input === 'string') return input\n return typeof input?.path === 'string' ? input.path : undefined\n}\n","import { styleText } from 'node:util'\nimport type { SummaryRenderer } from '@kubb/core'\nimport type { LogStatus } from '../types.ts'\nimport { getInputPath, type LoggerContext } from './context.ts'\nimport type { Phases } from './phases.ts'\nimport type { Problems } from './problems.ts'\nimport type { Progress } from './progress.ts'\nimport type { Spinner } from './spinner.ts'\nimport type { Walk } from './walk.ts'\n\n/**\n * One config's run: the group it opens, the state every feature resets at its start, and the\n * closing line, which the lifecycle end draws too for a run that threw before its summary.\n */\nexport function createGeneration(\n ctx: LoggerContext,\n { spinner, progress, walk, phases, problems }: { spinner: Spinner; progress: Progress; walk: Walk; phases: Phases; problems: Problems },\n): { renderSummary: SummaryRenderer } {\n const { writer, silent, human, text, hooks, onRun } = ctx\n\n function reset() {\n spinner.reset()\n progress.reset()\n walk.reset()\n phases.reset()\n problems.reset()\n }\n\n // A run that throws before `kubb:generation:end` never reaches the summary, so the lifecycle\n // end calls this too rather than leave a group without its closing line.\n function closeGroup(status: LogStatus) {\n if (!ctx.groupOpen) {\n return\n }\n ctx.groupOpen = false\n\n spinner.stop()\n progress.stop()\n writer.groupEnd(status === 'failed' ? styleText('red', problems.failedTitle()) : styleText('green', '✓ Generation succeeded'))\n }\n\n hooks.hook('kubb:lifecycle:start', () => {\n reset()\n })\n\n onRun('kubb:generation:start', ({ config }) => {\n closeGroup('failed')\n reset()\n\n walk.state.totalPlugins = config.plugins?.length ?? 0\n progress.state.inMemory = config.storage?.name === 'memory'\n problems.setSpec(config)\n\n if (silent) {\n return\n }\n\n const input = getInputPath(config)\n writer.group(text([styleText('bold', config.name ?? 'kubb'), input ? styleText('dim', input) : undefined].filter(Boolean).join(' ')))\n ctx.groupOpen = true\n\n spinner.start('Parsing spec')\n })\n\n onRun('kubb:generation:end', async ({ diagnostics = [] }) => {\n spinner.stop()\n progress.stop()\n problems.state.diagnostics = diagnostics\n await problems.flush()\n })\n\n hooks.hook('kubb:lifecycle:end', async () => {\n await problems.flush()\n closeGroup('failed')\n reset()\n })\n\n const renderSummary: SummaryRenderer = (lines, { status }) => {\n if (silent || !ctx.groupOpen) {\n return\n }\n\n spinner.stop()\n progress.stop()\n if (human) closeGroup(status)\n ctx.groupOpen = false\n writer.diagnostic([...lines])\n }\n\n return { renderSummary }\n}\n","import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { getElapsedMs } from '@internals/utils'\nimport { logLevel as logLevelMap } from '@kubb/core'\nimport { formatMsWithColor } from '../banner.ts'\nimport type { LoggerContext } from './context.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Phases = ReturnType<typeof createPhases>\n\n/**\n * One output phase while its step owns the line. A phase buffers what it is told, because a spinner\n * redraws over anything written under it, and prints the lot once it knows its own result.\n */\ntype Phase = StartPhaseOptions & {\n failed: boolean\n hrStart: [number, number]\n lines: Array<string>\n /**\n * Raw lines a hook printed, drawn outside the group.\n */\n output: Array<string>\n}\n\ntype StartPhaseOptions = {\n /**\n * Shown while the phase runs.\n */\n running: string\n success: string\n failure: string\n /**\n * Whether each hook's own result is worth a line. Format and lint run one command, so the phase\n * result already says everything; the post-generate phase runs several.\n */\n showHookResults?: boolean\n}\n\n/**\n * The three output phases, in the order the generate runner runs them.\n */\nconst PHASES = {\n format: { running: 'Formatting', success: 'Formatted', failure: 'Formatting failed' },\n lint: { running: 'Linting', success: 'Linted', failure: 'Linting failed' },\n hooks: {\n running: 'Running post-generate hooks',\n success: 'Post-generate hooks completed',\n failure: 'Post-generate hooks failed',\n showHookResults: true,\n },\n} as const satisfies Record<string, StartPhaseOptions>\n\n/** A hook's display name: its `name`, or the command line it runs. */\nfunction formatHookLabel({ command, name, args }: { command: string; name?: string; args?: ReadonlyArray<string> }): string {\n return name ?? (args?.length ? `${command} ${args.join(' ')}` : command)\n}\n\n/**\n * Drops the blank lines a subprocess leaves at either end of its output, so its block does not open\n * or close on an empty row.\n */\nfunction trimBlankEdges(lines: ReadonlyArray<string>): Array<string> {\n const start = lines.findIndex((line) => line.trim())\n if (start === -1) {\n return []\n }\n\n return lines.slice(start, lines.findLastIndex((line) => line.trim()) + 1)\n}\n\n/** The format, lint and post-generate phases, and the hooks and messages they buffer while their step owns the line. */\nexport function createPhases({ writer, silent, logLevel, text, line, onRun }: LoggerContext, spinner: Spinner) {\n const state = {\n phase: null as Phase | null,\n hooks: new Map<string, { hrStart: [number, number]; lines: Array<string> }>(),\n }\n\n function startPhase(options: StartPhaseOptions) {\n state.phase = { ...options, failed: false, hrStart: process.hrtime(), lines: [], output: [] }\n spinner.start(options.running)\n }\n\n function endPhase() {\n const phase = state.phase\n state.phase = null\n\n if (!phase || silent) {\n return\n }\n\n const duration = formatMsWithColor(getElapsedMs(phase.hrStart))\n\n spinner.stop(phase.failed ? `${phase.failure} after ${duration}` : `${phase.success} in ${duration}`, phase.failed ? 'failed' : 'success')\n\n if (phase.lines.length) {\n writer.block(phase.lines)\n }\n writeOutput(phase.output)\n }\n\n function writeOutput(lines: ReadonlyArray<string>) {\n const output = trimBlankEdges(lines)\n if (output.length) {\n writer.raw(output)\n }\n }\n\n onRun('kubb:format:start', () => startPhase(PHASES.format))\n onRun('kubb:format:end', endPhase)\n onRun('kubb:lint:start', () => startPhase(PHASES.lint))\n onRun('kubb:lint:end', endPhase)\n onRun('kubb:hooks:start', () => startPhase(PHASES.hooks))\n onRun('kubb:hooks:end', endPhase)\n\n onRun('kubb:hook:end', (ctx) => {\n const { id, command, name, args, success, error } = ctx\n if (!id) {\n return\n }\n\n if (!success && state.phase) {\n state.phase.failed = true\n }\n\n if (silent) {\n // Even when silent, surface a failed hook's captured output. `stdout` and `stderr` only exist on a failed result.\n if (!ctx.success) {\n if (ctx.stdout) console.log(ctx.stdout)\n if (ctx.stderr) console.error(ctx.stderr)\n }\n return\n }\n\n const active = state.hooks.get(id)\n if (!active) {\n return\n }\n state.hooks.delete(id)\n\n const label = styleText('dim', formatHookLabel({ command, name, args }))\n const reason = error?.message ? ` (${error.message})` : ''\n const result = success\n ? `${styleText('green', '✓')} ${label} in ${formatMsWithColor(getElapsedMs(active.hrStart))}`\n : `${styleText('red', '✗')} ${label} failed${reason}`\n\n const phase = state.phase\n if (phase) {\n if (phase.showHookResults || !success) {\n phase.lines.push(result)\n }\n phase.output.push(...active.lines)\n return\n }\n\n spinner.stop()\n writer.step(text(result))\n writeOutput(active.lines)\n })\n\n // Not registered at silent: the missing `kubb:hook:line` listener is also what tells the runner not to stream.\n if (!silent) {\n onRun('kubb:info', ({ message, info }) => {\n const formatted = line(styleText('blue', 'ℹ'), message, info)\n\n // Info carries something new (the auto-detected tool), so inside a phase it waits for the phase to print.\n if (state.phase) {\n state.phase.lines.push(formatted)\n return\n }\n if (spinner.message(formatted)) {\n return\n }\n writer.info(formatted)\n })\n\n onRun('kubb:success', ({ message, info }) => {\n const formatted = line(styleText('green', '✓'), message, logLevel >= logLevelMap.info ? info : undefined)\n\n // The phase step's own result already reports these successes, so let the step carry them.\n if (spinner.message(formatted)) {\n return\n }\n writer.success(formatted)\n })\n\n onRun('kubb:hook:start', ({ id, command, name, args }) => {\n if (!id) {\n return\n }\n state.hooks.set(id, { hrStart: process.hrtime(), lines: [] })\n spinner.message(text(`Running ${styleText('dim', formatHookLabel({ command, name, args }))}`))\n })\n\n onRun('kubb:hook:line', ({ id, line }) => {\n const active = state.hooks.get(id)\n if (!active) {\n return\n }\n\n // A phase step redraws its own line, so its output waits until the phase ends.\n if (state.phase) {\n active.lines.push(line)\n return\n }\n writer.raw([line])\n })\n }\n\n return {\n /** The phase whose step owns the line, so a failure or an info line can wait for it. */\n get phase(): Phase | null {\n return state.phase\n },\n reset() {\n state.phase = null\n state.hooks = new Map()\n },\n }\n}\n","import { styleText } from 'node:util'\nimport type { Adapter, DiagnosticLocation } from '@kubb/core'\n\n/**\n * A location in source text, with a terminal code frame that underlines it.\n */\nexport type SpecPosition = {\n line: number\n column: number\n frame: Array<string>\n}\n\n/**\n * Where `location` sits in `source` according to its adapter, with a code frame. `undefined` when the adapter cannot place it.\n */\nexport function locateInSpec({ adapter, source, location }: { adapter: Adapter; source: string; location: DiagnosticLocation }): SpecPosition | undefined {\n const lines = source.split(/\\r?\\n/)\n try {\n const range = adapter.locate?.(source, location)\n if (!range) return undefined\n const before = source.slice(0, range.start).split('\\n')\n const line = before.length\n const column = before.at(-1)!.length + 1\n const text = lines[line - 1] ?? ''\n const width = String(line).length\n const gutter = (number?: number) => styleText('dim', `${number === undefined ? ''.padStart(width) : String(number).padStart(width)} │`)\n const carets = '^'.repeat(Math.max(1, Math.min(range.end - range.start, text.length - column + 1)))\n return {\n line,\n column,\n frame: [\n ...(line > 1 ? [`${gutter(line - 1)} ${lines[line - 2]}`] : []),\n `${gutter(line)} ${text}`,\n `${gutter()} ${' '.repeat(column - 1)}${styleText('red', carets)}`,\n ],\n }\n } catch {\n return undefined\n }\n}\n","import { relative, resolve } from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { read } from '@internals/utils'\nimport type { Adapter, Config, Diagnostic, DiagnosticFormatOptions, ProblemDiagnostic } from '@kubb/core'\nimport { Diagnostics, getInputKind, logLevel as logLevelMap } from '@kubb/core'\nimport { pluralize } from '../../ui/text.ts'\nimport { locateInSpec } from '../specFrame.ts'\nimport { getInputPath, type LoggerContext } from './context.ts'\nimport type { Phases } from './phases.ts'\nimport type { Progress } from './progress.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Problems = ReturnType<typeof createProblems>\n\n/** Warnings, errors and diagnostics: printed as they come, or held back and grouped by plugin once a human's build ends. */\nexport function createProblems(ctx: LoggerContext, spinner: Spinner, progress: Progress, phases: Phases) {\n const { writer, silent, human, logLevel, text, line, hooks } = ctx\n const { audience } = writer\n const formatOptions: DiagnosticFormatOptions = {\n audience,\n verbose: logLevel >= logLevelMap.verbose,\n // The code lines up at the right edge, inside the group indent and the human view's per-problem indent.\n width: Math.min(process.stdout.columns || 80, 100) - (audience === 'human' ? 4 : 2),\n }\n const state = {\n /** Problems held back so the human view can print them grouped by plugin once the build ends. */\n problems: [] as Array<ProblemDiagnostic>,\n /** The finished config's diagnostics, for the closing verdict. */\n diagnostics: [] as Array<Diagnostic>,\n /** A local-file input, which a located diagnostic points into; `load` parses it once, on the first such diagnostic. */\n spec: undefined as { path: string; adapter: Adapter; source: Promise<string | undefined> } | undefined,\n }\n\n /** Format options for one problem, with its line and column in a local spec when its pointer resolves there. */\n async function optionsFor(problem: ProblemDiagnostic): Promise<DiagnosticFormatOptions> {\n const { location } = problem\n const { spec } = state\n if (!location || !spec) {\n return formatOptions\n }\n\n const source = await spec.source\n const position = source && locateInSpec({ adapter: spec.adapter, source, location })\n if (!position) {\n return formatOptions\n }\n return { ...formatOptions, position: { file: relative(process.cwd(), spec.path), ...position } }\n }\n\n /**\n * Prints problems grouped under their plugin's name, each with the code aligned at the right.\n */\n async function writeProblems(problems: ReadonlyArray<ProblemDiagnostic>) {\n if (!problems.length) {\n return\n }\n const formatted = await Promise.all(problems.map(async (problem) => Diagnostics.format(problem, await optionsFor(problem))))\n if (!human) {\n for (const lines of formatted) writer.diagnostic(lines)\n return\n }\n\n const byPlugin = Map.groupBy(\n problems.map((problem, index) => ({ plugin: problem.plugin ?? '', lines: formatted[index]! })),\n ({ plugin }) => plugin,\n )\n const lines = [...byPlugin].flatMap(([plugin, group]) => [\n ...(plugin ? [` ${styleText('bold', plugin)}`, ''] : []),\n ...group.flatMap((entry) => [...entry.lines.map((entryLine) => ` ${entryLine}`), '']),\n ])\n writer.diagnostic(lines.slice(0, -1))\n }\n\n hooks.hook('kubb:warn', ({ message, info }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n\n writer.warn(line(styleText('yellow', '⚠'), message, logLevel >= logLevelMap.info ? info : undefined))\n })\n\n // Unguarded: a failure stays visible even at silent.\n hooks.hook('kubb:error', ({ error }) => {\n const phase = phases.phase\n if (phase) {\n phase.failed = true\n }\n\n // Rendered as a `KUBB_UNKNOWN` diagnostic, so the output alone says what broke and where. The\n // name tells a `TypeError` from a plain `Error`.\n const message = error.name === 'Error' || Diagnostics.isError(error) ? error.message : `${error.name}: ${error.message}`\n const help = Diagnostics.isError(error) ? error.diagnostic.help : undefined\n const [headline = '', ...details] = Diagnostics.format({ code: Diagnostics.code.unknown, severity: 'error', message, help, cause: error }, formatOptions)\n\n if (!human) {\n spinner.stop()\n progress.stop()\n writer.diagnostic([headline, ...details])\n return\n }\n\n // The writer draws the error symbol, so the message goes in bare.\n if (spinner.active) {\n spinner.stop(message, 'failed')\n } else {\n writer.error(text(message))\n }\n if (details.length) {\n writer.block(details.map(text))\n }\n })\n\n hooks.hook('kubb:diagnostic', async ({ diagnostic }) => {\n // Silent still surfaces errors so failures stay visible. It drops warnings and info.\n if (silent && diagnostic.severity !== 'error') {\n return\n }\n // A Studio job's problems show in Studio; its job line counts the errors.\n if (ctx.session && !Diagnostics.isUpdate(diagnostic)) {\n return\n }\n\n spinner.stop()\n progress.stop()\n\n if (Diagnostics.isUpdate(diagnostic)) {\n writer.update(\n [`\\`v${diagnostic.currentVersion}\\` → \\`v${diagnostic.latestVersion}\\``, 'Run `npm install -g @kubb/cli` to update'],\n 'Update available for `Kubb`',\n )\n return\n }\n\n // Inside a build, the human view waits for the end to group by plugin.\n if (human && ctx.groupOpen) {\n state.problems.push(diagnostic)\n return\n }\n await writeProblems([diagnostic])\n })\n\n return {\n state,\n /** Points located diagnostics into the config's input when it is a local file. */\n setSpec(config: Config) {\n const input = getInputPath(config)\n if (input && config.adapter?.locate && getInputKind(input) === 'file') {\n const path = resolve(config.root, input)\n // Read lazily, once, and only when a diagnostic needs a frame.\n let source: Promise<string | undefined> | undefined\n state.spec = {\n path,\n adapter: config.adapter,\n get source() {\n return (source ??= read(path).catch(() => undefined))\n },\n }\n }\n },\n /** Prints the problems held back so far. */\n flush() {\n return writeProblems(state.problems.splice(0))\n },\n /** `✖ Failed 1 error · 1 warning in plugin-ts` once the build ended, or `✗ Generation failed` for a run that stopped early. */\n failedTitle(): string {\n const { errors, warnings } = Diagnostics.count(state.diagnostics)\n const counts = [errors && pluralize(errors, 'error'), warnings && pluralize(warnings, 'warning')].filter(Boolean).join(' · ')\n if (!human || !counts) {\n return '✗ Generation failed'\n }\n const plugins = Diagnostics.failedPlugins(state.diagnostics)\n return `✖ Failed ${counts}${plugins.length ? ` in ${plugins.join(', ')}` : ''}`\n },\n reset() {\n Object.assign(state, { problems: [], diagnostics: [], spec: undefined })\n },\n }\n}\n","import { relative } from 'node:path'\nimport { styleText } from 'node:util'\nimport { pluralize } from '../../ui/text.ts'\nimport type { WriterProgress } from '../types.ts'\nimport type { LoggerContext } from './context.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Progress = ReturnType<typeof createProgress>\n\n/** The progress bar over the file writes, and the counts the summary line shows. */\nexport function createProgress({ writer, silent, text, onRun }: LoggerContext, spinner: Spinner) {\n const state = {\n progress: null as WriterProgress | null,\n totalFiles: 0,\n processedFiles: 0,\n /** Whether this run keeps its files in memory, as a `kubb studio` run without `--allow-write` does. */\n inMemory: false,\n }\n\n function stop(message?: string) {\n const progress = state.progress\n if (!progress) {\n return\n }\n state.progress = null\n progress.stop(message === undefined ? '' : text(message))\n }\n\n if (!silent) {\n onRun('kubb:files:processing:start', ({ files }) => {\n spinner.stop()\n state.totalFiles = files.length\n state.processedFiles = 0\n\n state.progress = writer.progress(files.length)\n state.progress.start(text(`${state.inMemory ? 'Generating' : 'Writing'} ${pluralize(files.length, 'file')}`))\n })\n\n onRun('kubb:files:processing:update', ({ files }) => {\n for (const { file, config } of files) {\n state.processedFiles++\n state.progress?.advance(`${state.inMemory ? 'Generating' : 'Writing'} ${relative(config.root, file.path)}`)\n }\n })\n\n onRun('kubb:files:processing:end', ({ files, unchanged }) => {\n const skipped = unchanged.length ? styleText('dim', ` · ${unchanged.length} unchanged`) : ''\n stop(\n state.inMemory\n ? `Generated ${pluralize(state.processedFiles, 'file')} in memory`\n : `Wrote ${pluralize(files.length - unchanged.length, 'file')}${skipped}`,\n )\n })\n }\n\n return {\n state,\n stop,\n reset() {\n stop()\n Object.assign(state, { totalFiles: 0, processedFiles: 0, inMemory: false })\n },\n }\n}\n","import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, getElapsedMs } from '@internals/utils'\nimport { Diagnostics, logLevel as logLevelMap } from '@kubb/core'\nimport { pluralize, toPermissionFlag } from '../../ui/text.ts'\nimport { clock, type LoggerContext } from './context.ts'\nimport type { Spinner } from './spinner.ts'\n\n/** One line of a Studio session's job log: the time, the command, who asked for it, and how it ended. */\nfunction formatJobLine({ command, result, requestedBy }: { command: string; result: string; requestedBy?: string }): string {\n const by = requestedBy ? `${styleText('dim', `by ${requestedBy}`.padEnd(16))} ` : ''\n return `${styleText('dim', clock())} ${command.padEnd(10)} ${by}${result}`\n}\n\n/**\n * A `kubb studio` session. It emits these on the same emitter as its generations, so one logger\n * renders the whole command: the connection, then one job line per command.\n */\nexport function createSession(ctx: LoggerContext, spinner: Spinner) {\n const { writer, silent, human, logLevel, text, hooks } = ctx\n\n hooks.hook('studio:disconnected', ({ code, reason }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n\n spinner.stop()\n // 4002 is `AgentCloseCode.SUPERSEDED`, spelled out because `@kubb/studio` is an optional peer.\n if (code === 4002) {\n writer.warn(text('⚠ Another process connected to Kubb Studio as this agent, so this one stopped'))\n return\n }\n writer.warn(text(`⚠ Kubb Studio ended the session (${reason || `code ${code}`})`))\n })\n\n hooks.hook('studio:warn', ({ message, permission }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n const remedy = permission ? `; pass ${toPermissionFlag(permission)} to allow it` : ''\n // A warning drawn under a running spinner leaves a stale spinner frame above it, so it pauses the spinner like a job line does.\n const paused = spinner.active\n spinner.stop()\n writer.warn(text(`⚠ ${message}${remedy}`))\n if (paused) spinner.start('Ready for jobs')\n })\n\n // Unguarded, like `kubb:error`: a failure stays visible even at silent.\n hooks.hook('studio:error', ({ error }) => {\n if (spinner.active) {\n spinner.stop(error.message, 'failed')\n return\n }\n writer.error(text(error.message))\n })\n\n if (silent) {\n return\n }\n\n // The last generation's outcome, for the job line `studio:command` prints after it.\n let job: { fileCount: number; ms: number; errors: number } | null = null\n\n hooks.hook('studio:connected', ({ url, versions: { studio, kubb, agent } }) => {\n ctx.session = human\n spinner.stop()\n // The runtime version shows only when it differs from the host's.\n const versions = [`v${agent}`, kubb !== agent ? `runtime v${kubb}` : undefined, `Studio v${studio}`].filter(Boolean).join(' · ')\n writer.success(text(`✓ Connected to ${styleText('cyan', url)} ${styleText('dim', `· ${versions}`)}`))\n spinner.start('Ready for jobs')\n })\n\n hooks.hook('kubb:generation:start', () => {\n if (ctx.session) spinner.message(text('Generating'))\n })\n\n hooks.hook('kubb:generation:end', ({ diagnostics = [], filesCreated = 0, status, hrStart = process.hrtime() }) => {\n job = { fileCount: filesCreated, ms: getElapsedMs(hrStart), errors: status === 'failed' ? Diagnostics.count(diagnostics).errors : 0 }\n })\n\n hooks.hook('studio:command', ({ command, info, requestedBy, failed }) => {\n spinner.stop()\n const took = command === 'generate' && job ? `${pluralize(job.fileCount, 'file')} in ${formatMs(job.ms)} ` : ''\n const result = failed\n ? `${styleText('red', '✖')} ${job?.errors ? pluralize(job.errors, 'error') : 'failed'}, see Studio`\n : `${styleText('green', '✓')} ${took}${styleText('dim', `(${info})`)}`\n writer.info(formatJobLine({ command, requestedBy, result }))\n job = null\n spinner.start('Ready for jobs')\n })\n\n hooks.hook('studio:reconnecting', ({ delayMs }) => {\n spinner.stop()\n writer.info(text(styleText('dim', `Retrying connection to Kubb Studio in ${formatMs(delayMs)}`)))\n })\n}\n","import type { LogStatus, WriterSpinner } from '../types.ts'\nimport type { LoggerContext } from './context.ts'\n\nexport type Spinner = ReturnType<typeof createSpinner>\n\n/** The step whose end is not known when it starts: the spec parse, the node walk, a phase, or a Studio session waiting for jobs. */\nexport function createSpinner({ writer, silent, text }: LoggerContext) {\n let spinner: WriterSpinner | null = null\n\n function stop(message?: string, status: LogStatus = 'success') {\n const active = spinner\n if (!active) {\n return\n }\n spinner = null\n\n if (message === undefined) {\n active.clear()\n return\n }\n if (status === 'failed') {\n active.error(text(message))\n return\n }\n active.stop(text(message))\n }\n\n return {\n /** Whether a spinner is drawing right now. */\n get active(): boolean {\n return spinner !== null\n },\n start(message: string) {\n if (silent) {\n return\n }\n\n spinner = writer.spinner()\n spinner.start(text(message))\n },\n stop,\n /** Redraws the spinner's line. `false` when no spinner is running, so the caller prints the line itself. */\n message(line: string): boolean {\n if (!spinner) {\n return false\n }\n spinner.message(line)\n return true\n },\n reset: () => stop(),\n }\n}\n","import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, getElapsedMs } from '@internals/utils'\nimport { formatBar, formatMsWithColor } from '../banner.ts'\nimport { pluralize } from '../../ui/text.ts'\nimport type { LoggerContext } from './context.ts'\nimport type { Progress } from './progress.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Walk = ReturnType<typeof createWalk>\n\n/** Milliseconds between redraws of the live generation block, about clack's spinner frame rate. */\nconst WALK_REDRAW_MS = 80\n\nfunction createState() {\n return {\n totalPlugins: 0,\n completedPlugins: 0,\n failedPlugins: 0,\n /** `process.hrtime()` snapshot taken at the start of generation, for the elapsed time. */\n hrStart: process.hrtime(),\n /** Plugin results held back while the generation step owns the line. */\n pluginLines: [] as Array<string>,\n /** The node walk's live state: the spec's node total, the distinct nodes generated, and each plugin's count and current node. */\n walk: { total: 0, visited: new Set<string>(), plugins: new Map<string, { count: number; current: string }>() },\n lastWalkDraw: 0,\n }\n}\n\n/** The node walk the plugins share: the live generation block, and the plugin results printed once the walk ends. */\nexport function createWalk({ writer, silent, human, text, onRun }: LoggerContext, spinner: Spinner, progress: Progress) {\n const state = createState()\n\n /** The progress summary line the clack logger shows, `null` when there is nothing to display. */\n function buildProgressLine(): string | null {\n const parts: Array<string> = []\n const duration = formatMs(getElapsedMs(state.hrStart))\n const { totalFiles, processedFiles } = progress.state\n\n if (state.totalPlugins > 0) {\n const failed = state.failedPlugins > 0 ? ` ${styleText('red', `(${state.failedPlugins} failed)`)}` : ''\n parts.push(`Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins}${failed}`)\n }\n\n if (totalFiles > 0) {\n parts.push(`Files ${styleText('green', processedFiles.toString())}/${totalFiles}`)\n }\n\n if (parts.length === 0) {\n return null\n }\n\n parts.push(`${styleText('green', duration)} elapsed`)\n return parts.join(styleText('dim', ' | '))\n }\n\n if (!silent) {\n onRun('kubb:build:start', ({ nodeCounts: { schemas, operations } }) => {\n state.walk.total = schemas + operations\n const details = `${pluralize(schemas, 'schema')} · ${pluralize(operations, 'operation')} · ${formatMs(getElapsedMs(state.hrStart))}`\n spinner.stop(`Parsed spec ${styleText('dim', details)}`)\n spinner.start('Generating')\n })\n\n // Plugins all end after one shared node walk, so per-node hooks keep the step live; plain output would get a line per node.\n if (human) {\n const onNode = (key: string, name: string, plugin: string) => {\n const { total, visited, plugins } = state.walk\n visited.add(key)\n plugins.set(plugin, { count: (plugins.get(plugin)?.count ?? 0) + 1, current: name })\n\n // Counting stays per node; the redraw waits for the spinner's next frame.\n const now = Date.now()\n if (now - state.lastWalkDraw < WALK_REDRAW_MS) return\n state.lastWalkDraw = now\n\n const elapsed = styleText('dim', formatMs(getElapsedMs(state.hrStart)))\n const head = total\n ? `Generating ${formatBar(visited.size, total)} ${visited.size}/${total} nodes ${elapsed}`\n : `Generating ${pluralize(visited.size, 'node')} ${elapsed}`\n const width = Math.max(...[...plugins.keys()].map((pluginName) => pluginName.length))\n const rows = [...plugins].map(\n ([pluginName, row]) =>\n `${styleText('dim', '│')} ${pluginName.padEnd(width)} ${styleText('dim', String(row.count).padStart(4))} ${styleText('cyan', row.current)}`,\n )\n spinner.message(text([head, ...rows].join('\\n')))\n }\n\n onRun('kubb:generate:schema', (node, { plugin }) => onNode(`schema:${node.name}`, node.name ?? 'schema', plugin.name))\n onRun('kubb:generate:operation', (node, { plugin }) => onNode(`operation:${node.operationId}`, node.operationId, plugin.name))\n }\n\n // Buffered, not printed: a step redraws over anything written while it runs.\n onRun('kubb:plugin:end', ({ plugin, duration, success }) => {\n state[success ? 'completedPlugins' : 'failedPlugins']++\n state.pluginLines.push(text(`${plugin.name} ${success ? 'completed' : 'failed'} in ${formatMsWithColor(duration)}`))\n })\n\n onRun('kubb:plugins:end', () => {\n const failed = state.failedPlugins > 0\n spinner.stop(buildProgressLine() ?? undefined, failed ? 'failed' : 'success')\n\n if (state.pluginLines.length) {\n writer.block(state.pluginLines)\n state.pluginLines = []\n }\n })\n }\n\n return {\n state,\n reset() {\n Object.assign(state, createState())\n },\n }\n}\n","import type { Hookable, KubbHooks, SummaryRenderer } from '@kubb/core'\nimport type { LoggerWriter } from '../types.ts'\nimport { createLoggerContext } from './context.ts'\nimport { createGeneration } from './generation.ts'\nimport { createPhases } from './phases.ts'\nimport { createProblems } from './problems.ts'\nimport { createProgress } from './progress.ts'\nimport { createSession } from './session.ts'\nimport { createSpinner } from './spinner.ts'\nimport { createWalk } from './walk.ts'\n\n/**\n * Wires a {@link LoggerWriter} onto the run's hooks. Each feature registers the hooks for one\n * concern, so every writer reports the same run in the same order: one group per config, a step\n * over the plugin work, a progress bar for the writes, one step per output phase, then the summary.\n * It hands back `renderSummary`, which writes the `cli` reporter's summary inside the group opened\n * for that config and closes the group.\n */\nexport function installLogger({ hooks, writer, logLevel }: { hooks: Hookable<KubbHooks>; writer: LoggerWriter; logLevel: number }): {\n renderSummary: SummaryRenderer\n} {\n const ctx = createLoggerContext({ hooks, writer, logLevel })\n const spinner = createSpinner(ctx)\n const progress = createProgress(ctx, spinner)\n const walk = createWalk(ctx, spinner, progress)\n const phases = createPhases(ctx, spinner)\n const problems = createProblems(ctx, spinner, progress, phases)\n createSession(ctx, spinner)\n return createGeneration(ctx, { spinner, progress, walk, phases, problems })\n}\n","import process from 'node:process'\nimport { resolve } from 'node:path'\nimport { readFile } from 'node:fs/promises'\nimport { isPathInside } from '@internals/utils'\nimport type { GenerationResult, Hookable, KubbHooks, Reporter, ReporterContext } from '@kubb/core'\nimport { cacheStorage, createCliReporter, createOutputManifest, logLevel as logLevelMap } from '@kubb/core'\nimport { writer as defaultWriter } from '../ui/log.ts'\nimport { installLogger } from './features/index.ts'\nimport type { LoggerWriter } from './types.ts'\nimport { diffOutput, readOutputFiles } from '../runners/generate/utils.ts'\n\n/** Installs the live logger and wires the selected reporters. `cli` renders its summary through the logger, and is skipped when `json` owns stdout. */\nfunction setupReporters(\n context: Hookable<KubbHooks>,\n {\n logLevel,\n reporters,\n writer = defaultWriter(),\n dryRun = false,\n }: {\n /** Output verbosity. Use the `logLevel` constants exported from `@kubb/core`. */\n logLevel: number\n reporters: ReadonlyArray<Reporter>\n /** Overrides the terminal-based pick, e.g. the plain writer for `kubb studio snapshot`. */\n writer?: LoggerWriter\n /**\n * Labels the memory-backed generation as a preview rather than a completed write.\n */\n dryRun?: boolean\n },\n): void {\n const hasJson = reporters.some((reporter) => reporter.name === 'json')\n const selected = reporters.flatMap((reporter) => {\n if (reporter.name !== 'cli') return [reporter]\n if (hasJson) return []\n return [createCliReporter({ render: installLogger({ hooks: context, writer, logLevel }).renderSummary })]\n })\n const ctx: ReporterContext = { logLevel }\n const pluginFiles = selected.some((reporter) => reporter.needsPluginFiles) ? new Map<string, Array<string>>() : undefined\n const seen = new Set<string>()\n if (pluginFiles) {\n context.hook('kubb:plugin:end', ({ plugin, files }) => {\n for (const file of files) {\n if (seen.has(file.path)) continue\n seen.add(file.path)\n const paths = pluginFiles.get(plugin.name) ?? []\n paths.push(file.path)\n pluginFiles.set(plugin.name, paths)\n }\n })\n }\n\n // Configs generate one at a time, so the last write before `kubb:generation:end` is this config's.\n let filesUnchanged = 0\n let previous: Map<string, string> | undefined\n let paths: Array<string> = []\n let outputPath = ''\n const trackChanges = selected.some((reporter) => reporter.name === 'cli') && logLevel > logLevelMap.silent\n context.hook('kubb:generation:start', async ({ config }) => {\n pluginFiles?.clear()\n seen.clear()\n filesUnchanged = 0\n paths = []\n outputPath = resolve(config.root, config.output.path)\n previous = trackChanges && (dryRun || config.storage?.name === 'fs') ? await readOutputFiles(outputPath) : undefined\n })\n context.hook('kubb:files:processing:start', async ({ files }) => {\n if (!previous) return\n // Plugin output can live outside the main output folder; capture it before writes start.\n for (const file of files) {\n if (previous.has(file.path) || isPathInside(outputPath, file.path)) continue\n const source = await readFile(file.path, 'utf8').catch(() => null)\n if (source !== null) previous.set(file.path, source)\n }\n })\n context.hook('kubb:files:processing:end', ({ files, unchanged }) => {\n filesUnchanged = unchanged.length\n paths = files.map((file) => file.path)\n })\n\n context.hook('kubb:generation:end', async ({ config, storage, diagnostics = [], filesCreated = 0, status = 'success', hrStart = process.hrtime() }) => {\n const result: GenerationResult = { config, diagnostics, filesCreated, filesUnchanged, dryRun, status, hrStart }\n const cliResult = { ...result }\n if (previous && status !== 'failed') {\n const manifest = dryRun ? await createOutputManifest({ storage, cache: cacheStorage({ root: config.root }) }) : undefined\n const diff = await diffOutput({\n storage,\n paths,\n clean: Boolean(config.output.clean),\n manifest,\n previousFiles: previous,\n })\n const changes = { added: 0, modified: 0, deleted: 0, linesAdded: 0, linesRemoved: 0 }\n const counts = { A: 'added', M: 'modified', D: 'deleted' } as const\n for (const file of diff.files) {\n changes[counts[file.status]]++\n changes.linesAdded += file.added ?? 0\n changes.linesRemoved += file.removed ?? 0\n }\n cliResult.filesCreated = changes.added + changes.modified + diff.unchanged\n cliResult.filesUnchanged = diff.unchanged\n cliResult.fileChanges = changes\n }\n for (const reporter of selected) {\n const grouped = reporter.needsPluginFiles && pluginFiles?.size ? [...pluginFiles].map(([plugin, files]) => ({ plugin, files: [...files] })) : undefined\n await reporter.report({ ...(reporter.name === 'cli' ? cliResult : result), pluginFiles: grouped }, ctx)\n }\n })\n\n context.hook('kubb:lifecycle:end', async () => {\n for (const reporter of selected) await reporter.drain?.(ctx)\n })\n}\n\nexport default setupReporters\n\n/** Picks the reporters whose `name` is in `names`, in the given order (the CLI maps `--reporter` to this); duplicates and unknown names are skipped. */\nexport function selectReporters(reporters: ReadonlyArray<Reporter>, names: ReadonlyArray<string>): Array<Reporter> {\n return [...new Set(names)].flatMap((name) => reporters.find((reporter) => reporter.name === name) ?? [])\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reporters-D9P1Fj5L.cjs","names":["logLevelMap","styleText","styleText","process","formatMsWithColor","getElapsedMs","styleText","logLevelMap","styleText","logLevelMap","process","relative","Diagnostics","styleText","getInputKind","resolve","read","pluralize","pluralize","relative","styleText","styleText","logLevelMap","toPermissionFlag","process","getElapsedMs","Diagnostics","pluralize","formatMs","process","formatMs","getElapsedMs","styleText","pluralize","formatBar","formatMsWithColor","defaultWriter","createCliReporter","logLevelMap","resolve","readOutputFiles","isPathInside","readFile","process","createOutputManifest","cacheStorage","diffOutput"],"sources":["../src/loggers/features/context.ts","../src/loggers/features/generation.ts","../src/loggers/features/phases.ts","../src/loggers/specFrame.ts","../src/loggers/features/problems.ts","../src/loggers/features/progress.ts","../src/loggers/features/session.ts","../src/loggers/features/spinner.ts","../src/loggers/features/walk.ts","../src/loggers/features/index.ts","../src/loggers/reporters.ts"],"sourcesContent":["import { styleText } from 'node:util'\nimport { type Config, type Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport type { LoggerWriter } from '../types.ts'\n\n/**\n * What `installLogger` shares with its features: the writer, the verbosity flags, and the two\n * run-wide flags a feature flips for the others to read.\n */\nexport type LoggerContext = {\n hooks: Hookable<KubbHooks>\n writer: LoggerWriter\n logLevel: number\n silent: boolean\n human: boolean\n /** Set once a rich `kubb studio` session connects: each run then shows as one job line. */\n session: boolean\n /** Whether a config's group is open, so a problem can wait for its end. */\n groupOpen: boolean\n /** Prefixes a `[HH:MM:SS]` timestamp at verbose and above. */\n text: (message: string) => string\n /** `✓ message info`, with the info dimmed. */\n line: (symbol: string, message: string, info?: string) => string\n /** Registers a per-run hook. In a Studio session the job line stands for the whole run, so these stay quiet. */\n onRun: <Name extends keyof KubbHooks & string>(name: Name, fn: (...args: KubbHooks[Name]) => unknown) => () => void\n}\n\nexport function createLoggerContext({ hooks, writer, logLevel }: { hooks: Hookable<KubbHooks>; writer: LoggerWriter; logLevel: number }): LoggerContext {\n const text = (message: string) => (logLevel >= logLevelMap.verbose ? `${styleText('dim', `[${clock()}]`)} ${message}` : message)\n const ctx: LoggerContext = {\n hooks,\n writer,\n logLevel,\n silent: logLevel <= logLevelMap.silent,\n human: writer.audience === 'human',\n session: false,\n groupOpen: false,\n text,\n line: (symbol, message, info) => text([symbol, message, info && styleText('dim', info)].filter(Boolean).join(' ')),\n onRun(name, fn) {\n return hooks.hook(name, (...args) => (ctx.session ? undefined : fn(...args)))\n },\n }\n return ctx\n}\n\n/** `HH:MM:SS` in 24-hour time. */\nexport function clock(date = new Date()): string {\n return date.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' })\n}\n\n/** Display path for a config's input: the string form, or its `path` field when the input is an object. */\nexport function getInputPath(config: Config): string | undefined {\n const { input } = config\n if (typeof input === 'string') return input\n return typeof input?.path === 'string' ? input.path : undefined\n}\n","import { styleText } from 'node:util'\nimport type { SummaryRenderer } from '@kubb/core'\nimport type { LogStatus } from '../types.ts'\nimport { getInputPath, type LoggerContext } from './context.ts'\nimport type { Phases } from './phases.ts'\nimport type { Problems } from './problems.ts'\nimport type { Progress } from './progress.ts'\nimport type { Spinner } from './spinner.ts'\nimport type { Walk } from './walk.ts'\n\n/**\n * One config's run: the group it opens, the state every feature resets at its start, and the\n * closing line, which the lifecycle end draws too for a run that threw before its summary.\n */\nexport function createGeneration(\n ctx: LoggerContext,\n { spinner, progress, walk, phases, problems }: { spinner: Spinner; progress: Progress; walk: Walk; phases: Phases; problems: Problems },\n): { renderSummary: SummaryRenderer } {\n const { writer, silent, human, text, hooks, onRun } = ctx\n\n function reset() {\n spinner.reset()\n progress.reset()\n walk.reset()\n phases.reset()\n problems.reset()\n }\n\n // A run that throws before `kubb:generation:end` never reaches the summary, so the lifecycle\n // end calls this too rather than leave a group without its closing line.\n function closeGroup(status: LogStatus) {\n if (!ctx.groupOpen) {\n return\n }\n ctx.groupOpen = false\n\n spinner.stop()\n progress.stop()\n writer.groupEnd(status === 'failed' ? styleText('red', problems.failedTitle()) : styleText('green', '✓ Generation succeeded'))\n }\n\n hooks.hook('kubb:lifecycle:start', () => {\n reset()\n })\n\n onRun('kubb:generation:start', ({ config }) => {\n closeGroup('failed')\n reset()\n\n walk.state.totalPlugins = config.plugins?.length ?? 0\n progress.state.inMemory = config.storage?.name === 'memory'\n problems.setSpec(config)\n\n if (silent) {\n return\n }\n\n const input = getInputPath(config)\n writer.group(text([styleText('bold', config.name ?? 'kubb'), input ? styleText('dim', input) : undefined].filter(Boolean).join(' ')))\n ctx.groupOpen = true\n\n spinner.start('Parsing spec')\n })\n\n onRun('kubb:generation:end', async ({ diagnostics = [] }) => {\n spinner.stop()\n progress.stop()\n problems.state.diagnostics = diagnostics\n await problems.flush()\n })\n\n hooks.hook('kubb:lifecycle:end', async () => {\n await problems.flush()\n closeGroup('failed')\n reset()\n })\n\n const renderSummary: SummaryRenderer = (lines, { status }) => {\n if (silent || !ctx.groupOpen) {\n return\n }\n\n spinner.stop()\n progress.stop()\n if (human) closeGroup(status)\n ctx.groupOpen = false\n writer.diagnostic([...lines])\n }\n\n return { renderSummary }\n}\n","import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { getElapsedMs } from '@internals/utils'\nimport { logLevel as logLevelMap } from '@kubb/core'\nimport { formatMsWithColor } from '../banner.ts'\nimport type { LoggerContext } from './context.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Phases = ReturnType<typeof createPhases>\n\n/**\n * One output phase while its step owns the line. A phase buffers what it is told, because a spinner\n * redraws over anything written under it, and prints the lot once it knows its own result.\n */\ntype Phase = StartPhaseOptions & {\n failed: boolean\n hrStart: [number, number]\n lines: Array<string>\n /**\n * Raw lines a hook printed, drawn outside the group.\n */\n output: Array<string>\n}\n\ntype StartPhaseOptions = {\n /**\n * Shown while the phase runs.\n */\n running: string\n success: string\n failure: string\n /**\n * Whether each hook's own result is worth a line. Format and lint run one command, so the phase\n * result already says everything; the post-generate phase runs several.\n */\n showHookResults?: boolean\n}\n\n/**\n * The three output phases, in the order the generate runner runs them.\n */\nconst PHASES = {\n format: { running: 'Formatting', success: 'Formatted', failure: 'Formatting failed' },\n lint: { running: 'Linting', success: 'Linted', failure: 'Linting failed' },\n hooks: {\n running: 'Running post-generate hooks',\n success: 'Post-generate hooks completed',\n failure: 'Post-generate hooks failed',\n showHookResults: true,\n },\n} as const satisfies Record<string, StartPhaseOptions>\n\n/** A hook's display name: its `name`, or the command line it runs. */\nfunction formatHookLabel({ command, name, args }: { command: string; name?: string; args?: ReadonlyArray<string> }): string {\n return name ?? (args?.length ? `${command} ${args.join(' ')}` : command)\n}\n\n/**\n * Drops the blank lines a subprocess leaves at either end of its output, so its block does not open\n * or close on an empty row.\n */\nfunction trimBlankEdges(lines: ReadonlyArray<string>): Array<string> {\n const start = lines.findIndex((line) => line.trim())\n if (start === -1) {\n return []\n }\n\n return lines.slice(start, lines.findLastIndex((line) => line.trim()) + 1)\n}\n\n/** The format, lint and post-generate phases, and the hooks and messages they buffer while their step owns the line. */\nexport function createPhases({ writer, silent, logLevel, text, line, onRun }: LoggerContext, spinner: Spinner) {\n const state = {\n phase: null as Phase | null,\n hooks: new Map<string, { hrStart: [number, number]; lines: Array<string> }>(),\n }\n\n function startPhase(options: StartPhaseOptions) {\n state.phase = { ...options, failed: false, hrStart: process.hrtime(), lines: [], output: [] }\n spinner.start(options.running)\n }\n\n function endPhase() {\n const phase = state.phase\n state.phase = null\n\n if (!phase || silent) {\n return\n }\n\n const duration = formatMsWithColor(getElapsedMs(phase.hrStart))\n\n spinner.stop(phase.failed ? `${phase.failure} after ${duration}` : `${phase.success} in ${duration}`, phase.failed ? 'failed' : 'success')\n\n if (phase.lines.length) {\n writer.block(phase.lines)\n }\n writeOutput(phase.output)\n }\n\n function writeOutput(lines: ReadonlyArray<string>) {\n const output = trimBlankEdges(lines)\n if (output.length) {\n writer.raw(output)\n }\n }\n\n onRun('kubb:format:start', () => startPhase(PHASES.format))\n onRun('kubb:format:end', endPhase)\n onRun('kubb:lint:start', () => startPhase(PHASES.lint))\n onRun('kubb:lint:end', endPhase)\n onRun('kubb:hooks:start', () => startPhase(PHASES.hooks))\n onRun('kubb:hooks:end', endPhase)\n\n onRun('kubb:hook:end', (ctx) => {\n const { id, command, name, args, success, error } = ctx\n if (!id) {\n return\n }\n\n if (!success && state.phase) {\n state.phase.failed = true\n }\n\n if (silent) {\n // Even when silent, surface a failed hook's captured output. `stdout` and `stderr` only exist on a failed result.\n if (!ctx.success) {\n if (ctx.stdout) console.log(ctx.stdout)\n if (ctx.stderr) console.error(ctx.stderr)\n }\n return\n }\n\n const active = state.hooks.get(id)\n if (!active) {\n return\n }\n state.hooks.delete(id)\n\n const label = styleText('dim', formatHookLabel({ command, name, args }))\n const reason = error?.message ? ` (${error.message})` : ''\n const result = success\n ? `${styleText('green', '✓')} ${label} in ${formatMsWithColor(getElapsedMs(active.hrStart))}`\n : `${styleText('red', '✗')} ${label} failed${reason}`\n\n const phase = state.phase\n if (phase) {\n if (phase.showHookResults || !success) {\n phase.lines.push(result)\n }\n phase.output.push(...active.lines)\n return\n }\n\n spinner.stop()\n writer.step(text(result))\n writeOutput(active.lines)\n })\n\n // Not registered at silent: the missing `kubb:hook:line` listener is also what tells the runner not to stream.\n if (!silent) {\n onRun('kubb:info', ({ message, info }) => {\n const formatted = line(styleText('blue', 'ℹ'), message, info)\n\n // Info carries something new (the auto-detected tool), so inside a phase it waits for the phase to print.\n if (state.phase) {\n state.phase.lines.push(formatted)\n return\n }\n if (spinner.message(formatted)) {\n return\n }\n writer.info(formatted)\n })\n\n onRun('kubb:success', ({ message, info }) => {\n const formatted = line(styleText('green', '✓'), message, logLevel >= logLevelMap.info ? info : undefined)\n\n // The phase step's own result already reports these successes, so let the step carry them.\n if (spinner.message(formatted)) {\n return\n }\n writer.success(formatted)\n })\n\n onRun('kubb:hook:start', ({ id, command, name, args }) => {\n if (!id) {\n return\n }\n state.hooks.set(id, { hrStart: process.hrtime(), lines: [] })\n spinner.message(text(`Running ${styleText('dim', formatHookLabel({ command, name, args }))}`))\n })\n\n onRun('kubb:hook:line', ({ id, line }) => {\n const active = state.hooks.get(id)\n if (!active) {\n return\n }\n\n // A phase step redraws its own line, so its output waits until the phase ends.\n if (state.phase) {\n active.lines.push(line)\n return\n }\n writer.raw([line])\n })\n }\n\n return {\n /** The phase whose step owns the line, so a failure or an info line can wait for it. */\n get phase(): Phase | null {\n return state.phase\n },\n reset() {\n state.phase = null\n state.hooks = new Map()\n },\n }\n}\n","import { styleText } from 'node:util'\nimport type { Adapter, DiagnosticLocation } from '@kubb/core'\n\n/**\n * A location in source text, with a terminal code frame that underlines it.\n */\nexport type SpecPosition = {\n line: number\n column: number\n frame: Array<string>\n}\n\n/**\n * Where `location` sits in `source` according to its adapter, with a code frame. `undefined` when the adapter cannot place it.\n */\nexport function locateInSpec({ adapter, source, location }: { adapter: Adapter; source: string; location: DiagnosticLocation }): SpecPosition | undefined {\n const lines = source.split(/\\r?\\n/)\n try {\n const range = adapter.locate?.(source, location)\n if (!range) return undefined\n const before = source.slice(0, range.start).split('\\n')\n const line = before.length\n const column = before.at(-1)!.length + 1\n const text = lines[line - 1] ?? ''\n const width = String(line).length\n const gutter = (number?: number) => styleText('dim', `${number === undefined ? ''.padStart(width) : String(number).padStart(width)} │`)\n const carets = '^'.repeat(Math.max(1, Math.min(range.end - range.start, text.length - column + 1)))\n return {\n line,\n column,\n frame: [\n ...(line > 1 ? [`${gutter(line - 1)} ${lines[line - 2]}`] : []),\n `${gutter(line)} ${text}`,\n `${gutter()} ${' '.repeat(column - 1)}${styleText('red', carets)}`,\n ],\n }\n } catch {\n return undefined\n }\n}\n","import { relative, resolve } from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { read } from '@internals/utils'\nimport type { Adapter, Config, Diagnostic, DiagnosticFormatOptions, ProblemDiagnostic } from '@kubb/core'\nimport { Diagnostics, getInputKind, logLevel as logLevelMap } from '@kubb/core'\nimport { pluralize } from '../../ui/text.ts'\nimport { locateInSpec } from '../specFrame.ts'\nimport { getInputPath, type LoggerContext } from './context.ts'\nimport type { Phases } from './phases.ts'\nimport type { Progress } from './progress.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Problems = ReturnType<typeof createProblems>\n\n/** Warnings, errors and diagnostics: printed as they come, or held back and grouped by plugin once a human's build ends. */\nexport function createProblems(ctx: LoggerContext, spinner: Spinner, progress: Progress, phases: Phases) {\n const { writer, silent, human, logLevel, text, line, hooks } = ctx\n const { audience } = writer\n const formatOptions: DiagnosticFormatOptions = {\n audience,\n verbose: logLevel >= logLevelMap.verbose,\n // The code lines up at the right edge, inside the group indent and the human view's per-problem indent.\n width: Math.min(process.stdout.columns || 80, 100) - (audience === 'human' ? 4 : 2),\n }\n const state = {\n /** Problems held back so the human view can print them grouped by plugin once the build ends. */\n problems: [] as Array<ProblemDiagnostic>,\n /** The finished config's diagnostics, for the closing verdict. */\n diagnostics: [] as Array<Diagnostic>,\n /** A local-file input, which a located diagnostic points into; `load` parses it once, on the first such diagnostic. */\n spec: undefined as { path: string; adapter: Adapter; source: Promise<string | undefined> } | undefined,\n }\n\n /** Format options for one problem, with its line and column in a local spec when its pointer resolves there. */\n async function optionsFor(problem: ProblemDiagnostic): Promise<DiagnosticFormatOptions> {\n const { location } = problem\n const { spec } = state\n if (!location || !spec) {\n return formatOptions\n }\n\n const source = await spec.source\n const position = source && locateInSpec({ adapter: spec.adapter, source, location })\n if (!position) {\n return formatOptions\n }\n return { ...formatOptions, position: { file: relative(process.cwd(), spec.path), ...position } }\n }\n\n /**\n * Prints problems grouped under their plugin's name, each with the code aligned at the right.\n */\n async function writeProblems(problems: ReadonlyArray<ProblemDiagnostic>) {\n if (!problems.length) {\n return\n }\n const formatted = await Promise.all(problems.map(async (problem) => Diagnostics.format(problem, await optionsFor(problem))))\n if (!human) {\n for (const lines of formatted) writer.diagnostic(lines)\n return\n }\n\n const byPlugin = Map.groupBy(\n problems.map((problem, index) => ({ plugin: problem.plugin ?? '', lines: formatted[index]! })),\n ({ plugin }) => plugin,\n )\n const lines = [...byPlugin].flatMap(([plugin, group]) => [\n ...(plugin ? [` ${styleText('bold', plugin)}`, ''] : []),\n ...group.flatMap((entry) => [...entry.lines.map((entryLine) => ` ${entryLine}`), '']),\n ])\n writer.diagnostic(lines.slice(0, -1))\n }\n\n hooks.hook('kubb:warn', ({ message, info }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n\n writer.warn(line(styleText('yellow', '⚠'), message, logLevel >= logLevelMap.info ? info : undefined))\n })\n\n // Unguarded: a failure stays visible even at silent.\n hooks.hook('kubb:error', ({ error }) => {\n const phase = phases.phase\n if (phase) {\n phase.failed = true\n }\n\n // Rendered as a `KUBB_UNKNOWN` diagnostic, so the output alone says what broke and where. The\n // name tells a `TypeError` from a plain `Error`.\n const message = error.name === 'Error' || Diagnostics.isError(error) ? error.message : `${error.name}: ${error.message}`\n const help = Diagnostics.isError(error) ? error.diagnostic.help : undefined\n const [headline = '', ...details] = Diagnostics.format({ code: Diagnostics.code.unknown, severity: 'error', message, help, cause: error }, formatOptions)\n\n if (!human) {\n spinner.stop()\n progress.stop()\n writer.diagnostic([headline, ...details])\n return\n }\n\n // The writer draws the error symbol, so the message goes in bare.\n if (spinner.active) {\n spinner.stop(message, 'failed')\n } else {\n writer.error(text(message))\n }\n if (details.length) {\n writer.block(details.map(text))\n }\n })\n\n hooks.hook('kubb:diagnostic', async ({ diagnostic }) => {\n // Silent still surfaces errors so failures stay visible. It drops warnings and info.\n if (silent && diagnostic.severity !== 'error') {\n return\n }\n // A Studio job's problems show in Studio; its job line counts the errors.\n if (ctx.session && !Diagnostics.isUpdate(diagnostic)) {\n return\n }\n\n spinner.stop()\n progress.stop()\n\n if (Diagnostics.isUpdate(diagnostic)) {\n writer.update(\n [`\\`v${diagnostic.currentVersion}\\` → \\`v${diagnostic.latestVersion}\\``, 'Run `npm install -g @kubb/cli` to update'],\n 'Update available for `Kubb`',\n )\n return\n }\n\n // Inside a build, the human view waits for the end to group by plugin.\n if (human && ctx.groupOpen) {\n state.problems.push(diagnostic)\n return\n }\n await writeProblems([diagnostic])\n })\n\n return {\n state,\n /** Points located diagnostics into the config's input when it is a local file. */\n setSpec(config: Config) {\n const input = getInputPath(config)\n if (input && config.adapter?.locate && getInputKind(input) === 'file') {\n const path = resolve(config.root, input)\n // Read lazily, once, and only when a diagnostic needs a frame.\n let source: Promise<string | undefined> | undefined\n state.spec = {\n path,\n adapter: config.adapter,\n get source() {\n return (source ??= read(path).catch(() => undefined))\n },\n }\n }\n },\n /** Prints the problems held back so far. */\n flush() {\n return writeProblems(state.problems.splice(0))\n },\n /** `✖ Failed 1 error · 1 warning in plugin-ts` once the build ended, or `✗ Generation failed` for a run that stopped early. */\n failedTitle(): string {\n const { errors, warnings } = Diagnostics.count(state.diagnostics)\n const counts = [errors && pluralize(errors, 'error'), warnings && pluralize(warnings, 'warning')].filter(Boolean).join(' · ')\n if (!human || !counts) {\n return '✗ Generation failed'\n }\n const plugins = Diagnostics.failedPlugins(state.diagnostics)\n return `✖ Failed ${counts}${plugins.length ? ` in ${plugins.join(', ')}` : ''}`\n },\n reset() {\n Object.assign(state, { problems: [], diagnostics: [], spec: undefined })\n },\n }\n}\n","import { relative } from 'node:path'\nimport { styleText } from 'node:util'\nimport { pluralize } from '../../ui/text.ts'\nimport type { WriterProgress } from '../types.ts'\nimport type { LoggerContext } from './context.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Progress = ReturnType<typeof createProgress>\n\n/** The progress bar over the file writes, and the counts the summary line shows. */\nexport function createProgress({ writer, silent, text, onRun }: LoggerContext, spinner: Spinner) {\n const state = {\n progress: null as WriterProgress | null,\n totalFiles: 0,\n processedFiles: 0,\n /** Whether this run keeps its files in memory, as a `kubb studio` run without `--allow-write` does. */\n inMemory: false,\n }\n\n function stop(message?: string) {\n const progress = state.progress\n if (!progress) {\n return\n }\n state.progress = null\n progress.stop(message === undefined ? '' : text(message))\n }\n\n if (!silent) {\n onRun('kubb:files:processing:start', ({ files }) => {\n spinner.stop()\n state.totalFiles = files.length\n state.processedFiles = 0\n\n state.progress = writer.progress(files.length)\n state.progress.start(text(`${state.inMemory ? 'Generating' : 'Writing'} ${pluralize(files.length, 'file')}`))\n })\n\n onRun('kubb:files:processing:update', ({ files }) => {\n for (const { file, config } of files) {\n state.processedFiles++\n state.progress?.advance(`${state.inMemory ? 'Generating' : 'Writing'} ${relative(config.root, file.path)}`)\n }\n })\n\n onRun('kubb:files:processing:end', ({ files, unchanged }) => {\n const skipped = unchanged.length ? styleText('dim', ` · ${unchanged.length} unchanged`) : ''\n stop(\n state.inMemory\n ? `Generated ${pluralize(state.processedFiles, 'file')} in memory`\n : `Wrote ${pluralize(files.length - unchanged.length, 'file')}${skipped}`,\n )\n })\n }\n\n return {\n state,\n stop,\n reset() {\n stop()\n Object.assign(state, { totalFiles: 0, processedFiles: 0, inMemory: false })\n },\n }\n}\n","import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, getElapsedMs } from '@internals/utils'\nimport { Diagnostics, logLevel as logLevelMap } from '@kubb/core'\nimport { pluralize, toPermissionFlag } from '../../ui/text.ts'\nimport { clock, type LoggerContext } from './context.ts'\nimport type { Spinner } from './spinner.ts'\n\n/** One line of a Studio session's job log: the time, the command, who asked for it, and how it ended. */\nfunction formatJobLine({ command, result, requestedBy }: { command: string; result: string; requestedBy?: string }): string {\n const by = requestedBy ? `${styleText('dim', `by ${requestedBy}`.padEnd(16))} ` : ''\n return `${styleText('dim', clock())} ${command.padEnd(10)} ${by}${result}`\n}\n\n/**\n * A `kubb studio` session. It emits these on the same emitter as its generations, so one logger\n * renders the whole command: the connection, then one job line per command.\n */\nexport function createSession(ctx: LoggerContext, spinner: Spinner) {\n const { writer, silent, human, logLevel, text, hooks } = ctx\n\n hooks.hook('studio:disconnected', ({ code, reason }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n\n spinner.stop()\n // 4002 is `AgentCloseCode.SUPERSEDED`, spelled out because `@kubb/studio` is an optional peer.\n if (code === 4002) {\n writer.warn(text('⚠ Another process connected to Kubb Studio as this agent, so this one stopped'))\n return\n }\n writer.warn(text(`⚠ Kubb Studio ended the session (${reason || `code ${code}`})`))\n })\n\n hooks.hook('studio:warn', ({ message, permission }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n const remedy = permission ? `; pass ${toPermissionFlag(permission)} to allow it` : ''\n // A warning drawn under a running spinner leaves a stale spinner frame above it, so it pauses the spinner like a job line does.\n const paused = spinner.active\n spinner.stop()\n writer.warn(text(`⚠ ${message}${remedy}`))\n if (paused) spinner.start('Ready for jobs')\n })\n\n // Unguarded, like `kubb:error`: a failure stays visible even at silent.\n hooks.hook('studio:error', ({ error }) => {\n if (spinner.active) {\n spinner.stop(error.message, 'failed')\n return\n }\n writer.error(text(error.message))\n })\n\n if (silent) {\n return\n }\n\n // The last generation's outcome, for the job line `studio:command` prints after it.\n let job: { fileCount: number; ms: number; errors: number } | null = null\n\n hooks.hook('studio:connected', ({ url, versions: { studio, kubb, agent } }) => {\n ctx.session = human\n spinner.stop()\n // The runtime version shows only when it differs from the host's.\n const versions = [`v${agent}`, kubb !== agent ? `runtime v${kubb}` : undefined, `Studio v${studio}`].filter(Boolean).join(' · ')\n writer.success(text(`✓ Connected to ${styleText('cyan', url)} ${styleText('dim', `· ${versions}`)}`))\n spinner.start('Ready for jobs')\n })\n\n hooks.hook('kubb:generation:start', () => {\n if (ctx.session) spinner.message(text('Generating'))\n })\n\n hooks.hook('kubb:generation:end', ({ diagnostics = [], filesCreated = 0, status, hrStart = process.hrtime() }) => {\n job = { fileCount: filesCreated, ms: getElapsedMs(hrStart), errors: status === 'failed' ? Diagnostics.count(diagnostics).errors : 0 }\n })\n\n hooks.hook('studio:command', ({ command, info, requestedBy, failed }) => {\n spinner.stop()\n const took = command === 'generate' && job ? `${pluralize(job.fileCount, 'file')} in ${formatMs(job.ms)} ` : ''\n const result = failed\n ? `${styleText('red', '✖')} ${job?.errors ? pluralize(job.errors, 'error') : 'failed'}, see Studio`\n : `${styleText('green', '✓')} ${took}${styleText('dim', `(${info})`)}`\n writer.info(formatJobLine({ command, requestedBy, result }))\n job = null\n spinner.start('Ready for jobs')\n })\n\n hooks.hook('studio:reconnecting', ({ delayMs }) => {\n spinner.stop()\n writer.info(text(styleText('dim', `Retrying connection to Kubb Studio in ${formatMs(delayMs)}`)))\n })\n}\n","import type { LogStatus, WriterSpinner } from '../types.ts'\nimport type { LoggerContext } from './context.ts'\n\nexport type Spinner = ReturnType<typeof createSpinner>\n\n/** The step whose end is not known when it starts: the spec parse, the node walk, a phase, or a Studio session waiting for jobs. */\nexport function createSpinner({ writer, silent, text }: LoggerContext) {\n let spinner: WriterSpinner | null = null\n\n function stop(message?: string, status: LogStatus = 'success') {\n const active = spinner\n if (!active) {\n return\n }\n spinner = null\n\n if (message === undefined) {\n active.clear()\n return\n }\n if (status === 'failed') {\n active.error(text(message))\n return\n }\n active.stop(text(message))\n }\n\n return {\n /** Whether a spinner is drawing right now. */\n get active(): boolean {\n return spinner !== null\n },\n start(message: string) {\n if (silent) {\n return\n }\n\n spinner = writer.spinner()\n spinner.start(text(message))\n },\n stop,\n /** Redraws the spinner's line. `false` when no spinner is running, so the caller prints the line itself. */\n message(line: string): boolean {\n if (!spinner) {\n return false\n }\n spinner.message(line)\n return true\n },\n reset: () => stop(),\n }\n}\n","import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, getElapsedMs } from '@internals/utils'\nimport { formatBar, formatMsWithColor } from '../banner.ts'\nimport { pluralize } from '../../ui/text.ts'\nimport type { LoggerContext } from './context.ts'\nimport type { Progress } from './progress.ts'\nimport type { Spinner } from './spinner.ts'\n\nexport type Walk = ReturnType<typeof createWalk>\n\n/** Milliseconds between redraws of the live generation block, about clack's spinner frame rate. */\nconst WALK_REDRAW_MS = 80\n\nfunction createState() {\n return {\n totalPlugins: 0,\n completedPlugins: 0,\n failedPlugins: 0,\n /** `process.hrtime()` snapshot taken at the start of generation, for the elapsed time. */\n hrStart: process.hrtime(),\n /** Plugin results held back while the generation step owns the line. */\n pluginLines: [] as Array<string>,\n /** The node walk's live state: the spec's node total, the distinct nodes generated, and each plugin's count and current node. */\n walk: { total: 0, visited: new Set<string>(), plugins: new Map<string, { count: number; current: string }>() },\n lastWalkDraw: 0,\n }\n}\n\n/** The node walk the plugins share: the live generation block, and the plugin results printed once the walk ends. */\nexport function createWalk({ writer, silent, human, text, onRun }: LoggerContext, spinner: Spinner, progress: Progress) {\n const state = createState()\n\n /** The progress summary line the clack logger shows, `null` when there is nothing to display. */\n function buildProgressLine(): string | null {\n const parts: Array<string> = []\n const duration = formatMs(getElapsedMs(state.hrStart))\n const { totalFiles, processedFiles } = progress.state\n\n if (state.totalPlugins > 0) {\n const failed = state.failedPlugins > 0 ? ` ${styleText('red', `(${state.failedPlugins} failed)`)}` : ''\n parts.push(`Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins}${failed}`)\n }\n\n if (totalFiles > 0) {\n parts.push(`Files ${styleText('green', processedFiles.toString())}/${totalFiles}`)\n }\n\n if (parts.length === 0) {\n return null\n }\n\n parts.push(`${styleText('green', duration)} elapsed`)\n return parts.join(styleText('dim', ' | '))\n }\n\n if (!silent) {\n onRun('kubb:build:start', ({ nodeCounts: { schemas, operations } }) => {\n state.walk.total = schemas + operations\n const details = `${pluralize(schemas, 'schema')} · ${pluralize(operations, 'operation')} · ${formatMs(getElapsedMs(state.hrStart))}`\n spinner.stop(`Parsed spec ${styleText('dim', details)}`)\n spinner.start('Generating')\n })\n\n // Plugins all end after one shared node walk, so per-node hooks keep the step live; plain output would get a line per node.\n if (human) {\n const onNode = (key: string, name: string, plugin: string) => {\n const { total, visited, plugins } = state.walk\n visited.add(key)\n plugins.set(plugin, { count: (plugins.get(plugin)?.count ?? 0) + 1, current: name })\n\n // Counting stays per node; the redraw waits for the spinner's next frame.\n const now = Date.now()\n if (now - state.lastWalkDraw < WALK_REDRAW_MS) return\n state.lastWalkDraw = now\n\n const elapsed = styleText('dim', formatMs(getElapsedMs(state.hrStart)))\n const head = total\n ? `Generating ${formatBar(visited.size, total)} ${visited.size}/${total} nodes ${elapsed}`\n : `Generating ${pluralize(visited.size, 'node')} ${elapsed}`\n const width = Math.max(...[...plugins.keys()].map((pluginName) => pluginName.length))\n const rows = [...plugins].map(\n ([pluginName, row]) =>\n `${styleText('dim', '│')} ${pluginName.padEnd(width)} ${styleText('dim', String(row.count).padStart(4))} ${styleText('cyan', row.current)}`,\n )\n spinner.message(text([head, ...rows].join('\\n')))\n }\n\n onRun('kubb:generate:schema', (node, { plugin }) => onNode(`schema:${node.name}`, node.name ?? 'schema', plugin.name))\n onRun('kubb:generate:operation', (node, { plugin }) => onNode(`operation:${node.operationId}`, node.operationId, plugin.name))\n }\n\n // Buffered, not printed: a step redraws over anything written while it runs.\n onRun('kubb:plugin:end', ({ plugin, duration, success }) => {\n state[success ? 'completedPlugins' : 'failedPlugins']++\n state.pluginLines.push(text(`${plugin.name} ${success ? 'completed' : 'failed'} in ${formatMsWithColor(duration)}`))\n })\n\n onRun('kubb:plugins:end', () => {\n const failed = state.failedPlugins > 0\n spinner.stop(buildProgressLine() ?? undefined, failed ? 'failed' : 'success')\n\n if (state.pluginLines.length) {\n writer.block(state.pluginLines)\n state.pluginLines = []\n }\n })\n }\n\n return {\n state,\n reset() {\n Object.assign(state, createState())\n },\n }\n}\n","import type { Hookable, KubbHooks, SummaryRenderer } from '@kubb/core'\nimport type { LoggerWriter } from '../types.ts'\nimport { createLoggerContext } from './context.ts'\nimport { createGeneration } from './generation.ts'\nimport { createPhases } from './phases.ts'\nimport { createProblems } from './problems.ts'\nimport { createProgress } from './progress.ts'\nimport { createSession } from './session.ts'\nimport { createSpinner } from './spinner.ts'\nimport { createWalk } from './walk.ts'\n\n/**\n * Wires a {@link LoggerWriter} onto the run's hooks. Each feature registers the hooks for one\n * concern, so every writer reports the same run in the same order: one group per config, a step\n * over the plugin work, a progress bar for the writes, one step per output phase, then the summary.\n * It hands back `renderSummary`, which writes the `cli` reporter's summary inside the group opened\n * for that config and closes the group.\n */\nexport function installLogger({ hooks, writer, logLevel }: { hooks: Hookable<KubbHooks>; writer: LoggerWriter; logLevel: number }): {\n renderSummary: SummaryRenderer\n} {\n const ctx = createLoggerContext({ hooks, writer, logLevel })\n const spinner = createSpinner(ctx)\n const progress = createProgress(ctx, spinner)\n const walk = createWalk(ctx, spinner, progress)\n const phases = createPhases(ctx, spinner)\n const problems = createProblems(ctx, spinner, progress, phases)\n createSession(ctx, spinner)\n return createGeneration(ctx, { spinner, progress, walk, phases, problems })\n}\n","import process from 'node:process'\nimport { resolve } from 'node:path'\nimport { readFile } from 'node:fs/promises'\nimport { isPathInside } from '@internals/utils'\nimport type { GenerationResult, Hookable, KubbHooks, Reporter, ReporterContext } from '@kubb/core'\nimport { cacheStorage, createCliReporter, createOutputManifest, logLevel as logLevelMap } from '@kubb/core'\nimport { writer as defaultWriter } from '../ui/log.ts'\nimport { installLogger } from './features/index.ts'\nimport type { LoggerWriter } from './types.ts'\nimport { diffOutput, readOutputFiles } from '../runners/generate/utils.ts'\n\n/** Installs the live logger and wires the selected reporters. `cli` renders its summary through the logger, and is skipped when `json` owns stdout. */\nfunction setupReporters(\n context: Hookable<KubbHooks>,\n {\n logLevel,\n reporters,\n writer = defaultWriter(),\n dryRun = false,\n }: {\n /** Output verbosity. Use the `logLevel` constants exported from `@kubb/core`. */\n logLevel: number\n reporters: ReadonlyArray<Reporter>\n /** Overrides the terminal-based pick, e.g. the plain writer for `kubb studio snapshot`. */\n writer?: LoggerWriter\n /**\n * Labels the memory-backed generation as a preview rather than a completed write.\n */\n dryRun?: boolean\n },\n): void {\n const hasJson = reporters.some((reporter) => reporter.name === 'json')\n const selected = reporters.flatMap((reporter) => {\n if (reporter.name !== 'cli') return [reporter]\n if (hasJson) return []\n return [createCliReporter({ render: installLogger({ hooks: context, writer, logLevel }).renderSummary })]\n })\n const ctx: ReporterContext = { logLevel }\n const pluginFiles = selected.some((reporter) => reporter.needsPluginFiles) ? new Map<string, Array<string>>() : undefined\n const seen = new Set<string>()\n if (pluginFiles) {\n context.hook('kubb:plugin:end', ({ plugin, files }) => {\n for (const file of files) {\n if (seen.has(file.path)) continue\n seen.add(file.path)\n const paths = pluginFiles.get(plugin.name) ?? []\n paths.push(file.path)\n pluginFiles.set(plugin.name, paths)\n }\n })\n }\n\n // Configs generate one at a time, so the last write before `kubb:generation:end` is this config's.\n let filesUnchanged = 0\n let previous: Map<string, string> | undefined\n let paths: Array<string> = []\n let outputPath = ''\n const trackChanges = selected.some((reporter) => reporter.name === 'cli') && logLevel > logLevelMap.silent\n context.hook('kubb:generation:start', async ({ config }) => {\n pluginFiles?.clear()\n seen.clear()\n filesUnchanged = 0\n paths = []\n outputPath = resolve(config.root, config.output.path)\n previous = trackChanges && (dryRun || config.storage?.name === 'fs') ? await readOutputFiles(outputPath) : undefined\n })\n context.hook('kubb:files:processing:start', async ({ files }) => {\n if (!previous) return\n // Plugin output can live outside the main output folder; capture it before writes start.\n for (const file of files) {\n if (previous.has(file.path) || isPathInside(outputPath, file.path)) continue\n const source = await readFile(file.path, 'utf8').catch(() => null)\n if (source !== null) previous.set(file.path, source)\n }\n })\n context.hook('kubb:files:processing:end', ({ files, unchanged }) => {\n filesUnchanged = unchanged.length\n paths = files.map((file) => file.path)\n })\n\n context.hook('kubb:generation:end', async ({ config, storage, diagnostics = [], filesCreated = 0, status = 'success', hrStart = process.hrtime() }) => {\n const result: GenerationResult = { config, diagnostics, filesCreated, filesUnchanged, dryRun, status, hrStart }\n const cliResult = { ...result }\n if (previous && status !== 'failed') {\n const manifest = dryRun ? await createOutputManifest({ storage, cache: cacheStorage({ root: config.root }) }) : undefined\n const diff = await diffOutput({\n storage,\n paths,\n clean: Boolean(config.output.clean),\n manifest,\n previousFiles: previous,\n })\n const changes = { added: 0, modified: 0, deleted: 0, linesAdded: 0, linesRemoved: 0 }\n const counts = { A: 'added', M: 'modified', D: 'deleted' } as const\n for (const file of diff.files) {\n changes[counts[file.status]]++\n changes.linesAdded += file.added ?? 0\n changes.linesRemoved += file.removed ?? 0\n }\n cliResult.filesCreated = changes.added + changes.modified + diff.unchanged\n cliResult.filesUnchanged = diff.unchanged\n cliResult.fileChanges = changes\n }\n for (const reporter of selected) {\n const grouped = reporter.needsPluginFiles && pluginFiles?.size ? [...pluginFiles].map(([plugin, files]) => ({ plugin, files: [...files] })) : undefined\n await reporter.report({ ...(reporter.name === 'cli' ? cliResult : result), pluginFiles: grouped }, ctx)\n }\n })\n\n context.hook('kubb:lifecycle:end', async () => {\n for (const reporter of selected) await reporter.drain?.(ctx)\n })\n}\n\nexport default setupReporters\n\n/** Picks the reporters whose `name` is in `names`, in the given order (the CLI maps `--reporter` to this); duplicates and unknown names are skipped. */\nexport function selectReporters(reporters: ReadonlyArray<Reporter>, names: ReadonlyArray<string>): Array<Reporter> {\n return [...new Set(names)].flatMap((name) => reporters.find((reporter) => reporter.name === name) ?? [])\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
2
|
import { n as toError } from "./errors-DmC83ALX.js";
|
|
3
|
-
import { n as trackRun, r as version, s as isCIEnvironment } from "./Telemetry-
|
|
4
|
-
import { c as createSpinner } from "./utils-
|
|
5
|
-
import { _ as isRichOutput, a as logOutro, c as logBlock, d as logStep, g as canUseTTY, h as plainWriter, i as logIntro, n as toPermissionFlag, s as logTip } from "./text-
|
|
6
|
-
import { r as KUBB_CONFIG_FILENAME, t as getConfigs } from "./config-
|
|
3
|
+
import { n as trackRun, r as version, s as isCIEnvironment } from "./Telemetry-Bjn0mrII.js";
|
|
4
|
+
import { c as createSpinner } from "./utils-DnkrY3vN.js";
|
|
5
|
+
import { _ as isRichOutput, a as logOutro, c as logBlock, d as logStep, g as canUseTTY, h as plainWriter, i as logIntro, n as toPermissionFlag, s as logTip } from "./text-BbK3UX0I.js";
|
|
6
|
+
import { r as KUBB_CONFIG_FILENAME, t as getConfigs } from "./config-BD5d6yQG.js";
|
|
7
7
|
import { a as readCredentials, n as getCredentialsPath, o as writeCredentials, r as getMachineId, t as clearCredentials } from "./credentials-CZK6zPLv.js";
|
|
8
|
-
import { n as setupReporters } from "./reporters-
|
|
8
|
+
import { n as setupReporters } from "./reporters-CqYdEotX.js";
|
|
9
9
|
import { styleText } from "node:util";
|
|
10
10
|
import { hostname } from "node:os";
|
|
11
11
|
import process from "node:process";
|
|
@@ -286,7 +286,7 @@ async function connect(options, context = {}) {
|
|
|
286
286
|
let unwatch;
|
|
287
287
|
try {
|
|
288
288
|
if (!context.prepared) {
|
|
289
|
-
const { getWorkerStatus } = await import("./background-
|
|
289
|
+
const { getWorkerStatus } = await import("./background-BeAXQscS.js");
|
|
290
290
|
if ((await getWorkerStatus()).running) throw new Diagnostics.Error({
|
|
291
291
|
code: Diagnostics.code.unknown,
|
|
292
292
|
severity: "error",
|
|
@@ -354,7 +354,7 @@ async function connect(options, context = {}) {
|
|
|
354
354
|
await hooks.callHook("kubb:lifecycle:end");
|
|
355
355
|
unwatch?.();
|
|
356
356
|
if (background) {
|
|
357
|
-
const { startWorker } = await import("./background-
|
|
357
|
+
const { startWorker } = await import("./background-BeAXQscS.js");
|
|
358
358
|
await startWorker(options);
|
|
359
359
|
if (options.logLevel !== "silent") logOutro("Running in the background · kubb studio stop");
|
|
360
360
|
return;
|
|
@@ -427,4 +427,4 @@ async function runStudio(values, action, { block = false, json = false } = {}) {
|
|
|
427
427
|
//#endregion
|
|
428
428
|
export { login as a, runStudio as c, loadConfigs as i, watchKeys as l, formatCountdown as n, prepareConnection as o, formatPermissionRows as r, resolvePermissions as s, connect as t };
|
|
429
429
|
|
|
430
|
-
//# sourceMappingURL=run-
|
|
430
|
+
//# sourceMappingURL=run-BAav-oJX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-DAiTuC3q.js","names":["logLevelMap"],"sources":["../../../internals/utils/src/copyToClipboard.ts","../../../internals/utils/src/openInBrowser.ts","../src/runners/studio/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst COMMANDS: Partial<Record<NodeJS.Platform, [string, ...Array<string>]>> = {\n darwin: ['pbcopy'],\n win32: ['clip.exe'],\n linux: ['xclip', '-selection', 'clipboard'],\n}\n\n/**\n * Copies text to the system clipboard with the platform's own tool. Resolves `false` in CI, on a\n * platform without a known tool, or when the tool is missing or fails.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n // Wayland sessions have no X selection for xclip to serve, so they use `wl-copy`.\n const command = process.platform === 'linux' && process.env.WAYLAND_DISPLAY ? (['wl-copy'] as const) : COMMANDS[process.platform]\n if (!command || isCIEnvironment()) return false\n\n const [name, ...args] = command\n // stdout and stderr are ignored: xclip and wl-copy stay alive to serve the selection and would hold open pipes until the timeout.\n const run = x(name, args, { timeout: 2_000, nodeOptions: { stdio: ['pipe', 'ignore', 'ignore'] } })\n // A missing tool closes stdin before the write lands; the rejection below reports it.\n run.process?.stdin?.once('error', () => {})\n run.process?.stdin?.end(text)\n\n return run.then(\n ({ exitCode }) => exitCode === 0,\n () => false,\n )\n}\n","import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst ignore = () => {}\n\n/**\n * Opens a URL or local file in the default browser, unless running in CI.\n */\nexport function openInBrowser(target: string): void {\n if (isCIEnvironment()) return\n\n if (process.platform === 'win32') {\n x('cmd', ['/c', 'start', '', target]).then(ignore, ignore)\n return\n }\n x(process.platform === 'darwin' ? 'open' : 'xdg-open', [target]).then(ignore, ignore)\n}\n","import { hostname } from 'node:os'\nimport { toPermissionFlag } from '../../ui/text.ts'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport * as prompts from '@clack/prompts'\nimport { KUBB_CONFIG_FILENAME } from '@internals/shared'\nimport { copyToClipboard, isCIEnvironment, openInBrowser, toError } from '@internals/utils'\nimport type { CLIOptions, Config } from '@kubb/core'\nimport { cliReporter, Diagnostics, Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport { connectAgent, defaultStudioUrl, InvalidAgentTokenError, pairAgent, PairingCanceledError } from '@kubb/studio'\nimport { AgentPermission } from '@kubb/studio/protocol'\nimport { trackRun } from '../../Telemetry.ts'\nimport { plainWriter } from '../../loggers/plainWriter.ts'\nimport setupReporters from '../../loggers/reporters.ts'\nimport { logIntro, logOutro, logTip } from '../../ui/intro.ts'\nimport { logBlock, logStep } from '../../ui/log.ts'\nimport { createSpinner } from '../../ui/spinner.ts'\nimport { canUseTTY, isRichOutput } from '../../utils/env.ts'\nimport { getConfigs } from '../../config.ts'\nimport { clearCredentials, type Credentials, getCredentialsPath, getMachineId, readCredentials, writeCredentials } from './credentials.ts'\nimport { version } from '../../../package.json'\n\nexport type StudioOptions = {\n /**\n * Current `@kubb/cli` version, reported to Studio and used for the telemetry payload.\n */\n version: string\n configPath?: string\n /**\n * Base URL of the Studio instance, for a self-hosted deployment. Resolved before it reaches here,\n * since stored credentials are bound to it.\n */\n studioUrl: string\n /**\n * What Studio may do in this project. Each flag grants outright; the rest are asked once per\n * project through {@link resolvePermissions}.\n */\n permission: Record<AgentPermission, boolean>\n /**\n * Whether to open the approval page in a browser during pairing.\n */\n autoOpen: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\nexport type SnapshotOptions = Pick<StudioOptions, 'configPath' | 'studioUrl' | 'logLevel'> & {\n /**\n * Organization CI API key. Falls back to `KUBB_TOKEN`.\n */\n token?: string\n /**\n * Stable identity for the CI agent. Falls back to CI auto-detection.\n */\n id?: string\n /** Identity of another CI agent to also compare with. Falls back to CI auto-detection. */\n baseId?: string\n /**\n * Package name for the generated tarball. Falls back to the nearest package.json.\n */\n name?: string\n /**\n * Package version for the generated tarball. Falls back to the nearest package.json.\n */\n packageVersion?: string\n /**\n * Print the result as one JSON object instead of a summary.\n */\n json?: boolean\n}\n\n/** The flags a `kubb studio` subcommand parsed; each one is optional since a subcommand declares only the flags it uses. */\nexport type StudioValues = {\n config?: string\n url?: string\n allowRead?: boolean\n allowReadAst?: boolean\n allowWrite?: boolean\n allowConfigEdit?: boolean\n allowInstall?: boolean\n allowUpdate?: boolean\n allowSaveInput?: boolean\n allowExec?: boolean\n open?: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\ntype LoginOptions = {\n /**\n * Aborting this cancels an in-flight pairing request or poll and rejects with\n * {@link PairingCanceledError}. Wired to `kubb studio`'s shutdown signal, so Ctrl+C during\n * pairing cancels it instead of leaving the poll running.\n */\n signal?: AbortSignal\n /**\n * Credentials from before this login. When the fresh pairing resolves to the same agent on the\n * same Studio, its saved project permissions carry forward instead of being asked again.\n * Left out for an explicitly requested `kubb studio login`, which always starts clean.\n */\n previousCredentials?: Credentials | null\n}\n\n/**\n * Pairs this machine with Studio and stores the resulting token.\n *\n * The CLI holds a code and the browser approves it, rather than the user copying a token out of\n * the UI. The token comes back over the CLI's own HTTPS POST, so it never lands in a URL, a\n * server log, or a `Referer` header.\n */\nexport async function login({ studioUrl, autoOpen }: StudioOptions, { signal, previousCredentials }: LoginOptions = {}): Promise<Credentials> {\n const spinner = createSpinner()\n // A retry notice stays on screen a while before the countdown takes the line back.\n let retryUntil = 0\n // The spinner only starts once a code is shown.\n let waiting = false\n let countdown: NodeJS.Timeout | undefined\n\n try {\n const { token, agent } = await pairAgent({\n studioUrl,\n type: 'cli',\n name: path.basename(process.cwd()),\n hostname: hostname(),\n machineId: await getMachineId(),\n signal,\n onCode: (session) => {\n logStep(\n [\n 'Pair this machine',\n `${styleText('dim', 'Open')} ${styleText('cyan', session.verification_uri)}`,\n `${styleText('dim', 'Code')} ${styleText('bold', session.user_code)}`,\n ].join('\\n'),\n )\n\n if (autoOpen) {\n openInBrowser(session.verification_uri_complete)\n }\n\n // Same fallback as the poll in `@kubb/studio`, so the countdown ends when polling does.\n const deadline = Date.now() + (session.expires_in > 0 ? session.expires_in : 600) * 1000\n let copied = false\n const waitingText = () =>\n `Waiting for approval ${styleText('dim', `expires in ${formatCountdown(deadline - Date.now())}${copied ? ' · code copied' : ''} · ctrl+c to cancel`)}`\n clearInterval(countdown)\n spinner.start(waitingText())\n waiting = true\n // Plain output prints every message, so only an animated spinner ticks.\n if (isRichOutput()) countdown = setInterval(() => Date.now() > retryUntil && spinner.message(waitingText()), 1000)\n // Not awaited: the code shows at once, and the spinner picks up the copy when it lands.\n void copyToClipboard(session.user_code).then((done) => {\n copied = done\n })\n },\n onRetry: (error) => {\n retryUntil = Date.now() + 5000\n spinner.message(`Could not reach Kubb Studio, retrying: ${error.message}`)\n },\n })\n clearInterval(countdown)\n spinner.stop(`Paired as ${agent.name}${agent.organizationSlug ? ` · org ${agent.organizationSlug}` : ''}`)\n\n const keepsIdentity = previousCredentials?.studioUrl === studioUrl && previousCredentials.agentId === agent.id\n const credentials: Credentials = {\n studioUrl,\n token,\n agentId: agent.id,\n agentSlug: agent.slug,\n ...(agent.organizationSlug ? { organizationSlug: agent.organizationSlug } : {}),\n ...(keepsIdentity && previousCredentials?.projects ? { projects: previousCredentials.projects } : {}),\n }\n await writeCredentials(credentials)\n\n console.log(`Credentials stored in ${getCredentialsPath()}`)\n\n return credentials\n } catch (error) {\n clearInterval(countdown)\n if (waiting) {\n spinner.stop(error instanceof PairingCanceledError ? 'Pairing canceled' : 'Pairing failed')\n }\n throw error\n }\n}\n\n/** Time left on a pairing code as `m:ss`, never below `0:00`. */\nexport function formatCountdown(ms: number): string {\n const seconds = Math.max(0, Math.ceil(ms / 1000))\n\n return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`\n}\n\n/**\n * What each permission is asked as, in the order the list shows them.\n */\nconst PERMISSIONS: ReadonlyArray<{\n key: AgentPermission\n /**\n * Short label for status output and the connect summary.\n */\n label: string\n title: (configPath: string) => string\n hint: string\n}> = [\n { key: AgentPermission.READ, label: 'read source', title: () => 'Read generated files', hint: 'show code in the browser' },\n { key: AgentPermission.READ_AST, label: 'read spec', title: () => 'Read the parsed spec', hint: 'browse schemas and operations' },\n { key: AgentPermission.WRITE, label: 'write files', title: () => 'Write files to disk', hint: 'generate from the browser' },\n { key: AgentPermission.CONFIG_EDIT, label: 'edit config', title: (configPath) => `Change ${configPath}`, hint: 'edit plugin options' },\n { key: AgentPermission.INSTALL, label: 'add plugins', title: () => 'Install extensions from the registry', hint: 'kubb add from the browser' },\n { key: AgentPermission.UPDATE, label: 'update plugins', title: () => 'Update installed extensions', hint: 'kubb update from the browser' },\n {\n key: AgentPermission.SAVE_INPUT,\n label: 'save input',\n title: (configPath) => `Save the spec from Studio as the input in ${configPath}`,\n hint: 'keep a pasted spec, URL, or git file',\n },\n { key: AgentPermission.EXEC, label: 'run tools', title: () => 'Run the formatter, linter, and postGenerate', hint: 'after each generation' },\n]\n\n/**\n * Two permissions per row, each marked granted or not, with the flags that grant the missing ones\n * after the last row. For `kubb studio status`.\n */\nexport function formatPermissionRows(granted: Partial<Record<AgentPermission, boolean>>): Array<string> {\n const width = Math.max(...PERMISSIONS.map(({ label }) => label.length))\n const cells = PERMISSIONS.map(({ key, label }) => `${granted[key] ? styleText('green', '✓') : styleText('red', '✖')} ${label.padEnd(width)}`)\n const rows = Array.from({ length: Math.ceil(cells.length / 2) }, (_, index) => cells.slice(index * 2, index * 2 + 2).join(' '))\n const flags = PERMISSIONS.filter(({ key }) => !granted[key])\n .map(({ key }) => toPermissionFlag(key))\n .join(' ')\n\n return flags ? [...rows.slice(0, -1), `${rows.at(-1)} ${styleText('dim', flags)}`] : rows\n}\n\n/**\n * Resolves Studio permissions for the current project.\n * Flags win, saved answers are reused, and the rest are asked in one list whose answers are stored\n * in `~/.kubb/credentials.json`.\n */\nexport async function resolvePermissions(\n options: StudioOptions,\n credentials: Credentials,\n configPath: string = KUBB_CONFIG_FILENAME,\n): Promise<Record<AgentPermission, boolean>> {\n const project = process.cwd()\n const remembered = credentials.projects?.[project]\n const granted = Object.fromEntries(PERMISSIONS.map(({ key }) => [key, options.permission[key] || remembered?.[key] === true])) as Record<\n AgentPermission,\n boolean\n >\n const pending = PERMISSIONS.filter(({ key }) => !options.permission[key] && typeof remembered?.[key] !== 'boolean')\n\n if (!pending.length || isCIEnvironment() || !canUseTTY()) return granted\n\n prompts.updateSettings({ withGuide: true })\n const selected = await prompts.multiselect({\n message: 'What may Kubb Studio do in this project?',\n options: pending.map(({ key, title, hint }) => ({ value: key, label: title(configPath), hint })),\n required: false,\n })\n // A canceled list grants nothing and saves nothing, so the next run asks again.\n if (prompts.isCancel(selected)) return granted\n\n const answers = Object.fromEntries(pending.map(({ key }) => [key, selected.includes(key)]))\n await writeCredentials({\n ...credentials,\n projects: { ...credentials.projects, [project]: { ...remembered, ...answers } },\n })\n\n return { ...granted, ...answers }\n}\n\n/**\n * Loads the project's Kubb config the same way `kubb generate` does, one entry per `defineConfig(...)` entry.\n */\nexport async function loadConfigs(options: Pick<StudioOptions, 'configPath' | 'logLevel'>): Promise<{ configPath: string; configs: Array<Config> }> {\n const { configPath, configs } = await getConfigs({ configPath: options.configPath, logLevel: options.logLevel })\n\n if (!configs.length) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Config not defined, create a kubb.config.ts or pass it with --config',\n })\n }\n\n // `getConfigs` resolves this to an absolute path. Relativized here, once, so the permission\n // prompt and the path Studio receives over the wire both show the project-relative form instead\n // of leaking the local filesystem layout.\n return { configPath: path.relative(process.cwd(), configPath) || configPath, configs }\n}\n\nexport type PreparedConnection = {\n configPath: string\n credentials: Credentials\n permissions: StudioOptions['permission']\n}\n\n/** Validates the project and resolves pairing and permissions before starting its worker. */\nexport async function prepareConnection(options: StudioOptions, signal?: AbortSignal): Promise<PreparedConnection> {\n const { configPath } = await loadConfigs(options)\n const stored = await readCredentials()\n const credentials = await (async () => {\n if (stored?.studioUrl === options.studioUrl) return stored\n if (isCIEnvironment()) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Not paired with ${options.studioUrl}. In CI, run \\`kubb studio snapshot\\` instead, or run \\`kubb studio login\\` on a machine with a browser.`,\n })\n }\n return login(options, { signal })\n })()\n const permissions = await resolvePermissions(options, credentials, configPath)\n return { configPath, credentials, permissions }\n}\n\nexport type WorkerState = 'starting' | 'connected' | 'reconnecting' | 'authentication required' | 'stopped'\n\n/** Runs the same project connection in the foreground or in a background worker. */\nexport async function connect(\n options: StudioOptions,\n context: {\n prepared?: PreparedConnection\n signal?: AbortSignal\n onState?: (state: WorkerState) => void | Promise<void>\n } = {},\n): Promise<void> {\n const shutdown = new AbortController()\n const signal = context.signal ?? shutdown.signal\n const stop = () => shutdown.abort()\n const events = process as unknown as NodeJS.EventEmitter\n if (!context.signal) {\n events.once('SIGINT', stop)\n events.once('SIGTERM', stop)\n }\n let unwatch: (() => void) | undefined\n try {\n if (!context.prepared) {\n const { getWorkerStatus } = await import('./background.ts')\n const worker = await getWorkerStatus()\n if (worker.running)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'This project is running in the background. Run `kubb studio stop` first.',\n })\n }\n const prepared = context.prepared ?? (await prepareConnection(options, signal))\n let { credentials, permissions } = prepared\n const { configPath } = prepared\n let hinted = false\n // Set by a fresh pairing until it connects, so a token rejected right after approval fails the run instead of looping.\n let pairedAgain = false\n\n // The background worker writes to a log file, so it gets the plain logger rather than the\n // animated one. The logger also covers the `studio:*` events and each generation run.\n const hooks = new Hookable<KubbHooks>()\n setupReporters(hooks, {\n logLevel: logLevelMap[options.logLevel ?? 'info'],\n reporters: [cliReporter],\n ...(context.onState ? { writer: plainWriter } : {}),\n })\n // `b` hands the session to the background worker; only a foreground run in a terminal listens.\n const listens = !context.onState && process.stdin.isTTY === true && canUseTTY()\n let background = false\n hooks.hook('studio:connected', async () => {\n pairedAgain = false\n await context.onState?.('connected')\n if (listens && !unwatch) {\n unwatch = watchKeys({\n onBackground: () => {\n background = true\n stop()\n },\n onStop: stop,\n })\n }\n if (hinted || context.onState || options.logLevel === 'silent') return\n hinted = true\n logBlock([\n `${styleText('dim', 'Project')} ${path.basename(process.cwd())} ${styleText(\n 'dim',\n PERMISSIONS.filter(({ key }) => permissions[key])\n .map(({ label }) => label)\n .join(' · ') || 'no permissions',\n )}`,\n styleText('dim', listens ? 'Press b to keep running in the background, Ctrl+C to disconnect' : 'Press Ctrl+C to disconnect'),\n ])\n logTip()\n })\n hooks.hook('studio:reconnecting', () => context.onState?.('reconnecting'))\n\n for (;;) {\n try {\n await connectAgent({\n token: credentials.token,\n studioUrl: options.studioUrl,\n configPath,\n version: options.version,\n root: process.cwd(),\n permissions,\n loadConfigs: async () => (await loadConfigs(options)).configs,\n hooks,\n signal,\n })\n break\n } catch (error) {\n if (!(error instanceof InvalidAgentTokenError)) throw error\n await context.onState?.('authentication required')\n await clearCredentials()\n if (pairedAgain) throw new Error(`${error.message} Studio rejected the newly approved token too. Run \\`kubb studio login\\` and try again.`)\n if (context.onState || isCIEnvironment() || !canUseTTY()) throw new Error(`${error.message} Run \\`kubb studio login\\` to pair again.`)\n\n // The pairing prompts need stdin back.\n unwatch?.()\n unwatch = undefined\n console.log(styleText('yellow', `${error.message} Pairing again...`))\n credentials = await login(options, { signal, previousCredentials: credentials })\n pairedAgain = true\n permissions = await resolvePermissions(options, credentials, configPath)\n }\n }\n // Stops the \"Ready for jobs\" spinner, which would otherwise keep drawing under the closing line.\n await hooks.callHook('kubb:lifecycle:end')\n unwatch?.()\n if (background) {\n const { startWorker } = await import('./background.ts')\n await startWorker(options)\n if (options.logLevel !== 'silent') logOutro('Running in the background · kubb studio stop')\n return\n }\n if (!context.onState && signal.aborted && options.logLevel !== 'silent') logOutro('Disconnected')\n } catch (error) {\n if (!(error instanceof PairingCanceledError)) throw error\n } finally {\n unwatch?.()\n events.off('SIGINT', stop)\n events.off('SIGTERM', stop)\n }\n}\n\n/**\n * Listens for single keys on a TTY stdin. Raw mode turns Ctrl+C into a key instead of SIGINT, so it\n * is handled here too. Returns the function that restores the terminal, safe to call twice.\n */\nexport function watchKeys({ onBackground, onStop }: { onBackground: () => void; onStop: () => void }): () => void {\n const stdin = process.stdin\n const onData = (data: Buffer) => {\n const key = data.toString()\n if (key === 'b' || key === 'B') onBackground()\n if (key === '\\u0003') onStop()\n }\n // A clack spinner reads stdin too and exits the process on Ctrl+C, before the session can close\n // its socket, so its Ctrl+C alias is lifted while these keys are read.\n const cancelAlias = prompts.settings.aliases.get('\\u0003')\n prompts.settings.aliases.delete('\\u0003')\n stdin.setRawMode(true)\n stdin.on('data', onData)\n stdin.resume()\n let restored = false\n\n return () => {\n if (restored) return\n restored = true\n if (cancelAlias) prompts.settings.aliases.set('\\u0003', cancelAlias)\n stdin.off('data', onData)\n stdin.setRawMode(false)\n stdin.pause()\n }\n}\n\n/**\n * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,\n * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.\n */\nexport async function runStudio(\n values: StudioValues,\n action: (options: StudioOptions) => Promise<unknown>,\n { block = false, json = false }: { block?: boolean; json?: boolean } = {},\n): Promise<void> {\n const options: StudioOptions = {\n version,\n configPath: values.config,\n studioUrl: values.url ?? defaultStudioUrl,\n permission: Object.fromEntries(Object.values(AgentPermission).map((key) => [key, values[key] ?? false])) as Record<AgentPermission, boolean>,\n autoOpen: values.open ?? true,\n logLevel: values.logLevel,\n }\n const report = trackRun({ command: 'studio', hrStart: process.hrtime() })\n\n try {\n if (options.logLevel !== 'silent' && !json) {\n logIntro({\n warning: styleText('yellow', 'This feature is still under development, use with caution'),\n block,\n })\n }\n\n await action(options)\n\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run-BAav-oJX.js","names":["logLevelMap"],"sources":["../../../internals/utils/src/copyToClipboard.ts","../../../internals/utils/src/openInBrowser.ts","../src/runners/studio/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst COMMANDS: Partial<Record<NodeJS.Platform, [string, ...Array<string>]>> = {\n darwin: ['pbcopy'],\n win32: ['clip.exe'],\n linux: ['xclip', '-selection', 'clipboard'],\n}\n\n/**\n * Copies text to the system clipboard with the platform's own tool. Resolves `false` in CI, on a\n * platform without a known tool, or when the tool is missing or fails.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n // Wayland sessions have no X selection for xclip to serve, so they use `wl-copy`.\n const command = process.platform === 'linux' && process.env.WAYLAND_DISPLAY ? (['wl-copy'] as const) : COMMANDS[process.platform]\n if (!command || isCIEnvironment()) return false\n\n const [name, ...args] = command\n // stdout and stderr are ignored: xclip and wl-copy stay alive to serve the selection and would hold open pipes until the timeout.\n const run = x(name, args, { timeout: 2_000, nodeOptions: { stdio: ['pipe', 'ignore', 'ignore'] } })\n // A missing tool closes stdin before the write lands; the rejection below reports it.\n run.process?.stdin?.once('error', () => {})\n run.process?.stdin?.end(text)\n\n return run.then(\n ({ exitCode }) => exitCode === 0,\n () => false,\n )\n}\n","import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst ignore = () => {}\n\n/**\n * Opens a URL or local file in the default browser, unless running in CI.\n */\nexport function openInBrowser(target: string): void {\n if (isCIEnvironment()) return\n\n if (process.platform === 'win32') {\n x('cmd', ['/c', 'start', '', target]).then(ignore, ignore)\n return\n }\n x(process.platform === 'darwin' ? 'open' : 'xdg-open', [target]).then(ignore, ignore)\n}\n","import { hostname } from 'node:os'\nimport { toPermissionFlag } from '../../ui/text.ts'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport * as prompts from '@clack/prompts'\nimport { KUBB_CONFIG_FILENAME } from '@internals/shared'\nimport { copyToClipboard, isCIEnvironment, openInBrowser, toError } from '@internals/utils'\nimport type { CLIOptions, Config } from '@kubb/core'\nimport { cliReporter, Diagnostics, Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport { connectAgent, defaultStudioUrl, InvalidAgentTokenError, pairAgent, PairingCanceledError } from '@kubb/studio'\nimport { AgentPermission } from '@kubb/studio/protocol'\nimport { trackRun } from '../../Telemetry.ts'\nimport { plainWriter } from '../../loggers/plainWriter.ts'\nimport setupReporters from '../../loggers/reporters.ts'\nimport { logIntro, logOutro, logTip } from '../../ui/intro.ts'\nimport { logBlock, logStep } from '../../ui/log.ts'\nimport { createSpinner } from '../../ui/spinner.ts'\nimport { canUseTTY, isRichOutput } from '../../utils/env.ts'\nimport { getConfigs } from '../../config.ts'\nimport { clearCredentials, type Credentials, getCredentialsPath, getMachineId, readCredentials, writeCredentials } from './credentials.ts'\nimport { version } from '../../../package.json'\n\nexport type StudioOptions = {\n /**\n * Current `@kubb/cli` version, reported to Studio and used for the telemetry payload.\n */\n version: string\n configPath?: string\n /**\n * Base URL of the Studio instance, for a self-hosted deployment. Resolved before it reaches here,\n * since stored credentials are bound to it.\n */\n studioUrl: string\n /**\n * What Studio may do in this project. Each flag grants outright; the rest are asked once per\n * project through {@link resolvePermissions}.\n */\n permission: Record<AgentPermission, boolean>\n /**\n * Whether to open the approval page in a browser during pairing.\n */\n autoOpen: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\nexport type SnapshotOptions = Pick<StudioOptions, 'configPath' | 'studioUrl' | 'logLevel'> & {\n /**\n * Organization CI API key. Falls back to `KUBB_TOKEN`.\n */\n token?: string\n /**\n * Stable identity for the CI agent. Falls back to CI auto-detection.\n */\n id?: string\n /** Identity of another CI agent to also compare with. Falls back to CI auto-detection. */\n baseId?: string\n /**\n * Package name for the generated tarball. Falls back to the nearest package.json.\n */\n name?: string\n /**\n * Package version for the generated tarball. Falls back to the nearest package.json.\n */\n packageVersion?: string\n /**\n * Print the result as one JSON object instead of a summary.\n */\n json?: boolean\n}\n\n/** The flags a `kubb studio` subcommand parsed; each one is optional since a subcommand declares only the flags it uses. */\nexport type StudioValues = {\n config?: string\n url?: string\n allowRead?: boolean\n allowReadAst?: boolean\n allowWrite?: boolean\n allowConfigEdit?: boolean\n allowInstall?: boolean\n allowUpdate?: boolean\n allowSaveInput?: boolean\n allowExec?: boolean\n open?: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\ntype LoginOptions = {\n /**\n * Aborting this cancels an in-flight pairing request or poll and rejects with\n * {@link PairingCanceledError}. Wired to `kubb studio`'s shutdown signal, so Ctrl+C during\n * pairing cancels it instead of leaving the poll running.\n */\n signal?: AbortSignal\n /**\n * Credentials from before this login. When the fresh pairing resolves to the same agent on the\n * same Studio, its saved project permissions carry forward instead of being asked again.\n * Left out for an explicitly requested `kubb studio login`, which always starts clean.\n */\n previousCredentials?: Credentials | null\n}\n\n/**\n * Pairs this machine with Studio and stores the resulting token.\n *\n * The CLI holds a code and the browser approves it, rather than the user copying a token out of\n * the UI. The token comes back over the CLI's own HTTPS POST, so it never lands in a URL, a\n * server log, or a `Referer` header.\n */\nexport async function login({ studioUrl, autoOpen }: StudioOptions, { signal, previousCredentials }: LoginOptions = {}): Promise<Credentials> {\n const spinner = createSpinner()\n // A retry notice stays on screen a while before the countdown takes the line back.\n let retryUntil = 0\n // The spinner only starts once a code is shown.\n let waiting = false\n let countdown: NodeJS.Timeout | undefined\n\n try {\n const { token, agent } = await pairAgent({\n studioUrl,\n type: 'cli',\n name: path.basename(process.cwd()),\n hostname: hostname(),\n machineId: await getMachineId(),\n signal,\n onCode: (session) => {\n logStep(\n [\n 'Pair this machine',\n `${styleText('dim', 'Open')} ${styleText('cyan', session.verification_uri)}`,\n `${styleText('dim', 'Code')} ${styleText('bold', session.user_code)}`,\n ].join('\\n'),\n )\n\n if (autoOpen) {\n openInBrowser(session.verification_uri_complete)\n }\n\n // Same fallback as the poll in `@kubb/studio`, so the countdown ends when polling does.\n const deadline = Date.now() + (session.expires_in > 0 ? session.expires_in : 600) * 1000\n let copied = false\n const waitingText = () =>\n `Waiting for approval ${styleText('dim', `expires in ${formatCountdown(deadline - Date.now())}${copied ? ' · code copied' : ''} · ctrl+c to cancel`)}`\n clearInterval(countdown)\n spinner.start(waitingText())\n waiting = true\n // Plain output prints every message, so only an animated spinner ticks.\n if (isRichOutput()) countdown = setInterval(() => Date.now() > retryUntil && spinner.message(waitingText()), 1000)\n // Not awaited: the code shows at once, and the spinner picks up the copy when it lands.\n void copyToClipboard(session.user_code).then((done) => {\n copied = done\n })\n },\n onRetry: (error) => {\n retryUntil = Date.now() + 5000\n spinner.message(`Could not reach Kubb Studio, retrying: ${error.message}`)\n },\n })\n clearInterval(countdown)\n spinner.stop(`Paired as ${agent.name}${agent.organizationSlug ? ` · org ${agent.organizationSlug}` : ''}`)\n\n const keepsIdentity = previousCredentials?.studioUrl === studioUrl && previousCredentials.agentId === agent.id\n const credentials: Credentials = {\n studioUrl,\n token,\n agentId: agent.id,\n agentSlug: agent.slug,\n ...(agent.organizationSlug ? { organizationSlug: agent.organizationSlug } : {}),\n ...(keepsIdentity && previousCredentials?.projects ? { projects: previousCredentials.projects } : {}),\n }\n await writeCredentials(credentials)\n\n console.log(`Credentials stored in ${getCredentialsPath()}`)\n\n return credentials\n } catch (error) {\n clearInterval(countdown)\n if (waiting) {\n spinner.stop(error instanceof PairingCanceledError ? 'Pairing canceled' : 'Pairing failed')\n }\n throw error\n }\n}\n\n/** Time left on a pairing code as `m:ss`, never below `0:00`. */\nexport function formatCountdown(ms: number): string {\n const seconds = Math.max(0, Math.ceil(ms / 1000))\n\n return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`\n}\n\n/**\n * What each permission is asked as, in the order the list shows them.\n */\nconst PERMISSIONS: ReadonlyArray<{\n key: AgentPermission\n /**\n * Short label for status output and the connect summary.\n */\n label: string\n title: (configPath: string) => string\n hint: string\n}> = [\n { key: AgentPermission.READ, label: 'read source', title: () => 'Read generated files', hint: 'show code in the browser' },\n { key: AgentPermission.READ_AST, label: 'read spec', title: () => 'Read the parsed spec', hint: 'browse schemas and operations' },\n { key: AgentPermission.WRITE, label: 'write files', title: () => 'Write files to disk', hint: 'generate from the browser' },\n { key: AgentPermission.CONFIG_EDIT, label: 'edit config', title: (configPath) => `Change ${configPath}`, hint: 'edit plugin options' },\n { key: AgentPermission.INSTALL, label: 'add plugins', title: () => 'Install extensions from the registry', hint: 'kubb add from the browser' },\n { key: AgentPermission.UPDATE, label: 'update plugins', title: () => 'Update installed extensions', hint: 'kubb update from the browser' },\n {\n key: AgentPermission.SAVE_INPUT,\n label: 'save input',\n title: (configPath) => `Save the spec from Studio as the input in ${configPath}`,\n hint: 'keep a pasted spec, URL, or git file',\n },\n { key: AgentPermission.EXEC, label: 'run tools', title: () => 'Run the formatter, linter, and postGenerate', hint: 'after each generation' },\n]\n\n/**\n * Two permissions per row, each marked granted or not, with the flags that grant the missing ones\n * after the last row. For `kubb studio status`.\n */\nexport function formatPermissionRows(granted: Partial<Record<AgentPermission, boolean>>): Array<string> {\n const width = Math.max(...PERMISSIONS.map(({ label }) => label.length))\n const cells = PERMISSIONS.map(({ key, label }) => `${granted[key] ? styleText('green', '✓') : styleText('red', '✖')} ${label.padEnd(width)}`)\n const rows = Array.from({ length: Math.ceil(cells.length / 2) }, (_, index) => cells.slice(index * 2, index * 2 + 2).join(' '))\n const flags = PERMISSIONS.filter(({ key }) => !granted[key])\n .map(({ key }) => toPermissionFlag(key))\n .join(' ')\n\n return flags ? [...rows.slice(0, -1), `${rows.at(-1)} ${styleText('dim', flags)}`] : rows\n}\n\n/**\n * Resolves Studio permissions for the current project.\n * Flags win, saved answers are reused, and the rest are asked in one list whose answers are stored\n * in `~/.kubb/credentials.json`.\n */\nexport async function resolvePermissions(\n options: StudioOptions,\n credentials: Credentials,\n configPath: string = KUBB_CONFIG_FILENAME,\n): Promise<Record<AgentPermission, boolean>> {\n const project = process.cwd()\n const remembered = credentials.projects?.[project]\n const granted = Object.fromEntries(PERMISSIONS.map(({ key }) => [key, options.permission[key] || remembered?.[key] === true])) as Record<\n AgentPermission,\n boolean\n >\n const pending = PERMISSIONS.filter(({ key }) => !options.permission[key] && typeof remembered?.[key] !== 'boolean')\n\n if (!pending.length || isCIEnvironment() || !canUseTTY()) return granted\n\n prompts.updateSettings({ withGuide: true })\n const selected = await prompts.multiselect({\n message: 'What may Kubb Studio do in this project?',\n options: pending.map(({ key, title, hint }) => ({ value: key, label: title(configPath), hint })),\n required: false,\n })\n // A canceled list grants nothing and saves nothing, so the next run asks again.\n if (prompts.isCancel(selected)) return granted\n\n const answers = Object.fromEntries(pending.map(({ key }) => [key, selected.includes(key)]))\n await writeCredentials({\n ...credentials,\n projects: { ...credentials.projects, [project]: { ...remembered, ...answers } },\n })\n\n return { ...granted, ...answers }\n}\n\n/**\n * Loads the project's Kubb config the same way `kubb generate` does, one entry per `defineConfig(...)` entry.\n */\nexport async function loadConfigs(options: Pick<StudioOptions, 'configPath' | 'logLevel'>): Promise<{ configPath: string; configs: Array<Config> }> {\n const { configPath, configs } = await getConfigs({ configPath: options.configPath, logLevel: options.logLevel })\n\n if (!configs.length) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Config not defined, create a kubb.config.ts or pass it with --config',\n })\n }\n\n // `getConfigs` resolves this to an absolute path. Relativized here, once, so the permission\n // prompt and the path Studio receives over the wire both show the project-relative form instead\n // of leaking the local filesystem layout.\n return { configPath: path.relative(process.cwd(), configPath) || configPath, configs }\n}\n\nexport type PreparedConnection = {\n configPath: string\n credentials: Credentials\n permissions: StudioOptions['permission']\n}\n\n/** Validates the project and resolves pairing and permissions before starting its worker. */\nexport async function prepareConnection(options: StudioOptions, signal?: AbortSignal): Promise<PreparedConnection> {\n const { configPath } = await loadConfigs(options)\n const stored = await readCredentials()\n const credentials = await (async () => {\n if (stored?.studioUrl === options.studioUrl) return stored\n if (isCIEnvironment()) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Not paired with ${options.studioUrl}. In CI, run \\`kubb studio snapshot\\` instead, or run \\`kubb studio login\\` on a machine with a browser.`,\n })\n }\n return login(options, { signal })\n })()\n const permissions = await resolvePermissions(options, credentials, configPath)\n return { configPath, credentials, permissions }\n}\n\nexport type WorkerState = 'starting' | 'connected' | 'reconnecting' | 'authentication required' | 'stopped'\n\n/** Runs the same project connection in the foreground or in a background worker. */\nexport async function connect(\n options: StudioOptions,\n context: {\n prepared?: PreparedConnection\n signal?: AbortSignal\n onState?: (state: WorkerState) => void | Promise<void>\n } = {},\n): Promise<void> {\n const shutdown = new AbortController()\n const signal = context.signal ?? shutdown.signal\n const stop = () => shutdown.abort()\n const events = process as unknown as NodeJS.EventEmitter\n if (!context.signal) {\n events.once('SIGINT', stop)\n events.once('SIGTERM', stop)\n }\n let unwatch: (() => void) | undefined\n try {\n if (!context.prepared) {\n const { getWorkerStatus } = await import('./background.ts')\n const worker = await getWorkerStatus()\n if (worker.running)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'This project is running in the background. Run `kubb studio stop` first.',\n })\n }\n const prepared = context.prepared ?? (await prepareConnection(options, signal))\n let { credentials, permissions } = prepared\n const { configPath } = prepared\n let hinted = false\n // Set by a fresh pairing until it connects, so a token rejected right after approval fails the run instead of looping.\n let pairedAgain = false\n\n // The background worker writes to a log file, so it gets the plain logger rather than the\n // animated one. The logger also covers the `studio:*` events and each generation run.\n const hooks = new Hookable<KubbHooks>()\n setupReporters(hooks, {\n logLevel: logLevelMap[options.logLevel ?? 'info'],\n reporters: [cliReporter],\n ...(context.onState ? { writer: plainWriter } : {}),\n })\n // `b` hands the session to the background worker; only a foreground run in a terminal listens.\n const listens = !context.onState && process.stdin.isTTY === true && canUseTTY()\n let background = false\n hooks.hook('studio:connected', async () => {\n pairedAgain = false\n await context.onState?.('connected')\n if (listens && !unwatch) {\n unwatch = watchKeys({\n onBackground: () => {\n background = true\n stop()\n },\n onStop: stop,\n })\n }\n if (hinted || context.onState || options.logLevel === 'silent') return\n hinted = true\n logBlock([\n `${styleText('dim', 'Project')} ${path.basename(process.cwd())} ${styleText(\n 'dim',\n PERMISSIONS.filter(({ key }) => permissions[key])\n .map(({ label }) => label)\n .join(' · ') || 'no permissions',\n )}`,\n styleText('dim', listens ? 'Press b to keep running in the background, Ctrl+C to disconnect' : 'Press Ctrl+C to disconnect'),\n ])\n logTip()\n })\n hooks.hook('studio:reconnecting', () => context.onState?.('reconnecting'))\n\n for (;;) {\n try {\n await connectAgent({\n token: credentials.token,\n studioUrl: options.studioUrl,\n configPath,\n version: options.version,\n root: process.cwd(),\n permissions,\n loadConfigs: async () => (await loadConfigs(options)).configs,\n hooks,\n signal,\n })\n break\n } catch (error) {\n if (!(error instanceof InvalidAgentTokenError)) throw error\n await context.onState?.('authentication required')\n await clearCredentials()\n if (pairedAgain) throw new Error(`${error.message} Studio rejected the newly approved token too. Run \\`kubb studio login\\` and try again.`)\n if (context.onState || isCIEnvironment() || !canUseTTY()) throw new Error(`${error.message} Run \\`kubb studio login\\` to pair again.`)\n\n // The pairing prompts need stdin back.\n unwatch?.()\n unwatch = undefined\n console.log(styleText('yellow', `${error.message} Pairing again...`))\n credentials = await login(options, { signal, previousCredentials: credentials })\n pairedAgain = true\n permissions = await resolvePermissions(options, credentials, configPath)\n }\n }\n // Stops the \"Ready for jobs\" spinner, which would otherwise keep drawing under the closing line.\n await hooks.callHook('kubb:lifecycle:end')\n unwatch?.()\n if (background) {\n const { startWorker } = await import('./background.ts')\n await startWorker(options)\n if (options.logLevel !== 'silent') logOutro('Running in the background · kubb studio stop')\n return\n }\n if (!context.onState && signal.aborted && options.logLevel !== 'silent') logOutro('Disconnected')\n } catch (error) {\n if (!(error instanceof PairingCanceledError)) throw error\n } finally {\n unwatch?.()\n events.off('SIGINT', stop)\n events.off('SIGTERM', stop)\n }\n}\n\n/**\n * Listens for single keys on a TTY stdin. Raw mode turns Ctrl+C into a key instead of SIGINT, so it\n * is handled here too. Returns the function that restores the terminal, safe to call twice.\n */\nexport function watchKeys({ onBackground, onStop }: { onBackground: () => void; onStop: () => void }): () => void {\n const stdin = process.stdin\n const onData = (data: Buffer) => {\n const key = data.toString()\n if (key === 'b' || key === 'B') onBackground()\n if (key === '\\u0003') onStop()\n }\n // A clack spinner reads stdin too and exits the process on Ctrl+C, before the session can close\n // its socket, so its Ctrl+C alias is lifted while these keys are read.\n const cancelAlias = prompts.settings.aliases.get('\\u0003')\n prompts.settings.aliases.delete('\\u0003')\n stdin.setRawMode(true)\n stdin.on('data', onData)\n stdin.resume()\n let restored = false\n\n return () => {\n if (restored) return\n restored = true\n if (cancelAlias) prompts.settings.aliases.set('\\u0003', cancelAlias)\n stdin.off('data', onData)\n stdin.setRawMode(false)\n stdin.pause()\n }\n}\n\n/**\n * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,\n * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.\n */\nexport async function runStudio(\n values: StudioValues,\n action: (options: StudioOptions) => Promise<unknown>,\n { block = false, json = false }: { block?: boolean; json?: boolean } = {},\n): Promise<void> {\n const options: StudioOptions = {\n version,\n configPath: values.config,\n studioUrl: values.url ?? defaultStudioUrl,\n permission: Object.fromEntries(Object.values(AgentPermission).map((key) => [key, values[key] ?? false])) as Record<AgentPermission, boolean>,\n autoOpen: values.open ?? true,\n logLevel: values.logLevel,\n }\n const report = trackRun({ command: 'studio', hrStart: process.hrtime() })\n\n try {\n if (options.logLevel !== 'silent' && !json) {\n logIntro({\n warning: styleText('yellow', 'This feature is still under development, use with caution'),\n block,\n })\n }\n\n await action(options)\n\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
2
|
import { n as toError } from "./errors-DmC83ALX.js";
|
|
3
|
-
import { n as trackRun } from "./Telemetry-
|
|
3
|
+
import { n as trackRun } from "./Telemetry-Bjn0mrII.js";
|
|
4
4
|
import { styleText } from "node:util";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
//#region src/runners/mcp/run.ts
|
|
@@ -29,4 +29,4 @@ async function run() {
|
|
|
29
29
|
//#endregion
|
|
30
30
|
export { run };
|
|
31
31
|
|
|
32
|
-
//# sourceMappingURL=run-
|
|
32
|
+
//# sourceMappingURL=run-BeTIeaKr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-
|
|
1
|
+
{"version":3,"file":"run-BeTIeaKr.js","names":[],"sources":["../src/runners/mcp/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport type * as McpModule from '@kubb/mcp'\nimport { trackRun } from '../../Telemetry.ts'\n\n/**\n * Starts the `@kubb/mcp` server over stdio and reports the outcome to telemetry.\n */\nexport async function run(): Promise<void> {\n const { run: startMcpServer } = (await import('@kubb/mcp')) as typeof McpModule\n\n const report = trackRun({ command: 'mcp', hrStart: process.hrtime() })\n\n try {\n // The MCP stdio transport owns stdout: anything else written there corrupts the JSON-RPC stream.\n console.error(styleText('cyan', '⏳ Starting MCP server...'))\n console.warn(styleText('yellow', 'This feature is still under development, use with caution'))\n const server = startMcpServer()\n // Report once the client introduces itself, so the event names the client (e.g. `claude-code`, `cursor-vscode`).\n server.on('initialize', ({ clientInfo }) => void report({ status: 'success', mcpClient: clientInfo.name }), { once: true })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":";;;;;;;;;AASA,eAAsB,MAAqB;CACzC,MAAM,EAAE,KAAK,mBAAoB,MAAM,OAAO;CAE9C,MAAM,SAAS,SAAS;EAAE,SAAS;EAAO,SAAS,QAAQ,OAAO;CAAE,CAAC;CAErE,IAAI;EAEF,QAAQ,MAAM,UAAU,QAAQ,0BAA0B,CAAC;EAC3D,QAAQ,KAAK,UAAU,UAAU,2DAA2D,CAAC;EAG7F,eAAK,CAAC,CAAC,GAAG,eAAe,EAAE,iBAAiB,KAAK,OAAO;GAAE,QAAQ;GAAW,WAAW,WAAW;EAAK,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;CAC5H,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC,OAAO;EACpC,QAAQ,WAAW;CACrB;AACF"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
2
|
import { n as toError } from "./errors-DmC83ALX.js";
|
|
3
|
-
import { n as trackRun } from "./Telemetry-
|
|
4
|
-
import { t as pluralize } from "./text-
|
|
5
|
-
import { n as findConfigFile, t as getConfigs } from "./config-
|
|
6
|
-
import { t as logCommandSummary } from "./summary-
|
|
3
|
+
import { n as trackRun } from "./Telemetry-Bjn0mrII.js";
|
|
4
|
+
import { t as pluralize } from "./text-BbK3UX0I.js";
|
|
5
|
+
import { n as findConfigFile, t as getConfigs } from "./config-BD5d6yQG.js";
|
|
6
|
+
import { t as logCommandSummary } from "./summary-rD3DP405.js";
|
|
7
7
|
import { styleText } from "node:util";
|
|
8
8
|
import process from "node:process";
|
|
9
9
|
import { resolve } from "node:path";
|
|
@@ -96,4 +96,4 @@ async function run({ input, configPath }) {
|
|
|
96
96
|
//#endregion
|
|
97
97
|
export { run };
|
|
98
98
|
|
|
99
|
-
//# sourceMappingURL=run-
|
|
99
|
+
//# sourceMappingURL=run-Bu3NVhF_.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-
|
|
1
|
+
{"version":3,"file":"run-Bu3NVhF_.js","names":[],"sources":["../src/runners/validate/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { resolve } from 'node:path'\nimport { styleText } from 'node:util'\nimport { findConfigFile } from '@internals/shared'\nimport { toError } from '@internals/utils'\nimport { type Config, checkoutGitInput, getInputKind } from '@kubb/core'\nimport { trackRun } from '../../Telemetry.ts'\nimport { getConfigs } from '../../config.ts'\nimport { pluralize } from '../../ui/text.ts'\nimport { logCommandSummary } from '../../ui/summary.ts'\n\ntype ValidateOptions = {\n /**\n * Path, URL, or git input (`git+<repo>#<ref>:<path>`) of the specification to validate.\n */\n input: string\n configPath?: string\n}\n\n/**\n * Validates `input` with the configured adapters, falling back to OpenAPI when no config exists.\n * Exits the process with code 1 on validation failure or missing dependency.\n */\nexport async function run({ input, configPath }: ValidateOptions): Promise<void> {\n const hrStart = process.hrtime()\n const report = trackRun({ command: 'validate', hrStart })\n let adapterName: string | undefined\n\n try {\n const configFile = configPath ?? findConfigFile()\n // A config found by search that does not load must not block validating a file; an explicit `--config` still fails.\n const loaded = configFile\n ? await getConfigs({ configPath: configFile, input }).catch((error) => {\n if (configPath) throw error\n })\n : undefined\n const fallback = async () => {\n adapterName = '@kubb/adapter-oas'\n const { adapterOas } = await import('@kubb/adapter-oas')\n return [{ adapter: adapterOas(), input }]\n }\n // An array config often repeats one adapter, so each adapter and input pair is validated once.\n const unique = new Map(\n (loaded?.configs ?? []).map((config) => {\n const resolved = getInputKind(input) === 'file' ? resolve(config.root || process.cwd(), input) : input\n return [`${config.adapter?.name}\\0${resolved}`, { adapter: config.adapter, input: resolved }] as const\n }),\n )\n const targets: Array<{ adapter: Config['adapter']; input: string }> = loaded ? [...unique.values()] : await fallback()\n if (!targets.length) throw new Error('The Kubb config contains no configurations to validate.')\n for (const target of targets) {\n adapterName = target.adapter?.name\n if (!target.adapter) throw new Error('No adapter is configured. Set adapter in your Kubb config to validate this specification.')\n const checkout = getInputKind(target.input) === 'git' ? await checkoutGitInput(target.input) : undefined\n try {\n await target.adapter.validate(checkout?.path ?? target.input, { throwOnError: true })\n } finally {\n await checkout?.dispose()\n }\n }\n const specifications = new Set(targets.map((target) => target.input)).size\n const adapterNames = [...new Set(targets.flatMap((target) => target.adapter?.name ?? []))]\n await report({ status: 'success' })\n\n logCommandSummary({\n title: 'Validation passed',\n status: 'success',\n hrStart,\n lines: [\n ` ${styleText('bold', `${pluralize(specifications, 'specification')} validated`)}`,\n ` ${styleText('dim', 'Input')} ${styleText('cyan', input)}`,\n ` ${styleText('dim', adapterNames.length === 1 ? 'Adapter' : 'Adapters')} ${adapterNames.join(', ')}`,\n ],\n })\n } catch (error) {\n await report({ status: 'failed' })\n const message = toError(error).message\n const missingAdapter = adapterName === '@kubb/adapter-oas' && /(?:Cannot find|Cannot resolve|not found)[\\s\\S]*@kubb\\/adapter-oas/.test(message)\n logCommandSummary({\n title: missingAdapter ? 'Could not validate' : 'Validation failed',\n status: 'failed',\n hrStart,\n lines: [\n ` ${styleText('dim', 'Input')} ${styleText('cyan', input)}`,\n ` ${styleText('dim', 'Adapter')} ${adapterName ?? 'not configured'}${missingAdapter ? ' · not installed' : ''}`,\n '',\n styleText('bold', missingAdapter ? 'Required package' : 'Validation error'),\n ` ${styleText('red', message)}`,\n ...(missingAdapter\n ? ['', 'Install it with:', styleText('cyan', ' npm install @kubb/adapter-oas'), styleText('cyan', ' pnpm add @kubb/adapter-oas')]\n : []),\n ],\n })\n\n process.exit(1)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAuBA,eAAsB,IAAI,EAAE,OAAO,cAA8C;CAC/E,MAAM,UAAU,QAAQ,OAAO;CAC/B,MAAM,SAAS,SAAS;EAAE,SAAS;EAAY;CAAQ,CAAC;CACxD,IAAI;CAEJ,IAAI;EACF,MAAM,aAAa,cAAc,eAAe;EAEhD,MAAM,SAAS,aACX,MAAM,WAAW;GAAE,YAAY;GAAY;EAAM,CAAC,CAAC,CAAC,OAAO,UAAU;GACnE,IAAI,YAAY,MAAM;EACxB,CAAC,IACD,KAAA;EACJ,MAAM,WAAW,YAAY;GAC3B,cAAc;GACd,MAAM,EAAE,eAAe,MAAM,OAAO;GACpC,OAAO,CAAC;IAAE,SAAS,WAAW;IAAG;GAAM,CAAC;EAC1C;EAEA,MAAM,SAAS,IAAI,KAChB,QAAQ,WAAW,CAAC,EAAA,CAAG,KAAK,WAAW;GACtC,MAAM,WAAW,aAAa,KAAK,MAAM,SAAS,QAAQ,OAAO,QAAQ,QAAQ,IAAI,GAAG,KAAK,IAAI;GACjG,OAAO,CAAC,GAAG,OAAO,SAAS,KAAK,IAAI,YAAY;IAAE,SAAS,OAAO;IAAS,OAAO;GAAS,CAAC;EAC9F,CAAC,CACH;EACA,MAAM,UAAgE,SAAS,CAAC,GAAG,OAAO,OAAO,CAAC,IAAI,MAAM,SAAS;EACrH,IAAI,CAAC,QAAQ,QAAQ,MAAM,IAAI,MAAM,yDAAyD;EAC9F,KAAK,MAAM,UAAU,SAAS;GAC5B,cAAc,OAAO,SAAS;GAC9B,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,2FAA2F;GAChI,MAAM,WAAW,aAAa,OAAO,KAAK,MAAM,QAAQ,MAAM,iBAAiB,OAAO,KAAK,IAAI,KAAA;GAC/F,IAAI;IACF,MAAM,OAAO,QAAQ,SAAS,UAAU,QAAQ,OAAO,OAAO,EAAE,cAAc,KAAK,CAAC;GACtF,UAAU;IACR,MAAM,UAAU,QAAQ;GAC1B;EACF;EACA,MAAM,iBAAiB,IAAI,IAAI,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,CAAC;EACtE,MAAM,eAAe,CAAC,GAAG,IAAI,IAAI,QAAQ,SAAS,WAAW,OAAO,SAAS,QAAQ,CAAC,CAAC,CAAC,CAAC;EACzF,MAAM,OAAO,EAAE,QAAQ,UAAU,CAAC;EAElC,kBAAkB;GAChB,OAAO;GACP,QAAQ;GACR;GACA,OAAO;IACL,KAAK,UAAU,QAAQ,GAAG,UAAU,gBAAgB,eAAe,EAAE,WAAW;IAChF,KAAK,UAAU,OAAO,OAAO,EAAE,MAAM,UAAU,QAAQ,KAAK;IAC5D,KAAK,UAAU,OAAO,aAAa,WAAW,IAAI,YAAY,UAAU,EAAE,IAAI,aAAa,KAAK,IAAI;GACtG;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,MAAM,UAAU,QAAQ,KAAK,CAAC,CAAC;EAC/B,MAAM,iBAAiB,gBAAgB,uBAAuB,oEAAoE,KAAK,OAAO;EAC9I,kBAAkB;GAChB,OAAO,iBAAiB,uBAAuB;GAC/C,QAAQ;GACR;GACA,OAAO;IACL,KAAK,UAAU,OAAO,OAAO,EAAE,MAAM,UAAU,QAAQ,KAAK;IAC5D,KAAK,UAAU,OAAO,SAAS,EAAE,IAAI,eAAe,mBAAmB,iBAAiB,qBAAqB;IAC7G;IACA,UAAU,QAAQ,iBAAiB,qBAAqB,kBAAkB;IAC1E,KAAK,UAAU,OAAO,OAAO;IAC7B,GAAI,iBACA;KAAC;KAAI;KAAoB,UAAU,QAAQ,iCAAiC;KAAG,UAAU,QAAQ,8BAA8B;IAAC,IAChI,CAAC;GACP;EACF,CAAC;EAED,QAAQ,KAAK,CAAC;CAChB;AACF"}
|