@kubb/cli 5.0.0-alpha.9 → 5.0.0-beta.10
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 +180 -27
- package/bin/kubb.js +6 -0
- package/dist/agent-Bx2yllmS.js +68 -0
- package/dist/agent-Bx2yllmS.js.map +1 -0
- package/dist/agent-CeLwj5im.cjs +70 -0
- package/dist/agent-CeLwj5im.cjs.map +1 -0
- package/dist/{chunk--u3MIqq1.js → chunk-BvFE5Tac.js} +1 -0
- package/dist/constants-B2JTeRBb.js +42 -0
- package/dist/constants-B2JTeRBb.js.map +1 -0
- package/dist/constants-BINTA5VZ.cjs +77 -0
- package/dist/constants-BINTA5VZ.cjs.map +1 -0
- package/dist/constants-BYGmiFs0.cjs +139 -0
- package/dist/constants-BYGmiFs0.cjs.map +1 -0
- package/dist/constants-DSJ-Xrbv.js +116 -0
- package/dist/constants-DSJ-Xrbv.js.map +1 -0
- package/dist/define-Bdn8j5VM.cjs +54 -0
- package/dist/define-Bdn8j5VM.cjs.map +1 -0
- package/dist/define-m_fp-Aqm.js +43 -0
- package/dist/define-m_fp-Aqm.js.map +1 -0
- package/dist/errors-CINO1EIv.js +43 -0
- package/dist/errors-CINO1EIv.js.map +1 -0
- package/dist/{errors-DBW0N9w4.cjs → errors-CLCjoSg0.cjs} +22 -6
- package/dist/errors-CLCjoSg0.cjs.map +1 -0
- package/dist/{generate-Rly1EXBN.js → generate-BLvcvoIj.js} +12 -6
- package/dist/generate-BLvcvoIj.js.map +1 -0
- package/dist/{generate-DU5zzc54.cjs → generate-drLxTAnz.cjs} +11 -5
- package/dist/generate-drLxTAnz.cjs.map +1 -0
- package/dist/index.cjs +52 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +53 -22
- package/dist/index.js.map +1 -1
- package/dist/init-CGu7JZEF.js +53 -0
- package/dist/init-CGu7JZEF.js.map +1 -0
- package/dist/init-CyCjvIEF.cjs +53 -0
- package/dist/init-CyCjvIEF.cjs.map +1 -0
- package/dist/mcp-Cq2sylQC.js +39 -0
- package/dist/mcp-Cq2sylQC.js.map +1 -0
- package/dist/mcp-DSF5gpI-.cjs +39 -0
- package/dist/mcp-DSF5gpI-.cjs.map +1 -0
- package/dist/{package-BJ6ionm6.cjs → package-DZ-6zAIO.cjs} +2 -2
- package/dist/package-DZ-6zAIO.cjs.map +1 -0
- package/dist/package-OLYIpjqw.js +6 -0
- package/dist/package-OLYIpjqw.js.map +1 -0
- package/dist/{generate-BHNyeQXl.js → run-Bfbr3RaM.js} +781 -502
- package/dist/run-Bfbr3RaM.js.map +1 -0
- package/dist/run-BzpYYOQs.js +121 -0
- package/dist/run-BzpYYOQs.js.map +1 -0
- package/dist/run-CCZ24VKk.js +51 -0
- package/dist/run-CCZ24VKk.js.map +1 -0
- package/dist/run-CF97BWVa.js +244 -0
- package/dist/run-CF97BWVa.js.map +1 -0
- package/dist/run-CQbj3ley.cjs +52 -0
- package/dist/run-CQbj3ley.cjs.map +1 -0
- package/dist/{generate-Cq5RDTBL.cjs → run-CVlrIZoW.cjs} +786 -507
- package/dist/run-CVlrIZoW.cjs.map +1 -0
- package/dist/run-D0hmRpHy.js +49 -0
- package/dist/run-D0hmRpHy.js.map +1 -0
- package/dist/run-DwdAwnLG.cjs +125 -0
- package/dist/run-DwdAwnLG.cjs.map +1 -0
- package/dist/run-Lr0Ctnu0.cjs +50 -0
- package/dist/run-Lr0Ctnu0.cjs.map +1 -0
- package/dist/run-YsoCk5we.cjs +248 -0
- package/dist/run-YsoCk5we.cjs.map +1 -0
- package/dist/{shell-7HPrTCJ5.cjs → shell-475fQKaX.cjs} +8 -3
- package/dist/shell-475fQKaX.cjs.map +1 -0
- package/dist/{shell-DqqWsHCD.js → shell-CN6DNqeC.js} +9 -4
- package/dist/shell-CN6DNqeC.js.map +1 -0
- package/dist/{telemetry-DZ7IrLAU.cjs → telemetry-B2iWkY5e.cjs} +53 -13
- package/dist/telemetry-B2iWkY5e.cjs.map +1 -0
- package/dist/{telemetry-BF3SMlH6.js → telemetry-BkektVz6.js} +52 -12
- package/dist/telemetry-BkektVz6.js.map +1 -0
- package/dist/validate-CAUqLaGt.js +26 -0
- package/dist/validate-CAUqLaGt.js.map +1 -0
- package/dist/validate-J6AEd5zK.cjs +26 -0
- package/dist/validate-J6AEd5zK.cjs.map +1 -0
- package/package.json +57 -48
- package/src/commands/agent/start.ts +27 -8
- package/src/commands/agent.ts +3 -1
- package/src/commands/generate.ts +39 -8
- package/src/commands/init.ts +40 -4
- package/src/commands/mcp.ts +28 -4
- package/src/commands/validate.ts +11 -4
- package/src/constants.ts +5 -80
- package/src/index.ts +12 -13
- package/src/loggers/clackLogger.ts +98 -88
- package/src/loggers/fileSystemLogger.ts +37 -25
- package/src/loggers/githubActionsLogger.ts +35 -48
- package/src/loggers/plainLogger.ts +33 -45
- package/src/loggers/types.ts +6 -0
- package/src/loggers/utils.ts +155 -9
- package/src/runners/agent/run.ts +113 -0
- package/src/runners/agent/utils.ts +98 -0
- package/src/runners/generate/run.ts +276 -0
- package/src/runners/generate/utils.ts +209 -0
- package/src/runners/init/run.ts +211 -0
- package/src/{utils/packageManager.ts → runners/init/utils.ts} +10 -0
- package/src/runners/mcp/run.ts +55 -0
- package/src/runners/validate/run.ts +63 -0
- package/src/{utils/telemetry.ts → telemetry.ts} +28 -8
- package/bin/kubb.cjs +0 -18
- package/dist/agent-5mmp7QzF.js +0 -56
- package/dist/agent-5mmp7QzF.js.map +0 -1
- package/dist/agent-BKphjOIF.cjs +0 -58
- package/dist/agent-BKphjOIF.cjs.map +0 -1
- package/dist/agent-BapvKB4r.cjs +0 -92
- package/dist/agent-BapvKB4r.cjs.map +0 -1
- package/dist/agent-CBrpIMMU.js +0 -88
- package/dist/agent-CBrpIMMU.js.map +0 -1
- package/dist/constants-D0XHAHeZ.cjs +0 -178
- package/dist/constants-D0XHAHeZ.cjs.map +0 -1
- package/dist/constants-DJM9zCXm.js +0 -131
- package/dist/constants-DJM9zCXm.js.map +0 -1
- package/dist/define--M_JMcDC.js +0 -25
- package/dist/define--M_JMcDC.js.map +0 -1
- package/dist/define-D6Kfm7-Z.cjs +0 -36
- package/dist/define-D6Kfm7-Z.cjs.map +0 -1
- package/dist/errors-6mF_WKxg.js +0 -27
- package/dist/errors-6mF_WKxg.js.map +0 -1
- package/dist/errors-DBW0N9w4.cjs.map +0 -1
- package/dist/generate-BHNyeQXl.js.map +0 -1
- package/dist/generate-Cq5RDTBL.cjs.map +0 -1
- package/dist/generate-DU5zzc54.cjs.map +0 -1
- package/dist/generate-Rly1EXBN.js.map +0 -1
- package/dist/init-BK6inBTR.cjs +0 -306
- package/dist/init-BK6inBTR.cjs.map +0 -1
- package/dist/init-BQ6zfsnw.js +0 -302
- package/dist/init-BQ6zfsnw.js.map +0 -1
- package/dist/init-CN1JFyGX.cjs +0 -25
- package/dist/init-CN1JFyGX.cjs.map +0 -1
- package/dist/init-iN7e1XwI.js +0 -25
- package/dist/init-iN7e1XwI.js.map +0 -1
- package/dist/jiti-Cd3S0xwr.cjs +0 -16
- package/dist/jiti-Cd3S0xwr.cjs.map +0 -1
- package/dist/jiti-e08mD2Ph.js +0 -11
- package/dist/jiti-e08mD2Ph.js.map +0 -1
- package/dist/mcp-BiGUvbWP.js +0 -41
- package/dist/mcp-BiGUvbWP.js.map +0 -1
- package/dist/mcp-CONmm_xT.cjs +0 -42
- package/dist/mcp-CONmm_xT.cjs.map +0 -1
- package/dist/mcp-T7Q4nWbT.cjs +0 -16
- package/dist/mcp-T7Q4nWbT.cjs.map +0 -1
- package/dist/mcp-eP1S40LZ.js +0 -16
- package/dist/mcp-eP1S40LZ.js.map +0 -1
- package/dist/package-BJ6ionm6.cjs.map +0 -1
- package/dist/package-BKZ0H3Zf.js +0 -6
- package/dist/package-BKZ0H3Zf.js.map +0 -1
- package/dist/shell-7HPrTCJ5.cjs.map +0 -1
- package/dist/shell-DqqWsHCD.js.map +0 -1
- package/dist/telemetry-BF3SMlH6.js.map +0 -1
- package/dist/telemetry-DZ7IrLAU.cjs.map +0 -1
- package/dist/validate-BImbbx1t.js +0 -41
- package/dist/validate-BImbbx1t.js.map +0 -1
- package/dist/validate-DAZdX_0i.js +0 -25
- package/dist/validate-DAZdX_0i.js.map +0 -1
- package/dist/validate-DucFMytl.cjs +0 -25
- package/dist/validate-DucFMytl.cjs.map +0 -1
- package/dist/validate-ujLCYSWU.cjs +0 -42
- package/dist/validate-ujLCYSWU.cjs.map +0 -1
- package/src/runners/agent.ts +0 -102
- package/src/runners/generate.ts +0 -343
- package/src/runners/init.ts +0 -323
- package/src/runners/mcp.ts +0 -32
- package/src/runners/validate.ts +0 -35
- package/src/types.ts +0 -11
- package/src/utils/Writables.ts +0 -17
- package/src/utils/executeHooks.ts +0 -45
- package/src/utils/flags.ts +0 -10
- package/src/utils/getCosmiConfig.ts +0 -71
- package/src/utils/getSummary.ts +0 -68
- package/src/utils/jiti.ts +0 -9
- package/src/utils/runHook.ts +0 -75
- package/src/utils/watcher.ts +0 -19
package/src/runners/agent.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
import * as process from 'node:process'
|
|
4
|
-
import { fileURLToPath } from 'node:url'
|
|
5
|
-
import { styleText } from 'node:util'
|
|
6
|
-
import * as clack from '@clack/prompts'
|
|
7
|
-
import { spawnAsync } from '@internals/utils'
|
|
8
|
-
import { agentDefaults } from '../constants.ts'
|
|
9
|
-
import { buildTelemetryEvent, sendTelemetry } from '../utils/telemetry.ts'
|
|
10
|
-
|
|
11
|
-
type AgentStartOptions = {
|
|
12
|
-
port: string | undefined
|
|
13
|
-
host: string
|
|
14
|
-
configPath: string | undefined
|
|
15
|
-
allowWrite: boolean
|
|
16
|
-
allowAll: boolean
|
|
17
|
-
version: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function isPortAvailable(port: number, host: string): Promise<boolean> {
|
|
21
|
-
return new Promise((resolve) => {
|
|
22
|
-
const server = net.createServer()
|
|
23
|
-
server.once('error', () => resolve(false))
|
|
24
|
-
server.once('listening', () => {
|
|
25
|
-
server.close()
|
|
26
|
-
resolve(true)
|
|
27
|
-
})
|
|
28
|
-
server.listen(port, host)
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export async function runAgentStart({ port, host, configPath, allowWrite, allowAll, version }: AgentStartOptions): Promise<void> {
|
|
33
|
-
const hrStart = process.hrtime()
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
// Load .env file into process.env using Node.js built-in (v20.12.0+)
|
|
37
|
-
try {
|
|
38
|
-
process.loadEnvFile()
|
|
39
|
-
} catch {
|
|
40
|
-
// .env file may not exist; ignore
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Resolve the @kubb/agent package path
|
|
44
|
-
const agentPkgUrl = import.meta.resolve('@kubb/agent/package.json')
|
|
45
|
-
const agentPkgPath = fileURLToPath(agentPkgUrl)
|
|
46
|
-
const agentDir = path.dirname(agentPkgPath)
|
|
47
|
-
const serverPath = path.join(agentDir, agentDefaults.serverEntryPath)
|
|
48
|
-
|
|
49
|
-
// CLI params take priority over process.env; process.env fills in what the CLI didn't specify;
|
|
50
|
-
// agentDefaults are the last resort. Build env as: defaults ← process.env ← CLI.
|
|
51
|
-
const PORT = port !== undefined ? port : (process.env.PORT ?? agentDefaults.port)
|
|
52
|
-
const HOST = host !== agentDefaults.host ? host : (process.env.HOST ?? agentDefaults.host)
|
|
53
|
-
const KUBB_AGENT_ROOT = process.env.KUBB_AGENT_ROOT ?? process.cwd()
|
|
54
|
-
const KUBB_AGENT_CONFIG = path.resolve(process.cwd(), configPath || process.env.KUBB_AGENT_CONFIG || agentDefaults.configFile)
|
|
55
|
-
const KUBB_AGENT_ALLOW_WRITE = allowAll || allowWrite ? 'true' : (process.env.KUBB_AGENT_ALLOW_WRITE ?? 'false')
|
|
56
|
-
const KUBB_AGENT_ALLOW_ALL = allowAll ? 'true' : (process.env.KUBB_AGENT_ALLOW_ALL ?? 'false')
|
|
57
|
-
const KUBB_AGENT_TOKEN = process.env.KUBB_AGENT_TOKEN
|
|
58
|
-
const KUBB_AGENT_RETRY_TIMEOUT = process.env.KUBB_AGENT_RETRY_TIMEOUT ?? agentDefaults.retryTimeout
|
|
59
|
-
const KUBB_STUDIO_URL = process.env.KUBB_STUDIO_URL ?? agentDefaults.studioUrl
|
|
60
|
-
|
|
61
|
-
const env = {
|
|
62
|
-
...process.env,
|
|
63
|
-
PORT,
|
|
64
|
-
HOST,
|
|
65
|
-
KUBB_AGENT_ROOT,
|
|
66
|
-
KUBB_AGENT_CONFIG,
|
|
67
|
-
KUBB_AGENT_ALLOW_WRITE,
|
|
68
|
-
KUBB_AGENT_ALLOW_ALL,
|
|
69
|
-
KUBB_AGENT_TOKEN,
|
|
70
|
-
KUBB_AGENT_RETRY_TIMEOUT,
|
|
71
|
-
KUBB_STUDIO_URL,
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
clack.log.step(styleText('cyan', 'Starting agent server...'))
|
|
75
|
-
clack.log.info(styleText('dim', `Config: ${KUBB_AGENT_CONFIG}`))
|
|
76
|
-
clack.log.info(styleText('dim', `Host: ${HOST}`))
|
|
77
|
-
clack.log.info(styleText('dim', `Port: ${PORT}`))
|
|
78
|
-
if (!KUBB_AGENT_ALLOW_WRITE && !KUBB_AGENT_ALLOW_ALL) {
|
|
79
|
-
clack.log.warn(styleText('yellow', 'Filesystem writes disabled. Use --allow-write or --allow-all to enable.'))
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (!(await isPortAvailable(Number(PORT), HOST))) {
|
|
83
|
-
clack.log.error(styleText('red', `Port ${PORT} is already in use. Stop the existing process or choose a different port with --port.`))
|
|
84
|
-
process.exit(1)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
console.log(env)
|
|
88
|
-
|
|
89
|
-
// Spawns the server as a detached background process so the CLI can exit independently.
|
|
90
|
-
await spawnAsync('node', [serverPath], {
|
|
91
|
-
env,
|
|
92
|
-
cwd: process.cwd(),
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
await sendTelemetry(buildTelemetryEvent({ command: 'agent', kubbVersion: version, hrStart, status: 'success' }))
|
|
96
|
-
} catch (error) {
|
|
97
|
-
await sendTelemetry(buildTelemetryEvent({ command: 'agent', kubbVersion: version, hrStart, status: 'failed' }))
|
|
98
|
-
clack.log.error(styleText('red', 'Failed to start agent server'))
|
|
99
|
-
console.error(error)
|
|
100
|
-
process.exit(1)
|
|
101
|
-
}
|
|
102
|
-
}
|
package/src/runners/generate.ts
DELETED
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
import process from 'node:process'
|
|
4
|
-
import { styleText } from 'node:util'
|
|
5
|
-
import * as clack from '@clack/prompts'
|
|
6
|
-
import type { AsyncEventEmitter } from '@internals/utils'
|
|
7
|
-
import { AsyncEventEmitter as AsyncEventEmitterClass, executeIfOnline, toError } from '@internals/utils'
|
|
8
|
-
import {
|
|
9
|
-
type CLIOptions,
|
|
10
|
-
type Config,
|
|
11
|
-
detectFormatter,
|
|
12
|
-
detectLinter,
|
|
13
|
-
formatters,
|
|
14
|
-
getConfigs,
|
|
15
|
-
isInputPath,
|
|
16
|
-
type KubbEvents,
|
|
17
|
-
linters,
|
|
18
|
-
logLevel as logLevelMap,
|
|
19
|
-
safeBuild,
|
|
20
|
-
setup,
|
|
21
|
-
} from '@kubb/core'
|
|
22
|
-
import { version } from '../../package.json'
|
|
23
|
-
import { KUBB_NPM_PACKAGE_URL } from '../constants.ts'
|
|
24
|
-
import { setupLogger } from '../loggers/utils.ts'
|
|
25
|
-
import { executeHooks } from '../utils/executeHooks.ts'
|
|
26
|
-
import { getCosmiConfig } from '../utils/getCosmiConfig.ts'
|
|
27
|
-
import { buildTelemetryEvent, sendTelemetry } from '../utils/telemetry.ts'
|
|
28
|
-
import { startWatcher } from '../utils/watcher.ts'
|
|
29
|
-
|
|
30
|
-
type GenerateProps = {
|
|
31
|
-
input?: string
|
|
32
|
-
config: Config
|
|
33
|
-
events: AsyncEventEmitter<KubbEvents>
|
|
34
|
-
logLevel: number
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
type ToolMap = typeof formatters | typeof linters
|
|
38
|
-
|
|
39
|
-
type RunToolPassOptions = {
|
|
40
|
-
toolValue: string
|
|
41
|
-
detect: () => Promise<string | undefined>
|
|
42
|
-
toolMap: ToolMap
|
|
43
|
-
/** Short noun used in "Auto-detected <toolLabel>:" message, e.g. "formatter" or "linter". */
|
|
44
|
-
toolLabel: string
|
|
45
|
-
/** Verb prefix for the success message, e.g. "Formatting" or "Linting". */
|
|
46
|
-
successPrefix: string
|
|
47
|
-
noToolMessage: string
|
|
48
|
-
configName: string | undefined
|
|
49
|
-
outputPath: string
|
|
50
|
-
logLevel: number
|
|
51
|
-
events: AsyncEventEmitter<KubbEvents>
|
|
52
|
-
onStart: () => Promise<void>
|
|
53
|
-
onEnd: () => Promise<void>
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async function runToolPass({
|
|
57
|
-
toolValue,
|
|
58
|
-
detect,
|
|
59
|
-
toolMap,
|
|
60
|
-
toolLabel,
|
|
61
|
-
successPrefix,
|
|
62
|
-
noToolMessage,
|
|
63
|
-
configName,
|
|
64
|
-
outputPath,
|
|
65
|
-
logLevel,
|
|
66
|
-
events,
|
|
67
|
-
onStart,
|
|
68
|
-
onEnd,
|
|
69
|
-
}: RunToolPassOptions) {
|
|
70
|
-
await onStart()
|
|
71
|
-
|
|
72
|
-
let resolvedTool = toolValue
|
|
73
|
-
if (resolvedTool === 'auto') {
|
|
74
|
-
const detected = await detect()
|
|
75
|
-
if (!detected) {
|
|
76
|
-
await events.emit('warn', noToolMessage)
|
|
77
|
-
} else {
|
|
78
|
-
resolvedTool = detected
|
|
79
|
-
await events.emit('info', `Auto-detected ${toolLabel}: ${styleText('dim', resolvedTool)}`)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (resolvedTool && resolvedTool !== 'auto' && resolvedTool in toolMap) {
|
|
84
|
-
const toolConfig = toolMap[resolvedTool as keyof ToolMap]
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
const hookId = createHash('sha256').update([configName, resolvedTool].filter(Boolean).join('-')).digest('hex')
|
|
88
|
-
|
|
89
|
-
// Wire up the hook:end listener BEFORE emitting hook:start to avoid the race condition
|
|
90
|
-
// where hook:end fires synchronously inside emit('hook:start') before the listener is registered.
|
|
91
|
-
const hookEndPromise = new Promise<void>((resolve, reject) => {
|
|
92
|
-
const handler = ({ id, success, error }: { id?: string; command: string; args?: readonly string[]; success: boolean; error: Error | null }) => {
|
|
93
|
-
if (id !== hookId) return
|
|
94
|
-
events.off('hook:end', handler)
|
|
95
|
-
if (!success) {
|
|
96
|
-
reject(error ?? new Error(`${toolConfig.errorMessage}`))
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
events
|
|
100
|
-
.emit(
|
|
101
|
-
'success',
|
|
102
|
-
[
|
|
103
|
-
`${successPrefix} with ${styleText('dim', resolvedTool)}`,
|
|
104
|
-
logLevel >= logLevelMap.info ? `on ${styleText('dim', outputPath)}` : undefined,
|
|
105
|
-
'successfully',
|
|
106
|
-
]
|
|
107
|
-
.filter(Boolean)
|
|
108
|
-
.join(' '),
|
|
109
|
-
)
|
|
110
|
-
.then(resolve)
|
|
111
|
-
.catch(reject)
|
|
112
|
-
}
|
|
113
|
-
events.on('hook:end', handler)
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
await events.emit('hook:start', {
|
|
117
|
-
id: hookId,
|
|
118
|
-
command: toolConfig.command,
|
|
119
|
-
args: toolConfig.args(outputPath),
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
await hookEndPromise
|
|
123
|
-
} catch (caughtError) {
|
|
124
|
-
const err = new Error(toolConfig.errorMessage)
|
|
125
|
-
err.cause = caughtError
|
|
126
|
-
await events.emit('error', err)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
await onEnd()
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async function generate({ input, config: userConfig, events, logLevel }: GenerateProps): Promise<void> {
|
|
134
|
-
const inputPath = input ?? ('path' in userConfig.input ? userConfig.input.path : undefined)
|
|
135
|
-
const hrStart = process.hrtime()
|
|
136
|
-
|
|
137
|
-
const config: Config = {
|
|
138
|
-
...userConfig,
|
|
139
|
-
root: userConfig.root || process.cwd(),
|
|
140
|
-
input: inputPath
|
|
141
|
-
? {
|
|
142
|
-
...userConfig.input,
|
|
143
|
-
path: inputPath,
|
|
144
|
-
}
|
|
145
|
-
: userConfig.input,
|
|
146
|
-
output: {
|
|
147
|
-
write: true,
|
|
148
|
-
barrelType: 'named',
|
|
149
|
-
extension: {
|
|
150
|
-
'.ts': '.ts',
|
|
151
|
-
},
|
|
152
|
-
format: 'prettier',
|
|
153
|
-
...userConfig.output,
|
|
154
|
-
},
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
await events.emit('generation:start', config)
|
|
158
|
-
|
|
159
|
-
await events.emit('info', config.name ? `Setup generation ${styleText('bold', config.name)}` : 'Setup generation', inputPath)
|
|
160
|
-
|
|
161
|
-
const { sources, fabric, driver } = await setup({
|
|
162
|
-
config,
|
|
163
|
-
events,
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
await events.emit('info', config.name ? `Build generation ${styleText('bold', config.name)}` : 'Build generation', inputPath)
|
|
167
|
-
|
|
168
|
-
const { files, failedPlugins, pluginTimings, error } = await safeBuild(
|
|
169
|
-
{
|
|
170
|
-
config,
|
|
171
|
-
events,
|
|
172
|
-
},
|
|
173
|
-
{ driver, fabric, events, sources },
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
await events.emit('info', 'Load summary')
|
|
177
|
-
|
|
178
|
-
// Handle build failures (either from failed plugins or general errors)
|
|
179
|
-
|
|
180
|
-
const hasFailures = failedPlugins.size > 0 || error
|
|
181
|
-
if (hasFailures) {
|
|
182
|
-
// Collect all errors from failed plugins and general error
|
|
183
|
-
const allErrors: Error[] = [
|
|
184
|
-
error,
|
|
185
|
-
...Array.from(failedPlugins)
|
|
186
|
-
.filter((it) => it.error)
|
|
187
|
-
.map((it) => it.error),
|
|
188
|
-
].filter(Boolean)
|
|
189
|
-
|
|
190
|
-
for (const err of allErrors) {
|
|
191
|
-
await events.emit('error', err)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
await events.emit('generation:end', config, files, sources)
|
|
195
|
-
|
|
196
|
-
await events.emit('generation:summary', config, {
|
|
197
|
-
failedPlugins,
|
|
198
|
-
filesCreated: files.length,
|
|
199
|
-
status: 'failed',
|
|
200
|
-
hrStart,
|
|
201
|
-
pluginTimings: logLevel >= logLevelMap.verbose ? pluginTimings : undefined,
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
await sendTelemetry(
|
|
205
|
-
buildTelemetryEvent({
|
|
206
|
-
command: 'generate',
|
|
207
|
-
kubbVersion: version,
|
|
208
|
-
plugins: driver.plugins.map((p) => ({ name: p.name, options: p.options as Record<string, unknown> })),
|
|
209
|
-
hrStart,
|
|
210
|
-
filesCreated: files.length,
|
|
211
|
-
status: 'failed',
|
|
212
|
-
}),
|
|
213
|
-
)
|
|
214
|
-
|
|
215
|
-
process.exit(1)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
await events.emit('success', 'Generation successfully', inputPath)
|
|
219
|
-
await events.emit('generation:end', config, files, sources)
|
|
220
|
-
|
|
221
|
-
const outputPath = path.resolve(config.root, config.output.path)
|
|
222
|
-
|
|
223
|
-
if (config.output.format) {
|
|
224
|
-
await runToolPass({
|
|
225
|
-
toolValue: config.output.format,
|
|
226
|
-
detect: detectFormatter,
|
|
227
|
-
toolMap: formatters,
|
|
228
|
-
toolLabel: 'formatter',
|
|
229
|
-
successPrefix: 'Formatting',
|
|
230
|
-
noToolMessage: 'No formatter found (biome, prettier, or oxfmt). Skipping formatting.',
|
|
231
|
-
configName: config.name,
|
|
232
|
-
outputPath,
|
|
233
|
-
logLevel,
|
|
234
|
-
events,
|
|
235
|
-
onStart: () => events.emit('format:start'),
|
|
236
|
-
onEnd: () => events.emit('format:end'),
|
|
237
|
-
})
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (config.output.lint) {
|
|
241
|
-
await runToolPass({
|
|
242
|
-
toolValue: config.output.lint,
|
|
243
|
-
detect: detectLinter,
|
|
244
|
-
toolMap: linters,
|
|
245
|
-
toolLabel: 'linter',
|
|
246
|
-
successPrefix: 'Linting',
|
|
247
|
-
noToolMessage: 'No linter found (biome, oxlint, or eslint). Skipping linting.',
|
|
248
|
-
configName: config.name,
|
|
249
|
-
outputPath,
|
|
250
|
-
logLevel,
|
|
251
|
-
events,
|
|
252
|
-
onStart: () => events.emit('lint:start'),
|
|
253
|
-
onEnd: () => events.emit('lint:end'),
|
|
254
|
-
})
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (config.hooks) {
|
|
258
|
-
await events.emit('hooks:start')
|
|
259
|
-
await executeHooks({ hooks: config.hooks, events })
|
|
260
|
-
|
|
261
|
-
await events.emit('hooks:end')
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Only reached when there are no failures (process.exit(1) is called above otherwise)
|
|
265
|
-
await events.emit('generation:summary', config, {
|
|
266
|
-
failedPlugins,
|
|
267
|
-
filesCreated: files.length,
|
|
268
|
-
status: 'success',
|
|
269
|
-
hrStart,
|
|
270
|
-
pluginTimings,
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
const telemetryEvent = buildTelemetryEvent({
|
|
274
|
-
command: 'generate',
|
|
275
|
-
kubbVersion: version,
|
|
276
|
-
plugins: driver.plugins.map((p) => ({ name: p.name, options: p.options as Record<string, unknown> })),
|
|
277
|
-
hrStart,
|
|
278
|
-
filesCreated: files.length,
|
|
279
|
-
status: 'success',
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
await sendTelemetry(telemetryEvent)
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
type GenerateCommandOptions = {
|
|
286
|
-
input?: string
|
|
287
|
-
configPath?: string
|
|
288
|
-
logLevel: string
|
|
289
|
-
watch: boolean
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
export async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, watch }: GenerateCommandOptions): Promise<void> {
|
|
293
|
-
const logLevel = logLevelMap[logLevelKey as keyof typeof logLevelMap] ?? logLevelMap.info
|
|
294
|
-
const events = new AsyncEventEmitterClass<KubbEvents>()
|
|
295
|
-
|
|
296
|
-
await setupLogger(events, { logLevel })
|
|
297
|
-
|
|
298
|
-
await executeIfOnline(async () => {
|
|
299
|
-
try {
|
|
300
|
-
const res = await fetch(KUBB_NPM_PACKAGE_URL)
|
|
301
|
-
const data = (await res.json()) as { version: string }
|
|
302
|
-
const latestVersion = data.version
|
|
303
|
-
|
|
304
|
-
if (latestVersion && version < latestVersion) {
|
|
305
|
-
await events.emit('version:new', version, latestVersion)
|
|
306
|
-
}
|
|
307
|
-
} catch {
|
|
308
|
-
// Ignore network errors for version check
|
|
309
|
-
}
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
try {
|
|
313
|
-
const result = await getCosmiConfig('kubb', configPath)
|
|
314
|
-
const configs = await getConfigs(result.config, { input } as CLIOptions)
|
|
315
|
-
|
|
316
|
-
await events.emit('config:start')
|
|
317
|
-
await events.emit('info', 'Config loaded', path.relative(process.cwd(), result.filepath))
|
|
318
|
-
await events.emit('success', 'Config loaded successfully', path.relative(process.cwd(), result.filepath))
|
|
319
|
-
await events.emit('config:end', configs)
|
|
320
|
-
|
|
321
|
-
await events.emit('lifecycle:start', version)
|
|
322
|
-
|
|
323
|
-
for (const config of configs) {
|
|
324
|
-
if (isInputPath(config) && watch) {
|
|
325
|
-
await startWatcher([input || config.input.path], async (paths) => {
|
|
326
|
-
// remove to avoid duplicate listeners after each change
|
|
327
|
-
events.removeAll()
|
|
328
|
-
|
|
329
|
-
await generate({ input, config, logLevel, events })
|
|
330
|
-
|
|
331
|
-
clack.log.step(styleText('yellow', `Watching for changes in ${paths.join(' and ')}`))
|
|
332
|
-
})
|
|
333
|
-
} else {
|
|
334
|
-
await generate({ input, config, logLevel, events })
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
await events.emit('lifecycle:end')
|
|
339
|
-
} catch (error) {
|
|
340
|
-
await events.emit('error', toError(error))
|
|
341
|
-
process.exit(1)
|
|
342
|
-
}
|
|
343
|
-
}
|