diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java index 940a6b74cc3..fc07e0d7174 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenOperation.java @@ -14,7 +14,7 @@ public class CodegenOperation { public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMapContainer, isListContainer, isMultipart, hasMore = true, - isResponseBinary = false, hasReference = false, + isResponseBinary = false, isResponseFile = false, hasReference = false, isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestful; public String path, operationId, returnType, httpMethod, returnBaseType, @@ -217,6 +217,8 @@ public class CodegenOperation { return false; if (hasReference != that.hasReference) return false; + if (isResponseFile != that.isResponseFile) + return false; if (path != null ? !path.equals(that.path) : that.path != null) return false; if (operationId != null ? !operationId.equals(that.operationId) : that.operationId != null) @@ -297,6 +299,7 @@ public class CodegenOperation { result = 31 * result + (isMultipart ? 13:31); result = 31 * result + (hasMore ? 13:31); result = 31 * result + (isResponseBinary ? 13:31); + result = 31 * result + (isResponseFile ? 13:31); result = 31 * result + (hasReference ? 13:31); result = 31 * result + (path != null ? path.hashCode() : 0); result = 31 * result + (operationId != null ? operationId.hashCode() : 0); diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java index 834ab9d5ea4..4e6b9f8b879 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenProperty.java @@ -37,7 +37,7 @@ public class CodegenProperty implements Cloneable { public boolean hasMore, required, secondaryParam; public boolean hasMoreNonReadOnly; // for model constructor, true if next properyt is not readonly public boolean isPrimitiveType, isContainer, isNotContainer; - public boolean isString, isInteger, isLong, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime; + public boolean isString, isInteger, isLong, isFloat, isDouble, isByteArray, isBinary, isFile, isBoolean, isDate, isDateTime; public boolean isListContainer, isMapContainer; public boolean isEnum; public boolean isReadOnly = false; @@ -108,6 +108,7 @@ public class CodegenProperty implements Cloneable { result = prime * result + ((isDouble ? 13:31)); result = prime * result + ((isByteArray ? 13:31)); result = prime * result + ((isBinary ? 13:31)); + result = prime * result + ((isFile ? 13:31)); result = prime * result + ((isBoolean ? 13:31)); result = prime * result + ((isDate ? 13:31)); result = prime * result + ((isDateTime ? 13:31)); @@ -264,6 +265,9 @@ public class CodegenProperty implements Cloneable { if (this.isBinary != other.isBinary) { return false; } + if (this.isFile != other.isFile) { + return false; + } if (this.isListContainer != other.isListContainer) { return false; } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenResponse.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenResponse.java index a8a2117a31e..fb09f820be5 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenResponse.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenResponse.java @@ -16,6 +16,7 @@ public class CodegenResponse { public Boolean isMapContainer; public Boolean isListContainer; public Boolean isBinary = Boolean.FALSE; + public Boolean isFile = Boolean.FALSE; public Object schema; public String jsonSchema; @@ -63,6 +64,8 @@ public class CodegenResponse { return false; if (isBinary != null ? !isBinary.equals(that.isBinary) : that.isBinary != null) return false; + if (isFile != null ? !isFile.equals(that.isFile) : that.isFile != null) + return false; if (schema != null ? !schema.equals(that.schema) : that.schema != null) return false; return jsonSchema != null ? jsonSchema.equals(that.jsonSchema) : that.jsonSchema == null; @@ -85,6 +88,7 @@ public class CodegenResponse { result = 31 * result + (isMapContainer != null ? isMapContainer.hashCode() : 0); result = 31 * result + (isListContainer != null ? isListContainer.hashCode() : 0); result = 31 * result + (isBinary != null ? isBinary.hashCode() : 0); + result = 31 * result + (isFile != null ? isFile.hashCode() : 0); result = 31 * result + (schema != null ? schema.hashCode() : 0); result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0); return result; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index ce716c1bb02..2954a70845b 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -36,6 +36,7 @@ import io.swagger.models.properties.DateProperty; import io.swagger.models.properties.DateTimeProperty; import io.swagger.models.properties.DecimalProperty; import io.swagger.models.properties.DoubleProperty; +import io.swagger.models.properties.FileProperty; import io.swagger.models.properties.FloatProperty; import io.swagger.models.properties.IntegerProperty; import io.swagger.models.properties.LongProperty; @@ -783,6 +784,7 @@ public class DefaultCodegen { typeMapping.put("integer", "Integer"); typeMapping.put("ByteArray", "byte[]"); typeMapping.put("binary", "byte[]"); + typeMapping.put("file", "File"); instantiationTypes = new HashMap(); @@ -1087,6 +1089,8 @@ public class DefaultCodegen { datatype = "ByteArray"; } else if (p instanceof BinaryProperty) { datatype = "binary"; + } else if (p instanceof FileProperty) { + datatype = "file"; } else if (p instanceof BooleanProperty) { datatype = "boolean"; } else if (p instanceof DateProperty) { @@ -1566,6 +1570,9 @@ public class DefaultCodegen { if (p instanceof BinaryProperty) { property.isBinary = true; } + if (p instanceof FileProperty) { + property.isFile = true; + } if (p instanceof UUIDProperty) { property.isString = true; } @@ -1994,6 +2001,9 @@ public class DefaultCodegen { if (r.isBinary && r.isDefault){ op.isResponseBinary = Boolean.TRUE; } + if (r.isFile && r.isDefault){ + op.isResponseFile = Boolean.TRUE; + } } op.responses.get(op.responses.size() - 1).hasMore = false; @@ -2193,6 +2203,7 @@ public class DefaultCodegen { } r.dataType = cm.datatype; r.isBinary = isDataTypeBinary(cm.datatype); + r.isFile = isDataTypeFile(cm.datatype); if (cm.isContainer) { r.simpleType = false; r.containerType = cm.containerType; @@ -2382,6 +2393,7 @@ public class DefaultCodegen { p.dataType = cp.datatype; p.isPrimitiveType = cp.isPrimitiveType; p.isBinary = isDataTypeBinary(cp.datatype); + p.isFile = isDataTypeFile(cp.datatype); } // set boolean flag (e.g. isString) @@ -2474,6 +2486,8 @@ public class DefaultCodegen { p.example = "BINARY_DATA_HERE"; } else if (Boolean.TRUE.equals(p.isByteArray)) { p.example = "B"; + } else if (Boolean.TRUE.equals(p.isFile)) { + p.example = "/path/to/file.txt"; } else if (Boolean.TRUE.equals(p.isDate)) { p.example = "2013-10-20"; } else if (Boolean.TRUE.equals(p.isDateTime)) { @@ -2494,6 +2508,10 @@ public class DefaultCodegen { return dataType.toLowerCase().startsWith("byte"); } + public boolean isDataTypeFile(String dataType) { + return dataType.toLowerCase().equals("file"); + } + /** * Convert map of Swagger SecuritySchemeDefinition objects to a list of Codegen Security objects * @@ -3289,6 +3307,9 @@ public class DefaultCodegen { } else if (Boolean.TRUE.equals(property.isBinary)) { parameter.isByteArray = true; parameter.isPrimitiveType = true; + } else if (Boolean.TRUE.equals(property.isFile)) { + parameter.isFile = true; + parameter.isPrimitiveType = true; } else if (Boolean.TRUE.equals(property.isDate)) { parameter.isDate = true; parameter.isPrimitiveType = true; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java index 67a6ed0b422..50662a26dd5 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java @@ -1,5 +1,7 @@ package io.swagger.codegen.languages; +import io.swagger.models.properties.FileProperty; +import io.swagger.models.properties.Property; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,6 +29,8 @@ public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen public TypeScriptNodeClientCodegen() { super(); + typeMapping.put("file", "Buffer"); + // clear import mapping (from default generator) as TS does not use it // at the moment importMapping.clear(); @@ -92,6 +96,19 @@ public class TypeScriptNodeClientCodegen extends AbstractTypeScriptClientCodegen return "Generates a TypeScript nodejs client library."; } + @Override + public boolean isDataTypeFile(final String dataType) { + return dataType != null && dataType.equals("Buffer"); + } + + @Override + public String getTypeDeclaration(Property p) { + if (p instanceof FileProperty) { + return "Buffer"; + } + return super.getTypeDeclaration(p); + } + public void setNpmName(String npmName) { this.npmName = npmName; diff --git a/modules/swagger-codegen/src/main/resources/typescript-node/api.mustache b/modules/swagger-codegen/src/main/resources/typescript-node/api.mustache index cf6040ae3eb..48bbaabf5b0 100644 --- a/modules/swagger-codegen/src/main/resources/typescript-node/api.mustache +++ b/modules/swagger-codegen/src/main/resources/typescript-node/api.mustache @@ -237,7 +237,12 @@ export class {{classname}} { headers: headerParams, uri: localVarPath, useQuerystring: this._useQuerystring, +{{^isResponseFile}} json: true, +{{/isResponseFile}} +{{#isResponseFile}} + encoding: null, +{{/isResponseFile}} {{#bodyParam}} body: {{paramName}}, {{/bodyParam}} diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java index 37050a1be4b..5848108055d 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/CodegenTest.java @@ -43,7 +43,7 @@ public class CodegenTest { final CodegenParameter file = op.formParams.get(1); Assert.assertTrue(file.isFormParam); - Assert.assertEquals(file.dataType, "file"); + Assert.assertEquals(file.dataType, "File"); Assert.assertNull(file.required); Assert.assertTrue(file.isFile); Assert.assertNull(file.hasMore); @@ -187,6 +187,19 @@ public class CodegenTest { Assert.assertTrue(op.bodyParam.isBinary); Assert.assertTrue(op.responses.get(0).isBinary); } + + @Test(description = "return file when response format is file") + public void fileResponeseTest() { + final Swagger model = parseAndPrepareSwagger("src/test/resources/2_0/fileResponseTest.json"); + final DefaultCodegen codegen = new DefaultCodegen(); + final String path = "/tests/fileResponse"; + final Operation p = model.getPaths().get(path).getGet(); + final CodegenOperation op = codegen.fromOperation(path, "get", p, model.getDefinitions()); + + Assert.assertEquals(op.returnType, "File"); + Assert.assertTrue(op.responses.get(0).isFile); + Assert.assertTrue(op.isResponseFile); + } @Test(description = "discriminator is present") public void discriminatorTest() { diff --git a/modules/swagger-codegen/src/test/resources/2_0/fileResponseTest.json b/modules/swagger-codegen/src/test/resources/2_0/fileResponseTest.json new file mode 100644 index 00000000000..ab8237934ef --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/2_0/fileResponseTest.json @@ -0,0 +1,33 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "File Response Test", + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "basePath": "/v2", + "schemes": [ + "http" + ], + "paths": { + "/tests/fileResponse": { + "get": { + "operationId": "fileresponsetest", + "produces": [ + "application/octet-stream" + ], + "responses": { + "200": { + "description": "OutputFileData", + "schema": { + "type": "file" + } + } + } + } + } + } +}