@kubb/cli 5.12.1 → 5.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +2 -0
  2. package/dist/{Telemetry-wyeU72_v.js → Telemetry-BhoWyCRu.js} +2 -2
  3. package/dist/{Telemetry-wyeU72_v.js.map → Telemetry-BhoWyCRu.js.map} +1 -1
  4. package/dist/{Telemetry-D-IDgRfq.cjs → Telemetry-C7v3wFNp.cjs} +2 -2
  5. package/dist/{Telemetry-D-IDgRfq.cjs.map → Telemetry-C7v3wFNp.cjs.map} +1 -1
  6. package/dist/{background-DY-7vFSm.cjs → background-BCDVfX30.cjs} +2 -2
  7. package/dist/{background-DY-7vFSm.cjs.map → background-BCDVfX30.cjs.map} +1 -1
  8. package/dist/{background-D0g61wus.js → background-BLkaGx4A.js} +1 -1
  9. package/dist/{background-B49o0iOw.js → background-CUF-snCU.js} +2 -2
  10. package/dist/{background-B49o0iOw.js.map → background-CUF-snCU.js.map} +1 -1
  11. package/dist/credentials-CZK6zPLv.js.map +1 -1
  12. package/dist/credentials-DDaKqtJn.cjs.map +1 -1
  13. package/dist/index.cjs +32 -19
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.js +32 -19
  16. package/dist/index.js.map +1 -1
  17. package/dist/{registry-BS1M25zz.js → registry-BUPuJlgX.js} +3 -3
  18. package/dist/{registry-BS1M25zz.js.map → registry-BUPuJlgX.js.map} +1 -1
  19. package/dist/{registry-DSDoBaVk.cjs → registry-Cl-wgD7H.cjs} +3 -3
  20. package/dist/{registry-DSDoBaVk.cjs.map → registry-Cl-wgD7H.cjs.map} +1 -1
  21. package/dist/{reporters-C4xq0GFT.cjs → reporters-DkBWh4sD.cjs} +4 -4
  22. package/dist/{reporters-C4xq0GFT.cjs.map → reporters-DkBWh4sD.cjs.map} +1 -1
  23. package/dist/{reporters-BXNKLBLf.js → reporters-DzAzRAlM.js} +4 -4
  24. package/dist/{reporters-BXNKLBLf.js.map → reporters-DzAzRAlM.js.map} +1 -1
  25. package/dist/{run-4DWl8vSu.cjs → run-9uoP-2Xh.cjs} +4 -4
  26. package/dist/{run-4DWl8vSu.cjs.map → run-9uoP-2Xh.cjs.map} +1 -1
  27. package/dist/{run-CuRCXhQb.js → run-BJXDoxOJ.js} +6 -6
  28. package/dist/{run-CuRCXhQb.js.map → run-BJXDoxOJ.js.map} +1 -1
  29. package/dist/{run-Byr2y0hI.js → run-BWT7PtHZ.js} +4 -4
  30. package/dist/{run-Byr2y0hI.js.map → run-BWT7PtHZ.js.map} +1 -1
  31. package/dist/{run-Bd_ZfPG1.js → run-BcTgwks6.js} +19 -7
  32. package/dist/run-BcTgwks6.js.map +1 -0
  33. package/dist/{run-DNzoHmRZ.cjs → run-CK19O5v2.cjs} +6 -6
  34. package/dist/{run-DNzoHmRZ.cjs.map → run-CK19O5v2.cjs.map} +1 -1
  35. package/dist/{run-z960932J.js → run-CioQPR0t.js} +2 -2
  36. package/dist/{run-z960932J.js.map → run-CioQPR0t.js.map} +1 -1
  37. package/dist/{run-DcX-F_wC.js → run-DklXr_kO.js} +1 -1
  38. package/dist/{run-bSFXs9i3.cjs → run-DqFL5SMR.cjs} +2 -2
  39. package/dist/{run-bSFXs9i3.cjs.map → run-DqFL5SMR.cjs.map} +1 -1
  40. package/dist/{run-C9EYgEqG.cjs → run-T82Jef8b.cjs} +19 -7
  41. package/dist/run-T82Jef8b.cjs.map +1 -0
  42. package/dist/{snapshot-DzzsJSWr.cjs → snapshot-D5HiDktY.cjs} +6 -6
  43. package/dist/{snapshot-DzzsJSWr.cjs.map → snapshot-D5HiDktY.cjs.map} +1 -1
  44. package/dist/{snapshot-CLgI_qzL.js → snapshot-DLPs2buj.js} +6 -6
  45. package/dist/{snapshot-CLgI_qzL.js.map → snapshot-DLPs2buj.js.map} +1 -1
  46. package/dist/{status-B50z7yha.cjs → status-BFMmzCfD.cjs} +3 -3
  47. package/dist/{status-B50z7yha.cjs.map → status-BFMmzCfD.cjs.map} +1 -1
  48. package/dist/{status-DrKO_t5S.js → status-DlLYGONt.js} +3 -3
  49. package/dist/{status-DrKO_t5S.js.map → status-DlLYGONt.js.map} +1 -1
  50. package/dist/studioWorker.js +2 -2
  51. package/dist/{summary-C8QI_30-.cjs → summary-BwbfP0Qj.cjs} +3 -3
  52. package/dist/{summary-C8QI_30-.cjs.map → summary-BwbfP0Qj.cjs.map} +1 -1
  53. package/dist/{summary-Bi_pAA9i.js → summary-DvLq6uim.js} +3 -3
  54. package/dist/{summary-Bi_pAA9i.js.map → summary-DvLq6uim.js.map} +1 -1
  55. package/dist/{text-DgzXienb.js → text-DG7CyUe7.js} +2 -2
  56. package/dist/{text-DgzXienb.js.map → text-DG7CyUe7.js.map} +1 -1
  57. package/dist/{text-Sp4fptq1.cjs → text-DfFJj91M.cjs} +2 -2
  58. package/dist/{text-Sp4fptq1.cjs.map → text-DfFJj91M.cjs.map} +1 -1
  59. package/dist/{utils-BDDF8GOv.js → utils-BeOShrJ6.js} +3 -3
  60. package/dist/{utils-BDDF8GOv.js.map → utils-BeOShrJ6.js.map} +1 -1
  61. package/dist/{utils-Dju97QYB.cjs → utils-Cb4fBZiX.cjs} +3 -3
  62. package/dist/{utils-Dju97QYB.cjs.map → utils-Cb4fBZiX.cjs.map} +1 -1
  63. package/package.json +7 -7
  64. package/dist/run-Bd_ZfPG1.js.map +0 -1
  65. package/dist/run-C9EYgEqG.cjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
