@kubb/cli 5.0.0-beta.5 → 5.0.0-beta.7
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 +177 -26
- package/dist/agent-DN7o8nlE.js +68 -0
- package/dist/agent-DN7o8nlE.js.map +1 -0
- package/dist/agent-Fm9_8BBH.cjs +70 -0
- package/dist/agent-Fm9_8BBH.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.map +1 -1
- package/dist/{define-Ctii4bel.js → define-m_fp-Aqm.js} +2 -2
- package/dist/{define-Ctii4bel.js.map → define-m_fp-Aqm.js.map} +1 -1
- package/dist/{errors-CjPmyZHy.js → errors-CINO1EIv.js} +2 -2
- package/dist/{errors-CjPmyZHy.js.map → errors-CINO1EIv.js.map} +1 -1
- package/dist/errors-CLCjoSg0.cjs.map +1 -1
- package/dist/{generate-BqeFFQGD.js → generate-BY-juRdH.js} +12 -6
- package/dist/generate-BY-juRdH.js.map +1 -0
- package/dist/{generate-7td_hs73.cjs → generate-Bod9YCbF.cjs} +10 -4
- package/dist/generate-Bod9YCbF.cjs.map +1 -0
- package/dist/index.cjs +20 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -13
- package/dist/index.js.map +1 -1
- package/dist/init-BIkZU6mB.cjs +53 -0
- package/dist/init-BIkZU6mB.cjs.map +1 -0
- package/dist/init-Cs3Fp6nN.js +53 -0
- package/dist/init-Cs3Fp6nN.js.map +1 -0
- package/dist/mcp-BSNulBcC.js +39 -0
- package/dist/mcp-BSNulBcC.js.map +1 -0
- package/dist/mcp-DcSrFhhP.cjs +39 -0
- package/dist/mcp-DcSrFhhP.cjs.map +1 -0
- package/dist/package-D5wmvFl4.js +6 -0
- package/dist/package-D5wmvFl4.js.map +1 -0
- package/dist/{package-BmYRU2hz.cjs → package-DrUndPET.cjs} +2 -2
- package/dist/package-DrUndPET.cjs.map +1 -0
- package/dist/{generate-DVmGtwWe.js → run-BAJubgdA.js} +298 -315
- package/dist/run-BAJubgdA.js.map +1 -0
- package/dist/{agent-IP0eLV3C.js → run-BzpYYOQs.js} +46 -43
- 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/{init-Cag3082g.js → run-CF97BWVa.js} +102 -147
- 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-CUd1dUY5.cjs → run-CqKd6JNc.cjs} +295 -312
- package/dist/run-CqKd6JNc.cjs.map +1 -0
- package/dist/run-D0hmRpHy.js +49 -0
- package/dist/run-D0hmRpHy.js.map +1 -0
- package/dist/{agent-CS45W0kL.cjs → run-DwdAwnLG.cjs} +44 -41
- package/dist/run-DwdAwnLG.cjs.map +1 -0
- package/dist/{mcp-BfORW-mY.cjs → run-Lr0Ctnu0.cjs} +24 -21
- package/dist/run-Lr0Ctnu0.cjs.map +1 -0
- package/dist/{init-C5sZulT6.cjs → run-YsoCk5we.cjs} +100 -145
- package/dist/run-YsoCk5we.cjs.map +1 -0
- package/dist/shell-475fQKaX.cjs.map +1 -1
- package/dist/{shell-DLzN4fRo.js → shell-CN6DNqeC.js} +2 -2
- package/dist/{shell-DLzN4fRo.js.map → shell-CN6DNqeC.js.map} +1 -1
- package/dist/{telemetry-BU25EoI-.cjs → telemetry-B2iWkY5e.cjs} +5 -7
- package/dist/telemetry-B2iWkY5e.cjs.map +1 -0
- package/dist/{telemetry-CaNU4-Bf.js → telemetry-BkektVz6.js} +6 -8
- package/dist/telemetry-BkektVz6.js.map +1 -0
- package/dist/validate-Bfpf_UIh.cjs +26 -0
- package/dist/validate-Bfpf_UIh.cjs.map +1 -0
- package/dist/validate-lbUkWQ5o.js +26 -0
- package/dist/validate-lbUkWQ5o.js.map +1 -0
- package/package.json +12 -12
- package/src/commands/agent/start.ts +10 -7
- package/src/commands/agent.ts +3 -1
- package/src/commands/generate.ts +5 -3
- package/src/commands/init.ts +34 -3
- package/src/commands/mcp.ts +28 -4
- package/src/commands/validate.ts +6 -4
- package/src/constants.ts +1 -57
- package/src/index.ts +5 -3
- package/src/loggers/clackLogger.ts +45 -43
- package/src/loggers/fileSystemLogger.ts +11 -1
- package/src/loggers/githubActionsLogger.ts +13 -25
- package/src/loggers/plainLogger.ts +12 -23
- 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} +12 -5
- package/dist/agent-BcUEl9yB.js +0 -56
- package/dist/agent-BcUEl9yB.js.map +0 -1
- package/dist/agent-CS45W0kL.cjs.map +0 -1
- package/dist/agent-CsMvXeqI.cjs +0 -58
- package/dist/agent-CsMvXeqI.cjs.map +0 -1
- package/dist/agent-IP0eLV3C.js.map +0 -1
- package/dist/constants-B4iBDvCe.cjs +0 -148
- package/dist/constants-B4iBDvCe.cjs.map +0 -1
- package/dist/constants-DmPrkaz8.js +0 -95
- package/dist/constants-DmPrkaz8.js.map +0 -1
- package/dist/generate-7td_hs73.cjs.map +0 -1
- package/dist/generate-BqeFFQGD.js.map +0 -1
- package/dist/generate-CUd1dUY5.cjs.map +0 -1
- package/dist/generate-DVmGtwWe.js.map +0 -1
- package/dist/init-C5sZulT6.cjs.map +0 -1
- package/dist/init-Cag3082g.js.map +0 -1
- package/dist/init-CfAn19gC.js +0 -25
- package/dist/init-CfAn19gC.js.map +0 -1
- package/dist/init-CfsYoyGe.cjs +0 -25
- package/dist/init-CfsYoyGe.cjs.map +0 -1
- package/dist/mcp-BfORW-mY.cjs.map +0 -1
- package/dist/mcp-BtOV6acy.js +0 -16
- package/dist/mcp-BtOV6acy.js.map +0 -1
- package/dist/mcp-CIbuLGMx.cjs +0 -16
- package/dist/mcp-CIbuLGMx.cjs.map +0 -1
- package/dist/mcp-DtQ5o0On.js +0 -46
- package/dist/mcp-DtQ5o0On.js.map +0 -1
- package/dist/package-BmYRU2hz.cjs.map +0 -1
- package/dist/package-DBU5ii-k.js +0 -6
- package/dist/package-DBU5ii-k.js.map +0 -1
- package/dist/telemetry-BU25EoI-.cjs.map +0 -1
- package/dist/telemetry-CaNU4-Bf.js.map +0 -1
- package/dist/validate-CQqM9siF.js +0 -25
- package/dist/validate-CQqM9siF.js.map +0 -1
- package/dist/validate-DBXLaLIn.cjs +0 -34
- package/dist/validate-DBXLaLIn.cjs.map +0 -1
- package/dist/validate-DI23zgmL.js +0 -33
- package/dist/validate-DI23zgmL.js.map +0 -1
- package/dist/validate-DwX4LzYq.cjs +0 -25
- package/dist/validate-DwX4LzYq.cjs.map +0 -1
- package/src/runners/agent.ts +0 -155
- package/src/runners/generate.ts +0 -333
- package/src/runners/init.ts +0 -296
- package/src/runners/mcp.ts +0 -51
- package/src/runners/validate.ts +0 -39
- 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 -9
- package/src/utils/getConfig.ts +0 -10
- package/src/utils/getCosmiConfig.ts +0 -75
- package/src/utils/getSummary.ts +0 -68
- package/src/utils/runHook.ts +0 -91
- package/src/utils/watcher.ts +0 -19
package/src/runners/init.ts
DELETED
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs'
|
|
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 { PackageManagerInfo } from '@internals/utils'
|
|
7
|
-
import { detectPackageManager } from '@internals/utils'
|
|
8
|
-
import { initDefaults, KUBB_CONFIG_FILENAME, pluginDefaultConfigs } from '../constants.ts'
|
|
9
|
-
import { hasPackageJson, initPackageJson, installPackages } from '../utils/packageManager.ts'
|
|
10
|
-
|
|
11
|
-
type PluginOption = {
|
|
12
|
-
value: string
|
|
13
|
-
label: string
|
|
14
|
-
hint?: string
|
|
15
|
-
packageName: string
|
|
16
|
-
importName: string
|
|
17
|
-
category: 'types' | 'client' | 'framework' | 'validation' | 'testing' | 'mocks' | 'documentation' | 'ai'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const availablePlugins: PluginOption[] = [
|
|
21
|
-
{
|
|
22
|
-
value: 'plugin-ts',
|
|
23
|
-
label: 'TypeScript',
|
|
24
|
-
hint: 'Recommended',
|
|
25
|
-
packageName: '@kubb/plugin-ts',
|
|
26
|
-
importName: 'pluginTs',
|
|
27
|
-
category: 'types',
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
value: 'plugin-client',
|
|
31
|
-
label: 'Client (Fetch/Axios)',
|
|
32
|
-
packageName: '@kubb/plugin-client',
|
|
33
|
-
importName: 'pluginClient',
|
|
34
|
-
category: 'client',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
value: 'plugin-react-query',
|
|
38
|
-
label: 'React Query / TanStack Query',
|
|
39
|
-
packageName: '@kubb/plugin-react-query',
|
|
40
|
-
importName: 'pluginReactQuery',
|
|
41
|
-
category: 'framework',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
value: 'plugin-vue-query',
|
|
45
|
-
label: 'Vue Query',
|
|
46
|
-
packageName: '@kubb/plugin-vue-query',
|
|
47
|
-
importName: 'pluginVueQuery',
|
|
48
|
-
category: 'framework',
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
value: 'plugin-zod',
|
|
52
|
-
label: 'Zod Schemas',
|
|
53
|
-
packageName: '@kubb/plugin-zod',
|
|
54
|
-
importName: 'pluginZod',
|
|
55
|
-
category: 'validation',
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
value: 'plugin-faker',
|
|
59
|
-
label: 'Faker.js Mocks',
|
|
60
|
-
packageName: '@kubb/plugin-faker',
|
|
61
|
-
importName: 'pluginFaker',
|
|
62
|
-
category: 'mocks',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
value: 'plugin-msw',
|
|
66
|
-
label: 'MSW Handlers',
|
|
67
|
-
packageName: '@kubb/plugin-msw',
|
|
68
|
-
importName: 'pluginMsw',
|
|
69
|
-
category: 'mocks',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
value: 'plugin-cypress',
|
|
73
|
-
label: 'Cypress Tests',
|
|
74
|
-
packageName: '@kubb/plugin-cypress',
|
|
75
|
-
importName: 'pluginCypress',
|
|
76
|
-
category: 'testing',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
value: 'plugin-mcp',
|
|
80
|
-
label: 'MCP Server (AI / Model Context Protocol)',
|
|
81
|
-
packageName: '@kubb/plugin-mcp',
|
|
82
|
-
importName: 'pluginMcp',
|
|
83
|
-
category: 'ai',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
value: 'plugin-redoc',
|
|
87
|
-
label: 'ReDoc Documentation',
|
|
88
|
-
packageName: '@kubb/plugin-redoc',
|
|
89
|
-
importName: 'pluginRedoc',
|
|
90
|
-
category: 'documentation',
|
|
91
|
-
},
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
function generateConfigFile(selectedPlugins: PluginOption[], inputPath: string, outputPath: string): string {
|
|
95
|
-
const imports = selectedPlugins.map((plugin) => `import { ${plugin.importName} } from '${plugin.packageName}'`).join('\n')
|
|
96
|
-
|
|
97
|
-
const pluginConfigs = selectedPlugins
|
|
98
|
-
.map((plugin) => {
|
|
99
|
-
const config = (pluginDefaultConfigs as Record<string, string>)[plugin.value] ?? `${plugin.importName}()`
|
|
100
|
-
return ` ${config},`
|
|
101
|
-
})
|
|
102
|
-
.join('\n')
|
|
103
|
-
|
|
104
|
-
return `import { defineConfig } from 'kubb'
|
|
105
|
-
${imports}
|
|
106
|
-
|
|
107
|
-
export default defineConfig({
|
|
108
|
-
root: '.',
|
|
109
|
-
input: {
|
|
110
|
-
path: '${inputPath}',
|
|
111
|
-
},
|
|
112
|
-
output: {
|
|
113
|
-
path: '${outputPath}',
|
|
114
|
-
clean: true,
|
|
115
|
-
},
|
|
116
|
-
plugins: [
|
|
117
|
-
${pluginConfigs}
|
|
118
|
-
],
|
|
119
|
-
})
|
|
120
|
-
`
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function cancelAndExit(message = 'Operation cancelled.'): never {
|
|
124
|
-
clack.cancel(message)
|
|
125
|
-
process.exit(0)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
type InitOptions = {
|
|
129
|
-
yes: boolean
|
|
130
|
-
version: string
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export async function runInit({ yes, version }: InitOptions): Promise<void> {
|
|
134
|
-
const cwd = process.cwd()
|
|
135
|
-
|
|
136
|
-
clack.intro(styleText('bgCyan', styleText('black', ' Kubb Init ')))
|
|
137
|
-
|
|
138
|
-
try {
|
|
139
|
-
// Check/create package.json
|
|
140
|
-
let packageManager: PackageManagerInfo
|
|
141
|
-
if (!hasPackageJson(cwd)) {
|
|
142
|
-
if (!yes) {
|
|
143
|
-
const shouldInit = await clack.confirm({
|
|
144
|
-
message: 'No package.json found. Would you like to create one?',
|
|
145
|
-
initialValue: true,
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
if (clack.isCancel(shouldInit) || !shouldInit) {
|
|
149
|
-
cancelAndExit()
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
packageManager = detectPackageManager(cwd)
|
|
154
|
-
|
|
155
|
-
const spinner = clack.spinner()
|
|
156
|
-
spinner.start(`Initializing package.json with ${packageManager.name}`)
|
|
157
|
-
|
|
158
|
-
await initPackageJson(cwd, packageManager)
|
|
159
|
-
|
|
160
|
-
spinner.stop(`Created package.json with ${packageManager.name}`)
|
|
161
|
-
} else {
|
|
162
|
-
packageManager = detectPackageManager(cwd)
|
|
163
|
-
clack.log.info(`Detected package manager: ${styleText('cyan', packageManager.name)}`)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Prompt for OpenAPI spec path
|
|
167
|
-
let inputPath: string
|
|
168
|
-
if (yes) {
|
|
169
|
-
inputPath = initDefaults.inputPath
|
|
170
|
-
clack.log.info(`Using input path: ${styleText('cyan', inputPath)}`)
|
|
171
|
-
} else {
|
|
172
|
-
const inputPathResult = await clack.text({
|
|
173
|
-
message: 'Where is your OpenAPI specification located?',
|
|
174
|
-
placeholder: initDefaults.inputPath,
|
|
175
|
-
defaultValue: initDefaults.inputPath,
|
|
176
|
-
validate: (value) => {
|
|
177
|
-
if (!value) return 'Input path is required'
|
|
178
|
-
},
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
if (clack.isCancel(inputPathResult)) {
|
|
182
|
-
cancelAndExit()
|
|
183
|
-
}
|
|
184
|
-
inputPath = inputPathResult as string
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Prompt for output directory
|
|
188
|
-
let outputPath: string
|
|
189
|
-
if (yes) {
|
|
190
|
-
outputPath = initDefaults.outputPath
|
|
191
|
-
clack.log.info(`Using output path: ${styleText('cyan', outputPath)}`)
|
|
192
|
-
} else {
|
|
193
|
-
const outputPathResult = await clack.text({
|
|
194
|
-
message: 'Where should the generated files be output?',
|
|
195
|
-
placeholder: initDefaults.outputPath,
|
|
196
|
-
defaultValue: initDefaults.outputPath,
|
|
197
|
-
validate: (value) => {
|
|
198
|
-
if (!value) return 'Output path is required'
|
|
199
|
-
},
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
if (clack.isCancel(outputPathResult)) {
|
|
203
|
-
cancelAndExit()
|
|
204
|
-
}
|
|
205
|
-
outputPath = outputPathResult as string
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Plugin selection
|
|
209
|
-
let selectedPlugins: PluginOption[]
|
|
210
|
-
if (yes) {
|
|
211
|
-
selectedPlugins = availablePlugins.filter((plugin) => (initDefaults.plugins as readonly string[]).includes(plugin.value))
|
|
212
|
-
clack.log.info(`Using plugins: ${styleText('cyan', selectedPlugins.map((p) => p.label).join(', '))}`)
|
|
213
|
-
} else {
|
|
214
|
-
const selectedPluginValues = await clack.multiselect({
|
|
215
|
-
message: 'Select plugins to use:',
|
|
216
|
-
options: availablePlugins.map((plugin) => ({
|
|
217
|
-
value: plugin.value,
|
|
218
|
-
label: plugin.label,
|
|
219
|
-
hint: plugin.hint,
|
|
220
|
-
})),
|
|
221
|
-
initialValues: [...initDefaults.plugins],
|
|
222
|
-
required: true,
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
if (clack.isCancel(selectedPluginValues)) {
|
|
226
|
-
cancelAndExit()
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
selectedPlugins = availablePlugins.filter((plugin) => (selectedPluginValues as string[]).includes(plugin.value))
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Install packages
|
|
233
|
-
const packagesToInstall = ['kubb', ...selectedPlugins.map((p) => p.packageName)]
|
|
234
|
-
|
|
235
|
-
const spinner = clack.spinner()
|
|
236
|
-
spinner.start(`Installing ${packagesToInstall.length} packages with ${packageManager.name}`)
|
|
237
|
-
|
|
238
|
-
try {
|
|
239
|
-
await installPackages(packagesToInstall, packageManager, cwd)
|
|
240
|
-
spinner.stop(`Installed ${packagesToInstall.length} packages`)
|
|
241
|
-
} catch (error) {
|
|
242
|
-
spinner.stop('Installation failed')
|
|
243
|
-
throw error
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Generate config file
|
|
247
|
-
const configSpinner = clack.spinner()
|
|
248
|
-
configSpinner.start(`Creating ${KUBB_CONFIG_FILENAME}`)
|
|
249
|
-
|
|
250
|
-
const configContent = generateConfigFile(selectedPlugins, inputPath, outputPath)
|
|
251
|
-
const configPath = path.join(cwd, KUBB_CONFIG_FILENAME)
|
|
252
|
-
|
|
253
|
-
if (fs.existsSync(configPath)) {
|
|
254
|
-
configSpinner.stop(`${KUBB_CONFIG_FILENAME} already exists`)
|
|
255
|
-
|
|
256
|
-
if (!yes) {
|
|
257
|
-
const shouldOverwrite = await clack.confirm({
|
|
258
|
-
message: `${KUBB_CONFIG_FILENAME} already exists. Overwrite?`,
|
|
259
|
-
initialValue: false,
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
if (clack.isCancel(shouldOverwrite) || !shouldOverwrite) {
|
|
263
|
-
cancelAndExit('Keeping existing configuration. Packages have been installed.')
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
configSpinner.start(`Overwriting ${KUBB_CONFIG_FILENAME}`)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
fs.writeFileSync(configPath, configContent, 'utf-8')
|
|
271
|
-
|
|
272
|
-
configSpinner.stop(`Created ${KUBB_CONFIG_FILENAME}`)
|
|
273
|
-
|
|
274
|
-
clack.outro(
|
|
275
|
-
styleText('green', '✓ All set!') +
|
|
276
|
-
'\n\n' +
|
|
277
|
-
styleText('dim', 'Next steps:') +
|
|
278
|
-
'\n' +
|
|
279
|
-
styleText('cyan', ` 1. Make sure your OpenAPI spec is at: ${inputPath}`) +
|
|
280
|
-
'\n' +
|
|
281
|
-
styleText('cyan', ' 2. Generate code with: npx kubb generate') +
|
|
282
|
-
'\n' +
|
|
283
|
-
styleText('cyan', ' Or start a stream server with: npx kubb start') +
|
|
284
|
-
'\n' +
|
|
285
|
-
styleText('cyan', ` 3. Find generated files in: ${outputPath}`) +
|
|
286
|
-
'\n\n' +
|
|
287
|
-
styleText('dim', `Using ${packageManager.name} • Kubb v${version}`),
|
|
288
|
-
)
|
|
289
|
-
} catch (error) {
|
|
290
|
-
clack.log.error(styleText('red', 'An error occurred during initialization'))
|
|
291
|
-
if (error instanceof Error) {
|
|
292
|
-
clack.log.error(error.message)
|
|
293
|
-
}
|
|
294
|
-
process.exit(1)
|
|
295
|
-
}
|
|
296
|
-
}
|
package/src/runners/mcp.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import process from 'node:process'
|
|
2
|
-
import { styleText } from 'node:util'
|
|
3
|
-
import { getErrorMessage } from '@internals/utils'
|
|
4
|
-
import type * as McpModule from '@kubb/mcp'
|
|
5
|
-
import { buildTelemetryEvent, sendTelemetry } from '../utils/telemetry.ts'
|
|
6
|
-
|
|
7
|
-
type McpOptions = {
|
|
8
|
-
version: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function runMcp({ version }: McpOptions): Promise<void> {
|
|
12
|
-
let mod: typeof McpModule
|
|
13
|
-
try {
|
|
14
|
-
mod = (await import('@kubb/mcp')) as typeof McpModule
|
|
15
|
-
} catch (_e) {
|
|
16
|
-
console.error(styleText('red', 'The @kubb/mcp package is not installed.'))
|
|
17
|
-
console.error('')
|
|
18
|
-
console.error('Install it with:')
|
|
19
|
-
console.error(styleText('cyan', ' npm install @kubb/mcp'))
|
|
20
|
-
console.error(styleText('cyan', ' # or'))
|
|
21
|
-
console.error(styleText('cyan', ' pnpm install @kubb/mcp'))
|
|
22
|
-
console.error('')
|
|
23
|
-
process.exit(1)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const { run } = mod
|
|
27
|
-
const hrStart = process.hrtime()
|
|
28
|
-
try {
|
|
29
|
-
console.log('⏳ Starting MCP server...')
|
|
30
|
-
console.warn(styleText('yellow', 'This feature is still under development — use with caution'))
|
|
31
|
-
run()
|
|
32
|
-
await sendTelemetry(
|
|
33
|
-
buildTelemetryEvent({
|
|
34
|
-
command: 'mcp',
|
|
35
|
-
kubbVersion: version,
|
|
36
|
-
hrStart,
|
|
37
|
-
status: 'success',
|
|
38
|
-
}),
|
|
39
|
-
)
|
|
40
|
-
} catch (error) {
|
|
41
|
-
await sendTelemetry(
|
|
42
|
-
buildTelemetryEvent({
|
|
43
|
-
command: 'mcp',
|
|
44
|
-
kubbVersion: version,
|
|
45
|
-
hrStart,
|
|
46
|
-
status: 'failed',
|
|
47
|
-
}),
|
|
48
|
-
)
|
|
49
|
-
console.error(getErrorMessage(error))
|
|
50
|
-
}
|
|
51
|
-
}
|
package/src/runners/validate.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import process from 'node:process'
|
|
2
|
-
import { getErrorMessage } from '@internals/utils'
|
|
3
|
-
import { parseDocument, validateDocument } from '@kubb/adapter-oas'
|
|
4
|
-
import { buildTelemetryEvent, sendTelemetry } from '../utils/telemetry.ts'
|
|
5
|
-
|
|
6
|
-
type ValidateOptions = {
|
|
7
|
-
input: string
|
|
8
|
-
version: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function runValidate({ input, version }: ValidateOptions): Promise<void> {
|
|
12
|
-
const hrStart = process.hrtime()
|
|
13
|
-
try {
|
|
14
|
-
const document = await parseDocument(input)
|
|
15
|
-
await validateDocument(document, { throwOnError: true })
|
|
16
|
-
|
|
17
|
-
await sendTelemetry(
|
|
18
|
-
buildTelemetryEvent({
|
|
19
|
-
command: 'validate',
|
|
20
|
-
kubbVersion: version,
|
|
21
|
-
hrStart,
|
|
22
|
-
status: 'success',
|
|
23
|
-
}),
|
|
24
|
-
)
|
|
25
|
-
console.log('✅ Validation success')
|
|
26
|
-
} catch (error) {
|
|
27
|
-
await sendTelemetry(
|
|
28
|
-
buildTelemetryEvent({
|
|
29
|
-
command: 'validate',
|
|
30
|
-
kubbVersion: version,
|
|
31
|
-
hrStart,
|
|
32
|
-
status: 'failed',
|
|
33
|
-
}),
|
|
34
|
-
)
|
|
35
|
-
console.error('❌ Validation failed')
|
|
36
|
-
console.error(getErrorMessage(error))
|
|
37
|
-
process.exit(1)
|
|
38
|
-
}
|
|
39
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export type QuiteFlag = '--help' | '-h' | '--version' | '-v'
|
|
2
|
-
|
|
3
|
-
export type GenerateFlag = '--config' | '-c' | '--log-level' | '-l' | '--watch' | '-w' | '--debug' | '-d' | '--verbose' | '-v' | '--silent' | '-s'
|
|
4
|
-
|
|
5
|
-
export type ValidateFlag = '--input' | '-i'
|
|
6
|
-
|
|
7
|
-
export type InitFlag = '--yes' | '-y'
|
|
8
|
-
|
|
9
|
-
export type AgentStartFlag = '--config' | '-c' | '--port' | '-p' | '--host' | '--allow-write' | '--allow-all'
|
|
10
|
-
|
|
11
|
-
export type Arg = QuiteFlag | GenerateFlag | ValidateFlag | InitFlag | AgentStartFlag
|
package/src/utils/Writables.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { WritableOptions } from 'node:stream'
|
|
2
|
-
import { Writable } from 'node:stream'
|
|
3
|
-
import { styleText } from 'node:util'
|
|
4
|
-
import type * as clack from '@clack/prompts'
|
|
5
|
-
|
|
6
|
-
export class ClackWritable extends Writable {
|
|
7
|
-
taskLog: ReturnType<typeof clack.taskLog>
|
|
8
|
-
constructor(taskLog: ReturnType<typeof clack.taskLog>, opts?: WritableOptions) {
|
|
9
|
-
super(opts)
|
|
10
|
-
|
|
11
|
-
this.taskLog = taskLog
|
|
12
|
-
}
|
|
13
|
-
_write(chunk: Buffer, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void {
|
|
14
|
-
this.taskLog.message(`${styleText('dim', chunk.toString())}`)
|
|
15
|
-
callback()
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto'
|
|
2
|
-
import { styleText } from 'node:util'
|
|
3
|
-
import type { AsyncEventEmitter } from '@internals/utils'
|
|
4
|
-
import { tokenize } from '@internals/utils'
|
|
5
|
-
import type { Config, KubbHookEndContext, KubbHooks } from '@kubb/core'
|
|
6
|
-
|
|
7
|
-
type ExecutingHooksProps = {
|
|
8
|
-
configHooks: NonNullable<Config['hooks']>
|
|
9
|
-
hooks: AsyncEventEmitter<KubbHooks>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export async function executeHooks({ configHooks, hooks }: ExecutingHooksProps): Promise<void> {
|
|
13
|
-
const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean)
|
|
14
|
-
|
|
15
|
-
for (const command of commands) {
|
|
16
|
-
const [cmd, ...args] = tokenize(command)
|
|
17
|
-
|
|
18
|
-
if (!cmd) {
|
|
19
|
-
continue
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const hookId = createHash('sha256').update(command).digest('hex')
|
|
23
|
-
|
|
24
|
-
// Wire up the hook:end listener BEFORE emitting hook:start to avoid the race condition
|
|
25
|
-
// where hook:end fires synchronously inside emit('kubb:hook:start') before the listener is registered.
|
|
26
|
-
const hookEndPromise = new Promise<void>((resolve, reject) => {
|
|
27
|
-
const handler = (ctx: KubbHookEndContext) => {
|
|
28
|
-
if (ctx.id !== hookId) return
|
|
29
|
-
hooks.off('kubb:hook:end', handler)
|
|
30
|
-
if (!ctx.success) {
|
|
31
|
-
reject(ctx.error ?? new Error(`Hook failed: ${command}`))
|
|
32
|
-
return
|
|
33
|
-
}
|
|
34
|
-
hooks
|
|
35
|
-
.emit('kubb:success', { message: `${styleText('dim', command)} successfully executed` })
|
|
36
|
-
.then(resolve)
|
|
37
|
-
.catch(reject)
|
|
38
|
-
}
|
|
39
|
-
hooks.on('kubb:hook:end', handler)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
await hooks.emit('kubb:hook:start', { id: hookId, command: cmd, args })
|
|
43
|
-
await hookEndPromise
|
|
44
|
-
}
|
|
45
|
-
}
|
package/src/utils/flags.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type guard that confirms `value` is a member of `set`. Avoids type assertions with `Set<T extends string>`.
|
|
3
|
-
*/
|
|
4
|
-
export function isFlag<T extends string>(set: ReadonlySet<T>, value: string): value is T {
|
|
5
|
-
for (const flag of set) {
|
|
6
|
-
if (flag === value) return true
|
|
7
|
-
}
|
|
8
|
-
return false
|
|
9
|
-
}
|
package/src/utils/getConfig.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { CLIOptions, Config, PossibleConfig } from '@kubb/core'
|
|
2
|
-
|
|
3
|
-
type ConfigInput = PossibleConfig<CLIOptions>
|
|
4
|
-
|
|
5
|
-
export async function getConfigs(config: ConfigInput, args: CLIOptions): Promise<Array<Config>> {
|
|
6
|
-
const resolved = await (typeof config === 'function' ? config(args as CLIOptions) : config)
|
|
7
|
-
const userConfigs = Array.isArray(resolved) ? resolved : [resolved]
|
|
8
|
-
|
|
9
|
-
return userConfigs.map((item) => ({ ...item, plugins: item.plugins ?? [] }) as Config)
|
|
10
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { Config } from '@kubb/core'
|
|
2
|
-
import { cosmiconfig } from 'cosmiconfig'
|
|
3
|
-
import { createJiti } from 'jiti'
|
|
4
|
-
|
|
5
|
-
type CosmiconfigResult = {
|
|
6
|
-
filepath: string
|
|
7
|
-
isEmpty?: boolean
|
|
8
|
-
config: Config
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const jiti = createJiti(import.meta.url, {
|
|
12
|
-
jsx: {
|
|
13
|
-
runtime: 'automatic',
|
|
14
|
-
importSource: '@kubb/renderer-jsx',
|
|
15
|
-
},
|
|
16
|
-
moduleCache: false,
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
const tsLoader = async (configFile: string) => {
|
|
20
|
-
return jiti.import(configFile, { default: true })
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function getCosmiConfig(moduleName: string, config?: string): Promise<CosmiconfigResult> {
|
|
24
|
-
let result: CosmiconfigResult
|
|
25
|
-
const searchPlaces = [
|
|
26
|
-
'package.json',
|
|
27
|
-
`.${moduleName}rc`,
|
|
28
|
-
`.${moduleName}rc.json`,
|
|
29
|
-
`.${moduleName}rc.yaml`,
|
|
30
|
-
`.${moduleName}rc.yml`,
|
|
31
|
-
|
|
32
|
-
`.${moduleName}rc.ts`,
|
|
33
|
-
`.${moduleName}rc.mts`,
|
|
34
|
-
`.${moduleName}rc.cts`,
|
|
35
|
-
`.${moduleName}rc.js`,
|
|
36
|
-
`.${moduleName}rc.mjs`,
|
|
37
|
-
`.${moduleName}rc.cjs`,
|
|
38
|
-
|
|
39
|
-
`${moduleName}.config.ts`,
|
|
40
|
-
`${moduleName}.config.mts`,
|
|
41
|
-
`${moduleName}.config.cts`,
|
|
42
|
-
`${moduleName}.config.js`,
|
|
43
|
-
`${moduleName}.config.mjs`,
|
|
44
|
-
`${moduleName}.config.cjs`,
|
|
45
|
-
]
|
|
46
|
-
const explorer = cosmiconfig(moduleName, {
|
|
47
|
-
cache: false,
|
|
48
|
-
searchPlaces: [
|
|
49
|
-
...searchPlaces.map((searchPlace) => {
|
|
50
|
-
return `.config/${searchPlace}`
|
|
51
|
-
}),
|
|
52
|
-
...searchPlaces.map((searchPlace) => {
|
|
53
|
-
return `configs/${searchPlace}`
|
|
54
|
-
}),
|
|
55
|
-
...searchPlaces,
|
|
56
|
-
],
|
|
57
|
-
loaders: {
|
|
58
|
-
'.ts': tsLoader,
|
|
59
|
-
'.mts': tsLoader,
|
|
60
|
-
'.cts': tsLoader,
|
|
61
|
-
},
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
result = config ? ((await explorer.load(config)) as CosmiconfigResult) : ((await explorer.search()) as CosmiconfigResult)
|
|
66
|
-
} catch (error) {
|
|
67
|
-
throw new Error('Config failed loading', { cause: error })
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (result?.isEmpty || !result || !result.config) {
|
|
71
|
-
throw new Error('Config not defined, create a kubb.config.js or pass through your config with the option --config')
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return result as CosmiconfigResult
|
|
75
|
-
}
|
package/src/utils/getSummary.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import { styleText } from 'node:util'
|
|
3
|
-
import { formatHrtime, randomCliColor } from '@internals/utils'
|
|
4
|
-
import type { Config, Plugin } from '@kubb/core'
|
|
5
|
-
import { SUMMARY_MAX_BAR_LENGTH, SUMMARY_TIME_SCALE_DIVISOR } from '../constants.ts'
|
|
6
|
-
|
|
7
|
-
type SummaryProps = {
|
|
8
|
-
failedPlugins: Set<{ plugin: Plugin; error: Error }>
|
|
9
|
-
status: 'success' | 'failed'
|
|
10
|
-
hrStart: [number, number]
|
|
11
|
-
filesCreated: number
|
|
12
|
-
config: Config
|
|
13
|
-
pluginTimings?: Map<string, number>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }: SummaryProps): string[] {
|
|
17
|
-
const duration = formatHrtime(hrStart)
|
|
18
|
-
|
|
19
|
-
const pluginsCount = config.plugins?.length ?? 0
|
|
20
|
-
const successCount = pluginsCount - failedPlugins.size
|
|
21
|
-
|
|
22
|
-
const meta = {
|
|
23
|
-
plugins:
|
|
24
|
-
status === 'success'
|
|
25
|
-
? `${styleText('green', `${successCount} successful`)}, ${pluginsCount} total`
|
|
26
|
-
: `${styleText('green', `${successCount} successful`)}, ${styleText('red', `${failedPlugins.size} failed`)}, ${pluginsCount} total`,
|
|
27
|
-
pluginsFailed: status === 'failed' ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(', ') : undefined,
|
|
28
|
-
filesCreated,
|
|
29
|
-
time: styleText('green', duration),
|
|
30
|
-
output: path.resolve(config.root, config.output.path),
|
|
31
|
-
} as const
|
|
32
|
-
|
|
33
|
-
const labels = {
|
|
34
|
-
plugins: 'Plugins:',
|
|
35
|
-
failed: 'Failed:',
|
|
36
|
-
generated: 'Generated:',
|
|
37
|
-
pluginTimings: 'Plugin Timings:',
|
|
38
|
-
output: 'Output:',
|
|
39
|
-
}
|
|
40
|
-
const maxLength = Math.max(0, ...[...Object.values(labels), ...(pluginTimings ? Array.from(pluginTimings.keys()) : [])].map((s) => s.length))
|
|
41
|
-
|
|
42
|
-
const summaryLines: string[] = []
|
|
43
|
-
summaryLines.push(`${labels.plugins.padEnd(maxLength + 2)} ${meta.plugins}`)
|
|
44
|
-
|
|
45
|
-
if (meta.pluginsFailed) {
|
|
46
|
-
summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`)
|
|
50
|
-
|
|
51
|
-
if (pluginTimings && pluginTimings.size > 0) {
|
|
52
|
-
const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1])
|
|
53
|
-
|
|
54
|
-
summaryLines.push(`${labels.pluginTimings}`)
|
|
55
|
-
|
|
56
|
-
sortedTimings.forEach(([name, time]) => {
|
|
57
|
-
const timeStr = time >= 1000 ? `${(time / 1000).toFixed(2)}s` : `${Math.round(time)}ms`
|
|
58
|
-
const barLength = Math.min(Math.ceil(time / SUMMARY_TIME_SCALE_DIVISOR), SUMMARY_MAX_BAR_LENGTH)
|
|
59
|
-
const bar = styleText('dim', '█'.repeat(barLength))
|
|
60
|
-
|
|
61
|
-
summaryLines.push(`${styleText('dim', '•')} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`)
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`)
|
|
66
|
-
|
|
67
|
-
return summaryLines
|
|
68
|
-
}
|