Skip to content

Commit

Permalink
Typescript+Axios: multipart/form-data correctly handled (#2002)
Browse files Browse the repository at this point in the history
* Typescript 3.2

* Typescript spread operator

* Add vendor extension to the operation

* Remove url.URLSearchParams

* Generate form data in API

* Make axios scripts executable

* Reran generator

* Generate sample code

* Revert to 2.4 Typescript

* COLLECTION_FORMAT.{{collectionFormat}} everywhere for consistency

* Consistency on the CollectionFormats, comment on the vendor extension

* fix compilation error
  • Loading branch information
mvniekerk authored and wing328 committed Feb 13, 2019
1 parent 598bf0c commit 550774a
Show file tree
Hide file tree
Showing 16 changed files with 645 additions and 558 deletions.
Empty file modified bin/typescript-axios-petstore-all.sh
100644 → 100755
Empty file.
Empty file modified bin/typescript-axios-petstore-interfaces.sh
100644 → 100755
Empty file.
Empty file modified bin/typescript-axios-petstore-target-es6.json
100644 → 100755
Empty file.
Empty file modified bin/typescript-axios-petstore-target-es6.sh
100644 → 100755
Empty file.
Empty file modified bin/typescript-axios-petstore-with-npm-version.json
100644 → 100755
Empty file.
Empty file modified bin/typescript-axios-petstore-with-npm-version.sh
100644 → 100755
Empty file.
Empty file modified bin/typescript-axios-petstore.sh
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.utils.ModelUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.*;

public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodegen {
private static final SimpleDateFormat SNAPSHOT_SUFFIX_FORMAT = new SimpleDateFormat("yyyyMMddHHmm", Locale.ROOT);
Expand Down Expand Up @@ -126,6 +126,22 @@ public String getTypeDeclaration(Schema p) {
}
}

@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels);
Map<String, Object> vals = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operations = (List<CodegenOperation>) vals.get("operation");
/*
Filter all the operations that are multipart/form-data operations and set the vendor extension flag
'multipartFormData' for the template to work with.
*/
operations.stream()
.filter(op -> op.hasConsumes)
.filter(op -> op.consumes.stream().anyMatch(opc -> opc.values().stream().anyMatch("multipart/form-data"::equals)))
.forEach(op -> op.vendorExtensions.putIfAbsent("multipartFormData", true));
return objs;
}

