@kubb/core 5.0.0-beta.1 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -39
- package/dist/{PluginDriver-BXibeQk-.cjs → PluginDriver-Cu1Kj9S-.cjs} +95 -56
- package/dist/PluginDriver-Cu1Kj9S-.cjs.map +1 -0
- package/dist/{PluginDriver-DV3p2Hky.js → PluginDriver-D8Z0Htid.js} +90 -57
- package/dist/PluginDriver-D8Z0Htid.js.map +1 -0
- package/dist/{types-CuNocrbJ.d.ts → createKubb-ALdb8lmq.d.ts} +1427 -1493
- package/dist/index.cjs +119 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -143
- package/dist/index.js +119 -127
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +1 -1
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +1 -1
- package/dist/mocks.js.map +1 -1
- package/package.json +5 -12
- package/src/PluginDriver.ts +40 -7
- package/src/constants.ts +1 -1
- package/src/createAdapter.ts +77 -1
- package/src/createKubb.ts +802 -84
- package/src/defineGenerator.ts +92 -4
- package/src/defineLogger.ts +42 -3
- package/src/defineMiddleware.ts +1 -1
- package/src/definePlugin.ts +304 -8
- package/src/defineResolver.ts +185 -52
- package/src/devtools.ts +8 -1
- package/src/index.ts +1 -1
- package/src/mocks.ts +1 -2
- package/src/storages/fsStorage.ts +6 -31
- package/src/types.ts +37 -1292
- package/dist/PluginDriver-BXibeQk-.cjs.map +0 -1
- package/dist/PluginDriver-DV3p2Hky.js.map +0 -1
- package/src/Kubb.ts +0 -300
- package/src/renderNode.ts +0 -35
- package/src/utils/diagnostics.ts +0 -18
- package/src/utils/isInputPath.ts +0 -10
- package/src/utils/packageJSON.ts +0 -99
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __name } from "./chunk--u3MIqq1.js";
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as ResolverPathParams, A as isInputPath, B as KubbPluginSetupContext, C as KubbPluginsEndContext, D as PossibleConfig, E as KubbWarnContext, F as FileManager, G as Plugin, H as NormalizedPlugin, I as Exclude, J as ResolveBannerContext, K as PluginFactoryOptions, L as Group, M as GeneratorContext, N as defineGenerator, O as UserConfig, P as PluginDriver, Q as ResolverFileParams, R as Include, S as KubbLifecycleStartContext, T as KubbVersionNewContext, U as Output, V as KubbPluginStartContext, W as Override, X as Resolver, Y as ResolveOptionsContext, Z as ResolverContext, _ as KubbGenerationSummaryContext, _t as AdapterFactoryOptions, a as InputPath, at as Logger, b as KubbHooks, bt as logLevel, c as KubbBuildStartContext, ct as UserLogger, d as KubbErrorContext, dt as Storage, et as defineResolver, f as KubbFileProcessingUpdateContext, ft as createStorage, g as KubbGenerationStartContext, gt as Adapter, h as KubbGenerationEndContext, ht as createRenderer, i as InputData, it as defineMiddleware, j as Generator, k as createKubb, l as KubbConfigEndContext, lt as defineLogger, m as KubbFilesProcessingStartContext, mt as RendererFactory, n as CLIOptions, nt as defineParser, o as Kubb, ot as LoggerContext, p as KubbFilesProcessingEndContext, pt as Renderer, q as definePlugin, r as Config, rt as Middleware, s as KubbBuildEndContext, st as LoggerOptions, t as BuildOutput, tt as Parser, u as KubbDebugContext, ut as DevtoolsOptions, v as KubbHookEndContext, vt as AdapterSource, w as KubbSuccessContext, x as KubbInfoContext, xt as AsyncEventEmitter, y as KubbHookStartContext, yt as createAdapter, z as KubbPluginEndContext } from "./createKubb-ALdb8lmq.js";
|
|
3
3
|
import * as ast from "@kubb/ast";
|
|
4
|
-
import { FileNode
|
|
4
|
+
import { FileNode } from "@kubb/ast";
|
|
5
5
|
|
|
6
6
|
//#region ../../internals/utils/src/urlPath.d.ts
|
|
7
7
|
type URLObject = {
|
|
@@ -139,139 +139,6 @@ declare class URLPath {
|
|
|
139
139
|
toURLPath(): string;
|
|
140
140
|
}
|
|
141
141
|
//#endregion
|
|
142
|
-
//#region src/createAdapter.d.ts
|
|
143
|
-
type AdapterBuilder<T extends AdapterFactoryOptions> = (options: T['options']) => Adapter<T>;
|
|
144
|
-
/**
|
|
145
|
-
* Factory for implementing custom adapters that translate non-OpenAPI specs into Kubb's AST.
|
|
146
|
-
*
|
|
147
|
-
* Use this to support GraphQL schemas, gRPC definitions, AsyncAPI, or custom domain-specific languages.
|
|
148
|
-
* Built-in adapters include `@kubb/adapter-oas` for OpenAPI and Swagger documents.
|
|
149
|
-
*
|
|
150
|
-
* @note Adapters must parse their input format to Kubb's `InputNode` structure.
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```ts
|
|
154
|
-
* export const myAdapter = createAdapter<MyAdapter>((options) => {
|
|
155
|
-
* return {
|
|
156
|
-
* name: 'my-adapter',
|
|
157
|
-
* options,
|
|
158
|
-
* async parse(source) {
|
|
159
|
-
* // Transform source format to InputNode
|
|
160
|
-
* return { ... }
|
|
161
|
-
* },
|
|
162
|
-
* }
|
|
163
|
-
* })
|
|
164
|
-
*
|
|
165
|
-
* // Instantiate:
|
|
166
|
-
* const adapter = myAdapter({ validate: true })
|
|
167
|
-
* ```
|
|
168
|
-
*/
|
|
169
|
-
declare function createAdapter<T extends AdapterFactoryOptions = AdapterFactoryOptions>(build: AdapterBuilder<T>): (options?: T['options']) => Adapter<T>;
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/defineLogger.d.ts
|
|
172
|
-
/**
|
|
173
|
-
* Wraps a logger definition into a typed {@link Logger}.
|
|
174
|
-
*
|
|
175
|
-
* @example
|
|
176
|
-
* ```ts
|
|
177
|
-
* export const myLogger = defineLogger({
|
|
178
|
-
* name: 'my-logger',
|
|
179
|
-
* install(context, options) {
|
|
180
|
-
* context.on('kubb:info', (message) => console.log('ℹ', message))
|
|
181
|
-
* context.on('kubb:error', (error) => console.error('✗', error.message))
|
|
182
|
-
* },
|
|
183
|
-
* })
|
|
184
|
-
* ```
|
|
185
|
-
*/
|
|
186
|
-
declare function defineLogger<Options extends LoggerOptions = LoggerOptions>(logger: UserLogger<Options>): Logger<Options>;
|
|
187
|
-
//#endregion
|
|
188
|
-
//#region src/defineResolver.d.ts
|
|
189
|
-
/**
|
|
190
|
-
* Builder type for the plugin-specific resolver fields.
|
|
191
|
-
*
|
|
192
|
-
* `default`, `resolveOptions`, `resolvePath`, `resolveFile`, `resolveBanner`, and `resolveFooter`
|
|
193
|
-
* are optional — built-in fallbacks are injected when omitted.
|
|
194
|
-
*
|
|
195
|
-
* The builder receives `ctx` — a reference to the fully assembled resolver — so methods can
|
|
196
|
-
* call sibling resolver methods without using `this`. Because `ctx` is captured by the closure
|
|
197
|
-
* and the resolver is populated after the builder runs, `ctx` correctly reflects any overrides
|
|
198
|
-
* that were applied by the builder itself.
|
|
199
|
-
*/
|
|
200
|
-
type ResolverBuilder<T extends PluginFactoryOptions> = (ctx: T['resolver']) => Omit<T['resolver'], 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter' | 'name' | 'pluginName'> & Partial<Pick<T['resolver'], 'default' | 'resolveOptions' | 'resolvePath' | 'resolveFile' | 'resolveBanner' | 'resolveFooter'>> & {
|
|
201
|
-
name: string;
|
|
202
|
-
pluginName: T['name'];
|
|
203
|
-
};
|
|
204
|
-
/**
|
|
205
|
-
* Default option resolver — applies include/exclude filters and merges matching override options.
|
|
206
|
-
*
|
|
207
|
-
* Returns `null` when the node is filtered out by an `exclude` rule or not matched by any `include` rule.
|
|
208
|
-
*
|
|
209
|
-
* @example Include/exclude filtering
|
|
210
|
-
* ```ts
|
|
211
|
-
* const options = defaultResolveOptions(operationNode, {
|
|
212
|
-
* options: { output: 'types' },
|
|
213
|
-
* exclude: [{ type: 'tag', pattern: 'internal' }],
|
|
214
|
-
* })
|
|
215
|
-
* // → null when node has tag 'internal'
|
|
216
|
-
* ```
|
|
217
|
-
*
|
|
218
|
-
* @example Override merging
|
|
219
|
-
* ```ts
|
|
220
|
-
* const options = defaultResolveOptions(operationNode, {
|
|
221
|
-
* options: { enumType: 'asConst' },
|
|
222
|
-
* override: [{ type: 'operationId', pattern: 'listPets', options: { enumType: 'enum' } }],
|
|
223
|
-
* })
|
|
224
|
-
* // → { enumType: 'enum' } when operationId matches
|
|
225
|
-
* ```
|
|
226
|
-
*/
|
|
227
|
-
/**
|
|
228
|
-
* Defines a resolver for a plugin, injecting built-in defaults for name casing,
|
|
229
|
-
* include/exclude/override filtering, path resolution, and file construction.
|
|
230
|
-
*
|
|
231
|
-
* All four defaults can be overridden by providing them in the builder function:
|
|
232
|
-
* - `default` — name casing strategy (camelCase / PascalCase)
|
|
233
|
-
* - `resolveOptions` — include/exclude/override filtering
|
|
234
|
-
* - `resolvePath` — output path computation
|
|
235
|
-
* - `resolveFile` — full `FileNode` construction
|
|
236
|
-
*
|
|
237
|
-
* The builder receives `ctx` — a reference to the assembled resolver — so methods can
|
|
238
|
-
* call sibling resolver methods using `ctx` instead of `this`.
|
|
239
|
-
*
|
|
240
|
-
* @example Basic resolver with naming helpers
|
|
241
|
-
* ```ts
|
|
242
|
-
* export const resolver = defineResolver<PluginTs>((ctx) => ({
|
|
243
|
-
* name: 'default',
|
|
244
|
-
* resolveName(node) {
|
|
245
|
-
* return ctx.default(node.name, 'function')
|
|
246
|
-
* },
|
|
247
|
-
* resolveTypedName(node) {
|
|
248
|
-
* return ctx.default(node.name, 'type')
|
|
249
|
-
* },
|
|
250
|
-
* }))
|
|
251
|
-
* ```
|
|
252
|
-
*
|
|
253
|
-
* @example Override resolvePath for a custom output structure
|
|
254
|
-
* ```ts
|
|
255
|
-
* export const resolver = defineResolver<PluginTs>((_ctx) => ({
|
|
256
|
-
* name: 'custom',
|
|
257
|
-
* resolvePath({ baseName }, { root, output }) {
|
|
258
|
-
* return path.resolve(root, output.path, 'generated', baseName)
|
|
259
|
-
* },
|
|
260
|
-
* }))
|
|
261
|
-
* ```
|
|
262
|
-
*
|
|
263
|
-
* @example Use ctx.default inside a helper
|
|
264
|
-
* ```ts
|
|
265
|
-
* export const resolver = defineResolver<PluginTs>((ctx) => ({
|
|
266
|
-
* name: 'default',
|
|
267
|
-
* resolveParamName(node, param) {
|
|
268
|
-
* return ctx.default(`${node.operationId} ${param.in} ${param.name}`, 'type')
|
|
269
|
-
* },
|
|
270
|
-
* }))
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
declare function defineResolver<T extends PluginFactoryOptions>(build: ResolverBuilder<T>): T['resolver'];
|
|
274
|
-
//#endregion
|
|
275
142
|
//#region src/FileProcessor.d.ts
|
|
276
143
|
type ParseOptions = {
|
|
277
144
|
parsers?: Map<FileNode['extname'], Parser>;
|
|
@@ -364,12 +231,5 @@ declare const fsStorage: (options?: Record<string, never> | undefined) => Storag
|
|
|
364
231
|
*/
|
|
365
232
|
declare const memoryStorage: (options?: Record<string, never> | undefined) => Storage;
|
|
366
233
|
//#endregion
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Type guard to check if a given config has an `input.path`.
|
|
370
|
-
*/
|
|
371
|
-
declare function isInputPath(config: UserConfig | undefined): config is UserConfig<InputPath>;
|
|
372
|
-
declare function isInputPath(config: Config | undefined): config is Config<InputPath>;
|
|
373
|
-
//#endregion
|
|
374
|
-
export { Adapter, AdapterFactoryOptions, AdapterSource, AsyncEventEmitter, BuildOutput, CLIOptions, Config, DevtoolsOptions, Exclude, FileManager, FileProcessor, Generator, GeneratorContext, Group, Include, InputData, InputPath, Kubb, KubbBuildEndContext, KubbBuildStartContext, KubbConfigEndContext, KubbDebugContext, KubbErrorContext, KubbFileProcessingUpdateContext, KubbFilesProcessingEndContext, KubbFilesProcessingStartContext, KubbGenerationEndContext, KubbGenerationStartContext, KubbGenerationSummaryContext, KubbHookEndContext, KubbHookStartContext, KubbHooks, KubbInfoContext, KubbLifecycleStartContext, KubbPluginEndContext, KubbPluginSetupContext, KubbPluginStartContext, KubbPluginsEndContext, KubbSuccessContext, KubbVersionNewContext, KubbWarnContext, Logger, LoggerContext, LoggerOptions, Middleware, NormalizedPlugin, Output, Override, Parser, Plugin, PluginDriver, PluginFactoryOptions, PossibleConfig, Renderer, RendererFactory, ResolveBannerContext, ResolveNameParams, ResolveOptionsContext, Resolver, ResolverContext, ResolverFileParams, ResolverPathParams, Storage, URLPath, UserConfig, UserLogger, ast, createAdapter, createKubb, createRenderer, createStorage, defineGenerator, defineLogger, defineMiddleware, defineParser, definePlugin, defineResolver, fsStorage, isInputPath, logLevel, memoryStorage };
|
|
234
|
+
export { Adapter, AdapterFactoryOptions, AdapterSource, AsyncEventEmitter, BuildOutput, CLIOptions, Config, DevtoolsOptions, Exclude, FileManager, FileProcessor, Generator, GeneratorContext, Group, Include, InputData, InputPath, Kubb, KubbBuildEndContext, KubbBuildStartContext, KubbConfigEndContext, KubbDebugContext, KubbErrorContext, KubbFileProcessingUpdateContext, KubbFilesProcessingEndContext, KubbFilesProcessingStartContext, KubbGenerationEndContext, KubbGenerationStartContext, KubbGenerationSummaryContext, KubbHookEndContext, KubbHookStartContext, KubbHooks, KubbInfoContext, KubbLifecycleStartContext, KubbPluginEndContext, KubbPluginSetupContext, KubbPluginStartContext, KubbPluginsEndContext, KubbSuccessContext, KubbVersionNewContext, KubbWarnContext, Logger, LoggerContext, LoggerOptions, Middleware, NormalizedPlugin, Output, Override, Parser, Plugin, PluginDriver, PluginFactoryOptions, PossibleConfig, Renderer, RendererFactory, ResolveBannerContext, ResolveOptionsContext, Resolver, ResolverContext, ResolverFileParams, ResolverPathParams, Storage, URLPath, UserConfig, UserLogger, ast, createAdapter, createKubb, createRenderer, createStorage, defineGenerator, defineLogger, defineMiddleware, defineParser, definePlugin, defineResolver, fsStorage, isInputPath, logLevel, memoryStorage };
|
|
375
235
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as __name } from "./chunk--u3MIqq1.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as definePlugin, c as DEFAULT_STUDIO_URL, i as defineResolver, l as logLevel, n as applyHookResult, o as DEFAULT_BANNER, r as FileManager, s as DEFAULT_EXTENSION, t as PluginDriver, u as camelCase } from "./PluginDriver-D8Z0Htid.js";
|
|
3
3
|
import { EventEmitter } from "node:events";
|
|
4
4
|
import { access, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
5
5
|
import { dirname, join, resolve } from "node:path";
|
|
6
6
|
import * as ast from "@kubb/ast";
|
|
7
|
-
import { extractStringsFromNodes, transform, walk } from "@kubb/ast";
|
|
7
|
+
import { collectUsedSchemaNames, extractStringsFromNodes, transform, walk } from "@kubb/ast";
|
|
8
8
|
import { version } from "node:process";
|
|
9
9
|
//#region ../../internals/utils/src/errors.ts
|
|
10
10
|
/**
|
|
@@ -524,6 +524,9 @@ function createAdapter(build) {
|
|
|
524
524
|
return (options) => build(options ?? {});
|
|
525
525
|
}
|
|
526
526
|
//#endregion
|
|
527
|
+
//#region package.json
|
|
528
|
+
var version$1 = "5.0.0-beta.10";
|
|
529
|
+
//#endregion
|
|
527
530
|
//#region ../../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
528
531
|
var Node$1 = class {
|
|
529
532
|
static {
|
|
@@ -738,12 +741,6 @@ function createStorage(build) {
|
|
|
738
741
|
//#endregion
|
|
739
742
|
//#region src/storages/fsStorage.ts
|
|
740
743
|
/**
|
|
741
|
-
* Detects the filesystem error used to indicate that a path does not exist.
|
|
742
|
-
*/
|
|
743
|
-
function isMissingPathError(error) {
|
|
744
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
744
|
* Built-in filesystem storage driver.
|
|
748
745
|
*
|
|
749
746
|
* This is the default storage when no `storage` option is configured in the root config.
|
|
@@ -774,17 +771,15 @@ const fsStorage = createStorage(() => ({
|
|
|
774
771
|
try {
|
|
775
772
|
await access(resolve(key));
|
|
776
773
|
return true;
|
|
777
|
-
} catch (
|
|
778
|
-
|
|
779
|
-
throw new Error(`Failed to access storage item "${key}"`, { cause: error });
|
|
774
|
+
} catch (_error) {
|
|
775
|
+
return false;
|
|
780
776
|
}
|
|
781
777
|
},
|
|
782
778
|
async getItem(key) {
|
|
783
779
|
try {
|
|
784
780
|
return await readFile(resolve(key), "utf8");
|
|
785
|
-
} catch (
|
|
786
|
-
|
|
787
|
-
throw new Error(`Failed to read storage item "${key}"`, { cause: error });
|
|
781
|
+
} catch (_error) {
|
|
782
|
+
return null;
|
|
788
783
|
}
|
|
789
784
|
},
|
|
790
785
|
async setItem(key, value) {
|
|
@@ -800,9 +795,8 @@ const fsStorage = createStorage(() => ({
|
|
|
800
795
|
let entries;
|
|
801
796
|
try {
|
|
802
797
|
entries = await readdir(dir, { withFileTypes: true });
|
|
803
|
-
} catch (
|
|
804
|
-
|
|
805
|
-
throw new Error(`Failed to list storage keys under "${resolvedBase}"`, { cause: error });
|
|
798
|
+
} catch (_error) {
|
|
799
|
+
return;
|
|
806
800
|
}
|
|
807
801
|
for (const entry of entries) {
|
|
808
802
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
@@ -819,37 +813,31 @@ const fsStorage = createStorage(() => ({
|
|
|
819
813
|
}
|
|
820
814
|
}));
|
|
821
815
|
//#endregion
|
|
822
|
-
//#region package.json
|
|
823
|
-
var version$1 = "5.0.0-beta.1";
|
|
824
|
-
//#endregion
|
|
825
|
-
//#region src/utils/diagnostics.ts
|
|
826
|
-
/**
|
|
827
|
-
* Returns a snapshot of the current runtime environment.
|
|
828
|
-
*
|
|
829
|
-
* Useful for attaching context to debug logs and error reports so that
|
|
830
|
-
* issues can be reproduced without manual information gathering.
|
|
831
|
-
*/
|
|
832
|
-
function getDiagnosticInfo() {
|
|
833
|
-
return {
|
|
834
|
-
nodeVersion: version,
|
|
835
|
-
KubbVersion: version$1,
|
|
836
|
-
platform: process.platform,
|
|
837
|
-
arch: process.arch,
|
|
838
|
-
cwd: process.cwd()
|
|
839
|
-
};
|
|
840
|
-
}
|
|
841
|
-
//#endregion
|
|
842
|
-
//#region src/utils/isInputPath.ts
|
|
843
|
-
function isInputPath(config) {
|
|
844
|
-
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
845
|
-
}
|
|
846
|
-
//#endregion
|
|
847
816
|
//#region src/createKubb.ts
|
|
848
817
|
async function setup(userConfig, options = {}) {
|
|
849
818
|
const hooks = options.hooks ?? new AsyncEventEmitter();
|
|
819
|
+
const config = {
|
|
820
|
+
...userConfig,
|
|
821
|
+
root: userConfig.root || process.cwd(),
|
|
822
|
+
parsers: userConfig.parsers ?? [],
|
|
823
|
+
adapter: userConfig.adapter,
|
|
824
|
+
output: {
|
|
825
|
+
format: false,
|
|
826
|
+
lint: false,
|
|
827
|
+
extension: DEFAULT_EXTENSION,
|
|
828
|
+
defaultBanner: DEFAULT_BANNER,
|
|
829
|
+
...userConfig.output
|
|
830
|
+
},
|
|
831
|
+
storage: userConfig.storage ?? fsStorage(),
|
|
832
|
+
devtools: userConfig.devtools ? {
|
|
833
|
+
studioUrl: DEFAULT_STUDIO_URL,
|
|
834
|
+
...typeof userConfig.devtools === "boolean" ? {} : userConfig.devtools
|
|
835
|
+
} : void 0,
|
|
836
|
+
plugins: userConfig.plugins ?? []
|
|
837
|
+
};
|
|
838
|
+
const driver = new PluginDriver(config, { hooks });
|
|
850
839
|
const sources = /* @__PURE__ */ new Map();
|
|
851
840
|
const diagnosticInfo = getDiagnosticInfo();
|
|
852
|
-
if (Array.isArray(userConfig.input)) await hooks.emit("kubb:warn", { message: "This feature is still under development — use with caution" });
|
|
853
841
|
await hooks.emit("kubb:debug", {
|
|
854
842
|
date: /* @__PURE__ */ new Date(),
|
|
855
843
|
logs: [
|
|
@@ -859,7 +847,7 @@ async function setup(userConfig, options = {}) {
|
|
|
859
847
|
` • Output: ${userConfig.output?.path || "not specified"}`,
|
|
860
848
|
` • Plugins: ${userConfig.plugins?.length || 0}`,
|
|
861
849
|
"Output Settings:",
|
|
862
|
-
` • Storage: ${
|
|
850
|
+
` • Storage: ${config.storage.name}`,
|
|
863
851
|
` • Formatter: ${userConfig.output?.format || "none"}`,
|
|
864
852
|
` • Linter: ${userConfig.output?.lint || "none"}`,
|
|
865
853
|
"Environment:",
|
|
@@ -880,73 +868,56 @@ async function setup(userConfig, options = {}) {
|
|
|
880
868
|
throw new Error(`Cannot read file/URL defined in \`input.path\` or set with \`kubb generate PATH\` in the CLI of your Kubb config ${userConfig.input.path}`, { cause: error });
|
|
881
869
|
}
|
|
882
870
|
}
|
|
883
|
-
if (!userConfig.adapter) throw new Error("Adapter should be defined");
|
|
884
|
-
const config = {
|
|
885
|
-
...userConfig,
|
|
886
|
-
root: userConfig.root || process.cwd(),
|
|
887
|
-
parsers: userConfig.parsers ?? [],
|
|
888
|
-
adapter: userConfig.adapter,
|
|
889
|
-
output: {
|
|
890
|
-
format: false,
|
|
891
|
-
lint: false,
|
|
892
|
-
write: true,
|
|
893
|
-
extension: DEFAULT_EXTENSION,
|
|
894
|
-
defaultBanner: DEFAULT_BANNER,
|
|
895
|
-
...userConfig.output
|
|
896
|
-
},
|
|
897
|
-
devtools: userConfig.devtools ? {
|
|
898
|
-
studioUrl: DEFAULT_STUDIO_URL,
|
|
899
|
-
...typeof userConfig.devtools === "boolean" ? {} : userConfig.devtools
|
|
900
|
-
} : void 0,
|
|
901
|
-
plugins: userConfig.plugins
|
|
902
|
-
};
|
|
903
|
-
const storage = config.output.write === false ? null : config.storage ?? fsStorage();
|
|
904
871
|
if (config.output.clean) {
|
|
905
872
|
await hooks.emit("kubb:debug", {
|
|
906
873
|
date: /* @__PURE__ */ new Date(),
|
|
907
874
|
logs: ["Cleaning output directories", ` • Output: ${config.output.path}`]
|
|
908
875
|
});
|
|
909
|
-
await storage
|
|
876
|
+
await config.storage.clear(resolve(config.root, config.output.path));
|
|
910
877
|
}
|
|
911
|
-
const driver = new PluginDriver(config, { hooks });
|
|
912
878
|
function registerMiddlewareHook(event, middlewareHooks) {
|
|
913
879
|
const handler = middlewareHooks[event];
|
|
914
880
|
if (handler) hooks.on(event, handler);
|
|
915
881
|
}
|
|
916
882
|
for (const middleware of config.middleware ?? []) for (const event of Object.keys(middleware.hooks)) registerMiddlewareHook(event, middleware.hooks);
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
}
|
|
883
|
+
if (config.adapter) {
|
|
884
|
+
const source = inputToAdapterSource(config);
|
|
885
|
+
await hooks.emit("kubb:debug", {
|
|
886
|
+
date: /* @__PURE__ */ new Date(),
|
|
887
|
+
logs: [`Running adapter: ${config.adapter.name}`]
|
|
888
|
+
});
|
|
889
|
+
driver.adapter = config.adapter;
|
|
890
|
+
driver.inputNode = await config.adapter.parse(source);
|
|
891
|
+
await hooks.emit("kubb:debug", {
|
|
892
|
+
date: /* @__PURE__ */ new Date(),
|
|
893
|
+
logs: [
|
|
894
|
+
`✓ Adapter '${config.adapter.name}' resolved InputNode`,
|
|
895
|
+
` • Schemas: ${driver.inputNode.schemas.length}`,
|
|
896
|
+
` • Operations: ${driver.inputNode.operations.length}`
|
|
897
|
+
]
|
|
898
|
+
});
|
|
899
|
+
}
|
|
934
900
|
return {
|
|
935
901
|
config,
|
|
936
902
|
hooks,
|
|
937
903
|
driver,
|
|
938
|
-
sources
|
|
939
|
-
storage
|
|
904
|
+
sources
|
|
940
905
|
};
|
|
941
906
|
}
|
|
942
907
|
/**
|
|
943
908
|
* Walks the AST and dispatches nodes to a plugin's direct AST hooks
|
|
944
909
|
* (`schema`, `operation`, `operations`).
|
|
910
|
+
*
|
|
911
|
+
* When `include` contains only operation-scoped filters (`tag`, `operationId`, `path`,
|
|
912
|
+
* `method`, `contentType`) and no `schemaName` filter, the function pre-computes the set
|
|
913
|
+
* of top-level schema names transitively reachable from the included operations and skips
|
|
914
|
+
* schemas that fall outside that set. This ensures that component schemas referenced
|
|
915
|
+
* exclusively by excluded operations are not generated.
|
|
945
916
|
*/
|
|
946
917
|
async function runPluginAstHooks(plugin, context) {
|
|
947
918
|
const { adapter, inputNode, resolver, driver } = context;
|
|
948
919
|
const { exclude, include, override } = plugin.options;
|
|
949
|
-
if (!adapter || !inputNode) throw new Error(`[${plugin.name}] No adapter found. Add an OAS adapter (e.g.
|
|
920
|
+
if (!adapter || !inputNode) throw new Error(`[${plugin.name}] No adapter found. Add an OAS adapter (e.g. adapterOas()) before this plugin in your Kubb config.`);
|
|
950
921
|
function resolveRenderer(gen) {
|
|
951
922
|
return gen.renderer === null ? void 0 : gen.renderer ?? plugin.renderer ?? context.config.renderer;
|
|
952
923
|
}
|
|
@@ -956,10 +927,27 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
956
927
|
...context,
|
|
957
928
|
resolver: driver.getResolver(plugin.name)
|
|
958
929
|
};
|
|
930
|
+
const operationFilterTypes = new Set([
|
|
931
|
+
"tag",
|
|
932
|
+
"operationId",
|
|
933
|
+
"path",
|
|
934
|
+
"method",
|
|
935
|
+
"contentType"
|
|
936
|
+
]);
|
|
937
|
+
const hasOperationBasedIncludes = include?.some(({ type }) => operationFilterTypes.has(type)) ?? false;
|
|
938
|
+
const hasSchemaNameIncludes = include?.some(({ type }) => type === "schemaName") ?? false;
|
|
939
|
+
let allowedSchemaNames;
|
|
940
|
+
if (hasOperationBasedIncludes && !hasSchemaNameIncludes) allowedSchemaNames = collectUsedSchemaNames(inputNode.operations.filter((op) => resolver.resolveOptions(op, {
|
|
941
|
+
options: plugin.options,
|
|
942
|
+
exclude,
|
|
943
|
+
include,
|
|
944
|
+
override
|
|
945
|
+
}) !== null), inputNode.schemas);
|
|
959
946
|
await walk(inputNode, {
|
|
960
947
|
depth: "shallow",
|
|
961
948
|
async schema(node) {
|
|
962
949
|
const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
|
|
950
|
+
if (allowedSchemaNames !== void 0 && transformedNode.name && !allowedSchemaNames.has(transformedNode.name)) return;
|
|
963
951
|
const options = resolver.resolveOptions(transformedNode, {
|
|
964
952
|
options: plugin.options,
|
|
965
953
|
exclude,
|
|
@@ -1012,7 +1000,7 @@ async function runPluginAstHooks(plugin, context) {
|
|
|
1012
1000
|
}
|
|
1013
1001
|
}
|
|
1014
1002
|
async function safeBuild(setupResult) {
|
|
1015
|
-
const { driver, hooks, sources
|
|
1003
|
+
const { driver, hooks, sources } = setupResult;
|
|
1016
1004
|
const failedPlugins = /* @__PURE__ */ new Set();
|
|
1017
1005
|
const pluginTimings = /* @__PURE__ */ new Map();
|
|
1018
1006
|
const config = driver.config;
|
|
@@ -1103,6 +1091,7 @@ async function safeBuild(setupResult) {
|
|
|
1103
1091
|
});
|
|
1104
1092
|
await fileProcessor.run(files, {
|
|
1105
1093
|
parsers: parsersMap,
|
|
1094
|
+
mode: "parallel",
|
|
1106
1095
|
extension: config.output.extension,
|
|
1107
1096
|
onStart: async (processingFiles) => {
|
|
1108
1097
|
await hooks.emit("kubb:files:processing:start", { files: processingFiles });
|
|
@@ -1117,7 +1106,7 @@ async function safeBuild(setupResult) {
|
|
|
1117
1106
|
config
|
|
1118
1107
|
});
|
|
1119
1108
|
if (source) {
|
|
1120
|
-
await storage
|
|
1109
|
+
await config.storage.setItem(file.path, source);
|
|
1121
1110
|
sources.set(file.path, source);
|
|
1122
1111
|
}
|
|
1123
1112
|
},
|
|
@@ -1170,22 +1159,38 @@ async function build(setupResult) {
|
|
|
1170
1159
|
sources
|
|
1171
1160
|
};
|
|
1172
1161
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1162
|
+
/**
|
|
1163
|
+
* Returns a snapshot of the current runtime environment.
|
|
1164
|
+
*
|
|
1165
|
+
* Useful for attaching context to debug logs and error reports so that
|
|
1166
|
+
* issues can be reproduced without manual information gathering.
|
|
1167
|
+
*/
|
|
1168
|
+
function getDiagnosticInfo() {
|
|
1169
|
+
return {
|
|
1170
|
+
nodeVersion: version,
|
|
1171
|
+
KubbVersion: version$1,
|
|
1172
|
+
platform: process.platform,
|
|
1173
|
+
arch: process.arch,
|
|
1174
|
+
cwd: process.cwd()
|
|
1177
1175
|
};
|
|
1178
|
-
|
|
1176
|
+
}
|
|
1177
|
+
function isInputPath(config) {
|
|
1178
|
+
return typeof config?.input === "object" && config.input !== null && "path" in config.input;
|
|
1179
|
+
}
|
|
1180
|
+
function inputToAdapterSource(config) {
|
|
1181
|
+
const input = config.input;
|
|
1182
|
+
if (!input) throw new Error("[kubb] input is required when using an adapter. Provide input.path or input.data in your config.");
|
|
1183
|
+
if ("data" in input) return {
|
|
1179
1184
|
type: "data",
|
|
1180
|
-
data:
|
|
1185
|
+
data: input.data
|
|
1181
1186
|
};
|
|
1182
|
-
if (new URLPath(
|
|
1187
|
+
if (new URLPath(input.path).isURL) return {
|
|
1183
1188
|
type: "path",
|
|
1184
|
-
path:
|
|
1189
|
+
path: input.path
|
|
1185
1190
|
};
|
|
1186
1191
|
return {
|
|
1187
1192
|
type: "path",
|
|
1188
|
-
path: resolve(config.root,
|
|
1193
|
+
path: resolve(config.root, input.path)
|
|
1189
1194
|
};
|
|
1190
1195
|
}
|
|
1191
1196
|
/**
|
|
@@ -1285,7 +1290,11 @@ function defineGenerator(generator) {
|
|
|
1285
1290
|
/**
|
|
1286
1291
|
* Wraps a logger definition into a typed {@link Logger}.
|
|
1287
1292
|
*
|
|
1288
|
-
*
|
|
1293
|
+
* The optional second type parameter `TInstallReturn` allows loggers to return
|
|
1294
|
+
* a value from `install` — for example, a sink factory that the caller can
|
|
1295
|
+
* forward to hook execution.
|
|
1296
|
+
*
|
|
1297
|
+
* @example Basic logger
|
|
1289
1298
|
* ```ts
|
|
1290
1299
|
* export const myLogger = defineLogger({
|
|
1291
1300
|
* name: 'my-logger',
|
|
@@ -1295,6 +1304,17 @@ function defineGenerator(generator) {
|
|
|
1295
1304
|
* },
|
|
1296
1305
|
* })
|
|
1297
1306
|
* ```
|
|
1307
|
+
*
|
|
1308
|
+
* @example Logger that returns a hook sink factory
|
|
1309
|
+
* ```ts
|
|
1310
|
+
* export const myLogger = defineLogger<LoggerOptions, HookSinkFactory>({
|
|
1311
|
+
* name: 'my-logger',
|
|
1312
|
+
* install(context, options) {
|
|
1313
|
+
* // … register event handlers …
|
|
1314
|
+
* return (commandWithArgs) => ({ onStdout: console.log })
|
|
1315
|
+
* },
|
|
1316
|
+
* })
|
|
1317
|
+
* ```
|
|
1298
1318
|
*/
|
|
1299
1319
|
function defineLogger(logger) {
|
|
1300
1320
|
return logger;
|
|
@@ -1365,34 +1385,6 @@ function defineParser(parser) {
|
|
|
1365
1385
|
return parser;
|
|
1366
1386
|
}
|
|
1367
1387
|
//#endregion
|
|
1368
|
-
//#region src/definePlugin.ts
|
|
1369
|
-
/**
|
|
1370
|
-
* Wraps a factory function and returns a typed `Plugin` with lifecycle handlers grouped under `hooks`.
|
|
1371
|
-
*
|
|
1372
|
-
* Handlers live in a single `hooks` object (inspired by Astro integrations).
|
|
1373
|
-
* All lifecycle events from `KubbHooks` are available for subscription.
|
|
1374
|
-
*
|
|
1375
|
-
* @note For real plugins, use a `PluginFactoryOptions` type parameter to get type-safe context in `kubb:plugin:setup`.
|
|
1376
|
-
* Plugin names should follow the convention `plugin-<feature>` (e.g., `plugin-react-query`, `plugin-zod`).
|
|
1377
|
-
*
|
|
1378
|
-
* @example
|
|
1379
|
-
* ```ts
|
|
1380
|
-
* import { definePlugin } from '@kubb/core'
|
|
1381
|
-
*
|
|
1382
|
-
* export const pluginTs = definePlugin((options: { prefix?: string } = {}) => ({
|
|
1383
|
-
* name: 'plugin-ts',
|
|
1384
|
-
* hooks: {
|
|
1385
|
-
* 'kubb:plugin:setup'(ctx) {
|
|
1386
|
-
* ctx.setResolver(resolverTs)
|
|
1387
|
-
* },
|
|
1388
|
-
* },
|
|
1389
|
-
* }))
|
|
1390
|
-
* ```
|
|
1391
|
-
*/
|
|
1392
|
-
function definePlugin(factory) {
|
|
1393
|
-
return (options) => factory(options ?? {});
|
|
1394
|
-
}
|
|
1395
|
-
//#endregion
|
|
1396
1388
|
//#region src/storages/memoryStorage.ts
|
|
1397
1389
|
/**
|
|
1398
1390
|
* In-memory storage driver. Useful for testing and dry-run scenarios where
|