@kubb/cli 5.0.0-beta.36 → 5.0.0-beta.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -11
- package/dist/{agent-DajReUxm.cjs → agent-Bl8JwjMa.cjs} +4 -4
- package/dist/{agent-DajReUxm.cjs.map → agent-Bl8JwjMa.cjs.map} +1 -1
- package/dist/{agent-cAalLgeU.js → agent-CfZ_Uqde.js} +4 -4
- package/dist/{agent-cAalLgeU.js.map → agent-CfZ_Uqde.js.map} +1 -1
- package/dist/{constants-FhPsMOdo.cjs → constants-CAKUpLcQ.cjs} +3 -12
- package/dist/{constants-FhPsMOdo.cjs.map → constants-CAKUpLcQ.cjs.map} +1 -1
- package/dist/{constants-Co6NWt3U.js → constants-CYxk4aNm.js} +4 -7
- package/dist/{constants-Co6NWt3U.js.map → constants-CYxk4aNm.js.map} +1 -1
- package/dist/{generate-C6oskVzT.cjs → generate-Bgds6Zx3.cjs} +19 -14
- package/dist/generate-Bgds6Zx3.cjs.map +1 -0
- package/dist/{generate-DmYQJcBv.js → generate-CfxFqNeb.js} +19 -14
- package/dist/generate-CfxFqNeb.js.map +1 -0
- package/dist/index.cjs +8 -8
- package/dist/index.js +8 -8
- package/dist/{init-Dbb4U-Xs.cjs → init-C5wnuzeK.cjs} +2 -2
- package/dist/{init-Dbb4U-Xs.cjs.map → init-C5wnuzeK.cjs.map} +1 -1
- package/dist/{init-iOg_X-uh.js → init-TIec3Dym.js} +2 -2
- package/dist/{init-iOg_X-uh.js.map → init-TIec3Dym.js.map} +1 -1
- package/dist/{mcp-DxrSTT8i.cjs → mcp-Cr753GW1.cjs} +3 -3
- package/dist/{mcp-DxrSTT8i.cjs.map → mcp-Cr753GW1.cjs.map} +1 -1
- package/dist/{mcp-Ci2OkdBj.js → mcp-Damue5Mq.js} +3 -3
- package/dist/{mcp-Ci2OkdBj.js.map → mcp-Damue5Mq.js.map} +1 -1
- package/dist/package-Cnt1K03J.js +6 -0
- package/dist/package-Cnt1K03J.js.map +1 -0
- package/dist/{package-DbsOo2rT.cjs → package-guApEHiW.cjs} +2 -2
- package/dist/package-guApEHiW.cjs.map +1 -0
- package/dist/{run-v-75bcU1.js → run-BFEK9md9.js} +2 -2
- package/dist/{run-v-75bcU1.js.map → run-BFEK9md9.js.map} +1 -1
- package/dist/{run-GvXhj9XF.cjs → run-BFZtWpcW.cjs} +491 -314
- package/dist/run-BFZtWpcW.cjs.map +1 -0
- package/dist/{run-CCgNPz0F.cjs → run-BFv6avA_.cjs} +3 -3
- package/dist/{run-CCgNPz0F.cjs.map → run-BFv6avA_.cjs.map} +1 -1
- package/dist/{run-DpDKN_rb.cjs → run-BQZyg7If.cjs} +2 -2
- package/dist/{run-DpDKN_rb.cjs.map → run-BQZyg7If.cjs.map} +1 -1
- package/dist/{run-CPimpDgO.js → run-BvXxelGR.js} +2 -2
- package/dist/{run-CPimpDgO.js.map → run-BvXxelGR.js.map} +1 -1
- package/dist/{run-Lnupy7qb.cjs → run-Bz9IFMWg.cjs} +2 -2
- package/dist/{run-Lnupy7qb.cjs.map → run-Bz9IFMWg.cjs.map} +1 -1
- package/dist/{run-B9ZkldVt.js → run-C752fag9.js} +557 -380
- package/dist/run-C752fag9.js.map +1 -0
- package/dist/run-C_NMctua.cjs.map +1 -1
- package/dist/run-D8dCWepS.js.map +1 -1
- package/dist/{run-BRrNHp24.js → run-DJxYClJV.js} +3 -3
- package/dist/{run-BRrNHp24.js.map → run-DJxYClJV.js.map} +1 -1
- package/dist/{telemetry-DRhd3joO.cjs → telemetry-B80oJfxR.cjs} +2 -2
- package/dist/telemetry-B80oJfxR.cjs.map +1 -0
- package/dist/{telemetry-ne1IOrz1.js → telemetry-ueaMzs_c.js} +2 -2
- package/dist/telemetry-ueaMzs_c.js.map +1 -0
- package/dist/{validate-Bh7MgISX.js → validate-CYTKdezO.js} +3 -3
- package/dist/{validate-Bh7MgISX.js.map → validate-CYTKdezO.js.map} +1 -1
- package/dist/{validate-DVkJx4q8.cjs → validate-DMzjP-hd.cjs} +3 -3
- package/dist/{validate-DVkJx4q8.cjs.map → validate-DMzjP-hd.cjs.map} +1 -1
- package/package.json +6 -6
- package/src/commands/generate.ts +16 -10
- package/src/constants.ts +1 -1
- package/src/loggers/clackLogger.ts +68 -71
- package/src/loggers/diagnostics.ts +77 -0
- package/src/loggers/githubActionsLogger.ts +38 -31
- package/src/loggers/plainLogger.ts +10 -26
- package/src/loggers/types.ts +1 -1
- package/src/loggers/utils.ts +47 -94
- package/src/reporters/cliReporter.ts +89 -0
- package/src/reporters/fileReporter.ts +103 -0
- package/src/reporters/jsonReporter.ts +20 -0
- package/src/reporters/report.ts +84 -0
- package/src/runners/agent/run.ts +2 -2
- package/src/runners/generate/run.ts +130 -44
- package/src/runners/generate/utils.ts +8 -11
- package/src/runners/init/run.ts +1 -1
- package/src/telemetry.ts +2 -2
- package/dist/generate-C6oskVzT.cjs.map +0 -1
- package/dist/generate-DmYQJcBv.js.map +0 -1
- package/dist/package-DbsOo2rT.cjs.map +0 -1
- package/dist/package-_R15a7lY.js +0 -6
- package/dist/package-_R15a7lY.js.map +0 -1
- package/dist/run-B9ZkldVt.js.map +0 -1
- package/dist/run-GvXhj9XF.cjs.map +0 -1
- package/dist/telemetry-DRhd3joO.cjs.map +0 -1
- package/dist/telemetry-ne1IOrz1.js.map +0 -1
- package/src/loggers/fileSystemLogger.ts +0 -151
|
@@ -5,10 +5,24 @@ import { styleText } from 'node:util'
|
|
|
5
5
|
import * as clack from '@clack/prompts'
|
|
6
6
|
import type { AsyncEventEmitter } from '@internals/utils'
|
|
7
7
|
import { AsyncEventEmitter as AsyncEventEmitterClass, detectFormatter, detectLinter, executeIfOnline, formatters, linters, toError } from '@internals/utils'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type CLIOptions,
|
|
10
|
+
type Config,
|
|
11
|
+
createKubb,
|
|
12
|
+
type Diagnostic,
|
|
13
|
+
diagnosticCode,
|
|
14
|
+
Diagnostics,
|
|
15
|
+
isInputPath,
|
|
16
|
+
isProblemDiagnostic,
|
|
17
|
+
type KubbHooks,
|
|
18
|
+
logLevel as logLevelMap,
|
|
19
|
+
narrowDiagnostic,
|
|
20
|
+
type ProblemDiagnostic,
|
|
21
|
+
type ReporterName,
|
|
22
|
+
} from '@kubb/core'
|
|
9
23
|
import { version } from '../../../package.json'
|
|
10
24
|
import { KUBB_NPM_PACKAGE_URL } from '../../constants.ts'
|
|
11
|
-
import {
|
|
25
|
+
import { setupReporters, type HookSinkFactory } from '../../loggers/utils.ts'
|
|
12
26
|
import { buildTelemetryEvent, sendTelemetry } from '../../telemetry.ts'
|
|
13
27
|
import { executeHooks, getConfigs, runHook, startWatcher } from './utils.ts'
|
|
14
28
|
|
|
@@ -118,16 +132,16 @@ async function runToolPass({
|
|
|
118
132
|
command: toolConfig.command,
|
|
119
133
|
args: hookArgs,
|
|
120
134
|
commandWithArgs,
|
|
121
|
-
|
|
135
|
+
hooks,
|
|
122
136
|
stream,
|
|
123
137
|
sink: { onLine, onStdout, onStderr },
|
|
124
138
|
}).catch(() => {})
|
|
125
139
|
|
|
126
140
|
await hookEndPromise
|
|
127
141
|
} catch (caughtError) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
toolError =
|
|
142
|
+
// Don't render here. The caller turns this into a coded diagnostic and emits it through
|
|
143
|
+
// `Diagnostics.emit`, so format/lint/hook failures render like every other diagnostic.
|
|
144
|
+
toolError = toError(caughtError)
|
|
131
145
|
}
|
|
132
146
|
}
|
|
133
147
|
|
|
@@ -159,7 +173,7 @@ async function generate(options: GenerateProps): Promise<boolean> {
|
|
|
159
173
|
|
|
160
174
|
await hooks.emit('kubb:info', { message: config.name ? `Build generation ${styleText('bold', config.name)}` : 'Build generation', info: inputPath })
|
|
161
175
|
|
|
162
|
-
const { files,
|
|
176
|
+
const { files, diagnostics, driver } = await kubb.safeBuild()
|
|
163
177
|
|
|
164
178
|
await hooks.emit('kubb:info', { message: 'Load summary' })
|
|
165
179
|
|
|
@@ -168,34 +182,38 @@ async function generate(options: GenerateProps): Promise<boolean> {
|
|
|
168
182
|
const reportTelemetry = (status: 'success' | 'failed') =>
|
|
169
183
|
sendTelemetry(buildTelemetryEvent({ command: 'generate', kubbVersion: version, plugins: telemetryPlugins, hrStart, filesCreated: files.length, status }))
|
|
170
184
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
185
|
+
// Render every problem, not just on failure, so warnings and info surface too.
|
|
186
|
+
// `performance` diagnostics feed the summary, not the log.
|
|
187
|
+
for (const diagnostic of diagnostics) {
|
|
188
|
+
if (!isProblemDiagnostic(diagnostic)) {
|
|
189
|
+
continue
|
|
190
|
+
}
|
|
191
|
+
const unknown = narrowDiagnostic(diagnostic, diagnosticCode.unknown)
|
|
192
|
+
if (unknown) {
|
|
193
|
+
await hooks.emit('kubb:error', { error: unknown.cause ?? new Error(unknown.message) })
|
|
194
|
+
} else {
|
|
195
|
+
await Diagnostics.emit(hooks, diagnostic)
|
|
176
196
|
}
|
|
197
|
+
}
|
|
177
198
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
failedPlugins,
|
|
182
|
-
filesCreated: files.length,
|
|
183
|
-
status: 'failed',
|
|
184
|
-
hrStart,
|
|
185
|
-
pluginTimings: logLevel >= logLevelMap.verbose ? pluginTimings : undefined,
|
|
186
|
-
})
|
|
199
|
+
// Only an error-severity diagnostic fails the run. Warnings and info do not.
|
|
200
|
+
if (Diagnostics.hasError(diagnostics)) {
|
|
201
|
+
await hooks.emit('kubb:generation:end', { config, storage: kubb.storage, diagnostics, filesCreated: files.length, status: 'failed', hrStart })
|
|
187
202
|
|
|
188
203
|
await reportTelemetry('failed')
|
|
189
204
|
return false
|
|
190
205
|
}
|
|
191
206
|
|
|
192
|
-
await hooks.emit('kubb:success', { message: 'Generation succeeded', info: inputPath })
|
|
193
|
-
await hooks.emit('kubb:generation:end', { config, storage: kubb.storage })
|
|
194
|
-
|
|
195
207
|
const outputPath = path.resolve(config.root, config.output.path)
|
|
196
208
|
|
|
209
|
+
// The build succeeded. The formatter, linter, and post-generate hooks run after it. Their
|
|
210
|
+
// failures used to only emit `kubb:error`, so they never reached the summary, the json report,
|
|
211
|
+
// or the exit code. Collect them as coded diagnostics here.
|
|
212
|
+
const outputDiagnostics: Array<Diagnostic> = []
|
|
213
|
+
|
|
197
214
|
const toolPasses = [
|
|
198
215
|
config.output.format && {
|
|
216
|
+
code: diagnosticCode.formatFailed,
|
|
199
217
|
toolValue: config.output.format,
|
|
200
218
|
detect: detectFormatter,
|
|
201
219
|
toolMap: formatters,
|
|
@@ -206,6 +224,7 @@ async function generate(options: GenerateProps): Promise<boolean> {
|
|
|
206
224
|
onEnd: () => hooks.emit('kubb:format:end'),
|
|
207
225
|
},
|
|
208
226
|
config.output.lint && {
|
|
227
|
+
code: diagnosticCode.lintFailed,
|
|
209
228
|
toolValue: config.output.lint,
|
|
210
229
|
detect: detectLinter,
|
|
211
230
|
toolMap: linters,
|
|
@@ -215,22 +234,73 @@ async function generate(options: GenerateProps): Promise<boolean> {
|
|
|
215
234
|
onStart: () => hooks.emit('kubb:lint:start'),
|
|
216
235
|
onEnd: () => hooks.emit('kubb:lint:end'),
|
|
217
236
|
},
|
|
218
|
-
].filter(Boolean) as Array<Omit<RunToolPassOptions, 'configName' | 'outputPath' | 'logLevel' | 'hooks'>>
|
|
237
|
+
].filter(Boolean) as Array<{ code: ProblemDiagnostic['code'] } & Omit<RunToolPassOptions, 'configName' | 'outputPath' | 'logLevel' | 'hooks'>>
|
|
219
238
|
|
|
220
|
-
for (const pass of toolPasses) {
|
|
221
|
-
|
|
239
|
+
for (const { code, ...pass } of toolPasses) {
|
|
240
|
+
try {
|
|
241
|
+
await runToolPass({ ...pass, configName: config.name, outputPath, logLevel, hooks, makeSink })
|
|
242
|
+
} catch (caughtError) {
|
|
243
|
+
const diagnostic = outputDiagnostic(code, pass.toolLabel, caughtError)
|
|
244
|
+
outputDiagnostics.push(diagnostic)
|
|
245
|
+
await Diagnostics.emit(hooks, diagnostic)
|
|
246
|
+
}
|
|
222
247
|
}
|
|
223
248
|
|
|
224
249
|
if (config.hooks) {
|
|
225
250
|
await hooks.emit('kubb:hooks:start')
|
|
226
|
-
|
|
251
|
+
// `runHook` reports a failed `done` hook via `kubb:hook:end` rather than throwing, so listen
|
|
252
|
+
// for it across this pass and collect each failure.
|
|
253
|
+
const hookFailures: Array<Error> = []
|
|
254
|
+
const onHookEnd = (ctx: { success: boolean; error: Error | null }) => {
|
|
255
|
+
if (!ctx.success) hookFailures.push(ctx.error ?? new Error('Post-generate hook failed'))
|
|
256
|
+
}
|
|
257
|
+
hooks.on('kubb:hook:end', onHookEnd)
|
|
258
|
+
try {
|
|
259
|
+
await executeHooks({ configHooks: config.hooks, hooks, makeSink })
|
|
260
|
+
} finally {
|
|
261
|
+
hooks.off('kubb:hook:end', onHookEnd)
|
|
262
|
+
}
|
|
263
|
+
for (const error of hookFailures) {
|
|
264
|
+
const diagnostic = outputDiagnostic(diagnosticCode.hookFailed, 'Post-generate hook', error)
|
|
265
|
+
outputDiagnostics.push(diagnostic)
|
|
266
|
+
await Diagnostics.emit(hooks, diagnostic)
|
|
267
|
+
}
|
|
227
268
|
await hooks.emit('kubb:hooks:end')
|
|
228
269
|
}
|
|
229
270
|
|
|
230
|
-
|
|
271
|
+
const finalDiagnostics = [...diagnostics, ...outputDiagnostics]
|
|
272
|
+
const failed = Diagnostics.hasError(outputDiagnostics)
|
|
273
|
+
|
|
274
|
+
if (!failed) {
|
|
275
|
+
await hooks.emit('kubb:success', { message: 'Generation succeeded', info: inputPath })
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
await hooks.emit('kubb:generation:end', {
|
|
279
|
+
config,
|
|
280
|
+
storage: kubb.storage,
|
|
281
|
+
diagnostics: finalDiagnostics,
|
|
282
|
+
filesCreated: files.length,
|
|
283
|
+
status: failed ? 'failed' : 'success',
|
|
284
|
+
hrStart,
|
|
285
|
+
})
|
|
231
286
|
|
|
232
|
-
await reportTelemetry('success')
|
|
233
|
-
return
|
|
287
|
+
await reportTelemetry(failed ? 'failed' : 'success')
|
|
288
|
+
return !failed
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Builds a coded diagnostic for an output-phase failure (formatter, linter, or `done` hook).
|
|
293
|
+
*/
|
|
294
|
+
function outputDiagnostic(code: ProblemDiagnostic['code'], label: string, caughtError: unknown): ProblemDiagnostic {
|
|
295
|
+
const error = toError(caughtError)
|
|
296
|
+
return {
|
|
297
|
+
code,
|
|
298
|
+
severity: 'error',
|
|
299
|
+
message: `${label} failed: ${error.message}`,
|
|
300
|
+
help: 'Check that the tool is installed and that the command and its config are correct.',
|
|
301
|
+
location: { kind: 'config' },
|
|
302
|
+
cause: error,
|
|
303
|
+
}
|
|
234
304
|
}
|
|
235
305
|
|
|
236
306
|
type GenerateCommandOptions = {
|
|
@@ -238,6 +308,7 @@ type GenerateCommandOptions = {
|
|
|
238
308
|
configPath?: string
|
|
239
309
|
logLevel: string
|
|
240
310
|
watch: boolean
|
|
311
|
+
reporters?: Array<ReporterName>
|
|
241
312
|
}
|
|
242
313
|
|
|
243
314
|
async function checkForUpdate(hooks: AsyncEventEmitter<KubbHooks>): Promise<void> {
|
|
@@ -246,7 +317,7 @@ async function checkForUpdate(hooks: AsyncEventEmitter<KubbHooks>): Promise<void
|
|
|
246
317
|
const res = await fetch(KUBB_NPM_PACKAGE_URL)
|
|
247
318
|
const data = (await res.json()) as { version: string }
|
|
248
319
|
if (data.version && version < data.version) {
|
|
249
|
-
await
|
|
320
|
+
await Diagnostics.emit(hooks, Diagnostics.update({ currentVersion: version, latestVersion: data.version }))
|
|
250
321
|
}
|
|
251
322
|
} catch {
|
|
252
323
|
// Ignore network errors
|
|
@@ -256,29 +327,44 @@ async function checkForUpdate(hooks: AsyncEventEmitter<KubbHooks>): Promise<void
|
|
|
256
327
|
|
|
257
328
|
/**
|
|
258
329
|
* Runs the full Kubb generation lifecycle for the given CLI options.
|
|
259
|
-
*
|
|
330
|
+
* Loads configs, sets up the selected reporters (CLI `--reporter` overrides `config.reporters`),
|
|
331
|
+
* checks for a newer version, and calls `generate` for each config entry.
|
|
260
332
|
*/
|
|
261
|
-
export async function run({ input, configPath, logLevel: logLevelKey, watch }: GenerateCommandOptions): Promise<void> {
|
|
333
|
+
export async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters }: GenerateCommandOptions): Promise<void> {
|
|
262
334
|
const logLevel = logLevelMap[logLevelKey as keyof typeof logLevelMap] ?? logLevelMap.info
|
|
263
335
|
const hooks = new AsyncEventEmitterClass<KubbHooks>()
|
|
264
336
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
await checkForUpdate(hooks)
|
|
270
|
-
|
|
337
|
+
// Load the config first so `config.reporters` can pick the reporters. A failure here has no
|
|
338
|
+
// reporter installed yet, so fall back to the default `cli` reporter to surface it.
|
|
339
|
+
let configs: Array<Config>
|
|
340
|
+
let resolvedConfigPath: string
|
|
271
341
|
try {
|
|
272
|
-
await
|
|
273
|
-
|
|
274
|
-
const { configs, configPath: resolvedConfigPath } = await getConfigs({
|
|
342
|
+
const loaded = await getConfigs({
|
|
275
343
|
configPath,
|
|
276
344
|
input,
|
|
277
345
|
watch,
|
|
278
346
|
logLevel: logLevelKey as CLIOptions['logLevel'],
|
|
279
347
|
})
|
|
348
|
+
configs = loaded.configs
|
|
349
|
+
resolvedConfigPath = loaded.configPath
|
|
350
|
+
} catch (error) {
|
|
351
|
+
await setupReporters(hooks, { logLevel, reporters: ['cli'] })
|
|
352
|
+
await hooks.emit('kubb:error', { error: toError(error) })
|
|
353
|
+
process.exit(1)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// CLI `--reporter` wins. Otherwise the first config's `reporters`. Otherwise the default.
|
|
357
|
+
const reporters: Array<ReporterName> = cliReporters?.length ? cliReporters : (configs[0]?.reporters ?? ['cli'])
|
|
358
|
+
const makeSink = await setupReporters(hooks, { logLevel, reporters })
|
|
359
|
+
|
|
360
|
+
await hooks.emit('kubb:lifecycle:start', { version })
|
|
361
|
+
|
|
362
|
+
await checkForUpdate(hooks)
|
|
363
|
+
|
|
364
|
+
try {
|
|
280
365
|
const relativeConfigPath = path.relative(process.cwd(), resolvedConfigPath)
|
|
281
366
|
|
|
367
|
+
await hooks.emit('kubb:config:start')
|
|
282
368
|
await hooks.emit('kubb:info', { message: 'Config loaded', info: relativeConfigPath })
|
|
283
369
|
await hooks.emit('kubb:success', { message: 'Config loaded successfully', info: relativeConfigPath })
|
|
284
370
|
await hooks.emit('kubb:config:end', { configs })
|
|
@@ -289,7 +375,7 @@ export async function run({ input, configPath, logLevel: logLevelKey, watch }: G
|
|
|
289
375
|
await startWatcher(
|
|
290
376
|
[input || config.input.path],
|
|
291
377
|
async (paths) => {
|
|
292
|
-
// Don't removeAll()
|
|
378
|
+
// Don't removeAll(), that would also drop logger and lifecycle listeners.
|
|
293
379
|
// Plugin and middleware listeners are already disposed by safeBuild's
|
|
294
380
|
// setupResult.dispose() in its finally block, so re-running generate()
|
|
295
381
|
// on the same hooks emitter is safe.
|
|
@@ -135,7 +135,7 @@ export async function executeHooks({ configHooks, hooks, makeSink }: ExecuteHook
|
|
|
135
135
|
await hooks.emit('kubb:hook:start', { id: hookId, command: cmd, args })
|
|
136
136
|
|
|
137
137
|
const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs, hookId) ?? {}
|
|
138
|
-
await runHook({ id: hookId, command: cmd, args, commandWithArgs,
|
|
138
|
+
await runHook({ id: hookId, command: cmd, args, commandWithArgs, hooks, stream, sink: { onLine, onStdout, onStderr } })
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -144,13 +144,13 @@ type RunHookOptions = {
|
|
|
144
144
|
command: string
|
|
145
145
|
args?: ReadonlyArray<string>
|
|
146
146
|
commandWithArgs: string
|
|
147
|
-
|
|
147
|
+
hooks: AsyncEventEmitter<KubbHooks>
|
|
148
148
|
stream?: boolean
|
|
149
149
|
sink?: HookSinkOptions
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
export async function runHook({ id, command, args, commandWithArgs,
|
|
153
|
-
const emitEnd = (success: boolean, error: Error | null) =>
|
|
152
|
+
export async function runHook({ id, command, args, commandWithArgs, hooks, stream = false, sink }: RunHookOptions): Promise<void> {
|
|
153
|
+
const emitEnd = (success: boolean, error: Error | null) => hooks.emit('kubb:hook:end', { command, args, id, success, error })
|
|
154
154
|
|
|
155
155
|
try {
|
|
156
156
|
const proc = x(command, [...(args ?? [])], {
|
|
@@ -164,29 +164,26 @@ export async function runHook({ id, command, args, commandWithArgs, context, str
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
await
|
|
169
|
-
await context.emit('kubb:success', { message: `${styleText('dim', commandWithArgs)} successfully executed` })
|
|
167
|
+
await proc
|
|
168
|
+
await hooks.emit('kubb:success', { message: `${styleText('dim', commandWithArgs)} successfully executed` })
|
|
170
169
|
await emitEnd(true, null)
|
|
171
170
|
} catch (err) {
|
|
172
171
|
if (!(err instanceof NonZeroExitError)) {
|
|
173
172
|
const error = toError(err)
|
|
174
173
|
await emitEnd(false, error)
|
|
175
|
-
await context.emit('kubb:error', { error })
|
|
176
174
|
return
|
|
177
175
|
}
|
|
178
176
|
|
|
179
177
|
const stderr = err.output?.stderr ?? ''
|
|
180
178
|
const stdout = err.output?.stdout ?? ''
|
|
181
179
|
|
|
182
|
-
await context.emit('kubb:debug', { date: new Date(), logs: [stdout, stderr].filter(Boolean) })
|
|
183
|
-
|
|
184
180
|
if (stderr) sink?.onStderr?.(stderr)
|
|
185
181
|
if (stdout) sink?.onStdout?.(stdout)
|
|
186
182
|
|
|
187
183
|
const error = new Error(`Hook execute failed: ${commandWithArgs}`)
|
|
184
|
+
// Signal the failure via `kubb:hook:end` only. The caller turns it into a coded diagnostic and
|
|
185
|
+
// emits that through `Diagnostics.emit`, so emitting `kubb:error` here would render it twice.
|
|
188
186
|
await emitEnd(false, error)
|
|
189
|
-
await context.emit('kubb:error', { error })
|
|
190
187
|
}
|
|
191
188
|
}
|
|
192
189
|
|
package/src/runners/init/run.ts
CHANGED
|
@@ -64,7 +64,7 @@ export async function run({ yes, version, input: inputFlag, output: outputFlag,
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
try {
|
|
67
|
-
// Check/create package.json
|
|
67
|
+
// Check/create package.json, detect package manager once after the block
|
|
68
68
|
if (!hasPackageJson(cwd)) {
|
|
69
69
|
if (!yes) {
|
|
70
70
|
const shouldInit = await clack.confirm({
|
package/src/telemetry.ts
CHANGED
|
@@ -105,7 +105,7 @@ export type TelemetryPlugin = {
|
|
|
105
105
|
*/
|
|
106
106
|
name: string
|
|
107
107
|
/**
|
|
108
|
-
* anonymized plugin options snapshot
|
|
108
|
+
* anonymized plugin options snapshot, values are included but cannot be traced back to the user.
|
|
109
109
|
*/
|
|
110
110
|
options: Record<string, unknown>
|
|
111
111
|
}
|
|
@@ -246,7 +246,7 @@ export async function sendTelemetry(event: TelemetryEvent): Promise<void> {
|
|
|
246
246
|
signal: AbortSignal.timeout(5_000),
|
|
247
247
|
})
|
|
248
248
|
} catch (_e) {
|
|
249
|
-
// Fail silently
|
|
249
|
+
// Fail silently, telemetry must never break the CLI
|
|
250
250
|
}
|
|
251
251
|
})
|
|
252
252
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-C6oskVzT.cjs","names":["defineCommand"],"sources":["../src/commands/generate.ts"],"sourcesContent":["import { defineCommand } from '@internals/utils'\n\nexport const command = defineCommand({\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 arguments: ['[input]'],\n examples: ['kubb generate', 'kubb generate ./openapi.yaml', 'kubb generate --config kubb.config.ts', 'kubb generate --watch'],\n options: {\n config: {\n type: 'string',\n description: 'Path to the Kubb config',\n short: 'c',\n },\n logLevel: {\n type: 'string',\n description: 'Info, silent, verbose or debug',\n short: 'l',\n default: 'info',\n hint: 'silent|info|verbose|debug',\n enum: ['silent', 'info', 'verbose', 'debug'],\n },\n watch: {\n type: 'boolean',\n description: 'Watch mode based on the input file',\n short: 'w',\n default: false,\n },\n debug: {\n type: 'boolean',\n description: 'Override logLevel to debug',\n short: 'd',\n default: false,\n },\n verbose: {\n type: 'boolean',\n description: 'Override logLevel to verbose',\n short: 'v',\n default: false,\n },\n silent: {\n type: 'boolean',\n description: 'Override logLevel to silent',\n short: 's',\n default: false,\n },\n },\n async run({ values, positionals }) {\n const logLevel = values.debug ? 'debug' : values.verbose ? 'verbose' : values.silent ? 'silent' : values.logLevel\n const { run } = await import('../runners/generate/run.ts')\n\n await run({\n input: positionals[0],\n configPath: values.config,\n logLevel,\n watch: values.watch,\n })\n },\n})\n"],"mappings":";;AAEA,MAAa,yCAAUA,EAAAA,cAAc;CACnC,MAAM;CACN,aACE;CACF,WAAW,CAAC,SAAS;CACrB,UAAU;EAAC;EAAiB;EAAgC;EAAyC;CAAuB;CAC5H,SAAS;EACP,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;EACT;EACA,UAAU;GACR,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;GACT,MAAM;GACN,MAAM;IAAC;IAAU;IAAQ;IAAW;GAAO;EAC7C;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;CACF;CACA,MAAM,IAAI,EAAE,QAAQ,eAAe;EACjC,MAAM,WAAW,OAAO,QAAQ,UAAU,OAAO,UAAU,YAAY,OAAO,SAAS,WAAW,OAAO;EACzG,MAAM,EAAE,QAAQ,MAAA,QAAA,QAAA,EAAA,WAAA,QAAM,oBAAA,CAAA;EAEtB,MAAM,IAAI;GACR,OAAO,YAAY;GACnB,YAAY,OAAO;GACnB;GACA,OAAO,OAAO;EAChB,CAAC;CACH;AACF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-DmYQJcBv.js","names":[],"sources":["../src/commands/generate.ts"],"sourcesContent":["import { defineCommand } from '@internals/utils'\n\nexport const command = defineCommand({\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 arguments: ['[input]'],\n examples: ['kubb generate', 'kubb generate ./openapi.yaml', 'kubb generate --config kubb.config.ts', 'kubb generate --watch'],\n options: {\n config: {\n type: 'string',\n description: 'Path to the Kubb config',\n short: 'c',\n },\n logLevel: {\n type: 'string',\n description: 'Info, silent, verbose or debug',\n short: 'l',\n default: 'info',\n hint: 'silent|info|verbose|debug',\n enum: ['silent', 'info', 'verbose', 'debug'],\n },\n watch: {\n type: 'boolean',\n description: 'Watch mode based on the input file',\n short: 'w',\n default: false,\n },\n debug: {\n type: 'boolean',\n description: 'Override logLevel to debug',\n short: 'd',\n default: false,\n },\n verbose: {\n type: 'boolean',\n description: 'Override logLevel to verbose',\n short: 'v',\n default: false,\n },\n silent: {\n type: 'boolean',\n description: 'Override logLevel to silent',\n short: 's',\n default: false,\n },\n },\n async run({ values, positionals }) {\n const logLevel = values.debug ? 'debug' : values.verbose ? 'verbose' : values.silent ? 'silent' : values.logLevel\n const { run } = await import('../runners/generate/run.ts')\n\n await run({\n input: positionals[0],\n configPath: values.config,\n logLevel,\n watch: values.watch,\n })\n },\n})\n"],"mappings":";;;AAEA,MAAa,UAAU,cAAc;CACnC,MAAM;CACN,aACE;CACF,WAAW,CAAC,SAAS;CACrB,UAAU;EAAC;EAAiB;EAAgC;EAAyC;CAAuB;CAC5H,SAAS;EACP,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;EACT;EACA,UAAU;GACR,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;GACT,MAAM;GACN,MAAM;IAAC;IAAU;IAAQ;IAAW;GAAO;EAC7C;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,OAAO;GACL,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,SAAS;GACP,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;EACA,QAAQ;GACN,MAAM;GACN,aAAa;GACb,OAAO;GACP,SAAS;EACX;CACF;CACA,MAAM,IAAI,EAAE,QAAQ,eAAe;EACjC,MAAM,WAAW,OAAO,QAAQ,UAAU,OAAO,UAAU,YAAY,OAAO,SAAS,WAAW,OAAO;EACzG,MAAM,EAAE,QAAQ,MAAM,OAAO;EAE7B,MAAM,IAAI;GACR,OAAO,YAAY;GACnB,YAAY,OAAO;GACnB;GACA,OAAO,OAAO;EAChB,CAAC;CACH;AACF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package-DbsOo2rT.cjs","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
|
package/dist/package-_R15a7lY.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package-_R15a7lY.js","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
|