Skip to content

Commit 36b21dc

Browse files
committed
feat(OpenAPI 3.1.0): add new schema for 3.1.0
This involved breaking 2 and 3 out a little to better mirror the differences in the specs
1 parent 0c53697 commit 36b21dc

File tree

12 files changed

+217
-118
lines changed

12 files changed

+217
-118
lines changed

packages/cli/src/swagger/specGenerator.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { Tsoa, assertNever, Swagger } from '@tsoa/runtime';
33
import * as handlebars from 'handlebars';
44

55
export abstract class SpecGenerator {
6-
constructor(protected readonly metadata: Tsoa.Metadata, protected readonly config: ExtendedSpecConfig) {}
6+
constructor(
7+
protected readonly metadata: Tsoa.Metadata,
8+
protected readonly config: ExtendedSpecConfig,
9+
) {}
710

811
protected buildAdditionalProperties(type: Tsoa.Type) {
912
return this.getSwaggerType(type);
@@ -59,7 +62,7 @@ export abstract class SpecGenerator {
5962
}
6063
}
6164

62-
protected getSwaggerType(type: Tsoa.Type, title?: string): Swagger.Schema | Swagger.BaseSchema {
65+
protected getSwaggerType(type: Tsoa.Type, title?: string): Swagger.BaseSchema {
6366
if (type.dataType === 'void' || type.dataType === 'undefined') {
6467
return this.getSwaggerTypeForVoid(type.dataType);
6568
} else if (type.dataType === 'refEnum' || type.dataType === 'refObject' || type.dataType === 'refAlias') {
@@ -96,13 +99,13 @@ export abstract class SpecGenerator {
9699
}
97100
}
98101

99-
protected abstract getSwaggerTypeForUnionType(type: Tsoa.UnionType, title?: string): Swagger.Schema | Swagger.BaseSchema;
102+
protected abstract getSwaggerTypeForUnionType(type: Tsoa.UnionType, title?: string): Swagger.BaseSchema;
100103

101-
protected abstract getSwaggerTypeForIntersectionType(type: Tsoa.IntersectionType, title?: string): Swagger.Schema | Swagger.BaseSchema;
104+
protected abstract getSwaggerTypeForIntersectionType(type: Tsoa.IntersectionType, title?: string): Swagger.BaseSchema;
102105

103-
protected abstract buildProperties(properties: Tsoa.Property[]): { [propertyName: string]: Swagger.Schema | Swagger.Schema3 };
106+
protected abstract buildProperties(properties: Tsoa.Property[]): { [propertyName: string]: Swagger.Schema2 } | { [propertyName: string]: Swagger.Schema3 };
104107

105-
public getSwaggerTypeForObjectLiteral(objectLiteral: Tsoa.NestedObjectLiteralType, title?: string): Swagger.Schema {
108+
public getSwaggerTypeForObjectLiteral(objectLiteral: Tsoa.NestedObjectLiteralType, title?: string): Swagger.BaseSchema {
106109
const properties = this.buildProperties(objectLiteral.properties);
107110

108111
const additionalProperties = objectLiteral.additionalProperties && this.getSwaggerType(objectLiteral.additionalProperties);
@@ -146,7 +149,7 @@ export abstract class SpecGenerator {
146149
}
147150
};
148151

149-
protected getSwaggerTypeForPrimitiveType(dataType: Tsoa.PrimitiveTypeLiteral): Swagger.Schema {
152+
protected getSwaggerTypeForPrimitiveType(dataType: Tsoa.PrimitiveTypeLiteral): Swagger.BaseSchema {
150153
if (dataType === 'object') {
151154
if (process.env.NODE_ENV !== 'tsoa_test') {
152155
// eslint-disable-next-line no-console
@@ -162,7 +165,7 @@ export abstract class SpecGenerator {
162165
}
163166
}
164167

165-
const map: Record<Tsoa.PrimitiveTypeLiteral, Swagger.Schema> = {
168+
const map: Record<Tsoa.PrimitiveTypeLiteral, Swagger.BaseSchema> = {
166169
any: {
167170
// While the any type is discouraged, it does explicitly allows anything, so it should always allow additionalProperties
168171
additionalProperties: true,
@@ -188,7 +191,7 @@ export abstract class SpecGenerator {
188191
return map[dataType];
189192
}
190193

191-
protected getSwaggerTypeForArrayType(arrayType: Tsoa.ArrayType, title?: string): Swagger.Schema {
194+
protected getSwaggerTypeForArrayType(arrayType: Tsoa.ArrayType, title?: string): Swagger.BaseSchema {
192195
return {
193196
items: this.getSwaggerType(arrayType.elementType, title),
194197
type: 'array',

packages/cli/src/swagger/specGenerator2.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ export class SpecGenerator2 extends SpecGenerator {
227227
if (res.produces) {
228228
produces.push(...res.produces);
229229
}
230-
swaggerResponses[res.name].schema = this.getSwaggerType(res.schema) as Swagger.Schema;
230+
swaggerResponses[res.name].schema = this.getSwaggerType(res.schema) as Swagger.Schema2;
231231
}
232232
if (res.examples && res.examples[0]) {
233233
if ((res.exampleLabels?.filter(e => e).length || 0) > 0) {
@@ -307,7 +307,7 @@ export class SpecGenerator2 extends SpecGenerator {
307307
title: `${this.getOperationId(controllerName, method)}Body`,
308308
type: 'object',
309309
},
310-
} as Swagger.Parameter;
310+
} as Swagger.Parameter2;
311311
if (required.length) {
312312
parameter.schema.required = required;
313313
}
@@ -324,17 +324,6 @@ export class SpecGenerator2 extends SpecGenerator {
324324
}
325325

326326
private buildParameter(source: Tsoa.Parameter): Swagger.Parameter2 {
327-
let parameter = {
328-
default: source.default,
329-
description: source.description,
330-
in: source.in,
331-
name: source.name,
332-
required: this.isRequiredWithoutDefault(source),
333-
} as Swagger.Parameter2;
334-
if (source.deprecated) {
335-
parameter['x-deprecated'] = true;
336-
}
337-
338327
let type = source.type;
339328

340329
if (source.in !== 'body' && source.type.dataType === 'refEnum') {
@@ -348,16 +337,23 @@ export class SpecGenerator2 extends SpecGenerator {
348337
}
349338

350339
const parameterType = this.getSwaggerType(type);
351-
if (parameterType.format) {
352-
parameter.format = this.throwIfNotDataFormat(parameterType.format);
353-
}
340+
341+
let parameter = {
342+
default: source.default,
343+
description: source.description,
344+
in: source.in,
345+
name: source.name,
346+
required: this.isRequiredWithoutDefault(source),
347+
...(source.deprecated ? { 'x-deprecated': true } : {}),
348+
...(parameterType.$ref ? { schema: parameterType } : {}),
349+
...(parameterType.format ? { format: this.throwIfNotDataFormat(parameterType.format) } : {}),
350+
} as Swagger.Parameter2;
354351

355352
if (Swagger.isQueryParameter(parameter) && parameterType.type === 'array') {
356353
parameter.collectionFormat = 'multi';
357354
}
358355

359-
if (parameterType.$ref) {
360-
parameter.schema = parameterType as Swagger.Schema2;
356+
if (parameter.schema) {
361357
return parameter;
362358
}
363359

packages/cli/src/swagger/specGenerator3.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ export class SpecGenerator3 extends SpecGenerator {
503503
}
504504

505505
if (parameterType.$ref) {
506-
parameter.schema = parameterType as Swagger.Schema;
506+
parameter.schema = parameterType as Swagger.Schema3;
507507
return parameter;
508508
}
509509

@@ -581,7 +581,7 @@ export class SpecGenerator3 extends SpecGenerator {
581581
return { $ref: `#/components/schemas/${encodeURIComponent(referenceType.refName)}` };
582582
}
583583

584-
protected getSwaggerTypeForPrimitiveType(dataType: Tsoa.PrimitiveTypeLiteral): Swagger.Schema {
584+
protected getSwaggerTypeForPrimitiveType(dataType: Tsoa.PrimitiveTypeLiteral): Swagger.BaseSchema {
585585
if (dataType === 'any') {
586586
// Setting additionalProperties causes issues with code generators for OpenAPI 3
587587
// Therefore, we avoid setting it explicitly (since it's the implicit default already)
@@ -602,8 +602,8 @@ export class SpecGenerator3 extends SpecGenerator {
602602
// grouping enums is helpful because it makes the spec more readable and it
603603
// bypasses a failure in openapi-generator caused by using anyOf with
604604
// duplicate types.
605-
private groupEnums(types: Array<Swagger.Schema | Swagger.BaseSchema>) {
606-
const returnTypes: Array<Swagger.Schema | Swagger.BaseSchema> = [];
605+
private groupEnums(types: Swagger.BaseSchema[]) {
606+
const returnTypes: Swagger.BaseSchema[] = [];
607607
const enumValuesByType: Record<string, Record<string, boolean | string | number | null>> = {};
608608
for (const type of types) {
609609
if (type.enum && type.type) {
@@ -630,7 +630,7 @@ export class SpecGenerator3 extends SpecGenerator {
630630
return returnTypes;
631631
}
632632

633-
protected removeDuplicateSwaggerTypes(types: Array<Swagger.Schema | Swagger.BaseSchema>): Array<Swagger.Schema | Swagger.BaseSchema> {
633+
protected removeDuplicateSwaggerTypes(types: Swagger.BaseSchema[]): Swagger.BaseSchema[] {
634634
if (types.length === 1) {
635635
return types;
636636
} else {

packages/runtime/src/metadataGeneration/tsoa.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export namespace Tsoa {
4949
validators: Validators;
5050
deprecated: boolean;
5151
exampleLabels?: Array<string | undefined>;
52+
$ref?: Swagger.BaseSchema;
5253
}
5354

5455
export interface ResParameter extends Response, Parameter {

0 commit comments

Comments
 (0)