@@ -27,6 +27,33 @@ export class SpecGenerator3 extends SpecGenerator {
2727 super ( metadata , config ) ;
2828 }
2929
30+ // In OAS 3.0, exclusiveMinimum/exclusiveMaximum are boolean modifiers on minimum/maximum.
31+ // OAS 3.1 overrides this to pass through numeric values directly.
32+ protected transformValidatorsForSchema ( validators : Tsoa . Validators ) : Record < string , unknown > {
33+ if ( validators . exclusiveMinimum !== undefined && validators . minimum !== undefined ) {
34+ throw new Error ( 'Cannot use both @minimum and @exclusiveMinimum in OpenAPI 3.0. Use one or the other, or target OpenAPI 3.1.' ) ;
35+ }
36+ if ( validators . exclusiveMaximum !== undefined && validators . maximum !== undefined ) {
37+ throw new Error ( 'Cannot use both @maximum and @exclusiveMaximum in OpenAPI 3.0. Use one or the other, or target OpenAPI 3.1.' ) ;
38+ }
39+
40+ const result : Record < string , unknown > = { } ;
41+ Object . keys ( validators )
42+ . filter ( shouldIncludeValidatorInSchema )
43+ . forEach ( key => {
44+ if ( key === 'exclusiveMinimum' ) {
45+ result [ 'minimum' ] = validators . exclusiveMinimum ! . value ;
46+ result [ 'exclusiveMinimum' ] = true ;
47+ } else if ( key === 'exclusiveMaximum' ) {
48+ result [ 'maximum' ] = validators . exclusiveMaximum ! . value ;
49+ result [ 'exclusiveMaximum' ] = true ;
50+ } else {
51+ result [ key ] = validators [ key ] ! . value ;
52+ }
53+ } ) ;
54+ return result ;
55+ }
56+
3057 public GetSpec ( ) : Swagger . Spec3 {
3158 let spec : Swagger . Spec30 = {
3259 openapi : '3.0.0' ,
@@ -214,14 +241,7 @@ export class SpecGenerator3 extends SpecGenerator {
214241 } else if ( referenceType . dataType === 'refAlias' ) {
215242 const swaggerType = this . getSwaggerType ( referenceType . type ) ;
216243 const format = referenceType . format as Swagger . DataFormat ;
217- const validators = Object . keys ( referenceType . validators )
218- . filter ( shouldIncludeValidatorInSchema )
219- . reduce ( ( acc , key ) => {
220- return {
221- ...acc ,
222- [ key ] : referenceType . validators [ key ] ! . value ,
223- } ;
224- } , { } ) ;
244+ const validators = this . transformValidatorsForSchema ( referenceType . validators ) ;
225245
226246 schema [ referenceType . refName ] = {
227247 ...( swaggerType as Swagger . Schema3 ) ,
@@ -448,14 +468,7 @@ export class SpecGenerator3 extends SpecGenerator {
448468 }
449469
450470 protected buildMediaType ( controllerName : string , method : Tsoa . Method , parameter : Tsoa . Parameter ) : Swagger . MediaType {
451- const validators = Object . keys ( parameter . validators )
452- . filter ( shouldIncludeValidatorInSchema )
453- . reduce ( ( acc , key ) => {
454- return {
455- ...acc ,
456- [ key ] : parameter . validators [ key ] ! . value ,
457- } ;
458- } , { } ) ;
471+ const validators = this . transformValidatorsForSchema ( parameter . validators ) ;
459472
460473 const mediaType : Swagger . MediaType = {
461474 schema : {
@@ -516,12 +529,7 @@ export class SpecGenerator3 extends SpecGenerator {
516529 return Object . assign ( parameter , this . buildExamples ( source ) ) ;
517530 }
518531
519- const validatorObjs : { [ key in Tsoa . SchemaValidatorKey ] ?: unknown } = { } ;
520- Object . keys ( source . validators )
521- . filter ( shouldIncludeValidatorInSchema )
522- . forEach ( key => {
523- validatorObjs [ key ] = source . validators [ key ] ! . value ;
524- } ) ;
532+ const validatorObjs = this . transformValidatorsForSchema ( source . validators ) ;
525533
526534 if ( source . type . dataType === 'any' ) {
527535 parameter . schema . type = 'string' ;
@@ -578,11 +586,8 @@ export class SpecGenerator3 extends SpecGenerator {
578586 if ( ! swaggerType . $ref ) {
579587 swaggerType . default = property . default ;
580588
581- Object . keys ( property . validators )
582- . filter ( shouldIncludeValidatorInSchema )
583- . forEach ( key => {
584- swaggerType = { ...swaggerType , [ key ] : property . validators [ key ] ! . value } ;
585- } ) ;
589+ const propertyValidators = this . transformValidatorsForSchema ( property . validators ) ;
590+ swaggerType = { ...swaggerType , ...propertyValidators } ;
586591 }
587592 if ( property . deprecated ) {
588593 swaggerType . deprecated = true ;
0 commit comments