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.

Merge pull request #569 from hey-api/chore/remove-client-infer

feat: remove client inference

authored by

Lubos and committed by
GitHub
cd0f77fe 7af79b5b

+51 -140
+5
.changeset/chilly-masks-beg.md
··· 1 + --- 2 + "@hey-api/openapi-ts": minor 3 + --- 4 + 5 + feat: remove client inference
+5
.changeset/cold-spiders-bathe.md
··· 1 + --- 2 + "@hey-api/docs": patch 3 + --- 4 + 5 + docs: add migration for v0.45.0
+1 -1
docs/openapi-ts/clients.md
··· 11 11 12 12 ## Legacy Clients 13 13 14 - Before standalone client packages, clients were generated using `openapi-ts`. If you want to use a client that isn't published as a standalone package, you can explicitly set the `client` config option to generate it. 14 + Before standalone client packages, clients were generated using `openapi-ts`. If you want to generate a legacy client that isn't published as a standalone package, you can use the `client` config option. 15 15 16 16 ::: code-group 17 17
+1 -1
docs/openapi-ts/configuration.md
··· 40 40 41 41 ## Clients 42 42 43 - By default, `openapi-ts` will try to guess your client based on your project dependencies. If we don't get it right, you can specify the desired client 43 + By default, `openapi-ts` will generate a Fetch API client. If you want a different client, you can specify it using the `client` option. 44 44 45 45 ::: code-group 46 46
-2
docs/openapi-ts/get-started.md
··· 20 20 - works with CLI, Node.js, or npx 21 21 - supports OpenAPI 2.0, 3.0, and 3.1 specifications 22 22 - supports both JSON and YAML input files 23 - - supports external references using [json-schema-ref-parser](https://github.com/APIDevTools/json-schema-ref-parser/) 24 23 - generates TypeScript interfaces, REST clients, and JSON Schemas 25 24 - Fetch API, Axios, Angular, Node.js, and XHR clients available 26 - - abortable requests through cancellable promise pattern 27 25 28 26 ## Quick Start 29 27
+15 -1
docs/openapi-ts/migrating.md
··· 50 50 51 51 This config option is deprecated and will be removed in favor of [clients](./clients). 52 52 53 + ## v0.45.0 54 + 55 + ### Removed `client` inference 56 + 57 + `openapi-ts` will no longer infer which client you want to generate. By default, we will create a `fetch` client. If you want a different client, you can specify it using the `client` option. 58 + 59 + ```js{2} 60 + export default { 61 + client: 'axios', 62 + input: 'path/to/openapi.json', 63 + output: 'src/client', 64 + } 65 + ``` 66 + 53 67 ## v0.44.0 54 68 55 69 ### Moved `format` ··· 390 404 391 405 ## OpenAPI TypeScript Codegen 392 406 393 - `openapi-ts` was originally forked from Ferdi Koomen's [openapi-typescript-codegen](https://github.com/ferdikoomen/openapi-typescript-codegen). Therefore, we want you to be able to migrate your projects. Migration should be relatively straightforward if you follow the release notes on this page. Start here and scroll up to the release you're migrating to. 407 + `openapi-ts` was originally forked from Ferdi Koomen's [openapi-typescript-codegen](https://github.com/ferdikoomen/openapi-typescript-codegen). Therefore, we want you to be able to migrate your projects. Migration should be relatively straightforward if you follow the release notes on this page. Start on [v0.27.24](#v0-27-24) and scroll to the release you're migrating to.
+6 -3
examples/openapi-ts-fetch/openapi-ts.config.ts
··· 2 2 3 3 export default defineConfig({ 4 4 base: 'https://petstore3.swagger.io/api/v3', 5 - format: 'prettier', 5 + client: '@hey-api/client-fetch', 6 6 input: 7 7 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml', 8 - lint: 'eslint', 9 - output: './src/client', 8 + output: { 9 + format: 'prettier', 10 + lint: 'eslint', 11 + path: './src/client', 12 + }, 10 13 });
-2
packages/openapi-ts/README.md
··· 13 13 - works with CLI, Node.js, or npx 14 14 - supports OpenAPI 2.0, 3.0, and 3.1 specifications 15 15 - supports both JSON and YAML input files 16 - - supports external references using [json-schema-ref-parser](https://github.com/APIDevTools/json-schema-ref-parser/) 17 16 - generates TypeScript interfaces, REST clients, and JSON Schemas 18 17 - Fetch API, Axios, Angular, Node.js, and XHR clients available 19 - - abortable requests through cancellable promise pattern 20 18 21 19 ## Documentation 22 20
+16 -128
packages/openapi-ts/src/index.ts
··· 1 - import { existsSync, readFileSync } from 'node:fs'; 2 1 import path from 'node:path'; 3 2 4 3 import { loadConfig } from 'c12'; ··· 13 12 import { postProcessClient } from './utils/postprocess'; 14 13 import { writeClient } from './utils/write/client'; 15 14 16 - type Dependencies = Record<string, unknown>; 17 - interface PackageJson { 18 - dependencies?: Dependencies; 19 - devDependencies?: Dependencies; 20 - peerDependencies?: Dependencies; 21 - } 22 - 23 - /** 24 - * Dependencies used in each client. User must install these, without them 25 - * the generated client won't work. 26 - */ 27 - const clientDependencies: Record<Config['client'], string[]> = { 28 - '@hey-api/client-axios': ['axios'], 29 - '@hey-api/client-fetch': [], 30 - angular: ['@angular/common', '@angular/core', 'rxjs'], 31 - axios: ['axios'], 32 - fetch: [], 33 - node: ['node-fetch'], 34 - xhr: [], 35 - }; 36 - 37 15 type OutputProcesser = { 38 - args: (path: string) => string[]; 16 + args: (path: string) => ReadonlyArray<string>; 39 17 command: string; 40 - condition: (dependencies: Dependencies) => boolean; 41 18 name: string; 42 19 }; 43 20 ··· 51 28 biome: { 52 29 args: (path) => ['format', '--write', path], 53 30 command: 'biome', 54 - condition: (dependencies) => Boolean(dependencies['@biomejs/biome']), 55 31 name: 'Biome (Format)', 56 32 }, 57 33 prettier: { ··· 63 39 './.prettierignore', 64 40 ], 65 41 command: 'prettier', 66 - condition: (dependencies) => Boolean(dependencies.prettier), 67 42 name: 'Prettier', 68 43 }, 69 44 }; ··· 78 53 biome: { 79 54 args: (path) => ['lint', '--apply', path], 80 55 command: 'biome', 81 - condition: (dependencies) => Boolean(dependencies['@biomejs/biome']), 82 56 name: 'Biome (Lint)', 83 57 }, 84 58 eslint: { 85 59 args: (path) => [path, '--fix'], 86 60 command: 'eslint', 87 - condition: (dependencies) => Boolean(dependencies.eslint), 88 61 name: 'ESLint', 89 62 }, 90 63 }; 91 64 92 - const processOutput = (dependencies: Dependencies) => { 65 + const processOutput = () => { 93 66 const config = getConfig(); 67 + 94 68 if (config.output.format) { 95 - const formatter = formatters[config.output.format]; 96 - if (formatter.condition(dependencies)) { 97 - console.log(`✨ Running ${formatter.name}`); 98 - sync(formatter.command, formatter.args(config.output.path)); 99 - } 100 - } 101 - if (config.output.lint) { 102 - const linter = linters[config.output.lint]; 103 - if (linter.condition(dependencies)) { 104 - console.log(`✨ Running ${linter.name}`); 105 - sync(linter.command, linter.args(config.output.path)); 106 - } 69 + const module = formatters[config.output.format]; 70 + console.log(`✨ Running ${module.name}`); 71 + sync(module.command, module.args(config.output.path)); 107 72 } 108 - }; 109 73 110 - const inferClient = (dependencies: Dependencies): Config['client'] => { 111 - if (dependencies['@hey-api/client-axios']) { 112 - return '@hey-api/client-axios'; 113 - } 114 - if (dependencies['@hey-api/client-fetch']) { 115 - return '@hey-api/client-fetch'; 116 - } 117 - if (dependencies.axios) { 118 - return 'axios'; 119 - } 120 - if (dependencies['node-fetch']) { 121 - return 'node'; 122 - } 123 - if (Object.keys(dependencies).some((d) => d.startsWith('@angular'))) { 124 - return 'angular'; 74 + if (config.output.lint) { 75 + const module = linters[config.output.lint]; 76 + console.log(`✨ Running ${module.name}`); 77 + sync(module.command, module.args(config.output.path)); 125 78 } 126 - return 'fetch'; 127 79 }; 128 80 129 81 const logClientMessage = () => { ··· 131 83 switch (client) { 132 84 case 'angular': 133 85 return console.log('✨ Creating Angular client'); 86 + case '@hey-api/client-axios': 134 87 case 'axios': 135 88 return console.log('✨ Creating Axios client'); 89 + case '@hey-api/client-fetch': 136 90 case 'fetch': 137 91 return console.log('✨ Creating Fetch client'); 138 92 case 'node': ··· 142 96 } 143 97 }; 144 98 145 - const logMissingDependenciesWarning = (dependencies: Dependencies) => { 146 - const { client } = getConfig(); 147 - const missing = clientDependencies[client].filter( 148 - (d) => dependencies[d] === undefined, 149 - ); 150 - if (missing.length > 0) { 151 - console.log( 152 - '⚠️ Dependencies used in generated client are missing: ' + 153 - missing.join(' '), 154 - ); 155 - } 156 - }; 157 - 158 99 const getOutput = (userConfig: UserConfig): Config['output'] => { 159 100 let output: Config['output'] = { 160 101 format: false, ··· 228 169 return types; 229 170 }; 230 171 231 - const getInstalledDependencies = (): Dependencies => { 232 - const packageJsonToDependencies = (pkg: PackageJson): Dependencies => 233 - [ 234 - pkg.dependencies ?? {}, 235 - pkg.devDependencies ?? {}, 236 - pkg.peerDependencies ?? {}, 237 - ].reduce( 238 - (result, dependencies) => ({ 239 - ...result, 240 - ...dependencies, 241 - }), 242 - {}, 243 - ); 244 - 245 - let dependencies: Dependencies = {}; 246 - 247 - // Attempt to get all globally installed packages. 248 - const result = sync('npm', ['list', '-g', '--json', '--depth=0']); 249 - if (!result.error) { 250 - const globalDependencies: PackageJson = JSON.parse( 251 - result.stdout.toString(), 252 - ); 253 - dependencies = { 254 - ...dependencies, 255 - ...packageJsonToDependencies(globalDependencies), 256 - }; 257 - } 258 - 259 - // Attempt to read any dependencies installed in a local projects package.json. 260 - const pkgPath = path.resolve(process.cwd(), 'package.json'); 261 - if (existsSync(pkgPath)) { 262 - const localDependencies: PackageJson = JSON.parse( 263 - readFileSync(pkgPath).toString(), 264 - ); 265 - dependencies = { 266 - ...dependencies, 267 - ...packageJsonToDependencies(localDependencies), 268 - }; 269 - } 270 - 271 - return dependencies; 272 - }; 273 - 274 - const initConfig = async ( 275 - userConfig: UserConfig, 276 - dependencies: Dependencies, 277 - ) => { 172 + const initConfig = async (userConfig: UserConfig) => { 278 173 const { config: userConfigFromFile } = await loadConfig<UserConfig>({ 279 174 jitiOptions: { 280 175 esmResolve: true, ··· 289 184 290 185 const { 291 186 base, 187 + client = 'fetch', 292 188 debug = false, 293 189 dryRun = false, 294 190 exportCore = true, ··· 322 218 ); 323 219 } 324 220 325 - const client = userConfig.client || inferClient(dependencies); 326 221 const schemas = getSchemas(userConfig); 327 222 const services = getServices(userConfig); 328 223 const types = getTypes(userConfig); ··· 353 248 * @param userConfig {@link UserConfig} passed to the `createClient()` method 354 249 */ 355 250 export async function createClient(userConfig: UserConfig): Promise<Client> { 356 - const dependencies = getInstalledDependencies(); 357 - 358 - if (!dependencies.typescript) { 359 - throw new Error('🚫 dependency missing - TypeScript must be installed'); 360 - } 361 - 362 - const config = await initConfig(userConfig, dependencies); 251 + const config = await initConfig(userConfig); 363 252 364 253 const openApi = 365 254 typeof config.input === 'string' ··· 371 260 372 261 if (!config.dryRun) { 373 262 logClientMessage(); 374 - logMissingDependenciesWarning(dependencies); 375 263 await writeClient(openApi, client, templates); 376 - processOutput(dependencies); 264 + processOutput(); 377 265 } 378 266 379 267 console.log('✨ Done! Your client is located in:', config.output.path);
+1 -1
packages/openapi-ts/src/types/config.ts
··· 5 5 */ 6 6 base?: string; 7 7 /** 8 - * The selected HTTP client (fetch, xhr, node or axios) 8 + * HTTP client to generate 9 9 * @default 'fetch' 10 10 */ 11 11 client?:
+1 -1
packages/openapi-ts/src/utils/getHttpRequestName.ts
··· 2 2 3 3 /** 4 4 * Generate the HttpRequest filename based on the selected client 5 - * @param client The selected HTTP client (fetch, xhr, node or axios) 5 + * @param client HTTP client to generate 6 6 */ 7 7 export const getHttpRequestName = (client: Config['client']): string => { 8 8 switch (client) {