@kubb/core 1.15.0-canary.20231112T135011 → 2.0.0-alpha.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.
Files changed (55) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +1253 -1088
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +396 -411
  5. package/dist/index.d.ts +396 -411
  6. package/dist/index.js +1194 -1018
  7. package/dist/index.js.map +1 -1
  8. package/dist/utils.cjs +1272 -0
  9. package/dist/utils.cjs.map +1 -0
  10. package/dist/utils.d.cts +239 -0
  11. package/dist/utils.d.ts +239 -0
  12. package/dist/utils.js +1219 -0
  13. package/dist/utils.js.map +1 -0
  14. package/globals.d.ts +33 -16
  15. package/package.json +21 -14
  16. package/src/BarrelManager.ts +123 -0
  17. package/src/FileManager.ts +524 -0
  18. package/src/Generator.ts +34 -0
  19. package/src/PackageManager.ts +178 -0
  20. package/src/PluginManager.ts +629 -0
  21. package/src/PromiseManager.ts +51 -0
  22. package/src/SchemaGenerator.ts +8 -0
  23. package/src/build.ts +207 -0
  24. package/src/config.ts +22 -0
  25. package/src/errors.ts +12 -0
  26. package/src/index.ts +28 -0
  27. package/src/plugin.ts +80 -0
  28. package/src/types.ts +353 -0
  29. package/src/utils/EventEmitter.ts +24 -0
  30. package/src/utils/FunctionParams.ts +85 -0
  31. package/src/utils/Queue.ts +110 -0
  32. package/src/utils/TreeNode.ts +122 -0
  33. package/src/utils/URLPath.ts +133 -0
  34. package/src/utils/cache.ts +35 -0
  35. package/src/utils/clean.ts +5 -0
  36. package/src/utils/executeStrategies.ts +83 -0
  37. package/src/utils/index.ts +19 -0
  38. package/src/utils/logger.ts +76 -0
  39. package/src/utils/promise.ts +13 -0
  40. package/src/utils/randomColour.ts +39 -0
  41. package/src/utils/read.ts +68 -0
  42. package/src/utils/renderTemplate.ts +31 -0
  43. package/src/utils/throttle.ts +30 -0
  44. package/src/utils/timeout.ts +7 -0
  45. package/src/utils/transformers/combineCodes.ts +3 -0
  46. package/src/utils/transformers/createJSDocBlockText.ts +15 -0
  47. package/src/utils/transformers/escape.ts +31 -0
  48. package/src/utils/transformers/indent.ts +3 -0
  49. package/src/utils/transformers/index.ts +22 -0
  50. package/src/utils/transformers/nameSorter.ts +9 -0
  51. package/src/utils/transformers/searchAndReplace.ts +25 -0
  52. package/src/utils/transformers/transformReservedWord.ts +97 -0
  53. package/src/utils/transformers/trim.ts +3 -0
  54. package/src/utils/uniqueName.ts +20 -0
  55. package/src/utils/write.ts +63 -0