@Override
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
codegenModel.additionalPropertiesType = getTypeDeclaration(ModelUtils.getAdditionalProperties(schema));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,29 +97,27 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = Object.assign({ method: '{{httpMethod}}' }, baseOptions, options);
const localVarRequestOptions = { method: '{{httpMethod}}', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
{{#hasFormParams}}
const localVarFormParams = new url.URLSearchParams();
{{/hasFormParams}}
const localVarQueryParameter = {} as any;{{#vendorExtensions}}{{#hasFormParams}}
const localVarFormParams = new {{^multipartFormData}}URLSearchParams(){{/multipartFormData}}{{#multipartFormData}}FormData(){{/multipartFormData}};{{/hasFormParams}}{{/vendorExtensions}}
{{#authMethods}}
// authentication {{name}} required
{{#isApiKey}}
{{#isKeyInHeader}}
if (configuration && configuration.apiKey) {
const localVarApiKeyValue = typeof configuration.apiKey === 'function'
? configuration.apiKey("{{keyParamName}}")
: configuration.apiKey;
? configuration.apiKey("{{keyParamName}}")
: configuration.apiKey;
localVarHeaderParameter["{{keyParamName}}"] = localVarApiKeyValue;
}
{{/isKeyInHeader}}
{{#isKeyInQuery}}
if (configuration && configuration.apiKey) {
const localVarApiKeyValue = typeof configuration.apiKey === 'function'
? configuration.apiKey("{{keyParamName}}")
: configuration.apiKey;
? configuration.apiKey("{{keyParamName}}")
: configuration.apiKey;
localVarQueryParameter["{{keyParamName}}"] = localVarApiKeyValue;
}
{{/isKeyInQuery}}
Expand All @@ -133,9 +131,9 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
{{#isOAuth}}
// oauth required
if (configuration && configuration.accessToken) {
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
? configuration.accessToken("{{name}}", [{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}])
: configuration.accessToken;
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
? configuration.accessToken("{{name}}", [{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}])
: configuration.accessToken;
localVarHeaderParameter["Authorization"] = "Bearer " + localVarAccessTokenValue;
}
{{/isOAuth}}
Expand All @@ -148,7 +146,7 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
localVarQueryParameter['{{baseName}}'] = {{paramName}};
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
localVarQueryParameter['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS["{{collectionFormat}}"]);
localVarQueryParameter['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}});
{{/isCollectionFormatMulti}}
}
{{/isListContainer}}
Expand All @@ -172,7 +170,7 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
{{#headerParams}}
{{#isListContainer}}
if ({{paramName}}) {
localVarHeaderParameter['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS["{{collectionFormat}}"]);
localVarHeaderParameter['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}});
}
{{/isListContainer}}
{{^isListContainer}}
Expand All @@ -182,6 +180,7 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
{{/isListContainer}}
{{/headerParams}}
{{#vendorExtensions}}
{{#formParams}}
{{#isListContainer}}
if ({{paramName}}) {
Expand All @@ -190,21 +189,21 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
localVarFormParams.append('{{baseName}}', element as any);
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
localVarFormParams.set('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS["{{collectionFormat}}"]));
{{^isCollectionFormatMulti}}{{^multipartFormData}}
localVarFormParams.set('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}}));{{/multipartFormData}}{{#multipartFormData}}
localVarFormParams.append('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}}));{{/multipartFormData}}
{{/isCollectionFormatMulti}}
}
{{/isListContainer}}
}{{/isListContainer}}
{{^isListContainer}}
if ({{paramName}} !== undefined) {
localVarFormParams.set('{{baseName}}', {{paramName}} as any);
if ({{paramName}} !== undefined) { {{^multipartFormData}}
localVarFormParams.set('{{baseName}}', {{paramName}} as any);{{/multipartFormData}}{{#multipartFormData}}
localVarFormParams.append('{{baseName}}', {{paramName}} as any);{{/multipartFormData}}
}
{{/isListContainer}}
{{/formParams}}
{{#hasFormParams}}
localVarHeaderParameter['Content-Type'] = 'application/x-www-form-urlencoded';
{{/formParams}}{{/vendorExtensions}}
{{#hasFormParams}}{{#multipartFormData}}
localVarHeaderParameter['Content-Type'] = 'application/x-www-form-urlencoded';{{/multipartFormData}}{{#multipartFormData}}
localVarHeaderParameter['Content-Type'] = 'multipart/form-data';{{/multipartFormData}}
{{/hasFormParams}}
{{#bodyParam}}
{{^consumes}}
Expand All @@ -215,12 +214,12 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
{{/consumes.0}}
{{/bodyParam}}
localVarUrlObj.query = Object.assign({}, localVarUrlObj.query, localVarQueryParameter, options.query);
localVarUrlObj.query = {...localVarUrlObj.query, ...localVarQueryParameter, ...options.query};
// fix override query string Detail: https://stackoverflow.com/a/7517673/1077943
delete localVarUrlObj.search;
localVarRequestOptions.headers = Object.assign({}, localVarHeaderParameter, options.headers);
localVarRequestOptions.headers = {...localVarHeaderParameter, ...options.headers};
{{#hasFormParams}}
localVarRequestOptions.data = localVarFormParams.toString();
localVarRequestOptions.data = localVarFormParams{{#vendorExtensions}}{{^multipartFormData}}.toString(){{/multipartFormData}}{{/vendorExtensions}};
{{/hasFormParams}}
{{#bodyParam}}
const needsSerialization = (<any>"{{dataType}}" !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
Expand Down Expand Up @@ -258,7 +257,7 @@ export const {{classname}}Fp = function(configuration?: Configuration) {
{{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: any): (axios?: AxiosInstance, basePath?: string) => AxiosPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Response{{/returnType}}> {
const localVarAxiosArgs = {{classname}}AxiosParamCreator(configuration).{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs = Object.assign(localVarAxiosArgs.options, {url: basePath + localVarAxiosArgs.url})
const axiosRequestArgs = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"devDependencies": {
"@types/node": "^8.0.9",
"typescript": "^2.4"
"typescript": "^2.4"
}{{#npmRepository}},{{/npmRepository}}
{{#npmRepository}}
"publishConfig":{
Expand Down
Loading

0 comments on commit 550774a

Please sign in to comment.