JS client: support optional parameters with object syntax

Closes #2027
This commit is contained in:
xhh 2016-02-24 20:55:46 +08:00
parent bd32a6a410
commit baf5d2895e
8 changed files with 162 additions and 140 deletions

View File

@ -7,6 +7,7 @@ import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenParameter;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.SupportingFile;
@ -445,6 +446,35 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
return codegenModel;
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
// Generate and store argument list string of each operation into
// vendor-extension: x-codegen-argList.
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
List<String> argList = new ArrayList();
boolean hasOptionalParams = false;
for (CodegenParameter p : operation.allParams) {
if (p.required != null && p.required) {
argList.add(p.paramName);
} else {
hasOptionalParams = true;
}
}
if (hasOptionalParams) {
argList.add("opts");
}
if (!usePromises) {
argList.add("callback");
}
operation.vendorExtensions.put("x-codegen-argList", StringUtils.join(argList, ", "));
}
}
return objs;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
@ -488,7 +518,7 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
allowableValues.put("enumVars", enumVars);
}
// set vendor-extension: x-hasMoreRequired
// set vendor-extension: x-codegen-hasMoreRequired
CodegenProperty lastRequired = null;
for (CodegenProperty var : cm.vars) {
if (var.required != null && var.required) {
@ -497,9 +527,9 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
for (CodegenProperty var : cm.vars) {
if (var == lastRequired) {
var.vendorExtensions.put("x-hasMoreRequired", false);
var.vendorExtensions.put("x-codegen-hasMoreRequired", false);
} else if (var.required != null && var.required) {
var.vendorExtensions.put("x-hasMoreRequired", true);
var.vendorExtensions.put("x-codegen-hasMoreRequired", true);
}
}
}

View File

@ -1,54 +1,54 @@
(function(root, factory) {
{{=< >=}}(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['../ApiClient'{{#imports}}, '../model/{{import}}'{{/imports}}], factory);
define(['../ApiClient'<#imports>, '../model/<import>'</imports>], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports, like Node.
module.exports = factory(require('../ApiClient'){{#imports}}, require('../model/{{import}}'){{/imports}});
module.exports = factory(require('../ApiClient')<#imports>, require('../model/<import>')</imports>);
} else {
// Browser globals (root is window)
if (!root.{{moduleName}}) {
root.{{moduleName}} = {};
if (!root.<moduleName>) {
root.<moduleName> = {};
}
root.{{moduleName}}.{{classname}} = factory(root.{{moduleName}}.ApiClient{{#imports}}, root.{{moduleName}}.{{import}}{{/imports}});
root.<moduleName>.<classname> = factory(root.<moduleName>.ApiClient<#imports>, root.<moduleName>.<import></imports>);
}
}(this, function(ApiClient{{#imports}}, {{import}}{{/imports}}) {
}(this, function(ApiClient<#imports>, <import></imports>) {
'use strict';
var {{classname}} = function {{classname}}(apiClient) {
var <classname> = function <classname>(apiClient) {
this.apiClient = apiClient || ApiClient.default;
var self = this;
{{#operations}}
{{#operation}}
<#operations>
<#operation>
/**
* {{summary}}
* {{notes}}
{{#allParams}} * @param {{=<% %>=}}{<% dataType %>} <%={{ }}=%> {{paramName}} {{description}}
{{/allParams}} {{^usePromises}}* @param {function} callback the callback function, accepting three arguments: error, data, response{{/usePromises}}{{#returnType}}
* data is of type: {{{returnType}}}{{/returnType}}
* <summary>
* <notes><#allParams>
* @param {<dataType>} <#required><paramName></required><^required>opts['<paramName>']</required> <description></allParams><^usePromises>
* @param {function} callback the callback function, accepting three arguments: error, data, response</usePromises><#returnType>
* data is of type: <&returnType></returnType>
*/
self.{{nickname}} = function({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{^usePromises}}{{#hasParams}}, {{/hasParams}}callback{{/usePromises}}) {
var postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
throw "Missing the required parameter '{{paramName}}' when calling {{nickname}}";
self.<nickname> = function(<vendorExtensions.x-codegen-argList>) {<#hasOptionalParams>
opts = opts || {};</hasOptionalParams>
var postBody = <#bodyParam><#required><paramName></required><^required>opts['<paramName>']</required></bodyParam><^bodyParam>null</bodyParam>;
<#allParams><#required>
// verify the required parameter '<paramName>' is set
if (<paramName> == null) {
throw "Missing the required parameter '<paramName>' when calling <nickname>";
}
{{/required}}{{/allParams}}
</required></allParams>
{{=< >=}}
var pathParams = {<#pathParams>
'<baseName>': <paramName><#hasMore>,</hasMore></pathParams>
'<baseName>': <#required><paramName></required><^required>opts['<paramName>']</required><#hasMore>,</hasMore></pathParams>
};
var queryParams = {<#queryParams>
'<baseName>': <#collectionFormat>this.apiClient.buildCollectionParam(<paramName>, '<collectionFormat>')</collectionFormat><^collectionFormat><paramName></collectionFormat><#hasMore>,</hasMore></queryParams>
'<baseName>': <#collectionFormat>this.apiClient.buildCollectionParam(<#required><paramName></required><^required>opts['<paramName>']</required>, '<collectionFormat>')</collectionFormat><^collectionFormat><#required><paramName></required><^required>opts['<paramName>']</required></collectionFormat><#hasMore>,</hasMore></queryParams>
};
var headerParams = {<#headerParams>
'<baseName>': <paramName><#hasMore>,</hasMore></headerParams>
'<baseName>': <#required><paramName></required><^required>opts['<paramName>']</required><#hasMore>,</hasMore></headerParams>
};
var formParams = {<#formParams>
'<baseName>': <#collectionFormat>this.apiClient.buildCollectionParam(<paramName>, '<collectionFormat>')</collectionFormat><^collectionFormat><paramName></collectionFormat><#hasMore>,</hasMore></formParams>
'<baseName>': <#collectionFormat>this.apiClient.buildCollectionParam(<#required><paramName></required><^required>opts['<paramName>']</required>, '<collectionFormat>')</collectionFormat><^collectionFormat><#required><paramName></required><^required>opts['<paramName>']</required></collectionFormat><#hasMore>,</hasMore></formParams>
};
var authNames = [<#authMethods>'<name>'<#hasMore>, </hasMore></authMethods>];
@ -61,11 +61,11 @@
pathParams, queryParams, headerParams, formParams, postBody,
authNames, contentTypes, accepts, returnType<^usePromises>, callback</usePromises>
);
<={{ }}=>
}
{{/operation}}
{{/operations}}
</operation>
</operations>
};
return {{classname}};
}));
return <classname>;
}));<={{ }}=>

View File

@ -18,7 +18,7 @@
{{#description}}/**
* {{description}}
**/{{/description}}
var {{classname}} = function {{classname}}({{#vars}}{{#required}}{{name}}{{#vendorExtensions.x-hasMoreRequired}}, {{/vendorExtensions.x-hasMoreRequired}}{{/required}}{{/vars}}) { {{#parent}}/* extends {{{parent}}}*/{{/parent}}
var {{classname}} = function {{classname}}({{#vars}}{{#required}}{{name}}{{#vendorExtensions.x-codegen-hasMoreRequired}}, {{/vendorExtensions.x-codegen-hasMoreRequired}}{{/required}}{{/vars}}) { {{#parent}}/* extends {{{parent}}}*/{{/parent}}
{{#vars}}{{#required}}
/**{{#description}}
* {{{description}}}{{/description}}

View File

@ -24,12 +24,12 @@
/**
* Update an existing pet
*
* @param {Pet} body Pet object that needs to be added to the store
* @param {Pet} opts['body'] Pet object that needs to be added to the store
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.updatePet = function(body, callback) {
var postBody = body;
self.updatePet = function(opts, callback) {
opts = opts || {};
var postBody = opts['body'];
var pathParams = {
@ -57,12 +57,12 @@
/**
* Add a new pet to the store
*
* @param {Pet} body Pet object that needs to be added to the store
* @param {Pet} opts['body'] Pet object that needs to be added to the store
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.addPet = function(body, callback) {
var postBody = body;
self.addPet = function(opts, callback) {
opts = opts || {};
var postBody = opts['body'];
var pathParams = {
@ -90,19 +90,19 @@
/**
* Finds Pets by status
* Multiple status values can be provided with comma seperated strings
* @param {[String]} status Status values that need to be considered for filter
* @param {[String]} opts['status'] Status values that need to be considered for filter
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: [Pet]
*/
self.findPetsByStatus = function(status, callback) {
self.findPetsByStatus = function(opts, callback) {
opts = opts || {};
var postBody = null;
var pathParams = {
};
var queryParams = {
'status': this.apiClient.buildCollectionParam(status, 'multi')
'status': this.apiClient.buildCollectionParam(opts['status'], 'multi')
};
var headerParams = {
};
@ -125,19 +125,19 @@
/**
* Finds Pets by tags
* Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.
* @param {[String]} tags Tags to filter by
* @param {[String]} opts['tags'] Tags to filter by
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: [Pet]
*/
self.findPetsByTags = function(tags, callback) {
self.findPetsByTags = function(opts, callback) {
opts = opts || {};
var postBody = null;
var pathParams = {
};
var queryParams = {
'tags': this.apiClient.buildCollectionParam(tags, 'multi')
'tags': this.apiClient.buildCollectionParam(opts['tags'], 'multi')
};
var headerParams = {
};
@ -160,7 +160,7 @@
/**
* Find pet by ID
* Returns a pet when ID &lt; 10. ID &gt; 10 or nonintegers will simulate API error conditions
* @param {Integer} petId ID of pet that needs to be fetched
* @param {Integer} petId ID of pet that needs to be fetched
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: Pet
*/
@ -173,7 +173,6 @@
}
var pathParams = {
'petId': petId
};
@ -200,12 +199,13 @@
/**
* Updates a pet in the store with form data
*
* @param {String} petId ID of pet that needs to be updated
* @param {String} name Updated name of the pet
* @param {String} status Updated status of the pet
* @param {String} petId ID of pet that needs to be updated
* @param {String} opts['name'] Updated name of the pet
* @param {String} opts['status'] Updated status of the pet
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.updatePetWithForm = function(petId, name, status, callback) {
self.updatePetWithForm = function(petId, opts, callback) {
opts = opts || {};
var postBody = null;
// verify the required parameter 'petId' is set
@ -214,7 +214,6 @@
}
var pathParams = {
'petId': petId
};
@ -223,8 +222,8 @@
var headerParams = {
};
var formParams = {
'name': name,
'status': status
'name': opts['name'],
'status': opts['status']
};
var authNames = ['petstore_auth'];
@ -243,11 +242,12 @@
/**
* Deletes a pet
*
* @param {Integer} petId Pet id to delete
* @param {String} apiKey
* @param {Integer} petId Pet id to delete
* @param {String} opts['apiKey']
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.deletePet = function(petId, apiKey, callback) {
self.deletePet = function(petId, opts, callback) {
opts = opts || {};
var postBody = null;
// verify the required parameter 'petId' is set
@ -256,14 +256,13 @@
}
var pathParams = {
'petId': petId
};
var queryParams = {
};
var headerParams = {
'api_key': apiKey
'api_key': opts['apiKey']
};
var formParams = {
};
@ -284,12 +283,13 @@
/**
* uploads an image
*
* @param {Integer} petId ID of pet to update
* @param {String} additionalMetadata Additional data to pass to server
* @param {File} file file to upload
* @param {Integer} petId ID of pet to update
* @param {String} opts['additionalMetadata'] Additional data to pass to server
* @param {File} opts['file'] file to upload
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.uploadFile = function(petId, additionalMetadata, file, callback) {
self.uploadFile = function(petId, opts, callback) {
opts = opts || {};
var postBody = null;
// verify the required parameter 'petId' is set
@ -298,7 +298,6 @@
}
var pathParams = {
'petId': petId
};
@ -307,8 +306,8 @@
var headerParams = {
};
var formParams = {
'additionalMetadata': additionalMetadata,
'file': file
'additionalMetadata': opts['additionalMetadata'],
'file': opts['file']
};
var authNames = ['petstore_auth'];
@ -327,7 +326,7 @@
/**
* Fake endpoint to test byte array return by &#39;Find pet by ID&#39;
* Returns a pet when ID &lt; 10. ID &gt; 10 or nonintegers will simulate API error conditions
* @param {Integer} petId ID of pet that needs to be fetched
* @param {Integer} petId ID of pet that needs to be fetched
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: 'String'
*/
@ -340,7 +339,6 @@
}
var pathParams = {
'petId': petId
};
@ -367,12 +365,12 @@
/**
* Fake endpoint to test byte array in body parameter for adding a new pet to the store
*
* @param {String} body Pet object in the form of byte array
* @param {String} opts['body'] Pet object in the form of byte array
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.addPetUsingByteArray = function(body, callback) {
var postBody = body;
self.addPetUsingByteArray = function(opts, callback) {
opts = opts || {};
var postBody = opts['body'];
var pathParams = {

View File

@ -31,7 +31,6 @@
var postBody = null;
var pathParams = {
};
var queryParams = {
@ -57,13 +56,13 @@
/**
* Place an order for a pet
*
* @param {Order} body order placed for purchasing the pet
* @param {Order} opts['body'] order placed for purchasing the pet
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: Order
*/
self.placeOrder = function(body, callback) {
var postBody = body;
self.placeOrder = function(opts, callback) {
opts = opts || {};
var postBody = opts['body'];
var pathParams = {
@ -91,7 +90,7 @@
/**
* Find purchase order by ID
* For valid response try integer IDs with value &lt;= 5 or &gt; 10. Other values will generated exceptions
* @param {String} orderId ID of pet that needs to be fetched
* @param {String} orderId ID of pet that needs to be fetched
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: Order
*/
@ -104,7 +103,6 @@
}
var pathParams = {
'orderId': orderId
};
@ -131,7 +129,7 @@
/**
* Delete purchase order by ID
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
* @param {String} orderId ID of the order that needs to be deleted
* @param {String} orderId ID of the order that needs to be deleted
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.deleteOrder = function(orderId, callback) {
@ -143,7 +141,6 @@
}
var pathParams = {
'orderId': orderId
};

View File

@ -24,12 +24,12 @@
/**
* Create user
* This can only be done by the logged in user.
* @param {User} body Created user object
* @param {User} opts['body'] Created user object
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.createUser = function(body, callback) {
var postBody = body;
self.createUser = function(opts, callback) {
opts = opts || {};
var postBody = opts['body'];
var pathParams = {
@ -57,12 +57,12 @@
/**
* Creates list of users with given input array
*
* @param {[User]} body List of user object
* @param {[User]} opts['body'] List of user object
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.createUsersWithArrayInput = function(body, callback) {
var postBody = body;
self.createUsersWithArrayInput = function(opts, callback) {
opts = opts || {};
var postBody = opts['body'];
var pathParams = {
@ -90,12 +90,12 @@
/**
* Creates list of users with given input array
*
* @param {[User]} body List of user object
* @param {[User]} opts['body'] List of user object
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.createUsersWithListInput = function(body, callback) {
var postBody = body;
self.createUsersWithListInput = function(opts, callback) {
opts = opts || {};
var postBody = opts['body'];
var pathParams = {
@ -123,21 +123,21 @@
/**
* Logs user into the system
*
* @param {String} username The user name for login
* @param {String} password The password for login in clear text
* @param {String} opts['username'] The user name for login
* @param {String} opts['password'] The password for login in clear text
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: 'String'
*/
self.loginUser = function(username, password, callback) {
self.loginUser = function(opts, callback) {
opts = opts || {};
var postBody = null;
var pathParams = {
};
var queryParams = {
'username': username,
'password': password
'username': opts['username'],
'password': opts['password']
};
var headerParams = {
};
@ -166,7 +166,6 @@
var postBody = null;
var pathParams = {
};
var queryParams = {
@ -192,7 +191,7 @@
/**
* Get user by user name
*
* @param {String} username The name that needs to be fetched. Use user1 for testing.
* @param {String} username The name that needs to be fetched. Use user1 for testing.
* @param {function} callback the callback function, accepting three arguments: error, data, response
* data is of type: User
*/
@ -205,7 +204,6 @@
}
var pathParams = {
'username': username
};
@ -232,12 +230,13 @@
/**
* Updated user
* This can only be done by the logged in user.
* @param {String} username name that need to be deleted
* @param {User} body Updated user object
* @param {String} username name that need to be deleted
* @param {User} opts['body'] Updated user object
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.updateUser = function(username, body, callback) {
var postBody = body;
self.updateUser = function(username, opts, callback) {
opts = opts || {};
var postBody = opts['body'];
// verify the required parameter 'username' is set
if (username == null) {
@ -245,7 +244,6 @@
}
var pathParams = {
'username': username
};
@ -272,7 +270,7 @@
/**
* Delete user
* This can only be done by the logged in user.
* @param {String} username The name that needs to be deleted
* @param {String} username The name that needs to be deleted
* @param {function} callback the callback function, accepting three arguments: error, data, response
*/
self.deleteUser = function(username, callback) {
@ -284,7 +282,6 @@
}
var pathParams = {
'username': username
};

View File

@ -16,7 +16,7 @@
'use strict';
var Pet = function Pet(photoUrls, name) {
var Pet = function Pet(name, photoUrls) {
/**
* datatype: String

View File

@ -29,7 +29,7 @@ var createRandomPet = function() {
describe('PetApi', function() {
it('should create and get pet', function(done) {
var pet = createRandomPet();
api.addPet(pet, function(error) {
api.addPet({body: pet}, function(error) {
if (error) throw error;
api.getPetById(pet.id, function(error, fetched, response) {