@kubb/core
Advanced tools
Comparing version 0.11.2 to 0.13.0
@@ -21,7 +21,20 @@ type WithPromise<T> = Promise<T> | T; | ||
interface EmittedFile { | ||
/** | ||
* equal to importee when getting passed through resolveId | ||
*/ | ||
id: string; | ||
source: string | undefined; | ||
name: string | undefined; | ||
code: string | undefined; | ||
meta?: Record<string, any>; | ||
/** | ||
* The importer is the fully resolved id of the importing module. | ||
*/ | ||
importer?: string; | ||
/** | ||
* Name to be used to dynamicly create the fileName(based on input.path) | ||
*/ | ||
name?: string; | ||
/** | ||
* FileName will be the end result so no input.path will not be added | ||
*/ | ||
fileName?: string; | ||
source?: string; | ||
options?: Record<string, any>; | ||
} | ||
@@ -42,13 +55,2 @@ type EmitFile = (emittedFile: EmittedFile) => void; | ||
interface SerializablePluginCache { | ||
[key: string]: [number, any]; | ||
} | ||
interface Cache<TCache = any> { | ||
delete(id: string): boolean; | ||
get<T = TCache>(id: string): T; | ||
has(id: string): boolean; | ||
set<T = TCache>(id: string, value: T): void; | ||
} | ||
declare function createPluginCache(cache: SerializablePluginCache): Cache; | ||
/** | ||
@@ -61,3 +63,2 @@ * Get the type of the first argument in a function. | ||
declare class PluginDriver { | ||
private readonly pluginContexts; | ||
plugins: Plugin[]; | ||
@@ -67,7 +68,8 @@ readonly fileEmitter: FileEmitter; | ||
private readonly config; | ||
private readonly sortedPlugins; | ||
constructor(config: Api['config'], pluginCache: Record<string, SerializablePluginCache> | undefined, options: { | ||
logger: BuildContext['logger']; | ||
readonly core: Plugin<CorePluginOptions> & { | ||
api: CorePluginOptions['api']; | ||
}; | ||
constructor(config: Api['config'], options: { | ||
logger: BuildOptions['logger']; | ||
}); | ||
get api(): PluginContext; | ||
emitFile(...params: Parameters<FileEmitter['emitFile']>): Promise<EmittedFile>; | ||
@@ -87,3 +89,3 @@ resolveId: (source: string, importer: string, meta: Record<string, any> | undefined) => Promise<string | null | undefined>; | ||
*/ | ||
private runHook; | ||
private run; | ||
/** | ||
@@ -96,17 +98,16 @@ * Run a sync plugin hook and return the result. | ||
*/ | ||
private runHookSync; | ||
private runSync; | ||
} | ||
interface Cache<TCache = any> { | ||
delete(id: string): boolean; | ||
get<T = TCache>(id: string): T; | ||
has(id: string): boolean; | ||
set<T = TCache>(id: string, value: T): void; | ||
} | ||
declare function createPluginCache(cache: any): Cache; | ||
declare const format: (text: string) => string; | ||
declare const getRelativePath: (from?: string | null, to?: string | null) => string | { | ||
(searchValue: string | RegExp, replaceValue: string): string; | ||
(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string; | ||
(searchValue: { | ||
[Symbol.replace](string: string, replaceValue: string): string; | ||
}, replaceValue: string): string; | ||
(searchValue: { | ||
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; | ||
}, replacer: (substring: string, ...args: any[]) => string): string; | ||
}; | ||
declare const getRelativePath: (from?: string | null, to?: string | null) => string; | ||
@@ -119,4 +120,3 @@ type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = { | ||
type Plugin<TOptions extends PluginOptions = PluginOptions> = { | ||
name: PluginName | Omit<string, PluginName>; | ||
cacheKey?: string; | ||
name: string; | ||
api?: TOptions['api']; | ||
@@ -126,6 +126,10 @@ } & Partial<PluginLifecycle>; | ||
declare function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>): (userOptions: TOptions['userOptions']) => TOptions["nested"] extends true ? Plugin<TOptions>[] : Plugin<TOptions>; | ||
type Options = { | ||
config: Api['config']; | ||
fileEmitter: FileEmitter; | ||
resolveId: Api['resolveId']; | ||
load: Api['load']; | ||
}; | ||
type CorePluginOptions = PluginOptions<Options, false, Api>; | ||
interface ConfigEnv { | ||
mode: 'development'; | ||
} | ||
interface UserConfig { | ||
@@ -137,3 +141,3 @@ /** | ||
*/ | ||
root?: string; | ||
root: string; | ||
mode?: 'single'; | ||
@@ -161,4 +165,5 @@ input: { | ||
} | ||
type UserConfigFn = (env: ConfigEnv) => WithPromise<UserConfig>; | ||
type UserConfigFn = (options: BuildOptions) => WithPromise<UserConfig>; | ||
type UserConfigExport = WithPromise<UserConfig> | UserConfigFn; | ||
declare const defaultConfig: Partial<UserConfig>; | ||
/** | ||
@@ -171,7 +176,6 @@ * Type helper to make it easier to use kubb.config.ts | ||
type PluginName = string; | ||
type PluginLifecycle = { | ||
validate: (this: PluginContext, plugins: Plugin[]) => WithPromise<ValidationResult>; | ||
buildStart: (this: PluginContext) => WithPromise<void>; | ||
resolveId: (this: PluginContext, source: string, importer: string | undefined, meta: Record<string, any> | undefined) => string | null | undefined; | ||
resolveId: (this: PluginContext, importee: string, importer?: string, options?: Record<string, any>) => string | null | undefined; | ||
load: (this: PluginContext, id: string) => WithPromise<TransformResult | null>; | ||
@@ -184,15 +188,9 @@ transform: (this: PluginContext, code: string, id: string) => WithPromise<TransformResult>; | ||
type Api = { | ||
config: UserConfig & { | ||
root: string; | ||
}; | ||
input: Path; | ||
config: UserConfig; | ||
cache: Cache; | ||
emitFile: FileEmitter['emitFile']; | ||
resolveId: (source: string, importer?: string, meta?: Record<string, any>) => WithPromise<string | null | undefined>; | ||
resolveId: (importee: string, importer?: string, options?: Record<string, any>) => WithPromise<string | null | undefined>; | ||
load: (id: string) => WithPromise<TransformResult | void>; | ||
getEmittedFile: FileEmitter['getEmittedFile']; | ||
on: FileEmitter['on']; | ||
}; | ||
type PluginContext = Api & { | ||
cache: Cache; | ||
}; | ||
type PluginContext = Api; | ||
type ValidationResult = true | { | ||
@@ -202,4 +200,2 @@ message: string; | ||
type TransformResult = string | null; | ||
type Id = string; | ||
type Path = string; | ||
type LogType = 'error' | 'warn' | 'info'; | ||
@@ -219,3 +215,5 @@ type LogLevel = LogType | 'silent'; | ||
}; | ||
type BuildContext = { | ||
type BuildOptions = { | ||
config: Api['config']; | ||
mode: 'development' | 'production'; | ||
logger?: { | ||
@@ -226,8 +224,4 @@ log: (message: string, logLevel: LogLevel) => void; | ||
}; | ||
declare function build(this: BuildContext, userConfig: UserConfig, env: ConfigEnv): Promise<BuildOutput>; | ||
declare function build(options: BuildOptions): Promise<BuildOutput>; | ||
declare function getPluginContext(this: PluginDriver, plugin: Plugin, pluginCache: Record<string, SerializablePluginCache> | void): { | ||
cache: Cache<any>; | ||
}; | ||
export { Api, Argument0, BuildContext, Cache, ConfigEnv, EmitFile, EmittedFile, Emitter, FileEmitter, Id, Listener, LogLevel, LogType, Path, Plugin, PluginContext, PluginDriver, PluginFactory, PluginLifecycle, PluginLifecycleHooks, PluginName, PluginOptions, SerializablePluginCache, TransformResult, UserConfig, UserConfigExport, UserConfigFn, ValidationResult, WithPromise, build, createPlugin, createPluginCache, build as default, defineConfig, format, getPluginContext, getRelativePath, hooks, isPromise, write }; | ||
export { Api, Argument0, BuildOptions, Cache, EmitFile, EmittedFile, Emitter, FileEmitter, Listener, LogLevel, LogType, Plugin, PluginContext, PluginDriver, PluginFactory, PluginLifecycle, PluginLifecycleHooks, PluginOptions, TransformResult, UserConfig, UserConfigExport, UserConfigFn, ValidationResult, WithPromise, build, createPlugin, createPluginCache, build as default, defaultConfig, defineConfig, format, getRelativePath, hooks, isPromise, write }; |
@@ -5,4 +5,4 @@ 'use strict'; | ||
var path2 = require('path'); | ||
var fse2 = require('fs-extra'); | ||
var path = require('path'); | ||
var fse = require('fs-extra'); | ||
var prettier = require('prettier'); | ||
@@ -62,3 +62,3 @@ | ||
const subscribe = this.emitter.on("delete", (deletedFile) => { | ||
if (deletedFile?.id === emitedFile.id) { | ||
if (deletedFile?.id && deletedFile?.id === emitedFile.id) { | ||
resolve(deletedFile); | ||
@@ -98,2 +98,34 @@ return subscribe(); | ||
// src/utils/isPromise.ts | ||
var isPromise = (result) => { | ||
return typeof result?.then === "function"; | ||
}; | ||
var formatOptions = { | ||
tabWidth: 2, | ||
printWidth: 160, | ||
parser: "typescript", | ||
singleQuote: true, | ||
semi: false, | ||
bracketSameLine: false, | ||
endOfLine: "auto" | ||
}; | ||
var format = (text) => { | ||
return prettier.format(text, formatOptions); | ||
}; | ||
// src/utils/write.ts | ||
var write = async (data, path4, options = { format: false }) => { | ||
const formattedData = options.format ? format(data) : data; | ||
try { | ||
await fse.stat(path4); | ||
const oldContent = await fse.readFile(path4, { encoding: "utf-8" }); | ||
if (oldContent?.toString() === formattedData) { | ||
return; | ||
} | ||
} catch (_err) { | ||
return fse.outputFile(path4, formattedData); | ||
} | ||
return fse.outputFile(path4, formattedData); | ||
}; | ||
// src/utils/cache.ts | ||
@@ -124,11 +156,11 @@ function createPluginCache(cache) { | ||
} | ||
var getRelativePath = (from, to) => { | ||
if (!from || !to) { | ||
throw new Error("From and to should be filled in when retrieving the relativePath"); | ||
} | ||
const newPath = path.relative(from, to).replace("../", "").replace(".ts", "").trimEnd(); | ||
return `./${newPath}`; | ||
}; | ||
// src/context.ts | ||
function getPluginContext(plugin, pluginCache) { | ||
const cacheKey = plugin.cacheKey || plugin.name; | ||
const cacheInstance = createPluginCache(pluginCache[cacheKey] || (pluginCache[cacheKey] = /* @__PURE__ */ Object.create(null))); | ||
return { | ||
cache: cacheInstance | ||
}; | ||
} | ||
// src/plugin.ts | ||
function createPlugin(factory) { | ||
@@ -151,3 +183,2 @@ return (userOptions) => { | ||
const { fileEmitter, resolveId, load } = options; | ||
const schema = fse2.readFileSync(path2.resolve(options.config.root, options.config.input.path), "utf-8"); | ||
const api = { | ||
@@ -157,14 +188,23 @@ get config() { | ||
}, | ||
get input() { | ||
return schema; | ||
async emitFile(emittedFile) { | ||
const resolvedId = await resolveId(emittedFile.id, emittedFile.importer, emittedFile.options); | ||
const id = resolvedId || emittedFile.importer || emittedFile.id; | ||
return fileEmitter.emitFile({ | ||
...emittedFile, | ||
id | ||
}); | ||
}, | ||
on: fileEmitter.on.bind(fileEmitter), | ||
getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter), | ||
emitFile: fileEmitter.emitFile.bind(fileEmitter), | ||
resolveId, | ||
load | ||
load, | ||
cache: createPluginCache(/* @__PURE__ */ Object.create(null)) | ||
}; | ||
return { | ||
name, | ||
api | ||
api, | ||
resolveId(importee, importer) { | ||
if (!importer) { | ||
return null; | ||
} | ||
return path.resolve(importer, importee); | ||
} | ||
}; | ||
@@ -185,33 +225,14 @@ }); | ||
var PluginDriver = class { | ||
pluginContexts; | ||
plugins; | ||
fileEmitter; | ||
fileEmitter = new FileEmitter(); | ||
logger; | ||
config; | ||
sortedPlugins = /* @__PURE__ */ new Map(); | ||
constructor(config, pluginCache, options) { | ||
core; | ||
constructor(config, options) { | ||
this.logger = options.logger; | ||
this.config = config; | ||
this.fileEmitter = new FileEmitter(); | ||
this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter); | ||
const corePlugin = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId }); | ||
this.plugins = [corePlugin, ...config.plugins || []]; | ||
const coreApi = corePlugin.api; | ||
this.pluginContexts = new Map( | ||
this.plugins.map((plugin) => { | ||
const context = { | ||
...coreApi, | ||
...getPluginContext.call(this, plugin, pluginCache) | ||
}; | ||
return [plugin, context]; | ||
}) | ||
); | ||
this.core = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId }); | ||
this.plugins = [this.core, ...config.plugins || []]; | ||
} | ||
get api() { | ||
let context = {}; | ||
this.pluginContexts.forEach((value) => { | ||
context = { ...context, ...value }; | ||
}); | ||
return context; | ||
} | ||
emitFile(...params) { | ||
@@ -235,3 +256,3 @@ return this.fileEmitter.emitFile(...params); | ||
return result; | ||
return this.runHook("hookFirst", hookName, parameters, plugin); | ||
return this.run("hookFirst", hookName, parameters, plugin); | ||
}); | ||
@@ -247,5 +268,5 @@ } | ||
parallelPromises.length = 0; | ||
await this.runHook("hookParallel", hookName, parameters, plugin); | ||
await this.run("hookParallel", hookName, parameters, plugin); | ||
} else { | ||
const promise = this.runHook("hookParallel", hookName, parameters, plugin); | ||
const promise = this.run("hookParallel", hookName, parameters, plugin); | ||
parallelPromises.push(promise); | ||
@@ -260,4 +281,4 @@ } | ||
promise = promise.then( | ||
(argument02) => this.runHook("hookReduceArg0", hookName, [argument02, ...rest], plugin).then( | ||
(result) => reduce.call(this.api, argument02, result, plugin) | ||
(argument02) => this.run("hookReduceArg0", hookName, [argument02, ...rest], plugin).then( | ||
(result) => reduce.call(this.core.api, argument02, result, plugin) | ||
) | ||
@@ -271,3 +292,3 @@ ); | ||
for (const plugin of this.getSortedPlugins(hookName)) { | ||
promise = promise.then(() => this.runHook("hookSeq", hookName, parameters, plugin)); | ||
promise = promise.then(() => this.run("hookSeq", hookName, parameters, plugin)); | ||
} | ||
@@ -279,3 +300,3 @@ return promise.then(noReturn); | ||
} | ||
runHook(strategy, hookName, parameters, plugin) { | ||
run(strategy, hookName, parameters, plugin) { | ||
const hook = plugin[hookName]; | ||
@@ -290,3 +311,3 @@ return Promise.resolve().then(() => { | ||
} | ||
const hookResult = hook.apply(this.api, parameters); | ||
const hookResult = hook.apply(this.core.api, parameters); | ||
if (!hookResult?.then) { | ||
@@ -308,6 +329,6 @@ if (this.config.logLevel === "info" && this.logger?.spinner) { | ||
} | ||
runHookSync(hookName, parameters, plugin) { | ||
runSync(hookName, parameters, plugin) { | ||
const hook = plugin[hookName]; | ||
try { | ||
return hook.apply(this.api, parameters); | ||
return hook.apply(this.core.api, parameters); | ||
} catch (error) { | ||
@@ -321,2 +342,10 @@ return error; | ||
// src/config.ts | ||
var defaultConfig = { | ||
root: process.cwd() | ||
}; | ||
function defineConfig(config) { | ||
return config; | ||
} | ||
// src/build.ts | ||
@@ -330,5 +359,11 @@ async function transformReducer(previousCode, result, _plugin) { | ||
async function buildImplementation(options, done) { | ||
const { config } = options; | ||
const pluginCache = /* @__PURE__ */ Object.create(null); | ||
const pluginDriver = new PluginDriver(config, pluginCache, { logger: this.logger }); | ||
const { config, logger } = options; | ||
const pluginDriver = new PluginDriver( | ||
{ | ||
...defaultConfig, | ||
...config | ||
}, | ||
{ logger } | ||
); | ||
const input = fse.readFileSync(path.resolve(config.root, config.input.path), "utf-8"); | ||
const validations = await pluginDriver.hookParallel("validate", [pluginDriver.plugins]); | ||
@@ -339,3 +374,3 @@ const validationsWithMessage = validations.filter(Boolean); | ||
if (validation && typeof validation !== "boolean" && validation?.message) { | ||
this.logger?.log(validation.message, "warn"); | ||
logger?.log(validation.message, "warn"); | ||
} | ||
@@ -346,8 +381,10 @@ }); | ||
pluginDriver.fileEmitter.on("new", async (emittedFile) => { | ||
if (!emittedFile?.source) { | ||
if (!emittedFile) { | ||
return; | ||
} | ||
const resolvedId = await pluginDriver.hookFirst("resolveId", [emittedFile.source, path2.resolve(emittedFile.source), emittedFile.meta]); | ||
const id = resolvedId || emittedFile.source; | ||
let { code } = emittedFile; | ||
const { id } = emittedFile; | ||
if (!id) { | ||
throw new Error("No id could be transformed, please add id to emitFile or use resolveId"); | ||
} | ||
let { source: code } = emittedFile; | ||
const loadedResult = await pluginDriver.hookFirst("load", [id]); | ||
@@ -358,4 +395,4 @@ if (loadedResult) { | ||
if (code) { | ||
const result = await pluginDriver.hookReduceArg0("transform", [code, id], transformReducer); | ||
await pluginDriver.hookParallel("writeFile", [result, id]); | ||
const transformedCode = await pluginDriver.hookReduceArg0("transform", [code, id], transformReducer); | ||
await pluginDriver.hookParallel("writeFile", [transformedCode, id]); | ||
pluginDriver.fileEmitter.delete(emittedFile.id); | ||
@@ -366,6 +403,5 @@ } | ||
pluginDriver.emitFile({ | ||
id: path2.resolve(pluginDriver.api.config.root, pluginDriver.api.config.input.path), | ||
source: pluginDriver.api.config.input.path, | ||
id: config.input.path, | ||
name: void 0, | ||
code: pluginDriver.api.input | ||
source: input | ||
}); | ||
@@ -377,66 +413,12 @@ pluginDriver.fileEmitter.on("end", async () => { | ||
} | ||
function build(userConfig, env) { | ||
const config = { | ||
...userConfig, | ||
root: userConfig.root || process.cwd() | ||
}; | ||
return new Promise((resolve) => { | ||
buildImplementation.call( | ||
this, | ||
{ | ||
config, | ||
env | ||
}, | ||
resolve | ||
); | ||
function build(options) { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
buildImplementation(options, resolve); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
} | ||
// src/config.ts | ||
function defineConfig(config) { | ||
return config; | ||
} | ||
// src/utils/isPromise.ts | ||
var isPromise = (result) => { | ||
return typeof result?.then === "function"; | ||
}; | ||
var formatOptions = { | ||
tabWidth: 2, | ||
printWidth: 160, | ||
parser: "typescript", | ||
singleQuote: true, | ||
semi: false, | ||
bracketSameLine: false, | ||
endOfLine: "auto" | ||
}; | ||
var format = (text) => { | ||
return prettier.format(text, formatOptions); | ||
}; | ||
// src/utils/write.ts | ||
var write = async (data, path4, options = { format: false }) => { | ||
const formattedData = options.format ? format(data) : data; | ||
try { | ||
await fse2.stat(path4); | ||
const oldContent = await fse2.readFile(path4, { encoding: "utf-8" }); | ||
if (oldContent?.toString() === formattedData) { | ||
return; | ||
} | ||
} catch (_err) { | ||
return fse2.outputFile(path4, formattedData); | ||
} | ||
return fse2.outputFile(path4, formattedData); | ||
}; | ||
var getRelativePath = (from, to) => { | ||
if (!from || !to) { | ||
throw new Error("From and to should be filled in when retrieving the relativePath"); | ||
} | ||
const newPath = path2.relative(from, to).replace("../", "").replace(".ts", "").trimEnd(); | ||
if (newPath.startsWith("./") || newPath.startsWith("../")) { | ||
return newPath.replace; | ||
} | ||
return `./${newPath}`; | ||
}; | ||
// src/index.ts | ||
@@ -452,5 +434,5 @@ var src_default = build; | ||
exports.default = src_default; | ||
exports.defaultConfig = defaultConfig; | ||
exports.defineConfig = defineConfig; | ||
exports.format = format; | ||
exports.getPluginContext = getPluginContext; | ||
exports.getRelativePath = getRelativePath; | ||
@@ -457,0 +439,0 @@ exports.hooks = hooks; |
{ | ||
"name": "@kubb/core", | ||
"version": "0.11.2", | ||
"version": "0.13.0", | ||
"description": "Generator core", | ||
@@ -5,0 +5,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
95052
1054