UNPKG

@kubb/core

Version:

Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.

1 lines 52.4 kB
{"version":3,"file":"index.cjs","names":["#context","#options","AsyncEventEmitter","URLPath","exists","clean","fsPlugin","typescriptParser","write","PluginManager","error","BuildError","getElapsedMs","formatMs","getRelativePath","build","Queue","resolve","toPath","process","fsPromises","path","fs","path","#cache","#cwd","#SLASHES","path","mod","os","module","read","readSync","version","#match"],"sources":["../src/BaseGenerator.ts","../src/config.ts","../package.json","../src/utils/diagnostics.ts","../src/build.ts","../src/defineLogger.ts","../src/definePlugin.ts","../../../node_modules/.pnpm/p-limit@4.0.0/node_modules/p-limit/index.js","../../../node_modules/.pnpm/p-locate@6.0.0/node_modules/p-locate/index.js","../../../node_modules/.pnpm/locate-path@7.2.0/node_modules/locate-path/index.js","../../../node_modules/.pnpm/unicorn-magic@0.1.0/node_modules/unicorn-magic/node.js","../../../node_modules/.pnpm/find-up@7.0.0/node_modules/find-up/index.js","../src/PackageManager.ts","../src/types.ts"],"sourcesContent":["/**\n * Abstract class that contains the building blocks for plugins to create their own Generator\n * @link idea based on https://github.com/colinhacks/zod/blob/master/src/types.ts#L137\n */\nexport abstract class BaseGenerator<TOptions = unknown, TContext = unknown> {\n #options: TOptions = {} as TOptions\n #context: TContext = {} as TContext\n\n constructor(options?: TOptions, context?: TContext) {\n if (context) {\n this.#context = context\n }\n\n if (options) {\n this.#options = options\n }\n\n return this\n }\n\n get options(): TOptions {\n return this.#options\n }\n\n get context(): TContext {\n return this.#context\n }\n\n set options(options: TOptions) {\n this.#options = { ...this.#options, ...options }\n }\n\n abstract build(...params: unknown[]): unknown\n}\n","import type { InputPath, UserConfig } from './types.ts'\nimport type { PossiblePromise } from './utils/types.ts'\n\n/**\n * CLI options derived from command-line flags.\n */\nexport type CLIOptions = {\n /** Path to `kubb.config.js` */\n config?: string\n\n /** Enable watch mode for input files */\n watch?: boolean\n\n /**\n * Logging verbosity for CLI usage.\n *\n * - `silent`: hide non-essential logs\n * - `info`: show general logs (non-plugin-related)\n * - `debug`: include detailed plugin lifecycle logs\n * @default 'silent'\n */\n logLevel?: 'silent' | 'info' | 'debug'\n\n /** Run Kubb with Bun */\n bun?: boolean\n}\n/**\n * Helper for defining a Kubb configuration.\n *\n * Accepts either:\n * - A config object or array of configs\n * - A function returning the config(s), optionally async,\n * receiving the CLI options as argument\n *\n * @example\n * export default defineConfig(({ logLevel }) => ({\n * root: 'src',\n * plugins: [myPlugin()],\n * }))\n */\nexport function defineConfig(\n config: PossiblePromise<UserConfig | UserConfig[]> | ((cli: CLIOptions) => PossiblePromise<UserConfig | UserConfig[]>),\n): typeof config {\n return config\n}\n\n/**\n * Type guard to check if a given config has an `input.path`.\n */\nexport function isInputPath(config: UserConfig | undefined): config is UserConfig<InputPath> {\n return typeof config?.input === 'object' && config.input !== null && 'path' in config.input\n}\n","","import { version as nodeVersion } from 'node:process'\nimport { version as KubbVersion } from '../../package.json'\n\n/**\n * Get diagnostic information for debugging\n */\nexport function getDiagnosticInfo() {\n return {\n nodeVersion,\n KubbVersion,\n platform: process.platform,\n arch: process.arch,\n cwd: process.cwd(),\n } as const\n}\n","import { resolve } from 'node:path'\nimport type { KubbFile } from '@kubb/fabric-core/types'\nimport type { Fabric } from '@kubb/react-fabric'\nimport { createFabric } from '@kubb/react-fabric'\nimport { typescriptParser } from '@kubb/react-fabric/parsers'\nimport { fsPlugin } from '@kubb/react-fabric/plugins'\nimport { isInputPath } from './config.ts'\nimport { BuildError } from './errors.ts'\nimport { clean, exists, getRelativePath, write } from './fs/index.ts'\nimport { PluginManager } from './PluginManager.ts'\nimport type { Config, KubbEvents, Output, Plugin, UserConfig } from './types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\nimport { getDiagnosticInfo } from './utils/diagnostics.ts'\nimport { formatMs, getElapsedMs } from './utils/formatHrtime.ts'\nimport { URLPath } from './utils/URLPath.ts'\n\ntype BuildOptions = {\n config: UserConfig\n events?: AsyncEventEmitter<KubbEvents>\n}\n\ntype BuildOutput = {\n failedPlugins: Set<{ plugin: Plugin; error: Error }>\n fabric: Fabric\n files: Array<KubbFile.ResolvedFile>\n pluginManager: PluginManager\n pluginTimings: Map<string, number>\n error?: Error\n}\n\ntype SetupResult = {\n events: AsyncEventEmitter<KubbEvents>\n fabric: Fabric\n pluginManager: PluginManager\n}\n\nexport async function setup(options: BuildOptions): Promise<SetupResult> {\n const { config: userConfig, events = new AsyncEventEmitter<KubbEvents>() } = options\n\n const diagnosticInfo = getDiagnosticInfo()\n\n if (Array.isArray(userConfig.input)) {\n await events.emit('warn', 'This feature is still under development — use with caution')\n }\n\n await events.emit('debug', {\n date: new Date(),\n logs: [\n 'Configuration:',\n ` • Name: ${userConfig.name || 'unnamed'}`,\n ` • Root: ${userConfig.root || process.cwd()}`,\n ` • Output: ${userConfig.output?.path || 'not specified'}`,\n ` • Plugins: ${userConfig.plugins?.length || 0}`,\n 'Output Settings:',\n ` • Write: ${userConfig.output?.write !== false ? 'enabled' : 'disabled'}`,\n ` • Formater: ${userConfig.output?.format || 'none'}`,\n ` • Linter: ${userConfig.output?.lint || 'none'}`,\n 'Environment:',\n Object.entries(diagnosticInfo)\n .map(([key, value]) => ` • ${key}: ${value}`)\n .join('\\n'),\n ],\n })\n\n try {\n if (isInputPath(userConfig) && !new URLPath(userConfig.input.path).isURL) {\n await exists(userConfig.input.path)\n\n await events.emit('debug', {\n date: new Date(),\n logs: [`✓ Input file validated: ${userConfig.input.path}`],\n })\n }\n } catch (caughtError) {\n if (isInputPath(userConfig)) {\n const error = caughtError as Error\n\n throw new Error(\n `Cannot read file/URL defined in \\`input.path\\` or set with \\`kubb generate PATH\\` in the CLI of your Kubb config ${userConfig.input.path}`,\n {\n cause: error,\n },\n )\n }\n }\n\n const definedConfig: Config = {\n root: userConfig.root || process.cwd(),\n ...userConfig,\n output: {\n write: true,\n barrelType: 'named',\n extension: {\n '.ts': '.ts',\n },\n defaultBanner: 'simple',\n ...userConfig.output,\n },\n plugins: userConfig.plugins as Config['plugins'],\n }\n\n if (definedConfig.output.clean) {\n await events.emit('debug', {\n date: new Date(),\n logs: ['Cleaning output directories', ` • Output: ${definedConfig.output.path}`],\n })\n await clean(definedConfig.output.path)\n }\n\n const fabric = createFabric()\n fabric.use(fsPlugin, { dryRun: !definedConfig.output.write })\n fabric.use(typescriptParser)\n\n fabric.context.on('files:processing:start', (files) => {\n events.emit('files:processing:start', files)\n events.emit('debug', {\n date: new Date(),\n logs: [`Writing ${files.length} files...`],\n })\n })\n\n fabric.context.on('file:processing:update', async (params) => {\n const { file, source } = params\n await events.emit('file:processing:update', {\n ...params,\n config: definedConfig,\n source,\n })\n\n if (source) {\n await write(file.path, source, { sanity: false })\n }\n })\n\n fabric.context.on('files:processing:end', async (files) => {\n await events.emit('files:processing:end', files)\n await events.emit('debug', {\n date: new Date(),\n logs: [`✓ File write process completed for ${files.length} files`],\n })\n })\n\n await events.emit('debug', {\n date: new Date(),\n logs: [\n '✓ Fabric initialized',\n ` • File writing: ${definedConfig.output.write ? 'enabled' : 'disabled (dry-run)'}`,\n ` • Barrel type: ${definedConfig.output.barrelType || 'none'}`,\n ],\n })\n\n const pluginManager = new PluginManager(definedConfig, {\n fabric,\n events,\n concurrency: 15, // Increased from 5 to 15 for better parallel plugin execution\n })\n\n return {\n events,\n fabric,\n pluginManager,\n }\n}\n\nexport async function build(options: BuildOptions, overrides?: SetupResult): Promise<BuildOutput> {\n const { fabric, files, pluginManager, failedPlugins, pluginTimings, error } = await safeBuild(options, overrides)\n\n if (error) {\n throw error\n }\n\n if (failedPlugins.size > 0) {\n const errors = [...failedPlugins].map(({ error }) => error)\n\n throw new BuildError(`Build Error with ${failedPlugins.size} failed plugins`, { errors })\n }\n\n return {\n failedPlugins,\n fabric,\n files,\n pluginManager,\n pluginTimings,\n error: undefined,\n }\n}\n\nexport async function safeBuild(options: BuildOptions, overrides?: SetupResult): Promise<BuildOutput> {\n const { fabric, pluginManager, events } = overrides ? overrides : await setup(options)\n\n const failedPlugins = new Set<{ plugin: Plugin; error: Error }>()\n // in ms\n const pluginTimings = new Map<string, number>()\n const config = pluginManager.config\n\n try {\n for (const plugin of pluginManager.plugins) {\n const context = pluginManager.getContext(plugin)\n const hrStart = process.hrtime()\n\n const installer = plugin.install.bind(context)\n\n try {\n const timestamp = new Date()\n\n await events.emit('plugin:start', plugin)\n\n await events.emit('debug', {\n date: timestamp,\n logs: ['Installing plugin...', ` • Plugin Key: [${plugin.key.join(', ')}]`],\n })\n\n await installer(context)\n\n const duration = getElapsedMs(hrStart)\n pluginTimings.set(plugin.name, duration)\n\n await events.emit('plugin:end', plugin, { duration, success: true })\n\n await events.emit('debug', {\n date: new Date(),\n logs: [`✓ Plugin installed successfully (${formatMs(duration)})`],\n })\n } catch (caughtError) {\n const error = caughtError as Error\n const errorTimestamp = new Date()\n const duration = getElapsedMs(hrStart)\n\n await events.emit('plugin:end', plugin, {\n duration,\n success: false,\n error,\n })\n\n await events.emit('debug', {\n date: errorTimestamp,\n logs: [\n '✗ Plugin installation failed',\n ` • Plugin Key: ${JSON.stringify(plugin.key)}`,\n ` • Error: ${error.constructor.name} - ${error.message}`,\n ' • Stack Trace:',\n error.stack || 'No stack trace available',\n ],\n })\n\n failedPlugins.add({ plugin, error })\n }\n }\n\n if (config.output.barrelType) {\n const root = resolve(config.root)\n const rootPath = resolve(root, config.output.path, 'index.ts')\n\n await events.emit('debug', {\n date: new Date(),\n logs: ['Generating barrel file', ` • Type: ${config.output.barrelType}`, ` • Path: ${rootPath}`],\n })\n\n const barrelFiles = fabric.files.filter((file) => {\n return file.sources.some((source) => source.isIndexable)\n })\n\n await events.emit('debug', {\n date: new Date(),\n logs: [`Found ${barrelFiles.length} indexable files for barrel export`],\n })\n\n // Build a Map of plugin keys to plugins for efficient lookups\n const pluginKeyMap = new Map<string, Plugin>()\n for (const plugin of pluginManager.plugins) {\n pluginKeyMap.set(JSON.stringify(plugin.key), plugin)\n }\n\n const rootFile: KubbFile.File = {\n path: rootPath,\n baseName: 'index.ts',\n exports: barrelFiles\n .flatMap((file) => {\n const containsOnlyTypes = file.sources?.every((source) => source.isTypeOnly)\n\n return file.sources\n ?.map((source) => {\n if (!file.path || !source.isIndexable) {\n return undefined\n }\n\n // validate of the file is coming from plugin x, needs pluginKey on every file TODO update typing\n const meta = file.meta as any\n const plugin = meta?.pluginKey ? pluginKeyMap.get(JSON.stringify(meta.pluginKey)) : undefined\n const pluginOptions = plugin?.options as {\n output?: Output<any>\n }\n\n if (!pluginOptions || pluginOptions?.output?.barrelType === false) {\n return undefined\n }\n\n return {\n name: config.output.barrelType === 'all' ? undefined : [source.name],\n path: getRelativePath(rootPath, file.path),\n isTypeOnly: config.output.barrelType === 'all' ? containsOnlyTypes : source.isTypeOnly,\n } as KubbFile.Export\n })\n .filter(Boolean)\n })\n .filter(Boolean),\n sources: [],\n imports: [],\n meta: {},\n }\n\n await fabric.upsertFile(rootFile)\n\n await events.emit('debug', {\n date: new Date(),\n logs: [`✓ Generated barrel file (${rootFile.exports?.length || 0} exports)`],\n })\n }\n\n const files = [...fabric.files]\n\n await fabric.write({ extension: config.output.extension })\n\n return {\n failedPlugins,\n fabric,\n files,\n pluginManager,\n pluginTimings,\n }\n } catch (error) {\n return {\n failedPlugins,\n fabric,\n files: [],\n pluginManager,\n pluginTimings,\n error: error as Error,\n }\n }\n}\n","import type { Logger, LoggerOptions, UserLogger } from './types.ts'\n\nexport function defineLogger<Options extends LoggerOptions = LoggerOptions>(logger: UserLogger<Options>): Logger<Options> {\n return {\n ...logger,\n }\n}\n","import type { PluginFactoryOptions, UserPluginWithLifeCycle } from './types.ts'\n\ntype PluginBuilder<T extends PluginFactoryOptions = PluginFactoryOptions> = (options: T['options']) => UserPluginWithLifeCycle<T>\n\n/**\n * Wraps a plugin builder to make the options parameter optional.\n */\nexport function definePlugin<T extends PluginFactoryOptions = PluginFactoryOptions>(\n build: PluginBuilder<T>,\n): (options?: T['options']) => UserPluginWithLifeCycle<T> {\n return (options) => build(options ?? ({} as T['options']))\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst next = () => {\n\t\tactiveCount--;\n\n\t\tif (queue.size > 0) {\n\t\t\tqueue.dequeue()();\n\t\t}\n\t};\n\n\tconst run = async (fn, resolve, args) => {\n\t\tactiveCount++;\n\n\t\tconst result = (async () => fn(...args))();\n\n\t\tresolve(result);\n\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\tnext();\n\t};\n\n\tconst enqueue = (fn, resolve, args) => {\n\t\tqueue.enqueue(run.bind(undefined, fn, resolve, args));\n\n\t\t(async () => {\n\t\t\t// This function needs to wait until the next microtask before comparing\n\t\t\t// `activeCount` to `concurrency`, because `activeCount` is updated asynchronously\n\t\t\t// when the run function is dequeued and called. The comparison in the if-statement\n\t\t\t// needs to happen asynchronously as well to get an up-to-date value for `activeCount`.\n\t\t\tawait Promise.resolve();\n\n\t\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\t\tqueue.dequeue()();\n\t\t\t}\n\t\t})();\n\t};\n\n\tconst generator = (fn, ...args) => new Promise(resolve => {\n\t\tenqueue(fn, resolve, args);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue: () => {\n\t\t\t\tqueue.clear();\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n","import pLimit from 'p-limit';\n\nclass EndError extends Error {\n\tconstructor(value) {\n\t\tsuper();\n\t\tthis.value = value;\n\t}\n}\n\n// The input can also be a promise, so we await it.\nconst testElement = async (element, tester) => tester(await element);\n\n// The input can also be a promise, so we `Promise.all()` them both.\nconst finder = async element => {\n\tconst values = await Promise.all(element);\n\tif (values[1] === true) {\n\t\tthrow new EndError(values[0]);\n\t}\n\n\treturn false;\n};\n\nexport default async function pLocate(\n\titerable,\n\ttester,\n\t{\n\t\tconcurrency = Number.POSITIVE_INFINITY,\n\t\tpreserveOrder = true,\n\t} = {},\n) {\n\tconst limit = pLimit(concurrency);\n\n\t// Start all the promises concurrently with optional limit.\n\tconst items = [...iterable].map(element => [element, limit(testElement, element, tester)]);\n\n\t// Check the promises either serially or concurrently.\n\tconst checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY);\n\n\ttry {\n\t\tawait Promise.all(items.map(element => checkLimit(finder, element)));\n\t} catch (error) {\n\t\tif (error instanceof EndError) {\n\t\t\treturn error.value;\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n","import process from 'node:process';\nimport path from 'node:path';\nimport fs, {promises as fsPromises} from 'node:fs';\nimport {fileURLToPath} from 'node:url';\nimport pLocate from 'p-locate';\n\nconst typeMappings = {\n\tdirectory: 'isDirectory',\n\tfile: 'isFile',\n};\n\nfunction checkType(type) {\n\tif (Object.hasOwnProperty.call(typeMappings, type)) {\n\t\treturn;\n\t}\n\n\tthrow new Error(`Invalid type specified: ${type}`);\n}\n\nconst matchType = (type, stat) => stat[typeMappings[type]]();\n\nconst toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;\n\nexport async function locatePath(\n\tpaths,\n\t{\n\t\tcwd = process.cwd(),\n\t\ttype = 'file',\n\t\tallowSymlinks = true,\n\t\tconcurrency,\n\t\tpreserveOrder,\n\t} = {},\n) {\n\tcheckType(type);\n\tcwd = toPath(cwd);\n\n\tconst statFunction = allowSymlinks ? fsPromises.stat : fsPromises.lstat;\n\n\treturn pLocate(paths, async path_ => {\n\t\ttry {\n\t\t\tconst stat = await statFunction(path.resolve(cwd, path_));\n\t\t\treturn matchType(type, stat);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}, {concurrency, preserveOrder});\n}\n\nexport function locatePathSync(\n\tpaths,\n\t{\n\t\tcwd = process.cwd(),\n\t\ttype = 'file',\n\t\tallowSymlinks = true,\n\t} = {},\n) {\n\tcheckType(type);\n\tcwd = toPath(cwd);\n\n\tconst statFunction = allowSymlinks ? fs.statSync : fs.lstatSync;\n\n\tfor (const path_ of paths) {\n\t\ttry {\n\t\t\tconst stat = statFunction(path.resolve(cwd, path_), {\n\t\t\t\tthrowIfNoEntry: false,\n\t\t\t});\n\n\t\t\tif (!stat) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (matchType(type, stat)) {\n\t\t\t\treturn path_;\n\t\t\t}\n\t\t} catch {}\n\t}\n}\n","import {fileURLToPath} from 'node:url';\n\nexport function toPath(urlOrPath) {\n\treturn urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;\n}\n\nexport * from './default.js';\n","import path from 'node:path';\nimport {locatePath, locatePathSync} from 'locate-path';\nimport {toPath} from 'unicorn-magic';\n\nexport const findUpStop = Symbol('findUpStop');\n\nexport async function findUpMultiple(name, options = {}) {\n\tlet directory = path.resolve(toPath(options.cwd) ?? '');\n\tconst {root} = path.parse(directory);\n\tconst stopAt = path.resolve(directory, toPath(options.stopAt ?? root));\n\tconst limit = options.limit ?? Number.POSITIVE_INFINITY;\n\tconst paths = [name].flat();\n\n\tconst runMatcher = async locateOptions => {\n\t\tif (typeof name !== 'function') {\n\t\t\treturn locatePath(paths, locateOptions);\n\t\t}\n\n\t\tconst foundPath = await name(locateOptions.cwd);\n\t\tif (typeof foundPath === 'string') {\n\t\t\treturn locatePath([foundPath], locateOptions);\n\t\t}\n\n\t\treturn foundPath;\n\t};\n\n\tconst matches = [];\n\t// eslint-disable-next-line no-constant-condition\n\twhile (true) {\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tconst foundPath = await runMatcher({...options, cwd: directory});\n\n\t\tif (foundPath === findUpStop) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (foundPath) {\n\t\t\tmatches.push(path.resolve(directory, foundPath));\n\t\t}\n\n\t\tif (directory === stopAt || matches.length >= limit) {\n\t\t\tbreak;\n\t\t}\n\n\t\tdirectory = path.dirname(directory);\n\t}\n\n\treturn matches;\n}\n\nexport function findUpMultipleSync(name, options = {}) {\n\tlet directory = path.resolve(toPath(options.cwd) ?? '');\n\tconst {root} = path.parse(directory);\n\tconst stopAt = path.resolve(directory, toPath(options.stopAt) ?? root);\n\tconst limit = options.limit ?? Number.POSITIVE_INFINITY;\n\tconst paths = [name].flat();\n\n\tconst runMatcher = locateOptions => {\n\t\tif (typeof name !== 'function') {\n\t\t\treturn locatePathSync(paths, locateOptions);\n\t\t}\n\n\t\tconst foundPath = name(locateOptions.cwd);\n\t\tif (typeof foundPath === 'string') {\n\t\t\treturn locatePathSync([foundPath], locateOptions);\n\t\t}\n\n\t\treturn foundPath;\n\t};\n\n\tconst matches = [];\n\t// eslint-disable-next-line no-constant-condition\n\twhile (true) {\n\t\tconst foundPath = runMatcher({...options, cwd: directory});\n\n\t\tif (foundPath === findUpStop) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (foundPath) {\n\t\t\tmatches.push(path.resolve(directory, foundPath));\n\t\t}\n\n\t\tif (directory === stopAt || matches.length >= limit) {\n\t\t\tbreak;\n\t\t}\n\n\t\tdirectory = path.dirname(directory);\n\t}\n\n\treturn matches;\n}\n\nexport async function findUp(name, options = {}) {\n\tconst matches = await findUpMultiple(name, {...options, limit: 1});\n\treturn matches[0];\n}\n\nexport function findUpSync(name, options = {}) {\n\tconst matches = findUpMultipleSync(name, {...options, limit: 1});\n\treturn matches[0];\n}\n\nexport {\n\tpathExists,\n\tpathExistsSync,\n} from 'path-exists';\n","import mod from 'node:module'\nimport os from 'node:os'\nimport { pathToFileURL } from 'node:url'\n\nimport { findUp, findUpSync } from 'find-up'\nimport { coerce, satisfies } from 'semver'\n\nimport { read, readSync } from './fs/index.ts'\n\ntype PackageJSON = {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n}\n\ntype DependencyName = string\n\ntype DependencyVersion = string\n\nexport class PackageManager {\n static #cache: Record<DependencyName, DependencyVersion> = {}\n\n #cwd?: string\n #SLASHES = new Set(['/', '\\\\'])\n constructor(workspace?: string) {\n if (workspace) {\n this.#cwd = workspace\n }\n\n return this\n }\n\n set workspace(workspace: string) {\n this.#cwd = workspace\n }\n\n get workspace(): string | undefined {\n return this.#cwd\n }\n\n normalizeDirectory(directory: string): string {\n if (!this.#SLASHES.has(directory[directory.length - 1]!)) {\n return `${directory}/`\n }\n\n return directory\n }\n\n getLocation(path: string): string {\n let location = path\n\n if (this.#cwd) {\n const require = mod.createRequire(this.normalizeDirectory(this.#cwd))\n location = require.resolve(path)\n }\n\n return location\n }\n\n async import(path: string): Promise<any | undefined> {\n try {\n let location = this.getLocation(path)\n\n if (os.platform() === 'win32') {\n location = pathToFileURL(location).href\n }\n\n const module = await import(location)\n\n return module?.default ?? module\n } catch (error) {\n console.error(error)\n return undefined\n }\n }\n\n async getPackageJSON(): Promise<PackageJSON | undefined> {\n const pkgPath = await findUp(['package.json'], {\n cwd: this.#cwd,\n })\n if (!pkgPath) {\n return undefined\n }\n\n const json = await read(pkgPath)\n\n return JSON.parse(json) as PackageJSON\n }\n\n getPackageJSONSync(): PackageJSON | undefined {\n const pkgPath = findUpSync(['package.json'], {\n cwd: this.#cwd,\n })\n if (!pkgPath) {\n return undefined\n }\n\n const json = readSync(pkgPath)\n\n return JSON.parse(json) as PackageJSON\n }\n\n static setVersion(dependency: DependencyName, version: DependencyVersion): void {\n PackageManager.#cache[dependency] = version\n }\n\n #match(packageJSON: PackageJSON, dependency: DependencyName | RegExp): string | undefined {\n const dependencies = {\n ...(packageJSON['dependencies'] || {}),\n ...(packageJSON['devDependencies'] || {}),\n }\n\n if (typeof dependency === 'string' && dependencies[dependency]) {\n return dependencies[dependency]\n }\n\n const matchedDependency = Object.keys(dependencies).find((dep) => dep.match(dependency))\n\n return matchedDependency ? dependencies[matchedDependency] : undefined\n }\n\n async getVersion(dependency: DependencyName | RegExp): Promise<DependencyVersion | undefined> {\n if (typeof dependency === 'string' && PackageManager.#cache[dependency]) {\n return PackageManager.#cache[dependency]\n }\n\n const packageJSON = await this.getPackageJSON()\n\n if (!packageJSON) {\n return undefined\n }\n\n return this.#match(packageJSON, dependency)\n }\n\n getVersionSync(dependency: DependencyName | RegExp): DependencyVersion | undefined {\n if (typeof dependency === 'string' && PackageManager.#cache[dependency]) {\n return PackageManager.#cache[dependency]\n }\n\n const packageJSON = this.getPackageJSONSync()\n\n if (!packageJSON) {\n return undefined\n }\n\n return this.#match(packageJSON, dependency)\n }\n\n async isValid(dependency: DependencyName | RegExp, version: DependencyVersion): Promise<boolean> {\n const packageVersion = await this.getVersion(dependency)\n\n if (!packageVersion) {\n return false\n }\n\n if (packageVersion === version) {\n return true\n }\n\n const semVer = coerce(packageVersion)\n\n if (!semVer) {\n throw new Error(`${packageVersion} is not valid`)\n }\n\n return satisfies(semVer, version)\n }\n isValidSync(dependency: DependencyName | RegExp, version: DependencyVersion): boolean {\n const packageVersion = this.getVersionSync(dependency)\n\n if (!packageVersion) {\n return false\n }\n\n if (version === 'next' && packageVersion === version) {\n return true\n }\n\n const semVer = coerce(packageVersion)\n\n if (!semVer) {\n return false\n }\n\n return satisfies(semVer, version)\n }\n}\n","import type { KubbFile } from '@kubb/fabric-core/types'\nimport type { Fabric } from '@kubb/react-fabric'\nimport type { KubbEvents } from './Kubb.ts'\nimport type { PluginManager } from './PluginManager.ts'\nimport type { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\nimport type { PossiblePromise } from './utils/types.ts'\n\ndeclare global {\n namespace Kubb {\n interface PluginContext {}\n }\n}\n\n/**\n * Config used in `kubb.config.ts`\n *\n * @example\n * import { defineConfig } from '@kubb/core'\n * export default defineConfig({\n * ...\n * })\n */\nexport type UserConfig<TInput = Input> = Omit<Config<TInput>, 'root' | 'plugins'> & {\n /**\n * The project root directory, which can be either an absolute path or a path relative to the location of your `kubb.config.ts` file.\n * @default process.cwd()\n */\n root?: string\n /**\n * An array of Kubb plugins used for generation. Each plugin may have additional configurable options (defined within the plugin itself). If a plugin relies on another plugin, an error will occur if the required dependency is missing. Refer to “pre” for more details.\n */\n // inject needs to be omitted because else we have a clash with the PluginManager instance\n plugins?: Array<Omit<UnknownUserPlugin, 'inject'>>\n}\n\nexport type InputPath = {\n /**\n * Specify your Swagger/OpenAPI file, either as an absolute path or a path relative to the root.\n */\n path: string\n}\n\nexport type InputData = {\n /**\n * A `string` or `object` that contains your Swagger/OpenAPI data.\n */\n data: string | unknown\n}\n\ntype Input = InputPath | InputData | Array<InputPath>\n\nexport type BarrelType = 'all' | 'named' | 'propagate'\n\n/**\n * @private\n */\nexport type Config<TInput = Input> = {\n /**\n * The name to display in the CLI output.\n */\n name?: string\n /**\n * The project root directory, which can be either an absolute path or a path relative to the location of your `kubb.config.ts` file.\n * @default process.cwd()\n */\n root: string\n /**\n * You can use either `input.path` or `input.data`, depending on your specific needs.\n */\n input: TInput\n output: {\n /**\n * The path where all generated files will be exported.\n * This can be an absolute path or a path relative to the specified root option.\n */\n path: string\n /**\n * Clean the output directory before each build.\n */\n clean?: boolean\n /**\n * Save files to the file system.\n * @default true\n */\n write?: boolean\n /**\n * Specifies the formatting tool to be used.\n * @default prettier\n *\n * Possible values:\n * - 'auto': Automatically detects and uses biome or prettier (in that order of preference).\n * - 'prettier': Uses Prettier for code formatting.\n * - 'biome': Uses Biome for code formatting.\n *\n */\n format?: 'auto' | 'prettier' | 'biome' | 'oxfmt' | false\n /**\n * Specifies the linter that should be used to analyze the code.\n * The accepted values indicate different linting tools.\n *\n * Possible values:\n * - 'auto': Automatically detects and uses biome, oxlint, or eslint (in that order of preference).\n * - 'eslint': Represents the use of ESLint, a widely used JavaScript linter.\n * - 'biome': Represents the Biome linter, a modern tool for code scanning.\n * - 'oxlint': Represents the Oxlint tool for linting purposes.\n *\n */\n lint?: 'auto' | 'eslint' | 'biome' | 'oxlint' | false\n /**\n * Override the extension to the generated imports and exports, by default each plugin will add an extension\n * @default { '.ts': '.ts'}\n */\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n /**\n * Specify how `index.ts` files should be created. You can also disable the generation of barrel files here. While each plugin has its own `barrelType` option, this setting controls the creation of the root barrel file, such as` src/gen/index.ts`.\n * @default 'named'\n */\n barrelType?: Exclude<BarrelType, 'propagate'> | false\n /**\n * Add a default banner to the beginning of every generated file. This makes it clear that the file was generated by Kubb.\n * - 'simple': will only add banner with link to Kubb\n * - 'full': will add source, title, description and the OpenAPI version used\n * @default 'simple'\n */\n defaultBanner?: 'simple' | 'full' | false\n /**\n * Whether to override existing external files if they already exist.\n * When setting the option in the global configuration, all plugins inherit the same behavior by default.\n * However, all plugins also have an `output.override` option, which can be used to override the behavior for a specific plugin.\n * @default false\n */\n override?: boolean\n }\n /**\n * An array of Kubb plugins that will be used in the generation.\n * Each plugin may include additional configurable options(defined in the plugin itself).\n * If a plugin depends on another plugin, an error will be returned if the required dependency is missing. See pre for more details.\n */\n plugins?: Array<Plugin>\n /**\n * Hooks that will be called when a specific action is triggered in Kubb.\n */\n hooks?: {\n /**\n * Hook that will be triggered at the end of all executions.\n * Useful for running Prettier or ESLint to format/lint your code.\n */\n done?: string | Array<string>\n }\n}\n\n// plugin\n\nexport type PluginFactoryOptions<\n /**\n * Name to be used for the plugin, this will also be used for they key.\n */\n TName extends string = string,\n /**\n * Options of the plugin.\n */\n TOptions extends object = object,\n /**\n * Options of the plugin that can be used later on, see `options` inside your plugin config.\n */\n TResolvedOptions extends object = TOptions,\n /**\n * Context that you want to expose to other plugins.\n */\n TContext = any,\n /**\n * When calling `resolvePath` you can specify better types.\n */\n TResolvePathOptions extends object = object,\n> = {\n name: TName\n /**\n * Same behaviour like what has been done with `QueryKey` in `@tanstack/react-query`\n */\n key: PluginKey<TName | string>\n options: TOptions\n resolvedOptions: TResolvedOptions\n context: TContext\n resolvePathOptions: TResolvePathOptions\n}\n\nexport type PluginKey<TName> = [name: TName, identifier?: string | number]\n\nexport type GetPluginFactoryOptions<TPlugin extends UserPlugin> = TPlugin extends UserPlugin<infer X> ? X : never\n\nexport type UserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {\n /**\n * Unique name used for the plugin\n * The name of the plugin follows the format scope:foo-bar or foo-bar, adding scope: can avoid naming conflicts with other plugins.\n * @example @kubb/typescript\n */\n name: TOptions['name']\n /**\n * Options set for a specific plugin(see kubb.config.js), passthrough of options.\n */\n options: TOptions['resolvedOptions']\n /**\n * Specifies the preceding plugins for the current plugin. You can pass an array of preceding plugin names, and the current plugin will be executed after these plugins.\n * Can be used to validate dependent plugins.\n */\n pre?: Array<string>\n /**\n * Specifies the succeeding plugins for the current plugin. You can pass an array of succeeding plugin names, and the current plugin will be executed before these plugins.\n */\n post?: Array<string>\n inject?: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => TOptions['context']\n}\n\nexport type UserPluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = UserPlugin<TOptions> & PluginLifecycle<TOptions>\n\ntype UnknownUserPlugin = UserPlugin<PluginFactoryOptions<any, any, any, any, any>>\n\nexport type Plugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {\n /**\n * Unique name used for the plugin\n * @example @kubb/typescript\n */\n name: TOptions['name']\n /**\n * Internal key used when a developer uses more than one of the same plugin\n * @private\n */\n key: TOptions['key']\n /**\n * Specifies the preceding plugins for the current plugin. You can pass an array of preceding plugin names, and the current plugin will be executed after these plugins.\n * Can be used to validate dependent plugins.\n */\n pre?: Array<string>\n /**\n * Specifies the succeeding plugins for the current plugin. You can pass an array of succeeding plugin names, and the current plugin will be executed before these plugins.\n */\n post?: Array<string>\n /**\n * Options set for a specific plugin(see kubb.config.js), passthrough of options.\n */\n options: TOptions['resolvedOptions']\n\n install: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => PossiblePromise<void>\n /**\n * Define a context that can be used by other plugins, see `PluginManager' where we convert from `UserPlugin` to `Plugin`(used when calling `definePlugin`).\n */\n inject: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => TOptions['context']\n}\n\nexport type PluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = Plugin<TOptions> & PluginLifecycle<TOptions>\n\nexport type PluginLifecycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {\n /**\n * Start of the lifecycle of a plugin.\n * @type hookParallel\n */\n install?: (this: PluginContext<TOptions>, context: PluginContext<TOptions>) => PossiblePromise<void>\n /**\n * Resolve to a Path based on a baseName(example: `./Pet.ts`) and directory(example: `./models`).\n * Options can als be included.\n * @type hookFirst\n * @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'\n */\n resolvePath?: (this: PluginContext<TOptions>, baseName: KubbFile.BaseName, mode?: KubbFile.Mode, options?: TOptions['resolvePathOptions']) => KubbFile.Path\n /**\n * Resolve to a name based on a string.\n * Useful when converting to PascalCase or camelCase.\n * @type hookFirst\n * @example ('pet') => 'Pet'\n */\n resolveName?: (this: PluginContext<TOptions>, name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string\n}\n\nexport type PluginLifecycleHooks = keyof PluginLifecycle\n\nexport type PluginParameter<H extends PluginLifecycleHooks> = Parameters<Required<PluginLifecycle>[H]>\n\nexport type ResolvePathParams<TOptions = object> = {\n pluginKey?: Plugin['key']\n baseName: KubbFile.BaseName\n mode?: KubbFile.Mode\n /**\n * Options to be passed to 'resolvePath' 3th parameter\n */\n options?: TOptions\n}\n\nexport type ResolveNameParams = {\n name: string\n pluginKey?: Plugin['key']\n /**\n * `file` will be used to customize the name of the created file(use of camelCase)\n * `function` can be used to customize the exported functions(use of camelCase)\n * `type` is a special type for TypeScript(use of PascalCase)\n * `const` can be used for variables(use of camelCase)\n */\n type?: 'file' | 'function' | 'type' | 'const'\n}\n\nexport type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {\n fabric: Fabric\n config: Config\n pluginManager: PluginManager\n /**\n * Only add when the file does not exist yet\n */\n addFile: (...file: Array<KubbFile.File>) => Promise<void>\n /**\n * merging multiple sources into the same output file\n */\n upsertFile: (...file: Array<KubbFile.File>) => Promise<void>\n events: AsyncEventEmitter<KubbEvents>\n mode: KubbFile.Mode\n /**\n * Current plugin\n */\n plugin: Plugin<TOptions>\n} & Kubb.PluginContext\n/**\n * Specify the export location for the files and define the behavior of the output\n */\nexport type Output<TOptions> = {\n /**\n * Path to the output folder or file that will contain the generated code\n */\n path: string\n /**\n * Define what needs to be exported, here you can also disable the export of barrel files\n * @default 'named'\n */\n barrelType?: BarrelType | false\n /**\n * Add a banner text in the beginning of every file\n */\n banner?: string | ((options: TOptions) => string)\n /**\n * Add a footer text in the beginning of every file\n */\n footer?: string | ((options: TOptions) => string)\n /**\n * Whether to override existing external files if they already exist.\n * @default false\n */\n override?: boolean\n}\n\ntype GroupContext = {\n group: string\n}\n\nexport type Group = {\n /**\n * Define a type where to group the files on\n */\n type: 'tag' | 'path'\n /**\n * Return the name of a group based on the group name, this will be used for the file and name generation\n */\n name?: (context: GroupContext) => string\n}\n\nexport const LogLevel = {\n silent: Number.NEGATIVE_INFINITY,\n error: 0,\n warn: 1,\n info: 3,\n verbose: 4,\n debug: 5,\n} as const\n\nexport type LoggerOptions = {\n /**\n * @default 3\n */\n logLevel: (typeof LogLevel)[keyof typeof LogLevel]\n}\n\n/**\n * Shared context passed to all plugins, parsers, and Fabric internals.\n */\nexport interface LoggerContext extends AsyncEventEmitter<KubbEvents> {}\n\ntype Install<TOptions = unknown> = (context: LoggerContext, options?: TOptions) => void | Promise<void>\n\nexport type Logger<TOptions extends LoggerOptions = LoggerOptions> = {\n name: string\n install: Install<TOptions>\n}\n\nexport type UserLogger<TOptions extends LoggerOptions = LoggerOptions> = Omit<Logger<TOptions>, 'logLevel'>\n\nexport type { KubbEvents } from './Kubb.ts'\n"],"x_google_ignoreList":[7,8,9,10,11],"mappings":"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