@kubb/core 5.0.0-alpha.36 → 5.0.0-alpha.39

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/dist/{PluginDriver-CCdkwR14.cjs → PluginDriver-BQwm8hDd.cjs} +70 -147
  2. package/dist/PluginDriver-BQwm8hDd.cjs.map +1 -0
  3. package/dist/{PluginDriver-B_65W4fv.js → PluginDriver-CgXFtmNP.js} +36 -96
  4. package/dist/PluginDriver-CgXFtmNP.js.map +1 -0
  5. package/dist/index.cjs +23 -341
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.ts +5 -317
  8. package/dist/index.js +23 -311
  9. package/dist/index.js.map +1 -1
  10. package/dist/mocks.cjs +2 -3
  11. package/dist/mocks.cjs.map +1 -1
  12. package/dist/mocks.d.ts +2 -2
  13. package/dist/mocks.js +2 -2
  14. package/dist/mocks.js.map +1 -1
  15. package/dist/{PluginDriver-C9iBgYbk.d.ts → types-DUc5lEUp.d.ts} +596 -714
  16. package/package.json +4 -11
  17. package/src/PluginDriver.ts +18 -17
  18. package/src/constants.ts +0 -48
  19. package/src/createKubb.ts +1 -1
  20. package/src/defineResolver.ts +3 -3
  21. package/src/index.ts +3 -20
  22. package/src/mocks.ts +3 -3
  23. package/src/storages/fsStorage.ts +27 -7
  24. package/src/types.ts +3 -11
  25. package/src/utils/TreeNode.ts +3 -3
  26. package/src/utils/executeStrategies.ts +0 -16
  27. package/dist/PluginDriver-B_65W4fv.js.map +0 -1
  28. package/dist/PluginDriver-CCdkwR14.cjs.map +0 -1
  29. package/dist/chunk-ByKO4r7w.cjs +0 -38
  30. package/dist/hooks.cjs +0 -32
  31. package/dist/hooks.cjs.map +0 -1
  32. package/dist/hooks.d.ts +0 -23
  33. package/dist/hooks.js +0 -29
  34. package/dist/hooks.js.map +0 -1
  35. package/src/hooks/index.ts +0 -3
  36. package/src/hooks/useDriver.ts +0 -9
  37. package/src/hooks/useMode.ts +0 -8
  38. package/src/hooks/usePlugin.ts +0 -9
  39. package/src/utils/FunctionParams.ts +0 -155
  40. package/src/utils/formatters.ts +0 -45
  41. package/src/utils/getFunctionParams.ts +0 -254
  42. package/src/utils/linters.ts +0 -45
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/core",
3
- "version": "5.0.0-alpha.36",
3
+ "version": "5.0.0-alpha.39",
4
4
  "description": "Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -31,10 +31,6 @@
31
31
  "import": "./dist/index.js",
32
32
  "require": "./dist/index.cjs"
33
33
  },
