🚀 Socket Launch Week 🚀 Day 1: Introducing .NET Support in Socket.Learn More →

@kubb/core

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kubb/core - npm Package Compare versions

Comparing version

to
1.0.0-beta.5

@@ -108,5 +108,5 @@ import { DirectoryTreeOptions } from 'directory-tree';

} & Partial<PluginLifecycle<TOptions>>;
type PluginFactoryOptions<Options = unknown, Nested extends boolean = false, Api = any, ResolveIdOptions = Record<string, any>> = {
type PluginFactoryOptions<Options = unknown, Nested extends boolean = false, Api = any, resolvePathOptions = Record<string, any>> = {
options: Options;
resolveIdOptions: ResolveIdOptions;
resolvePathOptions: resolvePathOptions;
nested: Nested;

@@ -127,11 +127,19 @@ api: Api;

/**
* Resolve to an id based on importee(example: `./Pet.ts`) and directory(example: `./models`).
* Resolve to a Path based on a fileName(example: `./Pet.ts`) and directory(example: `./models`).
* Options can als be included.
* @type hookFirst
* @example ('./Pet.ts', './src/gen/')
* @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'
*/
resolveId: (this: Omit<PluginContext, 'addFile'>, fileName: string, directory?: string, options?: TOptions['resolveIdOptions']) => OptionalPath;
resolvePath: (this: Omit<PluginContext, 'addFile'>, fileName: string, directory?: string, options?: TOptions['resolvePathOptions']) => OptionalPath;
/**
* Makes it possible to run async logic to override the path defined previously by `resolveId`.
* Resolve to a name based on a string.
* Useful when converting to PascalCase or camelCase.
* @type hookFirst
* @example ('pet') => 'Pet'
*/
resolveName: (this: Omit<PluginContext, 'addFile'>, name: string) => string | null;
/**
* Makes it possible to run async logic to override the path defined previously by `resolvePath`.
* @type hookFirst
*/
load: (this: Omit<PluginContext, 'addFile'>, path: Path) => MaybePromise<TransformResult | null>;

@@ -144,3 +152,3 @@ /**

/**
* Write the result to the file-system based on the id(defined by `resolveId` or changed by `load`).
* Write the result to the file-system based on the id(defined by `resolvePath` or changed by `load`).
* @type hookParallel

@@ -156,15 +164,23 @@ */

type PluginLifecycleHooks = keyof PluginLifecycle;
type ResolveIdParams<TOptions = Record<string, any>> = {
fileName: string;
directory?: string | undefined;
type ResolvePathParams<TOptions = Record<string, any>> = {
/**
* When set, resolveId will only call resolveId of the name of the plugin set here.
* If not defined it will fall back on the resolveId of the core plugin.
* When set, resolvePath will only call resolvePath of the name of the plugin set here.
* If not defined it will fall back on the resolvePath of the core plugin.
*/
pluginName?: string;
fileName: string;
directory?: string | undefined;
/**
* Options to be passed to 'resolveId' 3th parameter
* Options to be passed to 'resolvePath' 3th parameter
*/
options?: TOptions;
};
type ResolveNameParams = {
/**
* When set, resolvePath will only call resolvePath of the name of the plugin set here.
* If not defined it will fall back on the resolvePath of the core plugin.
*/
pluginName?: string;
name: string;
};
type PluginContext<TOptions = Record<string, any>> = {

@@ -175,3 +191,4 @@ config: KubbConfig;

addFile: (file: File) => Promise<File>;
resolveId: (params: ResolveIdParams<TOptions>) => MaybePromise<OptionalPath>;
resolvePath: (params: ResolvePathParams<TOptions>) => OptionalPath;
resolveName: (params: ResolveNameParams) => string | null;
load: (id: string) => MaybePromise<TransformResult | void>;

@@ -212,4 +229,4 @@ };

declare function createJSDocBlockText({ comments }: {
comments: Array<string | undefined>;
}): string | undefined;
comments: Array<string>;
}): string;

@@ -331,3 +348,4 @@ declare function getUniqueName(originalName: string, data: Record<string, number>): string;

fileManager: FileManager;
resolveId: PluginContext['resolveId'];
resolvePath: PluginContext['resolvePath'];
resolveName: PluginContext['resolveName'];
load: PluginContext['load'];

@@ -357,10 +375,52 @@ };

});
resolveId: (params: ResolveIdParams) => Promise<OptionalPath>;
resolvePath: (params: ResolvePathParams) => OptionalPath;
resolveName: (params: ResolveNameParams) => string | null;
load: (id: string) => Promise<TransformResult>;
hookForPlugin<H extends PluginLifecycleHooks>(pluginName: string, hookName: H, parameters: Parameters<PluginLifecycle[H]>, skipped?: ReadonlySet<KubbPlugin> | null): Promise<ReturnType<PluginLifecycle[H]> | null>;
hookFirst<H extends PluginLifecycleHooks>(hookName: H, parameters: Parameters<PluginLifecycle[H]>, skipped?: ReadonlySet<KubbPlugin> | null): Promise<ReturnType<PluginLifecycle[H]> | null>;
hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined): Promise<Awaited<TOuput>[]>;
hookReduceArg0<H extends PluginLifecycleHooks>(hookName: H, [argument0, ...rest]: Parameters<PluginLifecycle[H]>, reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: KubbPlugin) => MaybePromise<Argument0<H> | null>): Promise<Argument0<H>>;
hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>): Promise<void>;
/**
*
* Run only hook for a specific plugin name
*/
hookForPlugin<H extends PluginLifecycleHooks>({ pluginName, hookName, parameters, }: {
pluginName: string;
hookName: H;
parameters: Parameters<PluginLifecycle[H]>;
}): Promise<ReturnType<PluginLifecycle[H]> | null>;
hookForPluginSync<H extends PluginLifecycleHooks>({ pluginName, hookName, parameters, }: {
pluginName: string;
hookName: H;
parameters: Parameters<PluginLifecycle[H]>;
}): ReturnType<PluginLifecycle[H]> | null;
/**
*
* Chains, first non-null result stops and returns
*/
hookFirst<H extends PluginLifecycleHooks>({ hookName, parameters, skipped, }: {
hookName: H;
parameters: Parameters<PluginLifecycle[H]>;
skipped?: ReadonlySet<KubbPlugin> | null;
}): Promise<ReturnType<PluginLifecycle[H]> | null>;
/**
*
* Chains, first non-null result stops and returns
*/
hookFirstSync<H extends PluginLifecycleHooks>({ hookName, parameters, skipped, }: {
hookName: H;
parameters: Parameters<PluginLifecycle[H]>;
skipped?: ReadonlySet<KubbPlugin> | null;
}): ReturnType<PluginLifecycle[H]> | null;
hookParallel<H extends PluginLifecycleHooks, TOuput = void>({ hookName, parameters, }: {
hookName: H;
parameters?: Parameters<PluginLifecycle[H]> | undefined;
}): Promise<Awaited<TOuput>[]>;
hookReduceArg0<H extends PluginLifecycleHooks>({ hookName, parameters, reduce, }: {
hookName: H;
parameters: Parameters<PluginLifecycle[H]>;
reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: KubbPlugin) => MaybePromise<Argument0<H> | null>;
}): Promise<Argument0<H>>;
hookSeq<H extends PluginLifecycleHooks>({ hookName, parameters }: {
hookName: H;
parameters?: Parameters<PluginLifecycle[H]>;
}): Promise<void>;
private getSortedPlugins;
private getPlugin;
/**

@@ -406,2 +466,2 @@ * Run an async plugin hook and return the result.

export { Argument0, CLIOptions, Cache, CacheStore, CorePluginOptions, File, FileManager, FileName, Generator, KubbBuild, KubbConfig, KubbJSONPlugin, KubbPlugin, KubbPluginKind, KubbUserConfig, LogLevel, LogType, Logger, MaybePromise, OptionalPath, Path, PathMode, PluginContext, PluginFactoryOptions, PluginLifecycle, PluginLifecycleHooks, PluginManager, Queue, QueueTask, ResolveIdParams, SchemaGenerator, Status, Strategy, TransformResult, TreeNode, TreeNodeOptions, UUID, ValidationPluginError, build, clean, combineFiles, createJSDocBlockText, createPlugin, createPluginCache, build as default, defineConfig, getFileSource, getPathMode, getRelativePath, getUniqueName, hooks, isPromise, isURL, name, nameSorter, objectToParameters, read, timeout, validatePlugins, write };
export { Argument0, CLIOptions, Cache, CacheStore, CorePluginOptions, File, FileManager, FileName, Generator, KubbBuild, KubbConfig, KubbJSONPlugin, KubbPlugin, KubbPluginKind, KubbUserConfig, LogLevel, LogType, Logger, MaybePromise, OptionalPath, Path, PathMode, PluginContext, PluginFactoryOptions, PluginLifecycle, PluginLifecycleHooks, PluginManager, Queue, QueueTask, ResolveNameParams, ResolvePathParams, SchemaGenerator, Status, Strategy, TransformResult, TreeNode, TreeNodeOptions, UUID, ValidationPluginError, build, clean, combineFiles, createJSDocBlockText, createPlugin, createPluginCache, build as default, defineConfig, getFileSource, getPathMode, getRelativePath, getUniqueName, hooks, isPromise, isURL, name, nameSorter, objectToParameters, read, timeout, validatePlugins, write };

@@ -142,3 +142,3 @@ import { createRequire } from 'module';

if (!filteredComments.length) {
return void 0;
return "";
}

@@ -218,3 +218,3 @@ const text = filteredComments.reduce((acc, comment) => {

var definePlugin = createPlugin((options) => {
const { fileManager, resolveId, load } = options;
const { fileManager, resolvePath, resolveName, load } = options;
const api = {

@@ -228,3 +228,4 @@ get config() {

},
resolveId,
resolvePath,
resolveName,
load,

@@ -237,3 +238,3 @@ cache: createPluginCache(/* @__PURE__ */ Object.create(null))

