[JS] (#7913) Adding support for multi file upload. Also adding the option for individual CodeGens to specify a collectionFormat (#7914)

* updated samples as well
This commit is contained in:
Troy P 2020-11-25 00:00:08 -08:00 committed by GitHub
parent 596d9a1d1d
commit 8cfc9b015a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 13 deletions

View File

@ -5771,7 +5771,6 @@ public class DefaultCodegen implements CodegenConfig {
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
// key => property name
// value => property schema
String collectionFormat = null;
Schema s = entry.getValue();
// array of schema
if (ModelUtils.isArraySchema(s)) {
@ -5795,6 +5794,7 @@ public class DefaultCodegen implements CodegenConfig {
}
//TODO fix collectformat for form parameters
//collectionFormat = getCollectionFormat(s);
String collectionFormat = getCollectionFormat(codegenParameter);
// default to csv:
codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
@ -6669,4 +6669,15 @@ public class DefaultCodegen implements CodegenConfig {
protected static boolean isJsonVendorMimeType(String mime) {
return mime != null && JSON_VENDOR_MIME_PATTERN.matcher(mime).matches();
}
/**
* Returns null by default but can be overwritten to return a valid collectionFormat
* for the {@link CodegenParameter}.
*
* @param codegenParameter parameter
* @return string for a collectionFormat.
*/
protected String getCollectionFormat(CodegenParameter codegenParameter) {
return null;
}
}

View File

@ -1220,4 +1220,16 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
}
}
@Override
protected String getCollectionFormat(CodegenParameter codegenParameter) {
// This method will return `passthrough` when the parameter data format is binary and an array.
// `passthrough` is not part of the OAS spec. However, this will act like a flag that we should
// not do any processing on the collection type (i.e. convert to tsv, csv, etc..). This is
// critical to support multi file uploads correctly.
if (codegenParameter.isArray && Objects.equals(codegenParameter.dataFormat, "binary")) {
return "passthrough";
}
return super.getCollectionFormat(codegenParameter);
}
}

View File

@ -316,6 +316,8 @@
case 'multi':
// return the array directly as SuperAgent will handle it as expected
return param.map(this.paramToString, this);
case 'passthrough':
return param;
default:
throw new Error('Unknown collection format: ' + collectionFormat);
}
@ -489,11 +491,16 @@
var _formParams = this.normalizeParams(formParams);
for (var key in _formParams) {
if (_formParams.hasOwnProperty(key)) {
if (this.isFileParam(_formParams[key])) {
let _formParamsValue = _formParams[key];
if (this.isFileParam(_formParamsValue)) {
// file field
request.attach(key, _formParams[key]);
request.attach(key, _formParamsValue);
} else if (Array.isArray(_formParamsValue) && _formParamsValue.length
&& this.isFileParam(_formParamsValue[0])) {
// multiple files
_formParamsValue.forEach(file => request.attach(key, file));
} else {
request.field(key, _formParams[key]);
request.field(key, _formParamsValue);
}
}
}

View File

@ -282,6 +282,8 @@ class ApiClient {
case 'multi':
//return the array directly as SuperAgent will handle it as expected
return param.map(this.paramToString, this);
case 'passthrough':
return param;
default:
throw new Error('Unknown collection format: ' + collectionFormat);
}
@ -451,11 +453,16 @@ class ApiClient {
var _formParams = this.normalizeParams(formParams);
for (var key in _formParams) {
if (_formParams.hasOwnProperty(key)) {
if (this.isFileParam(_formParams[key])) {
let _formParamsValue = _formParams[key];
if (this.isFileParam(_formParamsValue)) {
// file field
request.attach(key, _formParams[key]);
request.attach(key, _formParamsValue);
} else if (Array.isArray(_formParamsValue) && _formParamsValue.length
&& this.isFileParam(_formParamsValue[0])) {
// multiple files
_formParamsValue.forEach(file => request.attach(key, file));
} else {
request.field(key, _formParams[key]);
request.field(key, _formParamsValue);
}
}
}

View File

@ -17,9 +17,13 @@
package org.openapitools.codegen.javascript;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.RequestBody;
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.JavascriptClientCodegen;
import org.testng.Assert;
@ -113,4 +117,18 @@ public class JavascriptClientCodegenTest {
}
@Test(description = "test multiple file upload collection is correct")
public void testMultipleFileUpload() throws Exception {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/form-multipart-binary-array.yaml");
final JavascriptClientCodegen codegen = new JavascriptClientCodegen();
codegen.setOpenAPI(openAPI);
final String requestPath = "/multipart-array";
Operation textOperation = openAPI.getPaths().get(requestPath).getPost();
CodegenOperation operation = codegen.fromOperation(requestPath, "post", textOperation, null);
CodegenParameter codegenParameter = operation.allParams.get(0);
Assert.assertEquals(codegenParameter.collectionFormat, "passthrough");
}
}

View File

@ -280,6 +280,8 @@ class ApiClient {
case 'multi':
//return the array directly as SuperAgent will handle it as expected
return param.map(this.paramToString, this);
case 'passthrough':
return param;
default:
throw new Error('Unknown collection format: ' + collectionFormat);
}
@ -439,11 +441,16 @@ class ApiClient {
var _formParams = this.normalizeParams(formParams);
for (var key in _formParams) {
if (_formParams.hasOwnProperty(key)) {
if (this.isFileParam(_formParams[key])) {
let _formParamsValue = _formParams[key];
if (this.isFileParam(_formParamsValue)) {
// file field
request.attach(key, _formParams[key]);
request.attach(key, _formParamsValue);
} else if (Array.isArray(_formParamsValue) && _formParamsValue.length
&& this.isFileParam(_formParamsValue[0])) {
// multiple files
_formParamsValue.forEach(file => request.attach(key, file));
} else {
request.field(key, _formParams[key]);
request.field(key, _formParamsValue);
}
}
}

View File

@ -280,6 +280,8 @@ class ApiClient {
case 'multi':
//return the array directly as SuperAgent will handle it as expected
return param.map(this.paramToString, this);
case 'passthrough':
return param;
default:
throw new Error('Unknown collection format: ' + collectionFormat);
}
@ -431,11 +433,16 @@ class ApiClient {
var _formParams = this.normalizeParams(formParams);
for (var key in _formParams) {
if (_formParams.hasOwnProperty(key)) {
if (this.isFileParam(_formParams[key])) {
let _formParamsValue = _formParams[key];
if (this.isFileParam(_formParamsValue)) {
// file field
request.attach(key, _formParams[key]);
request.attach(key, _formParamsValue);
} else if (Array.isArray(_formParamsValue) && _formParamsValue.length
&& this.isFileParam(_formParamsValue[0])) {
// multiple files
_formParamsValue.forEach(file => request.attach(key, file));
} else {
request.field(key, _formParams[key]);
request.field(key, _formParamsValue);
}
}
}