@kubb/core 5.0.0-beta.2 → 5.0.0-beta.20

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.
Files changed (42) hide show
  1. package/README.md +8 -38
  2. package/dist/{PluginDriver-BXibeQk-.cjs → KubbDriver-BXSnJ3qM.cjs} +719 -164
  3. package/dist/KubbDriver-BXSnJ3qM.cjs.map +1 -0
  4. package/dist/{PluginDriver-DV3p2Hky.js → KubbDriver-Cxii_rBp.js} +693 -162
  5. package/dist/KubbDriver-Cxii_rBp.js.map +1 -0
  6. package/dist/{types-CC09VtBt.d.ts → createKubb-Dcmtjqds.d.ts} +1395 -1238
  7. package/dist/index.cjs +556 -785
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.ts +2 -185
  10. package/dist/index.js +551 -783
  11. package/dist/index.js.map +1 -1
  12. package/dist/mocks.cjs +30 -21
  13. package/dist/mocks.cjs.map +1 -1
  14. package/dist/mocks.d.ts +5 -5
  15. package/dist/mocks.js +29 -20
  16. package/dist/mocks.js.map +1 -1
  17. package/package.json +6 -18
  18. package/src/FileManager.ts +12 -0
  19. package/src/FileProcessor.ts +37 -38
  20. package/src/{PluginDriver.ts → KubbDriver.ts} +249 -86
  21. package/src/constants.ts +11 -6
  22. package/src/createAdapter.ts +84 -1
  23. package/src/createKubb.ts +1336 -297
  24. package/src/createRenderer.ts +23 -22
  25. package/src/defineGenerator.ts +96 -7
  26. package/src/defineLogger.ts +42 -3
  27. package/src/defineMiddleware.ts +1 -1
  28. package/src/defineParser.ts +1 -1
  29. package/src/definePlugin.ts +304 -8
  30. package/src/defineResolver.ts +268 -147
  31. package/src/devtools.ts +8 -1
  32. package/src/index.ts +2 -2
  33. package/src/mocks.ts +11 -14
  34. package/src/storages/fsStorage.ts +13 -37
  35. package/src/types.ts +38 -1292
  36. package/dist/PluginDriver-BXibeQk-.cjs.map +0 -1
  37. package/dist/PluginDriver-DV3p2Hky.js.map +0 -1
  38. package/src/Kubb.ts +0 -300
  39. package/src/renderNode.ts +0 -35
  40. package/src/utils/diagnostics.ts +0 -18
  41. package/src/utils/isInputPath.ts +0 -10
  42. package/src/utils/packageJSON.ts +0 -99
