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

test: print

Lubos 77464698 0b773597

+4 -4
.github/copilot-instructions.md
··· 49 49 # Server starts on http://localhost:5173/ 50 50 51 51 # Run CLI tool directly 52 - node packages/openapi-ts/bin/index.cjs --help 52 + node packages/openapi-ts/dist/run.js --help 53 53 # or after building 54 54 npx @hey-api/openapi-ts --help 55 55 ``` ··· 85 85 86 86 ```bash 87 87 # Test CLI help 88 - node packages/openapi-ts/bin/index.cjs --help 88 + node packages/openapi-ts/dist/run.js --help 89 89 90 90 # Test CLI version 91 - node packages/openapi-ts/bin/index.cjs --version 91 + node packages/openapi-ts/dist/run.js --version 92 92 93 93 # Test basic code generation with a simple OpenAPI spec 94 94 # Create a minimal test spec and generate client code 95 - node packages/openapi-ts/bin/index.cjs -i path/to/spec.json -o ./test-output --plugins "@hey-api/client-fetch" "@hey-api/typescript" 95 + node packages/openapi-ts/dist/run.js -i path/to/spec.json -o ./test-output --plugins "@hey-api/client-fetch" "@hey-api/typescript" 96 96 ``` 97 97 98 98 2. **Example Application Test**:
+1 -1
packages/openapi-ts/package.json
··· 66 66 "./package.json": "./package.json" 67 67 }, 68 68 "bin": { 69 - "openapi-ts": "./dist/run.cjs" 69 + "openapi-ts": "./dist/run.js" 70 70 }, 71 71 "files": [ 72 72 "dist",
+133
packages/openapi-ts/src/generate.ts
··· 1 + import { checkNodeVersion } from '~/config/engine'; 2 + import type { Configs } from '~/config/init'; 3 + import { initConfigs } from '~/config/init'; 4 + import { getLogs } from '~/config/logs'; 5 + import { createClient as pCreateClient } from '~/createClient'; 6 + import { 7 + ConfigValidationError, 8 + JobError, 9 + logCrashReport, 10 + openGitHubIssueWithCrashReport, 11 + printCrashReport, 12 + shouldReportCrash, 13 + } from '~/error'; 14 + import type { IR } from '~/ir/types'; 15 + import type { Client } from '~/types/client'; 16 + import type { UserConfig } from '~/types/config'; 17 + import type { LazyOrAsync, MaybeArray } from '~/types/utils'; 18 + import { printCliIntro } from '~/utils/cli'; 19 + import { registerHandlebarTemplates } from '~/utils/handlebars'; 20 + import { Logger } from '~/utils/logger'; 21 + 22 + /** 23 + * Generate a client from the provided configuration. 24 + * 25 + * @param userConfig User provided {@link UserConfig} configuration(s). 26 + */ 27 + export const createClient = async ( 28 + userConfig?: LazyOrAsync<MaybeArray<UserConfig>>, 29 + logger = new Logger(), 30 + ): Promise<ReadonlyArray<Client | IR.Context>> => { 31 + const resolvedConfig = 32 + typeof userConfig === 'function' ? await userConfig() : userConfig; 33 + const userConfigs = resolvedConfig 34 + ? resolvedConfig instanceof Array 35 + ? resolvedConfig 36 + : [resolvedConfig] 37 + : []; 38 + 39 + let rawLogs = userConfigs.find( 40 + (config) => getLogs(config).level !== 'silent', 41 + )?.logs; 42 + if (typeof rawLogs === 'string') { 43 + rawLogs = getLogs({ logs: rawLogs }); 44 + } 45 + 46 + let configs: Configs | undefined; 47 + 48 + try { 49 + checkNodeVersion(); 50 + 51 + const eventCreateClient = logger.timeEvent('createClient'); 52 + 53 + const eventConfig = logger.timeEvent('config'); 54 + configs = await initConfigs({ logger, userConfigs }); 55 + const printIntro = configs.results.some( 56 + (result) => result.config.logs.level !== 'silent', 57 + ); 58 + if (printIntro) { 59 + printCliIntro(); 60 + } 61 + eventConfig.timeEnd(); 62 + 63 + const allConfigErrors = configs.results.flatMap((result) => 64 + result.errors.map((error) => ({ error, jobIndex: result.jobIndex })), 65 + ); 66 + if (allConfigErrors.length) { 67 + throw new ConfigValidationError(allConfigErrors); 68 + } 69 + 70 + const eventHandlebars = logger.timeEvent('handlebars'); 71 + const templates = registerHandlebarTemplates(); 72 + eventHandlebars.timeEnd(); 73 + 74 + const clients = await Promise.all( 75 + configs.results.map(async (result) => { 76 + try { 77 + return await pCreateClient({ 78 + config: result.config, 79 + dependencies: configs!.dependencies, 80 + jobIndex: result.jobIndex, 81 + logger, 82 + templates, 83 + }); 84 + } catch (error) { 85 + throw new JobError('', { 86 + error, 87 + jobIndex: result.jobIndex, 88 + }); 89 + } 90 + }), 91 + ); 92 + const result = clients.filter((client) => Boolean(client)) as ReadonlyArray< 93 + Client | IR.Context 94 + >; 95 + 96 + eventCreateClient.timeEnd(); 97 + 98 + const printLogs = configs.results.some( 99 + (result) => result.config.logs.level === 'debug', 100 + ); 101 + logger.report(printLogs); 102 + 103 + return result; 104 + } catch (error) { 105 + const results = configs?.results ?? []; 106 + 107 + const logs = 108 + results.find((result) => result.config.logs.level !== 'silent')?.config 109 + .logs ?? 110 + results[0]?.config.logs ?? 111 + rawLogs; 112 + const dryRun = 113 + results.some((result) => result.config.dryRun) ?? 114 + userConfigs.some((config) => config.dryRun) ?? 115 + false; 116 + const logPath = 117 + logs?.file && !dryRun 118 + ? logCrashReport(error, logs.path ?? '') 119 + : undefined; 120 + if (!logs || logs.level !== 'silent') { 121 + printCrashReport({ error, logPath }); 122 + const isInteractive = 123 + results.some((result) => result.config.interactive) ?? 124 + userConfigs.some((config) => config.interactive) ?? 125 + false; 126 + if (await shouldReportCrash({ error, isInteractive })) { 127 + await openGitHubIssueWithCrashReport(error); 128 + } 129 + } 130 + 131 + throw error; 132 + } 133 + };
+1 -130
packages/openapi-ts/src/index.ts
··· 35 35 // @ts-expect-error 36 36 import colorSupport from 'color-support'; 37 37 38 - import { checkNodeVersion } from '~/config/engine'; 39 - import type { Configs } from '~/config/init'; 40 - import { initConfigs } from '~/config/init'; 41 - import { getLogs } from '~/config/logs'; 42 - import { createClient as pCreateClient } from '~/createClient'; 43 - import { 44 - ConfigValidationError, 45 - JobError, 46 - logCrashReport, 47 - openGitHubIssueWithCrashReport, 48 - printCrashReport, 49 - shouldReportCrash, 50 - } from '~/error'; 51 - import type { IR } from '~/ir/types'; 52 - import type { Client } from '~/types/client'; 53 38 import type { UserConfig } from '~/types/config'; 54 39 import type { LazyOrAsync, MaybeArray } from '~/types/utils'; 55 - import { printCliIntro } from '~/utils/cli'; 56 - import { registerHandlebarTemplates } from '~/utils/handlebars'; 57 - import { Logger } from '~/utils/logger'; 58 40 59 41 colors.enabled = colorSupport().hasBasic; 60 42 61 - /** 62 - * Generate a client from the provided configuration. 63 - * 64 - * @param userConfig User provided {@link UserConfig} configuration(s). 65 - */ 66 - export const createClient = async ( 67 - userConfig?: LazyOrAsync<MaybeArray<UserConfig>>, 68 - logger = new Logger(), 69 - ): Promise<ReadonlyArray<Client | IR.Context>> => { 70 - const resolvedConfig = 71 - typeof userConfig === 'function' ? await userConfig() : userConfig; 72 - const userConfigs = resolvedConfig 73 - ? resolvedConfig instanceof Array 74 - ? resolvedConfig 75 - : [resolvedConfig] 76 - : []; 77 - 78 - let rawLogs = userConfigs.find( 79 - (config) => getLogs(config).level !== 'silent', 80 - )?.logs; 81 - if (typeof rawLogs === 'string') { 82 - rawLogs = getLogs({ logs: rawLogs }); 83 - } 84 - 85 - let configs: Configs | undefined; 86 - 87 - try { 88 - checkNodeVersion(); 89 - 90 - const eventCreateClient = logger.timeEvent('createClient'); 91 - 92 - const eventConfig = logger.timeEvent('config'); 93 - configs = await initConfigs({ logger, userConfigs }); 94 - const printIntro = configs.results.some( 95 - (result) => result.config.logs.level !== 'silent', 96 - ); 97 - if (printIntro) { 98 - printCliIntro(); 99 - } 100 - eventConfig.timeEnd(); 101 - 102 - const allConfigErrors = configs.results.flatMap((result) => 103 - result.errors.map((error) => ({ error, jobIndex: result.jobIndex })), 104 - ); 105 - if (allConfigErrors.length) { 106 - throw new ConfigValidationError(allConfigErrors); 107 - } 108 - 109 - const eventHandlebars = logger.timeEvent('handlebars'); 110 - const templates = registerHandlebarTemplates(); 111 - eventHandlebars.timeEnd(); 112 - 113 - const clients = await Promise.all( 114 - configs.results.map(async (result) => { 115 - try { 116 - return await pCreateClient({ 117 - config: result.config, 118 - dependencies: configs!.dependencies, 119 - jobIndex: result.jobIndex, 120 - logger, 121 - templates, 122 - }); 123 - } catch (error) { 124 - throw new JobError('', { 125 - error, 126 - jobIndex: result.jobIndex, 127 - }); 128 - } 129 - }), 130 - ); 131 - const result = clients.filter((client) => Boolean(client)) as ReadonlyArray< 132 - Client | IR.Context 133 - >; 134 - 135 - eventCreateClient.timeEnd(); 136 - 137 - const printLogs = configs.results.some( 138 - (result) => result.config.logs.level === 'debug', 139 - ); 140 - logger.report(printLogs); 141 - 142 - return result; 143 - } catch (error) { 144 - const results = configs?.results ?? []; 145 - 146 - const logs = 147 - results.find((result) => result.config.logs.level !== 'silent')?.config 148 - .logs ?? 149 - results[0]?.config.logs ?? 150 - rawLogs; 151 - const dryRun = 152 - results.some((result) => result.config.dryRun) ?? 153 - userConfigs.some((config) => config.dryRun) ?? 154 - false; 155 - const logPath = 156 - logs?.file && !dryRun 157 - ? logCrashReport(error, logs.path ?? '') 158 - : undefined; 159 - if (!logs || logs.level !== 'silent') { 160 - printCrashReport({ error, logPath }); 161 - const isInteractive = 162 - results.some((result) => result.config.interactive) ?? 163 - userConfigs.some((config) => config.interactive) ?? 164 - false; 165 - if (await shouldReportCrash({ error, isInteractive })) { 166 - await openGitHubIssueWithCrashReport(error); 167 - } 168 - } 169 - 170 - throw error; 171 - } 172 - }; 43 + export { createClient } from './generate'; 173 44 174 45 /** 175 46 * Type helper for openapi-ts.config.ts, returns {@link MaybeArray<UserConfig>} object(s)
+24
scripts/examples-generate.sh
··· 11 11 12 12 echo "⏳ Generating client code for all examples..." 13 13 14 + # Build the CLI package and show diagnostics so CI can report why the bin may be missing 15 + echo "Building @hey-api/openapi-ts (required for example generation)..." 16 + if command -v pnpm >/dev/null 2>&1; then 17 + if pnpm -w -s --version >/dev/null 2>&1; then 18 + pnpm -w -s --filter "@hey-api/openapi-ts" build || pnpm -s --filter "@hey-api/openapi-ts" build || true 19 + else 20 + pnpm -s --filter "@hey-api/openapi-ts" build || true 21 + fi 22 + fi 23 + 24 + CLI_PKG_DIR="$ROOT_DIR/packages/openapi-ts" 25 + echo "-> Debug: showing $CLI_PKG_DIR/package.json" 26 + if [ -f "$CLI_PKG_DIR/package.json" ]; then 27 + cat "$CLI_PKG_DIR/package.json" 28 + else 29 + echo "-> Debug: package.json missing at $CLI_PKG_DIR" 30 + fi 31 + 32 + echo "-> Debug: listing $CLI_PKG_DIR top-level files" 33 + ls -la "$CLI_PKG_DIR" || true 34 + echo "-> Debug: listing $CLI_PKG_DIR/dist" 35 + ls -la "$CLI_PKG_DIR/dist" 2>/dev/null || echo "-> Debug: dist missing" 36 + 37 + 14 38 # Find all examples with openapi-ts script and generate code in parallel 15 39 # Concurrency control: adjust this number depending on CI machine resources 16 40 CONCURRENCY=${CONCURRENCY:-4}
+1 -1
scripts/publish-preview-packages.sh
··· 1 - #!/bin/bash 1 + #!/usr/bin/env bash 2 2 3 3 result=$(pnpx turbo run build --affected --dry-run=json) 4 4