api,
resolveId(fileName, directory) {
resolvePath(fileName, directory) {
if (!directory) {

@@ -243,2 +244,5 @@ return null;

return pathParser2.resolve(directory, fileName);
},
resolveName(name2) {
return name2;
}

@@ -465,3 +469,4 @@ };

buildStart: 1,
resolveId: 1,
resolvePath: 1,
resolveName: 1,
load: 1,

@@ -489,19 +494,80 @@ transform: 1,

load: this.load,
resolveId: this.resolveId
resolvePath: this.resolvePath,
resolveName: this.resolveName
});
this.plugins = [this.core, ...config.plugins || []];
}
resolveId = (params) => {
resolvePath = (params) => {
if (params.pluginName) {
return this.hookForPlugin(params.pluginName, "resolveId", [params.fileName, params.directory, params.options]);
return this.hookForPluginSync({
pluginName: params.pluginName,
hookName: "resolvePath",
parameters: [params.fileName, params.directory, params.options]
});
}
return this.hookFirst("resolveId", [params.fileName, params.directory, params.options]);
return this.hookFirstSync({
hookName: "resolvePath",
parameters: [params.fileName, params.directory, params.options]
});
};
resolveName = (params) => {
if (params.pluginName) {
return this.hookForPluginSync({
pluginName: params.pluginName,
hookName: "resolveName",
parameters: [params.name]
});
}
return this.hookFirstSync({
hookName: "resolveName",
parameters: [params.name]
});
};
load = async (id) => {
return this.hookFirst("load", [id]);
return this.hookFirst({
hookName: "load",
parameters: [id]
});
};
// run only hook for a specific plugin name
hookForPlugin(pluginName, hookName, parameters, skipped) {
/**
*
* Run only hook for a specific plugin name
*/
hookForPlugin({
pluginName,
hookName,
parameters
}) {
const plugin = this.getPlugin(hookName, pluginName);
return this.run({
strategy: "hookFirst",
hookName,
parameters,
plugin
});
}
hookForPluginSync({
pluginName,
hookName,
parameters
}) {
const plugin = this.getPlugin(hookName, pluginName);
return this.runSync({
strategy: "hookFirst",
hookName,
parameters,
plugin
});
}
/**
*
* Chains, first non-null result stops and returns
*/
hookFirst({
hookName,
parameters,
skipped
}) {
let promise = Promise.resolve(null);
for (const plugin of this.getSortedPlugins(hookName, pluginName)) {
for (const plugin of this.getSortedPlugins(hookName)) {
if (skipped && skipped.has(plugin))

@@ -512,3 +578,8 @@ continue;

return result;
return this.run("hookFirst", hookName, parameters, plugin);
return this.run({
strategy: "hookFirst",
hookName,
parameters,
plugin
});
});

@@ -518,18 +589,32 @@ }

}
// chains, first non-null result stops and returns
hookFirst(hookName, parameters, skipped) {
let promise = Promise.resolve(null);
/**
*
* Chains, first non-null result stops and returns
*/
hookFirstSync({
hookName,
parameters,
skipped
}) {
let result = null;
for (const plugin of this.getSortedPlugins(hookName)) {
if (skipped && skipped.has(plugin))
continue;
promise = promise.then((result) => {
if (result != null)
return result;
return this.run("hookFirst", hookName, parameters, plugin);
result = this.runSync({
strategy: "hookFirst",
hookName,
parameters,
plugin
});
if (result != null) {
break;
}
}
return promise;
return result;
}
// parallel
async hookParallel(hookName, parameters) {
async hookParallel({
hookName,
parameters
}) {
const parallelPromises = [];

@@ -540,5 +625,10 @@ for (const plugin of this.getSortedPlugins(hookName)) {

parallelPromises.length = 0;
await this.run("hookParallel", hookName, parameters, plugin);
await this.run({
strategy: "hookParallel",
hookName,
parameters,
plugin
});
} else {
const promise = this.run("hookParallel", hookName, parameters, plugin);
const promise = this.run({ strategy: "hookParallel", hookName, parameters, plugin });
parallelPromises.push(promise);

@@ -550,9 +640,17 @@ }

// chains, reduces returned value, handling the reduced value as the first hook argument
hookReduceArg0(hookName, [argument0, ...rest], reduce) {
hookReduceArg0({
hookName,
parameters,
reduce
}) {
const [argument0, ...rest] = parameters;
let promise = Promise.resolve(argument0);
for (const plugin of this.getSortedPlugins(hookName)) {
promise = promise.then(
(argument02) => this.run("hookReduceArg0", hookName, [argument02, ...rest], plugin).then(
(result) => reduce.call(this.core.api, argument02, result, plugin)
)
(argument02) => this.run({
strategy: "hookReduceArg0",
hookName,
parameters: [argument02, ...rest],
plugin
}).then((result) => reduce.call(this.core.api, argument02, result, plugin))
);

@@ -563,22 +661,30 @@ }

// chains
hookSeq(hookName, parameters) {
hookSeq({ hookName, parameters }) {
let promise = Promise.resolve();
for (const plugin of this.getSortedPlugins(hookName)) {
promise = promise.then(() => this.run("hookSeq", hookName, parameters, plugin));
promise = promise.then(
() => this.run({
strategy: "hookSeq",
hookName,
parameters,
plugin
})
);
}
return promise.then(noReturn);
}
getSortedPlugins(hookName, pluginName) {
getSortedPlugins(_hookName) {
const plugins = [...this.plugins];
if (pluginName) {
const pluginsByPluginName = plugins.filter((item) => item.name === pluginName && item[hookName]);
if (pluginsByPluginName.length === 0) {
if (this.config.logLevel === "warn" && this.logger?.spinner) {
this.logger.spinner.info(`Plugin hook with ${hookName} not found for plugin ${pluginName}`);
}
return [this.core];
return plugins;
}
getPlugin(hookName, pluginName) {
const plugins = [...this.plugins];
const pluginByPluginName = plugins.find((item) => item.name === pluginName && item[hookName]);
if (!pluginByPluginName) {
if (this.config.logLevel === "warn" && this.logger?.spinner) {
this.logger.spinner.info(`Plugin hook with ${hookName} not found for plugin ${pluginName}`);
}
return pluginsByPluginName;
return this.core;
}
return plugins;
return pluginByPluginName;
}

@@ -592,3 +698,8 @@ /**

// Implementation signature
run(strategy, hookName, parameters, plugin) {
run({
strategy,
hookName,
parameters,
plugin
}) {
const hook = plugin[hookName];

@@ -629,8 +740,17 @@ return Promise.resolve().then(() => {

*/
runSync(hookName, parameters, plugin) {
runSync({
strategy,
hookName,
parameters,
plugin
}) {
const hook = plugin[hookName];
try {
if (typeof hook !== "function") {
return hook;
}
return hook.apply(this.core.api, parameters);
} catch (error) {
return error;
} catch (e) {
this.catcher(e, plugin, hookName);
return null;
}

@@ -681,3 +801,6 @@ }

let code = getFileSource(file);
const loadedResult = await pluginManager.hookFirst("load", [path]);
const loadedResult = await pluginManager.hookFirst({
hookName: "load",
parameters: [path]
});
if (loadedResult) {

@@ -687,5 +810,12 @@ code = loadedResult;

if (code) {
const transformedCode = await pluginManager.hookReduceArg0("transform", [code, path], transformReducer);
const transformedCode = await pluginManager.hookReduceArg0({
hookName: "transform",
parameters: [code, path],
reduce: transformReducer
});
if (config.output.write || config.output.write === void 0) {
await pluginManager.hookParallel("writeFile", [transformedCode, path]);
await pluginManager.hookParallel({
hookName: "writeFile",
parameters: [transformedCode, path]
});
}

@@ -696,5 +826,11 @@ }

const { plugins, fileManager } = pluginManager;
await pluginManager.hookParallel("validate", [plugins]);
await pluginManager.hookParallel("buildStart", [config]);
await pluginManager.hookParallel("buildEnd");
await pluginManager.hookParallel({
hookName: "validate",
parameters: [plugins]
});
await pluginManager.hookParallel({
hookName: "buildStart",
parameters: [config]
});
await pluginManager.hookParallel({ hookName: "buildEnd" });
setTimeout(() => {

@@ -701,0 +837,0 @@ done({ files: fileManager.files.map((file) => ({ ...file, source: getFileSource(file) })) });

{
"name": "@kubb/core",
"version": "1.0.0-beta.4",
"version": "1.0.0-beta.5",
"description": "Generator core",

@@ -5,0 +5,0 @@ "repository": {

@@ -7,5 +7,6 @@ /* eslint-disable no-async-promise-executor */

import { clean, read } from './utils'
import { getFileSource } from './managers/fileManager'
import type { FileManager, File } from './managers/fileManager'
import type { QueueTask } from './utils'
import { FileManager, File, getFileSource } from './managers/fileManager'
import type { PluginContext, TransformResult, LogLevel, KubbPlugin } from './types'

@@ -61,3 +62,6 @@

const loadedResult = await pluginManager.hookFirst('load', [path])
const loadedResult = await pluginManager.hookFirst({
hookName: 'load',
parameters: [path],
})
if (loadedResult) {

@@ -68,6 +72,13 @@ code = loadedResult

if (code) {
const transformedCode = await pluginManager.hookReduceArg0('transform', [code, path], transformReducer)
const transformedCode = await pluginManager.hookReduceArg0({
hookName: 'transform',
parameters: [code, path],
reduce: transformReducer,
})
if (config.output.write || config.output.write === undefined) {
await pluginManager.hookParallel('writeFile', [transformedCode, path])
await pluginManager.hookParallel({
hookName: 'writeFile',
parameters: [transformedCode, path],
})
}

@@ -80,7 +91,13 @@ }

await pluginManager.hookParallel<'validate', true>('validate', [plugins])
await pluginManager.hookParallel<'validate', true>({
hookName: 'validate',
parameters: [plugins],
})
await pluginManager.hookParallel('buildStart', [config])
await pluginManager.hookParallel({
hookName: 'buildStart',
parameters: [config],
})
await pluginManager.hookParallel('buildEnd')
await pluginManager.hookParallel({ hookName: 'buildEnd' })
setTimeout(() => {

@@ -87,0 +104,0 @@ done({ files: fileManager.files.map((file) => ({ ...file, source: getFileSource(file) })) })

@@ -10,3 +10,3 @@ /* eslint-disable no-await-in-loop */

import type { Argument0, Strategy } from './types'
import type { KubbConfig, KubbPlugin, PluginLifecycleHooks, PluginLifecycle, MaybePromise, ResolveIdParams } from '../../types'
import type { KubbConfig, KubbPlugin, PluginLifecycleHooks, PluginLifecycle, MaybePromise, ResolvePathParams, ResolveNameParams } from '../../types'
import type { Logger } from '../../build'

@@ -23,3 +23,4 @@ import type { CorePluginOptions } from '../../plugin'

buildStart: 1,
resolveId: 1,
resolvePath: 1,
resolveName: 1,
load: 1,

@@ -55,3 +56,4 @@ transform: 1,

load: this.load,
resolveId: this.resolveId,
resolvePath: this.resolvePath,
resolveName: this.resolveName,
}) as KubbPlugin<CorePluginOptions> & {

@@ -63,26 +65,103 @@ api: CorePluginOptions['api']

resolveId = (params: ResolveIdParams) => {
resolvePath = (params: ResolvePathParams) => {
if (params.pluginName) {
return this.hookForPlugin(params.pluginName, 'resolveId', [params.fileName, params.directory, params.options])
return this.hookForPluginSync({
pluginName: params.pluginName,
hookName: 'resolvePath',
parameters: [params.fileName, params.directory, params.options],
})
}
return this.hookFirst('resolveId', [params.fileName, params.directory, params.options])
return this.hookFirstSync({
hookName: 'resolvePath',
parameters: [params.fileName, params.directory, params.options],
})
}
resolveName = (params: ResolveNameParams) => {
if (params.pluginName) {
return this.hookForPluginSync({
pluginName: params.pluginName,
hookName: 'resolveName',
parameters: [params.name],
})
}
return this.hookFirstSync({
hookName: 'resolveName',
parameters: [params.name],
})
}
load = async (id: string) => {
return this.hookFirst('load', [id])
return this.hookFirst({
hookName: 'load',
parameters: [id],
})
}
// run only hook for a specific plugin name
hookForPlugin<H extends PluginLifecycleHooks>(
pluginName: string,
hookName: H,
parameters: Parameters<PluginLifecycle[H]>,
/**
*
* Run only hook for a specific plugin name
*/
hookForPlugin<H extends PluginLifecycleHooks>({
pluginName,
hookName,
parameters,
}: {
pluginName: string
hookName: H
parameters: Parameters<PluginLifecycle[H]>
}): Promise<ReturnType<PluginLifecycle[H]> | null> {
const plugin = this.getPlugin(hookName, pluginName)
return this.run({
strategy: 'hookFirst',
hookName,
parameters,
plugin,
})
}
hookForPluginSync<H extends PluginLifecycleHooks>({
pluginName,
hookName,
parameters,
}: {
pluginName: string
hookName: H
parameters: Parameters<PluginLifecycle[H]>
}): ReturnType<PluginLifecycle[H]> | null {
const plugin = this.getPlugin(hookName, pluginName)
return this.runSync({
strategy: 'hookFirst',
hookName,
parameters,
plugin,
})
}
/**
*
* Chains, first non-null result stops and returns
*/
hookFirst<H extends PluginLifecycleHooks>({
hookName,
parameters,
skipped,
}: {
hookName: H
parameters: Parameters<PluginLifecycle[H]>
skipped?: ReadonlySet<KubbPlugin> | null
): Promise<ReturnType<PluginLifecycle[H]> | null> {
}): Promise<ReturnType<PluginLifecycle[H]> | null> {
let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)
for (const plugin of this.getSortedPlugins(hookName, pluginName)) {
for (const plugin of this.getSortedPlugins(hookName)) {
if (skipped && skipped.has(plugin)) continue
promise = promise.then((result) => {
if (result != null) return result
return this.run('hookFirst', hookName, parameters, plugin) as typeof result
return this.run({
strategy: 'hookFirst',
hookName,
parameters,
plugin,
}) as typeof result
})

@@ -93,21 +172,42 @@ }

// chains, first non-null result stops and returns
hookFirst<H extends PluginLifecycleHooks>(
hookName: H,
parameters: Parameters<PluginLifecycle[H]>,
/**
*
* Chains, first non-null result stops and returns
*/
hookFirstSync<H extends PluginLifecycleHooks>({
hookName,
parameters,
skipped,
}: {
hookName: H
parameters: Parameters<PluginLifecycle[H]>
skipped?: ReadonlySet<KubbPlugin> | null
): Promise<ReturnType<PluginLifecycle[H]> | null> {
let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)
}): ReturnType<PluginLifecycle[H]> | null {
let result = null
for (const plugin of this.getSortedPlugins(hookName)) {
if (skipped && skipped.has(plugin)) continue
promise = promise.then((result) => {
if (result != null) return result
return this.run('hookFirst', hookName, parameters, plugin) as typeof result
result = this.runSync({
strategy: 'hookFirst',
hookName,
parameters,
plugin,
})
if (result != null) {
break
}
}
return promise
return result
}
// parallel
async hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined) {
async hookParallel<H extends PluginLifecycleHooks, TOuput = void>({
hookName,
parameters,
}: {
hookName: H
parameters?: Parameters<PluginLifecycle[H]> | undefined
}) {
const parallelPromises: Promise<TOuput>[] = []

@@ -119,5 +219,10 @@

parallelPromises.length = 0
await this.run('hookParallel', hookName, parameters, plugin)
await this.run({
strategy: 'hookParallel',
hookName,
parameters,
plugin,
})
} else {
const promise: Promise<TOuput> = this.run('hookParallel', hookName, parameters, plugin)
const promise: Promise<TOuput> = this.run({ strategy: 'hookParallel', hookName, parameters, plugin })

@@ -131,13 +236,22 @@ parallelPromises.push(promise)

// chains, reduces returned value, handling the reduced value as the first hook argument
hookReduceArg0<H extends PluginLifecycleHooks>(
hookName: H,
[argument0, ...rest]: Parameters<PluginLifecycle[H]>,
hookReduceArg0<H extends PluginLifecycleHooks>({
hookName,
parameters,
reduce,
}: {
hookName: H
parameters: Parameters<PluginLifecycle[H]>
reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: KubbPlugin) => MaybePromise<Argument0<H> | null>
): Promise<Argument0<H>> {
}): Promise<Argument0<H>> {
const [argument0, ...rest] = parameters
let promise: Promise<Argument0<H>> = Promise.resolve(argument0)
for (const plugin of this.getSortedPlugins(hookName)) {
promise = promise.then((argument0) =>
this.run('hookReduceArg0', hookName, [argument0, ...rest] as Parameters<PluginLifecycle[H]>, plugin).then((result) =>
reduce.call(this.core.api, argument0, result as ReturnType<PluginLifecycle[H]>, plugin)
)
this.run({
strategy: 'hookReduceArg0',
hookName,
parameters: [argument0, ...rest] as Parameters<PluginLifecycle[H]>,
plugin,
}).then((result) => reduce.call(this.core.api, argument0, result as ReturnType<PluginLifecycle[H]>, plugin))
) as Promise<Argument0<H>>

@@ -150,6 +264,13 @@ }

hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>) {
hookSeq<H extends PluginLifecycleHooks>({ hookName, parameters }: { hookName: H; parameters?: Parameters<PluginLifecycle[H]> }) {
let promise: Promise<void> = Promise.resolve()
for (const plugin of this.getSortedPlugins(hookName)) {
promise = promise.then(() => this.run('hookSeq', hookName, parameters, plugin))
promise = promise.then(() =>
this.run({
strategy: 'hookSeq',
hookName,
parameters,
plugin,
})
)
}

@@ -159,18 +280,20 @@ return promise.then(noReturn)

private getSortedPlugins(hookName: keyof PluginLifecycle, pluginName?: string): KubbPlugin[] {
private getSortedPlugins(_hookName: keyof PluginLifecycle): KubbPlugin[] {
const plugins = [...this.plugins]
if (pluginName) {
const pluginsByPluginName = plugins.filter((item) => item.name === pluginName && item[hookName])
if (pluginsByPluginName.length === 0) {
// fallback on the core plugin when there is no match
if (this.config.logLevel === 'warn' && this.logger?.spinner) {
this.logger.spinner.info(`Plugin hook with ${hookName} not found for plugin ${pluginName}`)
}
return [this.core]
return plugins
}
private getPlugin(hookName: keyof PluginLifecycle, pluginName: string): KubbPlugin {
const plugins = [...this.plugins]
const pluginByPluginName = plugins.find((item) => item.name === pluginName && item[hookName])
if (!pluginByPluginName) {
// fallback on the core plugin when there is no match
if (this.config.logLevel === 'warn' && this.logger?.spinner) {
this.logger.spinner.info(`Plugin hook with ${hookName} not found for plugin ${pluginName}`)
}
return pluginsByPluginName
return this.core
}
return plugins
return pluginByPluginName
}

@@ -185,8 +308,13 @@

// Implementation signature
private run<H extends PluginLifecycleHooks, TResult = void>(
strategy: Strategy,
hookName: H,
parameters: unknown[] | undefined,
private run<H extends PluginLifecycleHooks, TResult = void>({
strategy,
hookName,
parameters,
plugin,
}: {
strategy: Strategy
hookName: H
parameters: unknown[] | undefined
plugin: KubbPlugin
): Promise<TResult> {
}): Promise<TResult> {
const hook = plugin[hookName]!

@@ -234,7 +362,13 @@

*/
private runSync<H extends PluginLifecycleHooks>(
hookName: H,
parameters: Parameters<PluginLifecycle[H]>,
private runSync<H extends PluginLifecycleHooks>({
strategy,
hookName,
parameters,
plugin,
}: {
strategy: Strategy
hookName: H
parameters: Parameters<PluginLifecycle[H]>
plugin: KubbPlugin
): ReturnType<PluginLifecycle[H]> | Error {
}): ReturnType<PluginLifecycle[H]> {
const hook = plugin[hookName]!

@@ -246,5 +380,10 @@

// eslint-disable-next-line @typescript-eslint/ban-types
if (typeof hook !== 'function') {
return hook
}
return (hook as Function).apply(this.core.api, parameters)
} catch (error) {
return error as Error
} catch (e) {
this.catcher<H>(e as Error, plugin, hookName)
return null as ReturnType<PluginLifecycle[H]>
}

@@ -251,0 +390,0 @@ }

@@ -33,3 +33,4 @@ import pathParser from 'path'

fileManager: FileManager
resolveId: PluginContext['resolveId']
resolvePath: PluginContext['resolvePath']
resolveName: PluginContext['resolveName']
load: PluginContext['load']

@@ -44,3 +45,3 @@ }

export const definePlugin = createPlugin<CorePluginOptions>((options) => {
const { fileManager, resolveId, load } = options
const { fileManager, resolvePath, resolveName, load } = options

@@ -55,3 +56,4 @@ const api: PluginContext = {

},
resolveId,
resolvePath,
resolveName,
load,

@@ -65,3 +67,3 @@ cache: createPluginCache(Object.create(null)),

api,
resolveId(fileName, directory) {
resolvePath(fileName, directory) {
if (!directory) {

@@ -72,3 +74,6 @@ return null

},
resolveName(name) {
return name
},
}
})

@@ -111,5 +111,5 @@ import type { FileManager, File } from './managers/fileManager'

// use of type objects
export type PluginFactoryOptions<Options = unknown, Nested extends boolean = false, Api = any, ResolveIdOptions = Record<string, any>> = {
export type PluginFactoryOptions<Options = unknown, Nested extends boolean = false, Api = any, resolvePathOptions = Record<string, any>> = {
options: Options
resolveIdOptions: ResolveIdOptions
resolvePathOptions: resolvePathOptions
nested: Nested

@@ -131,11 +131,19 @@ api: Api

/**
* Resolve to an id based on importee(example: `./Pet.ts`) and directory(example: `./models`).
* Resolve to a Path based on a fileName(example: `./Pet.ts`) and directory(example: `./models`).
* Options can als be included.
* @type hookFirst
* @example ('./Pet.ts', './src/gen/')
* @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'
*/
resolveId: (this: Omit<PluginContext, 'addFile'>, fileName: string, directory?: string, options?: TOptions['resolveIdOptions']) => OptionalPath
resolvePath: (this: Omit<PluginContext, 'addFile'>, fileName: string, directory?: string, options?: TOptions['resolvePathOptions']) => OptionalPath
/**
* Makes it possible to run async logic to override the path defined previously by `resolveId`.
* Resolve to a name based on a string.
* Useful when converting to PascalCase or camelCase.
* @type hookFirst
* @example ('pet') => 'Pet'
*/
resolveName: (this: Omit<PluginContext, 'addFile'>, name: string) => string | null
/**
* Makes it possible to run async logic to override the path defined previously by `resolvePath`.
* @type hookFirst
*/
load: (this: Omit<PluginContext, 'addFile'>, path: Path) => MaybePromise<TransformResult | null>

@@ -148,3 +156,3 @@ /**

/**
* Write the result to the file-system based on the id(defined by `resolveId` or changed by `load`).
* Write the result to the file-system based on the id(defined by `resolvePath` or changed by `load`).
* @type hookParallel

@@ -162,12 +170,12 @@ */

export type ResolveIdParams<TOptions = Record<string, any>> = {
fileName: string
directory?: string | undefined
export type ResolvePathParams<TOptions = Record<string, any>> = {
/**
* When set, resolveId will only call resolveId of the name of the plugin set here.
* If not defined it will fall back on the resolveId of the core plugin.
* When set, resolvePath will only call resolvePath of the name of the plugin set here.
* If not defined it will fall back on the resolvePath of the core plugin.
*/
pluginName?: string
fileName: string
directory?: string | undefined
/**
* Options to be passed to 'resolveId' 3th parameter
* Options to be passed to 'resolvePath' 3th parameter
*/

@@ -177,2 +185,11 @@ options?: TOptions

export type ResolveNameParams = {
/**
* When set, resolvePath will only call resolvePath of the name of the plugin set here.
* If not defined it will fall back on the resolvePath of the core plugin.
*/
pluginName?: string
name: string
}
export type PluginContext<TOptions = Record<string, any>> = {

@@ -183,3 +200,4 @@ config: KubbConfig

addFile: (file: File) => Promise<File>
resolveId: (params: ResolveIdParams<TOptions>) => MaybePromise<OptionalPath>
resolvePath: (params: ResolvePathParams<TOptions>) => OptionalPath
resolveName: (params: ResolveNameParams) => string | null
load: (id: string) => MaybePromise<TransformResult | void>

@@ -186,0 +204,0 @@ }

@@ -1,6 +0,6 @@

export function createJSDocBlockText({ comments }: { comments: Array<string | undefined> }) {
export function createJSDocBlockText({ comments }: { comments: Array<string> }): string {
const filteredComments = comments.filter(Boolean)
if (!filteredComments.length) {
return undefined
return ''
}

@@ -7,0 +7,0 @@

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