@@ -1 +1 @@
1
- {"version":3,"file":"mocks.cjs","names":["FileManager","PluginDriver","applyHookResult"],"sources":["../src/mocks.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { FileNode, OperationNode, SchemaNode, Visitor } from '@kubb/ast'\nimport { transform } from '@kubb/ast'\nimport { FileManager } from './FileManager.ts'\nimport { PluginDriver } from './PluginDriver.ts'\nimport { applyHookResult } from './renderNode.ts'\nimport type { Adapter, AdapterFactoryOptions, Config, Generator, GeneratorContext, NormalizedPlugin, PluginFactoryOptions } from './types.ts'\n\n/**\n\n * Creates a minimal `PluginDriver` mock for unit tests.\n */\nexport function createMockedPluginDriver(options: { name?: string; plugin?: NormalizedPlugin; config?: Config } = {}): PluginDriver {\n return {\n config: options?.config ?? {\n root: '.',\n output: {\n path: './path',\n },\n },\n getPlugin(_pluginName: string): NormalizedPlugin | undefined {\n return options?.plugin\n },\n getResolver: (_pluginName: string) => options?.plugin?.resolver,\n fileManager: new FileManager(),\n } as unknown as PluginDriver\n}\n\n/**\n * Creates a minimal `Adapter` mock for unit tests.\n * `parse` returns an empty `InputNode` by default; override via `options.parse`.\n * `getImports` returns `[]` by default.\n */\nexport function createMockedAdapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions>(\n options: {\n name?: TOptions['name']\n resolvedOptions?: TOptions['resolvedOptions']\n inputNode?: Adapter<TOptions>['inputNode']\n parse?: Adapter<TOptions>['parse']\n getImports?: Adapter<TOptions>['getImports']\n } = {},\n): Adapter<TOptions> {\n const inputNode = options.inputNode ?? null\n return {\n name: (options.name ?? 'oas') as TOptions['name'],\n options: (options.resolvedOptions ?? {}) as TOptions['resolvedOptions'],\n inputNode,\n parse: options.parse ?? (async () => ({ kind: 'Input' as const, schemas: [], operations: [] })),\n getImports: options.getImports ?? ((_node: SchemaNode, _resolve: (schemaName: string) => { name: string; path: string }) => []),\n } as Adapter<TOptions>\n}\n\n/**\n * Creates a minimal plugin mock for unit tests.\n *\n * @example\n * `const plugin = createMockedPlugin<PluginTs>({ name: '@kubb/plugin-ts', options })`\n */\nexport function createMockedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(params: {\n name: TOptions['name']\n options: TOptions['resolvedOptions']\n resolver?: TOptions['resolver']\n transformer?: Visitor\n dependencies?: Array<string>\n}): NormalizedPlugin<TOptions> {\n return {\n name: params.name,\n options: params.options,\n resolver: params.resolver,\n transformer: params.transformer,\n dependencies: params.dependencies,\n hooks: {},\n } as unknown as NormalizedPlugin<TOptions>\n}\n\ntype RenderGeneratorOptions<TOptions extends PluginFactoryOptions> = {\n config: Config\n adapter: Adapter\n driver: PluginDriver\n plugin: NormalizedPlugin<TOptions>\n options: TOptions['resolvedOptions']\n resolver: TOptions['resolver']\n}\n\nfunction createMockedPluginContext<TOptions extends PluginFactoryOptions>(opts: RenderGeneratorOptions<TOptions>): Omit<GeneratorContext<TOptions>, 'options'> {\n const root = resolve(opts.config.root, opts.config.output.path)\n\n return {\n config: opts.config,\n root,\n getMode: (output: { path: string }) => PluginDriver.getMode(resolve(root, output.path)),\n adapter: opts.adapter,\n resolver: opts.resolver,\n plugin: opts.plugin,\n driver: opts.driver,\n getResolver: (name: string) => opts.driver.getResolver(name),\n inputNode: { kind: 'Input', schemas: [], operations: [] },\n addFile: async (...files: Array<FileNode>) => opts.driver.fileManager.add(...files),\n upsertFile: async (...files: Array<FileNode>) => opts.driver.fileManager.upsert(...files),\n hooks: opts.driver.hooks ?? ({} as never),\n warn: (msg: string) => console.warn(msg),\n error: (msg: string) => console.error(msg),\n info: (msg: string) => console.info(msg),\n openInStudio: async () => {},\n } as unknown as Omit<GeneratorContext<TOptions>, 'options'>\n}\n\n/**\n * Renders a generator's `schema` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorSchema(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorSchema<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: SchemaNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.schema) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.schema(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult(result, opts.driver, generator.renderer ?? undefined)\n}\n\n/**\n * Renders a generator's `operation` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperation(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperation<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: OperationNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operation) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.operation(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult(result, opts.driver, generator.renderer ?? undefined)\n}\n\n/**\n * Renders a generator's `operations` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperations(classClientGenerator, nodes, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperations<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n nodes: Array<OperationNode>,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operations) return\n const context = createMockedPluginContext(opts)\n const transformedNodes = opts.plugin.transformer ? nodes.map((n) => transform(n, opts.plugin.transformer!)) : nodes\n const result = await generator.operations(transformedNodes, {\n ...context,\n options: opts.options,\n })\n await applyHookResult(result, opts.driver, generator.renderer ?? undefined)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mocks.cjs","names":["FileManager","KubbDriver","applyHookResult"],"sources":["../src/mocks.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { FileNode, InputMeta, OperationNode, SchemaNode, Visitor } from '@kubb/ast'\nimport { transform } from '@kubb/ast'\nimport { FileManager } from './FileManager.ts'\nimport { applyHookResult, KubbDriver } from './KubbDriver.ts'\nimport type { Adapter, AdapterFactoryOptions, Config, Generator, GeneratorContext, NormalizedPlugin, PluginFactoryOptions } from './types.ts'\n\n/**\n\n * Creates a minimal `PluginDriver` mock for unit tests.\n */\nexport function createMockedPluginDriver(options: { name?: string; plugin?: NormalizedPlugin; config?: Config } = {}): KubbDriver {\n return {\n config: options?.config ?? {\n root: '.',\n output: {\n path: './path',\n },\n },\n getPlugin(_pluginName: string): NormalizedPlugin | undefined {\n return options?.plugin\n },\n getResolver: (_pluginName: string) => options?.plugin?.resolver,\n fileManager: new FileManager(),\n } as unknown as KubbDriver\n}\n\n/**\n * Creates a minimal `Adapter` mock for unit tests.\n * `parse` returns an empty `InputNode` by default; override via `options.parse`.\n * `getImports` returns `[]` by default.\n */\nexport function createMockedAdapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions>(\n options: {\n name?: TOptions['name']\n resolvedOptions?: TOptions['resolvedOptions']\n parse?: Adapter<TOptions>['parse']\n getImports?: Adapter<TOptions>['getImports']\n } = {},\n): Adapter<TOptions> {\n return {\n name: (options.name ?? 'oas') as TOptions['name'],\n options: (options.resolvedOptions ?? {}) as TOptions['resolvedOptions'],\n parse: options.parse ?? (async () => ({ kind: 'Input' as const, schemas: [], operations: [] })),\n getImports: options.getImports ?? ((_node: SchemaNode, _resolve: (schemaName: string) => { name: string; path: string }) => []),\n } as Adapter<TOptions>\n}\n\n/**\n * Creates a minimal plugin mock for unit tests.\n *\n * @example\n * `const plugin = createMockedPlugin<PluginTs>({ name: '@kubb/plugin-ts', options })`\n */\nexport function createMockedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(params: {\n name: TOptions['name']\n options: TOptions['resolvedOptions']\n resolver?: TOptions['resolver']\n transformer?: Visitor\n dependencies?: Array<string>\n}): NormalizedPlugin<TOptions> {\n return {\n name: params.name,\n options: params.options,\n resolver: params.resolver,\n transformer: params.transformer,\n dependencies: params.dependencies,\n hooks: {},\n } as unknown as NormalizedPlugin<TOptions>\n}\n\ntype RenderGeneratorOptions<TOptions extends PluginFactoryOptions> = {\n config: Config\n adapter: Adapter\n meta?: InputMeta\n driver: KubbDriver\n plugin: NormalizedPlugin<TOptions>\n options: TOptions['resolvedOptions']\n resolver: TOptions['resolver']\n}\n\nfunction createMockedPluginContext<TOptions extends PluginFactoryOptions>(opts: RenderGeneratorOptions<TOptions>): Omit<GeneratorContext<TOptions>, 'options'> {\n const root = resolve(opts.config.root, opts.config.output.path)\n\n return {\n config: opts.config,\n root,\n getMode: (output: { path: string }) => KubbDriver.getMode(resolve(root, output.path)),\n adapter: opts.adapter,\n resolver: opts.resolver,\n plugin: opts.plugin,\n driver: opts.driver,\n getResolver: (name: string) => opts.driver.getResolver(name),\n meta: opts.meta ?? { circularNames: [], enumNames: [] },\n addFile: async (...files: Array<FileNode>) => opts.driver.fileManager.add(...files),\n upsertFile: async (...files: Array<FileNode>) => opts.driver.fileManager.upsert(...files),\n hooks: opts.driver.hooks ?? ({} as never),\n warn: (msg: string) => console.warn(msg),\n error: (msg: string) => console.error(msg),\n info: (msg: string) => console.info(msg),\n openInStudio: async () => {},\n } as unknown as Omit<GeneratorContext<TOptions>, 'options'>\n}\n\n/**\n * Renders a generator's `schema` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorSchema(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorSchema<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: SchemaNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.schema) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.schema(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult({ result, driver: opts.driver, rendererFactory: generator.renderer ?? undefined })\n}\n\n/**\n * Renders a generator's `operation` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperation(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperation<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: OperationNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operation) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.operation(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult({ result, driver: opts.driver, rendererFactory: generator.renderer ?? undefined })\n}\n\n/**\n * Renders a generator's `operations` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperations(classClientGenerator, nodes, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperations<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n nodes: Array<OperationNode>,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operations) return\n const context = createMockedPluginContext(opts)\n const transformedNodes = opts.plugin.transformer ? nodes.map((n) => transform(n, opts.plugin.transformer!)) : nodes\n const result = await generator.operations(transformedNodes, {\n ...context,\n options: opts.options,\n })\n await applyHookResult({ result, driver: opts.driver, rendererFactory: generator.renderer ?? undefined })\n}\n"],"mappings":"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"}
package/dist/mocks.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as __name } from "./chunk--u3MIqq1.js";
2
- import { R as NormalizedPlugin, V as PluginFactoryOptions, a as Config, n as AdapterFactoryOptions, ot as PluginDriver, t as Adapter, ut as Generator } from "./types-CC09VtBt.js";
3
- import { OperationNode, SchemaNode, Visitor } from "@kubb/ast";
2
+ import { H as NormalizedPlugin, K as PluginFactoryOptions, P as KubbDriver, bt as AdapterFactoryOptions, j as Generator, r as Config, yt as Adapter } from "./createKubb-Dcmtjqds.js";
3
+ import { InputMeta, OperationNode, SchemaNode, Visitor } from "@kubb/ast";
4
4
 
