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 #582 from hey-api/fix/types-req

fix: use generated types in request object instead of inlined duplicated paramschore: export enums in fetch example

authored by

Lubos and committed by
GitHub
a3b927a3 ad1aa5b6

+519 -2017
+5
.changeset/mean-experts-travel.md
··· 1 + --- 2 + "@hey-api/openapi-ts": patch 3 + --- 4 + 5 + fix: use generated types in request object instead of inlined duplicated params
+31 -31
packages/openapi-ts/src/compiler/module.ts
··· 3 3 import { 4 4 addLeadingJSDocComment, 5 5 type Comments, 6 - type ImportItemObject, 6 + type ImportExportItemObject, 7 7 ots, 8 8 } from './utils'; 9 9 ··· 20 20 ots.string(module), 21 21 ); 22 22 23 - type ImportItem = ImportItemObject | string; 23 + type ImportExportItem = ImportExportItemObject | string; 24 24 25 25 /** 26 26 * Create a named export declaration. Example: `export { X } from './y'`. ··· 29 29 * @returns ExportDeclaration 30 30 */ 31 31 export const createNamedExportDeclarations = ( 32 - items: Array<ImportItem> | ImportItem, 32 + items: Array<ImportExportItem> | ImportExportItem, 33 33 module: string, 34 34 ): ts.ExportDeclaration => { 35 35 items = Array.isArray(items) ? items : [items]; 36 - const isAllTypes = items.every((i) => typeof i === 'object' && i.isTypeOnly); 37 - return ts.factory.createExportDeclaration( 36 + const exportedTypes = Array.isArray(items) ? items : [items]; 37 + const hasNonTypeExport = exportedTypes.some( 38 + (item) => typeof item !== 'object' || !item.asType, 39 + ); 40 + const elements = items.map((name) => { 41 + const item = typeof name === 'string' ? { name } : name; 42 + return ots.export({ 43 + alias: item.alias, 44 + asType: hasNonTypeExport && item.asType, 45 + name: item.name, 46 + }); 47 + }); 48 + const exportClause = ts.factory.createNamedExports(elements); 49 + const moduleSpecifier = ots.string(module); 50 + const statement = ts.factory.createExportDeclaration( 38 51 undefined, 39 - isAllTypes, 40 - ts.factory.createNamedExports( 41 - items.map((item) => { 42 - const { 43 - name, 44 - isTypeOnly = undefined, 45 - alias = undefined, 46 - } = typeof item === 'string' ? { name: item } : item; 47 - return ots.export( 48 - name, 49 - isAllTypes ? false : Boolean(isTypeOnly), 50 - alias, 51 - ); 52 - }), 53 - ), 54 - ots.string(module), 52 + !hasNonTypeExport, 53 + exportClause, 54 + moduleSpecifier, 55 55 ); 56 + return statement; 56 57 }; 57 58 58 59 /** ··· 103 104 * @returns ImportDeclaration 104 105 */ 105 106 export const createNamedImportDeclarations = ( 106 - items: Array<ImportItem> | ImportItem, 107 + items: Array<ImportExportItem> | ImportExportItem, 107 108 module: string, 108 109 ): ts.ImportDeclaration => { 109 110 const importedTypes = Array.isArray(items) ? items : [items]; 110 - const isTypeOnly = !importedTypes.some( 111 - (item) => typeof item !== 'object' || !item.isTypeOnly, 111 + const hasNonTypeImport = importedTypes.some( 112 + (item) => typeof item !== 'object' || !item.asType, 112 113 ); 113 - const elements = importedTypes.map((item) => { 114 - const importedType: ImportItemObject = 115 - typeof item === 'string' ? { name: item } : item; 114 + const elements = importedTypes.map((name) => { 115 + const item = typeof name === 'string' ? { name } : name; 116 116 return ots.import({ 117 - alias: importedType.alias, 118 - isTypeOnly: isTypeOnly ? false : Boolean(importedType.isTypeOnly), 119 - name: importedType.name, 117 + alias: item.alias, 118 + asType: hasNonTypeImport && item.asType, 119 + name: item.name, 120 120 }); 121 121 }); 122 122 const namedBindings = ts.factory.createNamedImports(elements); 123 123 const importClause = ts.factory.createImportClause( 124 - isTypeOnly, 124 + !hasNonTypeImport, 125 125 undefined, 126 126 namedBindings, 127 127 );
+25 -16
packages/openapi-ts/src/compiler/utils.ts
··· 3 3 import { getConfig } from '../utils/config'; 4 4 import { unescapeName } from '../utils/escape'; 5 5 6 - export interface ImportItemObject { 6 + export interface ImportExportItemObject { 7 7 alias?: string; 8 - isTypeOnly?: boolean; 8 + asType?: boolean; 9 9 name: string; 10 10 } 11 11 ··· 81 81 return file.statements[0]; 82 82 } 83 83 84 - // ots for openapi-ts is helpers to reduce repetition of basic ts factory functions. 84 + /** 85 + * ots for openapi-ts are helpers to reduce repetition of basic TypeScript 86 + * factory functions. 87 + */ 85 88 export const ots = { 86 - // Create a boolean expression based on value. 89 + /** 90 + * Create a boolean expression based on value. 91 + */ 87 92 boolean: (value: boolean) => 88 93 value ? ts.factory.createTrue() : ts.factory.createFalse(), 89 - export: (name: string, isTypeOnly?: boolean, alias?: string) => { 90 - const n = ts.factory.createIdentifier(encodeURIComponent(name)); 91 - return ts.factory.createExportSpecifier( 92 - isTypeOnly ?? false, 93 - alias ? n : undefined, 94 - alias ? ts.factory.createIdentifier(encodeURIComponent(alias)) : n, 95 - ); 94 + export: ({ alias, asType = false, name }: ImportExportItemObject) => { 95 + const nameNode = ts.factory.createIdentifier(name); 96 + if (alias) { 97 + const aliasNode = ts.factory.createIdentifier(alias); 98 + return ts.factory.createExportSpecifier(asType, nameNode, aliasNode); 99 + } 100 + return ts.factory.createExportSpecifier(asType, undefined, nameNode); 96 101 }, 97 - import: ({ alias, isTypeOnly = false, name }: ImportItemObject) => { 102 + import: ({ alias, asType = false, name }: ImportExportItemObject) => { 98 103 const nameNode = ts.factory.createIdentifier(name); 99 104 if (alias) { 100 105 const aliasNode = ts.factory.createIdentifier(alias); 101 - return ts.factory.createImportSpecifier(isTypeOnly, nameNode, aliasNode); 106 + return ts.factory.createImportSpecifier(asType, nameNode, aliasNode); 102 107 } 103 - return ts.factory.createImportSpecifier(isTypeOnly, undefined, nameNode); 108 + return ts.factory.createImportSpecifier(asType, undefined, nameNode); 104 109 }, 105 - // Create a numeric expression, handling negative numbers. 110 + /** 111 + * Create a numeric expression, handling negative numbers. 112 + */ 106 113 number: (value: number) => { 107 114 if (value < 0) { 108 115 return ts.factory.createPrefixUnaryExpression( ··· 112 119 } 113 120 return ts.factory.createNumericLiteral(value); 114 121 }, 115 - // Create a string literal. This handles strings that start with '`' or "'". 122 + /** 123 + * Create a string literal. This handles strings that start with '`' or "'". 124 + */ 116 125 string: (value: string, unescape = false) => { 117 126 let text = value; 118 127 if (unescape) {
+2 -2
packages/openapi-ts/src/index.ts
··· 6 6 import { parse } from './openApi'; 7 7 import type { Client } from './types/client'; 8 8 import type { ClientConfig, Config, UserConfig } from './types/config'; 9 - import { getConfig, setConfig } from './utils/config'; 9 + import { getConfig, isStandaloneClient, setConfig } from './utils/config'; 10 10 import { getOpenApiSpec } from './utils/getOpenApiSpec'; 11 11 import { registerHandlebarTemplates } from './utils/handlebars'; 12 12 import { postProcessClient } from './utils/postprocess'; ··· 234 234 client, 235 235 debug, 236 236 dryRun, 237 - exportCore: client.startsWith('@hey-api') ? false : exportCore, 237 + exportCore: isStandaloneClient(client) ? false : exportCore, 238 238 input, 239 239 name, 240 240 output,
+12 -1
packages/openapi-ts/src/openApi/common/interfaces/client.ts
··· 31 31 code: number | 'default'; 32 32 } 33 33 34 + export type Method = 35 + | 'CONNECT' 36 + | 'DELETE' 37 + | 'GET' 38 + | 'HEAD' 39 + | 'OPTIONS' 40 + | 'PATCH' 41 + | 'POST' 42 + | 'PUT' 43 + | 'TRACE'; 44 + 34 45 export interface Operation extends OperationParameters { 35 46 deprecated: boolean; 36 47 description: string | null; 37 48 errors: OperationResponse[]; 38 - method: 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT'; 49 + method: Method; 39 50 /** 40 51 * Method name. Methods contain the request logic. 41 52 */
+7 -1
packages/openapi-ts/src/openApi/v2/parser/getServices.ts
··· 1 1 import type { Client } from '../../../types/client'; 2 + import { getConfig, isStandaloneClient } from '../../../utils/config'; 2 3 import { unique } from '../../../utils/unique'; 3 4 import type { Service } from '../../common/interfaces/client'; 4 5 import type { OpenApi } from '../interfaces/OpenApi'; ··· 15 16 openApi: OpenApi; 16 17 types: Client['types']; 17 18 }): Service[] => { 19 + const config = getConfig(); 20 + 18 21 const services = new Map<string, Service>(); 19 22 20 23 Object.entries(openApi.paths).forEach(([url, path]) => { ··· 37 40 case 'patch': { 38 41 // Each method contains an OpenAPI operation, we parse the operation 39 42 const op = path[method]!; 40 - const tags = op.tags?.length ? op.tags.filter(unique) : ['Default']; 43 + const tags = 44 + op.tags?.length && !isStandaloneClient(config) 45 + ? op.tags.filter(unique) 46 + : ['Default']; 41 47 tags.forEach((tag) => { 42 48 const operation = getOperation({ 43 49 method,
+1
packages/openapi-ts/src/openApi/v3/interfaces/OpenApiPath.ts
··· 6 6 * {@link} https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#path-item-object 7 7 */ 8 8 export interface OpenApiPath { 9 + connect?: OpenApiOperation; 9 10 delete?: OpenApiOperation; 10 11 description?: string; 11 12 get?: OpenApiOperation;
+9 -1
packages/openapi-ts/src/openApi/v3/parser/getServices.ts
··· 1 1 import type { Client } from '../../../types/client'; 2 + import { getConfig, isStandaloneClient } from '../../../utils/config'; 2 3 import { unique } from '../../../utils/unique'; 3 4 import type { Operation, Service } from '../../common/interfaces/client'; 4 5 import type { OpenApi } from '../interfaces/OpenApi'; ··· 6 7 import { getOperation } from './operation'; 7 8 8 9 const allowedServiceMethods = [ 10 + 'connect', 9 11 'delete', 10 12 'get', 11 13 'head', ··· 13 15 'patch', 14 16 'post', 15 17 'put', 18 + 'trace', 16 19 ] as const; 17 20 18 21 const getNewService = (operation: Operation): Service => ({ ··· 29 32 openApi: OpenApi; 30 33 types: Client['types']; 31 34 }): Service[] => { 35 + const config = getConfig(); 36 + 32 37 const services = new Map<string, Service>(); 33 38 34 39 for (const url in openApi.paths) { ··· 43 48 const method = key as Lowercase<Operation['method']>; 44 49 if (allowedServiceMethods.includes(method)) { 45 50 const op = path[method]!; 46 - const tags = op.tags?.length ? op.tags.filter(unique) : ['Default']; 51 + const tags = 52 + op.tags?.length && !isStandaloneClient(config) 53 + ? op.tags.filter(unique) 54 + : ['Default']; 47 55 tags.forEach((tag) => { 48 56 const operation = getOperation({ 49 57 method,
+5
packages/openapi-ts/src/utils/config.ts
··· 8 8 _config = config; 9 9 return getConfig(); 10 10 }; 11 + 12 + export const isStandaloneClient = (config: Config | Config['client']) => { 13 + const client = typeof config === 'string' ? config : config.client; 14 + return client.startsWith('@hey-api'); 15 + };
+2 -2
packages/openapi-ts/src/utils/write/index.ts
··· 17 17 if (config.services.response === 'response') { 18 18 files.index.add( 19 19 compiler.export.named( 20 - { isTypeOnly: true, name: 'ApiResult' }, 20 + { asType: true, name: 'ApiResult' }, 21 21 './core/ApiResult', 22 22 ), 23 23 ); ··· 37 37 } 38 38 files.index.add( 39 39 compiler.export.named( 40 - ['OpenAPI', { isTypeOnly: true, name: 'OpenAPIConfig' }], 40 + ['OpenAPI', { asType: true, name: 'OpenAPIConfig' }], 41 41 './core/OpenAPI', 42 42 ), 43 43 );
+112 -43
packages/openapi-ts/src/utils/write/services.ts
··· 2 2 3 3 import { 4 4 ClassElement, 5 + type Comments, 5 6 compiler, 6 7 FunctionParameter, 7 8 type Node, ··· 15 16 Service, 16 17 } from '../../openApi'; 17 18 import type { Client } from '../../types/client'; 18 - import { getConfig } from '../config'; 19 + import { getConfig, isStandaloneClient } from '../config'; 19 20 import { escapeComment, escapeName } from '../escape'; 20 21 import { transformServiceName } from '../transform'; 21 22 import { unique } from '../unique'; ··· 38 39 } 39 40 40 41 const { name } = uniqueTypeName({ meta, ...uniqueTypeNameArgs }); 41 - onImport(name); 42 + if (name) { 43 + onImport(name); 44 + } 42 45 }; 43 46 44 47 export const operationDataTypeName = (name: string) => 45 48 `${camelcase(name, { pascalCase: true })}Data`; 49 + 50 + export const operationErrorTypeName = (name: string) => 51 + `${camelcase(name, { pascalCase: true })}Error`; 46 52 47 53 export const operationResponseTypeName = (name: string) => 48 54 `${camelcase(name, { pascalCase: true })}Response`; ··· 51 57 client: Client, 52 58 operation: Operation, 53 59 ): FunctionParameter[] => { 54 - if (!operation.parameters.length) { 55 - return []; 56 - } 57 - 58 60 const config = getConfig(); 59 61 60 62 const { name: importedType } = uniqueTypeName({ ··· 68 70 nameTransformer: operationDataTypeName, 69 71 }); 70 72 71 - if (config.useOptions) { 72 - const isRequired = operation.parameters.some( 73 - (parameter) => parameter.isRequired, 74 - ); 73 + const isRequired = operation.parameters.some( 74 + (parameter) => parameter.isRequired, 75 + ); 76 + 77 + if (isStandaloneClient(config)) { 75 78 return [ 76 79 { 77 - default: isRequired ? undefined : {}, 78 - name: 'data', 79 - type: importedType, 80 + isRequired, 81 + name: 'options', 82 + type: importedType ? `Options<${importedType}>` : 'Options', 80 83 }, 81 84 ]; 82 85 } 83 86 87 + if (!operation.parameters.length) { 88 + return []; 89 + } 90 + 84 91 const getDefaultPrintable = ( 85 92 p: OperationParameter | Model, 86 93 ): string | undefined => { ··· 90 97 return JSON.stringify(p.default, null, 4); 91 98 }; 92 99 93 - return operation.parameters.map((p) => { 94 - const typePath = `${importedType}['${p.name}']`; 95 - return { 96 - default: p?.default, 97 - isRequired: (!p.isRequired && !getDefaultPrintable(p) ? '?' : '') === '', 98 - name: p.name, 99 - type: typePath, 100 - }; 101 - }); 100 + // legacy configuration 101 + if (!config.useOptions) { 102 + return operation.parameters.map((p) => { 103 + const typePath = `${importedType}['${p.name}']`; 104 + return { 105 + default: p?.default, 106 + isRequired: 107 + (!p.isRequired && !getDefaultPrintable(p) ? '?' : '') === '', 108 + name: p.name, 109 + type: typePath, 110 + }; 111 + }); 112 + } 113 + 114 + return [ 115 + { 116 + default: isRequired ? undefined : {}, 117 + name: 'data', 118 + type: importedType, 119 + }, 120 + ]; 102 121 }; 103 122 104 123 const toOperationReturnType = (client: Client, operation: Operation) => { ··· 136 155 return returnType; 137 156 }; 138 157 139 - const toOperationComment = (operation: Operation) => { 158 + const toOperationComment = (operation: Operation): Comments => { 140 159 const config = getConfig(); 160 + 161 + if (isStandaloneClient(config)) { 162 + const comment = [ 163 + operation.deprecated && '@deprecated', 164 + operation.summary && escapeComment(operation.summary), 165 + operation.description && escapeComment(operation.description), 166 + ]; 167 + return comment; 168 + } 169 + 141 170 let params: string[] = []; 171 + 142 172 if (operation.parameters.length) { 143 173 if (config.useOptions) { 144 174 params = [ 145 175 '@param data The data for the request.', 146 176 ...operation.parameters.map( 147 - (p) => 148 - `@param data.${p.name} ${p.description ? escapeComment(p.description) : ''}`, 177 + (parameter) => 178 + `@param data.${parameter.name} ${parameter.description ? escapeComment(parameter.description) : ''}`, 149 179 ), 150 180 ]; 151 181 } else { 152 182 params = operation.parameters.map( 153 - (p) => 154 - `@param ${p.name} ${p.description ? escapeComment(p.description) : ''}`, 183 + (parameter) => 184 + `@param ${parameter.name} ${parameter.description ? escapeComment(parameter.description) : ''}`, 155 185 ); 156 186 } 157 187 } 188 + 158 189 const comment = [ 159 190 operation.deprecated && '@deprecated', 160 191 operation.summary && escapeComment(operation.summary), ··· 172 203 const toRequestOptions = (operation: Operation) => { 173 204 const config = getConfig(); 174 205 175 - if (config.client.startsWith('@hey-api')) { 206 + if (isStandaloneClient(config)) { 176 207 const obj: ObjectValue[] = [ 177 208 { 178 - spread: 'data', 209 + spread: 'options', 179 210 }, 180 211 { 181 212 key: 'url', ··· 274 305 275 306 const options = toRequestOptions(operation); 276 307 277 - if (config.client.startsWith('@hey-api')) { 278 - const returnType = operation.results.length 308 + if (isStandaloneClient(config)) { 309 + const errorType = uniqueTypeName({ 310 + client, 311 + meta: { 312 + // TODO: this should be exact ref to operation for consistency, 313 + // but name should work too as operation ID is unique 314 + $ref: operation.name, 315 + name: operation.name, 316 + }, 317 + nameTransformer: operationErrorTypeName, 318 + }).name; 319 + const responseType = operation.results.length 279 320 ? uniqueTypeName({ 280 321 client, 281 322 meta: { ··· 291 332 compiler.return.functionCall({ 292 333 args: [options], 293 334 name: `client.${operation.method.toLocaleLowerCase()}`, 294 - types: [returnType], 335 + types: 336 + errorType && responseType 337 + ? [responseType, errorType] 338 + : errorType 339 + ? ['unknown', errorType] 340 + : responseType 341 + ? [responseType] 342 + : [], 295 343 }), 296 344 ]; 297 345 } ··· 345 393 }); 346 394 } 347 395 396 + if (isStandaloneClient(config)) { 397 + generateImport({ 398 + client, 399 + meta: { 400 + // TODO: this should be exact ref to operation for consistency, 401 + // but name should work too as operation ID is unique 402 + $ref: operation.name, 403 + name: operation.name, 404 + }, 405 + nameTransformer: operationErrorTypeName, 406 + onImport, 407 + }); 408 + } 409 + 410 + // TODO: improve response type detection 348 411 if (operation.results.length) { 349 412 generateImport({ 350 413 client, ··· 360 423 } 361 424 }); 362 425 363 - if (config.client.startsWith('@hey-api')) { 426 + if (isStandaloneClient(config)) { 364 427 service.operations.forEach((operation) => { 365 428 const expression = compiler.types.function({ 366 429 parameters: toOperationParamType(client, operation), ··· 460 523 } 461 524 462 525 // Import required packages and core files. 463 - if (config.client.startsWith('@hey-api')) { 464 - files.services?.addImport(['client'], config.client); 526 + if (isStandaloneClient(config)) { 527 + files.services?.addImport( 528 + [ 529 + 'client', 530 + { 531 + asType: true, 532 + name: 'Options', 533 + }, 534 + ], 535 + config.client, 536 + ); 465 537 } else { 466 538 if (config.client === 'angular') { 467 539 files.services?.addImport('Injectable', '@angular/core'); ··· 470 542 files.services?.addImport('HttpClient', '@angular/common/http'); 471 543 } 472 544 473 - files.services?.addImport( 474 - { isTypeOnly: true, name: 'Observable' }, 475 - 'rxjs', 476 - ); 545 + files.services?.addImport({ asType: true, name: 'Observable' }, 'rxjs'); 477 546 } else { 478 547 files.services?.addImport( 479 - { isTypeOnly: true, name: 'CancelablePromise' }, 548 + { asType: true, name: 'CancelablePromise' }, 480 549 './core/CancelablePromise', 481 550 ); 482 551 } 483 552 484 553 if (config.services.response === 'response') { 485 554 files.services?.addImport( 486 - { isTypeOnly: true, name: 'ApiResult' }, 555 + { asType: true, name: 'ApiResult' }, 487 556 './core/ApiResult', 488 557 ); 489 558 } 490 559 491 560 if (config.name) { 492 561 files.services?.addImport( 493 - { isTypeOnly: config.client !== 'angular', name: 'BaseHttpRequest' }, 562 + { asType: config.client !== 'angular', name: 'BaseHttpRequest' }, 494 563 './core/BaseHttpRequest', 495 564 ); 496 565 } else { ··· 506 575 if (files.types && !files.types.isEmpty()) { 507 576 const importedTypes = imports 508 577 .filter(unique) 509 - .map((name) => ({ isTypeOnly: true, name })); 578 + .map((name) => ({ asType: true, name })); 510 579 files.services?.addImport(importedTypes, `./${files.types.getName(false)}`); 511 580 } 512 581 };
+22 -7
packages/openapi-ts/src/utils/write/type.ts
··· 143 143 * Generates a unique name for the exported type for given model meta. 144 144 * @param args.client Internal client instance 145 145 * @param args.count Unique key for deduplication 146 + * @param args.create If a name record does not exist, should it be created? 146 147 * @param args.meta Meta property from the model 147 148 * @param args.nameTransformer Function for transforming name into the final 148 149 * value. In different contexts, a different strategy might be used. For ··· 153 154 export const uniqueTypeName = ({ 154 155 client, 155 156 count = 1, 157 + create = false, 156 158 meta, 157 159 nameTransformer, 158 160 }: Pick<Required<Model>, 'meta'> & { 159 161 client: Client; 160 162 count?: number; 163 + create?: boolean; 161 164 nameTransformer?: (value: string) => string; 162 165 }): UniqueTypeNameResult => { 163 166 let result: UniqueTypeNameResult = { 164 167 created: false, 165 - name: meta.name, 168 + name: '', 166 169 }; 170 + let name = meta.name; 167 171 if (nameTransformer) { 168 - result.name = nameTransformer(result.name); 172 + name = nameTransformer(name); 169 173 } 170 174 if (count > 1) { 171 - result.name = `${result.name}${count}`; 175 + name = `${name}${count}`; 172 176 } 173 - const type = client.types[result.name]; 177 + const type = client.types[name]; 174 178 if (!type) { 175 - client.types[result.name] = meta; 176 - result.created = true; 177 - } else if (type.$ref !== meta.$ref) { 179 + if (create) { 180 + client.types[name] = meta; 181 + result = { 182 + created: true, 183 + name, 184 + }; 185 + } 186 + } else if (type.$ref === meta.$ref) { 187 + result = { 188 + created: false, 189 + name, 190 + }; 191 + } else { 178 192 result = uniqueTypeName({ 179 193 client, 180 194 count: count + 1, 195 + create, 181 196 meta, 182 197 nameTransformer, 183 198 });
+144 -63
packages/openapi-ts/src/utils/write/types.ts
··· 4 4 type Node, 5 5 TypeScriptFile, 6 6 } from '../../compiler'; 7 - import type { Model, OperationParameter, Service } from '../../openApi'; 7 + import type { Model, OperationParameter } from '../../openApi'; 8 + import type { Method } from '../../openApi/common/interfaces/client'; 8 9 import type { Client } from '../../types/client'; 9 - import { getConfig } from '../config'; 10 + import { getConfig, isStandaloneClient } from '../config'; 10 11 import { enumEntry, enumUnionType } from '../enum'; 11 12 import { escapeComment } from '../escape'; 12 13 import { sortByName, sorterByName } from '../sort'; 13 - import { operationDataTypeName, operationResponseTypeName } from './services'; 14 + import { 15 + operationDataTypeName, 16 + operationErrorTypeName, 17 + operationResponseTypeName, 18 + } from './services'; 14 19 import { toType, uniqueTypeName } from './type'; 15 20 16 21 type OnNode = (node: Node) => void; ··· 53 58 return; 54 59 } 55 60 56 - const { created, name } = uniqueTypeName({ meta, ...uniqueTypeNameArgs }); 61 + const { created, name } = uniqueTypeName({ 62 + create: true, 63 + meta, 64 + ...uniqueTypeNameArgs, 65 + }); 57 66 if (created) { 58 67 const node = compiler.types.enum({ 59 68 comments, ··· 83 92 return; 84 93 } 85 94 86 - const { created, name } = uniqueTypeName({ meta, ...uniqueTypeNameArgs }); 95 + const { created, name } = uniqueTypeName({ 96 + create: true, 97 + meta, 98 + ...uniqueTypeNameArgs, 99 + }); 87 100 if (created) { 88 101 const node = compiler.typedef.alias({ comment, name, type }); 89 102 onNode(node); ··· 182 195 } 183 196 }; 184 197 185 - const processServiceTypes = (client: Client, onNode: OnNode) => { 186 - type ResMap = Map<number | 'default', Model>; 187 - type MethodMap = Map<'req' | 'res', ResMap | OperationParameter[]>; 188 - type MethodKey = Service['operations'][number]['method']; 189 - type PathMap = Map<MethodKey, MethodMap>; 198 + interface MethodMap { 199 + $ref?: string; 200 + req?: OperationParameter[]; 201 + res?: Record<number | string, Model>; 202 + } 203 + 204 + type PathMap = { 205 + [method in Method]?: MethodMap; 206 + }; 190 207 191 - const pathsMap = new Map<string, PathMap>(); 208 + type PathsMap = Record<string, PathMap>; 209 + 210 + const processServiceTypes = (client: Client, onNode: OnNode) => { 211 + const pathsMap: PathsMap = {}; 192 212 193 213 const config = getConfig(); 194 214 ··· 199 219 const hasErr = operation.errors.length; 200 220 201 221 if (hasReq || hasRes || hasErr) { 202 - let pathMap = pathsMap.get(operation.path); 203 - if (!pathMap) { 204 - pathsMap.set(operation.path, new Map()); 205 - pathMap = pathsMap.get(operation.path)!; 222 + if (!pathsMap[operation.path]) { 223 + pathsMap[operation.path] = {}; 206 224 } 225 + const pathMap = pathsMap[operation.path]!; 207 226 208 - let methodMap = pathMap.get(operation.method); 209 - if (!methodMap) { 210 - pathMap.set(operation.method, new Map()); 211 - methodMap = pathMap.get(operation.method)!; 227 + if (!pathMap[operation.method]) { 228 + pathMap[operation.method] = {}; 212 229 } 230 + const methodMap = pathMap[operation.method]!; 231 + methodMap.$ref = operation.name; 213 232 214 233 if (hasReq) { 215 234 const bodyParameter = operation.parameters ··· 263 282 .filter((parameter) => parameter.in === 'query') 264 283 .sort(sorterByName), 265 284 }; 266 - const operationProperties = config.client.startsWith('@hey-api') 285 + const operationProperties = isStandaloneClient(config) 267 286 ? [ 268 287 bodyParameters, 269 288 headerParameters, ··· 277 296 ) 278 297 : sortByName([...operation.parameters]); 279 298 280 - methodMap.set('req', operationProperties); 299 + methodMap.req = operationProperties; 281 300 282 301 // create type export for operation data 283 302 generateType({ ··· 299 318 } 300 319 301 320 if (hasRes) { 302 - let resMap = methodMap.get('res'); 303 - if (!resMap) { 304 - methodMap.set('res', new Map()); 305 - resMap = methodMap.get('res')!; 321 + if (!methodMap.res) { 322 + methodMap.res = {}; 306 323 } 307 324 308 - if (Array.isArray(resMap)) { 325 + if (Array.isArray(methodMap.res)) { 309 326 return; 310 327 } 311 328 312 329 operation.results.forEach((result) => { 313 - resMap.set(result.code, result); 330 + methodMap.res![result.code] = result; 314 331 }); 315 332 316 333 // create type export for operation response ··· 328 345 ...emptyModel, 329 346 export: 'any-of', 330 347 isRequired: true, 348 + // TODO: improve response type detection 331 349 properties: operation.results.filter( 332 350 (result) => 333 351 result.code === 'default' || ··· 335 353 ), 336 354 }), 337 355 }); 356 + 357 + if (isStandaloneClient(config)) { 358 + // TODO: improve error type detection 359 + const errorResults = operation.errors.filter( 360 + (result) => 361 + result.code === 'default' || 362 + (result.code >= 400 && result.code < 600), 363 + ); 364 + // create type export for operation error 365 + generateType({ 366 + client, 367 + meta: { 368 + // TODO: this should be exact ref to operation for consistency, 369 + // but name should work too as operation ID is unique 370 + $ref: operation.name, 371 + name: operation.name, 372 + }, 373 + nameTransformer: operationErrorTypeName, 374 + onNode, 375 + type: toType( 376 + errorResults.length 377 + ? { 378 + ...emptyModel, 379 + export: 'all-of', 380 + isRequired: true, 381 + properties: errorResults, 382 + } 383 + : { 384 + ...emptyModel, 385 + base: 'unknown', 386 + isRequired: true, 387 + type: 'unknown', 388 + }, 389 + ), 390 + }); 391 + } 338 392 } 339 393 340 394 if (hasErr) { 341 - let resMap = methodMap.get('res'); 342 - if (!resMap) { 343 - methodMap.set('res', new Map()); 344 - resMap = methodMap.get('res')!; 395 + if (!methodMap.res) { 396 + methodMap.res = {}; 345 397 } 346 398 347 - if (Array.isArray(resMap)) { 399 + if (Array.isArray(methodMap.res)) { 348 400 return; 349 401 } 350 402 351 403 operation.errors.forEach((error) => { 352 - resMap.set(error.code, error); 404 + methodMap.res![error.code] = error; 353 405 }); 354 406 } 355 407 } 356 408 }); 357 409 }); 358 410 359 - const properties = Array.from(pathsMap).map(([path, pathMap]) => { 360 - const pathParameters = Array.from(pathMap).map(([method, methodMap]) => { 361 - const methodParameters = Array.from(methodMap).map( 362 - ([name, baseOrResMap]) => { 363 - const reqResParameters = Array.isArray(baseOrResMap) 364 - ? baseOrResMap 365 - : Array.from(baseOrResMap).map(([code, base]) => { 366 - // TODO: move query params into separate query key 367 - const value: Model = { 368 - ...emptyModel, 369 - ...base, 370 - isRequired: true, 371 - name: String(code), 372 - }; 373 - return value; 374 - }); 411 + const properties = Object.entries(pathsMap).map(([path, pathMap]) => { 412 + const pathParameters = Object.entries(pathMap) 413 + .map(([_method, methodMap]) => { 414 + const method = _method as Method; 415 + 416 + let methodParameters: Model[] = []; 417 + 418 + if (methodMap.req) { 419 + const operationName = methodMap.$ref!; 420 + const { name: base } = uniqueTypeName({ 421 + client, 422 + meta: { 423 + // TODO: this should be exact ref to operation for consistency, 424 + // but name should work too as operation ID is unique 425 + $ref: operationName, 426 + name: operationName, 427 + }, 428 + nameTransformer: operationDataTypeName, 429 + }); 430 + const reqKey: Model = { 431 + ...emptyModel, 432 + base, 433 + export: 'reference', 434 + isRequired: true, 435 + name: 'req', 436 + properties: [], 437 + type: base, 438 + }; 439 + methodParameters = [...methodParameters, reqKey]; 440 + } 441 + 442 + if (methodMap.res) { 443 + const reqResParameters = Object.entries(methodMap.res).map( 444 + ([code, base]) => { 445 + // TODO: move query params into separate query key 446 + const value: Model = { 447 + ...emptyModel, 448 + ...base, 449 + isRequired: true, 450 + name: String(code), 451 + }; 452 + return value; 453 + }, 454 + ); 375 455 376 - const reqResKey: Model = { 456 + const resKey: Model = { 377 457 ...emptyModel, 378 458 isRequired: true, 379 - name, 459 + name: 'res', 380 460 properties: reqResParameters, 381 461 }; 382 - return reqResKey; 383 - }, 384 - ); 385 - const methodKey: Model = { 386 - ...emptyModel, 387 - isRequired: true, 388 - name: method.toLocaleLowerCase(), 389 - properties: methodParameters, 390 - }; 391 - return methodKey; 392 - }); 462 + methodParameters = [...methodParameters, resKey]; 463 + } 464 + 465 + const methodKey: Model = { 466 + ...emptyModel, 467 + isRequired: true, 468 + name: method.toLocaleLowerCase(), 469 + properties: methodParameters, 470 + }; 471 + return methodKey; 472 + }) 473 + .filter(Boolean); 393 474 const pathKey: Model = { 394 475 ...emptyModel, 395 476 isRequired: true, 396 477 name: `'${path}'`, 397 - properties: pathParameters, 478 + properties: pathParameters as Model[], 398 479 }; 399 480 return pathKey; 400 481 });
+15 -253
packages/openapi-ts/test/__snapshots__/test/generated/v2/types.gen.ts.snap
··· 729 729 export type $OpenApiTs = { 730 730 '/api/v{api-version}/descriptions/': { 731 731 post: { 732 - req: { 733 - /** 734 - * Testing backticks in string: `backticks` and ```multiple backticks``` should work 735 - */ 736 - parameterWithBackticks?: string; 737 - /** 738 - * Testing multiline comments in string: First line 739 - * Second line 740 - * 741 - * Fourth line 742 - */ 743 - parameterWithBreaks?: string; 744 - /** 745 - * Testing expression placeholders in string: ${expression} should work 746 - */ 747 - parameterWithExpressionPlaceholders?: string; 748 - /** 749 - * Testing quotes in string: 'single quote''' and "double quotes""" should work 750 - */ 751 - parameterWithQuotes?: string; 752 - /** 753 - * Testing reserved characters in string: * inline * and ** inline ** should work 754 - */ 755 - parameterWithReservedCharacters?: string; 756 - /** 757 - * Testing slashes in string: \backwards\\\ and /forwards/// should work 758 - */ 759 - parameterWithSlashes?: string; 760 - }; 732 + req: CallWithDescriptionsData; 761 733 }; 762 734 }; 763 735 '/api/v{api-version}/parameters/{parameterPath}': { 764 736 post: { 765 - req: { 766 - /** 767 - * This is the parameter that is sent as request body 768 - */ 769 - parameterBody: string; 770 - /** 771 - * This is the parameter that goes into the form data 772 - */ 773 - parameterForm: string; 774 - /** 775 - * This is the parameter that goes into the header 776 - */ 777 - parameterHeader: string; 778 - /** 779 - * This is the parameter that goes into the path 780 - */ 781 - parameterPath: string; 782 - /** 783 - * This is the parameter that goes into the query params 784 - */ 785 - parameterQuery: string; 786 - }; 737 + req: CallWithParametersData; 787 738 }; 788 739 }; 789 740 '/api/v{api-version}/parameters/{parameter.path.1}/{parameter-path-2}/{PARAMETER-PATH-3}': { 790 741 post: { 791 - req: { 792 - /** 793 - * This is the parameter with a reserved keyword 794 - */ 795 - _default?: string; 796 - /** 797 - * This is the parameter that is sent as request body 798 - */ 799 - parameterBody: string; 800 - /** 801 - * This is the parameter that goes into the request form data 802 - */ 803 - parameterForm: string; 804 - /** 805 - * This is the parameter that goes into the request header 806 - */ 807 - parameterHeader: string; 808 - /** 809 - * This is the parameter that goes into the path 810 - */ 811 - parameterPath1?: string; 812 - /** 813 - * This is the parameter that goes into the path 814 - */ 815 - parameterPath2?: string; 816 - /** 817 - * This is the parameter that goes into the path 818 - */ 819 - parameterPath3?: string; 820 - /** 821 - * This is the parameter that goes into the request query params 822 - */ 823 - parameterQuery: string; 824 - }; 742 + req: CallWithWeirdParameterNamesData; 825 743 }; 826 744 }; 827 745 '/api/v{api-version}/defaults': { 828 746 get: { 829 - req: { 830 - /** 831 - * This is a simple boolean with default value 832 - */ 833 - parameterBoolean: boolean; 834 - /** 835 - * This is a simple enum with default value 836 - */ 837 - parameterEnum: 'Success' | 'Warning' | 'Error'; 838 - /** 839 - * This is a simple model with default value 840 - */ 841 - parameterModel: ModelWithString; 842 - /** 843 - * This is a simple number with default value 844 - */ 845 - parameterNumber: number; 846 - /** 847 - * This is a simple string with default value 848 - */ 849 - parameterString: string; 850 - }; 747 + req: CallWithDefaultParametersData; 851 748 }; 852 749 post: { 853 - req: { 854 - /** 855 - * This is a simple boolean that is optional with default value 856 - */ 857 - parameterBoolean?: boolean; 858 - /** 859 - * This is a simple enum that is optional with default value 860 - */ 861 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 862 - /** 863 - * This is a simple model that is optional with default value 864 - */ 865 - parameterModel?: ModelWithString; 866 - /** 867 - * This is a simple number that is optional with default value 868 - */ 869 - parameterNumber?: number; 870 - /** 871 - * This is a simple string that is optional with default value 872 - */ 873 - parameterString?: string; 874 - }; 750 + req: CallWithDefaultOptionalParametersData; 875 751 }; 876 752 put: { 877 - req: { 878 - /** 879 - * This is a optional string with default 880 - */ 881 - parameterOptionalStringWithDefault?: string; 882 - /** 883 - * This is a optional string with empty default 884 - */ 885 - parameterOptionalStringWithEmptyDefault?: string; 886 - /** 887 - * This is a optional string with no default 888 - */ 889 - parameterOptionalStringWithNoDefault?: string; 890 - /** 891 - * This is a string that can be null with default 892 - */ 893 - parameterStringNullableWithDefault?: string | null; 894 - /** 895 - * This is a string that can be null with no default 896 - */ 897 - parameterStringNullableWithNoDefault?: string | null; 898 - /** 899 - * This is a string with default 900 - */ 901 - parameterStringWithDefault: string; 902 - /** 903 - * This is a string with empty default 904 - */ 905 - parameterStringWithEmptyDefault: string; 906 - /** 907 - * This is a string with no default 908 - */ 909 - parameterStringWithNoDefault: string; 910 - }; 753 + req: CallToTestOrderOfParamsData; 911 754 }; 912 755 }; 913 756 '/api/v{api-version}/no-content': { ··· 982 825 */ 983 826 202: ModelThatExtendsExtends; 984 827 /** 985 - * Message for default response 986 - */ 987 - default: ModelWithString; 988 - /** 989 828 * Message for 500 error 990 829 */ 991 830 500: ModelWithStringError; ··· 997 836 * Message for 502 error 998 837 */ 999 838 502: ModelWithStringError; 839 + /** 840 + * Message for default response 841 + */ 842 + default: ModelWithString; 1000 843 }; 1001 844 }; 1002 845 }; ··· 1022 865 }; 1023 866 '/api/v{api-version}/collectionFormat': { 1024 867 get: { 1025 - req: { 1026 - /** 1027 - * This is an array parameter that is sent as csv format (comma-separated values) 1028 - */ 1029 - parameterArrayCsv: Array<string>; 1030 - /** 1031 - * This is an array parameter that is sent as multi format (multiple parameter instances) 1032 - */ 1033 - parameterArrayMulti: Array<string>; 1034 - /** 1035 - * This is an array parameter that is sent as pipes format (pipe-separated values) 1036 - */ 1037 - parameterArrayPipes: Array<string>; 1038 - /** 1039 - * This is an array parameter that is sent as ssv format (space-separated values) 1040 - */ 1041 - parameterArraySsv: Array<string>; 1042 - /** 1043 - * This is an array parameter that is sent as tsv format (tab-separated values) 1044 - */ 1045 - parameterArrayTsv: Array<string>; 1046 - }; 868 + req: CollectionFormatData; 1047 869 }; 1048 870 }; 1049 871 '/api/v{api-version}/types': { 1050 872 get: { 1051 - req: { 1052 - /** 1053 - * This is a number parameter 1054 - */ 1055 - id?: number; 1056 - /** 1057 - * This is an array parameter 1058 - */ 1059 - parameterArray: Array<string>; 1060 - /** 1061 - * This is a boolean parameter 1062 - */ 1063 - parameterBoolean: boolean; 1064 - /** 1065 - * This is a dictionary parameter 1066 - */ 1067 - parameterDictionary: { 1068 - [key: string]: string; 1069 - }; 1070 - /** 1071 - * This is an enum parameter 1072 - */ 1073 - parameterEnum: 'Success' | 'Warning' | 'Error'; 1074 - /** 1075 - * This is a number parameter 1076 - */ 1077 - parameterNumber: number; 1078 - /** 1079 - * This is an object parameter 1080 - */ 1081 - parameterObject: unknown; 1082 - /** 1083 - * This is a string parameter 1084 - */ 1085 - parameterString: string; 1086 - }; 873 + req: TypesData; 1087 874 res: { 1088 875 /** 1089 876 * Response is a simple number ··· 1106 893 }; 1107 894 '/api/v{api-version}/complex': { 1108 895 get: { 1109 - req: { 1110 - /** 1111 - * Parameter containing object 1112 - */ 1113 - parameterObject: { 1114 - first?: { 1115 - second?: { 1116 - third?: string; 1117 - }; 1118 - }; 1119 - }; 1120 - /** 1121 - * Parameter containing reference 1122 - */ 1123 - parameterReference: ModelWithString; 1124 - }; 896 + req: ComplexTypesData; 1125 897 res: { 1126 898 /** 1127 899 * Successful response ··· 1158 930 }; 1159 931 '/api/v{api-version}/error': { 1160 932 post: { 1161 - req: { 1162 - /** 1163 - * Status code to return 1164 - */ 1165 - status: string; 1166 - }; 933 + req: TestErrorCodeData; 1167 934 res: { 1168 935 /** 1169 936 * Custom message: Successful response ··· 1190 957 }; 1191 958 '/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': { 1192 959 post: { 1193 - req: { 1194 - /** 1195 - * Dummy input param 1196 - */ 1197 - nonAsciiParamæøåÆøÅöôêÊ: number; 1198 - }; 960 + req: NonAsciiæøåÆøÅöôêÊ字符串Data; 1199 961 res: { 1200 962 /** 1201 963 * Successful response
+30 -360
packages/openapi-ts/test/__snapshots__/test/generated/v3/types.gen.ts.snap
··· 1412 1412 export type $OpenApiTs = { 1413 1413 '/api/v{api-version}/no-tag': { 1414 1414 post: { 1415 - req: { 1416 - requestBody: ModelWithReadOnlyAndWriteOnly | ModelWithArrayReadOnlyAndWriteOnly; 1417 - }; 1415 + req: PostServiceWithEmptyTagData; 1418 1416 res: { 1419 1417 default: ModelWithReadOnlyAndWriteOnly; 1420 1418 }; ··· 1432 1430 }; 1433 1431 '/api/v{api-version}/foo/{foo}/bar/{bar}': { 1434 1432 delete: { 1435 - req: { 1436 - /** 1437 - * bar in method 1438 - */ 1439 - bar: string; 1440 - /** 1441 - * foo in method 1442 - */ 1443 - foo: string; 1444 - }; 1433 + req: DeleteFooData3; 1445 1434 }; 1446 1435 }; 1447 1436 '/api/v{api-version}/parameters/{parameterPath}': { 1448 1437 post: { 1449 - req: { 1450 - fooAllOfEnum: ModelWithNestedArrayEnumsDataFoo; 1451 - fooRefEnum?: ModelWithNestedArrayEnumsDataFoo; 1452 - /** 1453 - * This is the parameter that goes into the cookie 1454 - */ 1455 - parameterCookie: string | null; 1456 - /** 1457 - * This is the parameter that goes into the form data 1458 - */ 1459 - parameterForm: string | null; 1460 - /** 1461 - * This is the parameter that goes into the header 1462 - */ 1463 - parameterHeader: string | null; 1464 - /** 1465 - * This is the parameter that goes into the path 1466 - */ 1467 - parameterPath: string | null; 1468 - /** 1469 - * This is the parameter that goes into the query params 1470 - */ 1471 - parameterQuery: string | null; 1472 - /** 1473 - * This is the parameter that goes into the body 1474 - */ 1475 - requestBody: ModelWithString | null; 1476 - }; 1438 + req: CallWithParametersData; 1477 1439 }; 1478 1440 }; 1479 1441 '/api/v{api-version}/parameters/{parameter.path.1}/{parameter-path-2}/{PARAMETER-PATH-3}': { 1480 1442 post: { 1481 - req: { 1482 - /** 1483 - * This is the parameter with a reserved keyword 1484 - */ 1485 - _default?: string; 1486 - /** 1487 - * This is the parameter that goes into the cookie 1488 - */ 1489 - parameterCookie: string | null; 1490 - /** 1491 - * This is the parameter that goes into the request form data 1492 - */ 1493 - parameterForm: string | null; 1494 - /** 1495 - * This is the parameter that goes into the request header 1496 - */ 1497 - parameterHeader: string | null; 1498 - /** 1499 - * This is the parameter that goes into the path 1500 - */ 1501 - parameterPath1?: string; 1502 - /** 1503 - * This is the parameter that goes into the path 1504 - */ 1505 - parameterPath2?: string; 1506 - /** 1507 - * This is the parameter that goes into the path 1508 - */ 1509 - parameterPath3?: string; 1510 - /** 1511 - * This is the parameter that goes into the request query params 1512 - */ 1513 - parameterQuery: string | null; 1514 - /** 1515 - * This is the parameter that goes into the body 1516 - */ 1517 - requestBody: ModelWithString | null; 1518 - }; 1443 + req: CallWithWeirdParameterNamesData; 1519 1444 }; 1520 1445 }; 1521 1446 '/api/v{api-version}/parameters/': { 1522 1447 get: { 1523 - req: { 1524 - /** 1525 - * This is an optional parameter 1526 - */ 1527 - parameter?: string; 1528 - /** 1529 - * This is a required parameter 1530 - */ 1531 - requestBody: ModelWithOneOfEnum; 1532 - }; 1448 + req: GetCallWithOptionalParamData; 1533 1449 }; 1534 1450 post: { 1535 - req: { 1536 - /** 1537 - * This is a required parameter 1538 - */ 1539 - parameter: Pageable; 1540 - /** 1541 - * This is an optional parameter 1542 - */ 1543 - requestBody?: ModelWithString; 1544 - }; 1451 + req: PostCallWithOptionalParamData; 1545 1452 }; 1546 1453 }; 1547 1454 '/api/v{api-version}/descriptions/': { 1548 1455 post: { 1549 - req: { 1550 - /** 1551 - * Testing backticks in string: `backticks` and ```multiple backticks``` should work 1552 - */ 1553 - parameterWithBackticks?: unknown; 1554 - /** 1555 - * Testing multiline comments in string: First line 1556 - * Second line 1557 - * 1558 - * Fourth line 1559 - */ 1560 - parameterWithBreaks?: unknown; 1561 - /** 1562 - * Testing expression placeholders in string: ${expression} should work 1563 - */ 1564 - parameterWithExpressionPlaceholders?: unknown; 1565 - /** 1566 - * Testing quotes in string: 'single quote''' and "double quotes""" should work 1567 - */ 1568 - parameterWithQuotes?: unknown; 1569 - /** 1570 - * Testing reserved characters in string: * inline * and ** inline ** should work 1571 - */ 1572 - parameterWithReservedCharacters?: unknown; 1573 - /** 1574 - * Testing slashes in string: \backwards\\\ and /forwards/// should work 1575 - */ 1576 - parameterWithSlashes?: unknown; 1577 - }; 1456 + req: CallWithDescriptionsData; 1578 1457 }; 1579 1458 }; 1580 1459 '/api/v{api-version}/parameters/deprecated': { 1581 1460 post: { 1582 - req: { 1583 - /** 1584 - * This parameter is deprecated 1585 - * @deprecated 1586 - */ 1587 - parameter: DeprecatedModel | null; 1588 - }; 1461 + req: DeprecatedCallData; 1589 1462 }; 1590 1463 }; 1591 1464 '/api/v{api-version}/requestBody/': { 1592 1465 post: { 1593 - req: { 1594 - /** 1595 - * A reusable request body 1596 - */ 1597 - foo?: ModelWithString; 1598 - /** 1599 - * This is a reusable parameter 1600 - */ 1601 - parameter?: string; 1602 - }; 1466 + req: PostApiRequestBodyData; 1603 1467 }; 1604 1468 }; 1605 1469 '/api/v{api-version}/formData/': { 1606 1470 post: { 1607 - req: { 1608 - /** 1609 - * A reusable request body 1610 - */ 1611 - formData?: ModelWithString; 1612 - /** 1613 - * This is a reusable parameter 1614 - */ 1615 - parameter?: string; 1616 - }; 1471 + req: PostApiFormDataData; 1617 1472 }; 1618 1473 }; 1619 1474 '/api/v{api-version}/defaults': { 1620 1475 get: { 1621 - req: { 1622 - /** 1623 - * This is a simple boolean with default value 1624 - */ 1625 - parameterBoolean?: boolean | null; 1626 - /** 1627 - * This is a simple enum with default value 1628 - */ 1629 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1630 - /** 1631 - * This is a simple model with default value 1632 - */ 1633 - parameterModel?: ModelWithString | null; 1634 - /** 1635 - * This is a simple number with default value 1636 - */ 1637 - parameterNumber?: number | null; 1638 - /** 1639 - * This is a simple string with default value 1640 - */ 1641 - parameterString?: string | null; 1642 - }; 1476 + req: CallWithDefaultParametersData; 1643 1477 }; 1644 1478 post: { 1645 - req: { 1646 - /** 1647 - * This is a simple boolean that is optional with default value 1648 - */ 1649 - parameterBoolean?: boolean; 1650 - /** 1651 - * This is a simple enum that is optional with default value 1652 - */ 1653 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1654 - /** 1655 - * This is a simple model that is optional with default value 1656 - */ 1657 - parameterModel?: ModelWithString; 1658 - /** 1659 - * This is a simple number that is optional with default value 1660 - */ 1661 - parameterNumber?: number; 1662 - /** 1663 - * This is a simple string that is optional with default value 1664 - */ 1665 - parameterString?: string; 1666 - }; 1479 + req: CallWithDefaultOptionalParametersData; 1667 1480 }; 1668 1481 put: { 1669 - req: { 1670 - /** 1671 - * This is a optional string with default 1672 - */ 1673 - parameterOptionalStringWithDefault?: string; 1674 - /** 1675 - * This is a optional string with empty default 1676 - */ 1677 - parameterOptionalStringWithEmptyDefault?: string; 1678 - /** 1679 - * This is a optional string with no default 1680 - */ 1681 - parameterOptionalStringWithNoDefault?: string; 1682 - /** 1683 - * This is a string that can be null with default 1684 - */ 1685 - parameterStringNullableWithDefault?: string | null; 1686 - /** 1687 - * This is a string that can be null with no default 1688 - */ 1689 - parameterStringNullableWithNoDefault?: string | null; 1690 - /** 1691 - * This is a string with default 1692 - */ 1693 - parameterStringWithDefault: string; 1694 - /** 1695 - * This is a string with empty default 1696 - */ 1697 - parameterStringWithEmptyDefault: string; 1698 - /** 1699 - * This is a string with no default 1700 - */ 1701 - parameterStringWithNoDefault: string; 1702 - }; 1482 + req: CallToTestOrderOfParamsData; 1703 1483 }; 1704 1484 }; 1705 1485 '/api/v{api-version}/no-content': { ··· 1743 1523 */ 1744 1524 201: ModelWithString; 1745 1525 /** 1746 - * Message for default response 1747 - */ 1748 - default: ModelWithBoolean; 1749 - /** 1750 1526 * Message for 500 error 1751 1527 */ 1752 1528 500: ModelWithStringError; ··· 1758 1534 * Message for 502 error 1759 1535 */ 1760 1536 502: ModelWithStringError; 1537 + /** 1538 + * Message for default response 1539 + */ 1540 + default: ModelWithBoolean; 1761 1541 }; 1762 1542 }; 1763 1543 put: { ··· 1779 1559 */ 1780 1560 202: ModelThatExtendsExtends; 1781 1561 /** 1782 - * Message for default response 1783 - */ 1784 - default: ModelWithString; 1785 - /** 1786 1562 * Message for 500 error 1787 1563 */ 1788 1564 500: ModelWithStringError; ··· 1794 1570 * Message for 502 error 1795 1571 */ 1796 1572 502: ModelWithStringError; 1573 + /** 1574 + * Message for default response 1575 + */ 1576 + default: ModelWithString; 1797 1577 }; 1798 1578 }; 1799 1579 }; ··· 1819 1599 }; 1820 1600 '/api/v{api-version}/collectionFormat': { 1821 1601 get: { 1822 - req: { 1823 - /** 1824 - * This is an array parameter that is sent as csv format (comma-separated values) 1825 - */ 1826 - parameterArrayCsv: Array<(string)> | null; 1827 - /** 1828 - * This is an array parameter that is sent as multi format (multiple parameter instances) 1829 - */ 1830 - parameterArrayMulti: Array<(string)> | null; 1831 - /** 1832 - * This is an array parameter that is sent as pipes format (pipe-separated values) 1833 - */ 1834 - parameterArrayPipes: Array<(string)> | null; 1835 - /** 1836 - * This is an array parameter that is sent as ssv format (space-separated values) 1837 - */ 1838 - parameterArraySsv: Array<(string)> | null; 1839 - /** 1840 - * This is an array parameter that is sent as tsv format (tab-separated values) 1841 - */ 1842 - parameterArrayTsv: Array<(string)> | null; 1843 - }; 1602 + req: CollectionFormatData; 1844 1603 }; 1845 1604 }; 1846 1605 '/api/v{api-version}/types': { 1847 1606 get: { 1848 - req: { 1849 - /** 1850 - * This is a number parameter 1851 - */ 1852 - id?: number; 1853 - /** 1854 - * This is an array parameter 1855 - */ 1856 - parameterArray: Array<(string)> | null; 1857 - /** 1858 - * This is a boolean parameter 1859 - */ 1860 - parameterBoolean: boolean | null; 1861 - /** 1862 - * This is a dictionary parameter 1863 - */ 1864 - parameterDictionary: { 1865 - [key: string]: unknown; 1866 - } | null; 1867 - /** 1868 - * This is an enum parameter 1869 - */ 1870 - parameterEnum: 'Success' | 'Warning' | 'Error' | null; 1871 - /** 1872 - * This is a number parameter 1873 - */ 1874 - parameterNumber: number; 1875 - /** 1876 - * This is an object parameter 1877 - */ 1878 - parameterObject: { 1879 - [key: string]: unknown; 1880 - } | null; 1881 - /** 1882 - * This is a string parameter 1883 - */ 1884 - parameterString: string | null; 1885 - }; 1607 + req: TypesData; 1886 1608 res: { 1887 1609 /** 1888 1610 * Response is a simple number ··· 1907 1629 }; 1908 1630 '/api/v{api-version}/upload': { 1909 1631 post: { 1910 - req: { 1911 - /** 1912 - * Supply a file reference for upload 1913 - */ 1914 - file: (Blob | File); 1915 - }; 1632 + req: UploadFileData; 1916 1633 res: { 1917 1634 200: boolean; 1918 1635 }; ··· 1920 1637 }; 1921 1638 '/api/v{api-version}/file/{id}': { 1922 1639 get: { 1923 - req: { 1924 - id: string; 1925 - }; 1640 + req: FileResponseData; 1926 1641 res: { 1927 1642 /** 1928 1643 * Success ··· 1933 1648 }; 1934 1649 '/api/v{api-version}/complex': { 1935 1650 get: { 1936 - req: { 1937 - /** 1938 - * Parameter containing object 1939 - */ 1940 - parameterObject: { 1941 - first?: { 1942 - second?: { 1943 - third?: string; 1944 - }; 1945 - }; 1946 - }; 1947 - /** 1948 - * Parameter containing reference 1949 - */ 1950 - parameterReference: ModelWithString; 1951 - }; 1651 + req: ComplexTypesData; 1952 1652 res: { 1953 1653 /** 1954 1654 * Successful response ··· 1967 1667 }; 1968 1668 '/api/v{api-version}/complex/{id}': { 1969 1669 put: { 1970 - req: { 1971 - id: number; 1972 - requestBody?: { 1973 - readonly key: string | null; 1974 - name: string | null; 1975 - enabled?: boolean; 1976 - readonly type: 'Monkey' | 'Horse' | 'Bird'; 1977 - listOfModels?: Array<ModelWithString> | null; 1978 - listOfStrings?: Array<(string)> | null; 1979 - parameters: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; 1980 - readonly user?: { 1981 - readonly id?: number; 1982 - readonly name?: string | null; 1983 - }; 1984 - }; 1985 - }; 1670 + req: ComplexParamsData; 1986 1671 res: { 1987 1672 /** 1988 1673 * Success ··· 1993 1678 }; 1994 1679 '/api/v{api-version}/multipart': { 1995 1680 post: { 1996 - req: { 1997 - formData?: { 1998 - content?: (Blob | File); 1999 - data?: ModelWithString | null; 2000 - }; 2001 - }; 1681 + req: MultipartRequestData; 2002 1682 }; 2003 1683 get: { 2004 1684 res: { ··· 2035 1715 }; 2036 1716 '/api/v{api-version}/error': { 2037 1717 post: { 2038 - req: { 2039 - /** 2040 - * Status code to return 2041 - */ 2042 - status: number; 2043 - }; 1718 + req: TestErrorCodeData; 2044 1719 res: { 2045 1720 /** 2046 1721 * Custom message: Successful response ··· 2067 1742 }; 2068 1743 '/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': { 2069 1744 post: { 2070 - req: { 2071 - /** 2072 - * Dummy input param 2073 - */ 2074 - nonAsciiParamæøåÆøÅöôêÊ: number; 2075 - }; 1745 + req: NonAsciiæøåÆøÅöôêÊ字符串Data; 2076 1746 res: { 2077 1747 /** 2078 1748 * Successful response
+30 -360
packages/openapi-ts/test/__snapshots__/test/generated/v3_angular/types.gen.ts.snap
··· 1289 1289 export type $OpenApiTs = { 1290 1290 '/api/v{api-version}/no-tag': { 1291 1291 post: { 1292 - req: { 1293 - requestBody: ModelWithReadOnlyAndWriteOnly | ModelWithArrayReadOnlyAndWriteOnly; 1294 - }; 1292 + req: PostServiceWithEmptyTagData; 1295 1293 res: { 1296 1294 default: ModelWithReadOnlyAndWriteOnly; 1297 1295 }; ··· 1309 1307 }; 1310 1308 '/api/v{api-version}/foo/{foo}/bar/{bar}': { 1311 1309 delete: { 1312 - req: { 1313 - /** 1314 - * bar in method 1315 - */ 1316 - bar: string; 1317 - /** 1318 - * foo in method 1319 - */ 1320 - foo: string; 1321 - }; 1310 + req: DeleteFooData3; 1322 1311 }; 1323 1312 }; 1324 1313 '/api/v{api-version}/parameters/{parameterPath}': { 1325 1314 post: { 1326 - req: { 1327 - fooAllOfEnum: ModelWithNestedArrayEnumsDataFoo; 1328 - fooRefEnum?: ModelWithNestedArrayEnumsDataFoo; 1329 - /** 1330 - * This is the parameter that goes into the cookie 1331 - */ 1332 - parameterCookie: string | null; 1333 - /** 1334 - * This is the parameter that goes into the form data 1335 - */ 1336 - parameterForm: string | null; 1337 - /** 1338 - * This is the parameter that goes into the header 1339 - */ 1340 - parameterHeader: string | null; 1341 - /** 1342 - * This is the parameter that goes into the path 1343 - */ 1344 - parameterPath: string | null; 1345 - /** 1346 - * This is the parameter that goes into the query params 1347 - */ 1348 - parameterQuery: string | null; 1349 - /** 1350 - * This is the parameter that goes into the body 1351 - */ 1352 - requestBody: ModelWithString | null; 1353 - }; 1315 + req: CallWithParametersData; 1354 1316 }; 1355 1317 }; 1356 1318 '/api/v{api-version}/parameters/{parameter.path.1}/{parameter-path-2}/{PARAMETER-PATH-3}': { 1357 1319 post: { 1358 - req: { 1359 - /** 1360 - * This is the parameter with a reserved keyword 1361 - */ 1362 - _default?: string; 1363 - /** 1364 - * This is the parameter that goes into the cookie 1365 - */ 1366 - parameterCookie: string | null; 1367 - /** 1368 - * This is the parameter that goes into the request form data 1369 - */ 1370 - parameterForm: string | null; 1371 - /** 1372 - * This is the parameter that goes into the request header 1373 - */ 1374 - parameterHeader: string | null; 1375 - /** 1376 - * This is the parameter that goes into the path 1377 - */ 1378 - parameterPath1?: string; 1379 - /** 1380 - * This is the parameter that goes into the path 1381 - */ 1382 - parameterPath2?: string; 1383 - /** 1384 - * This is the parameter that goes into the path 1385 - */ 1386 - parameterPath3?: string; 1387 - /** 1388 - * This is the parameter that goes into the request query params 1389 - */ 1390 - parameterQuery: string | null; 1391 - /** 1392 - * This is the parameter that goes into the body 1393 - */ 1394 - requestBody: ModelWithString | null; 1395 - }; 1320 + req: CallWithWeirdParameterNamesData; 1396 1321 }; 1397 1322 }; 1398 1323 '/api/v{api-version}/parameters/': { 1399 1324 get: { 1400 - req: { 1401 - /** 1402 - * This is an optional parameter 1403 - */ 1404 - parameter?: string; 1405 - /** 1406 - * This is a required parameter 1407 - */ 1408 - requestBody: ModelWithOneOfEnum; 1409 - }; 1325 + req: GetCallWithOptionalParamData; 1410 1326 }; 1411 1327 post: { 1412 - req: { 1413 - /** 1414 - * This is a required parameter 1415 - */ 1416 - parameter: Pageable; 1417 - /** 1418 - * This is an optional parameter 1419 - */ 1420 - requestBody?: ModelWithString; 1421 - }; 1328 + req: PostCallWithOptionalParamData; 1422 1329 }; 1423 1330 }; 1424 1331 '/api/v{api-version}/descriptions/': { 1425 1332 post: { 1426 - req: { 1427 - /** 1428 - * Testing backticks in string: `backticks` and ```multiple backticks``` should work 1429 - */ 1430 - parameterWithBackticks?: unknown; 1431 - /** 1432 - * Testing multiline comments in string: First line 1433 - * Second line 1434 - * 1435 - * Fourth line 1436 - */ 1437 - parameterWithBreaks?: unknown; 1438 - /** 1439 - * Testing expression placeholders in string: ${expression} should work 1440 - */ 1441 - parameterWithExpressionPlaceholders?: unknown; 1442 - /** 1443 - * Testing quotes in string: 'single quote''' and "double quotes""" should work 1444 - */ 1445 - parameterWithQuotes?: unknown; 1446 - /** 1447 - * Testing reserved characters in string: * inline * and ** inline ** should work 1448 - */ 1449 - parameterWithReservedCharacters?: unknown; 1450 - /** 1451 - * Testing slashes in string: \backwards\\\ and /forwards/// should work 1452 - */ 1453 - parameterWithSlashes?: unknown; 1454 - }; 1333 + req: CallWithDescriptionsData; 1455 1334 }; 1456 1335 }; 1457 1336 '/api/v{api-version}/parameters/deprecated': { 1458 1337 post: { 1459 - req: { 1460 - /** 1461 - * This parameter is deprecated 1462 - * @deprecated 1463 - */ 1464 - parameter: DeprecatedModel | null; 1465 - }; 1338 + req: DeprecatedCallData; 1466 1339 }; 1467 1340 }; 1468 1341 '/api/v{api-version}/requestBody/': { 1469 1342 post: { 1470 - req: { 1471 - /** 1472 - * A reusable request body 1473 - */ 1474 - foo?: ModelWithString; 1475 - /** 1476 - * This is a reusable parameter 1477 - */ 1478 - parameter?: string; 1479 - }; 1343 + req: PostApiRequestBodyData; 1480 1344 }; 1481 1345 }; 1482 1346 '/api/v{api-version}/formData/': { 1483 1347 post: { 1484 - req: { 1485 - /** 1486 - * A reusable request body 1487 - */ 1488 - formData?: ModelWithString; 1489 - /** 1490 - * This is a reusable parameter 1491 - */ 1492 - parameter?: string; 1493 - }; 1348 + req: PostApiFormDataData; 1494 1349 }; 1495 1350 }; 1496 1351 '/api/v{api-version}/defaults': { 1497 1352 get: { 1498 - req: { 1499 - /** 1500 - * This is a simple boolean with default value 1501 - */ 1502 - parameterBoolean?: boolean | null; 1503 - /** 1504 - * This is a simple enum with default value 1505 - */ 1506 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1507 - /** 1508 - * This is a simple model with default value 1509 - */ 1510 - parameterModel?: ModelWithString | null; 1511 - /** 1512 - * This is a simple number with default value 1513 - */ 1514 - parameterNumber?: number | null; 1515 - /** 1516 - * This is a simple string with default value 1517 - */ 1518 - parameterString?: string | null; 1519 - }; 1353 + req: CallWithDefaultParametersData; 1520 1354 }; 1521 1355 post: { 1522 - req: { 1523 - /** 1524 - * This is a simple boolean that is optional with default value 1525 - */ 1526 - parameterBoolean?: boolean; 1527 - /** 1528 - * This is a simple enum that is optional with default value 1529 - */ 1530 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1531 - /** 1532 - * This is a simple model that is optional with default value 1533 - */ 1534 - parameterModel?: ModelWithString; 1535 - /** 1536 - * This is a simple number that is optional with default value 1537 - */ 1538 - parameterNumber?: number; 1539 - /** 1540 - * This is a simple string that is optional with default value 1541 - */ 1542 - parameterString?: string; 1543 - }; 1356 + req: CallWithDefaultOptionalParametersData; 1544 1357 }; 1545 1358 put: { 1546 - req: { 1547 - /** 1548 - * This is a optional string with default 1549 - */ 1550 - parameterOptionalStringWithDefault?: string; 1551 - /** 1552 - * This is a optional string with empty default 1553 - */ 1554 - parameterOptionalStringWithEmptyDefault?: string; 1555 - /** 1556 - * This is a optional string with no default 1557 - */ 1558 - parameterOptionalStringWithNoDefault?: string; 1559 - /** 1560 - * This is a string that can be null with default 1561 - */ 1562 - parameterStringNullableWithDefault?: string | null; 1563 - /** 1564 - * This is a string that can be null with no default 1565 - */ 1566 - parameterStringNullableWithNoDefault?: string | null; 1567 - /** 1568 - * This is a string with default 1569 - */ 1570 - parameterStringWithDefault: string; 1571 - /** 1572 - * This is a string with empty default 1573 - */ 1574 - parameterStringWithEmptyDefault: string; 1575 - /** 1576 - * This is a string with no default 1577 - */ 1578 - parameterStringWithNoDefault: string; 1579 - }; 1359 + req: CallToTestOrderOfParamsData; 1580 1360 }; 1581 1361 }; 1582 1362 '/api/v{api-version}/no-content': { ··· 1620 1400 */ 1621 1401 201: ModelWithString; 1622 1402 /** 1623 - * Message for default response 1624 - */ 1625 - default: ModelWithBoolean; 1626 - /** 1627 1403 * Message for 500 error 1628 1404 */ 1629 1405 500: ModelWithStringError; ··· 1635 1411 * Message for 502 error 1636 1412 */ 1637 1413 502: ModelWithStringError; 1414 + /** 1415 + * Message for default response 1416 + */ 1417 + default: ModelWithBoolean; 1638 1418 }; 1639 1419 }; 1640 1420 put: { ··· 1656 1436 */ 1657 1437 202: ModelThatExtendsExtends; 1658 1438 /** 1659 - * Message for default response 1660 - */ 1661 - default: ModelWithString; 1662 - /** 1663 1439 * Message for 500 error 1664 1440 */ 1665 1441 500: ModelWithStringError; ··· 1671 1447 * Message for 502 error 1672 1448 */ 1673 1449 502: ModelWithStringError; 1450 + /** 1451 + * Message for default response 1452 + */ 1453 + default: ModelWithString; 1674 1454 }; 1675 1455 }; 1676 1456 }; ··· 1696 1476 }; 1697 1477 '/api/v{api-version}/collectionFormat': { 1698 1478 get: { 1699 - req: { 1700 - /** 1701 - * This is an array parameter that is sent as csv format (comma-separated values) 1702 - */ 1703 - parameterArrayCsv: Array<(string)> | null; 1704 - /** 1705 - * This is an array parameter that is sent as multi format (multiple parameter instances) 1706 - */ 1707 - parameterArrayMulti: Array<(string)> | null; 1708 - /** 1709 - * This is an array parameter that is sent as pipes format (pipe-separated values) 1710 - */ 1711 - parameterArrayPipes: Array<(string)> | null; 1712 - /** 1713 - * This is an array parameter that is sent as ssv format (space-separated values) 1714 - */ 1715 - parameterArraySsv: Array<(string)> | null; 1716 - /** 1717 - * This is an array parameter that is sent as tsv format (tab-separated values) 1718 - */ 1719 - parameterArrayTsv: Array<(string)> | null; 1720 - }; 1479 + req: CollectionFormatData; 1721 1480 }; 1722 1481 }; 1723 1482 '/api/v{api-version}/types': { 1724 1483 get: { 1725 - req: { 1726 - /** 1727 - * This is a number parameter 1728 - */ 1729 - id?: number; 1730 - /** 1731 - * This is an array parameter 1732 - */ 1733 - parameterArray: Array<(string)> | null; 1734 - /** 1735 - * This is a boolean parameter 1736 - */ 1737 - parameterBoolean: boolean | null; 1738 - /** 1739 - * This is a dictionary parameter 1740 - */ 1741 - parameterDictionary: { 1742 - [key: string]: unknown; 1743 - } | null; 1744 - /** 1745 - * This is an enum parameter 1746 - */ 1747 - parameterEnum: 'Success' | 'Warning' | 'Error' | null; 1748 - /** 1749 - * This is a number parameter 1750 - */ 1751 - parameterNumber: number; 1752 - /** 1753 - * This is an object parameter 1754 - */ 1755 - parameterObject: { 1756 - [key: string]: unknown; 1757 - } | null; 1758 - /** 1759 - * This is a string parameter 1760 - */ 1761 - parameterString: string | null; 1762 - }; 1484 + req: TypesData; 1763 1485 res: { 1764 1486 /** 1765 1487 * Response is a simple number ··· 1784 1506 }; 1785 1507 '/api/v{api-version}/upload': { 1786 1508 post: { 1787 - req: { 1788 - /** 1789 - * Supply a file reference for upload 1790 - */ 1791 - file: (Blob | File); 1792 - }; 1509 + req: UploadFileData; 1793 1510 res: { 1794 1511 200: boolean; 1795 1512 }; ··· 1797 1514 }; 1798 1515 '/api/v{api-version}/file/{id}': { 1799 1516 get: { 1800 - req: { 1801 - id: string; 1802 - }; 1517 + req: FileResponseData; 1803 1518 res: { 1804 1519 /** 1805 1520 * Success ··· 1810 1525 }; 1811 1526 '/api/v{api-version}/complex': { 1812 1527 get: { 1813 - req: { 1814 - /** 1815 - * Parameter containing object 1816 - */ 1817 - parameterObject: { 1818 - first?: { 1819 - second?: { 1820 - third?: string; 1821 - }; 1822 - }; 1823 - }; 1824 - /** 1825 - * Parameter containing reference 1826 - */ 1827 - parameterReference: ModelWithString; 1828 - }; 1528 + req: ComplexTypesData; 1829 1529 res: { 1830 1530 /** 1831 1531 * Successful response ··· 1844 1544 }; 1845 1545 '/api/v{api-version}/complex/{id}': { 1846 1546 put: { 1847 - req: { 1848 - id: number; 1849 - requestBody?: { 1850 - readonly key: string | null; 1851 - name: string | null; 1852 - enabled?: boolean; 1853 - readonly type: 'Monkey' | 'Horse' | 'Bird'; 1854 - listOfModels?: Array<ModelWithString> | null; 1855 - listOfStrings?: Array<(string)> | null; 1856 - parameters: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; 1857 - readonly user?: { 1858 - readonly id?: number; 1859 - readonly name?: string | null; 1860 - }; 1861 - }; 1862 - }; 1547 + req: ComplexParamsData; 1863 1548 res: { 1864 1549 /** 1865 1550 * Success ··· 1870 1555 }; 1871 1556 '/api/v{api-version}/multipart': { 1872 1557 post: { 1873 - req: { 1874 - formData?: { 1875 - content?: (Blob | File); 1876 - data?: ModelWithString | null; 1877 - }; 1878 - }; 1558 + req: MultipartRequestData; 1879 1559 }; 1880 1560 get: { 1881 1561 res: { ··· 1912 1592 }; 1913 1593 '/api/v{api-version}/error': { 1914 1594 post: { 1915 - req: { 1916 - /** 1917 - * Status code to return 1918 - */ 1919 - status: number; 1920 - }; 1595 + req: TestErrorCodeData; 1921 1596 res: { 1922 1597 /** 1923 1598 * Custom message: Successful response ··· 1944 1619 }; 1945 1620 '/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': { 1946 1621 post: { 1947 - req: { 1948 - /** 1949 - * Dummy input param 1950 - */ 1951 - nonAsciiParamæøåÆøÅöôêÊ: number; 1952 - }; 1622 + req: NonAsciiæøåÆøÅöôêÊ字符串Data; 1953 1623 res: { 1954 1624 /** 1955 1625 * Successful response
+30 -360
packages/openapi-ts/test/__snapshots__/test/generated/v3_client/types.gen.ts.snap
··· 1289 1289 export type $OpenApiTs = { 1290 1290 '/api/v{api-version}/no-tag': { 1291 1291 post: { 1292 - req: { 1293 - requestBody: ModelWithReadOnlyAndWriteOnly | ModelWithArrayReadOnlyAndWriteOnly; 1294 - }; 1292 + req: PostServiceWithEmptyTagData; 1295 1293 res: { 1296 1294 default: ModelWithReadOnlyAndWriteOnly; 1297 1295 }; ··· 1309 1307 }; 1310 1308 '/api/v{api-version}/foo/{foo}/bar/{bar}': { 1311 1309 delete: { 1312 - req: { 1313 - /** 1314 - * bar in method 1315 - */ 1316 - bar: string; 1317 - /** 1318 - * foo in method 1319 - */ 1320 - foo: string; 1321 - }; 1310 + req: DeleteFooData3; 1322 1311 }; 1323 1312 }; 1324 1313 '/api/v{api-version}/parameters/{parameterPath}': { 1325 1314 post: { 1326 - req: { 1327 - fooAllOfEnum: ModelWithNestedArrayEnumsDataFoo; 1328 - fooRefEnum?: ModelWithNestedArrayEnumsDataFoo; 1329 - /** 1330 - * This is the parameter that goes into the cookie 1331 - */ 1332 - parameterCookie: string | null; 1333 - /** 1334 - * This is the parameter that goes into the form data 1335 - */ 1336 - parameterForm: string | null; 1337 - /** 1338 - * This is the parameter that goes into the header 1339 - */ 1340 - parameterHeader: string | null; 1341 - /** 1342 - * This is the parameter that goes into the path 1343 - */ 1344 - parameterPath: string | null; 1345 - /** 1346 - * This is the parameter that goes into the query params 1347 - */ 1348 - parameterQuery: string | null; 1349 - /** 1350 - * This is the parameter that goes into the body 1351 - */ 1352 - requestBody: ModelWithString | null; 1353 - }; 1315 + req: CallWithParametersData; 1354 1316 }; 1355 1317 }; 1356 1318 '/api/v{api-version}/parameters/{parameter.path.1}/{parameter-path-2}/{PARAMETER-PATH-3}': { 1357 1319 post: { 1358 - req: { 1359 - /** 1360 - * This is the parameter with a reserved keyword 1361 - */ 1362 - _default?: string; 1363 - /** 1364 - * This is the parameter that goes into the cookie 1365 - */ 1366 - parameterCookie: string | null; 1367 - /** 1368 - * This is the parameter that goes into the request form data 1369 - */ 1370 - parameterForm: string | null; 1371 - /** 1372 - * This is the parameter that goes into the request header 1373 - */ 1374 - parameterHeader: string | null; 1375 - /** 1376 - * This is the parameter that goes into the path 1377 - */ 1378 - parameterPath1?: string; 1379 - /** 1380 - * This is the parameter that goes into the path 1381 - */ 1382 - parameterPath2?: string; 1383 - /** 1384 - * This is the parameter that goes into the path 1385 - */ 1386 - parameterPath3?: string; 1387 - /** 1388 - * This is the parameter that goes into the request query params 1389 - */ 1390 - parameterQuery: string | null; 1391 - /** 1392 - * This is the parameter that goes into the body 1393 - */ 1394 - requestBody: ModelWithString | null; 1395 - }; 1320 + req: CallWithWeirdParameterNamesData; 1396 1321 }; 1397 1322 }; 1398 1323 '/api/v{api-version}/parameters/': { 1399 1324 get: { 1400 - req: { 1401 - /** 1402 - * This is an optional parameter 1403 - */ 1404 - parameter?: string; 1405 - /** 1406 - * This is a required parameter 1407 - */ 1408 - requestBody: ModelWithOneOfEnum; 1409 - }; 1325 + req: GetCallWithOptionalParamData; 1410 1326 }; 1411 1327 post: { 1412 - req: { 1413 - /** 1414 - * This is a required parameter 1415 - */ 1416 - parameter: Pageable; 1417 - /** 1418 - * This is an optional parameter 1419 - */ 1420 - requestBody?: ModelWithString; 1421 - }; 1328 + req: PostCallWithOptionalParamData; 1422 1329 }; 1423 1330 }; 1424 1331 '/api/v{api-version}/descriptions/': { 1425 1332 post: { 1426 - req: { 1427 - /** 1428 - * Testing backticks in string: `backticks` and ```multiple backticks``` should work 1429 - */ 1430 - parameterWithBackticks?: unknown; 1431 - /** 1432 - * Testing multiline comments in string: First line 1433 - * Second line 1434 - * 1435 - * Fourth line 1436 - */ 1437 - parameterWithBreaks?: unknown; 1438 - /** 1439 - * Testing expression placeholders in string: ${expression} should work 1440 - */ 1441 - parameterWithExpressionPlaceholders?: unknown; 1442 - /** 1443 - * Testing quotes in string: 'single quote''' and "double quotes""" should work 1444 - */ 1445 - parameterWithQuotes?: unknown; 1446 - /** 1447 - * Testing reserved characters in string: * inline * and ** inline ** should work 1448 - */ 1449 - parameterWithReservedCharacters?: unknown; 1450 - /** 1451 - * Testing slashes in string: \backwards\\\ and /forwards/// should work 1452 - */ 1453 - parameterWithSlashes?: unknown; 1454 - }; 1333 + req: CallWithDescriptionsData; 1455 1334 }; 1456 1335 }; 1457 1336 '/api/v{api-version}/parameters/deprecated': { 1458 1337 post: { 1459 - req: { 1460 - /** 1461 - * This parameter is deprecated 1462 - * @deprecated 1463 - */ 1464 - parameter: DeprecatedModel | null; 1465 - }; 1338 + req: DeprecatedCallData; 1466 1339 }; 1467 1340 }; 1468 1341 '/api/v{api-version}/requestBody/': { 1469 1342 post: { 1470 - req: { 1471 - /** 1472 - * A reusable request body 1473 - */ 1474 - foo?: ModelWithString; 1475 - /** 1476 - * This is a reusable parameter 1477 - */ 1478 - parameter?: string; 1479 - }; 1343 + req: PostApiRequestBodyData; 1480 1344 }; 1481 1345 }; 1482 1346 '/api/v{api-version}/formData/': { 1483 1347 post: { 1484 - req: { 1485 - /** 1486 - * A reusable request body 1487 - */ 1488 - formData?: ModelWithString; 1489 - /** 1490 - * This is a reusable parameter 1491 - */ 1492 - parameter?: string; 1493 - }; 1348 + req: PostApiFormDataData; 1494 1349 }; 1495 1350 }; 1496 1351 '/api/v{api-version}/defaults': { 1497 1352 get: { 1498 - req: { 1499 - /** 1500 - * This is a simple boolean with default value 1501 - */ 1502 - parameterBoolean?: boolean | null; 1503 - /** 1504 - * This is a simple enum with default value 1505 - */ 1506 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1507 - /** 1508 - * This is a simple model with default value 1509 - */ 1510 - parameterModel?: ModelWithString | null; 1511 - /** 1512 - * This is a simple number with default value 1513 - */ 1514 - parameterNumber?: number | null; 1515 - /** 1516 - * This is a simple string with default value 1517 - */ 1518 - parameterString?: string | null; 1519 - }; 1353 + req: CallWithDefaultParametersData; 1520 1354 }; 1521 1355 post: { 1522 - req: { 1523 - /** 1524 - * This is a simple boolean that is optional with default value 1525 - */ 1526 - parameterBoolean?: boolean; 1527 - /** 1528 - * This is a simple enum that is optional with default value 1529 - */ 1530 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1531 - /** 1532 - * This is a simple model that is optional with default value 1533 - */ 1534 - parameterModel?: ModelWithString; 1535 - /** 1536 - * This is a simple number that is optional with default value 1537 - */ 1538 - parameterNumber?: number; 1539 - /** 1540 - * This is a simple string that is optional with default value 1541 - */ 1542 - parameterString?: string; 1543 - }; 1356 + req: CallWithDefaultOptionalParametersData; 1544 1357 }; 1545 1358 put: { 1546 - req: { 1547 - /** 1548 - * This is a optional string with default 1549 - */ 1550 - parameterOptionalStringWithDefault?: string; 1551 - /** 1552 - * This is a optional string with empty default 1553 - */ 1554 - parameterOptionalStringWithEmptyDefault?: string; 1555 - /** 1556 - * This is a optional string with no default 1557 - */ 1558 - parameterOptionalStringWithNoDefault?: string; 1559 - /** 1560 - * This is a string that can be null with default 1561 - */ 1562 - parameterStringNullableWithDefault?: string | null; 1563 - /** 1564 - * This is a string that can be null with no default 1565 - */ 1566 - parameterStringNullableWithNoDefault?: string | null; 1567 - /** 1568 - * This is a string with default 1569 - */ 1570 - parameterStringWithDefault: string; 1571 - /** 1572 - * This is a string with empty default 1573 - */ 1574 - parameterStringWithEmptyDefault: string; 1575 - /** 1576 - * This is a string with no default 1577 - */ 1578 - parameterStringWithNoDefault: string; 1579 - }; 1359 + req: CallToTestOrderOfParamsData; 1580 1360 }; 1581 1361 }; 1582 1362 '/api/v{api-version}/no-content': { ··· 1620 1400 */ 1621 1401 201: ModelWithString; 1622 1402 /** 1623 - * Message for default response 1624 - */ 1625 - default: ModelWithBoolean; 1626 - /** 1627 1403 * Message for 500 error 1628 1404 */ 1629 1405 500: ModelWithStringError; ··· 1635 1411 * Message for 502 error 1636 1412 */ 1637 1413 502: ModelWithStringError; 1414 + /** 1415 + * Message for default response 1416 + */ 1417 + default: ModelWithBoolean; 1638 1418 }; 1639 1419 }; 1640 1420 put: { ··· 1656 1436 */ 1657 1437 202: ModelThatExtendsExtends; 1658 1438 /** 1659 - * Message for default response 1660 - */ 1661 - default: ModelWithString; 1662 - /** 1663 1439 * Message for 500 error 1664 1440 */ 1665 1441 500: ModelWithStringError; ··· 1671 1447 * Message for 502 error 1672 1448 */ 1673 1449 502: ModelWithStringError; 1450 + /** 1451 + * Message for default response 1452 + */ 1453 + default: ModelWithString; 1674 1454 }; 1675 1455 }; 1676 1456 }; ··· 1696 1476 }; 1697 1477 '/api/v{api-version}/collectionFormat': { 1698 1478 get: { 1699 - req: { 1700 - /** 1701 - * This is an array parameter that is sent as csv format (comma-separated values) 1702 - */ 1703 - parameterArrayCsv: Array<(string)> | null; 1704 - /** 1705 - * This is an array parameter that is sent as multi format (multiple parameter instances) 1706 - */ 1707 - parameterArrayMulti: Array<(string)> | null; 1708 - /** 1709 - * This is an array parameter that is sent as pipes format (pipe-separated values) 1710 - */ 1711 - parameterArrayPipes: Array<(string)> | null; 1712 - /** 1713 - * This is an array parameter that is sent as ssv format (space-separated values) 1714 - */ 1715 - parameterArraySsv: Array<(string)> | null; 1716 - /** 1717 - * This is an array parameter that is sent as tsv format (tab-separated values) 1718 - */ 1719 - parameterArrayTsv: Array<(string)> | null; 1720 - }; 1479 + req: CollectionFormatData; 1721 1480 }; 1722 1481 }; 1723 1482 '/api/v{api-version}/types': { 1724 1483 get: { 1725 - req: { 1726 - /** 1727 - * This is a number parameter 1728 - */ 1729 - id?: number; 1730 - /** 1731 - * This is an array parameter 1732 - */ 1733 - parameterArray: Array<(string)> | null; 1734 - /** 1735 - * This is a boolean parameter 1736 - */ 1737 - parameterBoolean: boolean | null; 1738 - /** 1739 - * This is a dictionary parameter 1740 - */ 1741 - parameterDictionary: { 1742 - [key: string]: unknown; 1743 - } | null; 1744 - /** 1745 - * This is an enum parameter 1746 - */ 1747 - parameterEnum: 'Success' | 'Warning' | 'Error' | null; 1748 - /** 1749 - * This is a number parameter 1750 - */ 1751 - parameterNumber: number; 1752 - /** 1753 - * This is an object parameter 1754 - */ 1755 - parameterObject: { 1756 - [key: string]: unknown; 1757 - } | null; 1758 - /** 1759 - * This is a string parameter 1760 - */ 1761 - parameterString: string | null; 1762 - }; 1484 + req: TypesData; 1763 1485 res: { 1764 1486 /** 1765 1487 * Response is a simple number ··· 1784 1506 }; 1785 1507 '/api/v{api-version}/upload': { 1786 1508 post: { 1787 - req: { 1788 - /** 1789 - * Supply a file reference for upload 1790 - */ 1791 - file: (Blob | File); 1792 - }; 1509 + req: UploadFileData; 1793 1510 res: { 1794 1511 200: boolean; 1795 1512 }; ··· 1797 1514 }; 1798 1515 '/api/v{api-version}/file/{id}': { 1799 1516 get: { 1800 - req: { 1801 - id: string; 1802 - }; 1517 + req: FileResponseData; 1803 1518 res: { 1804 1519 /** 1805 1520 * Success ··· 1810 1525 }; 1811 1526 '/api/v{api-version}/complex': { 1812 1527 get: { 1813 - req: { 1814 - /** 1815 - * Parameter containing object 1816 - */ 1817 - parameterObject: { 1818 - first?: { 1819 - second?: { 1820 - third?: string; 1821 - }; 1822 - }; 1823 - }; 1824 - /** 1825 - * Parameter containing reference 1826 - */ 1827 - parameterReference: ModelWithString; 1828 - }; 1528 + req: ComplexTypesData; 1829 1529 res: { 1830 1530 /** 1831 1531 * Successful response ··· 1844 1544 }; 1845 1545 '/api/v{api-version}/complex/{id}': { 1846 1546 put: { 1847 - req: { 1848 - id: number; 1849 - requestBody?: { 1850 - readonly key: string | null; 1851 - name: string | null; 1852 - enabled?: boolean; 1853 - readonly type: 'Monkey' | 'Horse' | 'Bird'; 1854 - listOfModels?: Array<ModelWithString> | null; 1855 - listOfStrings?: Array<(string)> | null; 1856 - parameters: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; 1857 - readonly user?: { 1858 - readonly id?: number; 1859 - readonly name?: string | null; 1860 - }; 1861 - }; 1862 - }; 1547 + req: ComplexParamsData; 1863 1548 res: { 1864 1549 /** 1865 1550 * Success ··· 1870 1555 }; 1871 1556 '/api/v{api-version}/multipart': { 1872 1557 post: { 1873 - req: { 1874 - formData?: { 1875 - content?: (Blob | File); 1876 - data?: ModelWithString | null; 1877 - }; 1878 - }; 1558 + req: MultipartRequestData; 1879 1559 }; 1880 1560 get: { 1881 1561 res: { ··· 1912 1592 }; 1913 1593 '/api/v{api-version}/error': { 1914 1594 post: { 1915 - req: { 1916 - /** 1917 - * Status code to return 1918 - */ 1919 - status: number; 1920 - }; 1595 + req: TestErrorCodeData; 1921 1596 res: { 1922 1597 /** 1923 1598 * Custom message: Successful response ··· 1944 1619 }; 1945 1620 '/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': { 1946 1621 post: { 1947 - req: { 1948 - /** 1949 - * Dummy input param 1950 - */ 1951 - nonAsciiParamæøåÆøÅöôêÊ: number; 1952 - }; 1622 + req: NonAsciiæøåÆøÅöôêÊ字符串Data; 1953 1623 res: { 1954 1624 /** 1955 1625 * Successful response
+30 -360
packages/openapi-ts/test/__snapshots__/test/generated/v3_enums_typescript/types.gen.ts.snap
··· 1368 1368 export type $OpenApiTs = { 1369 1369 '/api/v{api-version}/no-tag': { 1370 1370 post: { 1371 - req: { 1372 - requestBody: ModelWithReadOnlyAndWriteOnly | ModelWithArrayReadOnlyAndWriteOnly; 1373 - }; 1371 + req: PostServiceWithEmptyTagData; 1374 1372 res: { 1375 1373 default: ModelWithReadOnlyAndWriteOnly; 1376 1374 }; ··· 1388 1386 }; 1389 1387 '/api/v{api-version}/foo/{foo}/bar/{bar}': { 1390 1388 delete: { 1391 - req: { 1392 - /** 1393 - * bar in method 1394 - */ 1395 - bar: string; 1396 - /** 1397 - * foo in method 1398 - */ 1399 - foo: string; 1400 - }; 1389 + req: DeleteFooData3; 1401 1390 }; 1402 1391 }; 1403 1392 '/api/v{api-version}/parameters/{parameterPath}': { 1404 1393 post: { 1405 - req: { 1406 - fooAllOfEnum: ModelWithNestedArrayEnumsDataFoo; 1407 - fooRefEnum?: ModelWithNestedArrayEnumsDataFoo; 1408 - /** 1409 - * This is the parameter that goes into the cookie 1410 - */ 1411 - parameterCookie: string | null; 1412 - /** 1413 - * This is the parameter that goes into the form data 1414 - */ 1415 - parameterForm: string | null; 1416 - /** 1417 - * This is the parameter that goes into the header 1418 - */ 1419 - parameterHeader: string | null; 1420 - /** 1421 - * This is the parameter that goes into the path 1422 - */ 1423 - parameterPath: string | null; 1424 - /** 1425 - * This is the parameter that goes into the query params 1426 - */ 1427 - parameterQuery: string | null; 1428 - /** 1429 - * This is the parameter that goes into the body 1430 - */ 1431 - requestBody: ModelWithString | null; 1432 - }; 1394 + req: CallWithParametersData; 1433 1395 }; 1434 1396 }; 1435 1397 '/api/v{api-version}/parameters/{parameter.path.1}/{parameter-path-2}/{PARAMETER-PATH-3}': { 1436 1398 post: { 1437 - req: { 1438 - /** 1439 - * This is the parameter with a reserved keyword 1440 - */ 1441 - _default?: string; 1442 - /** 1443 - * This is the parameter that goes into the cookie 1444 - */ 1445 - parameterCookie: string | null; 1446 - /** 1447 - * This is the parameter that goes into the request form data 1448 - */ 1449 - parameterForm: string | null; 1450 - /** 1451 - * This is the parameter that goes into the request header 1452 - */ 1453 - parameterHeader: string | null; 1454 - /** 1455 - * This is the parameter that goes into the path 1456 - */ 1457 - parameterPath1?: string; 1458 - /** 1459 - * This is the parameter that goes into the path 1460 - */ 1461 - parameterPath2?: string; 1462 - /** 1463 - * This is the parameter that goes into the path 1464 - */ 1465 - parameterPath3?: string; 1466 - /** 1467 - * This is the parameter that goes into the request query params 1468 - */ 1469 - parameterQuery: string | null; 1470 - /** 1471 - * This is the parameter that goes into the body 1472 - */ 1473 - requestBody: ModelWithString | null; 1474 - }; 1399 + req: CallWithWeirdParameterNamesData; 1475 1400 }; 1476 1401 }; 1477 1402 '/api/v{api-version}/parameters/': { 1478 1403 get: { 1479 - req: { 1480 - /** 1481 - * This is an optional parameter 1482 - */ 1483 - parameter?: string; 1484 - /** 1485 - * This is a required parameter 1486 - */ 1487 - requestBody: ModelWithOneOfEnum; 1488 - }; 1404 + req: GetCallWithOptionalParamData; 1489 1405 }; 1490 1406 post: { 1491 - req: { 1492 - /** 1493 - * This is a required parameter 1494 - */ 1495 - parameter: Pageable; 1496 - /** 1497 - * This is an optional parameter 1498 - */ 1499 - requestBody?: ModelWithString; 1500 - }; 1407 + req: PostCallWithOptionalParamData; 1501 1408 }; 1502 1409 }; 1503 1410 '/api/v{api-version}/descriptions/': { 1504 1411 post: { 1505 - req: { 1506 - /** 1507 - * Testing backticks in string: `backticks` and ```multiple backticks``` should work 1508 - */ 1509 - parameterWithBackticks?: unknown; 1510 - /** 1511 - * Testing multiline comments in string: First line 1512 - * Second line 1513 - * 1514 - * Fourth line 1515 - */ 1516 - parameterWithBreaks?: unknown; 1517 - /** 1518 - * Testing expression placeholders in string: ${expression} should work 1519 - */ 1520 - parameterWithExpressionPlaceholders?: unknown; 1521 - /** 1522 - * Testing quotes in string: 'single quote''' and "double quotes""" should work 1523 - */ 1524 - parameterWithQuotes?: unknown; 1525 - /** 1526 - * Testing reserved characters in string: * inline * and ** inline ** should work 1527 - */ 1528 - parameterWithReservedCharacters?: unknown; 1529 - /** 1530 - * Testing slashes in string: \backwards\\\ and /forwards/// should work 1531 - */ 1532 - parameterWithSlashes?: unknown; 1533 - }; 1412 + req: CallWithDescriptionsData; 1534 1413 }; 1535 1414 }; 1536 1415 '/api/v{api-version}/parameters/deprecated': { 1537 1416 post: { 1538 - req: { 1539 - /** 1540 - * This parameter is deprecated 1541 - * @deprecated 1542 - */ 1543 - parameter: DeprecatedModel | null; 1544 - }; 1417 + req: DeprecatedCallData; 1545 1418 }; 1546 1419 }; 1547 1420 '/api/v{api-version}/requestBody/': { 1548 1421 post: { 1549 - req: { 1550 - /** 1551 - * A reusable request body 1552 - */ 1553 - foo?: ModelWithString; 1554 - /** 1555 - * This is a reusable parameter 1556 - */ 1557 - parameter?: string; 1558 - }; 1422 + req: PostApiRequestBodyData; 1559 1423 }; 1560 1424 }; 1561 1425 '/api/v{api-version}/formData/': { 1562 1426 post: { 1563 - req: { 1564 - /** 1565 - * A reusable request body 1566 - */ 1567 - formData?: ModelWithString; 1568 - /** 1569 - * This is a reusable parameter 1570 - */ 1571 - parameter?: string; 1572 - }; 1427 + req: PostApiFormDataData; 1573 1428 }; 1574 1429 }; 1575 1430 '/api/v{api-version}/defaults': { 1576 1431 get: { 1577 - req: { 1578 - /** 1579 - * This is a simple boolean with default value 1580 - */ 1581 - parameterBoolean?: boolean | null; 1582 - /** 1583 - * This is a simple enum with default value 1584 - */ 1585 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1586 - /** 1587 - * This is a simple model with default value 1588 - */ 1589 - parameterModel?: ModelWithString | null; 1590 - /** 1591 - * This is a simple number with default value 1592 - */ 1593 - parameterNumber?: number | null; 1594 - /** 1595 - * This is a simple string with default value 1596 - */ 1597 - parameterString?: string | null; 1598 - }; 1432 + req: CallWithDefaultParametersData; 1599 1433 }; 1600 1434 post: { 1601 - req: { 1602 - /** 1603 - * This is a simple boolean that is optional with default value 1604 - */ 1605 - parameterBoolean?: boolean; 1606 - /** 1607 - * This is a simple enum that is optional with default value 1608 - */ 1609 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 1610 - /** 1611 - * This is a simple model that is optional with default value 1612 - */ 1613 - parameterModel?: ModelWithString; 1614 - /** 1615 - * This is a simple number that is optional with default value 1616 - */ 1617 - parameterNumber?: number; 1618 - /** 1619 - * This is a simple string that is optional with default value 1620 - */ 1621 - parameterString?: string; 1622 - }; 1435 + req: CallWithDefaultOptionalParametersData; 1623 1436 }; 1624 1437 put: { 1625 - req: { 1626 - /** 1627 - * This is a optional string with default 1628 - */ 1629 - parameterOptionalStringWithDefault?: string; 1630 - /** 1631 - * This is a optional string with empty default 1632 - */ 1633 - parameterOptionalStringWithEmptyDefault?: string; 1634 - /** 1635 - * This is a optional string with no default 1636 - */ 1637 - parameterOptionalStringWithNoDefault?: string; 1638 - /** 1639 - * This is a string that can be null with default 1640 - */ 1641 - parameterStringNullableWithDefault?: string | null; 1642 - /** 1643 - * This is a string that can be null with no default 1644 - */ 1645 - parameterStringNullableWithNoDefault?: string | null; 1646 - /** 1647 - * This is a string with default 1648 - */ 1649 - parameterStringWithDefault: string; 1650 - /** 1651 - * This is a string with empty default 1652 - */ 1653 - parameterStringWithEmptyDefault: string; 1654 - /** 1655 - * This is a string with no default 1656 - */ 1657 - parameterStringWithNoDefault: string; 1658 - }; 1438 + req: CallToTestOrderOfParamsData; 1659 1439 }; 1660 1440 }; 1661 1441 '/api/v{api-version}/no-content': { ··· 1699 1479 */ 1700 1480 201: ModelWithString; 1701 1481 /** 1702 - * Message for default response 1703 - */ 1704 - default: ModelWithBoolean; 1705 - /** 1706 1482 * Message for 500 error 1707 1483 */ 1708 1484 500: ModelWithStringError; ··· 1714 1490 * Message for 502 error 1715 1491 */ 1716 1492 502: ModelWithStringError; 1493 + /** 1494 + * Message for default response 1495 + */ 1496 + default: ModelWithBoolean; 1717 1497 }; 1718 1498 }; 1719 1499 put: { ··· 1735 1515 */ 1736 1516 202: ModelThatExtendsExtends; 1737 1517 /** 1738 - * Message for default response 1739 - */ 1740 - default: ModelWithString; 1741 - /** 1742 1518 * Message for 500 error 1743 1519 */ 1744 1520 500: ModelWithStringError; ··· 1750 1526 * Message for 502 error 1751 1527 */ 1752 1528 502: ModelWithStringError; 1529 + /** 1530 + * Message for default response 1531 + */ 1532 + default: ModelWithString; 1753 1533 }; 1754 1534 }; 1755 1535 }; ··· 1775 1555 }; 1776 1556 '/api/v{api-version}/collectionFormat': { 1777 1557 get: { 1778 - req: { 1779 - /** 1780 - * This is an array parameter that is sent as csv format (comma-separated values) 1781 - */ 1782 - parameterArrayCsv: Array<(string)> | null; 1783 - /** 1784 - * This is an array parameter that is sent as multi format (multiple parameter instances) 1785 - */ 1786 - parameterArrayMulti: Array<(string)> | null; 1787 - /** 1788 - * This is an array parameter that is sent as pipes format (pipe-separated values) 1789 - */ 1790 - parameterArrayPipes: Array<(string)> | null; 1791 - /** 1792 - * This is an array parameter that is sent as ssv format (space-separated values) 1793 - */ 1794 - parameterArraySsv: Array<(string)> | null; 1795 - /** 1796 - * This is an array parameter that is sent as tsv format (tab-separated values) 1797 - */ 1798 - parameterArrayTsv: Array<(string)> | null; 1799 - }; 1558 + req: CollectionFormatData; 1800 1559 }; 1801 1560 }; 1802 1561 '/api/v{api-version}/types': { 1803 1562 get: { 1804 - req: { 1805 - /** 1806 - * This is a number parameter 1807 - */ 1808 - id?: number; 1809 - /** 1810 - * This is an array parameter 1811 - */ 1812 - parameterArray: Array<(string)> | null; 1813 - /** 1814 - * This is a boolean parameter 1815 - */ 1816 - parameterBoolean: boolean | null; 1817 - /** 1818 - * This is a dictionary parameter 1819 - */ 1820 - parameterDictionary: { 1821 - [key: string]: unknown; 1822 - } | null; 1823 - /** 1824 - * This is an enum parameter 1825 - */ 1826 - parameterEnum: 'Success' | 'Warning' | 'Error' | null; 1827 - /** 1828 - * This is a number parameter 1829 - */ 1830 - parameterNumber: number; 1831 - /** 1832 - * This is an object parameter 1833 - */ 1834 - parameterObject: { 1835 - [key: string]: unknown; 1836 - } | null; 1837 - /** 1838 - * This is a string parameter 1839 - */ 1840 - parameterString: string | null; 1841 - }; 1563 + req: TypesData; 1842 1564 res: { 1843 1565 /** 1844 1566 * Response is a simple number ··· 1863 1585 }; 1864 1586 '/api/v{api-version}/upload': { 1865 1587 post: { 1866 - req: { 1867 - /** 1868 - * Supply a file reference for upload 1869 - */ 1870 - file: (Blob | File); 1871 - }; 1588 + req: UploadFileData; 1872 1589 res: { 1873 1590 200: boolean; 1874 1591 }; ··· 1876 1593 }; 1877 1594 '/api/v{api-version}/file/{id}': { 1878 1595 get: { 1879 - req: { 1880 - id: string; 1881 - }; 1596 + req: FileResponseData; 1882 1597 res: { 1883 1598 /** 1884 1599 * Success ··· 1889 1604 }; 1890 1605 '/api/v{api-version}/complex': { 1891 1606 get: { 1892 - req: { 1893 - /** 1894 - * Parameter containing object 1895 - */ 1896 - parameterObject: { 1897 - first?: { 1898 - second?: { 1899 - third?: string; 1900 - }; 1901 - }; 1902 - }; 1903 - /** 1904 - * Parameter containing reference 1905 - */ 1906 - parameterReference: ModelWithString; 1907 - }; 1607 + req: ComplexTypesData; 1908 1608 res: { 1909 1609 /** 1910 1610 * Successful response ··· 1923 1623 }; 1924 1624 '/api/v{api-version}/complex/{id}': { 1925 1625 put: { 1926 - req: { 1927 - id: number; 1928 - requestBody?: { 1929 - readonly key: string | null; 1930 - name: string | null; 1931 - enabled?: boolean; 1932 - readonly type: 'Monkey' | 'Horse' | 'Bird'; 1933 - listOfModels?: Array<ModelWithString> | null; 1934 - listOfStrings?: Array<(string)> | null; 1935 - parameters: ModelWithString | ModelWithEnum | ModelWithArray | ModelWithDictionary; 1936 - readonly user?: { 1937 - readonly id?: number; 1938 - readonly name?: string | null; 1939 - }; 1940 - }; 1941 - }; 1626 + req: ComplexParamsData; 1942 1627 res: { 1943 1628 /** 1944 1629 * Success ··· 1949 1634 }; 1950 1635 '/api/v{api-version}/multipart': { 1951 1636 post: { 1952 - req: { 1953 - formData?: { 1954 - content?: (Blob | File); 1955 - data?: ModelWithString | null; 1956 - }; 1957 - }; 1637 + req: MultipartRequestData; 1958 1638 }; 1959 1639 get: { 1960 1640 res: { ··· 1991 1671 }; 1992 1672 '/api/v{api-version}/error': { 1993 1673 post: { 1994 - req: { 1995 - /** 1996 - * Status code to return 1997 - */ 1998 - status: number; 1999 - }; 1674 + req: TestErrorCodeData; 2000 1675 res: { 2001 1676 /** 2002 1677 * Custom message: Successful response ··· 2023 1698 }; 2024 1699 '/api/v{api-version}/non-ascii-æøåÆØÅöôêÊ字符串': { 2025 1700 post: { 2026 - req: { 2027 - /** 2028 - * Dummy input param 2029 - */ 2030 - nonAsciiParamæøåÆøÅöôêÊ: number; 2031 - }; 1701 + req: NonAsciiæøåÆøÅöôêÊ字符串Data; 2032 1702 res: { 2033 1703 /** 2034 1704 * Successful response
+4 -79
packages/openapi-ts/test/__snapshots__/test/generated/v3_legacy_positional_args/types.gen.ts.snap
··· 104 104 export type $OpenApiTs = { 105 105 '/api/v{api-version}/defaults': { 106 106 get: { 107 - req: { 108 - /** 109 - * This is a simple boolean with default value 110 - */ 111 - parameterBoolean?: boolean | null; 112 - /** 113 - * This is a simple enum with default value 114 - */ 115 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 116 - /** 117 - * This is a simple model with default value 118 - */ 119 - parameterModel?: ModelWithString | null; 120 - /** 121 - * This is a simple number with default value 122 - */ 123 - parameterNumber?: number | null; 124 - /** 125 - * This is a simple string with default value 126 - */ 127 - parameterString?: string | null; 128 - }; 107 + req: CallWithDefaultParametersData; 129 108 }; 130 109 post: { 131 - req: { 132 - /** 133 - * This is a simple boolean that is optional with default value 134 - */ 135 - parameterBoolean?: boolean; 136 - /** 137 - * This is a simple enum that is optional with default value 138 - */ 139 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 140 - /** 141 - * This is a simple model that is optional with default value 142 - */ 143 - parameterModel?: ModelWithString; 144 - /** 145 - * This is a simple number that is optional with default value 146 - */ 147 - parameterNumber?: number; 148 - /** 149 - * This is a simple string that is optional with default value 150 - */ 151 - parameterString?: string; 152 - }; 110 + req: CallWithDefaultOptionalParametersData; 153 111 }; 154 112 put: { 155 - req: { 156 - /** 157 - * This is a optional string with default 158 - */ 159 - parameterOptionalStringWithDefault?: string; 160 - /** 161 - * This is a optional string with empty default 162 - */ 163 - parameterOptionalStringWithEmptyDefault?: string; 164 - /** 165 - * This is a optional string with no default 166 - */ 167 - parameterOptionalStringWithNoDefault?: string; 168 - /** 169 - * This is a string that can be null with default 170 - */ 171 - parameterStringNullableWithDefault?: string | null; 172 - /** 173 - * This is a string that can be null with no default 174 - */ 175 - parameterStringNullableWithNoDefault?: string | null; 176 - /** 177 - * This is a string with default 178 - */ 179 - parameterStringWithDefault: string; 180 - /** 181 - * This is a string with empty default 182 - */ 183 - parameterStringWithEmptyDefault: string; 184 - /** 185 - * This is a string with no default 186 - */ 187 - parameterStringWithNoDefault: string; 188 - }; 113 + req: CallToTestOrderOfParamsData; 189 114 }; 190 115 }; 191 - }; 116 + };
+3 -78
packages/openapi-ts/test/__snapshots__/test/generated/v3_options/types.gen.ts.snap
··· 104 104 export type $OpenApiTs = { 105 105 '/api/v{api-version}/defaults': { 106 106 get: { 107 - req: { 108 - /** 109 - * This is a simple boolean with default value 110 - */ 111 - parameterBoolean?: boolean | null; 112 - /** 113 - * This is a simple enum with default value 114 - */ 115 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 116 - /** 117 - * This is a simple model with default value 118 - */ 119 - parameterModel?: ModelWithString | null; 120 - /** 121 - * This is a simple number with default value 122 - */ 123 - parameterNumber?: number | null; 124 - /** 125 - * This is a simple string with default value 126 - */ 127 - parameterString?: string | null; 128 - }; 107 + req: CallWithDefaultParametersData; 129 108 }; 130 109 post: { 131 - req: { 132 - /** 133 - * This is a simple boolean that is optional with default value 134 - */ 135 - parameterBoolean?: boolean; 136 - /** 137 - * This is a simple enum that is optional with default value 138 - */ 139 - parameterEnum?: 'Success' | 'Warning' | 'Error'; 140 - /** 141 - * This is a simple model that is optional with default value 142 - */ 143 - parameterModel?: ModelWithString; 144 - /** 145 - * This is a simple number that is optional with default value 146 - */ 147 - parameterNumber?: number; 148 - /** 149 - * This is a simple string that is optional with default value 150 - */ 151 - parameterString?: string; 152 - }; 110 + req: CallWithDefaultOptionalParametersData; 153 111 }; 154 112 put: { 155 - req: { 156 - /** 157 - * This is a optional string with default 158 - */ 159 - parameterOptionalStringWithDefault?: string; 160 - /** 161 - * This is a optional string with empty default 162 - */ 163 - parameterOptionalStringWithEmptyDefault?: string; 164 - /** 165 - * This is a optional string with no default 166 - */ 167 - parameterOptionalStringWithNoDefault?: string; 168 - /** 169 - * This is a string that can be null with default 170 - */ 171 - parameterStringNullableWithDefault?: string | null; 172 - /** 173 - * This is a string that can be null with no default 174 - */ 175 - parameterStringNullableWithNoDefault?: string | null; 176 - /** 177 - * This is a string with default 178 - */ 179 - parameterStringWithDefault: string; 180 - /** 181 - * This is a string with empty default 182 - */ 183 - parameterStringWithEmptyDefault: string; 184 - /** 185 - * This is a string with no default 186 - */ 187 - parameterStringWithNoDefault: string; 188 - }; 113 + req: CallToTestOrderOfParamsData; 189 114 }; 190 115 }; 191 116 };