···3636 // TODO: parser - move to config.input
3737 if (client) {
3838 if (
3939- config.plugins['@hey-api/sdk']?.include &&
4040- config.plugins['@hey-api/sdk'].asClass
3939+ config.plugins['@hey-api/sdk']?.config.include &&
4040+ config.plugins['@hey-api/sdk'].config.asClass
4141 ) {
4242- const regexp = new RegExp(config.plugins['@hey-api/sdk'].include);
4242+ const regexp = new RegExp(config.plugins['@hey-api/sdk'].config.include);
4343 client.services = client.services.filter((service) =>
4444 regexp.test(service.name),
4545 );
4646 }
47474848- if (config.plugins['@hey-api/typescript']?.include) {
4949- const regexp = new RegExp(config.plugins['@hey-api/typescript'].include);
4848+ if (config.plugins['@hey-api/typescript']?.config.include) {
4949+ const regexp = new RegExp(
5050+ config.plugins['@hey-api/typescript'].config.include,
5151+ );
5052 client.models = client.models.filter((model) => regexp.test(model.name));
5153 }
5254 }
···6264 const clientPlugin = getClientPlugin(config);
6365 if (
6466 !isLegacyClient(config) &&
6565- 'bundle' in clientPlugin &&
6666- clientPlugin.bundle
6767+ 'bundle' in clientPlugin.config &&
6868+ clientPlugin.config.bundle
6769 ) {
6870 generateClientBundle({
6971 outputPath,
+1-1
packages/openapi-ts/src/generate/output.ts
···2525 tsConfig?.options.moduleResolution === ts.ModuleResolutionKind.NodeNext;
26262727 const client = getClientPlugin(context.config);
2828- if ('bundle' in client && client.bundle) {
2828+ if ('bundle' in client.config && client.config.bundle) {
2929 generateClientBundle({
3030 outputPath,
3131 plugin: client,
+5-1
packages/openapi-ts/src/index.ts
···109109export { defaultPaginationKeywords } from './ir/pagination';
110110export type { IR } from './ir/types';
111111export type { OpenApi, OpenApiSchemaObject } from './openApi/types';
112112-export { clientDefaultConfig } from './plugins/@hey-api/client-core/config';
112112+export {
113113+ clientDefaultConfig,
114114+ clientDefaultMeta,
115115+} from './plugins/@hey-api/client-core/config';
113116export { clientPluginHandler } from './plugins/@hey-api/client-core/plugin';
114117export type { Client } from './plugins/@hey-api/client-core/types';
118118+export { definePluginConfig } from './plugins/shared/utils/config';
115119export type { Plugin } from './plugins/types';
116120export type { UserConfig } from './types/config';
117121export type { LegacyIR } from './types/types';
+86-87
packages/openapi-ts/src/initConfigs.ts
···33import { loadConfig } from 'c12';
4455import { getLogs } from './getLogs';
66-import type { ClientPlugins, UserPlugins } from './plugins';
66+import type { UserPlugins } from './plugins';
77import { defaultPluginConfigs } from './plugins';
88import type {
99 AnyPluginName,
1010- DefaultPluginConfigs,
1110 PluginContext,
1211 PluginNames,
1312} from './plugins/types';
···8079};
81808281const getPluginsConfig = ({
8383- pluginConfigs,
8482 userPlugins,
8583 userPluginsConfig,
8684}: {
8787- pluginConfigs: DefaultPluginConfigs<ClientPlugins>;
8885 userPlugins: ReadonlyArray<AnyPluginName>;
8986 userPluginsConfig: Config['plugins'];
9087}): Pick<Config, 'plugins' | 'pluginOrder'> => {
···9794 throw new Error(`Circular reference detected at '${name}'`);
9895 }
9996100100- if (!pluginOrder.has(name)) {
101101- circularReferenceTracker.add(name);
9797+ if (pluginOrder.has(name)) {
9898+ return;
9999+ }
102100103103- const pluginConfig = pluginConfigs[name as PluginNames];
104104- if (!pluginConfig) {
105105- throw new Error(
106106- `unknown plugin dependency "${name}" - do you need to register a custom plugin with this name?`,
107107- );
108108- }
101101+ circularReferenceTracker.add(name);
109102110110- const defaultOptions = defaultPluginConfigs[name as PluginNames];
111111- const userOptions = userPluginsConfig[name as PluginNames];
112112- if (userOptions && defaultOptions) {
113113- const nativePluginOption = Object.keys(userOptions).find((key) =>
114114- key.startsWith('_'),
115115- );
116116- if (nativePluginOption) {
117117- throw new Error(
118118- `cannot register plugin "${name}" - attempting to override a native plugin option "${nativePluginOption}"`,
119119- );
120120- }
121121- }
103103+ const defaultPlugin = defaultPluginConfigs[name as PluginNames];
104104+ const userPlugin = userPluginsConfig[name as PluginNames];
122105123123- const config = {
124124- _dependencies: [],
125125- ...defaultOptions,
126126- ...userOptions,
127127- };
106106+ if (!defaultPlugin && !userPlugin) {
107107+ throw new Error(
108108+ `unknown plugin dependency "${name}" - do you need to register a custom plugin with this name?`,
109109+ );
110110+ }
128111129129- if (config._infer) {
130130- const context: PluginContext = {
131131- ensureDependency: (dependency) => {
112112+ const plugin = {
113113+ _dependencies: [],
114114+ ...defaultPlugin,
115115+ ...userPlugin,
116116+ config: {
117117+ ...defaultPlugin?.config,
118118+ ...userPlugin?.config,
119119+ },
120120+ };
121121+122122+ if (plugin._infer) {
123123+ const context: PluginContext = {
124124+ ensureDependency: (dependency) => {
125125+ if (
126126+ typeof dependency === 'string' &&
127127+ !plugin._dependencies.includes(dependency)
128128+ ) {
129129+ plugin._dependencies = [...plugin._dependencies, dependency];
130130+ }
131131+ },
132132+ pluginByTag: ({ defaultPlugin, errorMessage, tag }) => {
133133+ for (const userPlugin of userPlugins) {
134134+ const defaultConfig =
135135+ defaultPluginConfigs[userPlugin as PluginNames] ||
136136+ userPluginsConfig[userPlugin as PluginNames];
132137 if (
133133- typeof dependency === 'string' &&
134134- !config._dependencies.includes(dependency)
138138+ defaultConfig &&
139139+ defaultConfig._tags?.includes(tag) &&
140140+ userPlugin !== name
135141 ) {
136136- config._dependencies = [...config._dependencies, dependency];
142142+ return userPlugin;
137143 }
138138- },
139139- pluginByTag: ({ defaultPlugin, errorMessage, tag }) => {
140140- for (const userPlugin of userPlugins) {
141141- const defaultConfig =
142142- defaultPluginConfigs[userPlugin as PluginNames] ||
143143- pluginConfigs[userPlugin as PluginNames];
144144- if (
145145- defaultConfig &&
146146- defaultConfig._tags?.includes(tag) &&
147147- userPlugin !== name
148148- ) {
149149- return userPlugin;
150150- }
151151- }
144144+ }
152145153153- if (defaultPlugin) {
154154- const defaultConfig =
155155- defaultPluginConfigs[defaultPlugin as PluginNames] ||
156156- pluginConfigs[defaultPlugin as PluginNames];
157157- if (
158158- defaultConfig &&
159159- defaultConfig._tags?.includes(tag) &&
160160- defaultPlugin !== name
161161- ) {
162162- return defaultPlugin;
163163- }
146146+ if (defaultPlugin) {
147147+ const defaultConfig =
148148+ defaultPluginConfigs[defaultPlugin as PluginNames] ||
149149+ userPluginsConfig[defaultPlugin as PluginNames];
150150+ if (
151151+ defaultConfig &&
152152+ defaultConfig._tags?.includes(tag) &&
153153+ defaultPlugin !== name
154154+ ) {
155155+ return defaultPlugin;
164156 }
157157+ }
165158166166- throw new Error(
167167- errorMessage ||
168168- `missing plugin - no plugin with tag "${tag}" found`,
169169- );
170170- },
171171- };
172172- config._infer(config, context);
173173- }
159159+ throw new Error(
160160+ errorMessage ||
161161+ `missing plugin - no plugin with tag "${tag}" found`,
162162+ );
163163+ },
164164+ };
165165+ // @ts-expect-error
166166+ plugin._infer(plugin, context);
167167+ }
174168175175- for (const dependency of config._dependencies) {
176176- dfs(dependency);
177177- }
169169+ for (const dependency of plugin._dependencies) {
170170+ dfs(dependency);
171171+ }
178172179179- circularReferenceTracker.delete(name);
180180- pluginOrder.add(name);
173173+ circularReferenceTracker.delete(name);
174174+ pluginOrder.add(name);
181175182182- // @ts-expect-error
183183- plugins[name] = config;
184184- }
176176+ // @ts-expect-error
177177+ plugins[name] = plugin;
185178 };
186179187180 for (const name of userPlugins) {
···233226 const userPluginsConfig: Config['plugins'] = {};
234227235228 let definedPlugins: UserConfig['plugins'] = defaultPlugins;
229229+236230 if (userConfig.plugins) {
237231 userConfig.plugins = userConfig.plugins.filter(
238232 (plugin) =>
···255249 return plugin;
256250 }
257251258258- if (plugin.name) {
252252+ const pluginName = plugin.name;
253253+254254+ if (pluginName) {
259255 // @ts-expect-error
260260- userPluginsConfig[plugin.name] = plugin;
256256+ if (plugin._handler) {
257257+ // @ts-expect-error
258258+ userPluginsConfig[pluginName] = plugin;
259259+ } else {
260260+ // @ts-expect-error
261261+ userPluginsConfig[pluginName] = {
262262+ config: { ...plugin },
263263+ };
264264+ // @ts-expect-error
265265+ delete userPluginsConfig[pluginName]!.config.name;
266266+ }
261267 }
262268263263- return plugin.name;
269269+ return pluginName;
264270 })
265271 .filter(Boolean);
266272267267- return getPluginsConfig({
268268- pluginConfigs: {
269269- ...userPluginsConfig,
270270- ...defaultPluginConfigs,
271271- },
272272- userPlugins,
273273- userPluginsConfig,
274274- });
273273+ return getPluginsConfig({ userPlugins, userPluginsConfig });
275274};
276275277276const getWatch = (
···11+import type { BaseConfig, Plugin } from '../../types';
22+33+export const definePluginConfig =
44+ <Config extends BaseConfig>(defaultConfig: Plugin.Config<Config>) =>
55+ (
66+ userConfig?: Omit<Plugin.UserConfig<Config>, 'name'>,
77+ ): Omit<Plugin.Config<Config>, 'name'> & {
88+ /**
99+ * Cast name to `any` so it doesn't throw type error in `plugins` array.
1010+ * We could allow any `string` as plugin `name` in the object syntax, but
1111+ * that TypeScript trick would cause all string methods to appear as
1212+ * suggested auto completions, which is undesirable.
1313+ */
1414+ name: any;
1515+ } => ({
1616+ ...defaultConfig,
1717+ config: {
1818+ ...defaultConfig.config,
1919+ ...userConfig,
2020+ },
2121+ });