5
5
  //#region src/mocks.d.ts
6
6
  /**
@@ -11,7 +11,7 @@ declare function createMockedPluginDriver(options?: {
11
11
  name?: string;
12
12
  plugin?: NormalizedPlugin;
13
13
  config?: Config;
14
- }): PluginDriver;
14
+ }): KubbDriver;
15
15
  /**
16
16
  * Creates a minimal `Adapter` mock for unit tests.
17
17
  * `parse` returns an empty `InputNode` by default; override via `options.parse`.
@@ -20,7 +20,6 @@ declare function createMockedPluginDriver(options?: {
20
20
  declare function createMockedAdapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions>(options?: {
21
21
  name?: TOptions['name'];
22
22
  resolvedOptions?: TOptions['resolvedOptions'];
23
- inputNode?: Adapter<TOptions>['inputNode'];
24
23
  parse?: Adapter<TOptions>['parse'];
25
24
  getImports?: Adapter<TOptions>['getImports'];
26
25
  }): Adapter<TOptions>;
@@ -40,7 +39,8 @@ declare function createMockedPlugin<TOptions extends PluginFactoryOptions = Plug
40
39
  type RenderGeneratorOptions<TOptions extends PluginFactoryOptions> = {
41
40
  config: Config;
42
41
  adapter: Adapter;
43
- driver: PluginDriver;
42
+ meta?: InputMeta;
43
+ driver: KubbDriver;
44
44
  plugin: NormalizedPlugin<TOptions>;
45
45
  options: TOptions['resolvedOptions'];
46
46
  resolver: TOptions['resolver'];
package/dist/mocks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./chunk--u3MIqq1.js";
2
- import { n as applyHookResult, r as FileManager, t as PluginDriver } from "./PluginDriver-DV3p2Hky.js";
2
+ import { n as applyHookResult, r as FileManager, t as KubbDriver } from "./KubbDriver-Cxii_rBp.js";
3
3
  import { resolve } from "node:path";
4
4
  import { transform } from "@kubb/ast";
5
5
  //#region src/mocks.ts
@@ -26,11 +26,9 @@ function createMockedPluginDriver(options = {}) {
26
26
  * `getImports` returns `[]` by default.
27
27
  */
