@kubb/core 5.0.0-alpha.21 → 5.0.0-alpha.23
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/dist/{PluginDriver-CEQPafXV.d.ts → PluginDriver-P920mak9.d.ts} +135 -54
- package/dist/hooks.cjs +3 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +6 -3
- package/dist/hooks.js +3 -0
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +135 -228
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +26 -69
- package/dist/index.js +136 -227
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/Kubb.ts +5 -5
- package/src/PluginDriver.ts +110 -154
- package/src/build.ts +11 -11
- package/src/constants.ts +2 -12
- package/src/defineGenerator.ts +29 -7
- package/src/defineResolver.ts +13 -19
- package/src/hooks/useDriver.ts +3 -0
- package/src/hooks/useMode.ts +3 -3
- package/src/index.ts +0 -2
- package/src/renderNode.tsx +9 -6
- package/src/types.ts +67 -35
- package/src/utils/TreeNode.ts +22 -7
- package/src/utils/getBarrelFiles.ts +9 -6
- package/src/utils/getConfigs.ts +1 -1
- package/src/utils/getPreset.ts +3 -3
- package/src/utils/mergeResolvers.ts +9 -1
- package/src/defineBuilder.ts +0 -26
- package/src/definePreset.ts +0 -27
package/src/defineGenerator.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { OperationNode, SchemaNode } from '@kubb/ast/types'
|
|
2
|
-
import type {
|
|
2
|
+
import type { FabricFile } from '@kubb/fabric-core/types'
|
|
3
3
|
import type { FabricReactNode } from '@kubb/react-fabric/types'
|
|
4
|
+
import type { PluginDriver } from './PluginDriver.ts'
|
|
4
5
|
import type { Adapter, Config, Plugin, PluginFactoryOptions } from './types.ts'
|
|
5
6
|
|
|
6
7
|
export type Version = '1' | '2'
|
|
@@ -12,7 +13,9 @@ export type OperationsV2Props<TPlugin extends PluginFactoryOptions = PluginFacto
|
|
|
12
13
|
config: Config
|
|
13
14
|
plugin: Plugin<TPlugin>
|
|
14
15
|
adapter: Adapter
|
|
16
|
+
driver: PluginDriver
|
|
15
17
|
options: Plugin<TPlugin>['options']
|
|
18
|
+
resolver: TPlugin['resolver']
|
|
16
19
|
nodes: Array<OperationNode>
|
|
17
20
|
}
|
|
18
21
|
|
|
@@ -22,8 +25,10 @@ export type OperationsV2Props<TPlugin extends PluginFactoryOptions = PluginFacto
|
|
|
22
25
|
export type OperationV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
23
26
|
config: Config
|
|
24
27
|
adapter: Adapter
|
|
28
|
+
driver: PluginDriver
|
|
25
29
|
plugin: Plugin<TPlugin>
|
|
26
30
|
options: Plugin<TPlugin>['options']
|
|
31
|
+
resolver: TPlugin['resolver']
|
|
27
32
|
node: OperationNode
|
|
28
33
|
}
|
|
29
34
|
|
|
@@ -33,20 +38,28 @@ export type OperationV2Props<TPlugin extends PluginFactoryOptions = PluginFactor
|
|
|
33
38
|
export type SchemaV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
34
39
|
config: Config
|
|
35
40
|
adapter: Adapter
|
|
41
|
+
driver: PluginDriver
|
|
36
42
|
plugin: Plugin<TPlugin>
|
|
37
43
|
options: Plugin<TPlugin>['options']
|
|
44
|
+
resolver: TPlugin['resolver']
|
|
38
45
|
node: SchemaNode
|
|
39
46
|
}
|
|
40
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Input shape for a core v2 async generator — lifecycle methods are optional.
|
|
50
|
+
*/
|
|
41
51
|
type UserCoreGeneratorV2<TPlugin extends PluginFactoryOptions> = {
|
|
42
52
|
name: string
|
|
43
53
|
type: 'core'
|
|
44
54
|
version?: '2'
|
|
45
|
-
operations?(props: OperationsV2Props<TPlugin>): Promise<Array<
|
|
46
|
-
operation?(props: OperationV2Props<TPlugin>): Promise<Array<
|
|
47
|
-
schema?(props: SchemaV2Props<TPlugin>): Promise<Array<
|
|
55
|
+
operations?(props: OperationsV2Props<TPlugin>): Promise<Array<FabricFile.File>>
|
|
56
|
+
operation?(props: OperationV2Props<TPlugin>): Promise<Array<FabricFile.File>>
|
|
57
|
+
schema?(props: SchemaV2Props<TPlugin>): Promise<Array<FabricFile.File>>
|
|
48
58
|
}
|
|
49
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Input shape for a React v2 generator — component methods are optional.
|
|
62
|
+
*/
|
|
50
63
|
type UserReactGeneratorV2<TPlugin extends PluginFactoryOptions> = {
|
|
51
64
|
name: string
|
|
52
65
|
type: 'react'
|
|
@@ -56,15 +69,21 @@ type UserReactGeneratorV2<TPlugin extends PluginFactoryOptions> = {
|
|
|
56
69
|
Schema?(props: SchemaV2Props<TPlugin>): FabricReactNode
|
|
57
70
|
}
|
|
58
71
|
|
|
72
|
+
/**
|
|
73
|
+
* A fully resolved core v2 generator with `version: '2'` and guaranteed async lifecycle methods.
|
|
74
|
+
*/
|
|
59
75
|
export type CoreGeneratorV2<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
60
76
|
name: string
|
|
61
77
|
type: 'core'
|
|
62
78
|
version: '2'
|
|
63
|
-
operations(props: OperationsV2Props<TPlugin>): Promise<Array<
|
|
64
|
-
operation(props: OperationV2Props<TPlugin>): Promise<Array<
|
|
65
|
-
schema(props: SchemaV2Props<TPlugin>): Promise<Array<
|
|
79
|
+
operations(props: OperationsV2Props<TPlugin>): Promise<Array<FabricFile.File>>
|
|
80
|
+
operation(props: OperationV2Props<TPlugin>): Promise<Array<FabricFile.File>>
|
|
81
|
+
schema(props: SchemaV2Props<TPlugin>): Promise<Array<FabricFile.File>>
|
|
66
82
|
}
|
|
67
83
|
|
|
84
|
+
/**
|
|
85
|
+
* A fully resolved React v2 generator with `version: '2'` and guaranteed component methods.
|
|
86
|
+
*/
|
|
68
87
|
export type ReactGeneratorV2<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
69
88
|
name: string
|
|
70
89
|
type: 'react'
|
|
@@ -74,6 +93,9 @@ export type ReactGeneratorV2<TPlugin extends PluginFactoryOptions = PluginFactor
|
|
|
74
93
|
Schema(props: SchemaV2Props<TPlugin>): FabricReactNode
|
|
75
94
|
}
|
|
76
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Union of all v2 generator shapes accepted by the plugin system.
|
|
98
|
+
*/
|
|
77
99
|
export type Generator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = UserCoreGeneratorV2<TPlugin> | UserReactGeneratorV2<TPlugin>
|
|
78
100
|
|
|
79
101
|
/**
|
package/src/defineResolver.ts
CHANGED
|
@@ -2,7 +2,7 @@ import path from 'node:path'
|
|
|
2
2
|
import { camelCase, pascalCase } from '@internals/utils'
|
|
3
3
|
import { isOperationNode, isSchemaNode } from '@kubb/ast'
|
|
4
4
|
import type { Node, OperationNode, RootNode, SchemaNode } from '@kubb/ast/types'
|
|
5
|
-
import type {
|
|
5
|
+
import type { FabricFile } from '@kubb/fabric-core/types'
|
|
6
6
|
import { getMode } from './PluginDriver.ts'
|
|
7
7
|
import type {
|
|
8
8
|
Config,
|
|
@@ -193,33 +193,27 @@ export function defaultResolveOptions<TOptions>(
|
|
|
193
193
|
* // → '/src/types'
|
|
194
194
|
* ```
|
|
195
195
|
*/
|
|
196
|
-
export function defaultResolvePath(
|
|
196
|
+
export function defaultResolvePath(
|
|
197
|
+
{ baseName, pathMode, tag, path: groupPath }: ResolverPathParams,
|
|
198
|
+
{ root, output, group }: ResolverContext,
|
|
199
|
+
): FabricFile.Path {
|
|
197
200
|
const mode = pathMode ?? getMode(path.resolve(root, output.path))
|
|
198
201
|
|
|
199
202
|
if (mode === 'single') {
|
|
200
|
-
return path.resolve(root, output.path) as
|
|
203
|
+
return path.resolve(root, output.path) as FabricFile.Path
|
|
201
204
|
}
|
|
202
205
|
|
|
203
206
|
if (group && (groupPath || tag)) {
|
|
204
|
-
|
|
205
|
-
? group.name
|
|
206
|
-
: (ctx: { group: string }) => {
|
|
207
|
-
if (group.type === 'path') {
|
|
208
|
-
return `${ctx.group.split('/')[1]}`
|
|
209
|
-
}
|
|
210
|
-
return `${camelCase(ctx.group)}Controller`
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return path.resolve(root, output.path, groupName({ group: group.type === 'path' ? groupPath! : tag! }), baseName) as KubbFile.Path
|
|
207
|
+
return path.resolve(root, output.path, group.name({ group: group.type === 'path' ? groupPath! : tag! }), baseName) as FabricFile.Path
|
|
214
208
|
}
|
|
215
209
|
|
|
216
|
-
return path.resolve(root, output.path, baseName) as
|
|
210
|
+
return path.resolve(root, output.path, baseName) as FabricFile.Path
|
|
217
211
|
}
|
|
218
212
|
|
|
219
213
|
/**
|
|
220
214
|
* Default file resolver used by `defineResolver`.
|
|
221
215
|
*
|
|
222
|
-
* Resolves a `
|
|
216
|
+
* Resolves a `FabricFile.File` by combining name resolution (`resolver.default`) with
|
|
223
217
|
* path resolution (`resolver.resolvePath`). The resolved file always has empty
|
|
224
218
|
* `sources`, `imports`, and `exports` arrays — consumers populate those separately.
|
|
225
219
|
*
|
|
@@ -243,15 +237,15 @@ export function defaultResolvePath({ baseName, pathMode, tag, path: groupPath }:
|
|
|
243
237
|
* // → { baseName: 'listPets.ts', path: '/src/types/petsController/listPets.ts', ... }
|
|
244
238
|
* ```
|
|
245
239
|
*/
|
|
246
|
-
export function defaultResolveFile(this: Resolver, { name, extname, tag, path: groupPath }: ResolverFileParams, context: ResolverContext):
|
|
240
|
+
export function defaultResolveFile(this: Resolver, { name, extname, tag, path: groupPath }: ResolverFileParams, context: ResolverContext): FabricFile.File {
|
|
247
241
|
const pathMode = getMode(path.resolve(context.root, context.output.path))
|
|
248
242
|
const resolvedName = pathMode === 'single' ? '' : this.default(name, 'file')
|
|
249
|
-
const baseName = `${resolvedName}${extname}` as
|
|
243
|
+
const baseName = `${resolvedName}${extname}` as FabricFile.BaseName
|
|
250
244
|
const filePath = this.resolvePath({ baseName, pathMode, tag, path: groupPath }, context)
|
|
251
245
|
|
|
252
246
|
return {
|
|
253
247
|
path: filePath,
|
|
254
|
-
baseName: path.basename(filePath) as
|
|
248
|
+
baseName: path.basename(filePath) as FabricFile.BaseName,
|
|
255
249
|
meta: {
|
|
256
250
|
pluginName: this.pluginName,
|
|
257
251
|
},
|
|
@@ -397,7 +391,7 @@ export function defaultResolveFooter(node: RootNode | undefined, { output }: Res
|
|
|
397
391
|
* - `default` — name casing strategy (camelCase / PascalCase)
|
|
398
392
|
* - `resolveOptions` — include/exclude/override filtering
|
|
399
393
|
* - `resolvePath` — output path computation
|
|
400
|
-
* - `resolveFile` — full `
|
|
394
|
+
* - `resolveFile` — full `FabricFile.File` construction
|
|
401
395
|
*
|
|
402
396
|
* Methods in the builder have access to `this` (the full resolver object), so they
|
|
403
397
|
* can call other resolver methods without circular imports.
|
package/src/hooks/useDriver.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useFabric } from '@kubb/react-fabric'
|
|
2
2
|
import type { PluginDriver } from '../PluginDriver.ts'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated use `driver` from the generator component props instead
|
|
6
|
+
*/
|
|
4
7
|
export function useDriver(): PluginDriver {
|
|
5
8
|
const { meta } = useFabric<{ driver: PluginDriver }>()
|
|
6
9
|
|
package/src/hooks/useMode.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FabricFile } from '@kubb/fabric-core/types'
|
|
2
2
|
import { useFabric } from '@kubb/react-fabric'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @deprecated use `mode` from the generator component props instead
|
|
6
6
|
*/
|
|
7
|
-
export function useMode():
|
|
8
|
-
const { meta } = useFabric<{ mode:
|
|
7
|
+
export function useMode(): FabricFile.Mode {
|
|
8
|
+
const { meta } = useFabric<{ mode: FabricFile.Mode }>()
|
|
9
9
|
|
|
10
10
|
return meta.mode
|
|
11
11
|
}
|
package/src/index.ts
CHANGED
|
@@ -6,10 +6,8 @@ export { formatters, linters, logLevel } from './constants.ts'
|
|
|
6
6
|
export { createAdapter } from './createAdapter.ts'
|
|
7
7
|
export { createPlugin } from './createPlugin.ts'
|
|
8
8
|
export { createStorage } from './createStorage.ts'
|
|
9
|
-
export { defineBuilder } from './defineBuilder.ts'
|
|
10
9
|
export { defineGenerator } from './defineGenerator.ts'
|
|
11
10
|
export { defineLogger } from './defineLogger.ts'
|
|
12
|
-
export { definePreset } from './definePreset.ts'
|
|
13
11
|
export { definePresets } from './definePresets.ts'
|
|
14
12
|
export {
|
|
15
13
|
buildDefaultBanner,
|
package/src/renderNode.tsx
CHANGED
|
@@ -12,6 +12,7 @@ type BuildOperationsV2Options<TOptions extends PluginFactoryOptions> = {
|
|
|
12
12
|
adapter: Adapter
|
|
13
13
|
driver: PluginDriver
|
|
14
14
|
options: TOptions['resolvedOptions']
|
|
15
|
+
resolver: TOptions['resolver']
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -30,8 +31,8 @@ export async function renderOperations<TOptions extends PluginFactoryOptions>(
|
|
|
30
31
|
const fabricChild = createReactFabric()
|
|
31
32
|
|
|
32
33
|
await fabricChild.render(
|
|
33
|
-
<Fabric
|
|
34
|
-
<Component config={config} plugin={plugin} adapter={adapter} nodes={nodes} options={options.options} />
|
|
34
|
+
<Fabric>
|
|
35
|
+
<Component config={config} plugin={plugin} driver={driver} adapter={adapter} nodes={nodes} options={options.options} resolver={options.resolver} />
|
|
35
36
|
</Fabric>,
|
|
36
37
|
)
|
|
37
38
|
|
|
@@ -47,6 +48,7 @@ type BuildOperationV2Options<TOptions extends PluginFactoryOptions> = {
|
|
|
47
48
|
adapter: Adapter
|
|
48
49
|
driver: PluginDriver
|
|
49
50
|
options: TOptions['resolvedOptions']
|
|
51
|
+
resolver: TOptions['resolver']
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
/**
|
|
@@ -62,8 +64,8 @@ export async function renderOperation<TOptions extends PluginFactoryOptions>(nod
|
|
|
62
64
|
const fabricChild = createReactFabric()
|
|
63
65
|
|
|
64
66
|
await fabricChild.render(
|
|
65
|
-
<Fabric
|
|
66
|
-
<Component config={config} plugin={plugin} adapter={adapter} node={node} options={options.options} />
|
|
67
|
+
<Fabric>
|
|
68
|
+
<Component config={config} plugin={plugin} driver={driver} adapter={adapter} node={node} options={options.options} resolver={options.resolver} />
|
|
67
69
|
</Fabric>,
|
|
68
70
|
)
|
|
69
71
|
|
|
@@ -79,6 +81,7 @@ type BuildSchemaV2Options<TOptions extends PluginFactoryOptions> = {
|
|
|
79
81
|
adapter: Adapter
|
|
80
82
|
driver: PluginDriver
|
|
81
83
|
options: TOptions['resolvedOptions']
|
|
84
|
+
resolver: TOptions['resolver']
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
/**
|
|
@@ -94,8 +97,8 @@ export async function renderSchema<TOptions extends PluginFactoryOptions>(node:
|
|
|
94
97
|
const fabricChild = createReactFabric()
|
|
95
98
|
|
|
96
99
|
await fabricChild.render(
|
|
97
|
-
<Fabric
|
|
98
|
-
<Component config={config} plugin={plugin} adapter={adapter} node={node} options={options.options} />
|
|
100
|
+
<Fabric>
|
|
101
|
+
<Component config={config} plugin={plugin} driver={driver} adapter={adapter} node={node} options={options.options} resolver={options.resolver} />
|
|
99
102
|
</Fabric>,
|
|
100
103
|
)
|
|
101
104
|
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AsyncEventEmitter, PossiblePromise } from '@internals/utils'
|
|
2
2
|
import type { Node, RootNode, SchemaNode, Visitor } from '@kubb/ast/types'
|
|
3
|
-
import type { Fabric as FabricType
|
|
3
|
+
import type { FabricFile, Fabric as FabricType } from '@kubb/fabric-core/types'
|
|
4
4
|
import type { HttpMethod } from '@kubb/oas'
|
|
5
5
|
import type { DEFAULT_STUDIO_URL, logLevel } from './constants.ts'
|
|
6
6
|
import type { Storage } from './createStorage.ts'
|
|
@@ -119,13 +119,13 @@ export type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptio
|
|
|
119
119
|
*/
|
|
120
120
|
parse: (source: AdapterSource) => PossiblePromise<RootNode>
|
|
121
121
|
/**
|
|
122
|
-
* Extracts `
|
|
122
|
+
* Extracts `FabricFile.Import` entries needed by a `SchemaNode` tree.
|
|
123
123
|
* Populated after the first `parse()` call. Returns an empty array before that.
|
|
124
124
|
*
|
|
125
125
|
* The `resolve` callback receives the collision-corrected schema name and must
|
|
126
126
|
* return the `{ name, path }` pair for the import, or `undefined` to skip it.
|
|
127
127
|
*/
|
|
128
|
-
getImports: (node: SchemaNode, resolve: (schemaName: string) => { name: string; path: string }) => Array<
|
|
128
|
+
getImports: (node: SchemaNode, resolve: (schemaName: string) => { name: string; path: string }) => Array<FabricFile.Import>
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
export type BarrelType = 'all' | 'named' | 'propagate'
|
|
@@ -227,7 +227,7 @@ export type Config<TInput = Input> = {
|
|
|
227
227
|
* Overrides the extension for generated imports and exports. By default, each plugin adds an extension.
|
|
228
228
|
* @default { '.ts': '.ts'}
|
|
229
229
|
*/
|
|
230
|
-
extension?: Record<
|
|
230
|
+
extension?: Record<FabricFile.Extname, FabricFile.Extname | ''>
|
|
231
231
|
/**
|
|
232
232
|
* Configures how `index.ts` files are created, including disabling barrel file generation. Each plugin has its own `barrelType` option; this setting controls the root barrel file (e.g., `src/gen/index.ts`).
|
|
233
233
|
* @default 'named'
|
|
@@ -254,7 +254,7 @@ export type Config<TInput = Input> = {
|
|
|
254
254
|
* Each plugin may include additional configurable options(defined in the plugin itself).
|
|
255
255
|
* If a plugin depends on another plugin, an error is returned if the required dependency is missing. See pre for more details.
|
|
256
256
|
*/
|
|
257
|
-
plugins
|
|
257
|
+
plugins: Array<Plugin>
|
|
258
258
|
/**
|
|
259
259
|
* Devtools configuration for Kubb Studio integration.
|
|
260
260
|
*/
|
|
@@ -281,15 +281,25 @@ export type Config<TInput = Input> = {
|
|
|
281
281
|
|
|
282
282
|
// plugin
|
|
283
283
|
|
|
284
|
+
/**
|
|
285
|
+
* A type/string-pattern filter used for `include`, `exclude`, and `override` matching.
|
|
286
|
+
*/
|
|
284
287
|
type PatternFilter = {
|
|
285
288
|
type: string
|
|
286
289
|
pattern: string | RegExp
|
|
287
290
|
}
|
|
288
291
|
|
|
292
|
+
/**
|
|
293
|
+
* A pattern filter paired with partial option overrides to apply when the pattern matches.
|
|
294
|
+
*/
|
|
289
295
|
type PatternOverride<TOptions> = PatternFilter & {
|
|
290
296
|
options: Omit<Partial<TOptions>, 'override'>
|
|
291
297
|
}
|
|
292
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Context passed to `resolver.resolveOptions` to apply include/exclude/override filtering
|
|
301
|
+
* for a given operation or schema node.
|
|
302
|
+
*/
|
|
293
303
|
export type ResolveOptionsContext<TOptions> = {
|
|
294
304
|
options: TOptions
|
|
295
305
|
exclude?: Array<PatternFilter>
|
|
@@ -317,8 +327,8 @@ export type Resolver = {
|
|
|
317
327
|
pluginName: Plugin['name']
|
|
318
328
|
default(name: ResolveNameParams['name'], type?: ResolveNameParams['type']): string
|
|
319
329
|
resolveOptions<TOptions>(node: Node, context: ResolveOptionsContext<TOptions>): TOptions | null
|
|
320
|
-
resolvePath(params: ResolverPathParams, context: ResolverContext):
|
|
321
|
-
resolveFile(params: ResolverFileParams, context: ResolverContext):
|
|
330
|
+
resolvePath(params: ResolverPathParams, context: ResolverContext): FabricFile.Path
|
|
331
|
+
resolveFile(params: ResolverFileParams, context: ResolverContext): FabricFile.File
|
|
322
332
|
resolveBanner(node: RootNode | null, context: ResolveBannerContext): string | undefined
|
|
323
333
|
resolveFooter(node: RootNode | null, context: ResolveBannerContext): string | undefined
|
|
324
334
|
}
|
|
@@ -339,15 +349,6 @@ export type Resolver = {
|
|
|
339
349
|
*/
|
|
340
350
|
export type UserResolver = Omit<Resolver, 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter'>
|
|
341
351
|
|
|
342
|
-
/**
|
|
343
|
-
* Base type for plugin builder objects.
|
|
344
|
-
* Concrete plugin builder types extend this with their own schema-building helpers.
|
|
345
|
-
* Use `defineBuilder` to define a builder object and export it alongside the plugin.
|
|
346
|
-
*/
|
|
347
|
-
export type Builder = {
|
|
348
|
-
name: string
|
|
349
|
-
}
|
|
350
|
-
|
|
351
352
|
export type PluginFactoryOptions<
|
|
352
353
|
/**
|
|
353
354
|
* Name to be used for the plugin.
|
|
@@ -374,11 +375,6 @@ export type PluginFactoryOptions<
|
|
|
374
375
|
* Use `defineResolver` to define the resolver object and export it alongside the plugin.
|
|
375
376
|
*/
|
|
376
377
|
TResolver extends Resolver = Resolver,
|
|
377
|
-
/**
|
|
378
|
-
* Builder object that encapsulates the schema-building helpers used by this plugin.
|
|
379
|
-
* Use `defineBuilder` to define the builder object and export it alongside the plugin.
|
|
380
|
-
*/
|
|
381
|
-
TBuilder extends Builder = Builder,
|
|
382
378
|
> = {
|
|
383
379
|
name: TName
|
|
384
380
|
options: TOptions
|
|
@@ -386,7 +382,6 @@ export type PluginFactoryOptions<
|
|
|
386
382
|
context: TContext
|
|
387
383
|
resolvePathOptions: TResolvePathOptions
|
|
388
384
|
resolver: TResolver
|
|
389
|
-
builder: TBuilder
|
|
390
385
|
}
|
|
391
386
|
|
|
392
387
|
export type UserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
@@ -400,6 +395,10 @@ export type UserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOpti
|
|
|
400
395
|
* Options set for a specific plugin(see kubb.config.js), passthrough of options.
|
|
401
396
|
*/
|
|
402
397
|
options: TOptions['resolvedOptions']
|
|
398
|
+
/**
|
|
399
|
+
* The resolver for this plugin, accessible via `driver.getPluginByName(name)?.resolver`.
|
|
400
|
+
*/
|
|
401
|
+
resolver?: TOptions['resolver']
|
|
403
402
|
/**
|
|
404
403
|
* Specifies the preceding plugins for the current plugin. You can pass an array of preceding plugin names, and the current plugin is executed after these plugins.
|
|
405
404
|
* Can be used to validate dependent plugins.
|
|
@@ -435,6 +434,10 @@ export type Plugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>
|
|
|
435
434
|
* Options set for a specific plugin(see kubb.config.js), passthrough of options.
|
|
436
435
|
*/
|
|
437
436
|
options: TOptions['resolvedOptions']
|
|
437
|
+
/**
|
|
438
|
+
* The resolver for this plugin, accessible via `driver.getPluginByName(name)?.resolver`.
|
|
439
|
+
*/
|
|
440
|
+
resolver: TOptions['resolver']
|
|
438
441
|
|
|
439
442
|
install: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => PossiblePromise<void>
|
|
440
443
|
/**
|
|
@@ -458,7 +461,12 @@ export type PluginLifecycle<TOptions extends PluginFactoryOptions = PluginFactor
|
|
|
458
461
|
* @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'
|
|
459
462
|
* @deprecated this will be replaced by resolvers
|
|
460
463
|
*/
|
|
461
|
-
resolvePath?: (
|
|
464
|
+
resolvePath?: (
|
|
465
|
+
this: PluginContext<TOptions>,
|
|
466
|
+
baseName: FabricFile.BaseName,
|
|
467
|
+
mode?: FabricFile.Mode,
|
|
468
|
+
options?: TOptions['resolvePathOptions'],
|
|
469
|
+
) => FabricFile.Path
|
|
462
470
|
/**
|
|
463
471
|
* Resolve to a name based on a string.
|
|
464
472
|
* Useful when converting to PascalCase or camelCase.
|
|
@@ -475,8 +483,8 @@ export type PluginParameter<H extends PluginLifecycleHooks> = Parameters<Require
|
|
|
475
483
|
|
|
476
484
|
export type ResolvePathParams<TOptions = object> = {
|
|
477
485
|
pluginName?: string
|
|
478
|
-
baseName:
|
|
479
|
-
mode?:
|
|
486
|
+
baseName: FabricFile.BaseName
|
|
487
|
+
mode?: FabricFile.Mode
|
|
480
488
|
/**
|
|
481
489
|
* Options to be passed to 'resolvePath' 3th parameter
|
|
482
490
|
*/
|
|
@@ -501,20 +509,24 @@ export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryO
|
|
|
501
509
|
fabric: FabricType
|
|
502
510
|
config: Config
|
|
503
511
|
driver: PluginDriver
|
|
512
|
+
getPlugin: PluginDriver['getPlugin']
|
|
504
513
|
/**
|
|
505
514
|
* Only add when the file does not exist yet
|
|
506
515
|
*/
|
|
507
|
-
addFile: (...file: Array<
|
|
516
|
+
addFile: (...file: Array<FabricFile.File>) => Promise<void>
|
|
508
517
|
/**
|
|
509
518
|
* merging multiple sources into the same output file
|
|
510
519
|
*/
|
|
511
|
-
upsertFile: (...file: Array<
|
|
520
|
+
upsertFile: (...file: Array<FabricFile.File>) => Promise<void>
|
|
512
521
|
events: AsyncEventEmitter<KubbEvents>
|
|
513
|
-
mode: KubbFile.Mode
|
|
514
522
|
/**
|
|
515
523
|
* Current plugin
|
|
516
524
|
*/
|
|
517
525
|
plugin: Plugin<TOptions>
|
|
526
|
+
/**
|
|
527
|
+
* Resolver for the current plugin. Shorthand for `plugin.resolver`.
|
|
528
|
+
*/
|
|
529
|
+
resolver: TOptions['resolver']
|
|
518
530
|
|
|
519
531
|
/**
|
|
520
532
|
* Opens the Kubb Studio URL for the current `rootNode` in the default browser.
|
|
@@ -568,7 +580,7 @@ export type Output<_TOptions = unknown> = {
|
|
|
568
580
|
override?: boolean
|
|
569
581
|
}
|
|
570
582
|
|
|
571
|
-
export type
|
|
583
|
+
export type UserGroup = {
|
|
572
584
|
/**
|
|
573
585
|
* Defines the type where to group the files.
|
|
574
586
|
* - 'tag' groups files by OpenAPI tags.
|
|
@@ -582,6 +594,20 @@ export type Group = {
|
|
|
582
594
|
name?: (context: { group: string }) => string
|
|
583
595
|
}
|
|
584
596
|
|
|
597
|
+
export type Group = {
|
|
598
|
+
/**
|
|
599
|
+
* Defines the type where to group the files.
|
|
600
|
+
* - 'tag' groups files by OpenAPI tags.
|
|
601
|
+
* - 'path' groups files by OpenAPI paths.
|
|
602
|
+
* @default undefined
|
|
603
|
+
*/
|
|
604
|
+
type: 'tag' | 'path'
|
|
605
|
+
/**
|
|
606
|
+
* Return the name of a group based on the group name, this is used for the file and name generation.
|
|
607
|
+
*/
|
|
608
|
+
name: (context: { group: string }) => string
|
|
609
|
+
}
|
|
610
|
+
|
|
585
611
|
export type LoggerOptions = {
|
|
586
612
|
/**
|
|
587
613
|
* @default 3
|
|
@@ -714,8 +740,8 @@ export type ResolvePathOptions = {
|
|
|
714
740
|
* ```
|
|
715
741
|
*/
|
|
716
742
|
export type ResolverPathParams = {
|
|
717
|
-
baseName:
|
|
718
|
-
pathMode?:
|
|
743
|
+
baseName: FabricFile.BaseName
|
|
744
|
+
pathMode?: FabricFile.Mode
|
|
719
745
|
/**
|
|
720
746
|
* Tag value used when `group.type === 'tag'`.
|
|
721
747
|
*/
|
|
@@ -745,7 +771,9 @@ export type ResolverContext = {
|
|
|
745
771
|
root: string
|
|
746
772
|
output: Output
|
|
747
773
|
group?: Group
|
|
748
|
-
/**
|
|
774
|
+
/**
|
|
775
|
+
* Plugin name used to populate `meta.pluginName` on the resolved file.
|
|
776
|
+
*/
|
|
749
777
|
pluginName?: string
|
|
750
778
|
}
|
|
751
779
|
|
|
@@ -766,10 +794,14 @@ export type ResolverContext = {
|
|
|
766
794
|
*/
|
|
767
795
|
export type ResolverFileParams = {
|
|
768
796
|
name: string
|
|
769
|
-
extname:
|
|
770
|
-
/**
|
|
797
|
+
extname: FabricFile.Extname
|
|
798
|
+
/**
|
|
799
|
+
* Tag value used when `group.type === 'tag'`.
|
|
800
|
+
*/
|
|
771
801
|
tag?: string
|
|
772
|
-
/**
|
|
802
|
+
/**
|
|
803
|
+
* Path value used when `group.type === 'path'`.
|
|
804
|
+
*/
|
|
773
805
|
path?: string
|
|
774
806
|
}
|
|
775
807
|
|
package/src/utils/TreeNode.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import type {
|
|
2
|
+
import type { FabricFile } from '@kubb/fabric-core/types'
|
|
3
3
|
import { getMode } from '../PluginDriver.ts'
|
|
4
4
|
|
|
5
5
|
type BarrelData = {
|
|
6
|
-
file?:
|
|
6
|
+
file?: FabricFile.File
|
|
7
7
|
/**
|
|
8
8
|
* @deprecated use file instead
|
|
9
9
|
*/
|
|
10
|
-
type:
|
|
10
|
+
type: FabricFile.Mode
|
|
11
11
|
path: string
|
|
12
12
|
name: string
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Tree structure used to build per-directory barrel (`index.ts`) files from a
|
|
17
|
-
* flat list of generated {@link
|
|
17
|
+
* flat list of generated {@link FabricFile.File} entries.
|
|
18
18
|
*
|
|
19
19
|
* Each node represents either a directory or a file within the output tree.
|
|
20
20
|
* Use {@link TreeNode.build} to construct a root node from a file list, then
|
|
@@ -76,6 +76,9 @@ export class TreeNode {
|
|
|
76
76
|
return leaves
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Visits this node and every descendant in depth-first order.
|
|
81
|
+
*/
|
|
79
82
|
forEach(callback: (treeNode: TreeNode) => void): this {
|
|
80
83
|
if (typeof callback !== 'function') {
|
|
81
84
|
throw new TypeError('forEach() callback must be a function')
|
|
@@ -90,6 +93,9 @@ export class TreeNode {
|
|
|
90
93
|
return this
|
|
91
94
|
}
|
|
92
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Finds the first leaf that satisfies `predicate`, or `undefined` when none match.
|
|
98
|
+
*/
|
|
93
99
|
findDeep(predicate?: (value: TreeNode, index: number, obj: TreeNode[]) => boolean): TreeNode | undefined {
|
|
94
100
|
if (typeof predicate !== 'function') {
|
|
95
101
|
throw new TypeError('find() predicate must be a function')
|
|
@@ -98,6 +104,9 @@ export class TreeNode {
|
|
|
98
104
|
return this.leaves.find(predicate)
|
|
99
105
|
}
|
|
100
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Calls `callback` for every leaf of this node.
|
|
109
|
+
*/
|
|
101
110
|
forEachDeep(callback: (treeNode: TreeNode) => void): void {
|
|
102
111
|
if (typeof callback !== 'function') {
|
|
103
112
|
throw new TypeError('forEach() callback must be a function')
|
|
@@ -106,6 +115,9 @@ export class TreeNode {
|
|
|
106
115
|
this.leaves.forEach(callback)
|
|
107
116
|
}
|
|
108
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Returns all leaves that satisfy `callback`.
|
|
120
|
+
*/
|
|
109
121
|
filterDeep(callback: (treeNode: TreeNode) => boolean): Array<TreeNode> {
|
|
110
122
|
if (typeof callback !== 'function') {
|
|
111
123
|
throw new TypeError('filter() callback must be a function')
|
|
@@ -114,6 +126,9 @@ export class TreeNode {
|
|
|
114
126
|
return this.leaves.filter(callback)
|
|
115
127
|
}
|
|
116
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Maps every leaf through `callback` and returns the resulting array.
|
|
131
|
+
*/
|
|
117
132
|
mapDeep<T>(callback: (treeNode: TreeNode) => T): Array<T> {
|
|
118
133
|
if (typeof callback !== 'function') {
|
|
119
134
|
throw new TypeError('map() callback must be a function')
|
|
@@ -128,7 +143,7 @@ export class TreeNode {
|
|
|
128
143
|
* - Filters to files under `root` (when provided) and skips `.json` files.
|
|
129
144
|
* - Returns `null` when no files match.
|
|
130
145
|
*/
|
|
131
|
-
public static build(files:
|
|
146
|
+
public static build(files: FabricFile.File[], root?: string): TreeNode | null {
|
|
132
147
|
try {
|
|
133
148
|
const filteredTree = buildDirectoryTree(files, root)
|
|
134
149
|
|
|
@@ -172,13 +187,13 @@ export class TreeNode {
|
|
|
172
187
|
type DirectoryTree = {
|
|
173
188
|
name: string
|
|
174
189
|
path: string
|
|
175
|
-
file?:
|
|
190
|
+
file?: FabricFile.File
|
|
176
191
|
children: Array<DirectoryTree>
|
|
177
192
|
}
|
|
178
193
|
|
|
179
194
|
const normalizePath = (p: string): string => p.replaceAll('\\', '/')
|
|
180
195
|
|
|
181
|
-
function buildDirectoryTree(files: Array<
|
|
196
|
+
function buildDirectoryTree(files: Array<FabricFile.File>, rootFolder = ''): DirectoryTree | null {
|
|
182
197
|
const normalizedRootFolder = normalizePath(rootFolder)
|
|
183
198
|
const rootPrefix = normalizedRootFolder.endsWith('/') ? normalizedRootFolder : `${normalizedRootFolder}/`
|
|
184
199
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
import { getRelativePath } from '@internals/utils'
|
|
4
|
-
import type {
|
|
4
|
+
import type { FabricFile } from '@kubb/fabric-core/types'
|
|
5
5
|
import type { BarrelType } from '../types.ts'
|
|
6
6
|
import { TreeNode } from './TreeNode.ts'
|
|
7
7
|
|
|
@@ -29,16 +29,16 @@ type AddIndexesProps = {
|
|
|
29
29
|
meta?: FileMetaBase
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function getBarrelFilesByRoot(root: string | undefined, files: Array<
|
|
33
|
-
const cachedFiles = new Map<
|
|
32
|
+
function getBarrelFilesByRoot(root: string | undefined, files: Array<FabricFile.ResolvedFile>): Array<FabricFile.File> {
|
|
33
|
+
const cachedFiles = new Map<FabricFile.Path, FabricFile.File>()
|
|
34
34
|
|
|
35
35
|
TreeNode.build(files, root)?.forEach((treeNode) => {
|
|
36
36
|
if (!treeNode?.children || !treeNode.parent?.data.path) {
|
|
37
37
|
return
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
const barrelFilePath = join(treeNode.parent?.data.path, 'index.ts') as
|
|
41
|
-
const barrelFile:
|
|
40
|
+
const barrelFilePath = join(treeNode.parent?.data.path, 'index.ts') as FabricFile.Path
|
|
41
|
+
const barrelFile: FabricFile.File = {
|
|
42
42
|
path: barrelFilePath,
|
|
43
43
|
baseName: 'index.ts',
|
|
44
44
|
exports: [],
|
|
@@ -113,7 +113,10 @@ function trimExtName(text: string): string {
|
|
|
113
113
|
* - When `type` is `'all'`, strips named exports so every re-export becomes a wildcard (`export * from`).
|
|
114
114
|
* - Attaches `meta` to each barrel file for downstream plugin identification.
|
|
115
115
|
*/
|
|
116
|
-
export async function getBarrelFiles(
|
|
116
|
+
export async function getBarrelFiles(
|
|
117
|
+
files: Array<FabricFile.ResolvedFile>,
|
|
118
|
+
{ type, meta = {}, root, output }: AddIndexesProps,
|
|
119
|
+
): Promise<Array<FabricFile.File>> {
|
|
117
120
|
if (!type || type === 'propagate') {
|
|
118
121
|
return []
|
|
119
122
|
}
|
package/src/utils/getConfigs.ts
CHANGED
|
@@ -12,5 +12,5 @@ export async function getConfigs(config: ConfigInput | UserConfig, args: CLIOpti
|
|
|
12
12
|
const resolved = await (typeof config === 'function' ? config(args as CLIOptions) : config)
|
|
13
13
|
const userConfigs = Array.isArray(resolved) ? resolved : [resolved]
|
|
14
14
|
|
|
15
|
-
return userConfigs.map((item) => ({ ...item }) as Config)
|
|
15
|
+
return userConfigs.map((item) => ({ plugins: [], ...item }) as Config)
|
|
16
16
|
}
|