@kubb/cli 5.5.2 → 5.5.4

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 (87) hide show
  1. package/dist/{Telemetry-B3kc9gFh.cjs → Telemetry-BGfj0cEE.cjs} +11 -2
  2. package/dist/Telemetry-BGfj0cEE.cjs.map +1 -0
  3. package/dist/{Telemetry-cHHOzBW8.js → Telemetry-BgVmgqiW.js} +11 -2
  4. package/dist/Telemetry-BgVmgqiW.js.map +1 -0
  5. package/dist/{background-b3ec0X42.js → background-3oASCl0e.js} +2 -2
  6. package/dist/{background-b3ec0X42.js.map → background-3oASCl0e.js.map} +1 -1
  7. package/dist/{background-DUJO9lqp.cjs → background-CUTlW1Uo.cjs} +2 -2
  8. package/dist/{background-DUJO9lqp.cjs.map → background-CUTlW1Uo.cjs.map} +1 -1
  9. package/dist/background-D3EhbOlM.js +2 -0
  10. package/dist/{connect-BSN9mNt_.js → connect-1rQzCnlQ.js} +2 -2
  11. package/dist/{connect-BSN9mNt_.js.map → connect-1rQzCnlQ.js.map} +1 -1
  12. package/dist/{connect-_W1N8mi7.cjs → connect-DErJyH2K.cjs} +2 -2
  13. package/dist/{connect-_W1N8mi7.cjs.map → connect-DErJyH2K.cjs.map} +1 -1
  14. package/dist/{generate-Dp0XRNH2.cjs → generate-BE1yNlTr.cjs} +2 -2
  15. package/dist/{generate-Dp0XRNH2.cjs.map → generate-BE1yNlTr.cjs.map} +1 -1
  16. package/dist/{generate-Y4iSiFAh.js → generate-BaqPeI7c.js} +2 -2
  17. package/dist/{generate-Y4iSiFAh.js.map → generate-BaqPeI7c.js.map} +1 -1
  18. package/dist/index.cjs +8 -8
  19. package/dist/index.js +8 -8
  20. package/dist/{init-DbgeeViU.cjs → init-BgWwngao.cjs} +2 -2
  21. package/dist/{init-DbgeeViU.cjs.map → init-BgWwngao.cjs.map} +1 -1
  22. package/dist/{init-aIf8EBRW.js → init-Lbr8poOd.js} +2 -2
  23. package/dist/{init-aIf8EBRW.js.map → init-Lbr8poOd.js.map} +1 -1
  24. package/dist/{login-CA_mjtz4.cjs → login-B5SJfc2r.cjs} +2 -2
  25. package/dist/{login-CA_mjtz4.cjs.map → login-B5SJfc2r.cjs.map} +1 -1
  26. package/dist/{login-rq_qEFoy.js → login-D3WmMw8f.js} +2 -2
  27. package/dist/{login-rq_qEFoy.js.map → login-D3WmMw8f.js.map} +1 -1
  28. package/dist/{logout-B1J5c86y.js → logout-1LYszZjT.js} +3 -3
  29. package/dist/{logout-B1J5c86y.js.map → logout-1LYszZjT.js.map} +1 -1
  30. package/dist/{logout-DOMpoFGT.cjs → logout-B_nIhvr-.cjs} +3 -3
  31. package/dist/{logout-DOMpoFGT.cjs.map → logout-B_nIhvr-.cjs.map} +1 -1
  32. package/dist/package-Cp691yUF.js +6 -0
  33. package/dist/package-Cp691yUF.js.map +1 -0
  34. package/dist/{package-DTQG_XnR.cjs → package-GWkUXXHp.cjs} +2 -2
  35. package/dist/package-GWkUXXHp.cjs.map +1 -0
  36. package/dist/{run-B4Za6HxI.cjs → run-B9TJ_EJB.cjs} +3 -3
  37. package/dist/{run-B4Za6HxI.cjs.map → run-B9TJ_EJB.cjs.map} +1 -1
  38. package/dist/{run-DBMVTeYc.js → run-BImV4UtP.js} +5 -5
  39. package/dist/{run-DBMVTeYc.js.map → run-BImV4UtP.js.map} +1 -1
  40. package/dist/{run-DcxxL66g.cjs → run-BRHzFp8O.cjs} +5 -5
  41. package/dist/{run-DcxxL66g.cjs.map → run-BRHzFp8O.cjs.map} +1 -1
  42. package/dist/{run-C1NcWnFi.js → run-CnIUf-DQ.js} +12 -6
  43. package/dist/run-CnIUf-DQ.js.map +1 -0
  44. package/dist/{run-C0lN0_dx.cjs → run-D6cbi0ll.cjs} +11 -5
  45. package/dist/run-D6cbi0ll.cjs.map +1 -0
  46. package/dist/{run-Cb78U4HC.js → run-DeyU879M.js} +3 -3
  47. package/dist/{run-Cb78U4HC.js.map → run-DeyU879M.js.map} +1 -1
  48. package/dist/{run-C3hTDMfs.cjs → run-muVMUDQr.cjs} +3 -3
  49. package/dist/{run-C3hTDMfs.cjs.map → run-muVMUDQr.cjs.map} +1 -1
  50. package/dist/{run-D9nqSLXW.js → run-p60wFxuP.js} +3 -3
  51. package/dist/{run-D9nqSLXW.js.map → run-p60wFxuP.js.map} +1 -1
  52. package/dist/{snapshot-rP4XpT9w.js → snapshot-CL7I1t3R.js} +3 -3
  53. package/dist/{snapshot-rP4XpT9w.js.map → snapshot-CL7I1t3R.js.map} +1 -1
  54. package/dist/{snapshot-DA8yQlOl.cjs → snapshot-D96I3tAk.cjs} +3 -3
  55. package/dist/{snapshot-DA8yQlOl.cjs.map → snapshot-D96I3tAk.cjs.map} +1 -1
  56. package/dist/{start-DMXfSS7t.js → start-DyMt48UT.js} +3 -3
  57. package/dist/{start-DMXfSS7t.js.map → start-DyMt48UT.js.map} +1 -1
  58. package/dist/{start-BLKEsPUc.cjs → start-eQC6Ah7P.cjs} +3 -3
  59. package/dist/{start-BLKEsPUc.cjs.map → start-eQC6Ah7P.cjs.map} +1 -1
  60. package/dist/{status-gcJj6O3t.js → status-2y-COg-v.js} +3 -3
  61. package/dist/{status-gcJj6O3t.js.map → status-2y-COg-v.js.map} +1 -1
  62. package/dist/{status-s8YBdmMW.cjs → status-C3ipMO4I.cjs} +3 -3
  63. package/dist/{status-s8YBdmMW.cjs.map → status-C3ipMO4I.cjs.map} +1 -1
  64. package/dist/{stop-C1e8G7Dq.cjs → stop-BKBrz8OV.cjs} +2 -2
  65. package/dist/{stop-C1e8G7Dq.cjs.map → stop-BKBrz8OV.cjs.map} +1 -1
  66. package/dist/{stop-Dx4_298O.js → stop-Cb47DZzG.js} +2 -2
  67. package/dist/{stop-Dx4_298O.js.map → stop-Cb47DZzG.js.map} +1 -1
  68. package/dist/{studio-D4FYZGwK.js → studio-4iG51KbH.js} +9 -9
  69. package/dist/{studio-D4FYZGwK.js.map → studio-4iG51KbH.js.map} +1 -1
  70. package/dist/{studio-D7hfq4EP.cjs → studio-qkXrFCKL.cjs} +9 -9
  71. package/dist/{studio-D7hfq4EP.cjs.map → studio-qkXrFCKL.cjs.map} +1 -1
  72. package/dist/studioWorker.js +2 -2
  73. package/dist/{utils-BYY3_cyq.js → utils-CBqiF1Bf.js} +7 -9
  74. package/dist/utils-CBqiF1Bf.js.map +1 -0
  75. package/dist/{utils-Dcw3l4Wz.cjs → utils-DLTWkP_r.cjs} +7 -9
  76. package/dist/utils-DLTWkP_r.cjs.map +1 -0
  77. package/package.json +7 -7
  78. package/dist/Telemetry-B3kc9gFh.cjs.map +0 -1
  79. package/dist/Telemetry-cHHOzBW8.js.map +0 -1
  80. package/dist/background-CZuTWCy0.js +0 -2
  81. package/dist/package-CWi7augV.js +0 -6
  82. package/dist/package-CWi7augV.js.map +0 -1
  83. package/dist/package-DTQG_XnR.cjs.map +0 -1
  84. package/dist/run-C0lN0_dx.cjs.map +0 -1
  85. package/dist/run-C1NcWnFi.js.map +0 -1
  86. package/dist/utils-BYY3_cyq.js.map +0 -1
  87. package/dist/utils-Dcw3l4Wz.cjs.map +0 -1