2
  import { n as toError, t as getErrorMessage } from "./errors-DmC83ALX.js";
3
- import { f as getIntro, p as wakeUp } from "./utils-BDDF8GOv.js";
4
- import { _ as isRichOutput, r as isInteractiveRun } from "./text-DgzXienb.js";
3
+ import { f as getIntro, p as wakeUp } from "./utils-BeOShrJ6.js";
4
+ import { _ as isRichOutput, r as isInteractiveRun } from "./text-DG7CyUe7.js";
5
5
  import { stripVTControlCharacters } from "node:util";
6
6
  import process$1 from "node:process";
7
7
  import { setTimeout } from "node:timers/promises";
@@ -197,4 +197,4 @@ function closestIds({ input, ids }) {
197
197
  //#endregion
198
198
  export { installSpec as a, toRegistryId as c, logBanner as d, wantsMascot as f, incompatibility as i, toShortId as l, closestIds as n, isOutdated as o, fetchRegistryIndex as r, registryUrl as s, bumpOf as t, getBanner as u };
199
199
 
200
- //# sourceMappingURL=registry-BS1M25zz.js.map
200
+ //# sourceMappingURL=registry-BUPuJlgX.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry-BS1M25zz.js","names":["sleep","process"],"sources":["../src/ui/mascot.ts","../src/utils/registry.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport { stripVTControlCharacters } from 'node:util'\nimport { isRichOutput } from '../utils/env.ts'\nimport { type Expression, getIntro, wakeUp } from '../loggers/banner.ts'\nimport { isInteractiveRun } from './intro.ts'\n\nfunction bannerIntro(version: string, expression: Expression, command: string): string {\n return getIntro({ title: 'Turn your API spec into type-safe code', description: `kubb ${command}`, version, expression })\n}\n\n/** Whether the mascot can be drawn: a rich, 256-color terminal wide enough that no line wraps and throws off a redraw. */\nfunction canDrawMascot(version: string, command: string): boolean {\n if (!isRichOutput() || !process.stdout.hasColors(256)) return false\n\n return stripVTControlCharacters(bannerIntro(version, 'open', command))\n .split('\\n')\n .every((line) => line.length <= process.stdout.columns)\n}\n\n/**\n * Whether a command opens with the mascot. Only the long-running ones do: `generate`, a Studio\n * session or pairing, and `add` or `update` while they ask questions. Quick commands print only\n * their result.\n */\nexport function wantsMascot({ commandPath, values }: { commandPath: ReadonlyArray<string>; values: Record<string, unknown> }): boolean {\n const [command, subCommand] = commandPath\n if (values.help || values.version) return false\n if (command === 'studio') return subCommand === undefined || subCommand === 'connect' || subCommand === 'login'\n if (command === 'add' || command === 'update' || command === 'init') return isInteractiveRun({ yes: values.yes, dryRun: values.dryRun ?? values['dry-run'] })\n\n return command === undefined || command === 'generate'\n}\n\n/**\n * The still Kubb mascot with the version and the running command, such as `studio connect`, or a\n * single version line where the terminal cannot draw it. Commands print it as their header; it\n * draws at once, with no wake-up frames.\n */\nexport function getBanner(version: string, command: string): string {\n return canDrawMascot(version, command) ? `\\n${bannerIntro(version, 'open', command)}` : `Kubb CLI v${version}`\n}\n\n/**\n * Opens `kubb generate` with the mascot playing its wake-up frames in place, which takes under a\n * second and overlaps the config load. Elsewhere the still {@link getBanner} is the header.\n */\nexport async function logBanner(version: string): Promise<void> {\n if (!canDrawMascot(version, 'generate')) {\n console.log(getBanner(version, 'generate'))\n\n return\n }\n\n console.log('')\n for (const [index, [expression, ms]] of wakeUp.entries()) {\n const frame = bannerIntro(version, expression, 'generate')\n if (index > 0) process.stdout.moveCursor(0, -frame.split('\\n').length)\n console.log(frame)\n await sleep(ms)\n }\n}\n","import process from 'node:process'\nimport { getErrorMessage, toError } from '@internals/utils'\nimport { checkCompatibility, Diagnostics, type ExtensionManifest, isRegistryEntry, type RegistryArtifact, type RegistryEntry } from '@kubb/core'\nimport { difference, isLessThan, isValid } from 'verkit'\n\nconst DEFAULT_REGISTRY = 'https://kubb.dev/registry'\n\nconst SLUG = '[a-z0-9]+(?:-[a-z0-9]+)*'\nconst ID = new RegExp(`^${SLUG}(\\\\/${SLUG})?$`)\n\n/** The registry base URL: `KUBB_REGISTRY`, or kubb.dev. */\nexport function registryUrl(): string {\n const url = process.env.KUBB_REGISTRY || DEFAULT_REGISTRY\n if (!/^https?:\\/\\//.test(url))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `KUBB_REGISTRY must be an http(s) URL, got \"${url}\".`,\n help: 'Set `KUBB_REGISTRY` to an http(s) URL, or unset it to use https://kubb.dev/registry.',\n })\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Turns `owner/slug`, or a bare `slug` meaning `kubb-labs/<slug>`, into a registry id.\n *\n * @throws when the id has another shape, so it never reaches a URL unchecked.\n */\nexport function toRegistryId(input: string): string {\n if (!ID.test(input))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `\"${input}\" is not a registry id. Use owner/slug, such as kubb-labs/plugin-zod, or a slug, such as plugin-zod.`,\n })\n return input.includes('/') ? input : `kubb-labs/${input}`\n}\n\n/** The shortest id `kubb add` and `kubb update` accept: the slug for an official extension, else `owner/slug`. */\nexport function toShortId(id: string): string {\n return id.startsWith('kubb-labs/') ? id.slice('kubb-labs/'.length) : id\n}\n\n/**\n * GETs `url` as JSON. A non-2xx answer or a body that is not JSON returns no `body`.\n * A network error throws with the URL.\n */\nasync function fetchJSON(url: string): Promise<{ status: number; body?: unknown }> {\n let response: Response\n try {\n response = await globalThis.fetch(url, { headers: { accept: 'application/json' } })\n } catch (cause) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputUnreachable,\n severity: 'error',\n message: `Could not read ${url}: ${getErrorMessage(cause)}`,\n help: 'Check your network connection and that the registry is reachable.',\n cause: toError(cause),\n })\n }\n if (!response.ok) return { status: response.status }\n return { status: response.status, body: await response.json().catch(() => undefined) }\n}\n\n/** Fetches the registry index, leaving out entries that fail validation. */\nexport async function fetchRegistryIndex({ registry }: { registry: string }): Promise<Array<RegistryEntry>> {\n const { status, body } = await fetchJSON(`${registry}/index.json`)\n const index = body as { version?: unknown; extensions?: unknown } | null | undefined\n if (status !== 200 || index?.version !== 1 || !Array.isArray(index.extensions)) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `The registry at ${registry} sent an invalid index (HTTP ${status}).`,\n help: 'Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry.',\n })\n }\n return index.extensions.filter(isRegistryEntry)\n}\n\n/** What the package manager installs: `<package>@<version>`, or a GitHub release's commit, so the install cannot move with the tag. */\nexport function installSpec(artifact: RegistryArtifact): string {\n return artifact.kind === 'github' ? `github:${artifact.owner}/${artifact.repo}#${artifact.commit}` : `${artifact.package}@${artifact.version}`\n}\n\n/** Why the running Kubb or Node.js version cannot use this extension, or `undefined` when it can. */\nexport function incompatibility(manifest: ExtensionManifest): string | undefined {\n try {\n checkCompatibility({ name: manifest.name, compatibility: manifest.compatibility })\n return undefined\n } catch (error) {\n return getErrorMessage(error)\n }\n}\n\n/**\n * Whether `latest` is newer than `installed`. An unknown installed version counts as outdated, and an\n * invalid `latest` never does.\n */\nexport function isOutdated({ installed, latest }: { installed: string | undefined; latest: string }): boolean {\n if (!isValid(latest)) return false\n return !installed || !isValid(installed) || isLessThan(installed, latest)\n}\n\n/** `major`, `minor`, or `patch` from `installed` to `latest`, or `undefined` when either is unknown or invalid. */\nexport function bumpOf({ installed, latest }: { installed: string | undefined; latest: string }): 'major' | 'minor' | 'patch' | undefined {\n if (!installed || !isValid(installed) || !isValid(latest)) return undefined\n const kind = difference(installed, latest)\n if (!kind) return undefined\n if (kind.endsWith('major')) return 'major'\n return kind.endsWith('minor') ? 'minor' : 'patch'\n}\n\nfunction editDistance(a: string, b: string): number {\n const row = Array.from({ length: b.length + 1 }, (_, index) => index)\n for (let i = 1; i <= a.length; i++) {\n let previous = row[0]!\n row[0] = i\n for (let j = 1; j <= b.length; j++) {\n const current = row[j]!\n row[j] = Math.min(row[j]! + 1, row[j - 1]! + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1))\n previous = current\n }\n }\n return row[b.length]!\n}\n\n/** Words every extension shares, so they never make two ids look alike. */\nconst COMMON_TOKENS = new Set(['kubb', 'plugin', 'adapter', 'parser'])\n\n/**\n * The ids closest to a mistyped `input`, best first, at most three: those within a few edits of it,\n * or sharing a word such as `zod` in any order. Compares slugs, so the owner may be left out.\n */\nexport function closestIds({ input, ids }: { input: string; ids: Array<string> }): Array<string> {\n const slug = (id: string) => id.slice(id.indexOf('/') + 1)\n const tokens = new Set(\n slug(input)\n .split('-')\n .filter((token) => !COMMON_TOKENS.has(token)),\n )\n return ids\n .map((id) => ({\n id,\n distance: editDistance(slug(input), slug(id)),\n shared: slug(id)\n .split('-')\n .some((token) => tokens.has(token)),\n }))\n .filter(({ distance, shared }) => shared || distance <= Math.max(2, Math.floor(slug(input).length / 4)))\n .sort((a, b) => Number(b.shared) - Number(a.shared) || a.distance - b.distance)\n .slice(0, 3)\n .map(({ id }) => id)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry-BUPuJlgX.js","names":["sleep","process"],"sources":["../src/ui/mascot.ts","../src/utils/registry.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport { stripVTControlCharacters } from 'node:util'\nimport { isRichOutput } from '../utils/env.ts'\nimport { type Expression, getIntro, wakeUp } from '../loggers/banner.ts'\nimport { isInteractiveRun } from './intro.ts'\n\nfunction bannerIntro(version: string, expression: Expression, command: string): string {\n return getIntro({ title: 'Turn your API spec into type-safe code', description: `kubb ${command}`, version, expression })\n}\n\n/** Whether the mascot can be drawn: a rich, 256-color terminal wide enough that no line wraps and throws off a redraw. */\nfunction canDrawMascot(version: string, command: string): boolean {\n if (!isRichOutput() || !process.stdout.hasColors(256)) return false\n\n return stripVTControlCharacters(bannerIntro(version, 'open', command))\n .split('\\n')\n .every((line) => line.length <= process.stdout.columns)\n}\n\n/**\n * Whether a command opens with the mascot. Only the long-running ones do: `generate`, a Studio\n * session or pairing, and `add` or `update` while they ask questions. Quick commands print only\n * their result.\n */\nexport function wantsMascot({ commandPath, values }: { commandPath: ReadonlyArray<string>; values: Record<string, unknown> }): boolean {\n const [command, subCommand] = commandPath\n if (values.help || values.version) return false\n if (command === 'studio') return subCommand === undefined || subCommand === 'connect' || subCommand === 'login'\n if (command === 'add' || command === 'update' || command === 'init') return isInteractiveRun({ yes: values.yes, dryRun: values.dryRun ?? values['dry-run'] })\n\n return command === undefined || command === 'generate'\n}\n\n/**\n * The still Kubb mascot with the version and the running command, such as `studio connect`, or a\n * single version line where the terminal cannot draw it. Commands print it as their header; it\n * draws at once, with no wake-up frames.\n */\nexport function getBanner(version: string, command: string): string {\n return canDrawMascot(version, command) ? `\\n${bannerIntro(version, 'open', command)}` : `Kubb CLI v${version}`\n}\n\n/**\n * Opens `kubb generate` with the mascot playing its wake-up frames in place, which takes under a\n * second and overlaps the config load. Elsewhere the still {@link getBanner} is the header.\n */\nexport async function logBanner(version: string): Promise<void> {\n if (!canDrawMascot(version, 'generate')) {\n console.log(getBanner(version, 'generate'))\n\n return\n }\n\n console.log('')\n for (const [index, [expression, ms]] of wakeUp.entries()) {\n const frame = bannerIntro(version, expression, 'generate')\n if (index > 0) process.stdout.moveCursor(0, -frame.split('\\n').length)\n console.log(frame)\n await sleep(ms)\n }\n}\n","import process from 'node:process'\nimport { getErrorMessage, toError } from '@internals/utils'\nimport { checkCompatibility, Diagnostics, type ExtensionManifest, isRegistryEntry, type RegistryArtifact, type RegistryEntry } from '@kubb/core'\nimport { difference, isLessThan, isValid } from 'verkit'\n\nconst DEFAULT_REGISTRY = 'https://kubb.dev/registry'\n\nconst SLUG = '[a-z0-9]+(?:-[a-z0-9]+)*'\nconst ID = new RegExp(`^${SLUG}(\\\\/${SLUG})?$`)\n\n/** The registry base URL: `KUBB_REGISTRY`, or kubb.dev. */\nexport function registryUrl(): string {\n const url = process.env.KUBB_REGISTRY || DEFAULT_REGISTRY\n if (!/^https?:\\/\\//.test(url))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `KUBB_REGISTRY must be an http(s) URL, got \"${url}\".`,\n help: 'Set `KUBB_REGISTRY` to an http(s) URL, or unset it to use https://kubb.dev/registry.',\n })\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Turns `owner/slug`, or a bare `slug` meaning `kubb-labs/<slug>`, into a registry id.\n *\n * @throws when the id has another shape, so it never reaches a URL unchecked.\n */\nexport function toRegistryId(input: string): string {\n if (!ID.test(input))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `\"${input}\" is not a registry id. Use owner/slug, such as kubb-labs/plugin-zod, or a slug, such as plugin-zod.`,\n })\n return input.includes('/') ? input : `kubb-labs/${input}`\n}\n\n/** The shortest id `kubb add` and `kubb update` accept: the slug for an official extension, else `owner/slug`. */\nexport function toShortId(id: string): string {\n return id.startsWith('kubb-labs/') ? id.slice('kubb-labs/'.length) : id\n}\n\n/**\n * GETs `url` as JSON. A non-2xx answer or a body that is not JSON returns no `body`.\n * A network error throws with the URL.\n */\nasync function fetchJSON(url: string): Promise<{ status: number; body?: unknown }> {\n let response: Response\n try {\n response = await globalThis.fetch(url, { headers: { accept: 'application/json' } })\n } catch (cause) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputUnreachable,\n severity: 'error',\n message: `Could not read ${url}: ${getErrorMessage(cause)}`,\n help: 'Check your network connection and that the registry is reachable.',\n cause: toError(cause),\n })\n }\n if (!response.ok) return { status: response.status }\n return { status: response.status, body: await response.json().catch(() => undefined) }\n}\n\n/** Fetches the registry index, leaving out entries that fail validation. */\nexport async function fetchRegistryIndex({ registry }: { registry: string }): Promise<Array<RegistryEntry>> {\n const { status, body } = await fetchJSON(`${registry}/index.json`)\n const index = body as { version?: unknown; extensions?: unknown } | null | undefined\n if (status !== 200 || index?.version !== 1 || !Array.isArray(index.extensions)) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `The registry at ${registry} sent an invalid index (HTTP ${status}).`,\n help: 'Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry.',\n })\n }\n return index.extensions.filter(isRegistryEntry)\n}\n\n/** What the package manager installs: `<package>@<version>`, or a GitHub release's commit, so the install cannot move with the tag. */\nexport function installSpec(artifact: RegistryArtifact): string {\n return artifact.kind === 'github' ? `github:${artifact.owner}/${artifact.repo}#${artifact.commit}` : `${artifact.package}@${artifact.version}`\n}\n\n/** Why the running Kubb or Node.js version cannot use this extension, or `undefined` when it can. */\nexport function incompatibility(manifest: ExtensionManifest): string | undefined {\n try {\n checkCompatibility({ name: manifest.name, compatibility: manifest.compatibility })\n return undefined\n } catch (error) {\n return getErrorMessage(error)\n }\n}\n\n/**\n * Whether `latest` is newer than `installed`. An unknown installed version counts as outdated, and an\n * invalid `latest` never does.\n */\nexport function isOutdated({ installed, latest }: { installed: string | undefined; latest: string }): boolean {\n if (!isValid(latest)) return false\n return !installed || !isValid(installed) || isLessThan(installed, latest)\n}\n\n/** `major`, `minor`, or `patch` from `installed` to `latest`, or `undefined` when either is unknown or invalid. */\nexport function bumpOf({ installed, latest }: { installed: string | undefined; latest: string }): 'major' | 'minor' | 'patch' | undefined {\n if (!installed || !isValid(installed) || !isValid(latest)) return undefined\n const kind = difference(installed, latest)\n if (!kind) return undefined\n if (kind.endsWith('major')) return 'major'\n return kind.endsWith('minor') ? 'minor' : 'patch'\n}\n\nfunction editDistance(a: string, b: string): number {\n const row = Array.from({ length: b.length + 1 }, (_, index) => index)\n for (let i = 1; i <= a.length; i++) {\n let previous = row[0]!\n row[0] = i\n for (let j = 1; j <= b.length; j++) {\n const current = row[j]!\n row[j] = Math.min(row[j]! + 1, row[j - 1]! + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1))\n previous = current\n }\n }\n return row[b.length]!\n}\n\n/** Words every extension shares, so they never make two ids look alike. */\nconst COMMON_TOKENS = new Set(['kubb', 'plugin', 'adapter', 'parser'])\n\n/**\n * The ids closest to a mistyped `input`, best first, at most three: those within a few edits of it,\n * or sharing a word such as `zod` in any order. Compares slugs, so the owner may be left out.\n */\nexport function closestIds({ input, ids }: { input: string; ids: Array<string> }): Array<string> {\n const slug = (id: string) => id.slice(id.indexOf('/') + 1)\n const tokens = new Set(\n slug(input)\n .split('-')\n .filter((token) => !COMMON_TOKENS.has(token)),\n )\n return ids\n .map((id) => ({\n id,\n distance: editDistance(slug(input), slug(id)),\n shared: slug(id)\n .split('-')\n .some((token) => tokens.has(token)),\n }))\n .filter(({ distance, shared }) => shared || distance <= Math.max(2, Math.floor(slug(input).length / 4)))\n .sort((a, b) => Number(b.shared) - Number(a.shared) || a.distance - b.distance)\n .slice(0, 3)\n .map(({ id }) => id)\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
2
2
  const require_errors = require("./errors-Cl69p_vI.cjs");
3
- const require_utils = require("./utils-Dju97QYB.cjs");
4
- const require_text = require("./text-Sp4fptq1.cjs");
3
+ const require_utils = require("./utils-Cb4fBZiX.cjs");
4
+ const require_text = require("./text-DfFJj91M.cjs");
5
5
  let node_util = require("node:util");
6
6
  let node_process = require("node:process");
7
7
  node_process = require_rolldown_runtime.__toESM(node_process, 1);
@@ -269,4 +269,4 @@ Object.defineProperty(exports, "wantsMascot", {
269
269
  }
270
270
  });