package/src/build.ts ADDED
@@ -0,0 +1,207 @@
1
+ import pc from 'picocolors'
2
+
3
+ import { clean } from './utils/clean.ts'
4
+ import { createLogger, LogLevel } from './utils/logger.ts'
5
+ import { randomPicoColour } from './utils/randomColour.ts'
6
+ import { read } from './utils/read.ts'
7
+ import { URLPath } from './utils/URLPath.ts'
8
+ import { isInputPath } from './config.ts'
9
+ import { FileManager } from './FileManager.ts'
10
+ import { PluginManager } from './PluginManager.ts'
11
+ import { isPromise } from './PromiseManager.ts'
12
+
13
+ import type { KubbFile } from './FileManager.ts'
14
+ import type { KubbPlugin, PluginContext, PluginParameter, TransformResult } from './types.ts'
15
+ import type { Logger } from './utils/logger.ts'
16
+ import type { QueueJob } from './utils/Queue.ts'
17
+
18
+ type BuildOptions = {
19
+ config: PluginContext['config']
20
+ /**
21
+ * @default Logger without the spinner
22
+ */
23
+ logger?: Logger
24
+ }
25
+
26
+ type BuildOutput = {
27
+ files: FileManager['files']
28
+ pluginManager: PluginManager
29
+ /**
30
+ * Only for safeBuild
31
+ */
32
+ error?: Error
33
+ }
34
+
35
+ async function transformReducer(
36
+ this: PluginContext,
37
+ _previousCode: string,
38
+ result: TransformResult | Promise<TransformResult>,
39
+ _plugin: KubbPlugin,
40
+ ): Promise<string | null> {
41
+ return result
42
+ }
43
+
44
+ async function setup(options: BuildOptions): Promise<PluginManager> {
45
+ const { config, logger = createLogger({ logLevel: LogLevel.silent }) } = options
46
+
47
+ try {
48
+ if (isInputPath(config) && !new URLPath(config.input.path).isURL) {
49
+ await read(config.input.path)
50
+ }
51
+ } catch (e) {
52
+ if (isInputPath(config)) {
53
+ throw new Error(
54
+ 'Cannot read file/URL defined in `input.path` or set with `kubb generate PATH` in the CLI of your Kubb config ' + pc.dim(config.input.path),
55
+ {
56
+ cause: e,
57
+ },
58
+ )
59
+ }
60
+ }
61
+
62
+ if (config.output.clean) {
63
+ await clean(config.output.path)
64
+ }
65
+
66
+ const queueTask = async (file: KubbFile.File) => {
67
+ const { path } = file
68
+
69
+ let code: string | null = FileManager.getSource(file)
70
+
71
+ const { result: loadedResult } = await pluginManager.hookFirst({
72
+ hookName: 'load',
73
+ parameters: [path],
74
+ })
75
+ if (loadedResult && isPromise(loadedResult)) {
76
+ code = await loadedResult
77
+ }
78
+ if (loadedResult && !isPromise(loadedResult)) {
79
+ code = loadedResult
80
+ }
81
+
82
+ if (code) {
83
+ const transformedCode = await pluginManager.hookReduceArg0({
84
+ hookName: 'transform',
85
+ parameters: [code, path],
86
+ reduce: transformReducer,
87
+ })
88
+
89
+ if (config.output.write || config.output.write === undefined) {
90
+ if (file.meta?.pluginKey) {
91
+ // run only for pluginKey defined in the meta of the file
92
+ return pluginManager.hookForPlugin({
93
+ pluginKey: file.meta?.pluginKey,
94
+ hookName: 'writeFile',
95
+ parameters: [transformedCode, path],
96
+ })
97
+ }
98
+
99
+ return pluginManager.hookFirst({
100
+ hookName: 'writeFile',
101
+ parameters: [transformedCode, path],
102
+ })
103
+ }
104
+ }
105
+ }
106
+
107
+ const pluginManager = new PluginManager(config, { logger, task: queueTask as QueueJob<KubbFile.ResolvedFile>, writeTimeout: 0 })
108
+
109
+ pluginManager.on('execute', (executer) => {
110
+ const { hookName, parameters, plugin } = executer
111
+
112
+ if (hookName === 'writeFile' && logger.spinner) {
113
+ const [code] = parameters as PluginParameter<'writeFile'>
114
+
115
+ if (logger.logLevel === LogLevel.info) {
116
+ logger.spinner.start(`💾 Writing`)
117
+ }
118
+
119
+ if (logger.logLevel === 'debug') {
120
+ logger.info(`PluginKey ${pc.dim(JSON.stringify(plugin.key))} \nwith source\n\n${code}`)
121
+ }
122
+ }
123
+ })
124
+
125
+ pluginManager.on('executed', (executer) => {
126
+ const { hookName, plugin, output, parameters } = executer
127
+ const messsage = `${randomPicoColour(plugin.name)} Executing ${hookName}`
128
+
129
+ if (logger.logLevel === LogLevel.info && logger.spinner) {
130
+ if (hookName === 'writeFile') {
131
+ const [_code, path] = parameters as PluginParameter<'writeFile'>
132
+
133
+ logger.spinner.suffixText = pc.dim(path)
134
+ } else {
135
+ logger.spinner.suffixText = messsage
136
+ }
137
+ }
138
+
139
+ if (logger.logLevel === LogLevel.debug) {
140
+ logger.info(messsage)
141
+ const logs = [
142
+ parameters && `${pc.bgWhite(`Parameters`)} ${randomPicoColour(plugin.name)} ${hookName}`,
143
+ JSON.stringify(parameters, undefined, 2),
144
+ output && `${pc.bgWhite('Output')} ${randomPicoColour(plugin.name)} ${hookName}`,
145
+ output,
146
+ ].filter(Boolean)
147
+
148
+ console.log(logs.join('\n'))
149
+ }
150
+ })
151
+
152
+ return pluginManager
153
+ }
154
+
155
+ export async function build(options: BuildOptions): Promise<BuildOutput> {
156
+ const pluginManager = await setup(options)
157
+
158
+ const { fileManager, logger } = pluginManager
159
+
160
+ await pluginManager.hookParallel<'validate', true>({
161
+ hookName: 'validate',
162
+ parameters: [pluginManager.plugins],
163
+ })
164
+
165
+ await pluginManager.hookParallel({
166
+ hookName: 'buildStart',
167
+ parameters: [options.config],
168
+ })
169
+
170
+ await pluginManager.hookParallel({ hookName: 'buildEnd' })
171
+
172
+ if (!fileManager.isExecuting && logger.spinner) {
173
+ logger.spinner.suffixText = ''
174
+ logger.spinner.succeed(`💾 Writing completed`)
175
+ }
176
+
177
+ return { files: fileManager.files.map((file) => ({ ...file, source: FileManager.getSource(file) })), pluginManager }
178
+ }
179
+
180
+ export async function safeBuild(options: BuildOptions): Promise<BuildOutput> {
181
+ const pluginManager = await setup(options)
182
+
183
+ const { fileManager, logger } = pluginManager
184
+
185
+ try {
186
+ await pluginManager.hookParallel<'validate', true>({
187
+ hookName: 'validate',
188
+ parameters: [pluginManager.plugins],
189
+ })
190
+
191
+ await pluginManager.hookParallel({
192
+ hookName: 'buildStart',
193
+ parameters: [options.config],
194
+ })
195
+
196
+ await pluginManager.hookParallel({ hookName: 'buildEnd' })
197
+
198
+ if (!fileManager.isExecuting && logger.spinner) {
199
+ logger.spinner.suffixText = ''
200
+ logger.spinner.succeed(`💾 Writing completed`)
201
+ }
202
+ } catch (e) {
203
+ return { files: fileManager.files.map((file) => ({ ...file, source: FileManager.getSource(file) })), pluginManager, error: e as Error }
204
+ }
205
+
206
+ return { files: fileManager.files.map((file) => ({ ...file, source: FileManager.getSource(file) })), pluginManager }
207
+ }
package/src/config.ts ADDED
@@ -0,0 +1,22 @@
1
+ import type { PossiblePromise } from '@kubb/types'
2
+ import type { CLIOptions, InputPath, KubbConfig, KubbUserConfig } from './types.ts'
3
+
4
+ /**
5
+ * Type helper to make it easier to use kubb.config.js
6
+ * accepts a direct {@link KubbConfig} object, or a function that returns it.
7
+ * The function receives a {@link ConfigEnv} object that exposes two properties:
8
+ */
9
+ export function defineConfig(
10
+ options:
11
+ | PossiblePromise<KubbUserConfig | Array<KubbUserConfig>>
12
+ | ((
13
+ /** The options derived from the CLI flags */
14
+ cliOptions: CLIOptions,
15
+ ) => PossiblePromise<KubbUserConfig | Array<KubbUserConfig>>),
16
+ ): typeof options {
17
+ return options
18
+ }
19
+
20
+ export function isInputPath(result: KubbConfig | undefined): result is KubbConfig<InputPath> {
21
+ return !!result && 'path' in (result as any)
22
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Behaves as an Error to log a warning in the console(still stops the execution)
3
+ */
4
+ export class Warning extends Error {
5
+ constructor(message?: string, options?: { cause: Error }) {
6
+ super(message, { cause: options?.cause })
7
+
8
+ this.name = 'Warning'
9
+ }
10
+ }
11
+
12
+ export class ValidationPluginError extends Error {}
package/src/index.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { build } from './build.ts'
2
+
3
+ import type { ObjValueTuple, TupleToUnion } from '@kubb/types'
4
+
5
+ export { build, safeBuild } from './build.ts'
6
+ export * from './config.ts'
7
+ export * from './errors.ts'
8
+ export * from './FileManager.ts'
9
+ export { Generator } from './Generator.ts'
10
+ export { PackageManager } from './PackageManager.ts'
11
+ // dprint-ignore
12
+ export { createPlugin, pluginName as name, pluginName } from './plugin.ts'
13
+ export { PluginManager } from './PluginManager.ts'
14
+ export { PromiseManager } from './PromiseManager.ts'
15
+ export { SchemaGenerator } from './SchemaGenerator.ts'
16
+ export * from './types.ts'
17
+
18
+ export interface _Register {}
19
+ export type Plugins = _Register
20
+ export type OptionsPlugins = { [K in keyof Plugins]: Plugins[K]['options'] }
21
+
22
+ export type OptionsOfPlugin<K extends keyof Plugins> = Plugins[K]['options']
23
+
24
+ export type PluginUnion = TupleToUnion<ObjValueTuple<OptionsPlugins>>
25
+
26
+ export type Plugin = keyof Plugins
27
+
28
+ export default build
package/src/plugin.ts ADDED
@@ -0,0 +1,80 @@
1
+ import path from 'node:path'
2
+
3
+ import { createPluginCache } from './utils/cache.ts'
4
+
5
+ import type { FileManager } from './FileManager.ts'
6
+ import type { PluginManager } from './PluginManager.ts'
7
+ import type { KubbPlugin, KubbUserPluginWithLifeCycle, PluginContext, PluginFactoryOptions } from './types.ts'
8
+
9
+ type KubbPluginFactory<T extends PluginFactoryOptions = PluginFactoryOptions> = (options: T['options']) => KubbUserPluginWithLifeCycle<T>
10
+
11
+ export function createPlugin<T extends PluginFactoryOptions = PluginFactoryOptions>(factory: KubbPluginFactory<T>) {
12
+ return (options: T['options']): ReturnType<KubbPluginFactory<T>> => {
13
+ return factory(options)
14
+ }
15
+ }
16
+
17
+ type Options = {
18
+ config: PluginContext['config']
19
+ fileManager: FileManager
20
+ pluginManager: PluginManager
21
+ resolvePath: PluginContext['resolvePath']
22
+ resolveName: PluginContext['resolveName']
23
+ logger: PluginContext['logger']
24
+ getPlugins: () => KubbPlugin[]
25
+ plugin?: PluginContext['plugin']
26
+ }
27
+
28
+ // not publicly exported
29
+ export type CorePluginOptions = PluginFactoryOptions<'core', 'controller', Options, Options, PluginContext, never>
30
+
31
+ export const pluginName = 'core' satisfies CorePluginOptions['name']
32
+ export const pluginKey: CorePluginOptions['key'] = ['controller', pluginName] satisfies CorePluginOptions['key']
33
+
34
+ export const definePlugin = createPlugin<CorePluginOptions>((options) => {
35
+ const { fileManager, pluginManager, resolvePath, resolveName, logger } = options
36
+
37
+ return {
38
+ name: pluginName,
39
+ options,
40
+ key: ['controller', 'core'],
41
+ kind: 'controller',
42
+ api() {
43
+ return {
44
+ get config() {
45
+ return options.config
46
+ },
47
+ get plugins() {
48
+ return options.getPlugins()
49
+ },
50
+ get plugin() {
51
+ // see pluginManger.#execute where we override with `.call` the this with the correct plugin
52
+ return options.plugin as NonNullable<Options['plugin']>
53
+ },
54
+ logger,
55
+ fileManager,
56
+ pluginManager,
57
+ async addFile(...files) {
58
+ const resolvedFiles = await fileManager.add(...files)
59
+
60
+ if (!Array.isArray(resolvedFiles)) {
61
+ return [resolvedFiles]
62
+ }
63
+
64
+ return resolvedFiles
65
+ },
66
+ resolvePath,
67
+ resolveName,
68
+ cache: createPluginCache(),
69
+ }
70
+ },
71
+ resolvePath(baseName) {
72
+ const root = path.resolve(this.config.root, this.config.output.path)
73
+
74
+ return path.resolve(root, baseName)
75
+ },
76
+ resolveName(name) {
77
+ return name
78
+ },
79
+ }
80
+ })
package/src/types.ts ADDED
@@ -0,0 +1,353 @@
1
+ import type { PossiblePromise } from '@kubb/types'
2
+ import type { FileManager, KubbFile } from './FileManager.ts'
3
+ import type { OptionsPlugins, PluginUnion } from './index.ts'
4
+ import type { PluginManager } from './PluginManager.ts'
5
+ import type { Cache } from './utils/cache.ts'
6
+ import type { Logger, LogLevel } from './utils/logger.ts'
7
+
8
+ // config
9
+
10
+ /**
11
+ * Config used in `kubb.config.js`
12
+ *
13
+ * @example import { defineConfig } from '@kubb/core'
14
+ * export default defineConfig({
15
+ * ...
16
+ * })
17
+ */
18
+ export type KubbUserConfig =
19
+ & Omit<KubbConfig, 'root' | 'plugins'>
20
+ & {
21
+ /**
22
+ * Project root directory. Can be an absolute path, or a path relative from
23
+ * the location of the config file itself.
24
+ * @default process.cwd()
25
+ */
26
+ root?: string
27
+ /**
28
+ * Plugin type can be KubbJSONPlugin or KubbPlugin
29
+ * Example: ['@kubb/swagger', { output: false }]
30
+ * Or: createSwagger({ output: false })
31
+ */
32
+ plugins?: Array<Omit<UnknownKubbUserPlugin, 'api'> | KubbUnionPlugins | [name: string, options: object]>
33
+ }
34
+
35
+ export type InputPath = {
36
+ /**
37
+ * Path to be used as the input. This can be an absolute path or a path relative to the `root`.
38
+ */
39
+ path: string
40
+ }
41
+
42
+ export type InputData = {
43
+ /**
44
+ * `string` or `object` containing the data.
45
+ */
46
+ data: string | unknown
47
+ }
48
+
49
+ type Input = InputPath | InputData
50
+
51
+ /**
52
+ * @private
53
+ */
54
+ export type KubbConfig<TInput = Input> = {
55
+ /**
56
+ * Optional config name to show in CLI output
57
+ */
58
+ name?: string
59
+ /**
60
+ * Project root directory. Can be an absolute path, or a path relative from
61
+ * the location of the config file itself.
62
+ * @default process.cwd()
63
+ */
64
+ root: string
65
+ input: TInput
66
+ output: {
67
+ /**
68
+ * Path to be used to export all generated files.
69
+ * This can be an absolute path, or a path relative based of the defined `root` option.
70
+ */
71
+ path: string
72
+ /**
73
+ * Clean output directory before each build.
74
+ */
75
+ clean?: boolean
76
+ /**
77
+ * Write files to the fileSystem
78
+ * This is being used for the playground.
79
+ * @default true
80
+ */
81
+ write?: boolean
82
+ }
83
+ /**
84
+ * Array of Kubb plugins to use.
85
+ * The plugin/package can forsee some options that you need to pass through.
86
+ * Sometimes a plugin is depended on another plugin, if that's the case you will get an error back from the plugin you installed.
87
+ */
88
+ plugins?: Array<KubbPlugin>
89
+ /**
90
+ * Hooks that will be called when a specific action is triggered in Kubb.
91
+ */
92
+ hooks?: {
93
+ /**
94
+ * Hook that will be triggered at the end of all executions.
95
+ * Useful for running Prettier or ESLint to format/lint your code.
96
+ */
97
+ done?: string | Array<string>
98
+ }
99
+ }
100
+
101
+ export type CLIOptions = {
102
+ /**
103
+ * Path to `kubb.config.js`
104
+ */
105
+ config?: string
106
+ /**
107
+ * Watch changes on input
108
+ */
109
+ watch?: string
110
+
111
+ /**
112
+ * Log level to report when using the CLI
113
+ *
114
+ * `silent` will hide all information that is not relevant
115
+ *
116
+ * `info` will show all information possible(not related to the PluginManager)
117
+ *
118
+ * `debug` will show all information possible(related to the PluginManager), handy for seeing logs
119
+ * @default `silent`
120
+ */
121
+ logLevel?: LogLevel
122
+ }
123
+
124
+ // plugin
125
+
126
+ export type KubbPluginKind = 'schema' | 'controller'
127
+
128
+ export type KubbUnionPlugins = PluginUnion
129
+
130
+ export type KubbObjectPlugin = keyof OptionsPlugins
131
+
132
+ export type PluginFactoryOptions<
133
+ /**
134
+ * Name to be used for the plugin, this will also be used for they key.
135
+ */
136
+ TName extends string = string,
137
+ /**
138
+ * @type "schema" | "controller"
139
+ */
140
+ TKind extends KubbPluginKind = KubbPluginKind,
141
+ /**
142
+ * Options of the plugin.
143
+ */
144
+ TOptions extends object = object,
145
+ /**
146
+ * Options of the plugin that can be used later on, see `options` inside your plugin config.
147
+ */
148
+ TResolvedOptions extends object = TOptions,
149
+ /**
150
+ * API that you want to expose to other plugins.
151
+ */
152
+ TAPI = any,
153
+ /**
154
+ * When calling `resolvePath` you can specify better types.
155
+ */
156
+ TResolvePathOptions extends object = object,
157
+ /**
158
+ * When using @kubb/react(based on React) you can specify here which types should be used when calling render.
159
+ * Always extend from `AppMeta` of the core.
160
+ */
161
+ TAppMeta = unknown,
162
+ > = {
163
+ name: TName
164
+ kind: TKind
165
+ /**
166
+ * Same behaviour like what has been done with `QueryKey` in `@tanstack/react-query`
167
+ */
168
+ key: [kind: TKind | undefined, name: TName | string, identifier?: string | number]
169
+ options: TOptions
170
+ resolvedOptions: TResolvedOptions
171
+ api: TAPI
172
+ resolvePathOptions: TResolvePathOptions
173
+ appMeta: {
174
+ pluginManager: PluginManager
175
+ plugin: KubbPlugin<PluginFactoryOptions<TName, TKind, TOptions, TResolvedOptions, TAPI, TResolvePathOptions, TAppMeta>>
176
+ } & TAppMeta
177
+ }
178
+
179
+ export type GetPluginFactoryOptions<TPlugin extends KubbUserPlugin> = TPlugin extends KubbUserPlugin<infer X> ? X : never
180
+
181
+ export type KubbUserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> =
182
+ & {
183
+ /**
184
+ * Unique name used for the plugin
185
+ * @example @kubb/typescript
186
+ */
187
+ name: TOptions['name']
188
+ /**
189
+ * Internal key used when a developer uses more than one of the same plugin
190
+ * @private
191
+ */
192
+ key?: TOptions['key']
193
+ /**
194
+ * Options set for a specific plugin(see kubb.config.js), passthrough of options.
195
+ */
196
+ options: TOptions['resolvedOptions']
197
+ }
198
+ & (TOptions['api'] extends never ? {
199
+ api?: never
200
+ }
201
+ : {
202
+ api: (this: TOptions['name'] extends 'core' ? null : Omit<PluginContext<TOptions>, 'addFile'>) => TOptions['api']
203
+ })
204
+ & (TOptions['kind'] extends never ? {
205
+ kind?: never
206
+ }
207
+ : {
208
+ /**
209
+ * Kind/type for the plugin
210
+ *
211
+ * Type 'schema' can be used for JSON schema's, TypeScript types, ...
212
+ *
213
+ * Type 'controller' can be used to create generate API calls, React-Query hooks, Axios controllers, ...
214
+ * @default undefined
215
+ */
216
+ kind: TOptions['kind']
217
+ })
218
+
219
+ export type KubbUserPluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = KubbUserPlugin<TOptions> & PluginLifecycle<TOptions>
220
+
221
+ type UnknownKubbUserPlugin = KubbUserPlugin<PluginFactoryOptions<any, any, any, any, any, any, any>>
222
+
223
+ export type KubbPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> =
224
+ & {
225
+ /**
226
+ * Unique name used for the plugin
227
+ * @example @kubb/typescript
228
+ */
229
+ name: TOptions['name']
230
+ /**
231
+ * Internal key used when a developer uses more than one of the same plugin
232
+ * @private
233
+ */
234
+ key: TOptions['key']
235
+ /**
236
+ * Options set for a specific plugin(see kubb.config.js), passthrough of options.
237
+ */
238
+ options: TOptions['resolvedOptions']
239
+ /**
240
+ * Kind/type for the plugin
241
+ * Type 'schema' can be used for JSON schema's, TypeScript types, ...
242
+ * Type 'controller' can be used to create generate API calls, React-Query hooks, Axios controllers, ...
243
+ * @default undefined
244
+ */
245
+ kind?: TOptions['kind']
246
+ /**
247
+ * Define an api that can be used by other plugins, see `PluginManager' where we convert from `KubbUserPlugin` to `KubbPlugin`(used when calling `createPlugin`).
248
+ */
249
+ }
250
+ & (TOptions['api'] extends never ? {
251
+ api?: never
252
+ }
253
+ : {
254
+ api: TOptions['api']
255
+ })
256
+
257
+ export type KubbPluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = KubbPlugin<TOptions> & PluginLifecycle<TOptions>
258
+
259
+ export type PluginLifecycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
260
+ /**
261
+ * Valdiate all plugins to see if their depended plugins are installed and configured.
262
+ * @type hookParallel
263
+ */
264
+ validate?: (this: Omit<PluginContext<TOptions>, 'addFile'>, plugins: NonNullable<KubbConfig['plugins']>) => PossiblePromise<true>
265
+ /**
266
+ * Start of the lifecycle of a plugin.
267
+ * @type hookParallel
268
+ */
269
+ buildStart?: (this: PluginContext<TOptions>, kubbConfig: KubbConfig) => PossiblePromise<void>
270
+ /**
271
+ * Resolve to a Path based on a baseName(example: `./Pet.ts`) and directory(example: `./models`).
272
+ * Options can als be included.
273
+ * @type hookFirst
274
+ * @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'
275
+ */
276
+ resolvePath?: (this: PluginContext<TOptions>, baseName: string, directory?: string, options?: TOptions['resolvePathOptions']) => KubbFile.OptionalPath
277
+ /**
278
+ * Resolve to a name based on a string.
279
+ * Useful when converting to PascalCase or camelCase.
280
+ * @type hookFirst
281
+ * @example ('pet') => 'Pet'
282
+ */
283
+ resolveName?: (this: PluginContext<TOptions>, name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
284
+ /**
285
+ * Makes it possible to run async logic to override the path defined previously by `resolvePath`.
286
+ * @type hookFirst
287
+ */
288
+ load?: (this: Omit<PluginContext<TOptions>, 'addFile'>, path: KubbFile.Path) => PossiblePromise<TransformResult | null>
289
+ /**
290
+ * Transform the source-code.
291
+ * @type hookReduceArg0
292
+ */
293
+ transform?: (this: Omit<PluginContext<TOptions>, 'addFile'>, source: string, path: KubbFile.Path) => PossiblePromise<TransformResult>
294
+ /**
295
+ * Write the result to the file-system based on the id(defined by `resolvePath` or changed by `load`).
296
+ * @type hookParallel
297
+ */
298
+ writeFile?: (this: Omit<PluginContext<TOptions>, 'addFile'>, source: string | undefined, path: KubbFile.Path) => PossiblePromise<string | void>
299
+ /**
300
+ * End of the plugin lifecycle.
301
+ * @type hookParallel
302
+ */
303
+ buildEnd?: (this: PluginContext<TOptions>) => PossiblePromise<void>
304
+ }
305
+
306
+ export type PluginLifecycleHooks = keyof PluginLifecycle
307
+
308
+ export type PluginParameter<H extends PluginLifecycleHooks> = Parameters<Required<PluginLifecycle>[H]>
309
+
310
+ export type PluginCache = Record<string, [number, unknown]>
311
+
312
+ export type ResolvePathParams<TOptions = object> = {
313
+ pluginKey?: KubbPlugin['key']
314
+ baseName: string
315
+ directory?: string | undefined
316
+ /**
317
+ * Options to be passed to 'resolvePath' 3th parameter
318
+ */
319
+ options?: TOptions
320
+ }
321
+
322
+ export type ResolveNameParams = {
323
+ name: string
324
+ pluginKey?: KubbPlugin['key']
325
+ /**
326
+ * `file` will be used to customize the name of the created file(use of camelCase)
327
+ * `function` can be used used to customize the exported functions(use of camelCase)
328
+ * `type` is a special type for TypeScript(use of PascalCase)
329
+ */
330
+ type?: 'file' | 'function' | 'type'
331
+ }
332
+
333
+ export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
334
+ config: KubbConfig
335
+ cache: Cache<PluginCache>
336
+ fileManager: FileManager
337
+ pluginManager: PluginManager
338
+ addFile: (...file: Array<KubbFile.File>) => Promise<Array<KubbFile.File>>
339
+ resolvePath: (params: ResolvePathParams<TOptions['resolvePathOptions']>) => KubbFile.OptionalPath
340
+ resolveName: (params: ResolveNameParams) => string
341
+ logger: Logger
342
+ /**
343
+ * All plugins
344
+ */
345
+ plugins: KubbPlugin[]
346
+ /**
347
+ * Current plugin
348
+ */
349
+ plugin: KubbPlugin<TOptions>
350
+ }
351
+
352
+ // null will mean clear the watcher for this key
353
+ export type TransformResult = string | null