@@ -151,6 +151,7 @@ function buildOtlpPayload(event) {
151
151
  const spanId = (0, node_crypto.randomBytes)(8).toString("hex");
152
152
  const endTimeNs = BigInt(Date.now()) * 1000000n;
153
153
  const startTimeNs = endTimeNs - BigInt(event.duration) * 1000000n;
154
+ const pluginNames = [...new Set(event.plugins.map((plugin) => plugin.name))].sort();
154
155
  const attributes = [
155
156
  {
156
157
  key: "kubb.command",
@@ -194,6 +195,14 @@ function buildOtlpPayload(event) {
194
195
  },
195
196
  {
196
197
  key: "kubb.plugins",
198
+ value: { arrayValue: { values: pluginNames.map((name) => ({ stringValue: name })) } }
199
+ },
200
+ ...pluginNames.map((name) => ({
201
+ key: `kubb.plugin.${name}`,
202
+ value: { boolValue: true }
203
+ })),
204
+ {
205
+ key: "kubb.plugin_options",
197
206
  value: { arrayValue: { values: event.plugins.map((p) => ({ kvlistValue: { values: [{
198
207
  key: "name",
199
208
  value: { stringValue: p.name }
@@ -252,7 +261,7 @@ async function sendTelemetry(event) {
252
261
  headers: {
253
262
  "Content-Type": "application/json",
254
263
  "Kubb-Telemetry-Version": "1",
255
- "Kubb-Telemetry-Source": "kubb-core"
264
+ "Kubb-Telemetry-Source": "kubb-cli"
256
265
  },
257
266
  body: JSON.stringify(buildOtlpPayload(event)),
258
267
  signal: AbortSignal.timeout(5e3)
@@ -321,4 +330,4 @@ Object.defineProperty(exports, "sendTelemetry", {
321
330
  }
322
331
  });
323
332
 
324
- //# sourceMappingURL=Telemetry-B3kc9gFh.cjs.map
333
+ //# sourceMappingURL=Telemetry-BGfj0cEE.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Telemetry-BGfj0cEE.cjs","names":["process","os","isCIEnvironment","getAgentName","randomBytes"],"sources":["../../../internals/utils/src/runtime.ts","../src/constants.ts","../src/Telemetry.ts"],"sourcesContent":["/**\n * Name of the JavaScript runtime executing the current process.\n */\ntype RuntimeName = 'bun' | 'deno' | 'node'\n\n/**\n * Detects the JavaScript runtime executing the current process and exposes its name and version.\n *\n * Prefer the shared {@link runtime} instance over constructing your own.\n */\nclass Runtime {\n /**\n * `true` when the current process is running under Bun.\n *\n * Detection keys off the global `Bun` object rather than `process.versions`,\n * because Bun polyfills `process.versions.node` for Node compatibility and would\n * otherwise look like Node.\n *\n * @example\n * ```ts\n * if (runtime.isBun) {\n * await Bun.write(path, data)\n * }\n * ```\n */\n get isBun(): boolean {\n return typeof Bun !== 'undefined'\n }\n\n /**\n * `true` when the current process is running under Deno.\n */\n get isDeno(): boolean {\n return typeof (globalThis as { Deno?: unknown }).Deno !== 'undefined'\n }\n\n /**\n * `true` when the current process is running under Node.\n *\n * Bun and Deno are excluded first so a polyfilled `process` does not register as Node.\n */\n get isNode(): boolean {\n return !this.isBun && !this.isDeno && typeof process !== 'undefined' && process.versions?.node != null\n }\n\n /**\n * Name of the runtime executing the current process.\n *\n * @example\n * ```ts\n * runtime.name // 'bun' when run with `bun kubb`, 'node' otherwise\n * ```\n */\n get name(): RuntimeName {\n if (this.isBun) return 'bun'\n if (this.isDeno) return 'deno'\n\n return 'node'\n }\n\n /**\n * Version of the active runtime, or an empty string when it cannot be read.\n *\n * @example\n * ```ts\n * runtime.version // '1.3.11' under Bun, '22.22.2' under Node\n * ```\n */\n get version(): string {\n if (this.isBun) return process.versions.bun ?? ''\n if (this.isDeno) return (globalThis as { Deno?: { version?: { deno?: string } } }).Deno?.version?.deno ?? ''\n\n return process.versions?.node ?? ''\n }\n}\n\n/**\n * Shared {@link Runtime} instance describing the JavaScript runtime executing the current process.\n */\nexport const runtime = new Runtime()\n","/**\n * NPM registry endpoint used to check for @kubb/cli updates.\n */\nexport const KUBB_NPM_PACKAGE_URL = 'https://registry.npmjs.org/@kubb/cli/latest' as const\n\n/**\n * OpenTelemetry ingestion endpoint for anonymous usage telemetry.\n */\nexport const OTLP_ENDPOINT = 'https://otlp.kubb.dev' as const\n\n/**\n * Glob pattern for paths the file watcher ignores.\n */\nexport const WATCHER_IGNORED_PATHS = '**/{.git,node_modules}/**' as const\n\n/**\n * Quiet window in milliseconds that collapses a burst of watcher events (an editor save emits\n * several) into a single rebuild.\n */\nexport const WATCHER_DEBOUNCE_MS = 100\n\n/**\n * Interval in milliseconds between polls of a remote `input` URL in watch mode. A remote document\n * emits no filesystem events, so watch mode falls back to fetching it and comparing bodies.\n */\nexport const URL_WATCHER_INTERVAL_MS = 2_000\n\n/**\n * Upper bound in milliseconds for a single URL watcher request, covering both the response headers\n * and the body read. A server that hangs mid-response would otherwise stall polling forever.\n */\nexport const URL_WATCHER_TIMEOUT_MS = 10_000\n\n/**\n * Upper bound in milliseconds for the npm update check, so a slow registry never stalls a run.\n */\nexport const UPDATE_CHECK_TIMEOUT_MS = 3_000\n\n/**\n * Flags that short-circuit execution (help and version). The telemetry notice is suppressed for these.\n */\nexport const QUIET_FLAGS = new Set<string>(['--help', '-h', '--version', '-v', '--json'])\n","import { randomBytes } from 'node:crypto'\nimport os from 'node:os'\nimport process from 'node:process'\nimport { isCIEnvironment, runtime } from '@internals/utils'\nimport { getAgentName } from './agent.ts'\nimport { OTLP_ENDPOINT } from './constants.ts'\n\ntype OtlpValue =\n | { stringValue: string }\n | { boolValue: boolean }\n | { intValue: number }\n | { arrayValue: { values: Array<OtlpValue> } }\n | { kvlistValue: { values: Array<OtlpKeyValue> } }\n\ntype OtlpKeyValue = {\n key: string\n value: OtlpValue\n}\n\ntype OtlpSpan = {\n traceId: string\n spanId: string\n name: string\n kind: 1\n startTimeUnixNano: string\n endTimeUnixNano: string\n attributes: Array<OtlpKeyValue>\n status: { code: 1 | 2 }\n}\n\ntype OtlpExportTraceServiceRequest = {\n resourceSpans: Array<{\n resource: { attributes: Array<OtlpKeyValue> }\n scopeSpans: Array<{\n scope: { name: string; version: string }\n spans: Array<OtlpSpan>\n }>\n }>\n}\n\n/**\n * Anonymous plugin name and options snapshot sent with each telemetry event.\n */\nexport type TelemetryPlugin = {\n /**\n * Plugin name as registered in the Kubb config, e.g. `'@kubb/plugin-ts'`.\n */\n name: string\n /**\n * Anonymized snapshot of the plugin options. Values are included but cannot be traced back to a user.\n */\n options: Record<string, unknown>\n}\n\n/**\n * Anonymous snapshot of a single Kubb run, built by {@link buildTelemetryEvent} and sent by {@link sendTelemetry}.\n */\ntype TelemetryEvent = {\n command: string\n kubbVersion: string\n /**\n * Major version of Node that executed the run, e.g. `'22'`.\n */\n nodeVersion: string\n /**\n * Name of the JavaScript runtime that executed the run, `'bun'`, `'deno'`, or `'node'`.\n */\n runtime: string\n /**\n * Major version of the active runtime, e.g. `'1'` under Bun or `'22'` under Node.\n */\n runtimeVersion: string\n platform: string\n ci: boolean\n /**\n * Name of the detected AI coding agent (e.g. `'claude'`, `'cursor'`), when the CLI is invoked\n * by one. `undefined` when run by a human or an unrecognized caller.\n */\n agent?: string\n plugins: Array<TelemetryPlugin>\n duration: number\n filesCreated: number\n status: 'success' | 'failed'\n}\n\n/**\n * Returns `true` when telemetry is disabled via `DO_NOT_TRACK` or `KUBB_DISABLE_TELEMETRY`.\n */\nexport function isDisabled(): boolean {\n return (\n process.env['DO_NOT_TRACK'] === '1' ||\n process.env['DO_NOT_TRACK'] === 'true' ||\n process.env['KUBB_DISABLE_TELEMETRY'] === '1' ||\n process.env['KUBB_DISABLE_TELEMETRY'] === 'true'\n )\n}\n\n/**\n * Build an anonymous telemetry payload from a completed generation run.\n */\nexport function buildTelemetryEvent(options: {\n command: 'generate' | 'mcp' | 'studio' | 'validate'\n kubbVersion: string\n plugins?: Array<TelemetryPlugin>\n hrStart: [number, number]\n filesCreated?: number\n status: 'success' | 'failed'\n}): TelemetryEvent {\n const [seconds, nanoseconds] = process.hrtime(options.hrStart)\n const duration = Math.round(seconds * 1000 + nanoseconds / 1e6)\n\n return {\n command: options.command,\n kubbVersion: options.kubbVersion,\n nodeVersion: process.versions.node.split('.')[0] as string,\n runtime: runtime.name,\n runtimeVersion: runtime.version.split('.')[0] as string,\n platform: os.platform(),\n ci: isCIEnvironment(),\n agent: getAgentName(),\n plugins: options.plugins ?? [],\n duration,\n filesCreated: options.filesCreated ?? 0,\n status: options.status,\n }\n}\n\n/**\n * Convert a {@link TelemetryEvent} into an OTLP-compatible JSON trace payload.\n *\n * @see https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/\n */\nexport function buildOtlpPayload(event: TelemetryEvent): OtlpExportTraceServiceRequest {\n const traceId = randomBytes(16).toString('hex')\n const spanId = randomBytes(8).toString('hex')\n const endTimeNs = BigInt(Date.now()) * 1_000_000n\n const startTimeNs = endTimeNs - BigInt(event.duration) * 1_000_000n\n const pluginNames = [...new Set(event.plugins.map((plugin) => plugin.name))].sort()\n\n const attributes: Array<OtlpKeyValue> = [\n { key: 'kubb.command', value: { stringValue: event.command } },\n { key: 'kubb.version', value: { stringValue: event.kubbVersion } },\n { key: 'kubb.node_version', value: { stringValue: event.nodeVersion } },\n { key: 'kubb.runtime', value: { stringValue: event.runtime } },\n { key: 'kubb.runtime_version', value: { stringValue: event.runtimeVersion } },\n { key: 'kubb.platform', value: { stringValue: event.platform } },\n { key: 'kubb.ci', value: { boolValue: event.ci } },\n ...(event.agent ? [{ key: 'kubb.agent', value: { stringValue: event.agent } }] : []),\n { key: 'kubb.files_created', value: { intValue: event.filesCreated } },\n { key: 'kubb.status', value: { stringValue: event.status } },\n {\n key: 'kubb.plugins',\n value: { arrayValue: { values: pluginNames.map((name) => ({ stringValue: name })) } },\n },\n ...pluginNames.map((name) => ({ key: `kubb.plugin.${name}`, value: { boolValue: true } })),\n {\n key: 'kubb.plugin_options',\n value: {\n arrayValue: {\n values: event.plugins.map((p) => ({\n kvlistValue: {\n values: [\n { key: 'name', value: { stringValue: p.name } },\n {\n key: 'options',\n value: {\n stringValue: JSON.stringify({\n ...p.options,\n usedEnumNames: undefined,\n }),\n },\n },\n ],\n },\n })),\n },\n },\n },\n ]\n\n return {\n resourceSpans: [\n {\n resource: {\n attributes: [\n { key: 'service.name', value: { stringValue: 'kubb-core' } },\n {\n key: 'service.version',\n value: { stringValue: event.kubbVersion },\n },\n { key: 'telemetry.sdk.language', value: { stringValue: 'nodejs' } },\n ],\n },\n scopeSpans: [\n {\n scope: { name: 'kubb-core', version: event.kubbVersion },\n spans: [\n {\n traceId,\n spanId,\n name: event.command,\n kind: 1,\n startTimeUnixNano: String(startTimeNs),\n endTimeUnixNano: String(endTimeNs),\n attributes,\n status: {\n code: event.status === 'success' ? 1 : 2,\n },\n },\n ],\n },\n ],\n },\n ],\n }\n}\n\n/**\n * Send an anonymous telemetry event to the Kubb OTLP endpoint. Respects `DO_NOT_TRACK` and\n * `KUBB_DISABLE_TELEMETRY`, and fails silently so telemetry never interrupts a run. No file\n * paths, OpenAPI specs, or secrets are sent.\n */\nexport async function sendTelemetry(event: TelemetryEvent): Promise<void> {\n if (isDisabled()) {\n return\n }\n\n try {\n await fetch(`${OTLP_ENDPOINT}/v1/traces`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Kubb-Telemetry-Version': '1',\n 'Kubb-Telemetry-Source': 'kubb-cli',\n },\n body: JSON.stringify(buildOtlpPayload(event)),\n signal: AbortSignal.timeout(5_000),\n })\n } catch (_e) {\n // Fail silently, telemetry must never break the run\n }\n}\n"],"mappings":"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"}
@@ -149,6 +149,7 @@ function buildOtlpPayload(event) {
149
149
  const spanId = randomBytes(8).toString("hex");
150
150
  const endTimeNs = BigInt(Date.now()) * 1000000n;
151
151
  const startTimeNs = endTimeNs - BigInt(event.duration) * 1000000n;
152
+ const pluginNames = [...new Set(event.plugins.map((plugin) => plugin.name))].sort();
152
153
  const attributes = [
153
154
  {
154
155
  key: "kubb.command",
@@ -192,6 +193,14 @@ function buildOtlpPayload(event) {
192
193
  },
193
194
  {
194
195
  key: "kubb.plugins",
196
+ value: { arrayValue: { values: pluginNames.map((name) => ({ stringValue: name })) } }
197
+ },
198
+ ...pluginNames.map((name) => ({
199
+ key: `kubb.plugin.${name}`,
200
+ value: { boolValue: true }
201
+ })),
202
+ {
203
+ key: "kubb.plugin_options",
195
204
  value: { arrayValue: { values: event.plugins.map((p) => ({ kvlistValue: { values: [{
196
205
  key: "name",
197
206
  value: { stringValue: p.name }
@@ -250,7 +259,7 @@ async function sendTelemetry(event) {
250
259
  headers: {
251
260
  "Content-Type": "application/json",
252
261
  "Kubb-Telemetry-Version": "1",
253
- "Kubb-Telemetry-Source": "kubb-core"
262
+ "Kubb-Telemetry-Source": "kubb-cli"
254
263
  },
255
264
  body: JSON.stringify(buildOtlpPayload(event)),
256
265
  signal: AbortSignal.timeout(5e3)
@@ -260,4 +269,4 @@ async function sendTelemetry(event) {
260
269
  //#endregion
261
270
  export { QUIET_FLAGS as a, URL_WATCHER_TIMEOUT_MS as c, KUBB_NPM_PACKAGE_URL as i, WATCHER_IGNORED_PATHS as l, isDisabled as n, UPDATE_CHECK_TIMEOUT_MS as o, sendTelemetry as r, URL_WATCHER_INTERVAL_MS as s, buildTelemetryEvent as t, runtime as u };
262
271
 
263
- //# sourceMappingURL=Telemetry-cHHOzBW8.js.map
272
+ //# sourceMappingURL=Telemetry-BgVmgqiW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Telemetry-BgVmgqiW.js","names":["process"],"sources":["../../../internals/utils/src/runtime.ts","../src/constants.ts","../src/Telemetry.ts"],"sourcesContent":["/**\n * Name of the JavaScript runtime executing the current process.\n */\ntype RuntimeName = 'bun' | 'deno' | 'node'\n\n/**\n * Detects the JavaScript runtime executing the current process and exposes its name and version.\n *\n * Prefer the shared {@link runtime} instance over constructing your own.\n */\nclass Runtime {\n /**\n * `true` when the current process is running under Bun.\n *\n * Detection keys off the global `Bun` object rather than `process.versions`,\n * because Bun polyfills `process.versions.node` for Node compatibility and would\n * otherwise look like Node.\n *\n * @example\n * ```ts\n * if (runtime.isBun) {\n * await Bun.write(path, data)\n * }\n * ```\n */\n get isBun(): boolean {\n return typeof Bun !== 'undefined'\n }\n\n /**\n * `true` when the current process is running under Deno.\n */\n get isDeno(): boolean {\n return typeof (globalThis as { Deno?: unknown }).Deno !== 'undefined'\n }\n\n /**\n * `true` when the current process is running under Node.\n *\n * Bun and Deno are excluded first so a polyfilled `process` does not register as Node.\n */\n get isNode(): boolean {\n return !this.isBun && !this.isDeno && typeof process !== 'undefined' && process.versions?.node != null\n }\n\n /**\n * Name of the runtime executing the current process.\n *\n * @example\n * ```ts\n * runtime.name // 'bun' when run with `bun kubb`, 'node' otherwise\n * ```\n */\n get name(): RuntimeName {\n if (this.isBun) return 'bun'\n if (this.isDeno) return 'deno'\n\n return 'node'\n }\n\n /**\n * Version of the active runtime, or an empty string when it cannot be read.\n *\n * @example\n * ```ts\n * runtime.version // '1.3.11' under Bun, '22.22.2' under Node\n * ```\n */\n get version(): string {\n if (this.isBun) return process.versions.bun ?? ''\n if (this.isDeno) return (globalThis as { Deno?: { version?: { deno?: string } } }).Deno?.version?.deno ?? ''\n\n return process.versions?.node ?? ''\n }\n}\n\n/**\n * Shared {@link Runtime} instance describing the JavaScript runtime executing the current process.\n */\nexport const runtime = new Runtime()\n","/**\n * NPM registry endpoint used to check for @kubb/cli updates.\n */\nexport const KUBB_NPM_PACKAGE_URL = 'https://registry.npmjs.org/@kubb/cli/latest' as const\n\n/**\n * OpenTelemetry ingestion endpoint for anonymous usage telemetry.\n */\nexport const OTLP_ENDPOINT = 'https://otlp.kubb.dev' as const\n\n/**\n * Glob pattern for paths the file watcher ignores.\n */\nexport const WATCHER_IGNORED_PATHS = '**/{.git,node_modules}/**' as const\n\n/**\n * Quiet window in milliseconds that collapses a burst of watcher events (an editor save emits\n * several) into a single rebuild.\n */\nexport const WATCHER_DEBOUNCE_MS = 100\n\n/**\n * Interval in milliseconds between polls of a remote `input` URL in watch mode. A remote document\n * emits no filesystem events, so watch mode falls back to fetching it and comparing bodies.\n */\nexport const URL_WATCHER_INTERVAL_MS = 2_000\n\n/**\n * Upper bound in milliseconds for a single URL watcher request, covering both the response headers\n * and the body read. A server that hangs mid-response would otherwise stall polling forever.\n */\nexport const URL_WATCHER_TIMEOUT_MS = 10_000\n\n/**\n * Upper bound in milliseconds for the npm update check, so a slow registry never stalls a run.\n */\nexport const UPDATE_CHECK_TIMEOUT_MS = 3_000\n\n/**\n * Flags that short-circuit execution (help and version). The telemetry notice is suppressed for these.\n */\nexport const QUIET_FLAGS = new Set<string>(['--help', '-h', '--version', '-v', '--json'])\n","import { randomBytes } from 'node:crypto'\nimport os from 'node:os'\nimport process from 'node:process'\nimport { isCIEnvironment, runtime } from '@internals/utils'\nimport { getAgentName } from './agent.ts'\nimport { OTLP_ENDPOINT } from './constants.ts'\n\ntype OtlpValue =\n | { stringValue: string }\n | { boolValue: boolean }\n | { intValue: number }\n | { arrayValue: { values: Array<OtlpValue> } }\n | { kvlistValue: { values: Array<OtlpKeyValue> } }\n\ntype OtlpKeyValue = {\n key: string\n value: OtlpValue\n}\n\ntype OtlpSpan = {\n traceId: string\n spanId: string\n name: string\n kind: 1\n startTimeUnixNano: string\n endTimeUnixNano: string\n attributes: Array<OtlpKeyValue>\n status: { code: 1 | 2 }\n}\n\ntype OtlpExportTraceServiceRequest = {\n resourceSpans: Array<{\n resource: { attributes: Array<OtlpKeyValue> }\n scopeSpans: Array<{\n scope: { name: string; version: string }\n spans: Array<OtlpSpan>\n }>\n }>\n}\n\n/**\n * Anonymous plugin name and options snapshot sent with each telemetry event.\n */\nexport type TelemetryPlugin = {\n /**\n * Plugin name as registered in the Kubb config, e.g. `'@kubb/plugin-ts'`.\n */\n name: string\n /**\n * Anonymized snapshot of the plugin options. Values are included but cannot be traced back to a user.\n */\n options: Record<string, unknown>\n}\n\n/**\n * Anonymous snapshot of a single Kubb run, built by {@link buildTelemetryEvent} and sent by {@link sendTelemetry}.\n */\ntype TelemetryEvent = {\n command: string\n kubbVersion: string\n /**\n * Major version of Node that executed the run, e.g. `'22'`.\n */\n nodeVersion: string\n /**\n * Name of the JavaScript runtime that executed the run, `'bun'`, `'deno'`, or `'node'`.\n */\n runtime: string\n /**\n * Major version of the active runtime, e.g. `'1'` under Bun or `'22'` under Node.\n */\n runtimeVersion: string\n platform: string\n ci: boolean\n /**\n * Name of the detected AI coding agent (e.g. `'claude'`, `'cursor'`), when the CLI is invoked\n * by one. `undefined` when run by a human or an unrecognized caller.\n */\n agent?: string\n plugins: Array<TelemetryPlugin>\n duration: number\n filesCreated: number\n status: 'success' | 'failed'\n}\n\n/**\n * Returns `true` when telemetry is disabled via `DO_NOT_TRACK` or `KUBB_DISABLE_TELEMETRY`.\n */\nexport function isDisabled(): boolean {\n return (\n process.env['DO_NOT_TRACK'] === '1' ||\n process.env['DO_NOT_TRACK'] === 'true' ||\n process.env['KUBB_DISABLE_TELEMETRY'] === '1' ||\n process.env['KUBB_DISABLE_TELEMETRY'] === 'true'\n )\n}\n\n/**\n * Build an anonymous telemetry payload from a completed generation run.\n */\nexport function buildTelemetryEvent(options: {\n command: 'generate' | 'mcp' | 'studio' | 'validate'\n kubbVersion: string\n plugins?: Array<TelemetryPlugin>\n hrStart: [number, number]\n filesCreated?: number\n status: 'success' | 'failed'\n}): TelemetryEvent {\n const [seconds, nanoseconds] = process.hrtime(options.hrStart)\n const duration = Math.round(seconds * 1000 + nanoseconds / 1e6)\n\n return {\n command: options.command,\n kubbVersion: options.kubbVersion,\n nodeVersion: process.versions.node.split('.')[0] as string,\n runtime: runtime.name,\n runtimeVersion: runtime.version.split('.')[0] as string,\n platform: os.platform(),\n ci: isCIEnvironment(),\n agent: getAgentName(),\n plugins: options.plugins ?? [],\n duration,\n filesCreated: options.filesCreated ?? 0,\n status: options.status,\n }\n}\n\n/**\n * Convert a {@link TelemetryEvent} into an OTLP-compatible JSON trace payload.\n *\n * @see https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/\n */\nexport function buildOtlpPayload(event: TelemetryEvent): OtlpExportTraceServiceRequest {\n const traceId = randomBytes(16).toString('hex')\n const spanId = randomBytes(8).toString('hex')\n const endTimeNs = BigInt(Date.now()) * 1_000_000n\n const startTimeNs = endTimeNs - BigInt(event.duration) * 1_000_000n\n const pluginNames = [...new Set(event.plugins.map((plugin) => plugin.name))].sort()\n\n const attributes: Array<OtlpKeyValue> = [\n { key: 'kubb.command', value: { stringValue: event.command } },\n { key: 'kubb.version', value: { stringValue: event.kubbVersion } },\n { key: 'kubb.node_version', value: { stringValue: event.nodeVersion } },\n { key: 'kubb.runtime', value: { stringValue: event.runtime } },\n { key: 'kubb.runtime_version', value: { stringValue: event.runtimeVersion } },\n { key: 'kubb.platform', value: { stringValue: event.platform } },\n { key: 'kubb.ci', value: { boolValue: event.ci } },\n ...(event.agent ? [{ key: 'kubb.agent', value: { stringValue: event.agent } }] : []),\n { key: 'kubb.files_created', value: { intValue: event.filesCreated } },\n { key: 'kubb.status', value: { stringValue: event.status } },\n {\n key: 'kubb.plugins',\n value: { arrayValue: { values: pluginNames.map((name) => ({ stringValue: name })) } },\n },\n ...pluginNames.map((name) => ({ key: `kubb.plugin.${name}`, value: { boolValue: true } })),\n {\n key: 'kubb.plugin_options',\n value: {\n arrayValue: {\n values: event.plugins.map((p) => ({\n kvlistValue: {\n values: [\n { key: 'name', value: { stringValue: p.name } },\n {\n key: 'options',\n value: {\n stringValue: JSON.stringify({\n ...p.options,\n usedEnumNames: undefined,\n }),\n },\n },\n ],\n },\n })),\n },\n },\n },\n ]\n\n return {\n resourceSpans: [\n {\n resource: {\n attributes: [\n { key: 'service.name', value: { stringValue: 'kubb-core' } },\n {\n key: 'service.version',\n value: { stringValue: event.kubbVersion },\n },\n { key: 'telemetry.sdk.language', value: { stringValue: 'nodejs' } },\n ],\n },\n scopeSpans: [\n {\n scope: { name: 'kubb-core', version: event.kubbVersion },\n spans: [\n {\n traceId,\n spanId,\n name: event.command,\n kind: 1,\n startTimeUnixNano: String(startTimeNs),\n endTimeUnixNano: String(endTimeNs),\n attributes,\n status: {\n code: event.status === 'success' ? 1 : 2,\n },\n },\n ],\n },\n ],\n },\n ],\n }\n}\n\n/**\n * Send an anonymous telemetry event to the Kubb OTLP endpoint. Respects `DO_NOT_TRACK` and\n * `KUBB_DISABLE_TELEMETRY`, and fails silently so telemetry never interrupts a run. No file\n * paths, OpenAPI specs, or secrets are sent.\n */\nexport async function sendTelemetry(event: TelemetryEvent): Promise<void> {\n if (isDisabled()) {\n return\n }\n\n try {\n await fetch(`${OTLP_ENDPOINT}/v1/traces`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Kubb-Telemetry-Version': '1',\n 'Kubb-Telemetry-Source': 'kubb-cli',\n },\n body: JSON.stringify(buildOtlpPayload(event)),\n signal: AbortSignal.timeout(5_000),\n })\n } catch (_e) {\n // Fail silently, telemetry must never break the run\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
- import { a as prepareConnection, l as getProjectKubbHome } from "./run-DBMVTeYc.js";
2
+ import { a as prepareConnection, l as getProjectKubbHome } from "./run-BImV4UtP.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { hash, randomBytes } from "node:crypto";
5
5
  import { fork } from "node:child_process";
@@ -249,4 +249,4 @@ async function startWorker(options) {
249
249
  //#endregion
250
250
  export { stopWorker as a, startWorker as i, getWorkerStatus as n, serveWorker as r, getWorkerLogPath as t };
251
251
 
252
- //# sourceMappingURL=background-b3ec0X42.js.map
252
+ //# sourceMappingURL=background-3oASCl0e.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"background-b3ec0X42.js","names":["connectSocket","delay"],"sources":["../src/runners/studio/background.ts"],"sourcesContent":["import { fork } from 'node:child_process'\nimport { hash, randomBytes } from 'node:crypto'\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { connect as connectSocket, createServer } from 'node:net'\nimport path from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { getProjectKubbHome } from './credentials.ts'\nimport { prepareConnection, type PreparedConnection, type StudioOptions, type WorkerState } from './run.ts'\n\nexport type WorkerRecord = { id: string; pid: number; port: number; state: WorkerState }\nconst states: Array<WorkerState> = ['starting', 'connected', 'reconnecting', 'authentication required', 'stopped']\nexport const getWorkerLogPath = () => path.join(getProjectKubbHome(), 'worker.log')\nconst statePath = () => path.join(getProjectKubbHome(), 'worker.json')\n\nasync function readWorker(): Promise<WorkerRecord | null> {\n try {\n const value: unknown = JSON.parse(await readFile(statePath(), 'utf8'))\n if (!value || typeof value !== 'object') return null\n const record = value as Partial<WorkerRecord>\n return typeof record.id === 'string' &&\n /^[a-f0-9]{32}$/.test(record.id) &&\n Number.isInteger(record.pid) &&\n (record.pid ?? 0) > 1 &&\n Number.isInteger(record.port) &&\n (record.port ?? 0) > 0 &&\n (record.port ?? 0) <= 65535 &&\n states.includes(record.state as WorkerState)\n ? (record as WorkerRecord)\n : null\n } catch {\n return null\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/** Authenticated loopback IPC; a stored PID never authorizes sending a process signal. */\nfunction requestWorker(record: WorkerRecord, command: 'status' | 'stop'): Promise<WorkerRecord> {\n return new Promise((resolve, reject) => {\n const socket = connectSocket({ host: '127.0.0.1', port: record.port })\n let received = ''\n socket.setTimeout(2_000, () => socket.destroy(new Error('Worker control timed out')))\n socket.once('error', reject)\n socket.once('connect', () => socket.write(JSON.stringify({ id: record.id, command }) + '\\n'))\n socket.on('data', (chunk: Buffer) => {\n received += chunk.toString()\n if (received.length > 4096) socket.destroy(new Error('Invalid worker response'))\n })\n socket.once('end', () => {\n try {\n const response = JSON.parse(received) as WorkerRecord\n if (response.id !== record.id || response.pid !== record.pid || !states.includes(response.state)) throw new Error('Worker identity changed')\n resolve(response)\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nexport async function getWorkerStatus(): Promise<{ running: boolean; state: WorkerState; pid?: number }> {\n const record = await readWorker()\n if (!record) return { running: false, state: 'stopped' }\n try {\n const response = await requestWorker(record, 'status')\n return { running: true, state: response.state, pid: response.pid }\n } catch {\n return { running: false, state: record.state === 'authentication required' ? record.state : 'stopped' }\n }\n}\n\nexport async function stopWorker(): Promise<void> {\n const record = await readWorker()\n if (!record) return\n try {\n await requestWorker(record, 'stop')\n } catch (error) {\n if (\n (error as NodeJS.ErrnoException).code !== 'ECONNREFUSED' &&\n isAlive(record.pid) &&\n record.state !== 'stopped' &&\n record.state !== 'authentication required'\n ) {\n throw new Error('Cannot verify the background worker. No process was signaled.')\n }\n return\n }\n const deadline = Date.now() + 15_000\n while (Date.now() < deadline) {\n try {\n await requestWorker(record, 'status')\n } catch {\n return\n }\n await delay(100)\n }\n throw new Error('The worker has not finished shutting down. Check worker.log and try again.')\n}\n\n/** The listening port is the project lock, so stale state never needs a PID-based takeover. */\nexport async function serveWorker(shutdown: AbortController) {\n const record: WorkerRecord = { id: randomBytes(16).toString('hex'), pid: process.pid, port: 0, state: 'starting' }\n const server = createServer((socket) => {\n let input = ''\n socket.setTimeout(2_000, () => socket.destroy())\n socket.on('error', () => {})\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString()\n if (input.length > 4096) {\n socket.destroy()\n return\n }\n if (!input.includes('\\n')) return\n try {\n const request = JSON.parse(input) as { id?: unknown; command?: unknown }\n if (request.id !== record.id || !['status', 'stop'].includes(String(request.command))) {\n socket.destroy()\n return\n }\n socket.end(JSON.stringify(record))\n if (request.command === 'stop') shutdown.abort()\n } catch {\n socket.destroy()\n }\n })\n })\n // Hash the project directory to choose its loopback port; fail on collisions.\n const port = 20_000 + (Number.parseInt(hash('sha256', getProjectKubbHome()).slice(0, 8), 16) % 30_000)\n try {\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, '127.0.0.1', resolve)\n })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EADDRINUSE') throw error\n // Let a simultaneous starter finish writing its record before checking ownership.\n await delay(100)\n const existing = await readWorker()\n if (existing?.port === port) {\n try {\n return { existing: await requestWorker(existing, 'status') }\n } catch {\n /* Refuse an unverified listener. */\n }\n }\n throw new Error('The project control port is occupied or another worker is starting. Try again after stopping that listener.')\n }\n record.port = port\n let saving = Promise.resolve()\n const save = () => {\n const value = JSON.stringify(record)\n saving = saving.then(async () => {\n const temporary = `${statePath()}.${record.id}`\n await writeFile(temporary, value, { mode: 0o600 })\n await rename(temporary, statePath())\n })\n return saving\n }\n try {\n await mkdir(getProjectKubbHome(), { recursive: true, mode: 0o700 })\n await save()\n } catch (error) {\n server.close()\n throw error\n }\n return {\n async state(state: WorkerState) {\n record.state = state\n await save()\n },\n async close() {\n try {\n if (record.state !== 'authentication required') {\n record.state = 'stopped'\n await save()\n }\n } finally {\n await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())))\n }\n },\n }\n}\n\nexport type WorkerLaunch = { options: StudioOptions; prepared: PreparedConnection }\n\nexport async function startWorker(options: StudioOptions): Promise<void> {\n const current = await getWorkerStatus()\n if (current.running) {\n console.log(`Already running (${current.state}, PID ${current.pid}).`)\n return\n }\n const prepared = await prepareConnection(options)\n const entry = path.join(path.dirname(createRequire(import.meta.url).resolve('@kubb/cli/package.json')), 'dist', 'studioWorker.js')\n const child = fork(entry, [], { cwd: process.cwd(), detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] })\n try {\n const started = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => done(new Error('Background worker startup timed out')), 20_000)\n const done = (error?: Error) => {\n clearTimeout(timer)\n child.removeListener('error', failed)\n child.removeListener('exit', exited)\n child.removeListener('message', ready)\n if (error) reject(error)\n else resolve()\n }\n const failed = (error: Error) => done(error)\n const exited = () => done(new Error(`Background worker exited during startup. Check ${getWorkerLogPath()}`))\n child.once('error', failed)\n child.once('exit', exited)\n const ready = (message: unknown) => {\n if (!message || typeof message !== 'object' || !('started' in message) || message.started !== true)\n return done(new Error('Invalid worker startup response'))\n done()\n }\n child.once('message', ready)\n child.send({ options: { ...options, autoOpen: false }, prepared } satisfies WorkerLaunch, (error) => {\n if (error) done(error)\n })\n })\n await started\n if (child.connected) child.disconnect()\n child.unref()\n const status = await getWorkerStatus()\n console.log(`Background worker ${status.state} (PID ${status.pid ?? child.pid}). Logs: ${getWorkerLogPath()}`)\n } catch (error) {\n // This is the child we just spawned, not a PID recovered from disk.\n child.kill('SIGTERM')\n throw error\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"background-3oASCl0e.js","names":["connectSocket","delay"],"sources":["../src/runners/studio/background.ts"],"sourcesContent":["import { fork } from 'node:child_process'\nimport { hash, randomBytes } from 'node:crypto'\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { connect as connectSocket, createServer } from 'node:net'\nimport path from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { getProjectKubbHome } from './credentials.ts'\nimport { prepareConnection, type PreparedConnection, type StudioOptions, type WorkerState } from './run.ts'\n\nexport type WorkerRecord = { id: string; pid: number; port: number; state: WorkerState }\nconst states: Array<WorkerState> = ['starting', 'connected', 'reconnecting', 'authentication required', 'stopped']\nexport const getWorkerLogPath = () => path.join(getProjectKubbHome(), 'worker.log')\nconst statePath = () => path.join(getProjectKubbHome(), 'worker.json')\n\nasync function readWorker(): Promise<WorkerRecord | null> {\n try {\n const value: unknown = JSON.parse(await readFile(statePath(), 'utf8'))\n if (!value || typeof value !== 'object') return null\n const record = value as Partial<WorkerRecord>\n return typeof record.id === 'string' &&\n /^[a-f0-9]{32}$/.test(record.id) &&\n Number.isInteger(record.pid) &&\n (record.pid ?? 0) > 1 &&\n Number.isInteger(record.port) &&\n (record.port ?? 0) > 0 &&\n (record.port ?? 0) <= 65535 &&\n states.includes(record.state as WorkerState)\n ? (record as WorkerRecord)\n : null\n } catch {\n return null\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/** Authenticated loopback IPC; a stored PID never authorizes sending a process signal. */\nfunction requestWorker(record: WorkerRecord, command: 'status' | 'stop'): Promise<WorkerRecord> {\n return new Promise((resolve, reject) => {\n const socket = connectSocket({ host: '127.0.0.1', port: record.port })\n let received = ''\n socket.setTimeout(2_000, () => socket.destroy(new Error('Worker control timed out')))\n socket.once('error', reject)\n socket.once('connect', () => socket.write(JSON.stringify({ id: record.id, command }) + '\\n'))\n socket.on('data', (chunk: Buffer) => {\n received += chunk.toString()\n if (received.length > 4096) socket.destroy(new Error('Invalid worker response'))\n })\n socket.once('end', () => {\n try {\n const response = JSON.parse(received) as WorkerRecord\n if (response.id !== record.id || response.pid !== record.pid || !states.includes(response.state)) throw new Error('Worker identity changed')\n resolve(response)\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nexport async function getWorkerStatus(): Promise<{ running: boolean; state: WorkerState; pid?: number }> {\n const record = await readWorker()\n if (!record) return { running: false, state: 'stopped' }\n try {\n const response = await requestWorker(record, 'status')\n return { running: true, state: response.state, pid: response.pid }\n } catch {\n return { running: false, state: record.state === 'authentication required' ? record.state : 'stopped' }\n }\n}\n\nexport async function stopWorker(): Promise<void> {\n const record = await readWorker()\n if (!record) return\n try {\n await requestWorker(record, 'stop')\n } catch (error) {\n if (\n (error as NodeJS.ErrnoException).code !== 'ECONNREFUSED' &&\n isAlive(record.pid) &&\n record.state !== 'stopped' &&\n record.state !== 'authentication required'\n ) {\n throw new Error('Cannot verify the background worker. No process was signaled.')\n }\n return\n }\n const deadline = Date.now() + 15_000\n while (Date.now() < deadline) {\n try {\n await requestWorker(record, 'status')\n } catch {\n return\n }\n await delay(100)\n }\n throw new Error('The worker has not finished shutting down. Check worker.log and try again.')\n}\n\n/** The listening port is the project lock, so stale state never needs a PID-based takeover. */\nexport async function serveWorker(shutdown: AbortController) {\n const record: WorkerRecord = { id: randomBytes(16).toString('hex'), pid: process.pid, port: 0, state: 'starting' }\n const server = createServer((socket) => {\n let input = ''\n socket.setTimeout(2_000, () => socket.destroy())\n socket.on('error', () => {})\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString()\n if (input.length > 4096) {\n socket.destroy()\n return\n }\n if (!input.includes('\\n')) return\n try {\n const request = JSON.parse(input) as { id?: unknown; command?: unknown }\n if (request.id !== record.id || !['status', 'stop'].includes(String(request.command))) {\n socket.destroy()\n return\n }\n socket.end(JSON.stringify(record))\n if (request.command === 'stop') shutdown.abort()\n } catch {\n socket.destroy()\n }\n })\n })\n // Hash the project directory to choose its loopback port; fail on collisions.\n const port = 20_000 + (Number.parseInt(hash('sha256', getProjectKubbHome()).slice(0, 8), 16) % 30_000)\n try {\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, '127.0.0.1', resolve)\n })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EADDRINUSE') throw error\n // Let a simultaneous starter finish writing its record before checking ownership.\n await delay(100)\n const existing = await readWorker()\n if (existing?.port === port) {\n try {\n return { existing: await requestWorker(existing, 'status') }\n } catch {\n /* Refuse an unverified listener. */\n }\n }\n throw new Error('The project control port is occupied or another worker is starting. Try again after stopping that listener.')\n }\n record.port = port\n let saving = Promise.resolve()\n const save = () => {\n const value = JSON.stringify(record)\n saving = saving.then(async () => {\n const temporary = `${statePath()}.${record.id}`\n await writeFile(temporary, value, { mode: 0o600 })\n await rename(temporary, statePath())\n })\n return saving\n }\n try {\n await mkdir(getProjectKubbHome(), { recursive: true, mode: 0o700 })\n await save()\n } catch (error) {\n server.close()\n throw error\n }\n return {\n async state(state: WorkerState) {\n record.state = state\n await save()\n },\n async close() {\n try {\n if (record.state !== 'authentication required') {\n record.state = 'stopped'\n await save()\n }\n } finally {\n await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())))\n }\n },\n }\n}\n\nexport type WorkerLaunch = { options: StudioOptions; prepared: PreparedConnection }\n\nexport async function startWorker(options: StudioOptions): Promise<void> {\n const current = await getWorkerStatus()\n if (current.running) {\n console.log(`Already running (${current.state}, PID ${current.pid}).`)\n return\n }\n const prepared = await prepareConnection(options)\n const entry = path.join(path.dirname(createRequire(import.meta.url).resolve('@kubb/cli/package.json')), 'dist', 'studioWorker.js')\n const child = fork(entry, [], { cwd: process.cwd(), detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] })\n try {\n const started = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => done(new Error('Background worker startup timed out')), 20_000)\n const done = (error?: Error) => {\n clearTimeout(timer)\n child.removeListener('error', failed)\n child.removeListener('exit', exited)\n child.removeListener('message', ready)\n if (error) reject(error)\n else resolve()\n }\n const failed = (error: Error) => done(error)\n const exited = () => done(new Error(`Background worker exited during startup. Check ${getWorkerLogPath()}`))\n child.once('error', failed)\n child.once('exit', exited)\n const ready = (message: unknown) => {\n if (!message || typeof message !== 'object' || !('started' in message) || message.started !== true)\n return done(new Error('Invalid worker startup response'))\n done()\n }\n child.once('message', ready)\n child.send({ options: { ...options, autoOpen: false }, prepared } satisfies WorkerLaunch, (error) => {\n if (error) done(error)\n })\n })\n await started\n if (child.connected) child.disconnect()\n child.unref()\n const status = await getWorkerStatus()\n console.log(`Background worker ${status.state} (PID ${status.pid ?? child.pid}). Logs: ${getWorkerLogPath()}`)\n } catch (error) {\n // This is the child we just spawned, not a PID recovered from disk.\n child.kill('SIGTERM')\n throw error\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
2
- const require_run = require("./run-DcxxL66g.cjs");
2
+ const require_run = require("./run-BRHzFp8O.cjs");
3
3
  require("node:crypto");
4
4
  let node_child_process = require("node:child_process");
5
5
  let node_fs_promises = require("node:fs/promises");
@@ -168,4 +168,4 @@ exports.getWorkerStatus = getWorkerStatus;
168
168
  exports.startWorker = startWorker;
169
169
  exports.stopWorker = stopWorker;
170
170
 
171
- //# sourceMappingURL=background-DUJO9lqp.cjs.map
171
+ //# sourceMappingURL=background-CUTlW1Uo.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"background-DUJO9lqp.cjs","names":["path","getProjectKubbHome","readFile","connectSocket","delay","prepareConnection","createRequire","fork"],"sources":["../src/runners/studio/background.ts"],"sourcesContent":["import { fork } from 'node:child_process'\nimport { hash, randomBytes } from 'node:crypto'\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { connect as connectSocket, createServer } from 'node:net'\nimport path from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { getProjectKubbHome } from './credentials.ts'\nimport { prepareConnection, type PreparedConnection, type StudioOptions, type WorkerState } from './run.ts'\n\nexport type WorkerRecord = { id: string; pid: number; port: number; state: WorkerState }\nconst states: Array<WorkerState> = ['starting', 'connected', 'reconnecting', 'authentication required', 'stopped']\nexport const getWorkerLogPath = () => path.join(getProjectKubbHome(), 'worker.log')\nconst statePath = () => path.join(getProjectKubbHome(), 'worker.json')\n\nasync function readWorker(): Promise<WorkerRecord | null> {\n try {\n const value: unknown = JSON.parse(await readFile(statePath(), 'utf8'))\n if (!value || typeof value !== 'object') return null\n const record = value as Partial<WorkerRecord>\n return typeof record.id === 'string' &&\n /^[a-f0-9]{32}$/.test(record.id) &&\n Number.isInteger(record.pid) &&\n (record.pid ?? 0) > 1 &&\n Number.isInteger(record.port) &&\n (record.port ?? 0) > 0 &&\n (record.port ?? 0) <= 65535 &&\n states.includes(record.state as WorkerState)\n ? (record as WorkerRecord)\n : null\n } catch {\n return null\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/** Authenticated loopback IPC; a stored PID never authorizes sending a process signal. */\nfunction requestWorker(record: WorkerRecord, command: 'status' | 'stop'): Promise<WorkerRecord> {\n return new Promise((resolve, reject) => {\n const socket = connectSocket({ host: '127.0.0.1', port: record.port })\n let received = ''\n socket.setTimeout(2_000, () => socket.destroy(new Error('Worker control timed out')))\n socket.once('error', reject)\n socket.once('connect', () => socket.write(JSON.stringify({ id: record.id, command }) + '\\n'))\n socket.on('data', (chunk: Buffer) => {\n received += chunk.toString()\n if (received.length > 4096) socket.destroy(new Error('Invalid worker response'))\n })\n socket.once('end', () => {\n try {\n const response = JSON.parse(received) as WorkerRecord\n if (response.id !== record.id || response.pid !== record.pid || !states.includes(response.state)) throw new Error('Worker identity changed')\n resolve(response)\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nexport async function getWorkerStatus(): Promise<{ running: boolean; state: WorkerState; pid?: number }> {\n const record = await readWorker()\n if (!record) return { running: false, state: 'stopped' }\n try {\n const response = await requestWorker(record, 'status')\n return { running: true, state: response.state, pid: response.pid }\n } catch {\n return { running: false, state: record.state === 'authentication required' ? record.state : 'stopped' }\n }\n}\n\nexport async function stopWorker(): Promise<void> {\n const record = await readWorker()\n if (!record) return\n try {\n await requestWorker(record, 'stop')\n } catch (error) {\n if (\n (error as NodeJS.ErrnoException).code !== 'ECONNREFUSED' &&\n isAlive(record.pid) &&\n record.state !== 'stopped' &&\n record.state !== 'authentication required'\n ) {\n throw new Error('Cannot verify the background worker. No process was signaled.')\n }\n return\n }\n const deadline = Date.now() + 15_000\n while (Date.now() < deadline) {\n try {\n await requestWorker(record, 'status')\n } catch {\n return\n }\n await delay(100)\n }\n throw new Error('The worker has not finished shutting down. Check worker.log and try again.')\n}\n\n/** The listening port is the project lock, so stale state never needs a PID-based takeover. */\nexport async function serveWorker(shutdown: AbortController) {\n const record: WorkerRecord = { id: randomBytes(16).toString('hex'), pid: process.pid, port: 0, state: 'starting' }\n const server = createServer((socket) => {\n let input = ''\n socket.setTimeout(2_000, () => socket.destroy())\n socket.on('error', () => {})\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString()\n if (input.length > 4096) {\n socket.destroy()\n return\n }\n if (!input.includes('\\n')) return\n try {\n const request = JSON.parse(input) as { id?: unknown; command?: unknown }\n if (request.id !== record.id || !['status', 'stop'].includes(String(request.command))) {\n socket.destroy()\n return\n }\n socket.end(JSON.stringify(record))\n if (request.command === 'stop') shutdown.abort()\n } catch {\n socket.destroy()\n }\n })\n })\n // Hash the project directory to choose its loopback port; fail on collisions.\n const port = 20_000 + (Number.parseInt(hash('sha256', getProjectKubbHome()).slice(0, 8), 16) % 30_000)\n try {\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, '127.0.0.1', resolve)\n })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EADDRINUSE') throw error\n // Let a simultaneous starter finish writing its record before checking ownership.\n await delay(100)\n const existing = await readWorker()\n if (existing?.port === port) {\n try {\n return { existing: await requestWorker(existing, 'status') }\n } catch {\n /* Refuse an unverified listener. */\n }\n }\n throw new Error('The project control port is occupied or another worker is starting. Try again after stopping that listener.')\n }\n record.port = port\n let saving = Promise.resolve()\n const save = () => {\n const value = JSON.stringify(record)\n saving = saving.then(async () => {\n const temporary = `${statePath()}.${record.id}`\n await writeFile(temporary, value, { mode: 0o600 })\n await rename(temporary, statePath())\n })\n return saving\n }\n try {\n await mkdir(getProjectKubbHome(), { recursive: true, mode: 0o700 })\n await save()\n } catch (error) {\n server.close()\n throw error\n }\n return {\n async state(state: WorkerState) {\n record.state = state\n await save()\n },\n async close() {\n try {\n if (record.state !== 'authentication required') {\n record.state = 'stopped'\n await save()\n }\n } finally {\n await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())))\n }\n },\n }\n}\n\nexport type WorkerLaunch = { options: StudioOptions; prepared: PreparedConnection }\n\nexport async function startWorker(options: StudioOptions): Promise<void> {\n const current = await getWorkerStatus()\n if (current.running) {\n console.log(`Already running (${current.state}, PID ${current.pid}).`)\n return\n }\n const prepared = await prepareConnection(options)\n const entry = path.join(path.dirname(createRequire(import.meta.url).resolve('@kubb/cli/package.json')), 'dist', 'studioWorker.js')\n const child = fork(entry, [], { cwd: process.cwd(), detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] })\n try {\n const started = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => done(new Error('Background worker startup timed out')), 20_000)\n const done = (error?: Error) => {\n clearTimeout(timer)\n child.removeListener('error', failed)\n child.removeListener('exit', exited)\n child.removeListener('message', ready)\n if (error) reject(error)\n else resolve()\n }\n const failed = (error: Error) => done(error)\n const exited = () => done(new Error(`Background worker exited during startup. Check ${getWorkerLogPath()}`))\n child.once('error', failed)\n child.once('exit', exited)\n const ready = (message: unknown) => {\n if (!message || typeof message !== 'object' || !('started' in message) || message.started !== true)\n return done(new Error('Invalid worker startup response'))\n done()\n }\n child.once('message', ready)\n child.send({ options: { ...options, autoOpen: false }, prepared } satisfies WorkerLaunch, (error) => {\n if (error) done(error)\n })\n })\n await started\n if (child.connected) child.disconnect()\n child.unref()\n const status = await getWorkerStatus()\n console.log(`Background worker ${status.state} (PID ${status.pid ?? child.pid}). Logs: ${getWorkerLogPath()}`)\n } catch (error) {\n // This is the child we just spawned, not a PID recovered from disk.\n child.kill('SIGTERM')\n throw error\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"background-CUTlW1Uo.cjs","names":["path","getProjectKubbHome","readFile","connectSocket","delay","prepareConnection","createRequire","fork"],"sources":["../src/runners/studio/background.ts"],"sourcesContent":["import { fork } from 'node:child_process'\nimport { hash, randomBytes } from 'node:crypto'\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { connect as connectSocket, createServer } from 'node:net'\nimport path from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { getProjectKubbHome } from './credentials.ts'\nimport { prepareConnection, type PreparedConnection, type StudioOptions, type WorkerState } from './run.ts'\n\nexport type WorkerRecord = { id: string; pid: number; port: number; state: WorkerState }\nconst states: Array<WorkerState> = ['starting', 'connected', 'reconnecting', 'authentication required', 'stopped']\nexport const getWorkerLogPath = () => path.join(getProjectKubbHome(), 'worker.log')\nconst statePath = () => path.join(getProjectKubbHome(), 'worker.json')\n\nasync function readWorker(): Promise<WorkerRecord | null> {\n try {\n const value: unknown = JSON.parse(await readFile(statePath(), 'utf8'))\n if (!value || typeof value !== 'object') return null\n const record = value as Partial<WorkerRecord>\n return typeof record.id === 'string' &&\n /^[a-f0-9]{32}$/.test(record.id) &&\n Number.isInteger(record.pid) &&\n (record.pid ?? 0) > 1 &&\n Number.isInteger(record.port) &&\n (record.port ?? 0) > 0 &&\n (record.port ?? 0) <= 65535 &&\n states.includes(record.state as WorkerState)\n ? (record as WorkerRecord)\n : null\n } catch {\n return null\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/** Authenticated loopback IPC; a stored PID never authorizes sending a process signal. */\nfunction requestWorker(record: WorkerRecord, command: 'status' | 'stop'): Promise<WorkerRecord> {\n return new Promise((resolve, reject) => {\n const socket = connectSocket({ host: '127.0.0.1', port: record.port })\n let received = ''\n socket.setTimeout(2_000, () => socket.destroy(new Error('Worker control timed out')))\n socket.once('error', reject)\n socket.once('connect', () => socket.write(JSON.stringify({ id: record.id, command }) + '\\n'))\n socket.on('data', (chunk: Buffer) => {\n received += chunk.toString()\n if (received.length > 4096) socket.destroy(new Error('Invalid worker response'))\n })\n socket.once('end', () => {\n try {\n const response = JSON.parse(received) as WorkerRecord\n if (response.id !== record.id || response.pid !== record.pid || !states.includes(response.state)) throw new Error('Worker identity changed')\n resolve(response)\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nexport async function getWorkerStatus(): Promise<{ running: boolean; state: WorkerState; pid?: number }> {\n const record = await readWorker()\n if (!record) return { running: false, state: 'stopped' }\n try {\n const response = await requestWorker(record, 'status')\n return { running: true, state: response.state, pid: response.pid }\n } catch {\n return { running: false, state: record.state === 'authentication required' ? record.state : 'stopped' }\n }\n}\n\nexport async function stopWorker(): Promise<void> {\n const record = await readWorker()\n if (!record) return\n try {\n await requestWorker(record, 'stop')\n } catch (error) {\n if (\n (error as NodeJS.ErrnoException).code !== 'ECONNREFUSED' &&\n isAlive(record.pid) &&\n record.state !== 'stopped' &&\n record.state !== 'authentication required'\n ) {\n throw new Error('Cannot verify the background worker. No process was signaled.')\n }\n return\n }\n const deadline = Date.now() + 15_000\n while (Date.now() < deadline) {\n try {\n await requestWorker(record, 'status')\n } catch {\n return\n }\n await delay(100)\n }\n throw new Error('The worker has not finished shutting down. Check worker.log and try again.')\n}\n\n/** The listening port is the project lock, so stale state never needs a PID-based takeover. */\nexport async function serveWorker(shutdown: AbortController) {\n const record: WorkerRecord = { id: randomBytes(16).toString('hex'), pid: process.pid, port: 0, state: 'starting' }\n const server = createServer((socket) => {\n let input = ''\n socket.setTimeout(2_000, () => socket.destroy())\n socket.on('error', () => {})\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString()\n if (input.length > 4096) {\n socket.destroy()\n return\n }\n if (!input.includes('\\n')) return\n try {\n const request = JSON.parse(input) as { id?: unknown; command?: unknown }\n if (request.id !== record.id || !['status', 'stop'].includes(String(request.command))) {\n socket.destroy()\n return\n }\n socket.end(JSON.stringify(record))\n if (request.command === 'stop') shutdown.abort()\n } catch {\n socket.destroy()\n }\n })\n })\n // Hash the project directory to choose its loopback port; fail on collisions.\n const port = 20_000 + (Number.parseInt(hash('sha256', getProjectKubbHome()).slice(0, 8), 16) % 30_000)\n try {\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, '127.0.0.1', resolve)\n })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EADDRINUSE') throw error\n // Let a simultaneous starter finish writing its record before checking ownership.\n await delay(100)\n const existing = await readWorker()\n if (existing?.port === port) {\n try {\n return { existing: await requestWorker(existing, 'status') }\n } catch {\n /* Refuse an unverified listener. */\n }\n }\n throw new Error('The project control port is occupied or another worker is starting. Try again after stopping that listener.')\n }\n record.port = port\n let saving = Promise.resolve()\n const save = () => {\n const value = JSON.stringify(record)\n saving = saving.then(async () => {\n const temporary = `${statePath()}.${record.id}`\n await writeFile(temporary, value, { mode: 0o600 })\n await rename(temporary, statePath())\n })\n return saving\n }\n try {\n await mkdir(getProjectKubbHome(), { recursive: true, mode: 0o700 })\n await save()\n } catch (error) {\n server.close()\n throw error\n }\n return {\n async state(state: WorkerState) {\n record.state = state\n await save()\n },\n async close() {\n try {\n if (record.state !== 'authentication required') {\n record.state = 'stopped'\n await save()\n }\n } finally {\n await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())))\n }\n },\n }\n}\n\nexport type WorkerLaunch = { options: StudioOptions; prepared: PreparedConnection }\n\nexport async function startWorker(options: StudioOptions): Promise<void> {\n const current = await getWorkerStatus()\n if (current.running) {\n console.log(`Already running (${current.state}, PID ${current.pid}).`)\n return\n }\n const prepared = await prepareConnection(options)\n const entry = path.join(path.dirname(createRequire(import.meta.url).resolve('@kubb/cli/package.json')), 'dist', 'studioWorker.js')\n const child = fork(entry, [], { cwd: process.cwd(), detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] })\n try {\n const started = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => done(new Error('Background worker startup timed out')), 20_000)\n const done = (error?: Error) => {\n clearTimeout(timer)\n child.removeListener('error', failed)\n child.removeListener('exit', exited)\n child.removeListener('message', ready)\n if (error) reject(error)\n else resolve()\n }\n const failed = (error: Error) => done(error)\n const exited = () => done(new Error(`Background worker exited during startup. Check ${getWorkerLogPath()}`))\n child.once('error', failed)\n child.once('exit', exited)\n const ready = (message: unknown) => {\n if (!message || typeof message !== 'object' || !('started' in message) || message.started !== true)\n return done(new Error('Invalid worker startup response'))\n done()\n }\n child.once('message', ready)\n child.send({ options: { ...options, autoOpen: false }, prepared } satisfies WorkerLaunch, (error) => {\n if (error) done(error)\n })\n })\n await started\n if (child.connected) child.disconnect()\n child.unref()\n const status = await getWorkerStatus()\n console.log(`Background worker ${status.state} (PID ${status.pid ?? child.pid}). Logs: ${getWorkerLogPath()}`)\n } catch (error) {\n // This is the child we just spawned, not a PID recovered from disk.\n child.kill('SIGTERM')\n throw error\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { n as getWorkerStatus } from "./background-3oASCl0e.js";
2
+ export { getWorkerStatus };
@@ -1,5 +1,5 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
- import { n as createStudioOptions, o as run, t as connect } from "./run-DBMVTeYc.js";
2
+ import { n as createStudioOptions, o as run, t as connect } from "./run-BImV4UtP.js";
3
3
  //#region src/runners/studio/connect.ts
4
4
  const runner = async ({ values }) => {
5
5
  const options = createStudioOptions(values);
@@ -8,4 +8,4 @@ const runner = async ({ values }) => {
8
8
  //#endregion
9
9
  export { runner };
10
10
 
11
- //# sourceMappingURL=connect-BSN9mNt_.js.map
11
+ //# sourceMappingURL=connect-1rQzCnlQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-BSN9mNt_.js","names":[],"sources":["../src/runners/studio/connect.ts"],"sourcesContent":["import type { CommandRunner } from 'gunshi'\nimport type { definition } from '../../commands/studio/connect.ts'\nimport { connect, createStudioOptions, run } from './run.ts'\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options = createStudioOptions(values)\n await run(options, () => connect(options), { block: true })\n}\n"],"mappings":";;;AAIA,MAAa,SAA0E,OAAO,EAAE,aAAa;CAC3G,MAAM,UAAU,oBAAoB,MAAM;CAC1C,MAAM,IAAI,eAAe,QAAQ,OAAO,GAAG,EAAE,OAAO,KAAK,CAAC;AAC5D"}
1
+ {"version":3,"file":"connect-1rQzCnlQ.js","names":[],"sources":["../src/runners/studio/connect.ts"],"sourcesContent":["import type { CommandRunner } from 'gunshi'\nimport type { definition } from '../../commands/studio/connect.ts'\nimport { connect, createStudioOptions, run } from './run.ts'\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options = createStudioOptions(values)\n await run(options, () => connect(options), { block: true })\n}\n"],"mappings":";;;AAIA,MAAa,SAA0E,OAAO,EAAE,aAAa;CAC3G,MAAM,UAAU,oBAAoB,MAAM;CAC1C,MAAM,IAAI,eAAe,QAAQ,OAAO,GAAG,EAAE,OAAO,KAAK,CAAC;AAC5D"}
@@ -1,5 +1,5 @@
1
1
  require("./rolldown-runtime-qbf5tadS.cjs");
2
- const require_run = require("./run-DcxxL66g.cjs");
2
+ const require_run = require("./run-BRHzFp8O.cjs");
3
3
  //#region src/runners/studio/connect.ts
4
4
  const runner = async ({ values }) => {
5
5
  const options = require_run.createStudioOptions(values);
@@ -8,4 +8,4 @@ const runner = async ({ values }) => {
8
8
  //#endregion
9
9
  exports.runner = runner;
10
10
 
11
- //# sourceMappingURL=connect-_W1N8mi7.cjs.map
11
+ //# sourceMappingURL=connect-DErJyH2K.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-_W1N8mi7.cjs","names":["createStudioOptions","run","connect"],"sources":["../src/runners/studio/connect.ts"],"sourcesContent":["import type { CommandRunner } from 'gunshi'\nimport type { definition } from '../../commands/studio/connect.ts'\nimport { connect, createStudioOptions, run } from './run.ts'\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options = createStudioOptions(values)\n await run(options, () => connect(options), { block: true })\n}\n"],"mappings":";;;AAIA,MAAa,SAA0E,OAAO,EAAE,aAAa;CAC3G,MAAM,UAAUA,YAAAA,oBAAoB,MAAM;CAC1C,MAAMC,YAAAA,IAAI,eAAeC,YAAAA,QAAQ,OAAO,GAAG,EAAE,OAAO,KAAK,CAAC;AAC5D"}
1
+ {"version":3,"file":"connect-DErJyH2K.cjs","names":["createStudioOptions","run","connect"],"sources":["../src/runners/studio/connect.ts"],"sourcesContent":["import type { CommandRunner } from 'gunshi'\nimport type { definition } from '../../commands/studio/connect.ts'\nimport { connect, createStudioOptions, run } from './run.ts'\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options = createStudioOptions(values)\n await run(options, () => connect(options), { block: true })\n}\n"],"mappings":";;;AAIA,MAAa,SAA0E,OAAO,EAAE,aAAa;CAC3G,MAAM,UAAUA,YAAAA,oBAAoB,MAAM;CAC1C,MAAMC,YAAAA,IAAI,eAAeC,YAAAA,QAAQ,OAAO,GAAG,EAAE,OAAO,KAAK,CAAC;AAC5D"}
@@ -75,7 +75,7 @@ const command = (0, gunshi.defineWithTypes)()({
75
75
  async run(ctx) {
76
76
  const { values } = ctx;
77
77
  const logLevel = resolveLogLevel(values);
78
- const { run } = await Promise.resolve().then(() => require("./run-C0lN0_dx.cjs"));
78
+ const { run } = await Promise.resolve().then(() => require("./run-D6cbi0ll.cjs"));
79
79
  await run({
80
80
  input: values.input,
81
81
  configPath: values.config,
@@ -89,4 +89,4 @@ const command = (0, gunshi.defineWithTypes)()({
89
89
  //#endregion
90
90
  exports.command = command;
91
91
 
92
- //# sourceMappingURL=generate-Dp0XRNH2.cjs.map
92
+ //# sourceMappingURL=generate-BE1yNlTr.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-Dp0XRNH2.cjs","names":["defineWithTypes","configArg","logLevelArg","dryRunId"],"sources":["../src/commands/generate.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport type { ReporterName } from '@kubb/core'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { configArg, logLevelArg } from './shared.ts'\n\nconst REPORTER_NAMES: Array<ReporterName> = ['cli', 'json', 'file', 'html']\n\n/**\n * Splits and validates the comma-separated `--reporter` value against the known reporter names.\n */\nfunction parseReporters(value: string): Array<ReporterName> {\n const names = value\n .split(',')\n .map((name) => name.trim())\n .filter(Boolean)\n\n for (const name of names) {\n if (!REPORTER_NAMES.includes(name as ReporterName)) {\n throw new Error(`must be one of cli, json, file, html (got \"${name}\")`)\n }\n }\n\n return names as Array<ReporterName>\n}\n\n/**\n * Resolves the effective log level, letting the `--verbose` and `--silent` flags win over `--log-level`.\n */\nfunction resolveLogLevel({ verbose, silent, logLevel }: { verbose: boolean; silent: boolean; logLevel: string }): string {\n if (verbose) return 'verbose'\n if (silent) return 'silent'\n return logLevel\n}\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'generate',\n description:\n 'Generate TypeScript types, API clients, React Query hooks, Zod schemas, and more from an OpenAPI specification. Reads kubb.config.ts by default. Pass an OpenAPI file path as the first argument to override the input without editing the config.',\n examples: [\n 'kubb generate # generate from kubb.config.ts',\n 'kubb generate ./openapi.yaml # generate from this spec instead of the config input',\n 'kubb generate --config kubb.config.ts',\n 'kubb generate --watch # regenerate whenever the spec changes',\n 'kubb generate --dry-run # preview the run without writing files',\n 'kubb generate --reporter html # write an HTML run report',\n 'kubb studio # connect this project to Kubb Studio and generate from the browser',\n 'kubb studio --allow-write # let Studio write the generated files to disk',\n 'kubb studio login # pair this machine with Studio without connecting',\n ].join('\\n'),\n toKebab: true,\n args: {\n input: {\n type: 'positional',\n required: false,\n description: 'Path to the OpenAPI specification, overriding the config',\n },\n ...configArg,\n ...logLevelArg,\n watch: {\n type: 'boolean',\n description: 'Watch mode: watches an input file for changes, or polls an input URL',\n short: 'w',\n default: false,\n },\n verbose: {\n type: 'boolean',\n description: 'Override logLevel to verbose',\n default: false,\n },\n silent: {\n type: 'boolean',\n description: 'Override logLevel to silent',\n short: 's',\n default: false,\n },\n reporter: {\n type: 'custom',\n description: 'Reporters that render the run: cli, json, file, html. Comma-separated. Overrides config.reporters',\n metavar: 'cli|json|file|html',\n parse: parseReporters,\n },\n },\n async run(ctx) {\n const { values } = ctx\n const logLevel = resolveLogLevel(values)\n const { run } = await import('../runners/generate/run.ts')\n\n await run({\n input: values.input,\n configPath: values.config,\n logLevel,\n watch: values.watch,\n reporters: values.reporter,\n dryRun: ctx.extensions[dryRunId].enabled,\n })\n },\n})\n"],"mappings":";;;;;AAMA,MAAM,iBAAsC;CAAC;CAAO;CAAQ;CAAQ;AAAM;;;;AAK1E,SAAS,eAAe,OAAoC;CAC1D,MAAM,QAAQ,MACX,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO;CAEjB,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,eAAe,SAAS,IAAoB,GAC/C,MAAM,IAAI,MAAM,8CAA8C,KAAK,GAAG;CAI1E,OAAO;AACT;;;;AAKA,SAAS,gBAAgB,EAAE,SAAS,QAAQ,YAA6E;CACvH,IAAI,SAAS,OAAO;CACpB,IAAI,QAAQ,OAAO;CACnB,OAAO;AACT;AAEA,MAAa,WAAA,GAAUA,OAAAA,gBAAAA,CAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,OAAO;GACL,MAAM;GACN,UAAU;GACV,aAAa;EACf;EACA,GAAGC,eAAAA;EACH,GAAGC,eAAAA;EACH,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aAAa;GACb,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,UAAU;GACR,MAAM;GACN,aAAa;GACb,SAAS;GACT,OAAO;EACT;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,WAAW,gBAAgB,MAAM;EACvC,MAAM,EAAE,QAAQ,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,oBAAA,CAAA;EAEtB,MAAM,IAAI;GACR,OAAO,OAAO;GACd,YAAY,OAAO;GACnB;GACA,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,QAAQ,IAAI,WAAWC,sBAAAA,SAAS,CAAC;EACnC,CAAC;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"generate-BE1yNlTr.cjs","names":["defineWithTypes","configArg","logLevelArg","dryRunId"],"sources":["../src/commands/generate.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport type { ReporterName } from '@kubb/core'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { configArg, logLevelArg } from './shared.ts'\n\nconst REPORTER_NAMES: Array<ReporterName> = ['cli', 'json', 'file', 'html']\n\n/**\n * Splits and validates the comma-separated `--reporter` value against the known reporter names.\n */\nfunction parseReporters(value: string): Array<ReporterName> {\n const names = value\n .split(',')\n .map((name) => name.trim())\n .filter(Boolean)\n\n for (const name of names) {\n if (!REPORTER_NAMES.includes(name as ReporterName)) {\n throw new Error(`must be one of cli, json, file, html (got \"${name}\")`)\n }\n }\n\n return names as Array<ReporterName>\n}\n\n/**\n * Resolves the effective log level, letting the `--verbose` and `--silent` flags win over `--log-level`.\n */\nfunction resolveLogLevel({ verbose, silent, logLevel }: { verbose: boolean; silent: boolean; logLevel: string }): string {\n if (verbose) return 'verbose'\n if (silent) return 'silent'\n return logLevel\n}\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'generate',\n description:\n 'Generate TypeScript types, API clients, React Query hooks, Zod schemas, and more from an OpenAPI specification. Reads kubb.config.ts by default. Pass an OpenAPI file path as the first argument to override the input without editing the config.',\n examples: [\n 'kubb generate # generate from kubb.config.ts',\n 'kubb generate ./openapi.yaml # generate from this spec instead of the config input',\n 'kubb generate --config kubb.config.ts',\n 'kubb generate --watch # regenerate whenever the spec changes',\n 'kubb generate --dry-run # preview the run without writing files',\n 'kubb generate --reporter html # write an HTML run report',\n 'kubb studio # connect this project to Kubb Studio and generate from the browser',\n 'kubb studio --allow-write # let Studio write the generated files to disk',\n 'kubb studio login # pair this machine with Studio without connecting',\n ].join('\\n'),\n toKebab: true,\n args: {\n input: {\n type: 'positional',\n required: false,\n description: 'Path to the OpenAPI specification, overriding the config',\n },\n ...configArg,\n ...logLevelArg,\n watch: {\n type: 'boolean',\n description: 'Watch mode: watches an input file for changes, or polls an input URL',\n short: 'w',\n default: false,\n },\n verbose: {\n type: 'boolean',\n description: 'Override logLevel to verbose',\n default: false,\n },\n silent: {\n type: 'boolean',\n description: 'Override logLevel to silent',\n short: 's',\n default: false,\n },\n reporter: {\n type: 'custom',\n description: 'Reporters that render the run: cli, json, file, html. Comma-separated. Overrides config.reporters',\n metavar: 'cli|json|file|html',\n parse: parseReporters,\n },\n },\n async run(ctx) {\n const { values } = ctx\n const logLevel = resolveLogLevel(values)\n const { run } = await import('../runners/generate/run.ts')\n\n await run({\n input: values.input,\n configPath: values.config,\n logLevel,\n watch: values.watch,\n reporters: values.reporter,\n dryRun: ctx.extensions[dryRunId].enabled,\n })\n },\n})\n"],"mappings":";;;;;AAMA,MAAM,iBAAsC;CAAC;CAAO;CAAQ;CAAQ;AAAM;;;;AAK1E,SAAS,eAAe,OAAoC;CAC1D,MAAM,QAAQ,MACX,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO;CAEjB,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,eAAe,SAAS,IAAoB,GAC/C,MAAM,IAAI,MAAM,8CAA8C,KAAK,GAAG;CAI1E,OAAO;AACT;;;;AAKA,SAAS,gBAAgB,EAAE,SAAS,QAAQ,YAA6E;CACvH,IAAI,SAAS,OAAO;CACpB,IAAI,QAAQ,OAAO;CACnB,OAAO;AACT;AAEA,MAAa,WAAA,GAAUA,OAAAA,gBAAAA,CAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,OAAO;GACL,MAAM;GACN,UAAU;GACV,aAAa;EACf;EACA,GAAGC,eAAAA;EACH,GAAGC,eAAAA;EACH,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aAAa;GACb,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,UAAU;GACR,MAAM;GACN,aAAa;GACb,SAAS;GACT,OAAO;EACT;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,WAAW,gBAAgB,MAAM;EACvC,MAAM,EAAE,QAAQ,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,oBAAA,CAAA;EAEtB,MAAM,IAAI;GACR,OAAO,OAAO;GACd,YAAY,OAAO;GACnB;GACA,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,QAAQ,IAAI,WAAWC,sBAAAA,SAAS,CAAC;EACnC,CAAC;CACH;AACF,CAAC"}
@@ -75,7 +75,7 @@ const command = defineWithTypes()({
75
75
  async run(ctx) {
76
76
  const { values } = ctx;
77
77
  const logLevel = resolveLogLevel(values);
78
- const { run } = await import("./run-C1NcWnFi.js");
78
+ const { run } = await import("./run-CnIUf-DQ.js");
79
79
  await run({
80
80
  input: values.input,
81
81
  configPath: values.config,
@@ -89,4 +89,4 @@ const command = defineWithTypes()({
89
89
  //#endregion
90
90
  export { command };
91
91
 
92
- //# sourceMappingURL=generate-Y4iSiFAh.js.map
92
+ //# sourceMappingURL=generate-BaqPeI7c.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-Y4iSiFAh.js","names":[],"sources":["../src/commands/generate.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport type { ReporterName } from '@kubb/core'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { configArg, logLevelArg } from './shared.ts'\n\nconst REPORTER_NAMES: Array<ReporterName> = ['cli', 'json', 'file', 'html']\n\n/**\n * Splits and validates the comma-separated `--reporter` value against the known reporter names.\n */\nfunction parseReporters(value: string): Array<ReporterName> {\n const names = value\n .split(',')\n .map((name) => name.trim())\n .filter(Boolean)\n\n for (const name of names) {\n if (!REPORTER_NAMES.includes(name as ReporterName)) {\n throw new Error(`must be one of cli, json, file, html (got \"${name}\")`)\n }\n }\n\n return names as Array<ReporterName>\n}\n\n/**\n * Resolves the effective log level, letting the `--verbose` and `--silent` flags win over `--log-level`.\n */\nfunction resolveLogLevel({ verbose, silent, logLevel }: { verbose: boolean; silent: boolean; logLevel: string }): string {\n if (verbose) return 'verbose'\n if (silent) return 'silent'\n return logLevel\n}\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'generate',\n description:\n 'Generate TypeScript types, API clients, React Query hooks, Zod schemas, and more from an OpenAPI specification. Reads kubb.config.ts by default. Pass an OpenAPI file path as the first argument to override the input without editing the config.',\n examples: [\n 'kubb generate # generate from kubb.config.ts',\n 'kubb generate ./openapi.yaml # generate from this spec instead of the config input',\n 'kubb generate --config kubb.config.ts',\n 'kubb generate --watch # regenerate whenever the spec changes',\n 'kubb generate --dry-run # preview the run without writing files',\n 'kubb generate --reporter html # write an HTML run report',\n 'kubb studio # connect this project to Kubb Studio and generate from the browser',\n 'kubb studio --allow-write # let Studio write the generated files to disk',\n 'kubb studio login # pair this machine with Studio without connecting',\n ].join('\\n'),\n toKebab: true,\n args: {\n input: {\n type: 'positional',\n required: false,\n description: 'Path to the OpenAPI specification, overriding the config',\n },\n ...configArg,\n ...logLevelArg,\n watch: {\n type: 'boolean',\n description: 'Watch mode: watches an input file for changes, or polls an input URL',\n short: 'w',\n default: false,\n },\n verbose: {\n type: 'boolean',\n description: 'Override logLevel to verbose',\n default: false,\n },\n silent: {\n type: 'boolean',\n description: 'Override logLevel to silent',\n short: 's',\n default: false,\n },\n reporter: {\n type: 'custom',\n description: 'Reporters that render the run: cli, json, file, html. Comma-separated. Overrides config.reporters',\n metavar: 'cli|json|file|html',\n parse: parseReporters,\n },\n },\n async run(ctx) {\n const { values } = ctx\n const logLevel = resolveLogLevel(values)\n const { run } = await import('../runners/generate/run.ts')\n\n await run({\n input: values.input,\n configPath: values.config,\n logLevel,\n watch: values.watch,\n reporters: values.reporter,\n dryRun: ctx.extensions[dryRunId].enabled,\n })\n },\n})\n"],"mappings":";;;;;AAMA,MAAM,iBAAsC;CAAC;CAAO;CAAQ;CAAQ;AAAM;;;;AAK1E,SAAS,eAAe,OAAoC;CAC1D,MAAM,QAAQ,MACX,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO;CAEjB,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,eAAe,SAAS,IAAoB,GAC/C,MAAM,IAAI,MAAM,8CAA8C,KAAK,GAAG;CAI1E,OAAO;AACT;;;;AAKA,SAAS,gBAAgB,EAAE,SAAS,QAAQ,YAA6E;CACvH,IAAI,SAAS,OAAO;CACpB,IAAI,QAAQ,OAAO;CACnB,OAAO;AACT;AAEA,MAAa,UAAU,gBAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,OAAO;GACL,MAAM;GACN,UAAU;GACV,aAAa;EACf;EACA,GAAG;EACH,GAAG;EACH,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aAAa;GACb,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,UAAU;GACR,MAAM;GACN,aAAa;GACb,SAAS;GACT,OAAO;EACT;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,WAAW,gBAAgB,MAAM;EACvC,MAAM,EAAE,QAAQ,MAAM,OAAO;EAE7B,MAAM,IAAI;GACR,OAAO,OAAO;GACd,YAAY,OAAO;GACnB;GACA,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,QAAQ,IAAI,WAAW,SAAS,CAAC;EACnC,CAAC;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"generate-BaqPeI7c.js","names":[],"sources":["../src/commands/generate.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport type { ReporterName } from '@kubb/core'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { configArg, logLevelArg } from './shared.ts'\n\nconst REPORTER_NAMES: Array<ReporterName> = ['cli', 'json', 'file', 'html']\n\n/**\n * Splits and validates the comma-separated `--reporter` value against the known reporter names.\n */\nfunction parseReporters(value: string): Array<ReporterName> {\n const names = value\n .split(',')\n .map((name) => name.trim())\n .filter(Boolean)\n\n for (const name of names) {\n if (!REPORTER_NAMES.includes(name as ReporterName)) {\n throw new Error(`must be one of cli, json, file, html (got \"${name}\")`)\n }\n }\n\n return names as Array<ReporterName>\n}\n\n/**\n * Resolves the effective log level, letting the `--verbose` and `--silent` flags win over `--log-level`.\n */\nfunction resolveLogLevel({ verbose, silent, logLevel }: { verbose: boolean; silent: boolean; logLevel: string }): string {\n if (verbose) return 'verbose'\n if (silent) return 'silent'\n return logLevel\n}\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'generate',\n description:\n 'Generate TypeScript types, API clients, React Query hooks, Zod schemas, and more from an OpenAPI specification. Reads kubb.config.ts by default. Pass an OpenAPI file path as the first argument to override the input without editing the config.',\n examples: [\n 'kubb generate # generate from kubb.config.ts',\n 'kubb generate ./openapi.yaml # generate from this spec instead of the config input',\n 'kubb generate --config kubb.config.ts',\n 'kubb generate --watch # regenerate whenever the spec changes',\n 'kubb generate --dry-run # preview the run without writing files',\n 'kubb generate --reporter html # write an HTML run report',\n 'kubb studio # connect this project to Kubb Studio and generate from the browser',\n 'kubb studio --allow-write # let Studio write the generated files to disk',\n 'kubb studio login # pair this machine with Studio without connecting',\n ].join('\\n'),\n toKebab: true,\n args: {\n input: {\n type: 'positional',\n required: false,\n description: 'Path to the OpenAPI specification, overriding the config',\n },\n ...configArg,\n ...logLevelArg,\n watch: {\n type: 'boolean',\n description: 'Watch mode: watches an input file for changes, or polls an input URL',\n short: 'w',\n default: false,\n },\n verbose: {\n type: 'boolean',\n description: 'Override logLevel to verbose',\n default: false,\n },\n silent: {\n type: 'boolean',\n description: 'Override logLevel to silent',\n short: 's',\n default: false,\n },\n reporter: {\n type: 'custom',\n description: 'Reporters that render the run: cli, json, file, html. Comma-separated. Overrides config.reporters',\n metavar: 'cli|json|file|html',\n parse: parseReporters,\n },\n },\n async run(ctx) {\n const { values } = ctx\n const logLevel = resolveLogLevel(values)\n const { run } = await import('../runners/generate/run.ts')\n\n await run({\n input: values.input,\n configPath: values.config,\n logLevel,\n watch: values.watch,\n reporters: values.reporter,\n dryRun: ctx.extensions[dryRunId].enabled,\n })\n },\n})\n"],"mappings":";;;;;AAMA,MAAM,iBAAsC;CAAC;CAAO;CAAQ;CAAQ;AAAM;;;;AAK1E,SAAS,eAAe,OAAoC;CAC1D,MAAM,QAAQ,MACX,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO;CAEjB,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,eAAe,SAAS,IAAoB,GAC/C,MAAM,IAAI,MAAM,8CAA8C,KAAK,GAAG;CAI1E,OAAO;AACT;;;;AAKA,SAAS,gBAAgB,EAAE,SAAS,QAAQ,YAA6E;CACvH,IAAI,SAAS,OAAO;CACpB,IAAI,QAAQ,OAAO;CACnB,OAAO;AACT;AAEA,MAAa,UAAU,gBAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,OAAO;GACL,MAAM;GACN,UAAU;GACV,aAAa;EACf;EACA,GAAG;EACH,GAAG;EACH,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aAAa;GACb,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,UAAU;GACR,MAAM;GACN,aAAa;GACb,SAAS;GACT,OAAO;EACT;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,WAAW,gBAAgB,MAAM;EACvC,MAAM,EAAE,QAAQ,MAAM,OAAO;EAE7B,MAAM,IAAI;GACR,OAAO,OAAO;GACd,YAAY,OAAO;GACnB;GACA,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,QAAQ,IAAI,WAAW,SAAS,CAAC;EACnC,CAAC;CACH;AACF,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
3
- const require_Telemetry = require("./Telemetry-B3kc9gFh.cjs");
4
- const require_package = require("./package-DTQG_XnR.cjs");
3
+ const require_Telemetry = require("./Telemetry-BGfj0cEE.cjs");
4
+ const require_package = require("./package-GWkUXXHp.cjs");
5
5
  let node_util = require("node:util");
6
6
  let _gunshi_plugin_dryrun = require("@gunshi/plugin-dryrun");
7
7
  _gunshi_plugin_dryrun = require_rolldown_runtime.__toESM(_gunshi_plugin_dryrun, 1);
@@ -55,14 +55,14 @@ async function run(argv = process.argv) {
55
55
  const args = resolveDeprecatedFlags(stripExecArgs(argv));
56
56
  const isQuietFlag = args.some((arg) => require_Telemetry.QUIET_FLAGS.has(arg));
57
57
  if (!require_Telemetry.isDisabled() && !isQuietFlag) console.log(`${(0, node_util.styleText)("yellow", "Notice:")} Kubb collects anonymous telemetry data to help improve the tool. No personal data or file contents are collected. \nTo disable, set ${(0, node_util.styleText)("cyan", "KUBB_DISABLE_TELEMETRY=1")}.\n`);
58
- const { command: generateCommand } = await Promise.resolve().then(() => require("./generate-Dp0XRNH2.cjs"));
59
- const { command: initCommand } = await Promise.resolve().then(() => require("./init-DbgeeViU.cjs"));
58
+ const { command: generateCommand } = await Promise.resolve().then(() => require("./generate-BE1yNlTr.cjs"));
59
+ const { command: initCommand } = await Promise.resolve().then(() => require("./init-BgWwngao.cjs"));
60
60
  const { definition: validateDefinition } = await Promise.resolve().then(() => require("./validate-BcB0tFQ6.cjs"));
61
- const validateCommand = (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./run-B4Za6HxI.cjs"))).runner, validateDefinition);
61
+ const validateCommand = (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./run-B9TJ_EJB.cjs"))).runner, validateDefinition);
62
62
  const { definition: mcpDefinition } = await Promise.resolve().then(() => require("./mcp-B3B-rE7W.cjs"));
63
- const mcpCommand = (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./run-C3hTDMfs.cjs"))).runner, mcpDefinition);
64
- const { definition: studioDefinition } = await Promise.resolve().then(() => require("./studio-D7hfq4EP.cjs"));
65
- const studioCommand = (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./connect-_W1N8mi7.cjs"))).runner, studioDefinition);
63
+ const mcpCommand = (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./run-muVMUDQr.cjs"))).runner, mcpDefinition);
64
+ const { definition: studioDefinition } = await Promise.resolve().then(() => require("./studio-qkXrFCKL.cjs"));
65
+ const studioCommand = (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./connect-DErJyH2K.cjs"))).runner, studioDefinition);
66
66
  await (0, gunshi.cli)(args, generateCommand, {
67
67
  name: "kubb",
68
68
  version: require_package.version,
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
- import { a as QUIET_FLAGS, n as isDisabled } from "./Telemetry-cHHOzBW8.js";
3
- import { t as version } from "./package-CWi7augV.js";
2
+ import { a as QUIET_FLAGS, n as isDisabled } from "./Telemetry-BgVmgqiW.js";
3
+ import { t as version } from "./package-Cp691yUF.js";
4
4
  import { styleText } from "node:util";
5
5
  import dryrun from "@gunshi/plugin-dryrun";
6
6
  import { cli, lazy } from "gunshi";
@@ -53,14 +53,14 @@ async function run(argv = process.argv) {
53
53
  const args = resolveDeprecatedFlags(stripExecArgs(argv));
54
54
  const isQuietFlag = args.some((arg) => QUIET_FLAGS.has(arg));
55
55
  if (!isDisabled() && !isQuietFlag) console.log(`${styleText("yellow", "Notice:")} Kubb collects anonymous telemetry data to help improve the tool. No personal data or file contents are collected. \nTo disable, set ${styleText("cyan", "KUBB_DISABLE_TELEMETRY=1")}.\n`);
56
- const { command: generateCommand } = await import("./generate-Y4iSiFAh.js");
57
- const { command: initCommand } = await import("./init-aIf8EBRW.js");
56
+ const { command: generateCommand } = await import("./generate-BaqPeI7c.js");
57
+ const { command: initCommand } = await import("./init-Lbr8poOd.js");
58
58
  const { definition: validateDefinition } = await import("./validate-QpkCbIFJ.js");
59
- const validateCommand = lazy(async () => (await import("./run-Cb78U4HC.js")).runner, validateDefinition);
59
+ const validateCommand = lazy(async () => (await import("./run-DeyU879M.js")).runner, validateDefinition);
60
60
  const { definition: mcpDefinition } = await import("./mcp-B-GxGgVr.js");
61
- const mcpCommand = lazy(async () => (await import("./run-D9nqSLXW.js")).runner, mcpDefinition);
62
- const { definition: studioDefinition } = await import("./studio-D4FYZGwK.js");
63
- const studioCommand = lazy(async () => (await import("./connect-BSN9mNt_.js")).runner, studioDefinition);
61
+ const mcpCommand = lazy(async () => (await import("./run-p60wFxuP.js")).runner, mcpDefinition);
62
+ const { definition: studioDefinition } = await import("./studio-4iG51KbH.js");
63
+ const studioCommand = lazy(async () => (await import("./connect-1rQzCnlQ.js")).runner, studioDefinition);
64
64
  await cli(args, generateCommand, {
65
65
  name: "kubb",
66
66
  version,
@@ -1,5 +1,5 @@
1
1
  require("./rolldown-runtime-qbf5tadS.cjs");
2
- const require_package = require("./package-DTQG_XnR.cjs");
2
+ const require_package = require("./package-GWkUXXHp.cjs");
3
3
  let gunshi = require("gunshi");
4
4
  let _gunshi_plugin_dryrun = require("@gunshi/plugin-dryrun");
5
5
  //#region src/commands/init.ts
@@ -55,4 +55,4 @@ const command = (0, gunshi.defineWithTypes)()({
55
55
  //#endregion
56
56
  exports.command = command;
57
57
 
58
- //# sourceMappingURL=init-DbgeeViU.cjs.map
58
+ //# sourceMappingURL=init-BgWwngao.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"init-DbgeeViU.cjs","names":["defineWithTypes","dryRunId"],"sources":["../src/commands/init.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { version } from '../../package.json'\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'init',\n description:\n 'Scaffold a kubb.config.ts and install plugins for code generation from an OpenAPI spec. Run without flags for interactive setup, or pass --input, --output, and --plugins to skip the prompts.',\n examples: [\n 'kubb init',\n 'kubb init --yes',\n 'kubb init --input ./openapi.yaml --output ./src/gen --plugins plugin-ts,plugin-zod',\n 'kubb init --plugins plugin-ts,plugin-axios,plugin-react-query',\n 'kubb init --yes --dry-run',\n ].join('\\n'),\n toKebab: true,\n args: {\n yes: {\n type: 'boolean',\n description: 'Skip prompts and use default options',\n short: 'y',\n default: false,\n },\n input: {\n type: 'string',\n description: 'Path to the OpenAPI specification',\n short: 'i',\n metavar: 'path',\n },\n output: {\n type: 'string',\n description: 'Output directory for generated files',\n short: 'o',\n metavar: 'path',\n },\n plugins: {\n type: 'string',\n description:\n 'Comma-separated list of plugins to use (plugin-ts, plugin-axios, plugin-fetch, plugin-react-query, plugin-vue-query, plugin-zod, plugin-faker, plugin-msw, plugin-cypress, plugin-mcp, plugin-redoc)',\n metavar: 'plugin-ts,plugin-zod,...',\n },\n },\n async run(ctx) {\n const { values } = ctx\n const { run } = await import('../runners/init/run.ts')\n\n await run({\n yes: values.yes,\n version,\n input: values.input,\n output: values.output,\n plugins: values.plugins,\n dryRun: ctx.extensions[dryRunId],\n })\n },\n})\n"],"mappings":";;;;;AAKA,MAAa,WAAA,GAAUA,OAAAA,gBAAAA,CAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,KAAK;GACH,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aACE;GACF,SAAS;EACX;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,EAAE,QAAQ,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,oBAAA,CAAA;EAEtB,MAAM,IAAI;GACR,KAAK,OAAO;GACZ,SAAA,gBAAA;GACA,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,QAAQ,IAAI,WAAWC,sBAAAA;EACzB,CAAC;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"init-BgWwngao.cjs","names":["defineWithTypes","dryRunId"],"sources":["../src/commands/init.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { version } from '../../package.json'\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'init',\n description:\n 'Scaffold a kubb.config.ts and install plugins for code generation from an OpenAPI spec. Run without flags for interactive setup, or pass --input, --output, and --plugins to skip the prompts.',\n examples: [\n 'kubb init',\n 'kubb init --yes',\n 'kubb init --input ./openapi.yaml --output ./src/gen --plugins plugin-ts,plugin-zod',\n 'kubb init --plugins plugin-ts,plugin-axios,plugin-react-query',\n 'kubb init --yes --dry-run',\n ].join('\\n'),\n toKebab: true,\n args: {\n yes: {\n type: 'boolean',\n description: 'Skip prompts and use default options',\n short: 'y',\n default: false,\n },\n input: {\n type: 'string',\n description: 'Path to the OpenAPI specification',\n short: 'i',\n metavar: 'path',\n },\n output: {\n type: 'string',\n description: 'Output directory for generated files',\n short: 'o',\n metavar: 'path',\n },\n plugins: {\n type: 'string',\n description:\n 'Comma-separated list of plugins to use (plugin-ts, plugin-axios, plugin-fetch, plugin-react-query, plugin-vue-query, plugin-zod, plugin-faker, plugin-msw, plugin-cypress, plugin-mcp, plugin-redoc)',\n metavar: 'plugin-ts,plugin-zod,...',\n },\n },\n async run(ctx) {\n const { values } = ctx\n const { run } = await import('../runners/init/run.ts')\n\n await run({\n yes: values.yes,\n version,\n input: values.input,\n output: values.output,\n plugins: values.plugins,\n dryRun: ctx.extensions[dryRunId],\n })\n },\n})\n"],"mappings":";;;;;AAKA,MAAa,WAAA,GAAUA,OAAAA,gBAAAA,CAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,KAAK;GACH,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aACE;GACF,SAAS;EACX;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,EAAE,QAAQ,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,oBAAA,CAAA;EAEtB,MAAM,IAAI;GACR,KAAK,OAAO;GACZ,SAAA,gBAAA;GACA,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,QAAQ,IAAI,WAAWC,sBAAAA;EACzB,CAAC;CACH;AACF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
- import { t as version } from "./package-CWi7augV.js";
2
+ import { t as version } from "./package-Cp691yUF.js";
3
3
  import { t as dryRunId } from "./gunshiDryRun-DdKJuVn1.js";
4
4
  import { defineWithTypes } from "gunshi";
5
5
  //#region src/commands/init.ts
@@ -55,4 +55,4 @@ const command = defineWithTypes()({
55
55
  //#endregion
56
56
  export { command };
57
57
 
58
- //# sourceMappingURL=init-aIf8EBRW.js.map
58
+ //# sourceMappingURL=init-Lbr8poOd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init-aIf8EBRW.js","names":[],"sources":["../src/commands/init.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { version } from '../../package.json'\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'init',\n description:\n 'Scaffold a kubb.config.ts and install plugins for code generation from an OpenAPI spec. Run without flags for interactive setup, or pass --input, --output, and --plugins to skip the prompts.',\n examples: [\n 'kubb init',\n 'kubb init --yes',\n 'kubb init --input ./openapi.yaml --output ./src/gen --plugins plugin-ts,plugin-zod',\n 'kubb init --plugins plugin-ts,plugin-axios,plugin-react-query',\n 'kubb init --yes --dry-run',\n ].join('\\n'),\n toKebab: true,\n args: {\n yes: {\n type: 'boolean',\n description: 'Skip prompts and use default options',\n short: 'y',\n default: false,\n },\n input: {\n type: 'string',\n description: 'Path to the OpenAPI specification',\n short: 'i',\n metavar: 'path',\n },\n output: {\n type: 'string',\n description: 'Output directory for generated files',\n short: 'o',\n metavar: 'path',\n },\n plugins: {\n type: 'string',\n description:\n 'Comma-separated list of plugins to use (plugin-ts, plugin-axios, plugin-fetch, plugin-react-query, plugin-vue-query, plugin-zod, plugin-faker, plugin-msw, plugin-cypress, plugin-mcp, plugin-redoc)',\n metavar: 'plugin-ts,plugin-zod,...',\n },\n },\n async run(ctx) {\n const { values } = ctx\n const { run } = await import('../runners/init/run.ts')\n\n await run({\n yes: values.yes,\n version,\n input: values.input,\n output: values.output,\n plugins: values.plugins,\n dryRun: ctx.extensions[dryRunId],\n })\n },\n})\n"],"mappings":";;;;;AAKA,MAAa,UAAU,gBAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,KAAK;GACH,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aACE;GACF,SAAS;EACX;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,EAAE,QAAQ,MAAM,OAAO;EAE7B,MAAM,IAAI;GACR,KAAK,OAAO;GACZ;GACA,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,QAAQ,IAAI,WAAW;EACzB,CAAC;CACH;AACF,CAAC"}
1
+ {"version":3,"file":"init-Lbr8poOd.js","names":[],"sources":["../src/commands/init.ts"],"sourcesContent":["import { defineWithTypes } from 'gunshi'\nimport { dryRunId } from '../gunshiDryRun.ts'\nimport type { DryRunExtensions } from '../gunshiDryRun.ts'\nimport { version } from '../../package.json'\n\nexport const command = defineWithTypes<{ extensions: DryRunExtensions }>()({\n name: 'init',\n description:\n 'Scaffold a kubb.config.ts and install plugins for code generation from an OpenAPI spec. Run without flags for interactive setup, or pass --input, --output, and --plugins to skip the prompts.',\n examples: [\n 'kubb init',\n 'kubb init --yes',\n 'kubb init --input ./openapi.yaml --output ./src/gen --plugins plugin-ts,plugin-zod',\n 'kubb init --plugins plugin-ts,plugin-axios,plugin-react-query',\n 'kubb init --yes --dry-run',\n ].join('\\n'),\n toKebab: true,\n args: {\n yes: {\n type: 'boolean',\n description: 'Skip prompts and use default options',\n short: 'y',\n default: false,\n },\n input: {\n type: 'string',\n description: 'Path to the OpenAPI specification',\n short: 'i',\n metavar: 'path',\n },\n output: {\n type: 'string',\n description: 'Output directory for generated files',\n short: 'o',\n metavar: 'path',\n },\n plugins: {\n type: 'string',\n description:\n 'Comma-separated list of plugins to use (plugin-ts, plugin-axios, plugin-fetch, plugin-react-query, plugin-vue-query, plugin-zod, plugin-faker, plugin-msw, plugin-cypress, plugin-mcp, plugin-redoc)',\n metavar: 'plugin-ts,plugin-zod,...',\n },\n },\n async run(ctx) {\n const { values } = ctx\n const { run } = await import('../runners/init/run.ts')\n\n await run({\n yes: values.yes,\n version,\n input: values.input,\n output: values.output,\n plugins: values.plugins,\n dryRun: ctx.extensions[dryRunId],\n })\n },\n})\n"],"mappings":";;;;;AAKA,MAAa,UAAU,gBAAkD,CAAC,CAAC;CACzE,MAAM;CACN,aACE;CACF,UAAU;EACR;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CACX,SAAS;CACT,MAAM;EACJ,KAAK;GACH,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aACE;GACF,SAAS;EACX;CACF;CACA,MAAM,IAAI,KAAK;EACb,MAAM,EAAE,WAAW;EACnB,MAAM,EAAE,QAAQ,MAAM,OAAO;EAE7B,MAAM,IAAI;GACR,KAAK,OAAO;GACZ;GACA,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,QAAQ,IAAI,WAAW;EACzB,CAAC;CACH;AACF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  require("./rolldown-runtime-qbf5tadS.cjs");
2
- const require_run = require("./run-DcxxL66g.cjs");
2
+ const require_run = require("./run-BRHzFp8O.cjs");
3
3
  //#region src/runners/studio/login.ts
4
4
  const runner = async ({ values }) => {
5
5
  const options = require_run.createStudioOptions(values);
@@ -8,4 +8,4 @@ const runner = async ({ values }) => {
8
8
  //#endregion
9
9
  exports.runner = runner;
10
10
 
11
- //# sourceMappingURL=login-CA_mjtz4.cjs.map
11
+ //# sourceMappingURL=login-B5SJfc2r.cjs.map