···38383939Alternatively, you can use `openapi-ts.config.js` and configure the export statement depending on your project setup.
40404141+### Async config and factories
4242+4343+You can also export a function (sync or async) if you need to compute configuration dynamically (e.g., read env vars):
4444+4545+```js
4646+import { defineConfig } from '@hey-api/openapi-ts';
4747+4848+export default defineConfig(async () => {
4949+ return {
5050+ input: 'hey-api/backend',
5151+ output: 'src/client',
5252+ };
5353+});
5454+```
5555+5656+### Multiple configurations
5757+5858+You can also export an array to run multiple configurations in a single invocation (e.g., generate multiple clients):
5959+6060+```js
6161+import { defineConfig } from '@hey-api/openapi-ts';
6262+6363+export default defineConfig([
6464+ {
6565+ input: 'path/to/openapi_one.json',
6666+ output: 'src/client_one',
6767+ },
6868+ {
6969+ input: 'path/to/openapi_two.json',
7070+ output: 'src/client_two',
7171+ },
7272+]);
7373+```
7474+4175<!--
4276TODO: uncomment after c12 supports multiple configs
4377see https://github.com/unjs/c12/issues/92
+15-1
docs/openapi-ts/configuration/input.md
···991010## Input
11111212-The input can be a string path, URL, [API registry](#api-registry), an object containing any of these, or an object representing an OpenAPI specification. Hey API supports all valid OpenAPI versions and file formats.
1212+The input can be a string path, URL, [API registry](#api-registry), an object containing any of these, or an object representing an OpenAPI specification. You can also pass an array of inputs to merge multiple specifications. Hey API supports all valid OpenAPI versions and file formats.
13131414::: code-group
1515···5151};
5252```
5353<!-- prettier-ignore-end -->
5454+5555+```js [array]
5656+export default {
5757+ input: [
5858+ // [!code ++]
5959+ 'hey-api/backend', // [!code ++]
6060+ './overrides/openapi.yaml', // [!code ++]
6161+ ], // [!code ++]
6262+};
6363+// When you pass multiple inputs as an array, `@hey-api/openapi-ts` bundles them into a single resolved OpenAPI
6464+// document. To avoid name collisions between files, component names may be prefixed with the input file’s base
6565+// name when needed (for example, `users.yaml` ➜ `users.*`). References across files are resolved, and
6666+// later inputs in the array can override earlier ones on conflict.
6767+```
54685569:::
5670
···1919import { Logger } from './utils/logger';
20202121type ConfigValue = UserConfig | ReadonlyArray<UserConfig>;
2222-type Configs = ConfigValue | (() => ConfigValue) | (() => Promise<ConfigValue>);
2222+// Generic input shape for config that may be a value or a (possibly async) factory
2323+type ConfigInput<T extends ConfigValue> = T | (() => T) | (() => Promise<T>);
23242425colors.enabled = colorSupport().hasBasic;
2526···2930 * @param userConfig User provided {@link UserConfig} configuration.
3031 */
3132export const createClient = async (
3232- userConfig?: Configs,
3333+ userConfig?: ConfigInput<ConfigValue>,
3334 logger = new Logger(),
3435): Promise<ReadonlyArray<Client | IR.Context>> => {
3536 const resolvedConfig =
···105106};
106107107108/**
108108- * Type helper for openapi-ts.config.ts, returns {@link UserConfig} object
109109+ * Type helper for openapi-ts.config.ts, preserves input shape (object vs array)
109110 */
110110-export const defineConfig = async (config: Configs): Promise<ConfigValue> =>
111111- typeof config === 'function' ? await config() : config;
111111+export const defineConfig = async <T extends ConfigValue>(
112112+ config: ConfigInput<T>,
113113+): Promise<T> =>
114114+ typeof config === 'function'
115115+ ? await (config as () => T | Promise<T>)()
116116+ : (config as T);
112117113118export { defaultPaginationKeywords } from './config/parser';
114119export { defaultPlugins } from './config/plugins';
+2-2
packages/openapi-ts/src/types/config.d.ts
···2828 *
2929 * Alternatively, you can define a configuration object with more options.
3030 */
3131- input: InputPath | Input | (InputPath | Input)[];
3131+ input: InputPath | Input | ReadonlyArray<InputPath | Input>;
3232 /**
3333 * Show an interactive error reporting tool when the program crashes? You
3434 * generally want to keep this disabled (default).
···4747 * outputs to generate different versions of your SDK with different
4848 * configurations (e.g., different plugins, formatters, or paths).
4949 */
5050- output: string | Output | (string | Output)[];
5050+ output: string | Output | ReadonlyArray<string | Output>;
5151 /**
5252 * Customize how the input is parsed and transformed before it's passed to
5353 * plugins.