@kubb/core 5.0.0-alpha.9 → 5.0.0-beta.75
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 +23 -20
- package/dist/PluginDriver-BXibeQk-.cjs +1036 -0
- package/dist/PluginDriver-BXibeQk-.cjs.map +1 -0
- package/dist/PluginDriver-DV3p2Hky.js +945 -0
- package/dist/PluginDriver-DV3p2Hky.js.map +1 -0
- package/dist/index.cjs +729 -1641
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +271 -225
- package/dist/index.js +713 -1609
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +145 -0
- package/dist/mocks.cjs.map +1 -0
- package/dist/mocks.d.ts +80 -0
- package/dist/mocks.js +140 -0
- package/dist/mocks.js.map +1 -0
- package/dist/types-CuNocrbJ.d.ts +2148 -0
- package/package.json +51 -57
- package/src/FileManager.ts +115 -0
- package/src/FileProcessor.ts +86 -0
- package/src/Kubb.ts +207 -131
- package/src/PluginDriver.ts +325 -564
- package/src/constants.ts +20 -47
- package/src/createAdapter.ts +13 -6
- package/src/createKubb.ts +548 -0
- package/src/createRenderer.ts +57 -0
- package/src/createStorage.ts +13 -1
- package/src/defineGenerator.ts +77 -124
- package/src/defineLogger.ts +4 -2
- package/src/defineMiddleware.ts +62 -0
- package/src/defineParser.ts +44 -0
- package/src/definePlugin.ts +83 -0
- package/src/defineResolver.ts +418 -28
- package/src/devtools.ts +14 -14
- package/src/index.ts +13 -15
- package/src/mocks.ts +178 -0
- package/src/renderNode.ts +35 -0
- package/src/storages/fsStorage.ts +41 -11
- package/src/storages/memoryStorage.ts +4 -2
- package/src/types.ts +1031 -283
- package/src/utils/diagnostics.ts +4 -1
- package/src/utils/isInputPath.ts +10 -0
- package/src/utils/packageJSON.ts +50 -12
- package/dist/PluginDriver-BkFepPdm.d.ts +0 -1054
- package/dist/chunk-ByKO4r7w.cjs +0 -38
- package/dist/hooks.cjs +0 -103
- package/dist/hooks.cjs.map +0 -1
- package/dist/hooks.d.ts +0 -77
- package/dist/hooks.js +0 -98
- package/dist/hooks.js.map +0 -1
- package/src/build.ts +0 -418
- package/src/config.ts +0 -56
- package/src/createPlugin.ts +0 -28
- package/src/hooks/index.ts +0 -4
- package/src/hooks/useKubb.ts +0 -143
- package/src/hooks/useMode.ts +0 -11
- package/src/hooks/usePlugin.ts +0 -11
- package/src/hooks/usePluginDriver.ts +0 -11
- package/src/utils/FunctionParams.ts +0 -155
- package/src/utils/TreeNode.ts +0 -215
- package/src/utils/executeStrategies.ts +0 -81
- package/src/utils/formatters.ts +0 -56
- package/src/utils/getBarrelFiles.ts +0 -141
- package/src/utils/getConfigs.ts +0 -12
- package/src/utils/linters.ts +0 -25
package/src/build.ts
DELETED
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
import { dirname, relative, resolve } from 'node:path'
|
|
2
|
-
import { AsyncEventEmitter, BuildError, exists, formatMs, getElapsedMs, getRelativePath, URLPath } from '@internals/utils'
|
|
3
|
-
import type { Fabric as FabricType, KubbFile } from '@kubb/fabric-core/types'
|
|
4
|
-
import { createFabric } from '@kubb/react-fabric'
|
|
5
|
-
import { typescriptParser } from '@kubb/react-fabric/parsers'
|
|
6
|
-
import { fsPlugin } from '@kubb/react-fabric/plugins'
|
|
7
|
-
import { isInputPath } from './config.ts'
|
|
8
|
-
import { BARREL_FILENAME, DEFAULT_BANNER, DEFAULT_CONCURRENCY, DEFAULT_EXTENSION, DEFAULT_STUDIO_URL } from './constants.ts'
|
|
9
|
-
import { PluginDriver } from './PluginDriver.ts'
|
|
10
|
-
import { fsStorage } from './storages/fsStorage.ts'
|
|
11
|
-
import type { AdapterSource, Config, KubbEvents, Output, Plugin, Storage, UserConfig } from './types.ts'
|
|
12
|
-
import { getDiagnosticInfo } from './utils/diagnostics.ts'
|
|
13
|
-
import type { FileMetaBase } from './utils/getBarrelFiles.ts'
|
|
14
|
-
|
|
15
|
-
type BuildOptions = {
|
|
16
|
-
config: UserConfig
|
|
17
|
-
events?: AsyncEventEmitter<KubbEvents>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type BuildOutput = {
|
|
21
|
-
failedPlugins: Set<{ plugin: Plugin; error: Error }>
|
|
22
|
-
fabric: FabricType
|
|
23
|
-
files: Array<KubbFile.ResolvedFile>
|
|
24
|
-
driver: PluginDriver
|
|
25
|
-
pluginTimings: Map<string, number>
|
|
26
|
-
error?: Error
|
|
27
|
-
sources: Map<KubbFile.Path, string>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type SetupResult = {
|
|
31
|
-
events: AsyncEventEmitter<KubbEvents>
|
|
32
|
-
fabric: FabricType
|
|
33
|
-
driver: PluginDriver
|
|
34
|
-
sources: Map<KubbFile.Path, string>
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function setup(options: BuildOptions): Promise<SetupResult> {
|
|
38
|
-
const { config: userConfig, events = new AsyncEventEmitter<KubbEvents>() } = options
|
|
39
|
-
|
|
40
|
-
const sources: Map<KubbFile.Path, string> = new Map<KubbFile.Path, string>()
|
|
41
|
-
const diagnosticInfo = getDiagnosticInfo()
|
|
42
|
-
|
|
43
|
-
if (Array.isArray(userConfig.input)) {
|
|
44
|
-
await events.emit('warn', 'This feature is still under development — use with caution')
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
await events.emit('debug', {
|
|
48
|
-
date: new Date(),
|
|
49
|
-
logs: [
|
|
50
|
-
'Configuration:',
|
|
51
|
-
` • Name: ${userConfig.name || 'unnamed'}`,
|
|
52
|
-
` • Root: ${userConfig.root || process.cwd()}`,
|
|
53
|
-
` • Output: ${userConfig.output?.path || 'not specified'}`,
|
|
54
|
-
` • Plugins: ${userConfig.plugins?.length || 0}`,
|
|
55
|
-
'Output Settings:',
|
|
56
|
-
` • Storage: ${userConfig.output?.storage ? `custom(${userConfig.output.storage.name})` : userConfig.output?.write === false ? 'disabled' : 'filesystem (default)'}`,
|
|
57
|
-
` • Formatter: ${userConfig.output?.format || 'none'}`,
|
|
58
|
-
` • Linter: ${userConfig.output?.lint || 'none'}`,
|
|
59
|
-
'Environment:',
|
|
60
|
-
Object.entries(diagnosticInfo)
|
|
61
|
-
.map(([key, value]) => ` • ${key}: ${value}`)
|
|
62
|
-
.join('\n'),
|
|
63
|
-
],
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
if (isInputPath(userConfig) && !new URLPath(userConfig.input.path).isURL) {
|
|
68
|
-
await exists(userConfig.input.path)
|
|
69
|
-
|
|
70
|
-
await events.emit('debug', {
|
|
71
|
-
date: new Date(),
|
|
72
|
-
logs: [`✓ Input file validated: ${userConfig.input.path}`],
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
} catch (caughtError) {
|
|
76
|
-
if (isInputPath(userConfig)) {
|
|
77
|
-
const error = caughtError as Error
|
|
78
|
-
|
|
79
|
-
throw new Error(
|
|
80
|
-
`Cannot read file/URL defined in \`input.path\` or set with \`kubb generate PATH\` in the CLI of your Kubb config ${userConfig.input.path}`,
|
|
81
|
-
{
|
|
82
|
-
cause: error,
|
|
83
|
-
},
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const definedConfig: Config = {
|
|
89
|
-
root: userConfig.root || process.cwd(),
|
|
90
|
-
...userConfig,
|
|
91
|
-
output: {
|
|
92
|
-
write: true,
|
|
93
|
-
barrelType: 'named',
|
|
94
|
-
extension: DEFAULT_EXTENSION,
|
|
95
|
-
defaultBanner: DEFAULT_BANNER,
|
|
96
|
-
...userConfig.output,
|
|
97
|
-
},
|
|
98
|
-
devtools: userConfig.devtools
|
|
99
|
-
? {
|
|
100
|
-
studioUrl: DEFAULT_STUDIO_URL,
|
|
101
|
-
...(typeof userConfig.devtools === 'boolean' ? {} : userConfig.devtools),
|
|
102
|
-
}
|
|
103
|
-
: undefined,
|
|
104
|
-
plugins: userConfig.plugins as Config['plugins'],
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// write: false is the explicit dry-run opt-out; otherwise use the provided
|
|
108
|
-
// storage or fall back to fsStorage (backwards-compatible default).
|
|
109
|
-
// Keys are root-relative (e.g. `src/gen/api/getPets.ts`) so fsStorage()
|
|
110
|
-
// needs no configuration — it resolves them against process.cwd().
|
|
111
|
-
const storage: Storage | null = definedConfig.output.write === false ? null : (definedConfig.output.storage ?? fsStorage())
|
|
112
|
-
|
|
113
|
-
if (definedConfig.output.clean) {
|
|
114
|
-
await events.emit('debug', {
|
|
115
|
-
date: new Date(),
|
|
116
|
-
logs: ['Cleaning output directories', ` • Output: ${definedConfig.output.path}`],
|
|
117
|
-
})
|
|
118
|
-
await storage?.clear(resolve(definedConfig.root, definedConfig.output.path))
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const fabric = createFabric()
|
|
122
|
-
fabric.use(fsPlugin)
|
|
123
|
-
fabric.use(typescriptParser)
|
|
124
|
-
|
|
125
|
-
fabric.context.on('files:processing:start', (files) => {
|
|
126
|
-
events.emit('files:processing:start', files)
|
|
127
|
-
events.emit('debug', {
|
|
128
|
-
date: new Date(),
|
|
129
|
-
logs: [`Writing ${files.length} files...`],
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
fabric.context.on('file:processing:update', async (params) => {
|
|
134
|
-
const { file, source } = params
|
|
135
|
-
await events.emit('file:processing:update', {
|
|
136
|
-
...params,
|
|
137
|
-
config: definedConfig,
|
|
138
|
-
source,
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
if (source) {
|
|
142
|
-
// Key is root-relative so it's meaningful for any backend (fs, S3, Redis…)
|
|
143
|
-
const key = relative(resolve(definedConfig.root), file.path)
|
|
144
|
-
await storage?.setItem(key, source)
|
|
145
|
-
sources.set(file.path, source)
|
|
146
|
-
}
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
fabric.context.on('files:processing:end', async (files) => {
|
|
150
|
-
await events.emit('files:processing:end', files)
|
|
151
|
-
await events.emit('debug', {
|
|
152
|
-
date: new Date(),
|
|
153
|
-
logs: [`✓ File write process completed for ${files.length} files`],
|
|
154
|
-
})
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
await events.emit('debug', {
|
|
158
|
-
date: new Date(),
|
|
159
|
-
logs: [
|
|
160
|
-
'✓ Fabric initialized',
|
|
161
|
-
` • Storage: ${storage ? storage.name : 'disabled (dry-run)'}`,
|
|
162
|
-
` • Barrel type: ${definedConfig.output.barrelType || 'none'}`,
|
|
163
|
-
],
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
const pluginDriver = new PluginDriver(definedConfig, {
|
|
167
|
-
fabric,
|
|
168
|
-
events,
|
|
169
|
-
concurrency: DEFAULT_CONCURRENCY,
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
// Run the adapter (if provided) to produce the universal RootNode
|
|
173
|
-
if (definedConfig.adapter) {
|
|
174
|
-
const source = inputToAdapterSource(definedConfig)
|
|
175
|
-
|
|
176
|
-
await events.emit('debug', {
|
|
177
|
-
date: new Date(),
|
|
178
|
-
logs: [`Running adapter: ${definedConfig.adapter.name}`],
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
pluginDriver.adapter = definedConfig.adapter
|
|
182
|
-
pluginDriver.rootNode = await definedConfig.adapter.parse(source)
|
|
183
|
-
|
|
184
|
-
await events.emit('debug', {
|
|
185
|
-
date: new Date(),
|
|
186
|
-
logs: [
|
|
187
|
-
`✓ Adapter '${definedConfig.adapter.name}' resolved RootNode`,
|
|
188
|
-
` • Schemas: ${pluginDriver.rootNode.schemas.length}`,
|
|
189
|
-
` • Operations: ${pluginDriver.rootNode.operations.length}`,
|
|
190
|
-
],
|
|
191
|
-
})
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
events,
|
|
196
|
-
fabric,
|
|
197
|
-
driver: pluginDriver,
|
|
198
|
-
sources,
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export async function build(options: BuildOptions, overrides?: SetupResult): Promise<BuildOutput> {
|
|
203
|
-
const { fabric, files, driver, failedPlugins, pluginTimings, error, sources } = await safeBuild(options, overrides)
|
|
204
|
-
|
|
205
|
-
if (error) {
|
|
206
|
-
throw error
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (failedPlugins.size > 0) {
|
|
210
|
-
const errors = [...failedPlugins].map(({ error }) => error)
|
|
211
|
-
|
|
212
|
-
throw new BuildError(`Build Error with ${failedPlugins.size} failed plugins`, { errors })
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return {
|
|
216
|
-
failedPlugins,
|
|
217
|
-
fabric,
|
|
218
|
-
files,
|
|
219
|
-
driver,
|
|
220
|
-
pluginTimings,
|
|
221
|
-
error: undefined,
|
|
222
|
-
sources,
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
export async function safeBuild(options: BuildOptions, overrides?: SetupResult): Promise<BuildOutput> {
|
|
227
|
-
const { fabric, driver, events, sources } = overrides ? overrides : await setup(options)
|
|
228
|
-
|
|
229
|
-
const failedPlugins = new Set<{ plugin: Plugin; error: Error }>()
|
|
230
|
-
// in ms
|
|
231
|
-
const pluginTimings = new Map<string, number>()
|
|
232
|
-
const config = driver.config
|
|
233
|
-
|
|
234
|
-
try {
|
|
235
|
-
for (const plugin of driver.plugins) {
|
|
236
|
-
const context = driver.getContext(plugin)
|
|
237
|
-
const hrStart = process.hrtime()
|
|
238
|
-
|
|
239
|
-
const installer = plugin.install.bind(context)
|
|
240
|
-
|
|
241
|
-
try {
|
|
242
|
-
const timestamp = new Date()
|
|
243
|
-
|
|
244
|
-
await events.emit('plugin:start', plugin)
|
|
245
|
-
|
|
246
|
-
await events.emit('debug', {
|
|
247
|
-
date: timestamp,
|
|
248
|
-
logs: ['Installing plugin...', ` • Plugin Name: ${plugin.name}`],
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
await installer(context)
|
|
252
|
-
|
|
253
|
-
const duration = getElapsedMs(hrStart)
|
|
254
|
-
pluginTimings.set(plugin.name, duration)
|
|
255
|
-
|
|
256
|
-
await events.emit('plugin:end', plugin, { duration, success: true })
|
|
257
|
-
|
|
258
|
-
await events.emit('debug', {
|
|
259
|
-
date: new Date(),
|
|
260
|
-
logs: [`✓ Plugin installed successfully (${formatMs(duration)})`],
|
|
261
|
-
})
|
|
262
|
-
} catch (caughtError) {
|
|
263
|
-
const error = caughtError as Error
|
|
264
|
-
const errorTimestamp = new Date()
|
|
265
|
-
const duration = getElapsedMs(hrStart)
|
|
266
|
-
|
|
267
|
-
await events.emit('plugin:end', plugin, {
|
|
268
|
-
duration,
|
|
269
|
-
success: false,
|
|
270
|
-
error,
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
await events.emit('debug', {
|
|
274
|
-
date: errorTimestamp,
|
|
275
|
-
logs: [
|
|
276
|
-
'✗ Plugin installation failed',
|
|
277
|
-
` • Plugin Name: ${plugin.name}`,
|
|
278
|
-
` • Error: ${error.constructor.name} - ${error.message}`,
|
|
279
|
-
' • Stack Trace:',
|
|
280
|
-
error.stack || 'No stack trace available',
|
|
281
|
-
],
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
failedPlugins.add({ plugin, error })
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
if (config.output.barrelType) {
|
|
289
|
-
const root = resolve(config.root)
|
|
290
|
-
const rootPath = resolve(root, config.output.path, BARREL_FILENAME)
|
|
291
|
-
const rootDir = dirname(rootPath)
|
|
292
|
-
|
|
293
|
-
await events.emit('debug', {
|
|
294
|
-
date: new Date(),
|
|
295
|
-
logs: ['Generating barrel file', ` • Type: ${config.output.barrelType}`, ` • Path: ${rootPath}`],
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
const barrelFiles = fabric.files.filter((file) => {
|
|
299
|
-
return file.sources.some((source) => source.isIndexable)
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
await events.emit('debug', {
|
|
303
|
-
date: new Date(),
|
|
304
|
-
logs: [`Found ${barrelFiles.length} indexable files for barrel export`],
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
const existingBarrel = fabric.files.find((f) => f.path === rootPath)
|
|
308
|
-
const existingExports = new Set(
|
|
309
|
-
existingBarrel?.exports?.flatMap((e) => (Array.isArray(e.name) ? e.name : [e.name])).filter((n): n is string => Boolean(n)) ?? [],
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
const rootFile: KubbFile.File = {
|
|
313
|
-
path: rootPath,
|
|
314
|
-
baseName: BARREL_FILENAME,
|
|
315
|
-
exports: buildBarrelExports({ barrelFiles, rootDir, existingExports, config, driver }),
|
|
316
|
-
sources: [],
|
|
317
|
-
imports: [],
|
|
318
|
-
meta: {},
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
await fabric.upsertFile(rootFile)
|
|
322
|
-
|
|
323
|
-
await events.emit('debug', {
|
|
324
|
-
date: new Date(),
|
|
325
|
-
logs: [`✓ Generated barrel file (${rootFile.exports?.length || 0} exports)`],
|
|
326
|
-
})
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const files = [...fabric.files]
|
|
330
|
-
|
|
331
|
-
await fabric.write({ extension: config.output.extension })
|
|
332
|
-
|
|
333
|
-
return {
|
|
334
|
-
failedPlugins,
|
|
335
|
-
fabric,
|
|
336
|
-
files,
|
|
337
|
-
driver,
|
|
338
|
-
pluginTimings,
|
|
339
|
-
sources,
|
|
340
|
-
}
|
|
341
|
-
} catch (error) {
|
|
342
|
-
return {
|
|
343
|
-
failedPlugins,
|
|
344
|
-
fabric,
|
|
345
|
-
files: [],
|
|
346
|
-
driver,
|
|
347
|
-
pluginTimings,
|
|
348
|
-
error: error as Error,
|
|
349
|
-
sources,
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
type BuildBarrelExportsParams = {
|
|
355
|
-
barrelFiles: KubbFile.ResolvedFile[]
|
|
356
|
-
rootDir: string
|
|
357
|
-
existingExports: Set<string>
|
|
358
|
-
config: Config
|
|
359
|
-
driver: PluginDriver
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function buildBarrelExports({ barrelFiles, rootDir, existingExports, config, driver }: BuildBarrelExportsParams): KubbFile.Export[] {
|
|
363
|
-
const pluginNameMap = new Map<string, Plugin>()
|
|
364
|
-
for (const plugin of driver.plugins) {
|
|
365
|
-
pluginNameMap.set(plugin.name, plugin)
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
return barrelFiles.flatMap((file) => {
|
|
369
|
-
const containsOnlyTypes = file.sources?.every((source) => source.isTypeOnly)
|
|
370
|
-
|
|
371
|
-
return (file.sources ?? []).flatMap((source) => {
|
|
372
|
-
if (!file.path || !source.isIndexable) {
|
|
373
|
-
return []
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const meta = file.meta as FileMetaBase | undefined
|
|
377
|
-
const plugin = meta?.pluginName ? pluginNameMap.get(meta.pluginName) : undefined
|
|
378
|
-
const pluginOptions = plugin?.options as { output?: Output<unknown> } | undefined
|
|
379
|
-
|
|
380
|
-
if (!pluginOptions || pluginOptions.output?.barrelType === false) {
|
|
381
|
-
return []
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
const exportName = config.output.barrelType === 'all' ? undefined : source.name ? [source.name] : undefined
|
|
385
|
-
if (exportName?.some((n) => existingExports.has(n))) {
|
|
386
|
-
return []
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return [
|
|
390
|
-
{
|
|
391
|
-
name: exportName,
|
|
392
|
-
path: getRelativePath(rootDir, file.path),
|
|
393
|
-
isTypeOnly: config.output.barrelType === 'all' ? containsOnlyTypes : source.isTypeOnly,
|
|
394
|
-
} satisfies KubbFile.Export,
|
|
395
|
-
]
|
|
396
|
-
})
|
|
397
|
-
})
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* Maps the resolved `Config['input']` shape into an `AdapterSource` that
|
|
402
|
-
* the adapter's `parse()` can consume.
|
|
403
|
-
*/
|
|
404
|
-
function inputToAdapterSource(config: Config): AdapterSource {
|
|
405
|
-
if (Array.isArray(config.input)) {
|
|
406
|
-
return {
|
|
407
|
-
type: 'paths',
|
|
408
|
-
paths: config.input.map((i) => resolve(config.root, i.path)),
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if ('data' in config.input) {
|
|
413
|
-
return { type: 'data', data: config.input.data }
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const resolved = resolve(config.root, config.input.path)
|
|
417
|
-
return { type: 'path', path: resolved }
|
|
418
|
-
}
|
package/src/config.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { PossiblePromise } from '@internals/utils'
|
|
2
|
-
import type { InputPath, UserConfig } from './types.ts'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* CLI options derived from command-line flags.
|
|
6
|
-
*/
|
|
7
|
-
export type CLIOptions = {
|
|
8
|
-
/** Path to `kubb.config.js` */
|
|
9
|
-
config?: string
|
|
10
|
-
|
|
11
|
-
/** Enable watch mode for input files */
|
|
12
|
-
watch?: boolean
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Logging verbosity for CLI usage.
|
|
16
|
-
*
|
|
17
|
-
* - `silent`: hide non-essential logs
|
|
18
|
-
* - `info`: show general logs (non-plugin-related)
|
|
19
|
-
* - `debug`: include detailed plugin lifecycle logs
|
|
20
|
-
* @default 'silent'
|
|
21
|
-
*/
|
|
22
|
-
logLevel?: 'silent' | 'info' | 'debug'
|
|
23
|
-
|
|
24
|
-
/** Run Kubb with Bun */
|
|
25
|
-
bun?: boolean
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** All accepted forms of a Kubb configuration. */
|
|
29
|
-
export type ConfigInput = PossiblePromise<UserConfig | UserConfig[]> | ((cli: CLIOptions) => PossiblePromise<UserConfig | UserConfig[]>)
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Helper for defining a Kubb configuration.
|
|
33
|
-
*
|
|
34
|
-
* Accepts either:
|
|
35
|
-
* - A config object or array of configs
|
|
36
|
-
* - A function returning the config(s), optionally async,
|
|
37
|
-
* receiving the CLI options as argument
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* export default defineConfig(({ logLevel }) => ({
|
|
41
|
-
* root: 'src',
|
|
42
|
-
* plugins: [myPlugin()],
|
|
43
|
-
* }))
|
|
44
|
-
*/
|
|
45
|
-
export function defineConfig(config: (cli: CLIOptions) => PossiblePromise<UserConfig | UserConfig[]>): typeof config
|
|
46
|
-
export function defineConfig(config: PossiblePromise<UserConfig | UserConfig[]>): typeof config
|
|
47
|
-
export function defineConfig(config: ConfigInput): ConfigInput {
|
|
48
|
-
return config
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Type guard to check if a given config has an `input.path`.
|
|
53
|
-
*/
|
|
54
|
-
export function isInputPath(config: UserConfig | undefined): config is UserConfig<InputPath> {
|
|
55
|
-
return typeof config?.input === 'object' && config.input !== null && 'path' in config.input
|
|
56
|
-
}
|
package/src/createPlugin.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { PluginFactoryOptions, UserPluginWithLifeCycle } from './types.ts'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Builder type for a {@link UserPluginWithLifeCycle} — takes options and returns the plugin instance.
|
|
5
|
-
*/
|
|
6
|
-
type PluginBuilder<T extends PluginFactoryOptions = PluginFactoryOptions> = (options: T['options']) => UserPluginWithLifeCycle<T>
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Creates a plugin factory. Call the returned function with optional options to get the plugin instance.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* export const myPlugin = createPlugin<MyPlugin>((options) => {
|
|
13
|
-
* return {
|
|
14
|
-
* name: 'my-plugin',
|
|
15
|
-
* options,
|
|
16
|
-
* resolvePath(baseName) { ... },
|
|
17
|
-
* resolveName(name, type) { ... },
|
|
18
|
-
* }
|
|
19
|
-
* })
|
|
20
|
-
*
|
|
21
|
-
* // instantiate
|
|
22
|
-
* const plugin = myPlugin({ output: { path: 'src/gen' } })
|
|
23
|
-
*/
|
|
24
|
-
export function createPlugin<T extends PluginFactoryOptions = PluginFactoryOptions>(
|
|
25
|
-
build: PluginBuilder<T>,
|
|
26
|
-
): (options?: T['options']) => UserPluginWithLifeCycle<T> {
|
|
27
|
-
return (options) => build(options ?? ({} as T['options']))
|
|
28
|
-
}
|
package/src/hooks/index.ts
DELETED
package/src/hooks/useKubb.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import type { RootNode } from '@kubb/ast/types'
|
|
3
|
-
import type { KubbFile } from '@kubb/fabric-core/types'
|
|
4
|
-
import { useFabric } from '@kubb/react-fabric'
|
|
5
|
-
import type { GetFileOptions, PluginDriver } from '../PluginDriver.ts'
|
|
6
|
-
import type { Config, Plugin, PluginFactoryOptions, ResolveNameParams, ResolvePathParams } from '../types.ts'
|
|
7
|
-
|
|
8
|
-
type ResolvePathOptions = {
|
|
9
|
-
pluginName?: string
|
|
10
|
-
group?: {
|
|
11
|
-
tag?: string
|
|
12
|
-
path?: string
|
|
13
|
-
}
|
|
14
|
-
type?: ResolveNameParams['type']
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type UseKubbReturn<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
18
|
-
plugin: Plugin<TOptions>
|
|
19
|
-
mode: KubbFile.Mode
|
|
20
|
-
config: Config
|
|
21
|
-
/**
|
|
22
|
-
* Returns the plugin whose `name` matches `pluginName`, defaulting to the current plugin.
|
|
23
|
-
*/
|
|
24
|
-
getPluginByName: (pluginName?: string) => Plugin | undefined
|
|
25
|
-
/**
|
|
26
|
-
* Resolves a file reference, defaulting `pluginName` to the current plugin.
|
|
27
|
-
*/
|
|
28
|
-
getFile: (params: Omit<GetFileOptions<ResolvePathOptions>, 'pluginName'> & { pluginName?: string }) => KubbFile.File<{ pluginName: string }>
|
|
29
|
-
/**
|
|
30
|
-
* Resolves a name, defaulting `pluginName` to the current plugin.
|
|
31
|
-
*/
|
|
32
|
-
resolveName: (params: Omit<ResolveNameParams, 'pluginName'> & { pluginName?: string }) => string
|
|
33
|
-
/**
|
|
34
|
-
* Resolves a path, defaulting `pluginName` to the current plugin.
|
|
35
|
-
*/
|
|
36
|
-
resolvePath: <TPathOptions = object>(params: Omit<ResolvePathParams<TPathOptions>, 'pluginName'> & { pluginName?: string }) => KubbFile.Path
|
|
37
|
-
/**
|
|
38
|
-
* Resolves the banner using the plugin's `output.banner` option.
|
|
39
|
-
* Falls back to the default "Generated by Kubb" banner when `output.banner` is unset.
|
|
40
|
-
* When `output.banner` is a function and no node is provided, returns the default banner.
|
|
41
|
-
*/
|
|
42
|
-
resolveBanner: (node?: RootNode) => string | undefined
|
|
43
|
-
/**
|
|
44
|
-
* Resolves the footer using the plugin's `output.footer` option.
|
|
45
|
-
* Returns `undefined` when no footer is configured.
|
|
46
|
-
* When `output.footer` is a function and no node is provided, returns `undefined`.
|
|
47
|
-
*/
|
|
48
|
-
resolveFooter: (node?: RootNode) => string | undefined
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Generates the default "Generated by Kubb" banner from node metadata.
|
|
53
|
-
*/
|
|
54
|
-
function buildDefaultBanner({ title, description, version, config }: { title?: string; description?: string; version?: string; config: Config }): string {
|
|
55
|
-
try {
|
|
56
|
-
let source = ''
|
|
57
|
-
if (Array.isArray(config.input)) {
|
|
58
|
-
const first = config.input[0]
|
|
59
|
-
if (first && 'path' in first) {
|
|
60
|
-
source = path.basename(first.path)
|
|
61
|
-
}
|
|
62
|
-
} else if ('path' in config.input) {
|
|
63
|
-
source = path.basename(config.input.path)
|
|
64
|
-
} else if ('data' in config.input) {
|
|
65
|
-
source = 'text content'
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
let banner = '/**\n* Generated by Kubb (https://kubb.dev/).\n* Do not edit manually.\n'
|
|
69
|
-
|
|
70
|
-
if (config.output.defaultBanner === 'simple') {
|
|
71
|
-
banner += '*/\n'
|
|
72
|
-
return banner
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (source) {
|
|
76
|
-
banner += `* Source: ${source}\n`
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (title) {
|
|
80
|
-
banner += `* Title: ${title}\n`
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (description) {
|
|
84
|
-
const formattedDescription = description.replace(/\n/gm, '\n* ')
|
|
85
|
-
banner += `* Description: ${formattedDescription}\n`
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (version) {
|
|
89
|
-
banner += `* OpenAPI spec version: ${version}\n`
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
banner += '*/\n'
|
|
93
|
-
return banner
|
|
94
|
-
} catch (_error) {
|
|
95
|
-
return '/**\n* Generated by Kubb (https://kubb.dev/).\n* Do not edit manually.\n*/'
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function useKubb<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(): UseKubbReturn<TOptions> {
|
|
100
|
-
const { meta } = useFabric<{
|
|
101
|
-
plugin: Plugin<TOptions>
|
|
102
|
-
mode: KubbFile.Mode
|
|
103
|
-
driver: PluginDriver
|
|
104
|
-
}>()
|
|
105
|
-
|
|
106
|
-
const config = meta.driver.config
|
|
107
|
-
const defaultPluginName = meta.plugin.name
|
|
108
|
-
|
|
109
|
-
const output = (
|
|
110
|
-
meta.plugin.options as { output?: { banner?: string | ((node: RootNode) => string); footer?: string | ((node: RootNode) => string) } } | undefined
|
|
111
|
-
)?.output
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
plugin: meta.plugin as Plugin<TOptions>,
|
|
115
|
-
mode: meta.mode,
|
|
116
|
-
config,
|
|
117
|
-
getPluginByName: (pluginName = defaultPluginName) => meta.driver.getPluginByName.call(meta.driver, pluginName),
|
|
118
|
-
getFile: ({ pluginName = defaultPluginName, ...rest }) => meta.driver.getFile.call(meta.driver, { pluginName, ...rest }),
|
|
119
|
-
resolveName: ({ pluginName = defaultPluginName, ...rest }) => meta.driver.resolveName.call(meta.driver, { pluginName, ...rest }),
|
|
120
|
-
resolvePath: ({ pluginName = defaultPluginName, ...rest }) => meta.driver.resolvePath.call(meta.driver, { pluginName, ...rest }),
|
|
121
|
-
resolveBanner: (node?: RootNode) => {
|
|
122
|
-
if (typeof output?.banner === 'function') {
|
|
123
|
-
return node ? output.banner(node) : buildDefaultBanner({ config })
|
|
124
|
-
}
|
|
125
|
-
if (typeof output?.banner === 'string') {
|
|
126
|
-
return output.banner
|
|
127
|
-
}
|
|
128
|
-
if (config.output.defaultBanner === false) {
|
|
129
|
-
return undefined
|
|
130
|
-
}
|
|
131
|
-
return buildDefaultBanner({ config })
|
|
132
|
-
},
|
|
133
|
-
resolveFooter: (node?: RootNode) => {
|
|
134
|
-
if (typeof output?.footer === 'function') {
|
|
135
|
-
return node ? output.footer(node) : undefined
|
|
136
|
-
}
|
|
137
|
-
if (typeof output?.footer === 'string') {
|
|
138
|
-
return output.footer
|
|
139
|
-
}
|
|
140
|
-
return undefined
|
|
141
|
-
},
|
|
142
|
-
}
|
|
143
|
-
}
|
package/src/hooks/useMode.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { KubbFile } from '@kubb/fabric-core/types'
|
|
2
|
-
import { useFabric } from '@kubb/react-fabric'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated use `useKubb` instead
|
|
6
|
-
*/
|
|
7
|
-
export function useMode(): KubbFile.Mode {
|
|
8
|
-
const { meta } = useFabric<{ mode: KubbFile.Mode }>()
|
|
9
|
-
|
|
10
|
-
return meta.mode
|
|
11
|
-
}
|
package/src/hooks/usePlugin.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { useFabric } from '@kubb/react-fabric'
|
|
2
|
-
import type { Plugin, PluginFactoryOptions } from '../types.ts'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated use useKubb instead
|
|
6
|
-
*/
|
|
7
|
-
export function usePlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(): Plugin<TOptions> {
|
|
8
|
-
const { meta } = useFabric<{ plugin: Plugin<TOptions> }>()
|
|
9
|
-
|
|
10
|
-
return meta.plugin
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { useFabric } from '@kubb/react-fabric'
|
|
2
|
-
import type { PluginDriver } from '../PluginDriver.ts'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated use `useKubb` instead
|
|
6
|
-
*/
|
|
7
|
-
export function usePluginDriver(): PluginDriver {
|
|
8
|
-
const { meta } = useFabric<{ driver: PluginDriver }>()
|
|
9
|
-
|
|
10
|
-
return meta.driver
|
|
11
|
-
}
|