@kubb/core 5.0.0-beta.75 → 5.0.0-beta.9

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/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { t as __name } from "./chunk--u3MIqq1.js";
2
- import { $ as defineParser, A as KubbPluginStartContext, B as Override, C as KubbGenerationSummaryContext, D as KubbLifecycleStartContext, E as KubbInfoContext, F as Logger, G as ResolveOptionsContext, H as PossibleConfig, I as LoggerContext, J as ResolverFileParams, K as Resolver, L as LoggerOptions, M as KubbSuccessContext, N as KubbVersionNewContext, O as KubbPluginEndContext, P as KubbWarnContext, Q as Parser, R as NormalizedPlugin, S as KubbGenerationStartContext, T as KubbHookStartContext, U as ResolveBannerContext, V as PluginFactoryOptions, W as ResolveNameParams, X as UserConfig, Y as ResolverPathParams, Z as UserLogger, _ as KubbErrorContext, _t as logLevel, a as Config, at as createKubb, b as KubbFilesProcessingStartContext, c as GeneratorContext, ct as Plugin, d as InputData, dt as defineGenerator, et as Middleware, f as InputPath, ft as Storage, g as KubbDebugContext, gt as createRenderer, h as KubbConfigEndContext, ht as RendererFactory, i as CLIOptions, it as BuildOutput, j as KubbPluginsEndContext, k as KubbPluginSetupContext, l as Group, lt as definePlugin, m as KubbBuildStartContext, mt as Renderer, n as AdapterFactoryOptions, nt as Kubb, o as DevtoolsOptions, ot as PluginDriver, p as KubbBuildEndContext, pt as createStorage, q as ResolverContext, r as AdapterSource, rt as KubbHooks, s as Exclude, st as FileManager, t as Adapter, tt as defineMiddleware, u as Include, ut as Generator, v as KubbFileProcessingUpdateContext, vt as AsyncEventEmitter, w as KubbHookEndContext, x as KubbGenerationEndContext, y as KubbFilesProcessingEndContext, z as Output } from "./types-CuNocrbJ.js";
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, InputNode, Node } from "@kubb/ast";
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
- //#region src/utils/isInputPath.d.ts
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 DEFAULT_BANNER, c as logLevel, i as defineResolver, l as camelCase, n as applyHookResult, o as DEFAULT_EXTENSION, r as FileManager, s as DEFAULT_STUDIO_URL, t as PluginDriver } from "./PluginDriver-DV3p2Hky.js";
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.9";
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 (error) {
778
- if (isMissingPathError(error)) return false;
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 (error) {
786
- if (isMissingPathError(error)) return null;
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 (error) {
804
- if (isMissingPathError(error)) return;
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.75";
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: ${userConfig.storage ? `custom(${userConfig.storage.name})` : userConfig.output?.write === false ? "disabled" : "filesystem (default)"}`,
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?.clear(resolve(config.root, config.output.path));
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
- const adapter = config.adapter;
918
- if (!adapter) throw new Error("No adapter configured. Please provide an adapter in your kubb.config.ts.");
919
- const source = inputToAdapterSource(config);
920
- await hooks.emit("kubb:debug", {
921
- date: /* @__PURE__ */ new Date(),
922
- logs: [`Running adapter: ${adapter.name}`]
923
- });
924
- driver.adapter = adapter;
925
- driver.inputNode = await adapter.parse(source);
926
- await hooks.emit("kubb:debug", {
927
- date: /* @__PURE__ */ new Date(),
928
- logs: [
929
- `✓ Adapter '${adapter.name}' resolved InputNode`,
930
- ` • Schemas: ${driver.inputNode.schemas.length}`,
931
- ` • Operations: ${driver.inputNode.operations.length}`
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. pluginOas()) before this plugin in your Kubb config.`);
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, storage } = setupResult;
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?.setItem(file.path, source);
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
- function inputToAdapterSource(config) {
1174
- if (Array.isArray(config.input)) return {
1175
- type: "paths",
1176
- paths: config.input.map((i) => new URLPath(i.path).isURL ? i.path : resolve(config.root, i.path))
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
- if ("data" in config.input) return {
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: config.input.data
1185
+ data: input.data
1181
1186
  };
1182
- if (new URLPath(config.input.path).isURL) return {
1187
+ if (new URLPath(input.path).isURL) return {
1183
1188
  type: "path",
1184
- path: config.input.path
1189
+ path: input.path
1185
1190
  };
1186
1191
  return {
1187
1192
  type: "path",
1188
- path: resolve(config.root, config.input.path)
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
- * @example
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