34
- "./hooks": {
35
- "import": "./dist/hooks.js",
36
- "require": "./dist/hooks.cjs"
37
- },
38
34
  "./mocks": {
39
35
  "import": "./dist/mocks.js",
40
36
  "require": "./dist/mocks.cjs"
@@ -44,9 +40,6 @@
44
40
  "types": "./dist/index.d.ts",
45
41
  "typesVersions": {
46
42
  "*": {
47
- "hooks": [
48
- "./dist/hooks.d.ts"
49
- ],
50
43
  "mocks": [
51
44
  "./dist/mocks.d.ts"
52
45
  ]
@@ -75,8 +68,8 @@
75
68
  "remeda": "^2.33.7",
76
69
  "semver": "^7.7.4",
77
70
  "tinyexec": "^1.1.1",
78
- "@kubb/ast": "5.0.0-alpha.36",
79
- "@kubb/renderer-jsx": "5.0.0-alpha.36"
71
+ "@kubb/ast": "5.0.0-alpha.39",
72
+ "@kubb/renderer-jsx": "5.0.0-alpha.39"
80
73
  },
81
74
  "devDependencies": {
82
75
  "@types/semver": "^7.7.1",
@@ -84,7 +77,7 @@
84
77
  "@internals/utils": "0.0.0"
85
78
  },
86
79
  "peerDependencies": {
87
- "@kubb/renderer-jsx": "5.0.0-alpha.36"
80
+ "@kubb/renderer-jsx": "5.0.0-alpha.39"
88
81
  },
89
82
  "engines": {
90
83
  "node": ">=22"
@@ -73,21 +73,6 @@ export type GetFileOptions<TOptions = object> = {
73
73
  options?: TOptions
74
74
  }
75
75
 
76
- /**
77
- * Returns `'single'` when `fileOrFolder` has a file extension, `'split'` otherwise.
78
- *
79
- * @example
80
- * ```ts
81
- * getMode('src/gen/types.ts') // 'single'
82
- * getMode('src/gen/types') // 'split'
83
- * ```
84
- */
85
- export function getMode(fileOrFolder: string | undefined | null): 'single' | 'split' {
86
- if (!fileOrFolder) {
87
- return 'split'
88
- }
89
- return extname(fileOrFolder) ? 'single' : 'split'
90
- }
91
76
 
92
77
  const hookFirstNullCheck = (state: unknown) => !!(state as SafeParseResult<'resolveName'> | null)?.result
93
78
 
@@ -95,6 +80,22 @@ export class PluginDriver {
95
80
  readonly config: Config
96
81
  readonly options: Options
97
82
 
83
+ /**
84
+ * Returns `'single'` when `fileOrFolder` has a file extension, `'split'` otherwise.
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * PluginDriver.getMode('src/gen/types.ts') // 'single'
89
+ * PluginDriver.getMode('src/gen/types') // 'split'
90
+ * ```
91
+ */
92
+ static getMode(fileOrFolder: string | undefined | null): 'single' | 'split' {
93
+ if (!fileOrFolder) {
94
+ return 'split'
95
+ }
96
+ return extname(fileOrFolder) ? 'single' : 'split'
97
+ }
98
+
98
99
  /**
99
100
  * The universal `@kubb/ast` `InputNode` produced by the adapter, set by
100
101
  * the build pipeline after the adapter's `parse()` resolves.
@@ -301,7 +302,7 @@ export class PluginDriver {
301
302
  *
302
303
  * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
303
304
  */
304
- registerGenerator(pluginName: string, gen: Generator<any>): void {
305
+ registerGenerator(pluginName: string, gen: Generator): void {
305
306
  const resolveRenderer = () => {
306
307
  const plugin = this.plugins.get(pluginName)
307
308
  return gen.renderer === null ? undefined : (gen.renderer ?? plugin?.renderer ?? this.config.renderer)
@@ -422,7 +423,7 @@ export class PluginDriver {
422
423
  return resolve(driver.config.root, driver.config.output.path)
423
424
  },
424
425
  getMode(output: { path: string }): 'single' | 'split' {
425
- return getMode(resolve(driver.config.root, driver.config.output.path, output.path))
426
+ return PluginDriver.getMode(resolve(driver.config.root, driver.config.output.path, output.path))
426
427
  },
427
428
  hooks: driver.hooks,
428
429
  plugin,
package/src/constants.ts CHANGED
@@ -49,52 +49,4 @@ export const logLevel = {
49
49
  debug: 5,
50
50
  } as const
51
51
 
52
- /**
53
- * CLI command descriptors for each supported linter.
54
- *
55
- * Each entry contains the executable `command`, an `args` factory that maps an
56
- * output path to the correct argument list, and an `errorMessage` shown when
57
- * the linter is not found.
58
- */
59
- export const linters = {
60
- eslint: {
61
- command: 'eslint',
62
- args: (outputPath: string) => [outputPath, '--fix'],
63
- errorMessage: 'Eslint not found',
64
- },
65
- biome: {
66
- command: 'biome',
67
- args: (outputPath: string) => ['lint', '--fix', outputPath],
68
- errorMessage: 'Biome not found',
69
- },
70
- oxlint: {
71
- command: 'oxlint',
72
- args: (outputPath: string) => ['--fix', outputPath],
73
- errorMessage: 'Oxlint not found',
74
- },
75
- } as const
76
52
 
77
- /**
78
- * CLI command descriptors for each supported code formatter.
79
- *
80
- * Each entry contains the executable `command`, an `args` factory that maps an
81
- * output path to the correct argument list, and an `errorMessage` shown when
82
- * the formatter is not found.
83
- */
84
- export const formatters = {
85
- prettier: {
86
- command: 'prettier',
87
- args: (outputPath: string) => ['--ignore-unknown', '--write', outputPath],
88
- errorMessage: 'Prettier not found',
89
- },
90
- biome: {
91
- command: 'biome',
92
- args: (outputPath: string) => ['format', '--write', outputPath],
93
- errorMessage: 'Biome not found',
94
- },
95
- oxfmt: {
96
- command: 'oxfmt',
97
- args: (outputPath: string) => [outputPath],
98
- errorMessage: 'Oxfmt not found',
99
- },
100
- } as const
package/src/createKubb.ts CHANGED
@@ -187,7 +187,7 @@ async function runPluginAstHooks(plugin: Plugin, context: PluginContext): Promis
187
187
  throw new Error(`[${plugin.name}] No adapter found. Add an OAS adapter (e.g. pluginOas()) before this plugin in your Kubb config.`)
188
188
  }
189
189
 
190
- function resolveRenderer(gen: Generator<any>): RendererFactory | undefined {
190
+ function resolveRenderer(gen: Generator): RendererFactory | undefined {
191
191
  return gen.renderer === null ? undefined : (gen.renderer ?? plugin.renderer ?? context.config.renderer)
192
192
  }
193
193
 
@@ -2,7 +2,7 @@ import path from 'node:path'
2
2
  import { camelCase, pascalCase } from '@internals/utils'
3
3
  import type { FileNode, InputNode, Node, OperationNode, SchemaNode } from '@kubb/ast'
4
4
  import { createFile, isOperationNode, isSchemaNode } from '@kubb/ast'
5
- import { getMode } from './PluginDriver.ts'
5
+ import { PluginDriver } from './PluginDriver.ts'
6
6
  import type {
7
7
  Config,
8
8
  PluginFactoryOptions,
@@ -195,7 +195,7 @@ export function defaultResolveOptions<TOptions>(
195
195
  * ```
196
196
  */
197
197
  export function defaultResolvePath({ baseName, pathMode, tag, path: groupPath }: ResolverPathParams, { root, output, group }: ResolverContext): string {
198
- const mode = pathMode ?? getMode(path.resolve(root, output.path))
198
+ const mode = pathMode ?? PluginDriver.getMode(path.resolve(root, output.path))
199
199
 
200
200
  if (mode === 'single') {
201
201
  return path.resolve(root, output.path)
@@ -236,7 +236,7 @@ export function defaultResolvePath({ baseName, pathMode, tag, path: groupPath }:
236
236
  * ```
237
237
  */
238
238
  export function defaultResolveFile(this: Resolver, { name, extname, tag, path: groupPath }: ResolverFileParams, context: ResolverContext): FileNode {
239
- const pathMode = getMode(path.resolve(context.root, context.output.path))
239
+ const pathMode = PluginDriver.getMode(path.resolve(context.root, context.output.path))
240
240
  const resolvedName = pathMode === 'single' ? '' : this.default(name, 'file')
241
241
  const baseName = `${resolvedName}${extname}` as FileNode['baseName']
242
242
  const filePath = this.resolvePath({ baseName, pathMode, tag, path: groupPath }, context)
package/src/index.ts CHANGED
@@ -1,36 +1,19 @@
1
1
  export { AsyncEventEmitter, URLPath } from '@internals/utils'
2
2
  export * as ast from '@kubb/ast'
3
- export { composeTransformers, definePrinter } from '@kubb/ast'
4
- export { formatters, linters, logLevel } from './constants.ts'
3
+ export { logLevel } from './constants.ts'
5
4
  export { createAdapter } from './createAdapter.ts'
6
5
  export { createKubb } from './createKubb.ts'
7
- export { createPlugin } from './createPlugin.ts'
8
6
  export { createRenderer } from './createRenderer.ts'
9
7
  export { createStorage } from './createStorage.ts'
10
8
  export { defineGenerator } from './defineGenerator.ts'
11
9
  export { defineLogger } from './defineLogger.ts'
12
10
  export { defineParser } from './defineParser.ts'
13
11
  export { definePlugin } from './definePlugin.ts'
14
- export {
15
- buildDefaultBanner,
16
- defaultResolveBanner,
17
- defaultResolveFile,
18
- defaultResolveFooter,
19
- defaultResolveOptions,
20
- defaultResolvePath,
21
- defineResolver,
22
- } from './defineResolver.ts'
12
+ export { defineResolver } from './defineResolver.ts'
23
13
  export { FileManager } from './FileManager.ts'
24
14
  export { FileProcessor } from './FileProcessor.ts'
25
- export { getMode, PluginDriver } from './PluginDriver.ts'
15
+ export { PluginDriver } from './PluginDriver.ts'
26
16
  export { fsStorage } from './storages/fsStorage.ts'
27
17
  export { memoryStorage } from './storages/memoryStorage.ts'
28
18
  export * from './types.ts'
29
- export type { FunctionParamsAST } from './utils/FunctionParams.ts'
30
- export { detectFormatter } from './utils/formatters.ts'
31
- export { getBarrelFiles } from './utils/getBarrelFiles.ts'
32
- export type { Param, Params } from './utils/getFunctionParams.ts'
33
- export { createFunctionParams, FunctionParams, getFunctionParams } from './utils/getFunctionParams.ts'
34
19
  export { isInputPath } from './utils/isInputPath.ts'
35
- export { detectLinter } from './utils/linters.ts'
36
- export { satisfiesDependency } from './utils/packageJSON.ts'
package/src/mocks.ts CHANGED
@@ -2,7 +2,7 @@ import { resolve } from 'node:path'
2
2
  import type { FileNode, OperationNode, SchemaNode, Visitor } from '@kubb/ast'
3
3
  import { transform } from '@kubb/ast'
4
4
  import { FileManager } from './FileManager.ts'
5
- import { getMode, type PluginDriver } from './PluginDriver.ts'
5
+ import { PluginDriver } from './PluginDriver.ts'
6
6
  import { applyHookResult } from './renderNode.ts'
7
7
  import type {
8
8
  Adapter,
@@ -47,7 +47,7 @@ function pascalCase(text: string): string {
47
47
  /**
48
48
  * Creates a minimal `PluginDriver` mock suitable for unit tests.
49
49
  */
50
- export function createMockedPluginDriver(options: { name?: string; plugin?: Plugin<any>; config?: Config } = {}): PluginDriver {
50
+ export function createMockedPluginDriver(options: { name?: string; plugin?: Plugin; config?: Config } = {}): PluginDriver {
51
51
  return {
52
52
  resolveName: (result: ResolveNameParams) => {
53
53
  if (result.type === 'file') {
@@ -162,7 +162,7 @@ function createMockedPluginContext<TOptions extends PluginFactoryOptions>(opts:
162
162
  return {
163
163
  config: opts.config,
164
164
  root,
165
- getMode: (output: { path: string }) => getMode(resolve(root, output.path)),
165
+ getMode: (output: { path: string }) => PluginDriver.getMode(resolve(root, output.path)),
166
166
  adapter: opts.adapter,
167
167
  resolver: opts.resolver,
168
168
  plugin: opts.plugin,
@@ -4,6 +4,13 @@ import { join, resolve } from 'node:path'
4
4
  import { clean, write } from '@internals/utils'
5
5
  import { createStorage } from '../createStorage.ts'
6
6
 
7
+ /**
8
+ * Detects the filesystem error used to indicate that a path does not exist.
9
+ */
10
+ function isMissingPathError(error: unknown): error is NodeJS.ErrnoException {
11
+ return typeof error === 'object' && error !== null && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT'
12
+ }
13
+
7
14
  /**
8
15
  * Built-in filesystem storage driver.
9
16
  *
@@ -33,15 +40,23 @@ export const fsStorage = createStorage(() => ({
33
40
  try {
34
41
  await access(resolve(key))
35
42
  return true
36
- } catch {
37
- return false
43
+ } catch (error) {
44
+ if (isMissingPathError(error)) {
45
+ return false
46
+ }
47
+
48
+ throw new Error(`Failed to access storage item "${key}"`, { cause: error as Error })
38
49
  }
39
50
  },
40
51
  async getItem(key: string) {
41
52
  try {
42
53
  return await readFile(resolve(key), 'utf8')
43
- } catch {
44
- return null
54
+ } catch (error) {
55
+ if (isMissingPathError(error)) {
56
+ return null
57
+ }
58
+
59
+ throw new Error(`Failed to read storage item "${key}"`, { cause: error as Error })
45
60
  }
46
61
  },
47
62
  async setItem(key: string, value: string) {
@@ -52,13 +67,18 @@ export const fsStorage = createStorage(() => ({
52
67
  },
53
68
  async getKeys(base?: string) {
54
69
  const keys: Array<string> = []
70
+ const resolvedBase = resolve(base ?? process.cwd())
55
71
 
56
72
  async function walk(dir: string, prefix: string): Promise<void> {
57
73
  let entries: Array<Dirent>
58
74
  try {
59
75
  entries = (await readdir(dir, { withFileTypes: true })) as Array<Dirent>
60
- } catch {
61
- return
76
+ } catch (error) {
77
+ if (isMissingPathError(error)) {
78
+ return
79
+ }
80
+
81
+ throw new Error(`Failed to list storage keys under "${resolvedBase}"`, { cause: error as Error })
62
82
  }
63
83
  for (const entry of entries) {
64
84
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name
@@ -70,7 +90,7 @@ export const fsStorage = createStorage(() => ({
70
90
  }
71
91
  }
72
92
 
73
- await walk(resolve(base ?? process.cwd()), '')
93
+ await walk(resolvedBase, '')
74
94
 
75
95
  return keys
76
96
  },
package/src/types.ts CHANGED
@@ -435,7 +435,7 @@ export type UserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOpti
435
435
  * over `plugin.renderer`; set `renderer: null` on a generator to opt out of rendering even
436
436
  * when the plugin declares a renderer.
437
437
  */
438
- generators?: Array<Generator<any>>
438
+ generators?: Array<Generator>
439
439
  /**
440
440
  * Specifies the plugins that the current plugin depends on. The current plugin is executed after all listed plugins.
441
441
  * An error is returned if any required dependency plugin is missing.
@@ -555,7 +555,7 @@ export type Plugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions>
555
555
  * over `plugin.renderer`; set `renderer: null` on a generator to opt out of rendering even
556
556
  * when the plugin declares a renderer.
557
557
  */
558
- generators?: Array<Generator<any>>
558
+ generators?: Array<Generator>
559
559
 
560
560
  buildStart: (this: PluginContext<TOptions>) => PossiblePromise<void>
561
561
  /**
@@ -696,7 +696,7 @@ export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryO
696
696
  /**
697
697
  * Returns the output mode for the given output config.
698
698
  * Returns `'single'` when `output.path` has a file extension, `'split'` otherwise.
699
- * Shorthand for `getMode(path.resolve(this.root, output.path))`.
699
+ * Shorthand for `PluginDriver.getMode(path.resolve(this.root, output.path))`.
700
700
  */
701
701
  getMode: (output: { path: string }) => 'single' | 'split'
702
702
  driver: PluginDriver
@@ -1148,14 +1148,6 @@ export type PossibleConfig<TCliOptions = undefined> =
1148
1148
  | PossiblePromise<Config | Config[]>
1149
1149
  | ((...args: [TCliOptions] extends [undefined] ? [] : [TCliOptions]) => PossiblePromise<Config | Config[]>)
1150
1150
 
1151
- /**
1152
- * All accepted forms of a Kubb configuration.
1153
- * @deprecated
1154
- * Kept for backward compatibility. Prefer `PossibleConfig<CLIOptions>` in new code.
1155
- */
1156
- export type ConfigInput = PossibleConfig<CLIOptions>
1157
-
1158
1151
  export type { BuildOutput } from './createKubb.ts'
1159
1152
  export type { Parser } from './defineParser.ts'
1160
- export type { FunctionParamsAST } from './utils/FunctionParams.ts'
1161
1153
  export type { FileMetaBase } from './utils/getBarrelFiles.ts'
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path'
2
2
  import type { FileNode } from '@kubb/ast'
3
- import { getMode } from '../PluginDriver.ts'
3
+ import { PluginDriver } from '../PluginDriver.ts'
4
4
 
5
5
  type BarrelData = {
6
6
  file?: FileNode
@@ -155,7 +155,7 @@ export class TreeNode {
155
155
  name: filteredTree.name,
156
156
  path: filteredTree.path,
157
157
  file: filteredTree.file,
158
- type: getMode(filteredTree.path),
158
+ type: PluginDriver.getMode(filteredTree.path),
159
159
  })
160
160
 
161
161
  const recurse = (node: typeof treeNode, item: DirectoryTree) => {
@@ -163,7 +163,7 @@ export class TreeNode {
163
163
  name: item.name,
164
164
  path: item.path,
165
165
  file: item.file,
166
- type: getMode(item.path),
166
+ type: PluginDriver.getMode(item.path),
167
167
  })
168
168
 
169
169
  if (item.children?.length) {
@@ -82,19 +82,3 @@ export function hookParallel<TInput extends Array<PromiseFunc<TValue, null>>, TV
82
82
 
83
83
  return Promise.allSettled(tasks) as TOutput
84
84
  }
85
-
86
- /**
87
- * Execution strategy used when dispatching plugin hook calls.
88
- * @deprecated
89
- */
90
- export type Strategy = 'seq' | 'first' | 'parallel'
91
-
92
- type StrategyOutputMap<TInput extends Array<PromiseFunc<TValue, null>>, TValue> = {
93
- first: HookFirstOutput<TInput, TValue>
94
- seq: SeqOutput<TInput, TValue>
95
- parallel: HookParallelOutput<TInput, TValue>
96
- }
97
- /**
98
- * @deprecated
99
- */
100
- export type StrategySwitch<TStrategy extends Strategy, TInput extends Array<PromiseFunc<TValue, null>>, TValue> = StrategyOutputMap<TInput, TValue>[TStrategy]