fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 117 lines 3.6 kB view raw
1import path from 'node:path'; 2import { fileURLToPath } from 'node:url'; 3 4import { Logger } from '@hey-api/codegen-core'; 5import type { Context } from '@hey-api/shared'; 6import { 7 checkNodeVersion, 8 ConfigValidationError, 9 getLogs, 10 JobError, 11 logCrashReport, 12 openGitHubIssueWithCrashReport, 13 printCliIntro, 14 printCrashReport, 15 shouldReportCrash, 16} from '@hey-api/shared'; 17import type { LazyOrAsync, MaybeArray } from '@hey-api/types'; 18 19import type { Configs } from './config/init'; 20import { resolveJobs } from './config/init'; 21import type { UserConfig } from './config/types'; 22import { createClient as pCreateClient } from './createClient'; 23 24const __filename = fileURLToPath(import.meta.url); 25const __dirname = path.dirname(__filename); 26 27/** 28 * Generate a client from the provided configuration. 29 * 30 * @param userConfig User provided {@link UserConfig} configuration(s). 31 */ 32export async function createClient( 33 userConfig?: LazyOrAsync<MaybeArray<UserConfig>>, 34 logger = new Logger(), 35): Promise<ReadonlyArray<Context>> { 36 const resolvedConfig = typeof userConfig === 'function' ? await userConfig() : userConfig; 37 const userConfigs = resolvedConfig 38 ? resolvedConfig instanceof Array 39 ? resolvedConfig 40 : [resolvedConfig] 41 : []; 42 43 let rawLogs = userConfigs.find((config) => getLogs(config.logs).level !== 'silent')?.logs; 44 if (typeof rawLogs === 'string') { 45 rawLogs = getLogs(rawLogs); 46 } 47 48 let jobs: Configs['jobs'] = []; 49 50 try { 51 checkNodeVersion(); 52 53 const eventCreateClient = logger.timeEvent('createClient'); 54 55 const eventConfig = logger.timeEvent('config'); 56 const resolved = await resolveJobs({ logger, userConfigs }); 57 const dependencies = resolved.dependencies; 58 jobs = resolved.jobs; 59 const printIntro = jobs.some((job) => job.config.logs.level !== 'silent'); 60 if (printIntro) printCliIntro(__dirname); 61 eventConfig.timeEnd(); 62 63 const configErrors = jobs.flatMap((job) => 64 job.errors.map((error) => ({ error, jobIndex: job.index })), 65 ); 66 if (configErrors.length > 0) { 67 throw new ConfigValidationError(configErrors); 68 } 69 70 const outputs = await Promise.all( 71 jobs.map(async (job) => { 72 try { 73 return await pCreateClient({ 74 config: job.config, 75 dependencies, 76 jobIndex: job.index, 77 logger, 78 }); 79 } catch (error) { 80 if (error instanceof Error) { 81 throw new JobError('', { 82 error, 83 jobIndex: job.index, 84 }); 85 } 86 } 87 }), 88 ); 89 const contexts = outputs.filter((ctx): ctx is Context => ctx !== undefined); 90 91 eventCreateClient.timeEnd(); 92 93 logger.report(jobs.some((job) => job.config.logs.level === 'debug')); 94 95 return contexts; 96 } catch (error) { 97 const logs = 98 jobs.find((job) => job.config.logs.level !== 'silent')?.config.logs ?? 99 jobs[0]?.config.logs ?? 100 rawLogs; 101 const dryRun = 102 jobs.some((job) => job.config.dryRun) ?? userConfigs.some((config) => config.dryRun) ?? false; 103 const logPath = logs?.file && !dryRun ? logCrashReport(error, logs.path ?? '') : undefined; 104 if (!logs || logs.level !== 'silent') { 105 printCrashReport({ error, logPath }); 106 const isInteractive = 107 jobs.some((job) => job.config.interactive) ?? 108 userConfigs.some((config) => config.interactive) ?? 109 false; 110 if (await shouldReportCrash({ error, isInteractive })) { 111 await openGitHubIssueWithCrashReport(error, __dirname); 112 } 113 } 114 115 throw error; 116 } 117}