Skip to content

Commit

Permalink
Merge pull request #957 from qqilihq/fix/files-optional-or-required
Browse files Browse the repository at this point in the history
Fix/files optional or required
  • Loading branch information
WoH authored Apr 10, 2021
2 parents 5259731 + 330d293 commit eefef06
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 5 deletions.
4 changes: 2 additions & 2 deletions packages/cli/src/metadataGeneration/parameterGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class ParameterGenerator {
}
return ident.text === 'UploadedFile';
}) ?? parameterName,
required: true,
required: !parameter.questionToken && !parameter.initializer,
type,
parameterName,
validators: getParameterValidators(this.parameter, parameterName),
Expand All @@ -208,7 +208,7 @@ export class ParameterGenerator {
description: this.getParameterDescription(parameter),
in: 'formData',
name: getNodeFirstDecoratorValue(this.parameter, this.current.typeChecker, ident => ident.text === 'FormField') ?? parameterName,
required: true,
required: !parameter.questionToken && !parameter.initializer,
type,
parameterName,
validators: getParameterValidators(this.parameter, parameterName),
Expand Down
11 changes: 8 additions & 3 deletions packages/cli/src/swagger/specGenerator3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,20 +340,25 @@ export class SpecGenerator3 extends SpecGenerator {
}

private buildRequestBodyWithFormData(controllerName: string, method: Tsoa.Method, parameters: Tsoa.Parameter[]): Swagger.RequestBody {
let required = false;
const required: string[] = [];
const properties: { [propertyName: string]: Swagger.Schema3 } = {};
for (const parameter of parameters) {
const mediaType = this.buildMediaType(controllerName, method, parameter);
properties[parameter.name] = mediaType.schema!;
required = required || !!parameter.required;
if (parameter.required) {
required.push(parameter.name);
}
}
const requestBody: Swagger.RequestBody = {
required,
required: required.length > 0,
content: {
'multipart/form-data': {
schema: {
type: 'object',
properties,
// An empty list required: [] is not valid.
// If all properties are optional, do not specify the required keyword.
...(required && required.length && { required }),
},
},
},
Expand Down
5 changes: 5 additions & 0 deletions tests/fixtures/controllers/postController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export class PostTestController {
return aFile;
}

@Post('FileOptional')
public async postWithOptionalFile(@UploadedFile('optionalFile') optionalFile?: File): Promise<string> {
return optionalFile?.originalname ?? 'no file';
}

@Post('FileWithoutName')
public async postWithFileWithoutName(@UploadedFile() aFile: File): Promise<File> {
return aFile;
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/swagger/schemaDetails3.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ describe('Definition generation for OpenAPI 3.0.0', () => {
format: 'binary',
},
},
required: ['someFile'],
},
},
},
Expand Down Expand Up @@ -419,6 +420,7 @@ describe('Definition generation for OpenAPI 3.0.0', () => {
format: 'binary',
},
},
required: ['aFile'],
},
},
},
Expand Down Expand Up @@ -458,6 +460,37 @@ describe('Definition generation for OpenAPI 3.0.0', () => {
type: 'string',
},
},
required: ['someFiles', 'a', 'c'],
},
},
},
});
});
it('should not treat optional file as required', () => {
// Act
const specPost = new SpecGenerator3(metadataPost, getDefaultExtendedOptions()).GetSpec();
const pathPost = specPost.paths['/PostTest/FileOptional'].post;
if (!pathPost) {
throw new Error('PostTest file method not defined');
}
if (!pathPost.requestBody) {
throw new Error('PostTest file method has no requestBody');
}

// Assert
expect(pathPost.parameters).to.have.length(0);
expect(pathPost.requestBody).to.deep.equal({
required: false,
content: {
'multipart/form-data': {
schema: {
type: 'object',
properties: {
optionalFile: {
type: 'string',
format: 'binary',
},
},
},
},
},
Expand Down

0 comments on commit eefef06

Please sign in to comment.