271
271
 
272
- //# sourceMappingURL=registry-DSDoBaVk.cjs.map
272
+ //# sourceMappingURL=registry-Cl-wgD7H.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry-DSDoBaVk.cjs","names":["getIntro","isRichOutput","stripVTControlCharacters","isInteractiveRun","wakeUp","sleep","process","Diagnostics","getErrorMessage","toError","isRegistryEntry","isValid","isLessThan","difference"],"sources":["../src/ui/mascot.ts","../src/utils/registry.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport { stripVTControlCharacters } from 'node:util'\nimport { isRichOutput } from '../utils/env.ts'\nimport { type Expression, getIntro, wakeUp } from '../loggers/banner.ts'\nimport { isInteractiveRun } from './intro.ts'\n\nfunction bannerIntro(version: string, expression: Expression, command: string): string {\n return getIntro({ title: 'Turn your API spec into type-safe code', description: `kubb ${command}`, version, expression })\n}\n\n/** Whether the mascot can be drawn: a rich, 256-color terminal wide enough that no line wraps and throws off a redraw. */\nfunction canDrawMascot(version: string, command: string): boolean {\n if (!isRichOutput() || !process.stdout.hasColors(256)) return false\n\n return stripVTControlCharacters(bannerIntro(version, 'open', command))\n .split('\\n')\n .every((line) => line.length <= process.stdout.columns)\n}\n\n/**\n * Whether a command opens with the mascot. Only the long-running ones do: `generate`, a Studio\n * session or pairing, and `add` or `update` while they ask questions. Quick commands print only\n * their result.\n */\nexport function wantsMascot({ commandPath, values }: { commandPath: ReadonlyArray<string>; values: Record<string, unknown> }): boolean {\n const [command, subCommand] = commandPath\n if (values.help || values.version) return false\n if (command === 'studio') return subCommand === undefined || subCommand === 'connect' || subCommand === 'login'\n if (command === 'add' || command === 'update' || command === 'init') return isInteractiveRun({ yes: values.yes, dryRun: values.dryRun ?? values['dry-run'] })\n\n return command === undefined || command === 'generate'\n}\n\n/**\n * The still Kubb mascot with the version and the running command, such as `studio connect`, or a\n * single version line where the terminal cannot draw it. Commands print it as their header; it\n * draws at once, with no wake-up frames.\n */\nexport function getBanner(version: string, command: string): string {\n return canDrawMascot(version, command) ? `\\n${bannerIntro(version, 'open', command)}` : `Kubb CLI v${version}`\n}\n\n/**\n * Opens `kubb generate` with the mascot playing its wake-up frames in place, which takes under a\n * second and overlaps the config load. Elsewhere the still {@link getBanner} is the header.\n */\nexport async function logBanner(version: string): Promise<void> {\n if (!canDrawMascot(version, 'generate')) {\n console.log(getBanner(version, 'generate'))\n\n return\n }\n\n console.log('')\n for (const [index, [expression, ms]] of wakeUp.entries()) {\n const frame = bannerIntro(version, expression, 'generate')\n if (index > 0) process.stdout.moveCursor(0, -frame.split('\\n').length)\n console.log(frame)\n await sleep(ms)\n }\n}\n","import process from 'node:process'\nimport { getErrorMessage, toError } from '@internals/utils'\nimport { checkCompatibility, Diagnostics, type ExtensionManifest, isRegistryEntry, type RegistryArtifact, type RegistryEntry } from '@kubb/core'\nimport { difference, isLessThan, isValid } from 'verkit'\n\nconst DEFAULT_REGISTRY = 'https://kubb.dev/registry'\n\nconst SLUG = '[a-z0-9]+(?:-[a-z0-9]+)*'\nconst ID = new RegExp(`^${SLUG}(\\\\/${SLUG})?$`)\n\n/** The registry base URL: `KUBB_REGISTRY`, or kubb.dev. */\nexport function registryUrl(): string {\n const url = process.env.KUBB_REGISTRY || DEFAULT_REGISTRY\n if (!/^https?:\\/\\//.test(url))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `KUBB_REGISTRY must be an http(s) URL, got \"${url}\".`,\n help: 'Set `KUBB_REGISTRY` to an http(s) URL, or unset it to use https://kubb.dev/registry.',\n })\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Turns `owner/slug`, or a bare `slug` meaning `kubb-labs/<slug>`, into a registry id.\n *\n * @throws when the id has another shape, so it never reaches a URL unchecked.\n */\nexport function toRegistryId(input: string): string {\n if (!ID.test(input))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `\"${input}\" is not a registry id. Use owner/slug, such as kubb-labs/plugin-zod, or a slug, such as plugin-zod.`,\n })\n return input.includes('/') ? input : `kubb-labs/${input}`\n}\n\n/** The shortest id `kubb add` and `kubb update` accept: the slug for an official extension, else `owner/slug`. */\nexport function toShortId(id: string): string {\n return id.startsWith('kubb-labs/') ? id.slice('kubb-labs/'.length) : id\n}\n\n/**\n * GETs `url` as JSON. A non-2xx answer or a body that is not JSON returns no `body`.\n * A network error throws with the URL.\n */\nasync function fetchJSON(url: string): Promise<{ status: number; body?: unknown }> {\n let response: Response\n try {\n response = await globalThis.fetch(url, { headers: { accept: 'application/json' } })\n } catch (cause) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputUnreachable,\n severity: 'error',\n message: `Could not read ${url}: ${getErrorMessage(cause)}`,\n help: 'Check your network connection and that the registry is reachable.',\n cause: toError(cause),\n })\n }\n if (!response.ok) return { status: response.status }\n return { status: response.status, body: await response.json().catch(() => undefined) }\n}\n\n/** Fetches the registry index, leaving out entries that fail validation. */\nexport async function fetchRegistryIndex({ registry }: { registry: string }): Promise<Array<RegistryEntry>> {\n const { status, body } = await fetchJSON(`${registry}/index.json`)\n const index = body as { version?: unknown; extensions?: unknown } | null | undefined\n if (status !== 200 || index?.version !== 1 || !Array.isArray(index.extensions)) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `The registry at ${registry} sent an invalid index (HTTP ${status}).`,\n help: 'Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry.',\n })\n }\n return index.extensions.filter(isRegistryEntry)\n}\n\n/** What the package manager installs: `<package>@<version>`, or a GitHub release's commit, so the install cannot move with the tag. */\nexport function installSpec(artifact: RegistryArtifact): string {\n return artifact.kind === 'github' ? `github:${artifact.owner}/${artifact.repo}#${artifact.commit}` : `${artifact.package}@${artifact.version}`\n}\n\n/** Why the running Kubb or Node.js version cannot use this extension, or `undefined` when it can. */\nexport function incompatibility(manifest: ExtensionManifest): string | undefined {\n try {\n checkCompatibility({ name: manifest.name, compatibility: manifest.compatibility })\n return undefined\n } catch (error) {\n return getErrorMessage(error)\n }\n}\n\n/**\n * Whether `latest` is newer than `installed`. An unknown installed version counts as outdated, and an\n * invalid `latest` never does.\n */\nexport function isOutdated({ installed, latest }: { installed: string | undefined; latest: string }): boolean {\n if (!isValid(latest)) return false\n return !installed || !isValid(installed) || isLessThan(installed, latest)\n}\n\n/** `major`, `minor`, or `patch` from `installed` to `latest`, or `undefined` when either is unknown or invalid. */\nexport function bumpOf({ installed, latest }: { installed: string | undefined; latest: string }): 'major' | 'minor' | 'patch' | undefined {\n if (!installed || !isValid(installed) || !isValid(latest)) return undefined\n const kind = difference(installed, latest)\n if (!kind) return undefined\n if (kind.endsWith('major')) return 'major'\n return kind.endsWith('minor') ? 'minor' : 'patch'\n}\n\nfunction editDistance(a: string, b: string): number {\n const row = Array.from({ length: b.length + 1 }, (_, index) => index)\n for (let i = 1; i <= a.length; i++) {\n let previous = row[0]!\n row[0] = i\n for (let j = 1; j <= b.length; j++) {\n const current = row[j]!\n row[j] = Math.min(row[j]! + 1, row[j - 1]! + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1))\n previous = current\n }\n }\n return row[b.length]!\n}\n\n/** Words every extension shares, so they never make two ids look alike. */\nconst COMMON_TOKENS = new Set(['kubb', 'plugin', 'adapter', 'parser'])\n\n/**\n * The ids closest to a mistyped `input`, best first, at most three: those within a few edits of it,\n * or sharing a word such as `zod` in any order. Compares slugs, so the owner may be left out.\n */\nexport function closestIds({ input, ids }: { input: string; ids: Array<string> }): Array<string> {\n const slug = (id: string) => id.slice(id.indexOf('/') + 1)\n const tokens = new Set(\n slug(input)\n .split('-')\n .filter((token) => !COMMON_TOKENS.has(token)),\n )\n return ids\n .map((id) => ({\n id,\n distance: editDistance(slug(input), slug(id)),\n shared: slug(id)\n .split('-')\n .some((token) => tokens.has(token)),\n }))\n .filter(({ distance, shared }) => shared || distance <= Math.max(2, Math.floor(slug(input).length / 4)))\n .sort((a, b) => Number(b.shared) - Number(a.shared) || a.distance - b.distance)\n .slice(0, 3)\n .map(({ id }) => id)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry-Cl-wgD7H.cjs","names":["getIntro","isRichOutput","stripVTControlCharacters","isInteractiveRun","wakeUp","sleep","process","Diagnostics","getErrorMessage","toError","isRegistryEntry","isValid","isLessThan","difference"],"sources":["../src/ui/mascot.ts","../src/utils/registry.ts"],"sourcesContent":["import { setTimeout as sleep } from 'node:timers/promises'\nimport { stripVTControlCharacters } from 'node:util'\nimport { isRichOutput } from '../utils/env.ts'\nimport { type Expression, getIntro, wakeUp } from '../loggers/banner.ts'\nimport { isInteractiveRun } from './intro.ts'\n\nfunction bannerIntro(version: string, expression: Expression, command: string): string {\n return getIntro({ title: 'Turn your API spec into type-safe code', description: `kubb ${command}`, version, expression })\n}\n\n/** Whether the mascot can be drawn: a rich, 256-color terminal wide enough that no line wraps and throws off a redraw. */\nfunction canDrawMascot(version: string, command: string): boolean {\n if (!isRichOutput() || !process.stdout.hasColors(256)) return false\n\n return stripVTControlCharacters(bannerIntro(version, 'open', command))\n .split('\\n')\n .every((line) => line.length <= process.stdout.columns)\n}\n\n/**\n * Whether a command opens with the mascot. Only the long-running ones do: `generate`, a Studio\n * session or pairing, and `add` or `update` while they ask questions. Quick commands print only\n * their result.\n */\nexport function wantsMascot({ commandPath, values }: { commandPath: ReadonlyArray<string>; values: Record<string, unknown> }): boolean {\n const [command, subCommand] = commandPath\n if (values.help || values.version) return false\n if (command === 'studio') return subCommand === undefined || subCommand === 'connect' || subCommand === 'login'\n if (command === 'add' || command === 'update' || command === 'init') return isInteractiveRun({ yes: values.yes, dryRun: values.dryRun ?? values['dry-run'] })\n\n return command === undefined || command === 'generate'\n}\n\n/**\n * The still Kubb mascot with the version and the running command, such as `studio connect`, or a\n * single version line where the terminal cannot draw it. Commands print it as their header; it\n * draws at once, with no wake-up frames.\n */\nexport function getBanner(version: string, command: string): string {\n return canDrawMascot(version, command) ? `\\n${bannerIntro(version, 'open', command)}` : `Kubb CLI v${version}`\n}\n\n/**\n * Opens `kubb generate` with the mascot playing its wake-up frames in place, which takes under a\n * second and overlaps the config load. Elsewhere the still {@link getBanner} is the header.\n */\nexport async function logBanner(version: string): Promise<void> {\n if (!canDrawMascot(version, 'generate')) {\n console.log(getBanner(version, 'generate'))\n\n return\n }\n\n console.log('')\n for (const [index, [expression, ms]] of wakeUp.entries()) {\n const frame = bannerIntro(version, expression, 'generate')\n if (index > 0) process.stdout.moveCursor(0, -frame.split('\\n').length)\n console.log(frame)\n await sleep(ms)\n }\n}\n","import process from 'node:process'\nimport { getErrorMessage, toError } from '@internals/utils'\nimport { checkCompatibility, Diagnostics, type ExtensionManifest, isRegistryEntry, type RegistryArtifact, type RegistryEntry } from '@kubb/core'\nimport { difference, isLessThan, isValid } from 'verkit'\n\nconst DEFAULT_REGISTRY = 'https://kubb.dev/registry'\n\nconst SLUG = '[a-z0-9]+(?:-[a-z0-9]+)*'\nconst ID = new RegExp(`^${SLUG}(\\\\/${SLUG})?$`)\n\n/** The registry base URL: `KUBB_REGISTRY`, or kubb.dev. */\nexport function registryUrl(): string {\n const url = process.env.KUBB_REGISTRY || DEFAULT_REGISTRY\n if (!/^https?:\\/\\//.test(url))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `KUBB_REGISTRY must be an http(s) URL, got \"${url}\".`,\n help: 'Set `KUBB_REGISTRY` to an http(s) URL, or unset it to use https://kubb.dev/registry.',\n })\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Turns `owner/slug`, or a bare `slug` meaning `kubb-labs/<slug>`, into a registry id.\n *\n * @throws when the id has another shape, so it never reaches a URL unchecked.\n */\nexport function toRegistryId(input: string): string {\n if (!ID.test(input))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `\"${input}\" is not a registry id. Use owner/slug, such as kubb-labs/plugin-zod, or a slug, such as plugin-zod.`,\n })\n return input.includes('/') ? input : `kubb-labs/${input}`\n}\n\n/** The shortest id `kubb add` and `kubb update` accept: the slug for an official extension, else `owner/slug`. */\nexport function toShortId(id: string): string {\n return id.startsWith('kubb-labs/') ? id.slice('kubb-labs/'.length) : id\n}\n\n/**\n * GETs `url` as JSON. A non-2xx answer or a body that is not JSON returns no `body`.\n * A network error throws with the URL.\n */\nasync function fetchJSON(url: string): Promise<{ status: number; body?: unknown }> {\n let response: Response\n try {\n response = await globalThis.fetch(url, { headers: { accept: 'application/json' } })\n } catch (cause) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputUnreachable,\n severity: 'error',\n message: `Could not read ${url}: ${getErrorMessage(cause)}`,\n help: 'Check your network connection and that the registry is reachable.',\n cause: toError(cause),\n })\n }\n if (!response.ok) return { status: response.status }\n return { status: response.status, body: await response.json().catch(() => undefined) }\n}\n\n/** Fetches the registry index, leaving out entries that fail validation. */\nexport async function fetchRegistryIndex({ registry }: { registry: string }): Promise<Array<RegistryEntry>> {\n const { status, body } = await fetchJSON(`${registry}/index.json`)\n const index = body as { version?: unknown; extensions?: unknown } | null | undefined\n if (status !== 200 || index?.version !== 1 || !Array.isArray(index.extensions)) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `The registry at ${registry} sent an invalid index (HTTP ${status}).`,\n help: 'Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry.',\n })\n }\n return index.extensions.filter(isRegistryEntry)\n}\n\n/** What the package manager installs: `<package>@<version>`, or a GitHub release's commit, so the install cannot move with the tag. */\nexport function installSpec(artifact: RegistryArtifact): string {\n return artifact.kind === 'github' ? `github:${artifact.owner}/${artifact.repo}#${artifact.commit}` : `${artifact.package}@${artifact.version}`\n}\n\n/** Why the running Kubb or Node.js version cannot use this extension, or `undefined` when it can. */\nexport function incompatibility(manifest: ExtensionManifest): string | undefined {\n try {\n checkCompatibility({ name: manifest.name, compatibility: manifest.compatibility })\n return undefined\n } catch (error) {\n return getErrorMessage(error)\n }\n}\n\n/**\n * Whether `latest` is newer than `installed`. An unknown installed version counts as outdated, and an\n * invalid `latest` never does.\n */\nexport function isOutdated({ installed, latest }: { installed: string | undefined; latest: string }): boolean {\n if (!isValid(latest)) return false\n return !installed || !isValid(installed) || isLessThan(installed, latest)\n}\n\n/** `major`, `minor`, or `patch` from `installed` to `latest`, or `undefined` when either is unknown or invalid. */\nexport function bumpOf({ installed, latest }: { installed: string | undefined; latest: string }): 'major' | 'minor' | 'patch' | undefined {\n if (!installed || !isValid(installed) || !isValid(latest)) return undefined\n const kind = difference(installed, latest)\n if (!kind) return undefined\n if (kind.endsWith('major')) return 'major'\n return kind.endsWith('minor') ? 'minor' : 'patch'\n}\n\nfunction editDistance(a: string, b: string): number {\n const row = Array.from({ length: b.length + 1 }, (_, index) => index)\n for (let i = 1; i <= a.length; i++) {\n let previous = row[0]!\n row[0] = i\n for (let j = 1; j <= b.length; j++) {\n const current = row[j]!\n row[j] = Math.min(row[j]! + 1, row[j - 1]! + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1))\n previous = current\n }\n }\n return row[b.length]!\n}\n\n/** Words every extension shares, so they never make two ids look alike. */\nconst COMMON_TOKENS = new Set(['kubb', 'plugin', 'adapter', 'parser'])\n\n/**\n * The ids closest to a mistyped `input`, best first, at most three: those within a few edits of it,\n * or sharing a word such as `zod` in any order. Compares slugs, so the owner may be left out.\n */\nexport function closestIds({ input, ids }: { input: string; ids: Array<string> }): Array<string> {\n const slug = (id: string) => id.slice(id.indexOf('/') + 1)\n const tokens = new Set(\n slug(input)\n .split('-')\n .filter((token) => !COMMON_TOKENS.has(token)),\n )\n return ids\n .map((id) => ({\n id,\n distance: editDistance(slug(input), slug(id)),\n shared: slug(id)\n .split('-')\n .some((token) => tokens.has(token)),\n }))\n .filter(({ distance, shared }) => shared || distance <= Math.max(2, Math.floor(slug(input).length / 4)))\n .sort((a, b) => Number(b.shared) - Number(a.shared) || a.distance - b.distance)\n .slice(0, 3)\n .map(({ id }) => id)\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
2
- const require_Telemetry = require("./Telemetry-D-IDgRfq.cjs");
3
- const require_utils = require("./utils-Dju97QYB.cjs");
4
- const require_text = require("./text-Sp4fptq1.cjs");
2
+ const require_Telemetry = require("./Telemetry-C7v3wFNp.cjs");
3
+ const require_utils = require("./utils-Cb4fBZiX.cjs");
4
+ const require_text = require("./text-DfFJj91M.cjs");
5
5
  let node_util = require("node:util");
