fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: streamline output path handling and enhance multi-output configuration support

+70 -192
+1 -10
packages/nuxt/src/module.ts
··· 60 60 config.watch = false; 61 61 } 62 62 63 - const outputPath = 64 - config.output instanceof Array 65 - ? typeof config.output[0] === 'string' 66 - ? config.output[0] 67 - : config.output[0]?.path 68 - : typeof config.output === 'string' 69 - ? config.output 70 - : config.output.path; 71 - 72 63 const folder = path.resolve( 73 64 nuxt.options.rootDir, 74 - outputPath || path.join(nuxt.options.buildDir, 'client'), 65 + typeof config.output === 'string' ? config.output : config.output.path, 75 66 ); 76 67 77 68 nuxt.options.alias[options.alias!] = folder;
+4 -24
packages/openapi-ts-tests/main/test/2.0.x.test.ts
··· 40 40 }, 41 41 output: path.join( 42 42 outputDir, 43 - typeof userConfig.output === 'string' 44 - ? userConfig.output 45 - : Array.isArray(userConfig.output) 46 - ? typeof userConfig.output[0] === 'string' 47 - ? userConfig.output[0] 48 - : (userConfig.output[0] as any).path || '' 49 - : (userConfig.output as any).path || '', 43 + typeof userConfig.output === 'string' ? userConfig.output : '', 50 44 ), 51 45 }; 52 46 }; ··· 400 394 await createClient(config); 401 395 402 396 const outputPath = 403 - typeof config.output === 'string' 404 - ? config.output 405 - : config.output instanceof Array 406 - ? typeof config.output[0] === 'string' 407 - ? config.output[0] 408 - : config.output[0]?.path || '' 409 - : config.output.path; 397 + typeof config.output === 'string' ? config.output : config.output.path; 410 398 const filePaths = getFilePaths(outputPath); 411 399 412 400 await Promise.all( ··· 440 428 const outputPathA = 441 429 typeof configA.output === 'string' 442 430 ? configA.output 443 - : Array.isArray(configA.output) 444 - ? typeof configA.output[0] === 'string' 445 - ? configA.output[0] 446 - : (configA.output[0] as any).path 447 - : (configA.output as any).path; 431 + : configA.output.path; 448 432 const outputPathB = 449 433 typeof configB.output === 'string' 450 434 ? configB.output 451 - : Array.isArray(configB.output) 452 - ? typeof configB.output[0] === 'string' 453 - ? configB.output[0] 454 - : (configB.output[0] as any).path 455 - : (configB.output as any).path; 435 + : configB.output.path; 456 436 457 437 const filesA = getFilePaths(outputPathA); 458 438 const filesB = getFilePaths(outputPathB);
+4 -22
packages/openapi-ts-tests/main/test/3.0.x.test.ts
··· 42 42 outputDir, 43 43 typeof userConfig.output === 'string' 44 44 ? userConfig.output 45 - : Array.isArray(userConfig.output) 46 - ? typeof userConfig.output[0] === 'string' 47 - ? userConfig.output[0] 48 - : (userConfig.output[0] as any).path || '' 49 - : (userConfig.output as any).path || '', 45 + : userConfig.output.path, 50 46 ), 51 47 }; 52 48 }; ··· 664 660 await createClient(config); 665 661 666 662 const outputPath = 667 - typeof config.output === 'string' 668 - ? config.output 669 - : config.output instanceof Array 670 - ? typeof config.output[0] === 'string' 671 - ? config.output[0] 672 - : config.output[0]?.path || '' 673 - : config.output.path; 663 + typeof config.output === 'string' ? config.output : config.output.path; 674 664 const filePaths = getFilePaths(outputPath); 675 665 676 666 await Promise.all( ··· 705 695 const outputPathA = 706 696 typeof configA.output === 'string' 707 697 ? configA.output 708 - : Array.isArray(configA.output) 709 - ? typeof configA.output[0] === 'string' 710 - ? configA.output[0] 711 - : (configA.output[0] as any).path 712 - : (configA.output as any).path; 698 + : configA.output.path; 713 699 const outputPathB = 714 700 typeof configB.output === 'string' 715 701 ? configB.output 716 - : Array.isArray(configB.output) 717 - ? typeof configB.output[0] === 'string' 718 - ? configB.output[0] 719 - : (configB.output[0] as any).path 720 - : (configB.output as any).path; 702 + : configB.output.path; 721 703 722 704 const filesA = getFilePaths(outputPathA); 723 705 const filesB = getFilePaths(outputPathB);
+4 -22
packages/openapi-ts-tests/main/test/3.1.x.test.ts
··· 42 42 outputDir, 43 43 typeof userConfig.output === 'string' 44 44 ? userConfig.output 45 - : Array.isArray(userConfig.output) 46 - ? typeof userConfig.output[0] === 'string' 47 - ? userConfig.output[0] 48 - : (userConfig.output[0] as any).path || '' 49 - : (userConfig.output as any).path || '', 45 + : userConfig.output.path, 50 46 ), 51 47 }; 52 48 }; ··· 963 959 await createClient(config); 964 960 965 961 const outputPath = 966 - typeof config.output === 'string' 967 - ? config.output 968 - : config.output instanceof Array 969 - ? typeof config.output[0] === 'string' 970 - ? config.output[0] 971 - : config.output[0]?.path || '' 972 - : config.output.path; 962 + typeof config.output === 'string' ? config.output : config.output.path; 973 963 const filePaths = getFilePaths(outputPath); 974 964 975 965 await Promise.all( ··· 1004 994 const outputPathA = 1005 995 typeof configA.output === 'string' 1006 996 ? configA.output 1007 - : Array.isArray(configA.output) 1008 - ? typeof configA.output[0] === 'string' 1009 - ? configA.output[0] 1010 - : (configA.output[0] as any).path 1011 - : (configA.output as any).path; 997 + : configA.output.path; 1012 998 const outputPathB = 1013 999 typeof configB.output === 'string' 1014 1000 ? configB.output 1015 - : Array.isArray(configB.output) 1016 - ? typeof configB.output[0] === 'string' 1017 - ? configB.output[0] 1018 - : (configB.output[0] as any).path 1019 - : (configB.output as any).path; 1001 + : configB.output.path; 1020 1002 1021 1003 const filesA = getFilePaths(outputPathA); 1022 1004 const filesB = getFilePaths(outputPathB);
+7 -29
packages/openapi-ts-tests/main/test/clients.test.ts
··· 46 46 ? path.join(outputDir, userConfig.output) 47 47 : { 48 48 ...userConfig.output, 49 - path: path.join( 50 - outputDir, 51 - Array.isArray(userConfig.output) 52 - ? typeof userConfig.output[0] === 'string' 53 - ? userConfig.output[0] 54 - : (userConfig.output[0] as any)?.path || '' 55 - : (userConfig.output as any).path, 56 - ), 49 + path: path.join(outputDir, userConfig.output.path), 57 50 }, 58 51 }); 59 52 ··· 176 169 } 177 170 178 171 const outputPath = 179 - typeof config.output === 'string' 180 - ? config.output 181 - : config.output instanceof Array 182 - ? typeof config.output[0] === 'string' 183 - ? config.output[0] 184 - : config.output[0]?.path || '' 185 - : config.output.path; 172 + typeof config.output === 'string' ? config.output : config.output.path; 173 + 186 174 const filePaths = getFilePaths(outputPath); 187 175 188 176 await Promise.all( ··· 339 327 await createClient(config); 340 328 341 329 const outputPath = 342 - typeof config.output === 'string' 343 - ? config.output 344 - : config.output instanceof Array 345 - ? typeof config.output[0] === 'string' 346 - ? config.output[0] 347 - : config.output[0]?.path || '' 348 - : config.output.path; 330 + typeof config.output === 'string' ? config.output : config.output.path; 331 + 349 332 const filePaths = getFilePaths(outputPath); 350 333 351 334 await Promise.all( ··· 491 474 await createClient(config); 492 475 493 476 const outputPath = 494 - typeof config.output === 'string' 495 - ? config.output 496 - : config.output instanceof Array 497 - ? typeof config.output[0] === 'string' 498 - ? config.output[0] 499 - : config.output[0]?.path || '' 500 - : config.output.path; 477 + typeof config.output === 'string' ? config.output : config.output.path; 478 + 501 479 const filePaths = getFilePaths(outputPath); 502 480 503 481 await Promise.all(
+2 -7
packages/openapi-ts-tests/main/test/plugins.test.ts
··· 567 567 await createClient(config); 568 568 569 569 const outputPath = 570 - typeof config.output === 'string' 571 - ? config.output 572 - : config.output instanceof Array 573 - ? typeof config.output[0] === 'string' 574 - ? config.output[0] 575 - : config.output[0]?.path || '' 576 - : config.output.path; 570 + typeof config.output === 'string' ? config.output : config.output.path; 571 + 577 572 const filePaths = getFilePaths(outputPath); 578 573 579 574 await Promise.all(
+1 -7
packages/openapi-ts-tests/zod/v3/test/3.0.x.test.ts
··· 62 62 await createClient(config); 63 63 64 64 const outputPath = 65 - typeof config.output === 'string' 66 - ? config.output 67 - : config.output instanceof Array 68 - ? typeof config.output[0] === 'string' 69 - ? config.output[0] 70 - : config.output[0]?.path || '' 71 - : config.output.path; 65 + typeof config.output === 'string' ? config.output : config.output.path; 72 66 const filePaths = getFilePaths(outputPath); 73 67 74 68 await Promise.all(
+2 -7
packages/openapi-ts-tests/zod/v3/test/3.1.x.test.ts
··· 144 144 await createClient(config); 145 145 146 146 const outputPath = 147 - typeof config.output === 'string' 148 - ? config.output 149 - : config.output instanceof Array 150 - ? typeof config.output[0] === 'string' 151 - ? config.output[0] 152 - : config.output[0]?.path || '' 153 - : config.output.path; 147 + typeof config.output === 'string' ? config.output : config.output.path; 148 + 154 149 const filePaths = getFilePaths(outputPath); 155 150 156 151 await Promise.all(
+1 -5
packages/openapi-ts-tests/zod/v3/test/openapi.test.ts
··· 57 57 const outputPath = 58 58 typeof config.output === 'string' 59 59 ? config.output 60 - : config.output instanceof Array 61 - ? typeof config.output[0] === 'string' 62 - ? config.output[0] 63 - : config.output[0]?.path || '' 64 - : config.output.path; 60 + : config.output.path; 65 61 const filePaths = getFilePaths(outputPath); 66 62 67 63 await Promise.all(
+2 -7
packages/openapi-ts-tests/zod/v4/test/3.0.x.test.ts
··· 62 62 await createClient(config); 63 63 64 64 const outputPath = 65 - typeof config.output === 'string' 66 - ? config.output 67 - : config.output instanceof Array 68 - ? typeof config.output[0] === 'string' 69 - ? config.output[0] 70 - : config.output[0]?.path || '' 71 - : config.output.path; 65 + typeof config.output === 'string' ? config.output : config.output.path; 66 + 72 67 const filePaths = getFilePaths(outputPath); 73 68 74 69 await Promise.all(
+2 -7
packages/openapi-ts-tests/zod/v4/test/3.1.x.test.ts
··· 144 144 await createClient(config); 145 145 146 146 const outputPath = 147 - typeof config.output === 'string' 148 - ? config.output 149 - : config.output instanceof Array 150 - ? typeof config.output[0] === 'string' 151 - ? config.output[0] 152 - : config.output[0]?.path || '' 153 - : config.output.path; 147 + typeof config.output === 'string' ? config.output : config.output.path; 148 + 154 149 const filePaths = getFilePaths(outputPath); 155 150 156 151 await Promise.all(
+1 -5
packages/openapi-ts-tests/zod/v4/test/openapi.test.ts
··· 57 57 const outputPath = 58 58 typeof config.output === 'string' 59 59 ? config.output 60 - : config.output instanceof Array 61 - ? typeof config.output[0] === 'string' 62 - ? config.output[0] 63 - : config.output[0]?.path || '' 64 - : config.output.path; 60 + : config.output.path; 65 61 const filePaths = getFilePaths(outputPath); 66 62 67 63 await Promise.all(
+5 -5
packages/openapi-ts/src/__tests__/index.test.ts
··· 1 1 import { platform } from 'os'; 2 2 import { describe, expect, it } from 'vitest'; 3 3 4 - import type { UserConfig } from '../types/config'; 4 + import type { UserConfig, UserConfigMultiOutputs } from '../types/config'; 5 5 6 6 describe( 7 7 'main entry index', ··· 33 33 it('should handle multiple string outputs', async () => { 34 34 const { createClient } = await import('../index'); 35 35 36 - const config: UserConfig = { 36 + const config: UserConfigMultiOutputs = { 37 37 dryRun: true, 38 38 input: { 39 39 info: { title: 'Test API', version: '1.0.0' }, ··· 51 51 it('should handle multiple output objects with different configurations', async () => { 52 52 const { createClient } = await import('../index'); 53 53 54 - const config: UserConfig = { 54 + const config: UserConfigMultiOutputs = { 55 55 dryRun: true, 56 56 input: { 57 57 info: { title: 'Test API', version: '1.0.0' }, ··· 80 80 it('should handle mixed string and object outputs', async () => { 81 81 const { createClient } = await import('../index'); 82 82 83 - const config: UserConfig = { 83 + const config: UserConfigMultiOutputs = { 84 84 dryRun: true, 85 85 input: { 86 86 info: { title: 'Test API', version: '1.0.0' }, ··· 105 105 it('should preserve global config across multiple outputs', async () => { 106 106 const { createClient } = await import('../index'); 107 107 108 - const config: UserConfig = { 108 + const config: UserConfigMultiOutputs = { 109 109 dryRun: true, 110 110 experimentalParser: true, 111 111 input: {
-14
packages/openapi-ts/src/config/__tests__/input.test.ts
··· 169 169 expect(result.watch.enabled).toBe(true); 170 170 expect(result.watch.interval).toBe(1500); 171 171 }); 172 - 173 - it('should work with multi-output configurations', () => { 174 - const userConfig: UserConfig = { 175 - input: 'readme:abc123', 176 - output: ['src/client-1', 'src/client-2'], 177 - }; 178 - 179 - const result = getInput(userConfig); 180 - expect(result.path).toBe( 181 - 'https://dash.readme.com/api/v1/api-registry/abc123', 182 - ); 183 - // Input processing should be the same regardless of output configuration 184 - expect(result.watch.enabled).toBe(false); 185 - }); 186 172 }); 187 173 188 174 describe('error handling', () => {
+15 -6
packages/openapi-ts/src/config/init.ts
··· 3 3 import { loadConfig } from '@hey-api/c12'; 4 4 5 5 import { ConfigError } from '../error'; 6 - import type { Config, UserConfig } from '../types/config'; 6 + import type { 7 + Config, 8 + UserConfig, 9 + UserConfigMultiOutputs, 10 + } from '../types/config'; 7 11 import { isLegacyClient, setConfig } from '../utils/config'; 8 12 import { getInput } from './input'; 9 13 import { getLogs } from './logs'; ··· 18 22 * @internal 19 23 */ 20 24 const expandMultiOutputConfigs = ( 21 - userConfigs: ReadonlyArray<UserConfig>, 25 + userConfigs: ReadonlyArray<UserConfigMultiOutputs>, 22 26 ): ReadonlyArray<UserConfig> => { 23 27 const expandedConfigs: Array<UserConfig> = []; 24 28 ··· 33 37 } 34 38 } else { 35 39 // Single output configuration - keep as is 36 - expandedConfigs.push(userConfig); 40 + expandedConfigs.push(userConfig as UserConfig); 37 41 } 38 42 } 39 43 ··· 44 48 * @internal 45 49 */ 46 50 export const initConfigs = async ( 47 - userConfig: UserConfig | ReadonlyArray<UserConfig> | undefined, 51 + userConfig: 52 + | UserConfigMultiOutputs 53 + | ReadonlyArray<UserConfigMultiOutputs> 54 + | undefined, 48 55 ): Promise<{ 49 56 dependencies: Record<string, string>; 50 57 results: ReadonlyArray<{ ··· 62 69 } 63 70 64 71 const { config: configFromFile, configFile: loadedConfigFile } = 65 - await loadConfig<UserConfig>({ 72 + await loadConfig<UserConfigMultiOutputs>({ 66 73 configFile: configurationFile, 67 74 name: 'openapi-ts', 68 75 }); ··· 70 77 const dependencies = getProjectDependencies( 71 78 Object.keys(configFromFile).length ? loadedConfigFile : undefined, 72 79 ); 73 - const baseUserConfigs: ReadonlyArray<UserConfig> = Array.isArray(userConfig) 80 + const baseUserConfigs: ReadonlyArray<UserConfigMultiOutputs> = Array.isArray( 81 + userConfig, 82 + ) 74 83 ? userConfig 75 84 : Array.isArray(configFromFile) 76 85 ? configFromFile.map((config) =>
+3 -9
packages/openapi-ts/src/config/output.ts
··· 10 10 tsConfigPath: '', 11 11 }; 12 12 13 - // After expansion, output should always be a single output (string or Output object) 14 - // but TypeScript doesn't know this, so we need to handle the array case defensively 15 - const singleOutput = Array.isArray(userConfig.output) 16 - ? userConfig.output[0] 17 - : userConfig.output; 18 - 19 - if (typeof singleOutput === 'string') { 20 - output.path = singleOutput; 13 + if (typeof userConfig.output === 'string') { 14 + output.path = userConfig.output; 21 15 } else { 22 16 output = { 23 17 ...output, 24 - ...singleOutput, 18 + ...userConfig.output, 25 19 }; 26 20 } 27 21
+12 -5
packages/openapi-ts/src/index.ts
··· 14 14 } from './error'; 15 15 import type { IR } from './ir/types'; 16 16 import type { Client } from './types/client'; 17 - import type { Config, UserConfig } from './types/config'; 17 + import type { 18 + Config, 19 + UserConfig, 20 + UserConfigMultiOutputs, 21 + } from './types/config'; 18 22 import { registerHandlebarTemplates } from './utils/handlebars'; 19 23 import { Logger } from './utils/logger'; 20 24 21 - type ConfigValue = UserConfig | ReadonlyArray<UserConfig>; 25 + type ConfigValue = 26 + | UserConfigMultiOutputs 27 + | ReadonlyArray<UserConfigMultiOutputs>; 22 28 // Generic input shape for config that may be a value or a (possibly async) factory 23 29 type ConfigInput<T extends ConfigValue> = T | (() => T) | (() => Promise<T>); 24 30 ··· 27 33 /** 28 34 * Generate a client from the provided configuration. 29 35 * 30 - * @param userConfig User provided {@link UserConfig} configuration. 36 + * @param userConfig User provided {@link UserConfigMultiOutputs} configuration. 31 37 */ 32 38 export const createClient = async ( 33 39 userConfig?: ConfigInput<ConfigValue>, ··· 79 85 return result; 80 86 } catch (error) { 81 87 const config = configs[0] as Config | undefined; 88 + // TODO: Improve error handling for multi-output configs 82 89 const resolvedSingle = ( 83 90 Array.isArray(resolvedConfig) ? resolvedConfig[0] : resolvedConfig 84 - ) as UserConfig | undefined; 91 + ) as UserConfigMultiOutputs | undefined; 85 92 const dryRun = config ? config.dryRun : resolvedSingle?.dryRun; 86 93 const isInteractive = config 87 94 ? config.interactive 88 95 : resolvedSingle?.interactive; 89 - const logs = config?.logs ?? getLogs(resolvedSingle); 96 + const logs = config?.logs ?? getLogs(resolvedSingle as UserConfig); 90 97 91 98 let logPath: string | undefined; 92 99
+4 -1
packages/openapi-ts/src/types/config.d.ts
··· 5 5 import type { Output } from './output'; 6 6 import type { Parser, ResolvedParser } from './parser'; 7 7 8 + export interface UserConfigMultiOutputs extends UserConfig { 9 + output: string | Output | ReadonlyArray<string | Output>; 10 + } 8 11 export interface UserConfig { 9 12 /** 10 13 * Path to the config file. Set this value if you don't use the default ··· 47 50 * outputs to generate different versions of your SDK with different 48 51 * configurations (e.g., different plugins, formatters, or paths). 49 52 */ 50 - output: string | Output | ReadonlyArray<string | Output>; 53 + output: string | Output; 51 54 /** 52 55 * Customize how the input is parsed and transformed before it's passed to 53 56 * plugins.