fixed headers, file upload per #662

This commit is contained in:
Tony Tam
2015-01-06 17:45:06 -08:00
parent 38ea30834a
commit ba57476181
7 changed files with 681 additions and 447 deletions

View File

@@ -1,5 +1,5 @@
// swagger-client.js // swagger-client.js
// version 2.1.0-alpha.4 // version 2.1.0-alpha.5
/** /**
* Array Model * Array Model
**/ **/
@@ -538,18 +538,21 @@ var OperationGroup = function(tag, operation) {
var Operation = function(parent, operationId, httpMethod, path, args, definitions) { var Operation = function(parent, operationId, httpMethod, path, args, definitions) {
var errors = []; var errors = [];
parent = parent||{};
args = args||{};
this.operation = args; this.operation = args;
this.deprecated = args.deprecated; this.deprecated = args.deprecated;
this.consumes = args.consumes; this.consumes = args.consumes;
this.produces = args.produces; this.produces = args.produces;
this.parent = parent; this.parent = parent;
this.host = parent.host; this.host = parent.host || 'localhost';
this.schemes = parent.schemes; this.schemes = parent.schemes;
this.scheme = parent.scheme || 'http'; this.scheme = parent.scheme || 'http';
this.basePath = parent.basePath; this.basePath = parent.basePath || '/';
this.nickname = (operationId||errors.push('Operations must have a nickname.')); this.nickname = (operationId||errors.push('Operations must have a nickname.'));
this.method = (httpMethod||errors.push('Operation ' + operationId + ' is missing method.')); this.method = (httpMethod||errors.push('Operation ' + operationId + ' is missing method.'));
this.path = (path||errors.push('Operation ' + nickname + ' is missing path.')); this.path = (path||errors.push('Operation ' + this.nickname + ' is missing path.'));
this.parameters = args != null ? (args.parameters||[]) : {}; this.parameters = args != null ? (args.parameters||[]) : {};
this.summary = args.summary || ''; this.summary = args.summary || '';
this.responses = (args.responses||{}); this.responses = (args.responses||{});
@@ -643,8 +646,10 @@ var Operation = function(parent, operationId, httpMethod, path, args, definition
} }
} }
if (errors.length > 0) if (errors.length > 0) {
if(this.resource && this.resource.api && this.resource.api.fail)
this.resource.api.fail(errors); this.resource.api.fail(errors);
}
return this; return this;
} }
@@ -719,12 +724,16 @@ Operation.prototype.resolveModel = function (schema, definitions) {
return null; return null;
} }
Operation.prototype.help = function() { Operation.prototype.help = function(dontPrint) {
log(this.nickname + ': ' + this.operation.summary); var out = this.nickname + ': ' + this.summary + '\n';
for(var i = 0; i < this.parameters.length; i++) { for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i]; var param = this.parameters[i];
log(' * ' + param.name + ': ' + param.description); var typeInfo = typeFromJsonSchema(param.type, param.format);
out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description;
} }
if(typeof dontPrint === 'undefined')
log(out);
return out;
} }
Operation.prototype.getSignature = function(type, models) { Operation.prototype.getSignature = function(type, models) {
@@ -749,6 +758,121 @@ Operation.prototype.getSignature = function(type, models) {
} }
}; };
Operation.prototype.supportHeaderParams = function () {
return true;
};
Operation.prototype.supportedSubmitMethods = function () {
return this.resource.api.supportedSubmitMethods;
};
Operation.prototype.getHeaderParams = function (args) {
var headers = this.setContentTypes(args, {});
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if (param.in === 'header') {
var value = args[param.name];
if(Array.isArray(value))
value = this.encodePathCollection(param.collectionFormat, param.name, value);
else
value = this.encodePathParam(value);
headers[param.name] = value;
}
}
}
return headers;
}
Operation.prototype.urlify = function (args) {
var formParams = {};
var requestUrl = this.path;
// grab params from the args, build the querystring along the way
var querystring = '';
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if(param.in === 'path') {
var reg = new RegExp('\{' + param.name + '[^\}]*\}', 'gi');
var value = args[param.name];
if(Array.isArray(value))
value = this.encodePathCollection(param.collectionFormat, param.name, value);
else
value = this.encodePathParam(value);
requestUrl = requestUrl.replace(reg, value);
}
else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
if(querystring === '')
querystring += '?';
else
querystring += '&';
if(typeof param.collectionFormat !== 'undefined') {
var qp = args[param.name];
if(Array.isArray(qp))
querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp);
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else if (param.in === 'formData')
formParams[param.name] = args[param.name];
}
}
var url = this.scheme + '://' + this.host;
if(this.basePath !== '/')
url += this.basePath;
return url + requestUrl + querystring;
}
Operation.prototype.getMissingParams = function(args) {
var missingParams = [];
// check required params, track the ones that are missing
var i;
for(i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(param.required === true) {
if(typeof args[param.name] === 'undefined')
missingParams = param.name;
}
}
return missingParams;
}
Operation.prototype.getBody = function(headers, args) {
var formParams = {};
var body;
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if (param.in === 'body')
body = args[param.name];
}
}
// handle form params
if(headers['Content-Type'] === 'application/x-www-form-urlencoded') {
var encoded = "";
var key;
for(key in formParams) {
value = formParams[key];
if(typeof value !== 'undefined'){
if(encoded !== "")
encoded += "&";
encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
}
body = encoded;
}
return body;
}
/** /**
* gets sample response for a single operation * gets sample response for a single operation
**/ **/
@@ -778,7 +902,7 @@ Operation.prototype.getSampleJSON = function(type, models) {
else else
return sampleJson; return sampleJson;
} }
}; }
/** /**
* legacy binding * legacy binding
@@ -787,112 +911,42 @@ Operation.prototype["do"] = function(args, opts, callback, error, parent) {
return this.execute(args, opts, callback, error, parent); return this.execute(args, opts, callback, error, parent);
} }
/** /**
* executes an operation * executes an operation
**/ **/
Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) { Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) {
var args = (arg1||{}); var args = arg1 || {};
var opts = {}, success, error; var opts = {}, success, error;
if(typeof arg2 === 'object') { if(typeof arg2 === 'object') {
opts = arg2; opts = arg2;
success = arg3; success = arg3;
error = arg4; error = arg4;
} }
if(typeof arg2 === 'function') { if(typeof arg2 === 'function') {
success = arg2; success = arg2;
error = arg3; error = arg3;
} }
var formParams = {};
var headers = {};
var requestUrl = this.path;
success = (success||log) success = (success||log)
error = (error||log) error = (error||log)
var requiredParams = []; var missingParams = this.getMissingParams(args);
var missingParams = [];
// check required params, track the ones that are missing
var i;
for(i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(param.required === true) {
requiredParams.push(param.name);
if(typeof args[param.name] === 'undefined')
missingParams = param.name;
}
}
if(missingParams.length > 0) { if(missingParams.length > 0) {
var message = 'missing required params: ' + missingParams; var message = 'missing required params: ' + missingParams;
fail(message); fail(message);
return; return;
} }
// set content type negotiation var headers = this.getHeaderParams(args);
var consumes = this.consumes || this.parent.consumes || [ 'application/json' ]; var body = this.getBody(headers, args);
var produces = this.produces || this.parent.produces || [ 'application/json' ]; var url = this.urlify(args)
headers = this.setContentTypes(args, opts);
// grab params from the args, build the querystring along the way
var querystring = "";
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if(param.in === 'path') {
var reg = new RegExp('\{' + param.name + '[^\}]*\}', 'gi');
requestUrl = requestUrl.replace(reg, this.encodePathParam(args[param.name]));
}
else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
if(querystring === '')
querystring += '?';
else
querystring += '&';
if(typeof param.collectionFormat !== 'undefined') {
var qp = args[param.name];
if(Array.isArray(qp))
querystring += this.encodeCollection(param.collectionFormat, param.name, qp);
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else if (param.in === 'header')
headers[param.name] = args[param.name];
else if (param.in === 'formData')
formParams[param.name] = args[param.name];
else if (param.in === 'body')
args.body = args[param.name];
}
}
// handle form params
if(headers['Content-Type'] === 'application/x-www-form-urlencoded') {
var encoded = "";
var key;
for(key in formParams) {
value = formParams[key];
if(typeof value !== 'undefined'){
if(encoded !== "")
encoded += "&";
encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
}
// todo append?
args.body = encoded;
}
var url = this.scheme + '://' + this.host;
if(this.basePath !== '/')
url += this.basePath;
url += requestUrl + querystring;
var obj = { var obj = {
url: url, url: url,
method: this.method, method: this.method,
body: args.body, body: body,
useJQuery: this.useJQuery, useJQuery: this.useJQuery,
headers: headers, headers: headers,
on: { on: {
@@ -911,46 +965,53 @@ Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) {
Operation.prototype.setContentTypes = function(args, opts) { Operation.prototype.setContentTypes = function(args, opts) {
// default type // default type
var accepts = 'application/json'; var accepts = 'application/json';
var consumes = 'application/json'; var consumes = args.parameterContentType || 'application/json';
var allDefinedParams = this.parameters; var allDefinedParams = this.parameters;
var definedFormParams = []; var definedFormParams = [];
var definedFileParams = []; var definedFileParams = [];
var body = args.body; var body;
var headers = {}; var headers = {};
// get params from the operation and set them in definedFileParams, definedFormParams, headers // get params from the operation and set them in definedFileParams, definedFormParams, headers
var i; var i;
for(i = 0; i < allDefinedParams.length; i++) { for(i = 0; i < allDefinedParams.length; i++) {
var param = allDefinedParams[i]; var param = allDefinedParams[i];
if(param.in === 'formData') if(param.in === 'formData') {
definedFormParams.push(param); if(param.type === 'file')
else if(param.in === 'file')
definedFileParams.push(param); definedFileParams.push(param);
else
definedFormParams.push(param);
}
else if(param.in === 'header' && this.headers) { else if(param.in === 'header' && this.headers) {
var key = param.name; var key = param.name;
var headerValue = this.headers[param.name]; var headerValue = this.headers[param.name];
if(typeof this.headers[param.name] !== 'undefined') if(typeof this.headers[param.name] !== 'undefined')
headers[key] = headerValue; headers[key] = headerValue;
} }
else if(param.in === 'body' && typeof args[param.name] !== 'undefined') {
body = args[param.name];
}
} }
// if there's a body, need to set the accepts header via requestContentType // if there's a body, need to set the consumes header via requestContentType
if (body && (this.method === 'post' || this.method === 'put' || this.method === 'patch' || this.method === 'delete')) { if (body && (this.method === 'post' || this.method === 'put' || this.method === 'patch' || this.method === 'delete')) {
if (opts.requestContentType) if (opts.requestContentType)
consumes = opts.requestContentType; consumes = opts.requestContentType;
} else { } else {
// if any form params, content type must be set // if any form params, content type must be set
if(definedFormParams.length > 0) { if(definedFormParams.length > 0) {
if(definedFileParams.length > 0) if(opts.requestContentType) // override if set
consumes = opts.requestContentType;
else if(definedFileParams.length > 0) // if a file, must be multipart/form-data
consumes = 'multipart/form-data'; consumes = 'multipart/form-data';
else else // default to x-www-from-urlencoded
consumes = 'application/x-www-form-urlencoded'; consumes = 'application/x-www-form-urlencoded';
} }
else if (this.type == 'DELETE') else if (this.type == 'DELETE')
body = '{}'; body = '{}';
else if (this.type != 'DELETE') else if (this.type != 'DELETE')
accepts = null; consumes = null;
} }
if (consumes && this.consumes) { if (consumes && this.consumes) {
@@ -979,7 +1040,40 @@ Operation.prototype.setContentTypes = function(args, opts) {
return headers; return headers;
} }
Operation.prototype.encodeCollection = function(type, name, value) { Operation.prototype.asCurl = function (args) {
var results = [];
var headers = this.getHeaderParams(args);
if (headers) {
var key;
for (key in headers)
results.push("--header \"" + key + ": " + headers[key] + "\"");
}
return "curl " + (results.join(" ")) + " " + this.urlify(args);
}
Operation.prototype.encodePathCollection = function(type, name, value) {
var encoded = '';
var i;
var separator = '';
if(type === 'ssv')
separator = '%20';
else if(type === 'tsv')
separator = '\\t';
else if(type === 'pipes')
separator = '|';
else
separator = ',';
for(i = 0; i < value.length; i++) {
if(i == 0)
encoded = this.encodeQueryParam(value[i]);
else
encoded += separator + this.encodeQueryParam(value[i]);
}
return encoded;
}
Operation.prototype.encodeQueryCollection = function(type, name, value) {
var encoded = ''; var encoded = '';
var i; var i;
if(type === 'default' || type === 'multi') { if(type === 'default' || type === 'multi') {
@@ -998,6 +1092,13 @@ Operation.prototype.encodeCollection = function(type, name, value) {
separator = '\\t'; separator = '\\t';
else if(type === 'pipes') else if(type === 'pipes')
separator = '|'; separator = '|';
else if(type === 'brackets') {
for(i = 0; i < value.length; i++) {
if(i !== 0)
encoded += '&';
encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]);
}
}
if(separator !== '') { if(separator !== '') {
for(i = 0; i < value.length; i++) { for(i = 0; i < value.length; i++) {
if(i == 0) if(i == 0)
@@ -1007,7 +1108,6 @@ Operation.prototype.encodeCollection = function(type, name, value) {
} }
} }
} }
// TODO: support the different encoding schemes here
return encoded; return encoded;
} }
@@ -1022,16 +1122,15 @@ Operation.prototype.encodeQueryParam = function(arg) {
* TODO revisit, might not want to leave '/' * TODO revisit, might not want to leave '/'
**/ **/
Operation.prototype.encodePathParam = function(pathParam) { Operation.prototype.encodePathParam = function(pathParam) {
var encParts, part, parts, _i, _len; var encParts, part, parts, i, len;
pathParam = pathParam.toString(); pathParam = pathParam.toString();
if (pathParam.indexOf('/') === -1) { if (pathParam.indexOf('/') === -1) {
return encodeURIComponent(pathParam); return encodeURIComponent(pathParam);
} else { } else {
parts = pathParam.split('/'); parts = pathParam.split('/');
encParts = []; encParts = [];
for (_i = 0, _len = parts.length; _i < _len; _i++) { for (i = 0, len = parts.length; i < len; i++) {
part = parts[_i]; encParts.push(encodeURIComponent(parts[i]));
encParts.push(encodeURIComponent(part));
} }
return encParts.join('/'); return encParts.join('/');
} }
@@ -1278,7 +1377,7 @@ e.ApiKeyAuthorization = ApiKeyAuthorization;
e.PasswordAuthorization = PasswordAuthorization; e.PasswordAuthorization = PasswordAuthorization;
e.CookieAuthorization = CookieAuthorization; e.CookieAuthorization = CookieAuthorization;
e.SwaggerClient = SwaggerClient; e.SwaggerClient = SwaggerClient;
e.Operation = Operation;
/** /**
* SwaggerHttp is a wrapper for executing requests * SwaggerHttp is a wrapper for executing requests
*/ */

468
dist/lib/swagger.js vendored

File diff suppressed because it is too large Load Diff

6
dist/swagger-ui.js vendored
View File

@@ -1192,11 +1192,11 @@ function program3(depth0,data) {
if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); } if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1) buffer += escapeExpression(stack1)
+ "\">\n List Operations\n </a>\n </li>\n <li>\n <a href='#' class=\"expandResource\" data-id="; + "\">\n List Operations\n </a>\n </li>\n <li>\n <a href='#' class=\"expandResource\" data-id=\"";
if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); } if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1) buffer += escapeExpression(stack1)
+ ">\n Expand Operations\n </a>\n </li>\n "; + "\">\n Expand Operations\n </a>\n </li>\n ";
options = {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data}; options = {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data};
if (stack1 = helpers.url) { stack1 = stack1.call(depth0, options); } if (stack1 = helpers.url) { stack1 = stack1.call(depth0, options); }
else { stack1 = depth0.url; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } else { stack1 = depth0.url; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
@@ -2057,7 +2057,7 @@ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
params += 1; params += 1;
} }
} }
this.invocationUrl = this.model.supportHeaderParams() ? (headerParams = this.model.getHeaderParams(map), this.model.urlify(map, false)) : this.model.urlify(map, true); this.invocationUrl = this.model.supportHeaderParams() ? (headerParams = this.model.getHeaderParams(map), delete headerParams['Content-Type'], this.model.urlify(map, false)) : this.model.urlify(map, true);
$(".request_url", $(this.el)).html("<pre></pre>"); $(".request_url", $(this.el)).html("<pre></pre>");
$(".request_url pre", $(this.el)).text(this.invocationUrl); $(".request_url pre", $(this.el)).text(this.invocationUrl);
obj = { obj = {

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
// swagger-client.js // swagger-client.js
// version 2.1.0-alpha.4 // version 2.1.0-alpha.5
/** /**
* Array Model * Array Model
**/ **/
@@ -538,18 +538,21 @@ var OperationGroup = function(tag, operation) {
var Operation = function(parent, operationId, httpMethod, path, args, definitions) { var Operation = function(parent, operationId, httpMethod, path, args, definitions) {
var errors = []; var errors = [];
parent = parent||{};
args = args||{};
this.operation = args; this.operation = args;
this.deprecated = args.deprecated; this.deprecated = args.deprecated;
this.consumes = args.consumes; this.consumes = args.consumes;
this.produces = args.produces; this.produces = args.produces;
this.parent = parent; this.parent = parent;
this.host = parent.host; this.host = parent.host || 'localhost';
this.schemes = parent.schemes; this.schemes = parent.schemes;
this.scheme = parent.scheme || 'http'; this.scheme = parent.scheme || 'http';
this.basePath = parent.basePath; this.basePath = parent.basePath || '/';
this.nickname = (operationId||errors.push('Operations must have a nickname.')); this.nickname = (operationId||errors.push('Operations must have a nickname.'));
this.method = (httpMethod||errors.push('Operation ' + operationId + ' is missing method.')); this.method = (httpMethod||errors.push('Operation ' + operationId + ' is missing method.'));
this.path = (path||errors.push('Operation ' + nickname + ' is missing path.')); this.path = (path||errors.push('Operation ' + this.nickname + ' is missing path.'));
this.parameters = args != null ? (args.parameters||[]) : {}; this.parameters = args != null ? (args.parameters||[]) : {};
this.summary = args.summary || ''; this.summary = args.summary || '';
this.responses = (args.responses||{}); this.responses = (args.responses||{});
@@ -643,8 +646,10 @@ var Operation = function(parent, operationId, httpMethod, path, args, definition
} }
} }
if (errors.length > 0) if (errors.length > 0) {
if(this.resource && this.resource.api && this.resource.api.fail)
this.resource.api.fail(errors); this.resource.api.fail(errors);
}
return this; return this;
} }
@@ -719,12 +724,16 @@ Operation.prototype.resolveModel = function (schema, definitions) {
return null; return null;
} }
Operation.prototype.help = function() { Operation.prototype.help = function(dontPrint) {
log(this.nickname + ': ' + this.operation.summary); var out = this.nickname + ': ' + this.summary + '\n';
for(var i = 0; i < this.parameters.length; i++) { for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i]; var param = this.parameters[i];
log(' * ' + param.name + ': ' + param.description); var typeInfo = typeFromJsonSchema(param.type, param.format);
out += '\n * ' + param.name + ' (' + typeInfo + '): ' + param.description;
} }
if(typeof dontPrint === 'undefined')
log(out);
return out;
} }
Operation.prototype.getSignature = function(type, models) { Operation.prototype.getSignature = function(type, models) {
@@ -749,6 +758,121 @@ Operation.prototype.getSignature = function(type, models) {
} }
}; };
Operation.prototype.supportHeaderParams = function () {
return true;
};
Operation.prototype.supportedSubmitMethods = function () {
return this.resource.api.supportedSubmitMethods;
};
Operation.prototype.getHeaderParams = function (args) {
var headers = this.setContentTypes(args, {});
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if (param.in === 'header') {
var value = args[param.name];
if(Array.isArray(value))
value = this.encodePathCollection(param.collectionFormat, param.name, value);
else
value = this.encodePathParam(value);
headers[param.name] = value;
}
}
}
return headers;
}
Operation.prototype.urlify = function (args) {
var formParams = {};
var requestUrl = this.path;
// grab params from the args, build the querystring along the way
var querystring = '';
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if(param.in === 'path') {
var reg = new RegExp('\{' + param.name + '[^\}]*\}', 'gi');
var value = args[param.name];
if(Array.isArray(value))
value = this.encodePathCollection(param.collectionFormat, param.name, value);
else
value = this.encodePathParam(value);
requestUrl = requestUrl.replace(reg, value);
}
else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
if(querystring === '')
querystring += '?';
else
querystring += '&';
if(typeof param.collectionFormat !== 'undefined') {
var qp = args[param.name];
if(Array.isArray(qp))
querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp);
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else if (param.in === 'formData')
formParams[param.name] = args[param.name];
}
}
var url = this.scheme + '://' + this.host;
if(this.basePath !== '/')
url += this.basePath;
return url + requestUrl + querystring;
}
Operation.prototype.getMissingParams = function(args) {
var missingParams = [];
// check required params, track the ones that are missing
var i;
for(i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(param.required === true) {
if(typeof args[param.name] === 'undefined')
missingParams = param.name;
}
}
return missingParams;
}
Operation.prototype.getBody = function(headers, args) {
var formParams = {};
var body;
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if (param.in === 'body')
body = args[param.name];
}
}
// handle form params
if(headers['Content-Type'] === 'application/x-www-form-urlencoded') {
var encoded = "";
var key;
for(key in formParams) {
value = formParams[key];
if(typeof value !== 'undefined'){
if(encoded !== "")
encoded += "&";
encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
}
body = encoded;
}
return body;
}
/** /**
* gets sample response for a single operation * gets sample response for a single operation
**/ **/
@@ -778,7 +902,7 @@ Operation.prototype.getSampleJSON = function(type, models) {
else else
return sampleJson; return sampleJson;
} }
}; }
/** /**
* legacy binding * legacy binding
@@ -787,112 +911,42 @@ Operation.prototype["do"] = function(args, opts, callback, error, parent) {
return this.execute(args, opts, callback, error, parent); return this.execute(args, opts, callback, error, parent);
} }
/** /**
* executes an operation * executes an operation
**/ **/
Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) { Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) {
var args = (arg1||{}); var args = arg1 || {};
var opts = {}, success, error; var opts = {}, success, error;
if(typeof arg2 === 'object') { if(typeof arg2 === 'object') {
opts = arg2; opts = arg2;
success = arg3; success = arg3;
error = arg4; error = arg4;
} }
if(typeof arg2 === 'function') { if(typeof arg2 === 'function') {
success = arg2; success = arg2;
error = arg3; error = arg3;
} }
var formParams = {};
var headers = {};
var requestUrl = this.path;
success = (success||log) success = (success||log)
error = (error||log) error = (error||log)
var requiredParams = []; var missingParams = this.getMissingParams(args);
var missingParams = [];
// check required params, track the ones that are missing
var i;
for(i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(param.required === true) {
requiredParams.push(param.name);
if(typeof args[param.name] === 'undefined')
missingParams = param.name;
}
}
if(missingParams.length > 0) { if(missingParams.length > 0) {
var message = 'missing required params: ' + missingParams; var message = 'missing required params: ' + missingParams;
fail(message); fail(message);
return; return;
} }
// set content type negotiation var headers = this.getHeaderParams(args);
var consumes = this.consumes || this.parent.consumes || [ 'application/json' ]; var body = this.getBody(headers, args);
var produces = this.produces || this.parent.produces || [ 'application/json' ]; var url = this.urlify(args)
headers = this.setContentTypes(args, opts);
// grab params from the args, build the querystring along the way
var querystring = "";
for(var i = 0; i < this.parameters.length; i++) {
var param = this.parameters[i];
if(typeof args[param.name] !== 'undefined') {
if(param.in === 'path') {
var reg = new RegExp('\{' + param.name + '[^\}]*\}', 'gi');
requestUrl = requestUrl.replace(reg, this.encodePathParam(args[param.name]));
}
else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
if(querystring === '')
querystring += '?';
else
querystring += '&';
if(typeof param.collectionFormat !== 'undefined') {
var qp = args[param.name];
if(Array.isArray(qp))
querystring += this.encodeCollection(param.collectionFormat, param.name, qp);
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else
querystring += this.encodeQueryParam(param.name) + '=' + this.encodeQueryParam(args[param.name]);
}
else if (param.in === 'header')
headers[param.name] = args[param.name];
else if (param.in === 'formData')
formParams[param.name] = args[param.name];
else if (param.in === 'body')
args.body = args[param.name];
}
}
// handle form params
if(headers['Content-Type'] === 'application/x-www-form-urlencoded') {
var encoded = "";
var key;
for(key in formParams) {
value = formParams[key];
if(typeof value !== 'undefined'){
if(encoded !== "")
encoded += "&";
encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
}
// todo append?
args.body = encoded;
}
var url = this.scheme + '://' + this.host;
if(this.basePath !== '/')
url += this.basePath;
url += requestUrl + querystring;
var obj = { var obj = {
url: url, url: url,
method: this.method, method: this.method,
body: args.body, body: body,
useJQuery: this.useJQuery, useJQuery: this.useJQuery,
headers: headers, headers: headers,
on: { on: {
@@ -911,46 +965,53 @@ Operation.prototype.execute = function(arg1, arg2, arg3, arg4, parent) {
Operation.prototype.setContentTypes = function(args, opts) { Operation.prototype.setContentTypes = function(args, opts) {
// default type // default type
var accepts = 'application/json'; var accepts = 'application/json';
var consumes = 'application/json'; var consumes = args.parameterContentType || 'application/json';
var allDefinedParams = this.parameters; var allDefinedParams = this.parameters;
var definedFormParams = []; var definedFormParams = [];
var definedFileParams = []; var definedFileParams = [];
var body = args.body; var body;
var headers = {}; var headers = {};
// get params from the operation and set them in definedFileParams, definedFormParams, headers // get params from the operation and set them in definedFileParams, definedFormParams, headers
var i; var i;
for(i = 0; i < allDefinedParams.length; i++) { for(i = 0; i < allDefinedParams.length; i++) {
var param = allDefinedParams[i]; var param = allDefinedParams[i];
if(param.in === 'formData') if(param.in === 'formData') {
definedFormParams.push(param); if(param.type === 'file')
else if(param.in === 'file')
definedFileParams.push(param); definedFileParams.push(param);
else
definedFormParams.push(param);
}
else if(param.in === 'header' && this.headers) { else if(param.in === 'header' && this.headers) {
var key = param.name; var key = param.name;
var headerValue = this.headers[param.name]; var headerValue = this.headers[param.name];
if(typeof this.headers[param.name] !== 'undefined') if(typeof this.headers[param.name] !== 'undefined')
headers[key] = headerValue; headers[key] = headerValue;
} }
else if(param.in === 'body' && typeof args[param.name] !== 'undefined') {
body = args[param.name];
}
} }
// if there's a body, need to set the accepts header via requestContentType // if there's a body, need to set the consumes header via requestContentType
if (body && (this.method === 'post' || this.method === 'put' || this.method === 'patch' || this.method === 'delete')) { if (body && (this.method === 'post' || this.method === 'put' || this.method === 'patch' || this.method === 'delete')) {
if (opts.requestContentType) if (opts.requestContentType)
consumes = opts.requestContentType; consumes = opts.requestContentType;
} else { } else {
// if any form params, content type must be set // if any form params, content type must be set
if(definedFormParams.length > 0) { if(definedFormParams.length > 0) {
if(definedFileParams.length > 0) if(opts.requestContentType) // override if set
consumes = opts.requestContentType;
else if(definedFileParams.length > 0) // if a file, must be multipart/form-data
consumes = 'multipart/form-data'; consumes = 'multipart/form-data';
else else // default to x-www-from-urlencoded
consumes = 'application/x-www-form-urlencoded'; consumes = 'application/x-www-form-urlencoded';
} }
else if (this.type == 'DELETE') else if (this.type == 'DELETE')
body = '{}'; body = '{}';
else if (this.type != 'DELETE') else if (this.type != 'DELETE')
accepts = null; consumes = null;
} }
if (consumes && this.consumes) { if (consumes && this.consumes) {
@@ -979,7 +1040,40 @@ Operation.prototype.setContentTypes = function(args, opts) {
return headers; return headers;
} }
Operation.prototype.encodeCollection = function(type, name, value) { Operation.prototype.asCurl = function (args) {
var results = [];
var headers = this.getHeaderParams(args);
if (headers) {
var key;
for (key in headers)
results.push("--header \"" + key + ": " + headers[key] + "\"");
}
return "curl " + (results.join(" ")) + " " + this.urlify(args);
}
Operation.prototype.encodePathCollection = function(type, name, value) {
var encoded = '';
var i;
var separator = '';
if(type === 'ssv')
separator = '%20';
else if(type === 'tsv')
separator = '\\t';
else if(type === 'pipes')
separator = '|';
else
separator = ',';
for(i = 0; i < value.length; i++) {
if(i == 0)
encoded = this.encodeQueryParam(value[i]);
else
encoded += separator + this.encodeQueryParam(value[i]);
}
return encoded;
}
Operation.prototype.encodeQueryCollection = function(type, name, value) {
var encoded = ''; var encoded = '';
var i; var i;
if(type === 'default' || type === 'multi') { if(type === 'default' || type === 'multi') {
@@ -998,6 +1092,13 @@ Operation.prototype.encodeCollection = function(type, name, value) {
separator = '\\t'; separator = '\\t';
else if(type === 'pipes') else if(type === 'pipes')
separator = '|'; separator = '|';
else if(type === 'brackets') {
for(i = 0; i < value.length; i++) {
if(i !== 0)
encoded += '&';
encoded += this.encodeQueryParam(name) + '[]=' + this.encodeQueryParam(value[i]);
}
}
if(separator !== '') { if(separator !== '') {
for(i = 0; i < value.length; i++) { for(i = 0; i < value.length; i++) {
if(i == 0) if(i == 0)
@@ -1007,7 +1108,6 @@ Operation.prototype.encodeCollection = function(type, name, value) {
} }
} }
} }
// TODO: support the different encoding schemes here
return encoded; return encoded;
} }
@@ -1022,16 +1122,15 @@ Operation.prototype.encodeQueryParam = function(arg) {
* TODO revisit, might not want to leave '/' * TODO revisit, might not want to leave '/'
**/ **/
Operation.prototype.encodePathParam = function(pathParam) { Operation.prototype.encodePathParam = function(pathParam) {
var encParts, part, parts, _i, _len; var encParts, part, parts, i, len;
pathParam = pathParam.toString(); pathParam = pathParam.toString();
if (pathParam.indexOf('/') === -1) { if (pathParam.indexOf('/') === -1) {
return encodeURIComponent(pathParam); return encodeURIComponent(pathParam);
} else { } else {
parts = pathParam.split('/'); parts = pathParam.split('/');
encParts = []; encParts = [];
for (_i = 0, _len = parts.length; _i < _len; _i++) { for (i = 0, len = parts.length; i < len; i++) {
part = parts[_i]; encParts.push(encodeURIComponent(parts[i]));
encParts.push(encodeURIComponent(part));
} }
return encParts.join('/'); return encParts.join('/');
} }
@@ -1278,7 +1377,7 @@ e.ApiKeyAuthorization = ApiKeyAuthorization;
e.PasswordAuthorization = PasswordAuthorization; e.PasswordAuthorization = PasswordAuthorization;
e.CookieAuthorization = CookieAuthorization; e.CookieAuthorization = CookieAuthorization;
e.SwaggerClient = SwaggerClient; e.SwaggerClient = SwaggerClient;
e.Operation = Operation;
/** /**
* SwaggerHttp is a wrapper for executing requests * SwaggerHttp is a wrapper for executing requests
*/ */

View File

@@ -19,8 +19,13 @@
"readmeFilename": "README.md", "readmeFilename": "README.md",
"dependencies": { "dependencies": {
"coffee-script": "~1.6.3", "coffee-script": "~1.6.3",
"swagger-client": "2.0.41", "swagger-client": "2.0.48",
"handlebars": "~1.0.10", "handlebars": "~1.0.10",
"less": "~1.4.2" "less": "~1.4.2"
},
"devDependencies": {
"express": "3.x",
"docco": "0.4.x",
"cors": "2.1.1"
} }
} }

View File

@@ -229,6 +229,7 @@ class OperationView extends Backbone.View
@invocationUrl = @invocationUrl =
if @model.supportHeaderParams() if @model.supportHeaderParams()
headerParams = @model.getHeaderParams(map) headerParams = @model.getHeaderParams(map)
delete headerParams['Content-Type']
@model.urlify(map, false) @model.urlify(map, false)
else else
@model.urlify(map, true) @model.urlify(map, true)