6
6
  let node_process = require("node:process");
7
7
  node_process = require_rolldown_runtime.__toESM(node_process, 1);
@@ -826,4 +826,4 @@ Object.defineProperty(exports, "setupReporters", {
826
826
  }
827
827
  });
828
828
 
829
- //# sourceMappingURL=reporters-C4xq0GFT.cjs.map
829
+ //# sourceMappingURL=reporters-DkBWh4sD.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"reporters-C4xq0GFT.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-DkBWh4sD.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,7 +1,7 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
- import { a as getElapsedMs, i as formatMs } from "./Telemetry-wyeU72_v.js";
3
- import { a as readOutputFiles, d as formatMsWithColor, g as read, h as isPathInside, r as diffOutput, u as formatBar } from "./utils-BDDF8GOv.js";
4
- import { n as toPermissionFlag, p as writer, t as pluralize } from "./text-DgzXienb.js";
2
+ import { a as getElapsedMs, i as formatMs } from "./Telemetry-BhoWyCRu.js";
3
+ import { a as readOutputFiles, d as formatMsWithColor, g as read, h as isPathInside, r as diffOutput, u as formatBar } from "./utils-BeOShrJ6.js";
4
+ import { n as toPermissionFlag, p as writer, t as pluralize } from "./text-DG7CyUe7.js";
5
5
  import { styleText } from "node:util";
6
6
  import process from "node:process";
7
7
  import { readFile } from "node:fs/promises";
@@ -814,4 +814,4 @@ function selectReporters(reporters, names) {
814
814
  //#endregion
815
815
  export { setupReporters as n, selectReporters as t };
816
816
 
817
- //# sourceMappingURL=reporters-BXNKLBLf.js.map
817
+ //# sourceMappingURL=reporters-DzAzRAlM.js.map