@kubb/core 0.11.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/build.ts","../src/utils/Emitter.ts","../src/utils/FileEmitter.ts","../src/utils/cache.ts","../src/context.ts","../src/plugin.ts","../src/utils/PluginDriver.ts","../src/config.ts","../src/utils/isPromise.ts","../src/utils/write.ts","../src/utils/format.ts","../src/utils/read.ts","../src/index.ts"],"names":["path","argument0","fse"],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport { PluginDriver } from './utils/PluginDriver'\n\nimport type { Api, PluginContext, TransformResult, ValidationResult, LogLevel } from './types'\nimport type { UserConfig, ConfigEnv } from './config'\nimport type { Plugin } from './plugin'\n\ntype BuildOutput = void\n\n// Same type as ora\ntype Spinner = {\n start: (text?: string) => Spinner\n succeed: (text: string) => Spinner\n stopAndPersist: (options: { text: string }) => Spinner\n render: () => Spinner\n text: string\n info: (text: string) => Spinner\n}\n\nexport type BuildContext = {\n logger?: {\n log: (message: string, logLevel: LogLevel) => void\n spinner?: Spinner\n }\n}\n\nasync function transformReducer(this: PluginContext, previousCode: string, result: TransformResult, _plugin: Plugin) {\n if (result === null) {\n return null\n }\n return result\n}\n\ntype BuildImplementationOptions = {\n config: Api['config']\n env: ConfigEnv\n}\n\nasync function buildImplementation(this: BuildContext, options: BuildImplementationOptions, done: (output: BuildOutput) => void) {\n const { config } = options\n\n const pluginCache = Object.create(null)\n const pluginDriver = new PluginDriver(config, pluginCache, { logger: this.logger })\n\n const validations = await pluginDriver.hookParallel<'validate', ValidationResult>('validate', [pluginDriver.plugins])\n\n const validationsWithMessage = validations.filter(Boolean)\n\n if (validationsWithMessage.some((validation) => typeof validation !== 'boolean')) {\n validationsWithMessage.forEach((validation) => {\n if (validation && typeof validation !== 'boolean' && validation?.message) {\n this.logger?.log(validation.message, 'warn')\n }\n })\n\n return\n }\n\n pluginDriver.fileEmitter.on('new', async (emittedFile) => {\n if (!emittedFile?.source) {\n return\n }\n\n const resolvedId = await pluginDriver.hookFirst('resolveId', [emittedFile.source, path.resolve(emittedFile.source), emittedFile.meta])\n const id = resolvedId || emittedFile.source\n let { code } = emittedFile\n\n const loadedResult = await pluginDriver.hookFirst('load', [id])\n if (loadedResult) {\n code = loadedResult\n }\n\n if (code) {\n const result = await pluginDriver.hookReduceArg0('transform', [code, id], transformReducer)\n\n await pluginDriver.hookParallel('writeFile', [result, id])\n pluginDriver.fileEmitter.delete(emittedFile.id)\n }\n })\n\n await pluginDriver.hookParallel('buildStart')\n\n pluginDriver.emitFile({\n id: path.resolve(pluginDriver.api.config.root, pluginDriver.api.config.input.path),\n source: pluginDriver.api.config.input.path,\n name: undefined,\n code: pluginDriver.api.input,\n })\n\n pluginDriver.fileEmitter.on('end', async () => {\n await pluginDriver.hookParallel('buildEnd')\n done()\n })\n}\n\nexport function build(this: BuildContext, userConfig: UserConfig, env: ConfigEnv): Promise<BuildOutput> {\n const config: UserConfig = {\n ...userConfig,\n root: userConfig.root || process.cwd(),\n }\n\n return new Promise((resolve) => {\n buildImplementation.call(\n this,\n {\n config,\n env,\n },\n resolve\n )\n })\n}\n","export type Listener<T> = (value?: T) => void\n\nexport class Emitter<TValue = unknown, TTopics = unknown> {\n private readonly listeners: Set<{\n topic?: TTopics\n cb: Listener<TValue>\n }> = new Set()\n\n private readonly topics?: TTopics[]\n\n constructor(topics?: TTopics[]) {\n this.topics = topics\n }\n\n emit(...params: [topic: TTopics, value?: TValue] | [value?: TValue]) {\n const isTopic = (value: any): value is TTopics => !!this.topics?.includes(value)\n\n if (isTopic(params[0])) {\n this.listeners.forEach((listener) => {\n if (listener.topic === params[0]) {\n listener.cb(params[1])\n }\n })\n return\n }\n this.listeners.forEach((listener) => listener.cb(params[0] as TValue))\n }\n\n subscribe: (cb: Listener<TValue>) => () => void = (cb) => {\n const listener = {\n topic: undefined,\n cb,\n }\n this.listeners.add(listener)\n // Unsubscribe\n return () => this.listeners.delete(listener)\n }\n\n on(topic: TTopics, cb: Listener<TValue>) {\n const listener = {\n topic,\n cb,\n }\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n destroy: () => void = () => this.listeners.clear()\n}\n","import { Emitter } from './Emitter'\n\nexport interface EmittedFile {\n id: string\n // this can be used as a dynamic path, also resolveId will use this as source(first parameter)\n source: string | undefined\n name: string | undefined\n code: string | undefined\n meta?: Record<string, any>\n}\n\nexport type EmitFile = (emittedFile: EmittedFile) => void\n\ntype Topics = 'new' | 'delete' | 'end'\nexport class FileEmitter {\n private readonly emitter: Emitter<EmittedFile, Topics>\n\n private readonly filesByReferenceId: Map<string, EmittedFile> = new Map()\n\n constructor(emitter: Emitter<EmittedFile, Topics> = new Emitter<EmittedFile, Topics>(['delete', 'end', 'new'])) {\n this.emitter = emitter\n }\n\n emitFile(emitedFile: EmittedFile) {\n // save locally in this class\n this.assignReferenceId(emitedFile, emitedFile.id)\n this.emitter.emit('new', emitedFile)\n return new Promise<EmittedFile>((resolve) => {\n const subscribe = this.emitter.on('delete', (deletedFile) => {\n if (deletedFile?.id === emitedFile.id) {\n resolve(deletedFile)\n return subscribe()\n }\n return undefined\n })\n })\n }\n\n delete(fileReferenceId: string) {\n const deletedFile = this.filesByReferenceId.get(fileReferenceId)\n this.filesByReferenceId.delete(fileReferenceId)\n if (this.filesByReferenceId.size === 0) {\n this.emitter.emit('end')\n }\n return this.emitter.emit('delete', deletedFile)\n }\n\n subscribe(...params: Parameters<typeof this.emitter['subscribe']>) {\n this.emitter.subscribe(...params)\n }\n\n on(...params: Parameters<typeof this.emitter['on']>) {\n this.emitter.on(...params)\n }\n\n private assignReferenceId(emittedFile: EmittedFile, fileReferenceId: string | undefined) {\n if (fileReferenceId) {\n this.filesByReferenceId.set(fileReferenceId, emittedFile)\n }\n }\n\n getEmittedFile = (fileReferenceId?: string | null): EmittedFile | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)\n }\n}\n","/* eslint-disable no-param-reassign */\n/* eslint-disable consistent-return */\nexport interface SerializablePluginCache {\n [key: string]: [number, any]\n}\n\nexport interface Cache<TCache = any> {\n delete(id: string): boolean\n get<T = TCache>(id: string): T\n has(id: string): boolean\n set<T = TCache>(id: string, value: T): void\n}\n\nexport function createPluginCache(cache: SerializablePluginCache): Cache {\n return {\n delete(id: string) {\n return delete cache[id]\n },\n get(id: string) {\n const item = cache[id]\n if (!item) return\n item[0] = 0\n return item[1]\n },\n has(id: string) {\n const item = cache[id]\n if (!item) return false\n item[0] = 0\n return true\n },\n set(id: string, value: any) {\n cache[id] = [0, value]\n },\n }\n}\n","/* eslint-disable no-param-reassign */\nimport { createPluginCache } from './utils/cache'\n\nimport type { PluginDriver } from './utils/PluginDriver'\nimport type { SerializablePluginCache } from './utils/cache'\nimport type { Plugin } from './plugin'\n\nexport function getPluginContext(this: PluginDriver, plugin: Plugin, pluginCache: Record<string, SerializablePluginCache> | void) {\n const cacheKey = plugin.cacheKey || (plugin.name as string)\n\n const cacheInstance = createPluginCache(pluginCache[cacheKey] || (pluginCache[cacheKey] = Object.create(null)))\n\n return {\n cache: cacheInstance,\n }\n}\n","/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport fse from 'fs-extra'\n\nimport type { FileEmitter } from './utils'\nimport type { PluginLifecycle, PluginName, Api } from './types'\n\n// use of type objects\nexport type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = {\n userOptions: UserOptions\n nested: Nested\n api: Api\n}\n\nexport type Plugin<TOptions extends PluginOptions = PluginOptions> = {\n name: PluginName | Omit<string, PluginName>\n cacheKey?: string\n api?: TOptions['api']\n} & Partial<PluginLifecycle>\n\nexport type PluginFactory<TOptions extends PluginOptions = PluginOptions> = (\n options: TOptions['userOptions']\n) => TOptions['nested'] extends true ? Array<Plugin<TOptions>> : Plugin<TOptions>\n\nexport function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>) {\n return (userOptions: TOptions['userOptions']) => {\n const plugin = factory(userOptions)\n if (Array.isArray(plugin)) {\n throw new Error('Not implemented')\n }\n\n // default transform\n if (!plugin.transform) {\n plugin.transform = function transform(code) {\n return code\n }\n }\n\n return plugin\n }\n}\n\ntype Options = {\n // root will be filled in with a default value in build(process.cwd)\n config: Api['config']\n fileEmitter: FileEmitter\n resolveId: Api['resolveId']\n load: Api['load']\n}\n\n// not exported\ntype CorePluginOptions = PluginOptions<Options, false, Api>\n\nexport const name = 'core' as const\n\nexport const definePlugin = createPlugin<CorePluginOptions>((options) => {\n const { fileEmitter, resolveId, load } = options\n\n const schema = fse.readFileSync(path.resolve(options.config.root, options.config.input.path), 'utf-8')\n\n const api: Api = {\n get config() {\n return options.config\n },\n get input() {\n return schema\n },\n on: fileEmitter.on.bind(fileEmitter),\n getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),\n emitFile: fileEmitter.emitFile.bind(fileEmitter),\n resolveId,\n load,\n }\n\n return {\n name,\n api,\n }\n})\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable no-undef */\n// inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#\n\nimport { FileEmitter } from './FileEmitter'\n\nimport { getPluginContext } from '../context'\nimport { definePlugin } from '../plugin'\n\nimport type { WithPromise } from './isPromise'\nimport type { BuildContext } from '../build'\nimport type { SerializablePluginCache } from './cache'\nimport type { Plugin } from '../plugin'\nimport type { PluginLifecycleHooks, PluginLifecycle, PluginContext, Api } from '../types'\n\n/**\n * Get the type of the first argument in a function.\n * @example Arg0<(a: string, b: number) => void> -> string\n */\nexport type Argument0<H extends keyof PluginLifecycle> = Parameters<PluginLifecycle[H]>[0]\n\ntype Strategy = 'hookFirst' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'\n\n// This will make sure no input hook is omitted\nconst hookNames: {\n [P in PluginLifecycleHooks]: 1\n} = {\n validate: 1,\n buildStart: 1,\n resolveId: 1,\n load: 1,\n transform: 1,\n writeFile: 1,\n buildEnd: 1,\n}\nexport const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]\n\nexport class PluginDriver {\n private readonly pluginContexts: ReadonlyMap<Plugin, PluginContext>\n\n public plugins: Plugin[]\n\n public readonly fileEmitter: FileEmitter\n\n private readonly logger?: BuildContext['logger']\n\n private readonly config: Api['config']\n\n private readonly sortedPlugins = new Map<PluginLifecycleHooks, Plugin[]>()\n\n constructor(config: Api['config'], pluginCache: Record<string, SerializablePluginCache> | undefined, options: { logger: BuildContext['logger'] }) {\n this.logger = options.logger\n this.config = config\n\n this.fileEmitter = new FileEmitter()\n\n this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter)\n\n const corePlugin = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId })\n this.plugins = [corePlugin, ...(config.plugins || [])]\n const coreApi = corePlugin.api\n this.pluginContexts = new Map(\n this.plugins.map((plugin) => {\n const context = {\n ...coreApi,\n ...getPluginContext.call(this, plugin, pluginCache),\n }\n return [plugin, context]\n })\n )\n }\n\n get api() {\n let context = {}\n this.pluginContexts.forEach((value) => {\n context = { ...context, ...value }\n })\n return context as PluginContext\n }\n\n emitFile(...params: Parameters<FileEmitter['emitFile']>) {\n return this.fileEmitter.emitFile(...params)\n }\n\n resolveId = (source: string, importer: string, meta: Record<string, any> | undefined) => {\n return this.hookFirst('resolveId', [source, importer, meta])\n }\n\n load = async (id: string) => {\n const result = await this.hookFirst('load', [id])\n return result\n }\n\n // chains, first non-null result stops and returns\n hookFirst<H extends PluginLifecycleHooks>(\n hookName: H,\n parameters: Parameters<PluginLifecycle[H]>,\n skipped?: ReadonlySet<Plugin> | null\n ): Promise<ReturnType<PluginLifecycle[H]> | null> {\n let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)\n for (const plugin of this.getSortedPlugins(hookName)) {\n if (skipped && skipped.has(plugin)) continue\n promise = promise.then((result) => {\n if (result != null) return result\n return this.runHook('hookFirst', hookName, parameters, plugin) as any\n })\n }\n return promise\n }\n\n // parallel\n async hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined) {\n const parallelPromises: Promise<TOuput>[] = []\n\n for (const plugin of this.getSortedPlugins(hookName)) {\n if ((plugin[hookName] as { sequential?: boolean })?.sequential) {\n await Promise.all(parallelPromises)\n parallelPromises.length = 0\n await this.runHook('hookParallel', hookName, parameters, plugin)\n } else {\n const promise: Promise<TOuput> = this.runHook('hookParallel', hookName, parameters, plugin)\n\n parallelPromises.push(promise)\n }\n }\n return Promise.all(parallelPromises)\n }\n\n // chains, reduces returned value, handling the reduced value as the first hook argument\n hookReduceArg0<H extends PluginLifecycleHooks>(\n hookName: H,\n [argument0, ...rest]: Parameters<PluginLifecycle[H]>,\n reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: Plugin) => WithPromise<Argument0<H> | null>\n ): Promise<Argument0<H>> {\n let promise = Promise.resolve(argument0)\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then((argument0) =>\n this.runHook('hookReduceArg0', hookName, [argument0, ...rest] as Parameters<PluginLifecycle[H]>, plugin).then((result) =>\n reduce.call(this.api, argument0, result, plugin)\n )\n )\n }\n return promise\n }\n\n // chains\n\n hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>) {\n let promise: Promise<void> = Promise.resolve()\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then(() => this.runHook('hookSeq', hookName, parameters, plugin))\n }\n return promise.then(noReturn)\n }\n\n private getSortedPlugins(_hookName: keyof PluginLifecycle): Plugin[] {\n return [...this.plugins]\n }\n\n /**\n * Run an async plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The actual pluginObject to run.\n */\n // Implementation signature\n private runHook<H extends PluginLifecycleHooks, TResult = void>(\n strategy: Strategy,\n hookName: H,\n parameters: unknown[] | undefined,\n plugin: Plugin\n ): Promise<TResult> {\n // We always filter for plugins that support the hook before running it\n const hook = plugin[hookName]!\n // const context = this.pluginContexts.get(plugin) || {};\n\n return Promise.resolve().then(() => {\n if (typeof hook !== 'function') {\n return hook\n }\n\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`\n }\n\n const hookResult = (hook as any).apply(this.api, parameters)\n\n if (!hookResult?.then) {\n // short circuit for non-thenables and non-Promises\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return hookResult\n }\n\n return Promise.resolve(hookResult).then((result) => {\n // action was fulfilled\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return result\n })\n })\n }\n\n /**\n * Run a sync plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be in `PluginHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The acutal plugin\n * @param replaceContext When passed, the plugin context can be overridden.\n */\n private runHookSync<H extends PluginLifecycleHooks>(hookName: H, parameters: Parameters<PluginLifecycle[H]>, plugin: Plugin): ReturnType<PluginLifecycle[H]> {\n const hook = plugin[hookName]!\n\n // const context = this.pluginContexts.get(plugin)!;\n\n try {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (hook as Function).apply(this.api, parameters)\n } catch (error: any) {\n return error\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noReturn() {}\n","import type { WithPromise } from './utils/isPromise'\nimport type { LogLevel } from './types'\nimport type { Plugin } from './plugin'\n\nexport interface ConfigEnv {\n mode: 'development'\n}\n// TODO revert to this to have multiple options like async, object, ...\n// export type PluginOption = PluginOptions | false | null | undefined | PluginOption[] | Promise<PluginOptions | false | null | undefined | PluginOption[]>;\n\nexport interface UserConfig {\n /**\n * Project root directory. Can be an absolute path, or a path relative from\n * the location of the config file itself.\n * @default process.cwd()\n */\n root?: string\n mode?: 'single'\n input: {\n /**\n * Path or link to the input file\n */\n path: string\n }\n output: {\n /**\n * Path to export folder\n */\n path: string\n }\n /**\n * Array of Kubb plugins to use.\n */\n plugins?: Plugin[]\n /**\n * Log level to report when using the CLI\n */\n\n logLevel?: LogLevel\n}\n\nexport type UserConfigFn = (env: ConfigEnv) => WithPromise<UserConfig>\nexport type UserConfigExport = WithPromise<UserConfig> | UserConfigFn\n\n/**\n * Type helper to make it easier to use kubb.config.ts\n * accepts a direct {@link UserConfig} object, or a function that returns it.\n * The function receives a {@link ConfigEnv} object that exposes two properties:\n */\nexport function defineConfig(config: UserConfigExport): UserConfigExport {\n return config\n}\n","export type WithPromise<T> = Promise<T> | T\n\nexport const isPromise = <T>(result: WithPromise<T>): result is Promise<T> => {\n return typeof (result as any)?.then === 'function'\n}\n","/* eslint-disable consistent-return */\nimport fse from 'fs-extra'\n\nimport { format } from './format'\n\ntype WriteOptions = {\n format: boolean\n}\n\nexport const write = async (data: string, path: string, options: WriteOptions = { format: false }) => {\n const formattedData = options.format ? format(data) : data\n\n try {\n await fse.stat(path)\n const oldContent = await fse.readFile(path, { encoding: 'utf-8' })\n if (oldContent?.toString() === formattedData) {\n return\n }\n } catch (_err) {\n return fse.outputFile(path, formattedData)\n }\n\n return fse.outputFile(path, formattedData)\n}\n","import { format as prettierFormat } from 'prettier'\n\nimport type { Options } from 'prettier'\n\nconst formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n}\nexport const format = (text: string) => {\n return prettierFormat(text, formatOptions)\n}\n","import path from 'path'\n\n// TODO check for a better way or resolving the relative path\nexport const getRelativePath = (from?: string | null, to?: string | null) => {\n if (!from || !to) {\n throw new Error('From and to should be filled in when retrieving the relativePath')\n }\n const newPath = path.relative(from, to).replace('../', '').replace('.ts', '').trimEnd()\n\n if (newPath.startsWith('./') || newPath.startsWith('../')) {\n return newPath.replace\n }\n return `./${newPath}`\n}\n","/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { build } from './build'\n\nexport * from './config'\nexport * from './build'\nexport { Plugin, PluginOptions, PluginFactory, createPlugin } from './plugin'\nexport * from './utils'\nexport * from './types'\nexport * from './context'\n\nexport default build\n"]}
1
+ {"version":3,"sources":["../src/build.ts","../src/utils/Emitter.ts","../src/utils/FileEmitter.ts","../src/plugin.ts","../src/utils/isPromise.ts","../src/utils/write.ts","../src/utils/format.ts","../src/utils/cache.ts","../src/utils/read.ts","../src/utils/PluginDriver.ts","../src/config.ts","../src/index.ts"],"names":["path","fse","argument0"],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport fse from 'fs-extra'\n\nimport { PluginDriver } from './utils/PluginDriver'\nimport { defaultConfig } from './config'\n\nimport type { Api, PluginContext, TransformResult, ValidationResult, LogLevel } from './types'\nimport type { Plugin } from './plugin'\n\ntype BuildOutput = void\n\n// Same type as ora\ntype Spinner = {\n start: (text?: string) => Spinner\n succeed: (text: string) => Spinner\n stopAndPersist: (options: { text: string }) => Spinner\n render: () => Spinner\n text: string\n info: (text: string) => Spinner\n}\n\nexport type BuildOptions = {\n config: Api['config']\n mode: 'development' | 'production'\n logger?: {\n log: (message: string, logLevel: LogLevel) => void\n spinner?: Spinner\n }\n}\n\nasync function transformReducer(this: PluginContext, previousCode: string, result: TransformResult, _plugin: Plugin) {\n if (result === null) {\n return null\n }\n return result\n}\n\nasync function buildImplementation(options: BuildOptions, done: (output: BuildOutput) => void) {\n const { config, logger } = options\n\n if (config.clear) {\n await fse.remove(config.output.path)\n }\n\n const pluginDriver = new PluginDriver(\n {\n ...defaultConfig,\n ...config,\n },\n { logger }\n )\n const input = fse.readFileSync(path.resolve(config.root, config.input.path), 'utf-8')\n\n const validations = await pluginDriver.hookParallel<'validate', ValidationResult>('validate', [pluginDriver.plugins])\n const validationsWithMessage = validations.filter(Boolean)\n\n if (validationsWithMessage.some((validation) => typeof validation !== 'boolean')) {\n validationsWithMessage.forEach((validation) => {\n if (validation && typeof validation !== 'boolean' && validation?.message) {\n logger?.log(validation.message, 'warn')\n }\n })\n\n return\n }\n\n pluginDriver.fileEmitter.on('new', async (emittedFile) => {\n if (!emittedFile) {\n return\n }\n const { id } = emittedFile\n\n if (!id) {\n throw new Error('No id could be transformed, please add id to emitFile or use resolveId')\n }\n\n let { source: code } = emittedFile\n\n const loadedResult = await pluginDriver.hookFirst('load', [id])\n if (loadedResult) {\n code = loadedResult\n }\n\n if (code) {\n const transformedCode = await pluginDriver.hookReduceArg0('transform', [code, id], transformReducer)\n\n await pluginDriver.hookParallel('writeFile', [transformedCode, id])\n pluginDriver.fileEmitter.delete(emittedFile.id)\n }\n })\n\n await pluginDriver.hookParallel('buildStart')\n\n pluginDriver.emitFile({\n id: config.input.path,\n name: undefined,\n source: input,\n })\n\n pluginDriver.fileEmitter.on('end', async () => {\n await pluginDriver.hookParallel('buildEnd')\n done()\n })\n}\n\nexport function build(options: BuildOptions): Promise<BuildOutput> {\n return new Promise((resolve, reject) => {\n try {\n buildImplementation(options, resolve)\n } catch (e) {\n reject(e)\n }\n })\n}\n","export type Listener<T> = (value?: T) => void\n\nexport class Emitter<TValue = unknown, TTopics = unknown> {\n private readonly listeners: Set<{\n topic?: TTopics\n cb: Listener<TValue>\n }> = new Set()\n\n private readonly topics?: TTopics[]\n\n constructor(topics?: TTopics[]) {\n this.topics = topics\n }\n\n emit(...params: [topic: TTopics, value?: TValue] | [value?: TValue]) {\n const isTopic = (value: any): value is TTopics => !!this.topics?.includes(value)\n\n if (isTopic(params[0])) {\n this.listeners.forEach((listener) => {\n if (listener.topic === params[0]) {\n listener.cb(params[1])\n }\n })\n return\n }\n this.listeners.forEach((listener) => listener.cb(params[0] as TValue))\n }\n\n subscribe: (cb: Listener<TValue>) => () => void = (cb) => {\n const listener = {\n topic: undefined,\n cb,\n }\n this.listeners.add(listener)\n // Unsubscribe\n return () => this.listeners.delete(listener)\n }\n\n on(topic: TTopics, cb: Listener<TValue>) {\n const listener = {\n topic,\n cb,\n }\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n destroy: () => void = () => this.listeners.clear()\n}\n","import { Emitter } from './Emitter'\n\nexport interface EmittedFile {\n /**\n * equal to importee when getting passed through resolveId\n */\n id: string\n /**\n * The importer is the fully resolved id of the importing module.\n */\n importer?: string\n /**\n * Name to be used to dynamicly create the fileName(based on input.path)\n */\n name?: string\n /**\n * FileName will be the end result so no input.path will not be added\n */\n fileName?: string\n source?: string\n options?: Record<string, any>\n}\n\nexport type EmitFile = (emittedFile: EmittedFile) => void\n\ntype Topics = 'new' | 'delete' | 'end'\nexport class FileEmitter {\n private readonly emitter: Emitter<EmittedFile, Topics>\n\n private readonly filesByReferenceId: Map<string, EmittedFile> = new Map()\n\n constructor(emitter: Emitter<EmittedFile, Topics> = new Emitter<EmittedFile, Topics>(['delete', 'end', 'new'])) {\n this.emitter = emitter\n }\n\n // TODO add default resolveId in core that takes name or fileName to resolve the correct files\n emitFile(emitedFile: EmittedFile) {\n // save locally in this class\n this.assignReferenceId(emitedFile, emitedFile.id)\n this.emitter.emit('new', emitedFile)\n return new Promise<EmittedFile>((resolve) => {\n const subscribe = this.emitter.on('delete', (deletedFile) => {\n if (deletedFile?.id && deletedFile?.id === emitedFile.id) {\n resolve(deletedFile)\n return subscribe()\n }\n return undefined\n })\n })\n }\n\n delete(fileReferenceId: string) {\n const deletedFile = this.filesByReferenceId.get(fileReferenceId)\n this.filesByReferenceId.delete(fileReferenceId)\n if (this.filesByReferenceId.size === 0) {\n this.emitter.emit('end')\n }\n return this.emitter.emit('delete', deletedFile)\n }\n\n subscribe(...params: Parameters<typeof this.emitter['subscribe']>) {\n this.emitter.subscribe(...params)\n }\n\n on(...params: Parameters<typeof this.emitter['on']>) {\n this.emitter.on(...params)\n }\n\n private assignReferenceId(emittedFile: EmittedFile, fileReferenceId: string | undefined) {\n if (fileReferenceId) {\n this.filesByReferenceId.set(fileReferenceId, emittedFile)\n }\n }\n\n getEmittedFile = (fileReferenceId?: string | null): EmittedFile | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)\n }\n}\n","import path from 'path'\n\nimport { createPluginCache, getRelativePath, write } from './utils'\n\nimport type { EmittedFile } from './utils/FileEmitter'\nimport type { FileEmitter } from './utils'\nimport type { PluginLifecycle, Api } from './types'\n\n// use of type objects\nexport type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = {\n userOptions: UserOptions\n nested: Nested\n api: Api\n}\n\nexport type Plugin<TOptions extends PluginOptions = PluginOptions> = {\n name: string\n api?: TOptions['api']\n} & Partial<PluginLifecycle>\n\nexport type PluginFactory<TOptions extends PluginOptions = PluginOptions> = (\n options: TOptions['userOptions']\n) => TOptions['nested'] extends true ? Array<Plugin<TOptions>> : Plugin<TOptions>\n\nexport function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>) {\n return (userOptions: TOptions['userOptions']) => {\n const plugin = factory(userOptions)\n if (Array.isArray(plugin)) {\n throw new Error('Not implemented')\n }\n\n // default transform\n if (!plugin.transform) {\n plugin.transform = function transform(code) {\n return code\n }\n }\n\n return plugin\n }\n}\n\ntype Options = {\n // root will be filled in with a default value in build(process.cwd)\n config: Api['config']\n fileEmitter: FileEmitter\n resolveId: Api['resolveId']\n load: Api['load']\n}\n\n// not publicly exported\nexport type CorePluginOptions = PluginOptions<Options, false, Api>\n\nexport const name = 'core' as const\n\nexport const definePlugin = createPlugin<CorePluginOptions>((options) => {\n const { fileEmitter, resolveId, load } = options\n const indexFiles: EmittedFile[] = []\n\n const api: Api = {\n get config() {\n return options.config\n },\n async emitFile(emittedFile) {\n const resolvedId = await resolveId(emittedFile.id, emittedFile.importer, emittedFile.options)\n const id = resolvedId || emittedFile.importer || emittedFile.id\n\n return fileEmitter.emitFile({\n ...emittedFile,\n id,\n })\n },\n addToIndex: (emittedFile: EmittedFile) => {\n indexFiles.push(emittedFile)\n },\n resolveId,\n load,\n cache: createPluginCache(Object.create(null)),\n }\n\n return {\n name,\n api,\n async buildEnd() {\n if (!indexFiles.length) {\n return\n }\n\n let index = ``\n\n indexFiles.forEach((item) => {\n index += `export * from \"${getRelativePath(path.resolve(this.config.root, this.config.output.path), item.id)}\";\\n`\n })\n\n await write(index, path.resolve(this.config.root, this.config.output.path, 'index.ts'), { format: true })\n },\n resolveId(importee, importer) {\n if (!importer) {\n return null\n }\n return path.resolve(importer, importee)\n },\n }\n})\n","export type WithPromise<T> = Promise<T> | T\n\nexport const isPromise = <T>(result: WithPromise<T>): result is Promise<T> => {\n return typeof (result as any)?.then === 'function'\n}\n","/* eslint-disable consistent-return */\nimport fse from 'fs-extra'\n\nimport { format } from './format'\n\ntype WriteOptions = {\n format: boolean\n}\n\nexport const write = async (data: string, path: string, options: WriteOptions = { format: false }) => {\n const formattedData = options.format ? format(data) : data\n\n try {\n await fse.stat(path)\n const oldContent = await fse.readFile(path, { encoding: 'utf-8' })\n if (oldContent?.toString() === formattedData) {\n return\n }\n } catch (_err) {\n return fse.outputFile(path, formattedData)\n }\n\n return fse.outputFile(path, formattedData)\n}\n","import { format as prettierFormat } from 'prettier'\n\nimport type { Options } from 'prettier'\n\nconst formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n}\nexport const format = (text: string) => {\n return prettierFormat(text, formatOptions)\n}\n","/* eslint-disable no-param-reassign */\n/* eslint-disable consistent-return */\n\nexport interface Cache<TCache = any> {\n delete(id: string): boolean\n get<T = TCache>(id: string): T\n has(id: string): boolean\n set<T = TCache>(id: string, value: T): void\n}\n\nexport function createPluginCache(cache: any): Cache {\n return {\n delete(id: string) {\n return delete cache[id]\n },\n get(id: string) {\n const item = cache[id]\n if (!item) return\n item[0] = 0\n return item[1]\n },\n has(id: string) {\n const item = cache[id]\n if (!item) return false\n item[0] = 0\n return true\n },\n set(id: string, value: any) {\n cache[id] = [0, value]\n },\n }\n}\n","import path from 'path'\n\n// TODO check for a better way or resolving the relative path\nexport const getRelativePath = (from?: string | null, to?: string | null) => {\n if (!from || !to) {\n throw new Error('From and to should be filled in when retrieving the relativePath')\n }\n const newPath = path.relative(from, to).replace('../', '').replace('.ts', '').trimEnd()\n\n return `./${newPath}`\n}\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable no-undef */\n// inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#\n\nimport { FileEmitter } from './FileEmitter'\n\nimport { definePlugin } from '../plugin'\n\nimport type { WithPromise } from './isPromise'\nimport type { BuildOptions } from '../build'\nimport type { Plugin, CorePluginOptions } from '../plugin'\nimport type { PluginLifecycleHooks, PluginLifecycle, Api } from '../types'\n\n/**\n * Get the type of the first argument in a function.\n * @example Arg0<(a: string, b: number) => void> -> string\n */\nexport type Argument0<H extends keyof PluginLifecycle> = Parameters<PluginLifecycle[H]>[0]\n\ntype Strategy = 'hookFirst' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'\n\n// This will make sure no input hook is omitted\nconst hookNames: {\n [P in PluginLifecycleHooks]: 1\n} = {\n validate: 1,\n buildStart: 1,\n resolveId: 1,\n load: 1,\n transform: 1,\n writeFile: 1,\n buildEnd: 1,\n}\nexport const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]\n\nexport class PluginDriver {\n public plugins: Plugin[]\n\n public readonly fileEmitter: FileEmitter = new FileEmitter()\n\n private readonly logger?: BuildOptions['logger']\n\n private readonly config: Api['config']\n\n public readonly core: Plugin<CorePluginOptions> & { api: CorePluginOptions['api'] }\n\n constructor(config: Api['config'], options: { logger: BuildOptions['logger'] }) {\n this.logger = options.logger\n this.config = config\n this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter)\n\n this.core = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId }) as Plugin<CorePluginOptions> & {\n api: CorePluginOptions['api']\n }\n this.plugins = [this.core, ...(config.plugins || [])]\n }\n\n emitFile(...params: Parameters<FileEmitter['emitFile']>) {\n return this.fileEmitter.emitFile(...params)\n }\n\n resolveId = (source: string, importer: string, meta: Record<string, any> | undefined) => {\n return this.hookFirst('resolveId', [source, importer, meta])\n }\n\n load = async (id: string) => {\n const result = await this.hookFirst('load', [id])\n return result\n }\n\n // chains, first non-null result stops and returns\n hookFirst<H extends PluginLifecycleHooks>(\n hookName: H,\n parameters: Parameters<PluginLifecycle[H]>,\n skipped?: ReadonlySet<Plugin> | null\n ): Promise<ReturnType<PluginLifecycle[H]> | null> {\n let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)\n for (const plugin of this.getSortedPlugins(hookName)) {\n if (skipped && skipped.has(plugin)) continue\n promise = promise.then((result) => {\n if (result != null) return result\n return this.run('hookFirst', hookName, parameters, plugin) as any\n })\n }\n return promise\n }\n\n // parallel\n async hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined) {\n const parallelPromises: Promise<TOuput>[] = []\n\n for (const plugin of this.getSortedPlugins(hookName)) {\n if ((plugin[hookName] as { sequential?: boolean })?.sequential) {\n await Promise.all(parallelPromises)\n parallelPromises.length = 0\n await this.run('hookParallel', hookName, parameters, plugin)\n } else {\n const promise: Promise<TOuput> = this.run('hookParallel', hookName, parameters, plugin)\n\n parallelPromises.push(promise)\n }\n }\n return Promise.all(parallelPromises)\n }\n\n // chains, reduces returned value, handling the reduced value as the first hook argument\n hookReduceArg0<H extends PluginLifecycleHooks>(\n hookName: H,\n [argument0, ...rest]: Parameters<PluginLifecycle[H]>,\n reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: Plugin) => WithPromise<Argument0<H> | null>\n ): Promise<Argument0<H>> {\n let promise = Promise.resolve(argument0)\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then((argument0) =>\n this.run('hookReduceArg0', hookName, [argument0, ...rest] as Parameters<PluginLifecycle[H]>, plugin).then((result) =>\n reduce.call(this.core.api, argument0, result, plugin)\n )\n )\n }\n return promise\n }\n\n // chains\n\n hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>) {\n let promise: Promise<void> = Promise.resolve()\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then(() => this.run('hookSeq', hookName, parameters, plugin))\n }\n return promise.then(noReturn)\n }\n\n private getSortedPlugins(_hookName: keyof PluginLifecycle): Plugin[] {\n return [...this.plugins]\n }\n\n /**\n * Run an async plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The actual pluginObject to run.\n */\n // Implementation signature\n private run<H extends PluginLifecycleHooks, TResult = void>(\n strategy: Strategy,\n hookName: H,\n parameters: unknown[] | undefined,\n plugin: Plugin\n ): Promise<TResult> {\n // We always filter for plugins that support the hook before running it\n const hook = plugin[hookName]!\n // const context = this.pluginContexts.get(plugin) || {};\n\n return Promise.resolve().then(() => {\n if (typeof hook !== 'function') {\n return hook\n }\n\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`\n }\n\n const hookResult = (hook as any).apply(this.core.api, parameters)\n\n if (!hookResult?.then) {\n // short circuit for non-thenables and non-Promises\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return hookResult\n }\n\n return Promise.resolve(hookResult).then((result) => {\n // action was fulfilled\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return result\n })\n })\n }\n\n /**\n * Run a sync plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be in `PluginHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The acutal plugin\n * @param replaceContext When passed, the plugin context can be overridden.\n */\n private runSync<H extends PluginLifecycleHooks>(hookName: H, parameters: Parameters<PluginLifecycle[H]>, plugin: Plugin): ReturnType<PluginLifecycle[H]> {\n const hook = plugin[hookName]!\n\n // const context = this.pluginContexts.get(plugin)!;\n\n try {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (hook as Function).apply(this.core.api, parameters)\n } catch (error: any) {\n return error\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noReturn() {}\n","import type { BuildOptions } from './build'\nimport type { WithPromise } from './utils/isPromise'\nimport type { LogLevel } from './types'\nimport type { Plugin } from './plugin'\n\n// TODO revert to this to have multiple options like async, object, ...\n// export type PluginOption = PluginOptions | false | null | undefined | PluginOption[] | Promise<PluginOptions | false | null | undefined | PluginOption[]>;\n\nexport interface UserConfig {\n /**\n * Project root directory. Can be an absolute path, or a path relative from\n * the location of the config file itself.\n * @default process.cwd()\n */\n root: string\n clear?: boolean\n mode?: 'single'\n input: {\n /**\n * Path or link to the input file\n */\n path: string\n }\n output: {\n /**\n * Path to export folder\n */\n path: string\n }\n /**\n * Array of Kubb plugins to use.\n */\n plugins?: Plugin[]\n /**\n * Log level to report when using the CLI\n */\n\n logLevel?: LogLevel\n}\n\nexport type UserConfigFn = (options: BuildOptions) => WithPromise<UserConfig>\nexport type UserConfigExport = WithPromise<UserConfig> | UserConfigFn\n\nexport const defaultConfig: Partial<UserConfig> = {\n root: process.cwd(),\n}\n\n/**\n * Type helper to make it easier to use kubb.config.ts\n * accepts a direct {@link UserConfig} object, or a function that returns it.\n * The function receives a {@link ConfigEnv} object that exposes two properties:\n */\nexport function defineConfig(config: UserConfigExport): UserConfigExport {\n return config\n}\n","/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { build } from './build'\n\nexport * from './config'\nexport * from './build'\nexport { Plugin, PluginOptions, PluginFactory, createPlugin } from './plugin'\nexport * from './utils'\nexport * from './types'\n\nexport default build\n"]}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import path2 from 'path';
2
- import fse2 from 'fs-extra';
2
+ import fse from 'fs-extra';
3
3
  import { format as format$1 } from 'prettier';
4
4
 
5
5
  // src/build.ts
@@ -54,7 +54,7 @@ var FileEmitter = class {
54
54
  this.emitter.emit("new", emitedFile);
55
55
  return new Promise((resolve) => {
56
56
  const subscribe = this.emitter.on("delete", (deletedFile) => {
57
- if (deletedFile?.id === emitedFile.id) {
57
+ if (deletedFile?.id && deletedFile?.id === emitedFile.id) {
58
58
  resolve(deletedFile);
59
59
  return subscribe();
60
60
  }
@@ -89,6 +89,38 @@ var FileEmitter = class {
89
89
  };
90
90
  };
91
91
 
92
+ // src/utils/isPromise.ts
93
+ var isPromise = (result) => {
94
+ return typeof result?.then === "function";
95
+ };
96
+ var formatOptions = {
97
+ tabWidth: 2,
98
+ printWidth: 160,
99
+ parser: "typescript",
100
+ singleQuote: true,
101
+ semi: false,
102
+ bracketSameLine: false,
103
+ endOfLine: "auto"
104
+ };
105
+ var format = (text) => {
106
+ return format$1(text, formatOptions);
107
+ };
108
+
109
+ // src/utils/write.ts
110
+ var write = async (data, path4, options = { format: false }) => {
111
+ const formattedData = options.format ? format(data) : data;
112
+ try {
113
+ await fse.stat(path4);
114
+ const oldContent = await fse.readFile(path4, { encoding: "utf-8" });
115
+ if (oldContent?.toString() === formattedData) {
116
+ return;
117
+ }
118
+ } catch (_err) {
119
+ return fse.outputFile(path4, formattedData);
120
+ }
121
+ return fse.outputFile(path4, formattedData);
122
+ };
123
+
92
124
  // src/utils/cache.ts
93
125
  function createPluginCache(cache) {
94
126
  return {
@@ -114,15 +146,15 @@ function createPluginCache(cache) {
114
146
  }
115
147
  };
116
148
  }
149
+ var getRelativePath = (from, to) => {
150
+ if (!from || !to) {
151
+ throw new Error("From and to should be filled in when retrieving the relativePath");
152
+ }
153
+ const newPath = path2.relative(from, to).replace("../", "").replace(".ts", "").trimEnd();
154
+ return `./${newPath}`;
155
+ };
117
156
 
118
- // src/context.ts
119
- function getPluginContext(plugin, pluginCache) {
120
- const cacheKey = plugin.cacheKey || plugin.name;
121
- const cacheInstance = createPluginCache(pluginCache[cacheKey] || (pluginCache[cacheKey] = /* @__PURE__ */ Object.create(null)));
122
- return {
123
- cache: cacheInstance
124
- };
125
- }
157
+ // src/plugin.ts
126
158
  function createPlugin(factory) {
127
159
  return (userOptions) => {
128
160
  const plugin = factory(userOptions);
@@ -140,23 +172,46 @@ function createPlugin(factory) {
140
172
  var name = "core";
141
173
  var definePlugin = createPlugin((options) => {
142
174
  const { fileEmitter, resolveId, load } = options;
143
- const schema = fse2.readFileSync(path2.resolve(options.config.root, options.config.input.path), "utf-8");
175
+ const indexFiles = [];
144
176
  const api = {
145
177
  get config() {
146
178
  return options.config;
147
179
  },
148
- get input() {
149
- return schema;
180
+ async emitFile(emittedFile) {
181
+ const resolvedId = await resolveId(emittedFile.id, emittedFile.importer, emittedFile.options);
182
+ const id = resolvedId || emittedFile.importer || emittedFile.id;
183
+ return fileEmitter.emitFile({
184
+ ...emittedFile,
185
+ id
186
+ });
187
+ },
188
+ addToIndex: (emittedFile) => {
189
+ indexFiles.push(emittedFile);
150
190
  },
151
- on: fileEmitter.on.bind(fileEmitter),
152
- getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),
153
- emitFile: fileEmitter.emitFile.bind(fileEmitter),
154
191
  resolveId,
155
- load
192
+ load,
193
+ cache: createPluginCache(/* @__PURE__ */ Object.create(null))
156
194
  };
157
195
  return {
158
196
  name,
159
- api
197
+ api,
198
+ async buildEnd() {
199
+ if (!indexFiles.length) {
200
+ return;
201
+ }
202
+ let index = ``;
203
+ indexFiles.forEach((item) => {
204
+ index += `export * from "${getRelativePath(path2.resolve(this.config.root, this.config.output.path), item.id)}";
205
+ `;
206
+ });
207
+ await write(index, path2.resolve(this.config.root, this.config.output.path, "index.ts"), { format: true });
208
+ },
209
+ resolveId(importee, importer) {
210
+ if (!importer) {
211
+ return null;
212
+ }
213
+ return path2.resolve(importer, importee);
214
+ }
160
215
  };
161
216
  });
162
217
 
@@ -172,36 +227,17 @@ var hookNames = {
172
227
  };
173
228
  var hooks = Object.keys(hookNames);
174
229
  var PluginDriver = class {
175
- pluginContexts;
176
230
  plugins;
177
- fileEmitter;
231
+ fileEmitter = new FileEmitter();
178
232
  logger;
179
233
  config;
180
- sortedPlugins = /* @__PURE__ */ new Map();
181
- constructor(config, pluginCache, options) {
234
+ core;
235
+ constructor(config, options) {
182
236
  this.logger = options.logger;
183
237
  this.config = config;
184
- this.fileEmitter = new FileEmitter();
185
238
  this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter);
186
- const corePlugin = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId });
187
- this.plugins = [corePlugin, ...config.plugins || []];
188
- const coreApi = corePlugin.api;
189
- this.pluginContexts = new Map(
190
- this.plugins.map((plugin) => {
191
- const context = {
192
- ...coreApi,
193
- ...getPluginContext.call(this, plugin, pluginCache)
194
- };
195
- return [plugin, context];
196
- })
197
- );
198
- }
199
- get api() {
200
- let context = {};
201
- this.pluginContexts.forEach((value) => {
202
- context = { ...context, ...value };
203
- });
204
- return context;
239
+ this.core = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId });
240
+ this.plugins = [this.core, ...config.plugins || []];
205
241
  }
206
242
  emitFile(...params) {
207
243
  return this.fileEmitter.emitFile(...params);
@@ -221,7 +257,7 @@ var PluginDriver = class {
221
257
  promise = promise.then((result) => {
222
258
  if (result != null)
223
259
  return result;
224
- return this.runHook("hookFirst", hookName, parameters, plugin);
260
+ return this.run("hookFirst", hookName, parameters, plugin);
225
261
  });
226
262
  }
227
263
  return promise;
@@ -232,9 +268,9 @@ var PluginDriver = class {
232
268
  if (plugin[hookName]?.sequential) {
233
269
  await Promise.all(parallelPromises);
234
270
  parallelPromises.length = 0;
235
- await this.runHook("hookParallel", hookName, parameters, plugin);
271
+ await this.run("hookParallel", hookName, parameters, plugin);
236
272
  } else {
237
- const promise = this.runHook("hookParallel", hookName, parameters, plugin);
273
+ const promise = this.run("hookParallel", hookName, parameters, plugin);
238
274
  parallelPromises.push(promise);
239
275
  }
240
276
  }
@@ -244,8 +280,8 @@ var PluginDriver = class {
244
280
  let promise = Promise.resolve(argument0);
245
281
  for (const plugin of this.getSortedPlugins(hookName)) {
246
282
  promise = promise.then(
247
- (argument02) => this.runHook("hookReduceArg0", hookName, [argument02, ...rest], plugin).then(
248
- (result) => reduce.call(this.api, argument02, result, plugin)
283
+ (argument02) => this.run("hookReduceArg0", hookName, [argument02, ...rest], plugin).then(
284
+ (result) => reduce.call(this.core.api, argument02, result, plugin)
249
285
  )
250
286
  );
251
287
  }
@@ -254,14 +290,14 @@ var PluginDriver = class {
254
290
  hookSeq(hookName, parameters) {
255
291
  let promise = Promise.resolve();
256
292
  for (const plugin of this.getSortedPlugins(hookName)) {
257
- promise = promise.then(() => this.runHook("hookSeq", hookName, parameters, plugin));
293
+ promise = promise.then(() => this.run("hookSeq", hookName, parameters, plugin));
258
294
  }
259
295
  return promise.then(noReturn);
260
296
  }
261
297
  getSortedPlugins(_hookName) {
262
298
  return [...this.plugins];
263
299
  }
264
- runHook(strategy, hookName, parameters, plugin) {
300
+ run(strategy, hookName, parameters, plugin) {
265
301
  const hook = plugin[hookName];
266
302
  return Promise.resolve().then(() => {
267
303
  if (typeof hook !== "function") {
@@ -271,7 +307,7 @@ var PluginDriver = class {
271
307
  this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name}
272
308
  `;
273
309
  }
274
- const hookResult = hook.apply(this.api, parameters);
310
+ const hookResult = hook.apply(this.core.api, parameters);
275
311
  if (!hookResult?.then) {
276
312
  if (this.config.logLevel === "info" && this.logger?.spinner) {
277
313
  this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name}
@@ -288,10 +324,10 @@ var PluginDriver = class {
288
324
  });
289
325
  });
290
326
  }
291
- runHookSync(hookName, parameters, plugin) {
327
+ runSync(hookName, parameters, plugin) {
292
328
  const hook = plugin[hookName];
293
329
  try {
294
- return hook.apply(this.api, parameters);
330
+ return hook.apply(this.core.api, parameters);
295
331
  } catch (error) {
296
332
  return error;
297
333
  }
@@ -300,6 +336,14 @@ var PluginDriver = class {
300
336
  function noReturn() {
301
337
  }
302
338
 
339
+ // src/config.ts
340
+ var defaultConfig = {
341
+ root: process.cwd()
342
+ };
343
+ function defineConfig(config) {
344
+ return config;
345
+ }
346
+
303
347
  // src/build.ts
304
348
  async function transformReducer(previousCode, result, _plugin) {
305
349
  if (result === null) {
@@ -308,115 +352,71 @@ async function transformReducer(previousCode, result, _plugin) {
308
352
  return result;
309
353
  }
310
354
  async function buildImplementation(options, done) {
311
- const { config } = options;
312
- const pluginCache = /* @__PURE__ */ Object.create(null);
313
- const pluginDriver = new PluginDriver(config, pluginCache, { logger: this.logger });
355
+ const { config, logger } = options;
356
+ if (config.clear) {
357
+ await fse.remove(config.output.path);
358
+ }
359
+ const pluginDriver = new PluginDriver(
360
+ {
361
+ ...defaultConfig,
362
+ ...config
363
+ },
364
+ { logger }
365
+ );
366
+ const input = fse.readFileSync(path2.resolve(config.root, config.input.path), "utf-8");
314
367
  const validations = await pluginDriver.hookParallel("validate", [pluginDriver.plugins]);
315
368
  const validationsWithMessage = validations.filter(Boolean);
316
369
  if (validationsWithMessage.some((validation) => typeof validation !== "boolean")) {
317
370
  validationsWithMessage.forEach((validation) => {
318
371
  if (validation && typeof validation !== "boolean" && validation?.message) {
319
- this.logger?.log(validation.message, "warn");
372
+ logger?.log(validation.message, "warn");
320
373
  }
321
374
  });
322
375
  return;
323
376
  }
324
377
  pluginDriver.fileEmitter.on("new", async (emittedFile) => {
325
- if (!emittedFile?.source) {
378
+ if (!emittedFile) {
326
379
  return;
327
380
  }
328
- const resolvedId = await pluginDriver.hookFirst("resolveId", [emittedFile.source, path2.resolve(emittedFile.source), emittedFile.meta]);
329
- const id = resolvedId || emittedFile.source;
330
- let { code } = emittedFile;
381
+ const { id } = emittedFile;
382
+ if (!id) {
383
+ throw new Error("No id could be transformed, please add id to emitFile or use resolveId");
384
+ }
385
+ let { source: code } = emittedFile;
331
386
  const loadedResult = await pluginDriver.hookFirst("load", [id]);
332
387
  if (loadedResult) {
333
388
  code = loadedResult;
334
389
  }
335
390
  if (code) {
336
- const result = await pluginDriver.hookReduceArg0("transform", [code, id], transformReducer);
337
- await pluginDriver.hookParallel("writeFile", [result, id]);
391
+ const transformedCode = await pluginDriver.hookReduceArg0("transform", [code, id], transformReducer);
392
+ await pluginDriver.hookParallel("writeFile", [transformedCode, id]);
338
393
  pluginDriver.fileEmitter.delete(emittedFile.id);
339
394
  }
340
395
  });
341
396
  await pluginDriver.hookParallel("buildStart");
342
397
  pluginDriver.emitFile({
343
- id: path2.resolve(pluginDriver.api.config.root, pluginDriver.api.config.input.path),
344
- source: pluginDriver.api.config.input.path,
398
+ id: config.input.path,
345
399
  name: void 0,
346
- code: pluginDriver.api.input
400
+ source: input
347
401
  });
348
402
  pluginDriver.fileEmitter.on("end", async () => {
349
403
  await pluginDriver.hookParallel("buildEnd");
350
404
  done();
351
405
  });
352
406
  }
353
- function build(userConfig, env) {
354
- const config = {
355
- ...userConfig,
356
- root: userConfig.root || process.cwd()
357
- };
358
- return new Promise((resolve) => {
359
- buildImplementation.call(
360
- this,
361
- {
362
- config,
363
- env
364
- },
365
- resolve
366
- );
407
+ function build(options) {
408
+ return new Promise((resolve, reject) => {
409
+ try {
410
+ buildImplementation(options, resolve);
411
+ } catch (e) {
412
+ reject(e);
413
+ }
367
414
  });
368
415
  }
369
416
 
370
- // src/config.ts
371
- function defineConfig(config) {
372
- return config;
373
- }
374
-
375
- // src/utils/isPromise.ts
376
- var isPromise = (result) => {
377
- return typeof result?.then === "function";
378
- };
379
- var formatOptions = {
380
- tabWidth: 2,
381
- printWidth: 160,
382
- parser: "typescript",
383
- singleQuote: true,
384
- semi: false,
385
- bracketSameLine: false,
386
- endOfLine: "auto"
387
- };
388
- var format = (text) => {
389
- return format$1(text, formatOptions);
390
- };
391
-
392
- // src/utils/write.ts
393
- var write = async (data, path4, options = { format: false }) => {
394
- const formattedData = options.format ? format(data) : data;
395
- try {
396
- await fse2.stat(path4);
397
- const oldContent = await fse2.readFile(path4, { encoding: "utf-8" });
398
- if (oldContent?.toString() === formattedData) {
399
- return;
400
- }
401
- } catch (_err) {
402
- return fse2.outputFile(path4, formattedData);
403
- }
404
- return fse2.outputFile(path4, formattedData);
405
- };
406
- var getRelativePath = (from, to) => {
407
- if (!from || !to) {
408
- throw new Error("From and to should be filled in when retrieving the relativePath");
409
- }
410
- const newPath = path2.relative(from, to).replace("../", "").replace(".ts", "").trimEnd();
411
- if (newPath.startsWith("./") || newPath.startsWith("../")) {
412
- return newPath.replace;
413
- }
414
- return `./${newPath}`;
415
- };
416
-
417
417
  // src/index.ts
418
418
  var src_default = build;
419
419
 
420
- export { Emitter, FileEmitter, PluginDriver, build, createPlugin, createPluginCache, src_default as default, defineConfig, format, getPluginContext, getRelativePath, hooks, isPromise, write };
420
+ export { Emitter, FileEmitter, PluginDriver, build, createPlugin, createPluginCache, src_default as default, defaultConfig, defineConfig, format, getRelativePath, hooks, isPromise, write };
421
421
  //# sourceMappingURL=out.js.map
422
422
  //# sourceMappingURL=index.mjs.map