28
28
  function createMockedAdapter(options = {}) {
29
- const inputNode = options.inputNode ?? null;
30
29
  return {
31
30
  name: options.name ?? "oas",
32
31
  options: options.resolvedOptions ?? {},
33
- inputNode,
34
32
  parse: options.parse ?? (async () => ({
35
33
  kind: "Input",
36
34
  schemas: [],
@@ -60,16 +58,15 @@ function createMockedPluginContext(opts) {
60
58
  return {
61
59
  config: opts.config,
62
60
  root,
63
- getMode: (output) => PluginDriver.getMode(resolve(root, output.path)),
61
+ getMode: (output) => KubbDriver.getMode(resolve(root, output.path)),
64
62
  adapter: opts.adapter,
65
63
  resolver: opts.resolver,
66
64
  plugin: opts.plugin,
67
65
  driver: opts.driver,
68
66
  getResolver: (name) => opts.driver.getResolver(name),
69
- inputNode: {
70
- kind: "Input",
71
- schemas: [],
72
- operations: []
67
+ meta: opts.meta ?? {
68
+ circularNames: [],
69
+ enumNames: []
73
70
  },
74
71
  addFile: async (...files) => opts.driver.fileManager.add(...files),
75
72
  upsertFile: async (...files) => opts.driver.fileManager.upsert(...files),
@@ -93,10 +90,14 @@ async function renderGeneratorSchema(generator, node, opts) {
93
90
  if (!generator.schema) return;
94
91
  const context = createMockedPluginContext(opts);
95
92
  const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node;
96
- await applyHookResult(await generator.schema(transformedNode, {
97
- ...context,
98
- options: opts.options
99
- }), opts.driver, generator.renderer ?? void 0);
93
+ await applyHookResult({
94
+ result: await generator.schema(transformedNode, {
95
+ ...context,
96
+ options: opts.options
97
+ }),
98
+ driver: opts.driver,
99
+ rendererFactory: generator.renderer ?? void 0
100
+ });
100
101
  }
101
102
  /**
102
103
  * Renders a generator's `operation` method in a test context.
@@ -111,10 +112,14 @@ async function renderGeneratorOperation(generator, node, opts) {
111
112
  if (!generator.operation) return;
112
113
  const context = createMockedPluginContext(opts);
113
114
  const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node;
114
- await applyHookResult(await generator.operation(transformedNode, {
115
- ...context,
116
- options: opts.options
117
- }), opts.driver, generator.renderer ?? void 0);
115
+ await applyHookResult({
116
+ result: await generator.operation(transformedNode, {
117
+ ...context,
118
+ options: opts.options
119
+ }),
120
+ driver: opts.driver,
121
+ rendererFactory: generator.renderer ?? void 0
122
+ });
118
123
  }
119
124
  /**
120
125
  * Renders a generator's `operations` method in a test context.
@@ -129,10 +134,14 @@ async function renderGeneratorOperations(generator, nodes, opts) {
129
134
  if (!generator.operations) return;
130
135
  const context = createMockedPluginContext(opts);
131
136
  const transformedNodes = opts.plugin.transformer ? nodes.map((n) => transform(n, opts.plugin.transformer)) : nodes;
132
- await applyHookResult(await generator.operations(transformedNodes, {
133
- ...context,
134
- options: opts.options
135
- }), opts.driver, generator.renderer ?? void 0);
137
+ await applyHookResult({
138
+ result: await generator.operations(transformedNodes, {
139
+ ...context,
140
+ options: opts.options
141
+ }),
142
+ driver: opts.driver,
143
+ rendererFactory: generator.renderer ?? void 0
144
+ });
136
145
  }
137
146
  //#endregion
138
147
  export { createMockedAdapter, createMockedPlugin, createMockedPluginDriver, renderGeneratorOperation, renderGeneratorOperations, renderGeneratorSchema };
package/dist/mocks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mocks.js","names":[],"sources":["../src/mocks.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { FileNode, OperationNode, SchemaNode, Visitor } from '@kubb/ast'\nimport { transform } from '@kubb/ast'\nimport { FileManager } from './FileManager.ts'\nimport { PluginDriver } from './PluginDriver.ts'\nimport { applyHookResult } from './renderNode.ts'\nimport type { Adapter, AdapterFactoryOptions, Config, Generator, GeneratorContext, NormalizedPlugin, PluginFactoryOptions } from './types.ts'\n\n/**\n\n * Creates a minimal `PluginDriver` mock for unit tests.\n */\nexport function createMockedPluginDriver(options: { name?: string; plugin?: NormalizedPlugin; config?: Config } = {}): PluginDriver {\n return {\n config: options?.config ?? {\n root: '.',\n output: {\n path: './path',\n },\n },\n getPlugin(_pluginName: string): NormalizedPlugin | undefined {\n return options?.plugin\n },\n getResolver: (_pluginName: string) => options?.plugin?.resolver,\n fileManager: new FileManager(),\n } as unknown as PluginDriver\n}\n\n/**\n * Creates a minimal `Adapter` mock for unit tests.\n * `parse` returns an empty `InputNode` by default; override via `options.parse`.\n * `getImports` returns `[]` by default.\n */\nexport function createMockedAdapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions>(\n options: {\n name?: TOptions['name']\n resolvedOptions?: TOptions['resolvedOptions']\n inputNode?: Adapter<TOptions>['inputNode']\n parse?: Adapter<TOptions>['parse']\n getImports?: Adapter<TOptions>['getImports']\n } = {},\n): Adapter<TOptions> {\n const inputNode = options.inputNode ?? null\n return {\n name: (options.name ?? 'oas') as TOptions['name'],\n options: (options.resolvedOptions ?? {}) as TOptions['resolvedOptions'],\n inputNode,\n parse: options.parse ?? (async () => ({ kind: 'Input' as const, schemas: [], operations: [] })),\n getImports: options.getImports ?? ((_node: SchemaNode, _resolve: (schemaName: string) => { name: string; path: string }) => []),\n } as Adapter<TOptions>\n}\n\n/**\n * Creates a minimal plugin mock for unit tests.\n *\n * @example\n * `const plugin = createMockedPlugin<PluginTs>({ name: '@kubb/plugin-ts', options })`\n */\nexport function createMockedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(params: {\n name: TOptions['name']\n options: TOptions['resolvedOptions']\n resolver?: TOptions['resolver']\n transformer?: Visitor\n dependencies?: Array<string>\n}): NormalizedPlugin<TOptions> {\n return {\n name: params.name,\n options: params.options,\n resolver: params.resolver,\n transformer: params.transformer,\n dependencies: params.dependencies,\n hooks: {},\n } as unknown as NormalizedPlugin<TOptions>\n}\n\ntype RenderGeneratorOptions<TOptions extends PluginFactoryOptions> = {\n config: Config\n adapter: Adapter\n driver: PluginDriver\n plugin: NormalizedPlugin<TOptions>\n options: TOptions['resolvedOptions']\n resolver: TOptions['resolver']\n}\n\nfunction createMockedPluginContext<TOptions extends PluginFactoryOptions>(opts: RenderGeneratorOptions<TOptions>): Omit<GeneratorContext<TOptions>, 'options'> {\n const root = resolve(opts.config.root, opts.config.output.path)\n\n return {\n config: opts.config,\n root,\n getMode: (output: { path: string }) => PluginDriver.getMode(resolve(root, output.path)),\n adapter: opts.adapter,\n resolver: opts.resolver,\n plugin: opts.plugin,\n driver: opts.driver,\n getResolver: (name: string) => opts.driver.getResolver(name),\n inputNode: { kind: 'Input', schemas: [], operations: [] },\n addFile: async (...files: Array<FileNode>) => opts.driver.fileManager.add(...files),\n upsertFile: async (...files: Array<FileNode>) => opts.driver.fileManager.upsert(...files),\n hooks: opts.driver.hooks ?? ({} as never),\n warn: (msg: string) => console.warn(msg),\n error: (msg: string) => console.error(msg),\n info: (msg: string) => console.info(msg),\n openInStudio: async () => {},\n } as unknown as Omit<GeneratorContext<TOptions>, 'options'>\n}\n\n/**\n * Renders a generator's `schema` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorSchema(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorSchema<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: SchemaNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.schema) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.schema(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult(result, opts.driver, generator.renderer ?? undefined)\n}\n\n/**\n * Renders a generator's `operation` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperation(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperation<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: OperationNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operation) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.operation(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult(result, opts.driver, generator.renderer ?? undefined)\n}\n\n/**\n * Renders a generator's `operations` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperations(classClientGenerator, nodes, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperations<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n nodes: Array<OperationNode>,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operations) return\n const context = createMockedPluginContext(opts)\n const transformedNodes = opts.plugin.transformer ? nodes.map((n) => transform(n, opts.plugin.transformer!)) : nodes\n const result = await generator.operations(transformedNodes, {\n ...context,\n options: opts.options,\n })\n await applyHookResult(result, opts.driver, generator.renderer ?? undefined)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mocks.js","names":[],"sources":["../src/mocks.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { FileNode, InputMeta, OperationNode, SchemaNode, Visitor } from '@kubb/ast'\nimport { transform } from '@kubb/ast'\nimport { FileManager } from './FileManager.ts'\nimport { applyHookResult, KubbDriver } from './KubbDriver.ts'\nimport type { Adapter, AdapterFactoryOptions, Config, Generator, GeneratorContext, NormalizedPlugin, PluginFactoryOptions } from './types.ts'\n\n/**\n\n * Creates a minimal `PluginDriver` mock for unit tests.\n */\nexport function createMockedPluginDriver(options: { name?: string; plugin?: NormalizedPlugin; config?: Config } = {}): KubbDriver {\n return {\n config: options?.config ?? {\n root: '.',\n output: {\n path: './path',\n },\n },\n getPlugin(_pluginName: string): NormalizedPlugin | undefined {\n return options?.plugin\n },\n getResolver: (_pluginName: string) => options?.plugin?.resolver,\n fileManager: new FileManager(),\n } as unknown as KubbDriver\n}\n\n/**\n * Creates a minimal `Adapter` mock for unit tests.\n * `parse` returns an empty `InputNode` by default; override via `options.parse`.\n * `getImports` returns `[]` by default.\n */\nexport function createMockedAdapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions>(\n options: {\n name?: TOptions['name']\n resolvedOptions?: TOptions['resolvedOptions']\n parse?: Adapter<TOptions>['parse']\n getImports?: Adapter<TOptions>['getImports']\n } = {},\n): Adapter<TOptions> {\n return {\n name: (options.name ?? 'oas') as TOptions['name'],\n options: (options.resolvedOptions ?? {}) as TOptions['resolvedOptions'],\n parse: options.parse ?? (async () => ({ kind: 'Input' as const, schemas: [], operations: [] })),\n getImports: options.getImports ?? ((_node: SchemaNode, _resolve: (schemaName: string) => { name: string; path: string }) => []),\n } as Adapter<TOptions>\n}\n\n/**\n * Creates a minimal plugin mock for unit tests.\n *\n * @example\n * `const plugin = createMockedPlugin<PluginTs>({ name: '@kubb/plugin-ts', options })`\n */\nexport function createMockedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>(params: {\n name: TOptions['name']\n options: TOptions['resolvedOptions']\n resolver?: TOptions['resolver']\n transformer?: Visitor\n dependencies?: Array<string>\n}): NormalizedPlugin<TOptions> {\n return {\n name: params.name,\n options: params.options,\n resolver: params.resolver,\n transformer: params.transformer,\n dependencies: params.dependencies,\n hooks: {},\n } as unknown as NormalizedPlugin<TOptions>\n}\n\ntype RenderGeneratorOptions<TOptions extends PluginFactoryOptions> = {\n config: Config\n adapter: Adapter\n meta?: InputMeta\n driver: KubbDriver\n plugin: NormalizedPlugin<TOptions>\n options: TOptions['resolvedOptions']\n resolver: TOptions['resolver']\n}\n\nfunction createMockedPluginContext<TOptions extends PluginFactoryOptions>(opts: RenderGeneratorOptions<TOptions>): Omit<GeneratorContext<TOptions>, 'options'> {\n const root = resolve(opts.config.root, opts.config.output.path)\n\n return {\n config: opts.config,\n root,\n getMode: (output: { path: string }) => KubbDriver.getMode(resolve(root, output.path)),\n adapter: opts.adapter,\n resolver: opts.resolver,\n plugin: opts.plugin,\n driver: opts.driver,\n getResolver: (name: string) => opts.driver.getResolver(name),\n meta: opts.meta ?? { circularNames: [], enumNames: [] },\n addFile: async (...files: Array<FileNode>) => opts.driver.fileManager.add(...files),\n upsertFile: async (...files: Array<FileNode>) => opts.driver.fileManager.upsert(...files),\n hooks: opts.driver.hooks ?? ({} as never),\n warn: (msg: string) => console.warn(msg),\n error: (msg: string) => console.error(msg),\n info: (msg: string) => console.info(msg),\n openInStudio: async () => {},\n } as unknown as Omit<GeneratorContext<TOptions>, 'options'>\n}\n\n/**\n * Renders a generator's `schema` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorSchema(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorSchema<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: SchemaNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.schema) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.schema(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult({ result, driver: opts.driver, rendererFactory: generator.renderer ?? undefined })\n}\n\n/**\n * Renders a generator's `operation` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperation(typeGenerator, node, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperation<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n node: OperationNode,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operation) return\n const context = createMockedPluginContext(opts)\n const transformedNode = opts.plugin.transformer ? transform(node, opts.plugin.transformer) : node\n const result = await generator.operation(transformedNode, {\n ...context,\n options: opts.options,\n })\n await applyHookResult({ result, driver: opts.driver, rendererFactory: generator.renderer ?? undefined })\n}\n\n/**\n * Renders a generator's `operations` method in a test context.\n *\n * @example\n * ```ts\n * await renderGeneratorOperations(classClientGenerator, nodes, { config, adapter, driver, plugin, options, resolver })\n * await matchFiles(driver.fileManager.files)\n * ```\n */\nexport async function renderGeneratorOperations<TOptions extends PluginFactoryOptions>(\n generator: Generator<TOptions>,\n nodes: Array<OperationNode>,\n opts: RenderGeneratorOptions<TOptions>,\n): Promise<void> {\n if (!generator.operations) return\n const context = createMockedPluginContext(opts)\n const transformedNodes = opts.plugin.transformer ? nodes.map((n) => transform(n, opts.plugin.transformer!)) : nodes\n const result = await generator.operations(transformedNodes, {\n ...context,\n options: opts.options,\n })\n await applyHookResult({ result, driver: opts.driver, rendererFactory: generator.renderer ?? undefined })\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,20 +1,13 @@
1
1
  {
2
2
  "name": "@kubb/core",
3
- "version": "5.0.0-beta.2",
4
- "description": "Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.",
3
+ "version": "5.0.0-beta.20",
4
+ "description": "Core engine for Kubb's plugin-based code generation system. Provides the plugin driver, file manager, defineConfig, and build orchestration used by every Kubb plugin.",
5
5
  "keywords": [
6
- "ast",
7
6
  "code-generator",
8
7
  "codegen",
9
- "core-library",
10
- "file-system",
11
8
  "kubb",
12
- "oas",
13
9
  "openapi",
14
- "plugin-framework",
15
10
  "plugin-system",
16
- "plugins",
17
- "swagger",
18
11
  "typescript"
19
12
  ],
20
13
  "license": "MIT",
@@ -63,17 +56,16 @@
63
56
  "registry": "https://registry.npmjs.org/"
64
57
  },
65
58
  "dependencies": {
66
- "fflate": "^0.8.2",
59
+ "fflate": "^0.8.3",
67
60
  "tinyexec": "^1.1.2",
68
- "@kubb/ast": "5.0.0-beta.2"
61
+ "@kubb/ast": "5.0.0-beta.20"
69
62
  },
70
63
  "devDependencies": {
71
- "p-limit": "^7.3.0",
72
64
  "@internals/utils": "0.0.0",
73
- "@kubb/renderer-jsx": "5.0.0-beta.2"
65
+ "@kubb/renderer-jsx": "5.0.0-beta.20"
74
66
  },
75
67
  "peerDependencies": {
76
- "@kubb/renderer-jsx": "5.0.0-beta.2"
68
+ "@kubb/renderer-jsx": "5.0.0-beta.20"
77
69
  },
78
70
  "size-limit": [
79
71
  {
@@ -85,10 +77,6 @@
85
77
  "engines": {
86
78
  "node": ">=22"
87
79
  },
88
- "inlinedDependencies": {
89
- "p-limit": "7.3.0",
90
- "yocto-queue": "1.2.2"
91
- },
92
80
  "scripts": {
93
81
  "build": "tsdown && size-limit",
94
82
  "clean": "npx rimraf ./dist",
@@ -91,6 +91,18 @@ export class FileManager {
91
91
  this.#filesCache = null
92
92
  }
93
93
 
94
+ /**
95
+ * Releases all stored files. Called by the core after `kubb:build:end` to
96
+ * free the per-plugin FileNode caches for the rest of the process lifetime.
97
+ */
98
+ dispose(): void {
99
+ this.clear()
100
+ }
101
+
102
+ [Symbol.dispose](): void {
103
+ this.dispose()
104
+ }
105
+
94
106
  /**
95
107
  * All stored files, sorted by path length (shorter paths first).
96
108
  */
@@ -1,7 +1,6 @@
1
1
  import type { CodeNode, FileNode } from '@kubb/ast'
2
2
  import { extractStringsFromNodes } from '@kubb/ast'
3
- import pLimit from 'p-limit'
4
- import { PARALLEL_CONCURRENCY_LIMIT } from './constants.ts'
3
+ import { AsyncEventEmitter } from '@internals/utils'
5
4
  import type { Parser } from './defineParser.ts'
6
5
 
7
6
  type ParseOptions = {
@@ -9,21 +8,29 @@ type ParseOptions = {
9
8
  extension?: Record<FileNode['extname'], FileNode['extname'] | ''>
10
9
  }
11
10
 
12
- type RunOptions = ParseOptions & {
13
- /**
14
- * @default 'sequential'
15
- */
16
- mode?: 'sequential' | 'parallel'
17
- onStart?: (files: Array<FileNode>) => Promise<void> | void
18
- onEnd?: (files: Array<FileNode>) => Promise<void> | void
19
- onUpdate?: (params: { file: FileNode; source?: string; processed: number; total: number; percentage: number }) => Promise<void> | void
11
+ export type FileProcessorEvents = {
12
+ start: [files: Array<FileNode>]
13
+ update: [params: { file: FileNode; source?: string; processed: number; total: number; percentage: number }]
14
+ end: [files: Array<FileNode>]
15
+ }
16
+
17
+ export type ParsedFile = {
18
+ file: FileNode
19
+ source: string
20
+ processed: number
21
+ total: number
22
+ percentage: number
20
23
  }
21
24
 
22
25
  function joinSources(file: FileNode): string {
23
- return file.sources
24
- .map((item) => extractStringsFromNodes(item.nodes as Array<CodeNode>))
25
- .filter(Boolean)
26
- .join('\n\n')
26
+ const sources = file.sources
27
+ if (sources.length === 0) return ''
28
+ const parts: string[] = []
29
+ for (const source of sources) {
30
+ const s = extractStringsFromNodes(source.nodes as Array<CodeNode>)
31
+ if (s) parts.push(s)
32
+ }
33
+ return parts.join('\n\n')
27
34
  }
28
35
 
29
36
  /**
@@ -33,9 +40,9 @@ function joinSources(file: FileNode): string {
33
40
  * @internal
34
41
  */
35
42
  export class FileProcessor {
36
- readonly #limit = pLimit(PARALLEL_CONCURRENCY_LIMIT)
43
+ readonly events = new AsyncEventEmitter<FileProcessorEvents>()
37
44
 
38
- async parse(file: FileNode, { parsers, extension }: ParseOptions = {}): Promise<string> {
45
+ parse(file: FileNode, { parsers, extension }: ParseOptions = {}): string {
39
46
  const parseExtName = extension?.[file.extname] || undefined
40
47
 
41
48
  if (!parsers || !file.extname) {
@@ -51,35 +58,27 @@ export class FileProcessor {
51
58
  return parser.parse(file, { extname: parseExtName })
52
59
  }
53
60
 
54
- async run(files: Array<FileNode>, { parsers, mode = 'sequential', extension, onStart, onEnd, onUpdate }: RunOptions = {}): Promise<Array<FileNode>> {
55
- await onStart?.(files)
56
-
61
+ *stream(files: ReadonlyArray<FileNode>, options: ParseOptions = {}): Generator<ParsedFile> {
57
62
  const total = files.length
63
+ if (total === 0) return
64
+
58
65
  let processed = 0
66
+ for (const file of files) {
67
+ const source = this.parse(file, options)
68
+ processed++
59
69
 
60
- const processOne = async (file: FileNode) => {
61
- const source = await this.parse(file, { extension, parsers })
62
- const currentProcessed = ++processed
63
- const percentage = (currentProcessed / total) * 100
64
-
65
- await onUpdate?.({
66
- file,
67
- source,
68
- processed: currentProcessed,
69
- percentage,
70
- total,
71
- })
70
+ yield { file, source, processed, total, percentage: (processed / total) * 100 }
72
71
  }
72
+ }
73
+
74
+ async run(files: Array<FileNode>, options: ParseOptions = {}): Promise<Array<FileNode>> {
75
+ await this.events.emit('start', files)
73
76
 
74
- if (mode === 'sequential') {
75
- for (const file of files) {
76
- await processOne(file)
77
- }
78
- } else {
79
- await Promise.all(files.map((file) => this.#limit(() => processOne(file))))
77
+ for (const { file, source, processed, total, percentage } of this.stream(files, options)) {
78
+ await this.events.emit('update', { file, source, processed, percentage, total })
80
79
  }
81
80
 
82
- await onEnd?.(files)
81
+ await this.events.emit('end', files)
83
82
 
84
83
  return files
85
84
  }