@kubb/core 5.0.0-alpha.2 → 5.0.0-alpha.4
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/hooks.cjs +24 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +36 -2
- package/dist/hooks.js +24 -1
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +108 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +38 -2
- package/dist/index.js +109 -15
- package/dist/index.js.map +1 -1
- package/dist/{types-B7eZvqwD.d.ts → types-Bbh1o0yW.d.ts} +85 -9
- package/package.json +2 -2
- package/src/PluginManager.ts +32 -16
- package/src/build.ts +1 -0
- package/src/defineGenerator.ts +106 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useKubb.ts +22 -0
- package/src/hooks/useMode.ts +3 -0
- package/src/hooks/usePlugin.ts +3 -0
- package/src/hooks/usePluginManager.ts +3 -0
- package/src/index.ts +2 -0
- package/src/types.ts +29 -7
- package/src/utils/resolveOptions.ts +93 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { t as __name } from "./chunk--u3MIqq1.js";
|
|
2
2
|
import { EventEmitter } from "node:events";
|
|
3
3
|
import { Fabric } from "@kubb/react-fabric";
|
|
4
|
+
import { OperationNode, Printer, PrinterFactoryOptions, RootNode, SchemaNode } from "@kubb/ast/types";
|
|
4
5
|
import { KubbFile } from "@kubb/fabric-core/types";
|
|
5
|
-
import {
|
|
6
|
+
import { FabricReactNode } from "@kubb/react-fabric/types";
|
|
6
7
|
|
|
7
8
|
//#region ../../internals/utils/dist/index.d.ts
|
|
8
9
|
/**
|
|
@@ -226,6 +227,7 @@ declare class PluginManager {
|
|
|
226
227
|
* the build pipeline after the adapter's `parse()` resolves.
|
|
227
228
|
*/
|
|
228
229
|
rootNode: RootNode | undefined;
|
|
230
|
+
adapter: Adapter | undefined;
|
|
229
231
|
constructor(config: Config, options: Options);
|
|
230
232
|
get events(): AsyncEventEmitter<KubbEvents>;
|
|
231
233
|
getContext<TOptions extends PluginFactoryOptions>(plugin: Plugin<TOptions>): PluginContext<TOptions> & Record<string, unknown>;
|
|
@@ -529,6 +531,61 @@ interface KubbEvents {
|
|
|
529
531
|
'plugins:hook:processing:end': [meta: ExecutedMeta];
|
|
530
532
|
}
|
|
531
533
|
//#endregion
|
|
534
|
+
//#region src/defineGenerator.d.ts
|
|
535
|
+
type OperationsV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
536
|
+
config: Config;
|
|
537
|
+
adapter: Adapter;
|
|
538
|
+
options: Plugin<TPlugin>['options'];
|
|
539
|
+
nodes: Array<OperationNode>;
|
|
540
|
+
};
|
|
541
|
+
type OperationV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
542
|
+
config: Config;
|
|
543
|
+
adapter: Adapter;
|
|
544
|
+
options: Plugin<TPlugin>['options'];
|
|
545
|
+
node: OperationNode;
|
|
546
|
+
};
|
|
547
|
+
type SchemaV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
548
|
+
config: Config;
|
|
549
|
+
adapter: Adapter;
|
|
550
|
+
options: Plugin<TPlugin>['options'];
|
|
551
|
+
node: SchemaNode;
|
|
552
|
+
};
|
|
553
|
+
type UserCoreGeneratorV2<TPlugin extends PluginFactoryOptions> = {
|
|
554
|
+
name: string;
|
|
555
|
+
type: 'core';
|
|
556
|
+
version?: '2';
|
|
557
|
+
operations?(props: OperationsV2Props<TPlugin>): Promise<Array<KubbFile.File>>;
|
|
558
|
+
operation?(props: OperationV2Props<TPlugin>): Promise<Array<KubbFile.File>>;
|
|
559
|
+
schema?(props: SchemaV2Props<TPlugin>): Promise<Array<KubbFile.File>>;
|
|
560
|
+
};
|
|
561
|
+
type UserReactGeneratorV2<TPlugin extends PluginFactoryOptions> = {
|
|
562
|
+
name: string;
|
|
563
|
+
type: 'react';
|
|
564
|
+
version?: '2';
|
|
565
|
+
Operations?(props: OperationsV2Props<TPlugin>): FabricReactNode;
|
|
566
|
+
Operation?(props: OperationV2Props<TPlugin>): FabricReactNode;
|
|
567
|
+
Schema?(props: SchemaV2Props<TPlugin>): FabricReactNode;
|
|
568
|
+
};
|
|
569
|
+
type CoreGeneratorV2<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
570
|
+
name: string;
|
|
571
|
+
type: 'core';
|
|
572
|
+
version: '2';
|
|
573
|
+
operations(props: OperationsV2Props<TPlugin>): Promise<Array<KubbFile.File>>;
|
|
574
|
+
operation(props: OperationV2Props<TPlugin>): Promise<Array<KubbFile.File>>;
|
|
575
|
+
schema(props: SchemaV2Props<TPlugin>): Promise<Array<KubbFile.File>>;
|
|
576
|
+
};
|
|
577
|
+
type ReactGeneratorV2<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
578
|
+
name: string;
|
|
579
|
+
type: 'react';
|
|
580
|
+
version: '2';
|
|
581
|
+
Operations(props: OperationsV2Props<TPlugin>): FabricReactNode;
|
|
582
|
+
Operation(props: OperationV2Props<TPlugin>): FabricReactNode;
|
|
583
|
+
Schema(props: SchemaV2Props<TPlugin>): FabricReactNode;
|
|
584
|
+
};
|
|
585
|
+
type Generator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = UserCoreGeneratorV2<TPlugin> | UserReactGeneratorV2<TPlugin>;
|
|
586
|
+
declare function defineGenerator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions>(generator: UserReactGeneratorV2<TPlugin>): ReactGeneratorV2<TPlugin>;
|
|
587
|
+
declare function defineGenerator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions>(generator: UserCoreGeneratorV2<TPlugin>): CoreGeneratorV2<TPlugin>;
|
|
588
|
+
//#endregion
|
|
532
589
|
//#region src/types.d.ts
|
|
533
590
|
declare global {
|
|
534
591
|
namespace Kubb {
|
|
@@ -617,6 +674,17 @@ type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
|
|
|
617
674
|
/** Human-readable identifier, e.g. `'oas'`, `'drizzle'`, `'asyncapi'`. */name: TOptions['name']; /** Resolved options (after defaults have been applied). */
|
|
618
675
|
options: TOptions['resolvedOptions']; /** Convert the raw source into a universal `RootNode`. */
|
|
619
676
|
parse: (source: AdapterSource) => PossiblePromise<RootNode>;
|
|
677
|
+
/**
|
|
678
|
+
* Extracts `KubbFile.Import` entries needed by a `SchemaNode` tree.
|
|
679
|
+
* Populated after the first `parse()` call. Returns an empty array before that.
|
|
680
|
+
*
|
|
681
|
+
* The `resolve` callback receives the collision-corrected schema name and must
|
|
682
|
+
* return the `{ name, path }` pair for the import, or `undefined` to skip it.
|
|
683
|
+
*/
|
|
684
|
+
getImports: (node: SchemaNode, resolve: (schemaName: string) => {
|
|
685
|
+
name: string;
|
|
686
|
+
path: string;
|
|
687
|
+
}) => Array<KubbFile.Import>;
|
|
620
688
|
};
|
|
621
689
|
type BarrelType = 'all' | 'named' | 'propagate';
|
|
622
690
|
type DevtoolsOptions = {
|
|
@@ -905,18 +973,26 @@ type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions>
|
|
|
905
973
|
* Current plugin
|
|
906
974
|
*/
|
|
907
975
|
plugin: Plugin<TOptions>;
|
|
908
|
-
/**
|
|
909
|
-
* Returns the universal `@kubb/ast` `RootNode` produced by the configured adapter.
|
|
910
|
-
* Returns `undefined` when no adapter was set (legacy OAS-only usage).
|
|
911
|
-
*/
|
|
912
|
-
rootNode: RootNode | undefined;
|
|
913
976
|
/**
|
|
914
977
|
* Opens the Kubb Studio URL for the current `rootNode` in the default browser.
|
|
915
978
|
* Falls back to printing the URL if the browser cannot be launched.
|
|
916
979
|
* No-ops silently when no adapter has set a `rootNode`.
|
|
917
980
|
*/
|
|
918
981
|
openInStudio: (options?: DevtoolsOptions) => Promise<void>;
|
|
919
|
-
} &
|
|
982
|
+
} & ({
|
|
983
|
+
/**
|
|
984
|
+
* Returns the universal `@kubb/ast` `RootNode` produced by the configured adapter.
|
|
985
|
+
* Returns `undefined` when no adapter was set (legacy OAS-only usage).
|
|
986
|
+
*/
|
|
987
|
+
rootNode: RootNode;
|
|
988
|
+
/**
|
|
989
|
+
* Return the adapter from `@kubb/ast`
|
|
990
|
+
*/
|
|
991
|
+
adapter: Adapter;
|
|
992
|
+
} | {
|
|
993
|
+
rootNode?: never;
|
|
994
|
+
adapter?: never;
|
|
995
|
+
}) & Kubb.PluginContext;
|
|
920
996
|
/**
|
|
921
997
|
* Specify the export location for the files and define the behavior of the output
|
|
922
998
|
*/
|
|
@@ -977,5 +1053,5 @@ type Logger<TOptions extends LoggerOptions = LoggerOptions> = {
|
|
|
977
1053
|
};
|
|
978
1054
|
type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Omit<Logger<TOptions>, 'logLevel'>;
|
|
979
1055
|
//#endregion
|
|
980
|
-
export { UserPluginWithLifeCycle as A,
|
|
981
|
-
//# sourceMappingURL=types-
|
|
1056
|
+
export { UserPluginWithLifeCycle as A, formatters as B, PrinterFactoryOptions as C, UserConfig as D, UnknownUserPlugin as E, KubbEvents as F, logLevel as H, PluginManager as I, getMode as L, Generator as M, ReactGeneratorV2 as N, UserLogger as O, defineGenerator as P, DefineStorage as R, Printer as S, ResolvePathParams as T, AsyncEventEmitter as U, linters as V, URLPath as W, PluginFactoryOptions as _, Config as a, PluginParameter as b, Group as c, Logger as d, LoggerContext as f, PluginContext as g, Plugin as h, BarrelType as i, CoreGeneratorV2 as j, UserPlugin as k, InputData as l, Output as m, AdapterFactoryOptions as n, DevtoolsOptions as o, LoggerOptions as p, AdapterSource as r, GetPluginFactoryOptions as s, Adapter as t, InputPath as u, PluginLifecycle as v, ResolveNameParams as w, PluginWithLifeCycle as x, PluginLifecycleHooks as y, defineStorage as z };
|
|
1057
|
+
//# sourceMappingURL=types-Bbh1o0yW.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/core",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.4",
|
|
4
4
|
"description": "Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"remeda": "^2.33.6",
|
|
72
72
|
"semver": "^7.7.4",
|
|
73
73
|
"tinyexec": "^1.0.4",
|
|
74
|
-
"@kubb/ast": "5.0.0-alpha.
|
|
74
|
+
"@kubb/ast": "5.0.0-alpha.4"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@types/semver": "^7.7.1",
|
package/src/PluginManager.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { basename, extname, resolve } from 'node:path'
|
|
2
2
|
import { performance } from 'node:perf_hooks'
|
|
3
3
|
import type { AsyncEventEmitter } from '@internals/utils'
|
|
4
4
|
import { setUniqueName, transformReservedWord } from '@internals/utils'
|
|
@@ -10,6 +10,7 @@ import { openInStudio as openInStudioFn } from './devtools.ts'
|
|
|
10
10
|
import { ValidationPluginError } from './errors.ts'
|
|
11
11
|
import { isPromiseRejectedResult, PromiseManager } from './PromiseManager.ts'
|
|
12
12
|
import type {
|
|
13
|
+
Adapter,
|
|
13
14
|
Config,
|
|
14
15
|
DevtoolsOptions,
|
|
15
16
|
KubbEvents,
|
|
@@ -59,7 +60,7 @@ export function getMode(fileOrFolder: string | undefined | null): KubbFile.Mode
|
|
|
59
60
|
if (!fileOrFolder) {
|
|
60
61
|
return 'split'
|
|
61
62
|
}
|
|
62
|
-
return
|
|
63
|
+
return extname(fileOrFolder) ? 'single' : 'split'
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
export class PluginManager {
|
|
@@ -71,6 +72,7 @@ export class PluginManager {
|
|
|
71
72
|
* the build pipeline after the adapter's `parse()` resolves.
|
|
72
73
|
*/
|
|
73
74
|
rootNode: RootNode | undefined = undefined
|
|
75
|
+
adapter: Adapter | undefined = undefined
|
|
74
76
|
#studioIsOpen = false
|
|
75
77
|
|
|
76
78
|
readonly #plugins = new Set<Plugin>()
|
|
@@ -104,7 +106,7 @@ export class PluginManager {
|
|
|
104
106
|
plugin,
|
|
105
107
|
events: this.options.events,
|
|
106
108
|
pluginManager: this,
|
|
107
|
-
mode: getMode(
|
|
109
|
+
mode: getMode(resolve(this.config.root, this.config.output.path)),
|
|
108
110
|
addFile: async (...files: Array<KubbFile.File>) => {
|
|
109
111
|
await this.options.fabric.addFile(...files)
|
|
110
112
|
},
|
|
@@ -114,17 +116,20 @@ export class PluginManager {
|
|
|
114
116
|
get rootNode(): RootNode | undefined {
|
|
115
117
|
return pluginManager.rootNode
|
|
116
118
|
},
|
|
119
|
+
get adapter(): Adapter | undefined {
|
|
120
|
+
return pluginManager.adapter
|
|
121
|
+
},
|
|
117
122
|
openInStudio(options?: DevtoolsOptions) {
|
|
123
|
+
if (!pluginManager.config.devtools || pluginManager.#studioIsOpen) {
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
|
|
118
127
|
if (typeof pluginManager.config.devtools !== 'object') {
|
|
119
128
|
throw new Error('Devtools must be an object')
|
|
120
129
|
}
|
|
121
130
|
|
|
122
|
-
if (!pluginManager.rootNode) {
|
|
123
|
-
throw new Error('
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (pluginManager.#studioIsOpen) {
|
|
127
|
-
return
|
|
131
|
+
if (!pluginManager.rootNode || !pluginManager.adapter) {
|
|
132
|
+
throw new Error('adapter is not defined, make sure you have set the parser in kubb.config.ts')
|
|
128
133
|
}
|
|
129
134
|
|
|
130
135
|
pluginManager.#studioIsOpen = true
|
|
@@ -159,16 +164,22 @@ export class PluginManager {
|
|
|
159
164
|
}
|
|
160
165
|
|
|
161
166
|
getFile<TOptions = object>({ name, mode, extname, pluginName, options }: GetFileProps<TOptions>): KubbFile.File<{ pluginName: string }> {
|
|
162
|
-
const
|
|
163
|
-
|
|
167
|
+
const resolvedName = mode ? (mode === 'single' ? '' : this.resolveName({ name, pluginName, type: 'file' })) : name
|
|
168
|
+
|
|
169
|
+
const path = this.resolvePath({
|
|
170
|
+
baseName: `${resolvedName}${extname}` as const,
|
|
171
|
+
mode,
|
|
172
|
+
pluginName,
|
|
173
|
+
options,
|
|
174
|
+
})
|
|
164
175
|
|
|
165
176
|
if (!path) {
|
|
166
|
-
throw new Error(`Filepath should be defined for resolvedName "${
|
|
177
|
+
throw new Error(`Filepath should be defined for resolvedName "${resolvedName}" and pluginName "${pluginName}"`)
|
|
167
178
|
}
|
|
168
179
|
|
|
169
180
|
return {
|
|
170
181
|
path,
|
|
171
|
-
baseName,
|
|
182
|
+
baseName: basename(path) as KubbFile.File['baseName'],
|
|
172
183
|
meta: {
|
|
173
184
|
pluginName,
|
|
174
185
|
},
|
|
@@ -179,8 +190,8 @@ export class PluginManager {
|
|
|
179
190
|
}
|
|
180
191
|
|
|
181
192
|
resolvePath = <TOptions = object>(params: ResolvePathParams<TOptions>): KubbFile.Path => {
|
|
182
|
-
const root =
|
|
183
|
-
const defaultPath =
|
|
193
|
+
const root = resolve(this.config.root, this.config.output.path)
|
|
194
|
+
const defaultPath = resolve(root, params.baseName)
|
|
184
195
|
|
|
185
196
|
if (params.pluginName) {
|
|
186
197
|
const paths = this.hookForPluginSync({
|
|
@@ -456,7 +467,12 @@ export class PluginManager {
|
|
|
456
467
|
return plugins
|
|
457
468
|
.map((plugin) => {
|
|
458
469
|
if (plugin.pre) {
|
|
459
|
-
|
|
470
|
+
let missingPlugins = plugin.pre.filter((pluginName) => !plugins.find((pluginToFind) => pluginToFind.name === pluginName))
|
|
471
|
+
|
|
472
|
+
// when adapter is set, we can ignore the depends on plugin-oas, in v5 this will not be needed anymore
|
|
473
|
+
if (missingPlugins.includes('plugin-oas') && this.adapter) {
|
|
474
|
+
missingPlugins = missingPlugins.filter((pluginName) => pluginName !== 'plugin-oas')
|
|
475
|
+
}
|
|
460
476
|
|
|
461
477
|
if (missingPlugins.length > 0) {
|
|
462
478
|
throw new ValidationPluginError(`The plugin '${plugin.name}' has a pre set that references missing plugins for '${missingPlugins.join(', ')}'`)
|
package/src/build.ts
CHANGED
|
@@ -180,6 +180,7 @@ export async function setup(options: BuildOptions): Promise<SetupResult> {
|
|
|
180
180
|
logs: [`Running adapter: ${definedConfig.adapter.name}`],
|
|
181
181
|
})
|
|
182
182
|
|
|
183
|
+
pluginManager.adapter = definedConfig.adapter
|
|
183
184
|
pluginManager.rootNode = await definedConfig.adapter.parse(source)
|
|
184
185
|
|
|
185
186
|
await events.emit('debug', {
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { OperationNode, SchemaNode } from '@kubb/ast/types'
|
|
2
|
+
import type { KubbFile } from '@kubb/fabric-core/types'
|
|
3
|
+
import type { FabricReactNode } from '@kubb/react-fabric/types'
|
|
4
|
+
import type { Adapter, Config, Plugin, PluginFactoryOptions } from './types.ts'
|
|
5
|
+
|
|
6
|
+
export type Version = '1' | '2'
|
|
7
|
+
|
|
8
|
+
// V2 props — fully typed with @kubb/ast (already a @kubb/core dependency)
|
|
9
|
+
export type OperationsV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
10
|
+
config: Config
|
|
11
|
+
adapter: Adapter
|
|
12
|
+
options: Plugin<TPlugin>['options']
|
|
13
|
+
nodes: Array<OperationNode>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type OperationV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
17
|
+
config: Config
|
|
18
|
+
adapter: Adapter
|
|
19
|
+
options: Plugin<TPlugin>['options']
|
|
20
|
+
node: OperationNode
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type SchemaV2Props<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
24
|
+
config: Config
|
|
25
|
+
adapter: Adapter
|
|
26
|
+
options: Plugin<TPlugin>['options']
|
|
27
|
+
node: SchemaNode
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type UserCoreGeneratorV2<TPlugin extends PluginFactoryOptions> = {
|
|
31
|
+
name: string
|
|
32
|
+
type: 'core'
|
|
33
|
+
version?: '2'
|
|
34
|
+
operations?(props: OperationsV2Props<TPlugin>): Promise<Array<KubbFile.File>>
|
|
35
|
+
operation?(props: OperationV2Props<TPlugin>): Promise<Array<KubbFile.File>>
|
|
36
|
+
schema?(props: SchemaV2Props<TPlugin>): Promise<Array<KubbFile.File>>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type UserReactGeneratorV2<TPlugin extends PluginFactoryOptions> = {
|
|
40
|
+
name: string
|
|
41
|
+
type: 'react'
|
|
42
|
+
version?: '2'
|
|
43
|
+
Operations?(props: OperationsV2Props<TPlugin>): FabricReactNode
|
|
44
|
+
Operation?(props: OperationV2Props<TPlugin>): FabricReactNode
|
|
45
|
+
Schema?(props: SchemaV2Props<TPlugin>): FabricReactNode
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type CoreGeneratorV2<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
49
|
+
name: string
|
|
50
|
+
type: 'core'
|
|
51
|
+
version: '2'
|
|
52
|
+
operations(props: OperationsV2Props<TPlugin>): Promise<Array<KubbFile.File>>
|
|
53
|
+
operation(props: OperationV2Props<TPlugin>): Promise<Array<KubbFile.File>>
|
|
54
|
+
schema(props: SchemaV2Props<TPlugin>): Promise<Array<KubbFile.File>>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type ReactGeneratorV2<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = {
|
|
58
|
+
name: string
|
|
59
|
+
type: 'react'
|
|
60
|
+
version: '2'
|
|
61
|
+
Operations(props: OperationsV2Props<TPlugin>): FabricReactNode
|
|
62
|
+
Operation(props: OperationV2Props<TPlugin>): FabricReactNode
|
|
63
|
+
Schema(props: SchemaV2Props<TPlugin>): FabricReactNode
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type Generator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions> = UserCoreGeneratorV2<TPlugin> | UserReactGeneratorV2<TPlugin>
|
|
67
|
+
|
|
68
|
+
export function defineGenerator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions>(
|
|
69
|
+
generator: UserReactGeneratorV2<TPlugin>,
|
|
70
|
+
): ReactGeneratorV2<TPlugin>
|
|
71
|
+
|
|
72
|
+
export function defineGenerator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions>(generator: UserCoreGeneratorV2<TPlugin>): CoreGeneratorV2<TPlugin>
|
|
73
|
+
|
|
74
|
+
export function defineGenerator<TPlugin extends PluginFactoryOptions = PluginFactoryOptions>(
|
|
75
|
+
generator: UserCoreGeneratorV2<TPlugin> | UserReactGeneratorV2<TPlugin>,
|
|
76
|
+
): unknown {
|
|
77
|
+
if (generator.type === 'react') {
|
|
78
|
+
return {
|
|
79
|
+
version: '2',
|
|
80
|
+
Operations() {
|
|
81
|
+
return null
|
|
82
|
+
},
|
|
83
|
+
Operation() {
|
|
84
|
+
return null
|
|
85
|
+
},
|
|
86
|
+
Schema() {
|
|
87
|
+
return null
|
|
88
|
+
},
|
|
89
|
+
...generator,
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
version: '2',
|
|
95
|
+
async operations() {
|
|
96
|
+
return []
|
|
97
|
+
},
|
|
98
|
+
async operation() {
|
|
99
|
+
return []
|
|
100
|
+
},
|
|
101
|
+
async schema() {
|
|
102
|
+
return []
|
|
103
|
+
},
|
|
104
|
+
...generator,
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export { useKubb } from './useKubb.ts'
|
|
2
|
+
|
|
3
|
+
/** @deprecated Use `useKubb` from `@kubb/core/hooks` instead */
|
|
1
4
|
export { useMode } from './useMode.ts'
|
|
5
|
+
/** @deprecated Use `useKubb` from `@kubb/core/hooks` instead */
|
|
2
6
|
export { usePlugin } from './usePlugin.ts'
|
|
7
|
+
/** @deprecated Use `useKubb` from `@kubb/core/hooks` instead */
|
|
3
8
|
export { usePluginManager } from './usePluginManager.ts'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { KubbFile } from '@kubb/fabric-core/types'
|
|
2
|
+
import { useApp as useAppBase } from '@kubb/react-fabric'
|
|
3
|
+
import type { PluginManager } from '../PluginManager.ts'
|
|
4
|
+
import type { Plugin, PluginFactoryOptions } from '../types.ts'
|
|
5
|
+
|
|
6
|
+
export function useKubb<TOptions extends PluginFactoryOptions = PluginFactoryOptions>() {
|
|
7
|
+
const { meta } = useAppBase<{
|
|
8
|
+
plugin: Plugin<TOptions>
|
|
9
|
+
mode: KubbFile.Mode
|
|
10
|
+
pluginManager: PluginManager
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
plugin: meta.plugin as Plugin<TOptions>,
|
|
15
|
+
mode: meta.mode,
|
|
16
|
+
config: meta.pluginManager.config,
|
|
17
|
+
getPluginByName: meta.pluginManager.getPluginByName.bind(meta.pluginManager),
|
|
18
|
+
getFile: meta.pluginManager.getFile.bind(meta.pluginManager),
|
|
19
|
+
resolveName: meta.pluginManager.resolveName.bind(meta.pluginManager),
|
|
20
|
+
resolvePath: meta.pluginManager.resolvePath.bind(meta.pluginManager),
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/hooks/useMode.ts
CHANGED
package/src/hooks/usePlugin.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useApp } from '@kubb/react-fabric'
|
|
2
2
|
import type { Plugin, PluginFactoryOptions } from '../types.ts'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated use useApp instead
|
|
6
|
+
*/
|
|
4
7
|
export function usePlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(): Plugin<TOptions> {
|
|
5
8
|
const { meta } = useApp<{ plugin: Plugin<TOptions> }>()
|
|
6
9
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useApp } from '@kubb/react-fabric'
|
|
2
2
|
import type { PluginManager } from '../PluginManager.ts'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated use `useKubb` instead
|
|
6
|
+
*/
|
|
4
7
|
export function usePluginManager(): PluginManager {
|
|
5
8
|
const { meta } = useApp<{ pluginManager: PluginManager }>()
|
|
6
9
|
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { build, build as default, safeBuild, setup } from './build.ts'
|
|
|
4
4
|
export { type CLIOptions, type ConfigInput, defineConfig, isInputPath } from './config.ts'
|
|
5
5
|
export { formatters, linters, logLevel } from './constants.ts'
|
|
6
6
|
export { defineAdapter } from './defineAdapter.ts'
|
|
7
|
+
export { defineGenerator } from './defineGenerator.ts'
|
|
7
8
|
export { defineLogger } from './defineLogger.ts'
|
|
8
9
|
export { definePlugin } from './definePlugin.ts'
|
|
9
10
|
export { defineStorage } from './defineStorage.ts'
|
|
@@ -20,3 +21,4 @@ export type { FileMetaBase } from './utils/getBarrelFiles.ts'
|
|
|
20
21
|
export { getBarrelFiles } from './utils/getBarrelFiles.ts'
|
|
21
22
|
export { getConfigs } from './utils/getConfigs.ts'
|
|
22
23
|
export { detectLinter } from './utils/linters.ts'
|
|
24
|
+
export { resolveOptions } from './utils/resolveOptions.ts'
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AsyncEventEmitter, PossiblePromise } from '@internals/utils'
|
|
2
|
-
import type { RootNode } from '@kubb/ast/types'
|
|
2
|
+
import type { RootNode, SchemaNode } from '@kubb/ast/types'
|
|
3
3
|
import type { KubbFile } from '@kubb/fabric-core/types'
|
|
4
4
|
import type { Fabric } from '@kubb/react-fabric'
|
|
5
5
|
import type { DEFAULT_STUDIO_URL, logLevel } from './constants.ts'
|
|
@@ -98,6 +98,14 @@ export type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptio
|
|
|
98
98
|
options: TOptions['resolvedOptions']
|
|
99
99
|
/** Convert the raw source into a universal `RootNode`. */
|
|
100
100
|
parse: (source: AdapterSource) => PossiblePromise<RootNode>
|
|
101
|
+
/**
|
|
102
|
+
* Extracts `KubbFile.Import` entries needed by a `SchemaNode` tree.
|
|
103
|
+
* Populated after the first `parse()` call. Returns an empty array before that.
|
|
104
|
+
*
|
|
105
|
+
* The `resolve` callback receives the collision-corrected schema name and must
|
|
106
|
+
* return the `{ name, path }` pair for the import, or `undefined` to skip it.
|
|
107
|
+
*/
|
|
108
|
+
getImports: (node: SchemaNode, resolve: (schemaName: string) => { name: string; path: string }) => Array<KubbFile.Import>
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
export type BarrelType = 'all' | 'named' | 'propagate'
|
|
@@ -408,18 +416,31 @@ export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryO
|
|
|
408
416
|
* Current plugin
|
|
409
417
|
*/
|
|
410
418
|
plugin: Plugin<TOptions>
|
|
411
|
-
|
|
412
|
-
* Returns the universal `@kubb/ast` `RootNode` produced by the configured adapter.
|
|
413
|
-
* Returns `undefined` when no adapter was set (legacy OAS-only usage).
|
|
414
|
-
*/
|
|
415
|
-
rootNode: RootNode | undefined
|
|
419
|
+
|
|
416
420
|
/**
|
|
417
421
|
* Opens the Kubb Studio URL for the current `rootNode` in the default browser.
|
|
418
422
|
* Falls back to printing the URL if the browser cannot be launched.
|
|
419
423
|
* No-ops silently when no adapter has set a `rootNode`.
|
|
420
424
|
*/
|
|
421
425
|
openInStudio: (options?: DevtoolsOptions) => Promise<void>
|
|
422
|
-
} &
|
|
426
|
+
} & (
|
|
427
|
+
| {
|
|
428
|
+
/**
|
|
429
|
+
* Returns the universal `@kubb/ast` `RootNode` produced by the configured adapter.
|
|
430
|
+
* Returns `undefined` when no adapter was set (legacy OAS-only usage).
|
|
431
|
+
*/
|
|
432
|
+
rootNode: RootNode
|
|
433
|
+
/**
|
|
434
|
+
* Return the adapter from `@kubb/ast`
|
|
435
|
+
*/
|
|
436
|
+
adapter: Adapter
|
|
437
|
+
}
|
|
438
|
+
| {
|
|
439
|
+
rootNode?: never
|
|
440
|
+
adapter?: never
|
|
441
|
+
}
|
|
442
|
+
) &
|
|
443
|
+
Kubb.PluginContext
|
|
423
444
|
/**
|
|
424
445
|
* Specify the export location for the files and define the behavior of the output
|
|
425
446
|
*/
|
|
@@ -487,5 +508,6 @@ export type Logger<TOptions extends LoggerOptions = LoggerOptions> = {
|
|
|
487
508
|
|
|
488
509
|
export type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Omit<Logger<TOptions>, 'logLevel'>
|
|
489
510
|
|
|
511
|
+
export type { CoreGeneratorV2, Generator, ReactGeneratorV2 } from './defineGenerator.ts'
|
|
490
512
|
export type { DefineStorage } from './defineStorage.ts'
|
|
491
513
|
export type { KubbEvents } from './Kubb.ts'
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { isOperationNode, isSchemaNode } from '@kubb/ast'
|
|
2
|
+
import type { Node, OperationNode, SchemaNode } from '@kubb/ast/types'
|
|
3
|
+
|
|
4
|
+
type FilterItem = {
|
|
5
|
+
type: string
|
|
6
|
+
pattern: string | RegExp
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type OverrideItem<TOptions> = FilterItem & {
|
|
10
|
+
options: Partial<TOptions>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type ResolveOptionsContext<TOptions> = {
|
|
14
|
+
options: TOptions
|
|
15
|
+
exclude?: Array<FilterItem>
|
|
16
|
+
include?: Array<FilterItem>
|
|
17
|
+
override?: Array<OverrideItem<TOptions>>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function matchesOperationPattern(node: OperationNode, type: string, pattern: string | RegExp): boolean {
|
|
21
|
+
switch (type) {
|
|
22
|
+
case 'tag':
|
|
23
|
+
return node.tags.some((tag) => !!tag.match(pattern))
|
|
24
|
+
case 'operationId':
|
|
25
|
+
return !!node.operationId.match(pattern)
|
|
26
|
+
case 'path':
|
|
27
|
+
return !!node.path.match(pattern)
|
|
28
|
+
case 'method':
|
|
29
|
+
return !!(node.method.toLowerCase() as string).match(pattern)
|
|
30
|
+
default:
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function matchesSchemaPattern(node: SchemaNode, type: string, pattern: string | RegExp): boolean | null {
|
|
36
|
+
switch (type) {
|
|
37
|
+
case 'schemaName':
|
|
38
|
+
return node.name ? !!node.name.match(pattern) : false
|
|
39
|
+
default:
|
|
40
|
+
return null
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Resolves the effective plugin options for a given AST node by applying
|
|
46
|
+
* `exclude`, `include`, and `override` rules from the plugin configuration.
|
|
47
|
+
*
|
|
48
|
+
* Returns `null` when the node is excluded or not matched by `include`.
|
|
49
|
+
* Returns the merged options (base options merged with any matching `override`) otherwise.
|
|
50
|
+
*
|
|
51
|
+
* Supported filter types for `OperationNode`: `tag`, `operationId`, `path`, `method`.
|
|
52
|
+
* Supported filter types for `SchemaNode`: `schemaName`.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* const resolved = resolveOptions(operationNode, { options, exclude, include, override })
|
|
56
|
+
* if (!resolved) return // excluded
|
|
57
|
+
*/
|
|
58
|
+
export function resolveOptions<TOptions>(node: Node, { options, exclude = [], include, override = [] }: ResolveOptionsContext<TOptions>): TOptions | null {
|
|
59
|
+
if (isOperationNode(node)) {
|
|
60
|
+
const isExcluded = exclude.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))
|
|
61
|
+
if (isExcluded) {
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (include && !include.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) {
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const overrideOptions = override.find(({ type, pattern }) => matchesOperationPattern(node, type, pattern))?.options
|
|
70
|
+
|
|
71
|
+
return { ...options, ...overrideOptions }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (isSchemaNode(node)) {
|
|
75
|
+
if (exclude.some(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)) {
|
|
76
|
+
return null
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (include) {
|
|
80
|
+
const results = include.map(({ type, pattern }) => matchesSchemaPattern(node, type, pattern))
|
|
81
|
+
const applicable = results.filter((r) => r !== null)
|
|
82
|
+
if (applicable.length > 0 && !applicable.includes(true)) {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const overrideOptions = override.find(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)?.options
|
|
88
|
+
|
|
89
|
+
return { ...options, ...overrideOptions }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return options
|
|
93
|
+
}
|