swagger-client
Advanced tools
Comparing version 2.1.5-M2 to 2.1.5
@@ -20,3 +20,3 @@ 'use strict'; | ||
}; | ||
}; | ||
} | ||
@@ -35,3 +35,3 @@ /* Here for IE8 Support */ | ||
}; | ||
}; | ||
} | ||
@@ -45,1 +45,2 @@ module.exports = SwaggerClient; | ||
SwaggerClient.SwaggerClient = deprecationWrapper; | ||
SwaggerClient.SchemaMarkup = require('./lib/schema-markup'); |
102
lib/auth.js
'use strict'; | ||
var helpers = require('./helpers'); | ||
var btoa = require('btoa'); // jshint ignore:line | ||
var CookieJar = require('cookiejar'); | ||
var _ = { | ||
each: require('lodash-compat/collection/each'), | ||
includes: require('lodash-compat/collection/includes'), | ||
isObject: require('lodash-compat/lang/isObject'), | ||
isArray: require('lodash-compat/lang/isArray') | ||
}; | ||
@@ -9,8 +16,19 @@ /** | ||
*/ | ||
var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function () { | ||
this.authz = {}; | ||
var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) { | ||
this.authz = authz || {}; | ||
}; | ||
/** | ||
* Add auths to the hash | ||
* Will overwrite any existing | ||
* | ||
*/ | ||
SwaggerAuthorizations.prototype.add = function (name, auth) { | ||
this.authz[name] = auth; | ||
if(_.isObject(name)) { | ||
for (var key in name) { | ||
this.authz[key] = name[key]; | ||
} | ||
} else if(typeof name === 'string' ){ | ||
this.authz[name] = auth; | ||
} | ||
@@ -24,51 +42,27 @@ return auth; | ||
SwaggerAuthorizations.prototype.apply = function (obj, authorizations) { | ||
var status = null; | ||
var key, name, value, result; | ||
SwaggerAuthorizations.prototype.apply = function (obj, securities) { | ||
var status = true; | ||
var applyAll = !securities; | ||
var flattenedSecurities = []; | ||
// Apply all authorizations if there were no authorizations to apply | ||
if (typeof authorizations === 'undefined') { | ||
for (key in this.authz) { | ||
value = this.authz[key]; | ||
result = value.apply(obj, authorizations); | ||
// Securities could be [ {} ] | ||
_.each(securities, function (obj, key) { | ||
if (result === true) { | ||
status = true; | ||
} | ||
// Make sure we account for securities being [ str ] | ||
if(typeof key === 'string') { | ||
flattenedSecurities.push(key); | ||
} | ||
} else { | ||
// 2.0 support | ||
if (Array.isArray(authorizations)) { | ||
for (var i = 0; i < authorizations.length; i++) { | ||
var auth = authorizations[i]; | ||
for (name in auth) { | ||
for (key in this.authz) { | ||
if (key === name) { | ||
value = this.authz[key]; | ||
result = value.apply(obj, authorizations); | ||
// Flatten keys in to our array | ||
_.each(obj, function (val, key) { | ||
flattenedSecurities.push(key); | ||
}); | ||
}); | ||
if (result === true) { | ||
status = true; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} else { | ||
// 1.2 support | ||
for (name in authorizations) { | ||
for (key in this.authz) { | ||
if (key === name) { | ||
value = this.authz[key]; | ||
result = value.apply(obj, authorizations); | ||
if (result === true) { | ||
status = true; | ||
} | ||
} | ||
} | ||
} | ||
_.each(this.authz, function (auth, authName) { | ||
if(applyAll || _.includes(flattenedSecurities, authName)) { | ||
var newStatus = auth.apply(obj); | ||
status = status && !!newStatus; // logical ORs regarding status | ||
} | ||
} | ||
}); | ||
@@ -97,3 +91,5 @@ return status; | ||
} else if (this.type === 'header') { | ||
obj.headers[this.name] = this.value; | ||
if(typeof obj.headers[this.name] === 'undefined') { | ||
obj.headers[this.name] = this.value; | ||
} | ||
@@ -118,4 +114,8 @@ return true; | ||
*/ | ||
var PasswordAuthorization = module.exports.PasswordAuthorization = function (name, username, password) { | ||
this.name = name; | ||
var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) { | ||
if (arguments.length === 3) { | ||
helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password'); | ||
username = arguments[1]; | ||
password = arguments[2]; | ||
} | ||
this.username = username; | ||
@@ -126,5 +126,7 @@ this.password = password; | ||
PasswordAuthorization.prototype.apply = function (obj) { | ||
obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password); | ||
if(typeof obj.headers.Authorization === 'undefined') { | ||
obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password); | ||
} | ||
return true; | ||
}; |
@@ -10,2 +10,3 @@ 'use strict'; | ||
isArray: require('lodash-compat/lang/isArray'), | ||
isObject: require('lodash-compat/lang/isObject'), | ||
isFunction: require('lodash-compat/lang/isFunction'), | ||
@@ -85,4 +86,4 @@ isPlainObject: require('lodash-compat/lang/isPlainObject'), | ||
var SwaggerClient = module.exports = function (url, options) { | ||
this.authorizations = null; | ||
this.authorizationScheme = null; | ||
this.authorizations = null; | ||
this.basePath = null; | ||
@@ -97,3 +98,6 @@ this.debug = false; | ||
this.useJQuery = false; | ||
this.swaggerObject = {}; | ||
this.clientAuthorizations = new auth.SwaggerAuthorizations(); | ||
if (typeof url !== 'undefined') { | ||
@@ -110,7 +114,5 @@ return this.initialize(url, options); | ||
options = (options || {}); | ||
if (typeof url === 'string') { | ||
this.url = url; | ||
} else if (typeof url === 'object') { | ||
} else if (_.isObject(url)) { | ||
options = url; | ||
@@ -120,2 +122,4 @@ this.url = options.url; | ||
options = options || {}; | ||
this.clientAuthorizations.add(options.authorizations); | ||
this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*'; | ||
@@ -125,3 +129,3 @@ this.defaultSuccessCallback = options.defaultSuccessCallback || null; | ||
this.modelPropertyMacro = options.modelPropertyMacro || null; | ||
this.parameterMacro = options.modelPropertyMacro || null; | ||
this.parameterMacro = options.parameterMacro || null; | ||
@@ -136,7 +140,3 @@ if (typeof options.success === 'function') { | ||
if (options.authorizations) { | ||
this.clientAuthorizations = options.authorizations; | ||
} else { | ||
this.clientAuthorizations = new auth.SwaggerAuthorizations(); | ||
} | ||
this.options = options || {}; | ||
@@ -147,4 +147,7 @@ this.supportedSubmitMethods = options.supportedSubmitMethods || []; | ||
this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document | ||
this.options = options; | ||
if (options.scheme) { | ||
this.scheme = options.scheme; | ||
} | ||
if (typeof options.success === 'function') { | ||
@@ -163,3 +166,3 @@ this.ready = true; | ||
this.progress('fetching resource list: ' + this.url); | ||
this.progress('fetching resource list: ' + this.url + '; Please wait.'); | ||
@@ -186,4 +189,10 @@ var obj = { | ||
response: function (resp) { | ||
var responseObj = resp.obj || JSON.parse(resp.data); | ||
var responseObj = resp.obj; | ||
if(!responseObj) { | ||
return self.fail('failed to parse JSON/YAML response'); | ||
} | ||
self.swaggerVersion = responseObj.swaggerVersion; | ||
self.swaggerObject = responseObj; | ||
@@ -193,3 +202,3 @@ if (responseObj.swagger && parseInt(responseObj.swagger) === 2) { | ||
new Resolver().resolve(responseObj, self.buildFromSpec, self); | ||
new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self); | ||
@@ -199,5 +208,8 @@ self.isValid = true; | ||
var converter = new SwaggerSpecConverter(); | ||
self.oldSwaggerObject = self.swaggerObject; | ||
converter.setDocumentationLocation(self.url); | ||
converter.convert(responseObj, function(spec) { | ||
new Resolver().resolve(spec, self.buildFromSpec, self); | ||
converter.convert(responseObj, self.clientAuthorizations, function(spec) { | ||
self.swaggerObject = spec; | ||
new Resolver().resolve(spec, self.url, self.buildFromSpec, self); | ||
self.isValid = true; | ||
@@ -211,5 +223,6 @@ }); | ||
if (this.spec) { | ||
self.swaggerObject = this.spec; | ||
setTimeout(function () { | ||
new Resolver().resolve(self.spec, self.buildFromSpec, self); | ||
}, 10); | ||
}, 10); | ||
} else { | ||
@@ -222,3 +235,3 @@ this.clientAuthorizations.apply(obj); | ||
new SwaggerHttp().execute(obj); | ||
new SwaggerHttp().execute(obj, this.options); | ||
} | ||
@@ -268,5 +281,5 @@ | ||
location = this.parseUri(this.url); | ||
if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { | ||
if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) { | ||
this.scheme = location.scheme || 'http'; | ||
} else { | ||
} else if (typeof this.scheme === 'undefined') { | ||
this.scheme = this.schemes[0]; | ||
@@ -287,2 +300,5 @@ } | ||
} | ||
else if (typeof this.scheme === 'undefined') { | ||
this.scheme = this.schemes[0]; | ||
} | ||
} | ||
@@ -326,3 +342,3 @@ | ||
} | ||
var tags = operation.tags; | ||
@@ -335,4 +351,11 @@ | ||
var operationId = self.idFromOp(path, method, operation); | ||
var operationObject = new Operation(self, operation.scheme, operationId, method, path, operation, | ||
self.definitions, self.models, self.clientAuthorizations); | ||
var operationObject = new Operation(self, | ||
operation.scheme, | ||
operationId, | ||
method, | ||
path, | ||
operation, | ||
self.definitions, | ||
self.models, | ||
self.clientAuthorizations); | ||
@@ -388,3 +411,3 @@ // bind self operation's execute command to the api | ||
// bind to the apis object | ||
self.apis[apiProperty][operationId] = operationGroup[operationId]= _.bind(operationObject.execute, | ||
self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute, | ||
operationObject); | ||
@@ -480,2 +503,30 @@ self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help, | ||
SwaggerClient.prototype.setHost = function (host) { | ||
this.host = host; | ||
if(this.apis) { | ||
_.forEach(this.apis, function(api) { | ||
if(api.operations) { | ||
_.forEach(api.operations, function(operation) { | ||
operation.host = host; | ||
}); | ||
} | ||
}); | ||
} | ||
}; | ||
SwaggerClient.prototype.setBasePath = function (basePath) { | ||
this.basePath = basePath; | ||
if(this.apis) { | ||
_.forEach(this.apis, function(api) { | ||
if(api.operations) { | ||
_.forEach(api.operations, function(operation) { | ||
operation.basePath = basePath; | ||
}); | ||
} | ||
}); | ||
} | ||
}; | ||
SwaggerClient.prototype.fail = function (message) { | ||
@@ -482,0 +533,0 @@ this.failure(message); |
'use strict'; | ||
var _ = { | ||
isPlainObject: require('lodash-compat/lang/isPlainObject') | ||
isPlainObject: require('lodash-compat/lang/isPlainObject'), | ||
indexOf: require('lodash-compat/array/indexOf') | ||
}; | ||
@@ -24,3 +25,3 @@ | ||
module.exports.optionHtml = function (label, value) { | ||
var optionHtml = module.exports.optionHtml = function (label, value) { | ||
return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>'; | ||
@@ -37,30 +38,2 @@ }; | ||
module.exports.typeFromJsonSchema = function (type, format) { | ||
var str; | ||
if (type === 'integer' && format === 'int32') { | ||
str = 'integer'; | ||
} else if (type === 'integer' && format === 'int64') { | ||
str = 'long'; | ||
} else if (type === 'integer' && typeof format === 'undefined') { | ||
str = 'long'; | ||
} else if (type === 'string' && format === 'date-time') { | ||
str = 'date-time'; | ||
} else if (type === 'string' && format === 'date') { | ||
str = 'date'; | ||
} else if (type === 'number' && format === 'float') { | ||
str = 'float'; | ||
} else if (type === 'number' && format === 'double') { | ||
str = 'double'; | ||
} else if (type === 'number' && typeof format === 'undefined') { | ||
str = 'double'; | ||
} else if (type === 'boolean') { | ||
str = 'boolean'; | ||
} else if (type === 'string') { | ||
str = 'string'; | ||
} | ||
return str; | ||
}; | ||
var simpleRef = module.exports.simpleRef = function (name) { | ||
@@ -78,44 +51,1 @@ if (typeof name === 'undefined') { | ||
var getStringSignature = module.exports.getStringSignature = function (obj, baseComponent) { | ||
var str = ''; | ||
if (typeof obj.$ref !== 'undefined') { | ||
str += simpleRef(obj.$ref); | ||
} else if (typeof obj.type === 'undefined') { | ||
str += 'object'; | ||
} else if (obj.type === 'array') { | ||
if (baseComponent) { | ||
str += getStringSignature((obj.items || obj.$ref || {})); | ||
} else { | ||
str += 'Array['; | ||
str += getStringSignature((obj.items || obj.$ref || {})); | ||
str += ']'; | ||
} | ||
} else if (obj.type === 'integer' && obj.format === 'int32') { | ||
str += 'integer'; | ||
} else if (obj.type === 'integer' && obj.format === 'int64') { | ||
str += 'long'; | ||
} else if (obj.type === 'integer' && typeof obj.format === 'undefined') { | ||
str += 'long'; | ||
} else if (obj.type === 'string' && obj.format === 'date-time') { | ||
str += 'date-time'; | ||
} else if (obj.type === 'string' && obj.format === 'date') { | ||
str += 'date'; | ||
} else if (obj.type === 'string' && typeof obj.format === 'undefined') { | ||
str += 'string'; | ||
} else if (obj.type === 'number' && obj.format === 'float') { | ||
str += 'float'; | ||
} else if (obj.type === 'number' && obj.format === 'double') { | ||
str += 'double'; | ||
} else if (obj.type === 'number' && typeof obj.format === 'undefined') { | ||
str += 'double'; | ||
} else if (obj.type === 'boolean') { | ||
str += 'boolean'; | ||
} else if (obj.$ref) { | ||
str += simpleRef(obj.$ref); | ||
} else { | ||
str += obj.type; | ||
} | ||
return str; | ||
}; |
@@ -6,2 +6,6 @@ 'use strict'; | ||
var request = require('superagent'); | ||
var jsyaml = require('js-yaml'); | ||
var _ = { | ||
isObject: require('lodash-compat/lang/isObject') | ||
}; | ||
@@ -24,9 +28,31 @@ /* | ||
SwaggerHttp.prototype.execute = function (obj, opts) { | ||
if (obj && (typeof obj.useJQuery === 'boolean')) { | ||
this.useJQuery = obj.useJQuery; | ||
} else { | ||
this.useJQuery = this.isIE8(); | ||
var client; | ||
if(opts && opts.client) { | ||
client = opts.client; | ||
} | ||
else { | ||
client = new SuperagentHttpClient(opts); | ||
} | ||
if (obj && typeof obj.body === 'object') { | ||
// legacy support | ||
if ((obj && obj.useJQuery === true) || this.isInternetExplorer()) { | ||
client = new JQueryHttpClient(opts); | ||
} | ||
var success = obj.on.response; | ||
var responseInterceptor = function(data) { | ||
if(opts && opts.responseInterceptor) { | ||
data = opts.responseInterceptor.apply(data); | ||
} | ||
success(data); | ||
}; | ||
obj.on.response = function(data) { | ||
responseInterceptor(data); | ||
}; | ||
if (_.isObject(obj) && _.isObject(obj.body)) { | ||
// special processing for file uploads via jquery | ||
@@ -42,11 +68,6 @@ if (obj.body.type && obj.body.type === 'formData'){ | ||
} | ||
if (this.useJQuery) { | ||
return new JQueryHttpClient(opts).execute(obj); | ||
} else { | ||
return new SuperagentHttpClient(opts).execute(obj); | ||
} | ||
client.execute(obj); | ||
}; | ||
SwaggerHttp.prototype.isIE8 = function () { | ||
SwaggerHttp.prototype.isInternetExplorer = function () { | ||
var detectedIE = false; | ||
@@ -134,15 +155,13 @@ | ||
var contentType = (headers['content-type'] || headers['Content-Type'] || null); | ||
if (contentType) { | ||
if (contentType.indexOf('application/json') === 0 || contentType.indexOf('+json') > 0) { | ||
try { | ||
out.obj = response.responseJSON || JSON.parse(out.data) || {}; | ||
} catch (ex) { | ||
// do not set out.obj | ||
helpers.log('unable to parse JSON content'); | ||
} | ||
} | ||
try { | ||
var possibleObj = response.responseJSON || jsyaml.safeLoad(response.responseText); | ||
out.obj = (typeof possibleObj === 'string') ? {} : possibleObj; | ||
} catch (ex) { | ||
// do not set out.obj | ||
helpers.log('unable to parse JSON/YAML content'); | ||
} | ||
// I can throw, or parse null? | ||
out.obj = out.obj || null; | ||
if (response.status >= 200 && response.status < 300) { | ||
@@ -168,7 +187,5 @@ cb.response(out); | ||
} | ||
var headers = obj.headers || {}; | ||
var r = request[method](obj.url); | ||
var name; | ||
for (name in headers) { | ||
@@ -182,2 +199,6 @@ r.set(name, headers[name]); | ||
if(typeof r.buffer === 'function') { | ||
r.buffer(); // force superagent to populate res.text with the raw response data | ||
} | ||
r.end(function (err, res) { | ||
@@ -205,3 +226,20 @@ res = res || { | ||
} else if (res && obj.on && obj.on.response) { | ||
response.obj = (typeof res.body !== 'undefined') ? res.body : res.text; | ||
var possibleObj; | ||
// Already parsed by by superagent? | ||
if(res.body && Object.keys(res.body).length > 0) { | ||
possibleObj = res.body; | ||
} else { | ||
try { | ||
possibleObj = jsyaml.safeLoad(res.text); | ||
// can parse into a string... which we don't need running around in the system | ||
possibleObj = (typeof possibleObj === 'string') ? null : possibleObj; | ||
} catch(e) { | ||
helpers.log('cannot parse JSON/YAML content'); | ||
} | ||
} | ||
// null means we can't parse into object | ||
response.obj = possibleObj || null; | ||
response.status = res.status; | ||
@@ -208,0 +246,0 @@ response.statusText = res.text; |
'use strict'; | ||
var SwaggerHttp = require('./http'); | ||
var _ = { | ||
isObject: require('lodash-compat/lang/isObject'), | ||
isArray: require('lodash-compat/lang/isArray') | ||
}; | ||
/** | ||
/** | ||
* Resolves a spec's remote references | ||
@@ -10,18 +15,50 @@ */ | ||
Resolver.prototype.resolve = function (spec, callback, scope) { | ||
Resolver.prototype.processAllOf = function(name, definition, resolutionTable, unresolvedRefs, spec) { | ||
var i, location, property; | ||
definition['x-resolved-from'] = [ '#/definitions/' + name ]; | ||
var allOf = definition.allOf; | ||
// the refs go first | ||
allOf.sort(function(a, b) { | ||
if(a.$ref && b.$ref) { return 0; } | ||
else if(a.$ref) { return -1; } | ||
else { return 1; } | ||
}); | ||
for (i = 0; i < allOf.length; i++) { | ||
property = allOf[i]; | ||
location = '/definitions/' + name + '/allOf'; | ||
this.resolveInline(null, spec, property, resolutionTable, unresolvedRefs, location); | ||
} | ||
}; | ||
Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) { | ||
var root = arg1, callback = arg2, scope = arg3, location, i; | ||
if(typeof arg1 === 'function') { | ||
root = null; | ||
callback = arg1; | ||
scope = arg2; | ||
} | ||
var _root = root; | ||
this.scope = (scope || this); | ||
this.iteration = this.iteration || 0; | ||
var host, name, path, property, propertyName; | ||
var name, path, property, propertyName; | ||
var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {}; | ||
var resolutionTable = {}; // store objects for dereferencing | ||
var resolutionTable = []; // store objects for dereferencing | ||
// models | ||
// definitions | ||
for (name in spec.definitions) { | ||
var model = spec.definitions[name]; | ||
var definition = spec.definitions[name]; | ||
for (propertyName in definition.properties) { | ||
property = definition.properties[propertyName]; | ||
if(_.isArray(property.allOf)) { | ||
this.processAllOf(name, property, resolutionTable, unresolvedRefs, spec); | ||
} | ||
else { | ||
this.resolveTo(root, property, resolutionTable, '/definitions'); | ||
} | ||
} | ||
for (propertyName in model.properties) { | ||
property = model.properties[propertyName]; | ||
this.resolveTo(property, resolutionTable); | ||
if(definition.allOf) { | ||
this.processAllOf(name, definition, resolutionTable, unresolvedRefs, spec); | ||
} | ||
@@ -33,3 +70,2 @@ } | ||
var method, operation, responseCode; | ||
path = spec.paths[name]; | ||
@@ -40,3 +76,5 @@ | ||
if(method === '$ref') { | ||
this.resolveInline(spec, path, resolutionTable, unresolvedRefs); | ||
// location = path[method]; | ||
location = '/paths' + name; | ||
this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location); | ||
} | ||
@@ -46,9 +84,9 @@ else { | ||
var i, parameters = operation.parameters; | ||
var parameters = operation.parameters; | ||
for (i in parameters) { | ||
var parameter = parameters[i]; | ||
location = '/paths' + name + '/' + method + '/parameters'; | ||
if (parameter.in === 'body' && parameter.schema) { | ||
this.resolveTo(parameter.schema, resolutionTable); | ||
this.resolveTo(root, parameter.schema, resolutionTable, location); | ||
} | ||
@@ -58,3 +96,3 @@ | ||
// parameter reference | ||
this.resolveInline(spec, parameter, resolutionTable, unresolvedRefs); | ||
this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref); | ||
} | ||
@@ -65,11 +103,13 @@ } | ||
var response = operation.responses[responseCode]; | ||
if(typeof response === 'object') { | ||
location = '/paths' + name + '/' + method + '/responses/' + responseCode; | ||
if(_.isObject(response)) { | ||
if(response.$ref) { | ||
// response reference | ||
this.resolveInline(spec, response, resolutionTable, unresolvedRefs); | ||
this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location); | ||
} | ||
if (response.schema) { | ||
this.resolveTo(root, response.schema, resolutionTable, location); | ||
} | ||
} | ||
if (response.schema && response.schema.$ref) { | ||
this.resolveTo(response.schema, resolutionTable); | ||
} | ||
} | ||
@@ -80,156 +120,216 @@ } | ||
// get hosts | ||
var opts = {}, expectedCalls = 0; | ||
var expectedCalls = 0, toResolve = []; | ||
// if the root is same as obj[i].root we can resolve locally | ||
var all = resolutionTable; | ||
for (name in resolutionTable) { | ||
var parts = name.split('#'); | ||
var parts; | ||
for(i = 0; i < all.length; i++) { | ||
var a = all[i]; | ||
if(root === a.root) { | ||
if(a.resolveAs === 'ref') { | ||
// resolve any path walking | ||
var joined = ((a.root || '') + '/' + a.key).split('/'); | ||
var normalized = []; | ||
var url = ''; | ||
var k; | ||
if (parts.length === 2) { | ||
host = parts[0]; path = parts[1]; | ||
if (!Array.isArray(opts[host])) { | ||
opts[host] = []; | ||
expectedCalls += 1; | ||
if(a.key.indexOf('../') >= 0) { | ||
for(var j = 0; j < joined.length; j++) { | ||
if(joined[j] === '..') { | ||
normalized = normalized.slice(0, normalized.length-1); | ||
} | ||
else { | ||
normalized.push(joined[j]); | ||
} | ||
} | ||
for(k = 0; k < normalized.length; k ++) { | ||
if(k > 0) { | ||
url += '/'; | ||
} | ||
url += normalized[k]; | ||
} | ||
// we now have to remote resolve this because the path has changed | ||
a.root = url; | ||
toResolve.push(a); | ||
} | ||
else { | ||
parts = a.key.split('#'); | ||
if(parts.length === 2) { | ||
if(parts[0].indexOf('http://') === 0 || parts[0].indexOf('https://') === 0) { | ||
a.root = parts[0]; | ||
} | ||
location = parts[1].split('/'); | ||
var r; | ||
var s = spec; | ||
for(k = 0; k < location.length; k++) { | ||
var part = location[k]; | ||
if(part !== '') { | ||
s = s[part]; | ||
if(typeof s !== 'undefined') { | ||
r = s; | ||
} | ||
else { | ||
r = null; | ||
break; | ||
} | ||
} | ||
} | ||
if(r === null) { | ||
// must resolve this too | ||
toResolve.push(a); | ||
} | ||
} | ||
} | ||
} | ||
opts[host].push(path); | ||
else { | ||
if (a.resolveAs === 'inline') { | ||
if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') { | ||
// handle relative schema | ||
parts = a.root.split('/'); | ||
location = ''; | ||
for(i = 0; i < parts.length - 1; i++) { | ||
location += parts[i] + '/'; | ||
} | ||
location += a.key; | ||
a.root = location; | ||
a.location = ''; | ||
} | ||
toResolve.push(a); | ||
} | ||
} | ||
} | ||
else { | ||
if (!Array.isArray(opts[name])) { | ||
opts[name] = []; | ||
expectedCalls += 1; | ||
} | ||
opts[name].push(null); | ||
toResolve.push(a); | ||
} | ||
} | ||
expectedCalls = toResolve.length; | ||
for (name in opts) { | ||
var self = this, opt = opts[name]; | ||
// resolve anything that is local | ||
for(var ii = 0; ii < toResolve.length; ii++) { | ||
(function(item, self) { | ||
if(item.root === null || item.root === root) { | ||
// local resolve | ||
self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item); | ||
processedCalls += 1; | ||
host = name; | ||
var obj = { | ||
useJQuery: false, // TODO | ||
url: host, | ||
method: 'get', | ||
headers: { | ||
accept: this.scope.swaggerRequestHeaders || 'application/json' | ||
}, | ||
on: { | ||
error: function () { | ||
processedCalls += 1; | ||
var i; | ||
for (i = 0; i < opt.length; i++) { | ||
// fail all of these | ||
var resolved = host + '#' + opt[i]; | ||
unresolvedRefs[resolved] = null; | ||
} | ||
if (processedCalls === expectedCalls) { | ||
self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback); | ||
} | ||
}, // jshint ignore:line | ||
response: function (response) { | ||
var i, j, swagger = response.obj; | ||
if(swagger === null || Object.keys(swagger).length === 0) { | ||
try { | ||
swagger = JSON.parse(response.data); | ||
} | ||
catch (e){ | ||
swagger = {}; | ||
} | ||
} | ||
processedCalls += 1; | ||
for (i = 0; i < opt.length; i++) { | ||
var path = opt[i]; | ||
if(path == null) { | ||
resolvedRefs[name] = { | ||
name: name, | ||
obj: swagger | ||
if(processedCalls === expectedCalls) { | ||
self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback); | ||
} | ||
} | ||
else { | ||
var obj = { | ||
useJQuery: false, // TODO | ||
url: item.root, | ||
method: 'get', | ||
headers: { | ||
accept: self.scope.swaggerRequestHeaders || 'application/json' | ||
}, | ||
on: { | ||
error: function () { | ||
processedCalls += 1; | ||
unresolvedRefs[item.key] = { | ||
root: item.root, | ||
location: item.location | ||
}; | ||
} | ||
else { | ||
var location = swagger, parts = path.split('/'); | ||
for (j = 0; j < parts.length; j++) { | ||
var segment = parts[j]; | ||
if(segment.indexOf('~1') !== -1) { | ||
segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/'); | ||
if(segment.charAt(0) !== '/') { | ||
segment = '/' + segment; | ||
} | ||
} | ||
if (typeof location === 'undefined') { | ||
break; | ||
} | ||
if (segment.length > 0) { | ||
location = location[segment]; | ||
} | ||
if (processedCalls === expectedCalls) { | ||
self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); | ||
} | ||
var resolved = host + '#' + path, resolvedName = parts[j-1]; | ||
}, // jshint ignore:line | ||
response: function (response) { | ||
var swagger = response.obj; | ||
self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item); | ||
processedCalls += 1; | ||
if (typeof location !== 'undefined') { | ||
resolvedRefs[resolved] = { | ||
name: resolvedName, | ||
obj: location | ||
}; | ||
} else { | ||
unresolvedRefs[resolved] = null; | ||
if (processedCalls === expectedCalls) { | ||
self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); | ||
} | ||
} | ||
} | ||
if (processedCalls === expectedCalls) { | ||
self.finish(spec, resolutionTable, resolvedRefs, unresolvedRefs, callback); | ||
} | ||
} // jshint ignore:line | ||
}; | ||
if (scope && scope.clientAuthorizations) { | ||
scope.clientAuthorizations.apply(obj); | ||
} | ||
} // jshint ignore:line | ||
}; | ||
new SwaggerHttp().execute(obj); | ||
} | ||
}(toResolve[ii], this)); | ||
} | ||
if (scope && scope.clientAuthorizations) { | ||
scope.clientAuthorizations.apply(obj); | ||
if (Object.keys(toResolve).length === 0) { | ||
this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback); | ||
} | ||
}; | ||
Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) { | ||
var path = item.location; | ||
var location = spec, parts = path.split('/'); | ||
if(path !== '') { | ||
for (var j = 0; j < parts.length; j++) { | ||
var segment = parts[j]; | ||
if (segment.indexOf('~1') !== -1) { | ||
segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/'); | ||
if (segment.charAt(0) !== '/') { | ||
segment = '/' + segment; | ||
} | ||
} | ||
if (typeof location === 'undefined' || location === null) { | ||
break; | ||
} | ||
if (segment === '' && j === (parts.length - 1) && parts.length > 1) { | ||
location = null; | ||
break; | ||
} | ||
if (segment.length > 0) { | ||
location = location[segment]; | ||
} | ||
} | ||
} | ||
var resolved = item.key; | ||
parts = item.key.split('/'); | ||
var resolvedName = parts[parts.length-1]; | ||
new SwaggerHttp().execute(obj); | ||
if(resolvedName.indexOf('#') >= 0) { | ||
resolvedName = resolvedName.split('#')[1]; | ||
} | ||
if (Object.keys(opts).length === 0) { | ||
callback.call(this.scope, spec, unresolvedRefs); | ||
if (location !== null && typeof location !== 'undefined') { | ||
resolvedRefs[resolved] = { | ||
name: resolvedName, | ||
obj: location, | ||
key: item.key, | ||
root: item.root | ||
}; | ||
} else { | ||
unresolvedRefs[resolved] = { | ||
root: item.root, | ||
location: item.location | ||
}; | ||
} | ||
}; | ||
Resolver.prototype.finish = function (spec, resolutionTable, resolvedRefs, unresolvedRefs, callback) { | ||
Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback) { | ||
// walk resolution table and replace with resolved refs | ||
var ref; | ||
for (ref in resolutionTable) { | ||
var i, locations = resolutionTable[ref]; | ||
var item = resolutionTable[ref]; | ||
for (i = 0; i < locations.length; i++) { | ||
var resolvedTo = resolvedRefs[locations[i].obj.$ref]; | ||
if (resolvedTo) { | ||
if (!spec.definitions) { | ||
spec.definitions = {}; | ||
var key = item.key; | ||
var resolvedTo = resolvedRefs[key]; | ||
if (resolvedTo) { | ||
spec.definitions = spec.definitions || {}; | ||
if (item.resolveAs === 'ref') { | ||
for (key in resolvedTo.obj) { | ||
var abs = this.retainRoot(resolvedTo.obj[key], item.root); | ||
} | ||
spec.definitions[resolvedTo.name] = resolvedTo.obj; | ||
item.obj.$ref = '#/definitions/' + resolvedTo.name; | ||
} else if (item.resolveAs === 'inline') { | ||
var targetObj = item.obj; | ||
targetObj['x-resolved-from'] = [ item.key ]; | ||
delete targetObj.$ref; | ||
if (locations[i].resolveAs === '$ref') { | ||
spec.definitions[resolvedTo.name] = resolvedTo.obj; | ||
locations[i].obj.$ref = '#/definitions/' + resolvedTo.name; | ||
} else if (locations[i].resolveAs === 'inline') { | ||
var targetObj = locations[i].obj; | ||
var key; | ||
delete targetObj.$ref; | ||
for (key in resolvedTo.obj) { | ||
targetObj[key] = resolvedTo.obj[key]; | ||
} | ||
for (key in resolvedTo.obj) { | ||
var abs = this.retainRoot(resolvedTo.obj[key], item.root); | ||
targetObj[key] = abs; | ||
} | ||
@@ -239,5 +339,6 @@ } | ||
} | ||
var existingUnresolved = this.countUnresolvedRefs(spec); | ||
// TODO need to check if we're done instead of just resolving 2x | ||
if(this.iteration === 2) { | ||
if(existingUnresolved.length === 0 || this.iteration > 5) { | ||
this.resolveAllOf(spec.definitions); | ||
callback.call(this.scope, spec, unresolvedRefs); | ||
@@ -247,6 +348,82 @@ } | ||
this.iteration += 1; | ||
this.resolve(spec, callback, this.scope); | ||
this.resolve(spec, root, callback, this.scope); | ||
} | ||
}; | ||
Resolver.prototype.countUnresolvedRefs = function(spec) { | ||
var i; | ||
var refs = this.getRefs(spec); | ||
var keys = []; | ||
var unresolvedKeys = []; | ||
for(i in refs) { | ||
if(i.indexOf('#') === 0) { | ||
keys.push(i.substring(1)); | ||
} | ||
else { | ||
unresolvedKeys.push(i); | ||
} | ||
} | ||
// verify possible keys | ||
for (i = 0; i < keys.length; i++) { | ||
var part = keys[i]; | ||
var parts = part.split('/'); | ||
var obj = spec; | ||
for (var k = 0; k < parts.length; k++) { | ||
var key = parts[k]; | ||
if(key !== '') { | ||
obj = obj[key]; | ||
if(typeof obj === 'undefined') { | ||
unresolvedKeys.push(part); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
return unresolvedKeys.length; | ||
}; | ||
Resolver.prototype.getRefs = function(spec, obj) { | ||
obj = obj || spec; | ||
var output = {}; | ||
for(var key in obj) { | ||
if (!obj.hasOwnProperty(key)) { | ||
continue; | ||
} | ||
var item = obj[key]; | ||
if(key === '$ref' && typeof item === 'string') { | ||
output[item] = null; | ||
} | ||
else if(_.isObject(item)) { | ||
var o = this.getRefs(item); | ||
for(var k in o) { | ||
output[k] = null; | ||
} | ||
} | ||
} | ||
return output; | ||
}; | ||
Resolver.prototype.retainRoot = function(obj, root) { | ||
// walk object and look for relative $refs | ||
for(var key in obj) { | ||
var item = obj[key]; | ||
if(key === '$ref' && typeof item === 'string') { | ||
// stop and inspect | ||
if(item.indexOf('http://') !== 0 && item.indexOf('https://') !== 0) { | ||
if(item.indexOf('#') !== 0) { | ||
item = '#' + item; | ||
} | ||
item = (root || '') + item; | ||
obj[key] = item; | ||
} | ||
} | ||
else if(_.isObject(item)) { | ||
this.retainRoot(item, root); | ||
} | ||
} | ||
return obj; | ||
}; | ||
/** | ||
@@ -256,58 +433,205 @@ * immediately in-lines local refs, queues remote refs | ||
*/ | ||
Resolver.prototype.resolveInline = function (spec, property, objs, unresolvedRefs) { | ||
var ref = property.$ref; | ||
Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) { | ||
var key = property.$ref, ref = property.$ref, i, p, p2, rs; | ||
var rootTrimmed = false; | ||
if (ref) { | ||
if(ref.indexOf('../') === 0) { | ||
// reset root | ||
p = ref.split('../'); | ||
p2 = root.split('/'); | ||
ref = ''; | ||
for(i = 0; i < p.length; i++) { | ||
if(p[i] === '') { | ||
p2 = p2.slice(0, p2.length-1); | ||
} | ||
else { | ||
ref += p[i]; | ||
} | ||
} | ||
root = ''; | ||
for(i = 0; i < p2.length - 1; i++) { | ||
if(i > 0) { root += '/'; } | ||
root += p2[i]; | ||
} | ||
rootTrimmed = true; | ||
} | ||
if(ref.indexOf('#') >= 0) { | ||
if(ref.indexOf('/') === 0) { | ||
rs = ref.split('#'); | ||
p = root.split('//'); | ||
p2 = p[1].split('/'); | ||
root = p[0] + '//' + p2[0] + rs[0]; | ||
location = rs[1]; | ||
} | ||
else { | ||
rs = ref.split('#'); | ||
if(rs[0] !== '') { | ||
p2 = root.split('/'); | ||
p2 = p2.slice(0, p2.length - 1); | ||
if(!rootTrimmed) { | ||
root = ''; | ||
for (var k = 0; k < p2.length; k++) { | ||
if(k > 0) { root += '/'; } | ||
root += p2[k]; | ||
} | ||
} | ||
root += '/' + ref.split('#')[0]; | ||
} | ||
location = rs[1]; | ||
} | ||
} | ||
if (ref.indexOf('http') === 0) { | ||
if (Array.isArray(objs[ref])) { | ||
objs[ref].push({obj: property, resolveAs: 'inline'}); | ||
} else { | ||
objs[ref] = [{obj: property, resolveAs: 'inline'}]; | ||
if(ref.indexOf('#') >= 0) { | ||
root = ref.split('#')[0]; | ||
location = ref.split('#')[1]; | ||
} | ||
else { | ||
root = ref; | ||
location = ''; | ||
} | ||
resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); | ||
} else if (ref.indexOf('#') === 0) { | ||
// local resolve | ||
var shortenedRef = ref.substring(1); | ||
var i, parts = shortenedRef.split('/'), location = spec; | ||
location = ref.split('#')[1]; | ||
resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); | ||
} | ||
else { | ||
resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location}); | ||
} | ||
} else if (property.type === 'array') { | ||
this.resolveTo(root, property.items, resolutionTable, location); | ||
} | ||
}; | ||
for (i = 0; i < parts.length; i++) { | ||
var part = parts[i]; | ||
Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) { | ||
var sp, i; | ||
var ref = property.$ref; | ||
var lroot = root; | ||
if (typeof ref !== 'undefined') { | ||
if(ref.indexOf('#') >= 0) { | ||
var parts = ref.split('#'); | ||
if (part.length > 0) { | ||
location = location[part]; | ||
// #/definitions/foo | ||
// foo.json#/bar | ||
if(parts[0] && ref.indexOf('/') === 0) { | ||
} | ||
else if(parts[0] && ref.indexOf('http') === 0) { | ||
} | ||
else if(parts[0] && parts[0].length > 0) { | ||
// relative file | ||
sp = root.split('/'); | ||
lroot = ''; | ||
for(i = 0; i < sp.length - 1; i++) { | ||
lroot += sp[i] + '/'; | ||
} | ||
lroot += parts[0]; | ||
} | ||
else { | ||
if (location) { | ||
delete property.$ref; | ||
} | ||
var key; | ||
for (key in location) { | ||
property[key] = location[key]; | ||
} | ||
} else { | ||
unresolvedRefs[ref] = null; | ||
location = parts[1]; | ||
} | ||
else { | ||
// relative file | ||
sp = root.split('/'); | ||
lroot = ''; | ||
for(i = 0; i < sp.length - 1; i++) { | ||
lroot += sp[i] + '/'; | ||
} | ||
lroot += ref; | ||
location = ''; | ||
} | ||
resolutionTable.push({ | ||
obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location | ||
}); | ||
} else if (property.type === 'array') { | ||
this.resolveTo(property.items, objs); | ||
var items = property.items; | ||
this.resolveTo(root, items, resolutionTable, location); | ||
} | ||
}; | ||
Resolver.prototype.resolveTo = function (property, objs) { | ||
var ref = property.$ref; | ||
Resolver.prototype.resolveAllOf = function(spec, obj, depth) { | ||
depth = depth || 0; | ||
obj = obj || spec; | ||
var name; | ||
for(var key in obj) { | ||
if (!obj.hasOwnProperty(key)) { | ||
continue; | ||
} | ||
var item = obj[key]; | ||
if(item === null) { | ||
throw new TypeError('Swagger 2.0 does not support null types (' + obj + '). See https://github.com/swagger-api/swagger-spec/issues/229.'); | ||
} | ||
if(typeof item === 'object') { | ||
this.resolveAllOf(spec, item, depth + 1); | ||
} | ||
if(item && typeof item.allOf !== 'undefined') { | ||
var allOf = item.allOf; | ||
if(_.isArray(allOf)) { | ||
var output = {}; | ||
output['x-composed'] = true; | ||
if (typeof item['x-resolved-from'] !== 'undefined') { | ||
output['x-resolved-from'] = item['x-resolved-from']; | ||
} | ||
output.properties = {}; | ||
if ( item.example ){ | ||
output.example = item.example; | ||
} | ||
for(var i = 0; i < allOf.length; i++) { | ||
var component = allOf[i]; | ||
var source = 'self'; | ||
if(typeof component['x-resolved-from'] !== 'undefined') { | ||
source = component['x-resolved-from'][0]; | ||
} | ||
if (ref) { | ||
if (ref.indexOf('http') === 0) { | ||
if (Array.isArray(objs[ref])) { | ||
objs[ref].push({obj: property, resolveAs: '$ref'}); | ||
} else { | ||
objs[ref] = [{obj: property, resolveAs: '$ref'}]; | ||
for(var part in component) { | ||
if(!output.hasOwnProperty(part)) { | ||
output[part] = JSON.parse(JSON.stringify(component[part])); | ||
if(part === 'properties') { | ||
for(name in output[part]) { | ||
output[part][name]['x-resolved-from'] = source; | ||
} | ||
} | ||
} | ||
else { | ||
if(part === 'properties') { | ||
var properties = component[part]; | ||
for(name in properties) { | ||
output.properties[name] = JSON.parse(JSON.stringify(properties[name])); | ||
var resolvedFrom = properties[name]['x-resolved-from']; | ||
if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') { | ||
resolvedFrom = source; | ||
} | ||
output.properties[name]['x-resolved-from'] = resolvedFrom; | ||
} | ||
} | ||
else if(part === 'required') { | ||
// merge & dedup the required array | ||
var a = output.required.concat(component[part]); | ||
for(var k = 0; k < a.length; ++k) { | ||
for(var j = k + 1; j < a.length; ++j) { | ||
if(a[k] === a[j]) { a.splice(j--, 1); } | ||
} | ||
} | ||
output.required = a; | ||
} | ||
else if(part === 'x-resolved-from') { | ||
output['x-resolved-from'].push(source); | ||
} | ||
else { | ||
// TODO: need to merge this property | ||
// console.log('what to do with ' + part) | ||
} | ||
} | ||
} | ||
} | ||
obj[key] = output; | ||
} | ||
} | ||
} else if (property.type === 'array') { | ||
var items = property.items; | ||
this.resolveTo(items, objs); | ||
if(_.isObject(item)) { | ||
this.resolveAllOf(spec, item, depth + 1); | ||
} | ||
} | ||
}; |
'use strict'; | ||
var SwaggerClient = require('./client'); | ||
var SwaggerHttp = require('./http'); | ||
var _ = { | ||
isObject: require('lodash-compat/lang/isObject') | ||
}; | ||
@@ -19,3 +21,3 @@ var SwaggerSpecConverter = module.exports = function () { | ||
**/ | ||
SwaggerSpecConverter.prototype.convert = function (obj, callback) { | ||
SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, callback) { | ||
// not a valid spec | ||
@@ -25,2 +27,3 @@ if(!obj || !Array.isArray(obj.apis)) { | ||
} | ||
this.clientAuthorizations = clientAuthorizations; | ||
@@ -37,7 +40,2 @@ // create a new swagger object to return | ||
this.securityDefinitions(obj, swagger); | ||
// take basePath into account | ||
if (obj.basePath) { | ||
this.setDocumentationLocation(obj.basePath); | ||
} | ||
@@ -68,3 +66,3 @@ // take basePath into account | ||
SwaggerSpecConverter.prototype.declaration = function(obj, swagger) { | ||
var name, i; | ||
var name, i, p, pos; | ||
if(!obj.apis) { | ||
@@ -75,4 +73,4 @@ return; | ||
if (obj.basePath.indexOf('http://') === 0) { | ||
var p = obj.basePath.substring('http://'.length); | ||
var pos = p.indexOf('/'); | ||
p = obj.basePath.substring('http://'.length); | ||
pos = p.indexOf('/'); | ||
if (pos > 0) { | ||
@@ -87,4 +85,4 @@ swagger.host = p.substring(0, pos); | ||
} else if (obj.basePath.indexOf('https://') === 0) { | ||
var p = obj.basePath.substring('https://'.length); | ||
var pos = p.indexOf('/'); | ||
p = obj.basePath.substring('https://'.length); | ||
pos = p.indexOf('/'); | ||
if (pos > 0) { | ||
@@ -114,3 +112,3 @@ swagger.host = p.substring(0, pos); | ||
// build a mapping of id to name for 1.0 model resolutions | ||
if(typeof obj === 'object') { | ||
if(_.isObject(obj)) { | ||
for(name in obj.models) { | ||
@@ -130,3 +128,3 @@ var existingModel = obj.models[name]; | ||
var models = obj.models; | ||
var models = obj.models || {}; | ||
this.models(models, swagger); | ||
@@ -136,3 +134,3 @@ }; | ||
SwaggerSpecConverter.prototype.models = function(obj, swagger) { | ||
if(typeof obj !== 'object') { | ||
if(!_.isObject(obj)) { | ||
return; | ||
@@ -170,11 +168,3 @@ } | ||
// Convert required array into required props on .property | ||
if(existingModel.required instanceof Array){ | ||
for(var i = 0, len = existingModel.required.length; i < len; i++) { | ||
var reqProp = existingModel.required[i]; | ||
if (schema.properties[reqProp]) { | ||
schema.properties[reqProp].required = true; | ||
} | ||
} | ||
} | ||
schema.required = existingModel.required; | ||
swagger.definitions[name] = schema; | ||
@@ -194,3 +184,3 @@ } | ||
return pathString.replace('/',''); | ||
} | ||
}; | ||
@@ -232,2 +222,3 @@ SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) { | ||
if(typeof existingAuthorizations !== 'undefined') { | ||
var scopesObject; | ||
for(var key in existingAuthorizations) { | ||
@@ -241,3 +232,3 @@ operation.security = operation.security || []; | ||
} | ||
var scopesObject = {}; | ||
scopesObject = {}; | ||
scopesObject[key] = securityScopes; | ||
@@ -247,3 +238,3 @@ operation.security.push(scopesObject); | ||
else { | ||
var scopesObject = {}; | ||
scopesObject = {}; | ||
scopesObject[key] = []; | ||
@@ -290,4 +281,4 @@ operation.security.push(scopesObject); | ||
SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation, swagger) { | ||
if(typeof existingOperation !== 'object') { | ||
SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) { | ||
if(!_.isObject(existingOperation)) { | ||
return; | ||
@@ -317,4 +308,7 @@ } | ||
} | ||
// Convert responseModel -> schema{$ref: responseModel} | ||
if(existingResponse.responseModel) { | ||
response.schema = {'$ref': existingResponse.responseModel}; | ||
} | ||
operation.responses['' + existingResponse.code] = response; | ||
// TODO: schema | ||
} | ||
@@ -331,5 +325,5 @@ } | ||
SwaggerSpecConverter.prototype.authorizations = function(obj, swagger) { | ||
SwaggerSpecConverter.prototype.authorizations = function(obj) { | ||
// TODO | ||
if(typeof obj !== 'object') { | ||
if(!_.isObject(obj)) { | ||
return; | ||
@@ -339,3 +333,3 @@ } | ||
SwaggerSpecConverter.prototype.parameters = function(operation, obj, swagger) { | ||
SwaggerSpecConverter.prototype.parameters = function(operation, obj) { | ||
if(!Array.isArray(obj)) { | ||
@@ -381,2 +375,5 @@ return; | ||
} | ||
if(typeof existingParameter.defaultValue !== 'undefined') { | ||
parameter.default = existingParameter.defaultValue; | ||
} | ||
@@ -389,3 +386,3 @@ operation.parameters = operation.parameters || []; | ||
SwaggerSpecConverter.prototype.dataType = function(source, target) { | ||
if(typeof source !== 'object') { | ||
if(!_.isObject(source)) { | ||
return; | ||
@@ -400,2 +397,5 @@ } | ||
} | ||
if (source.format) { | ||
target.format = source.format; | ||
} | ||
@@ -476,6 +476,7 @@ // default can be 'false' | ||
SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, callback) { | ||
var i, processedCount = 0; | ||
var self = this; | ||
var i; | ||
var processedCount = 0; // jshint ignore:line | ||
var self = this; // jshint ignore:line | ||
var expectedCount = obj.apis.length; | ||
var _swagger = swagger; | ||
var _swagger = swagger; // jshint ignore:line | ||
@@ -497,3 +498,3 @@ if(expectedCount === 0) { | ||
}); | ||
}; | ||
} | ||
var http = { | ||
@@ -505,9 +506,6 @@ url: absolutePath, | ||
}; | ||
/* jshint ignore:start */ | ||
http.on.response = function(data) { | ||
processedCount += 1; | ||
var obj = data.obj; | ||
if(typeof obj === 'undefined' || obj === null ) { | ||
try { obj = JSON.parse(data.statusText); } | ||
catch (e) {} | ||
} | ||
if(obj) { | ||
@@ -527,2 +525,8 @@ self.declaration(obj, _swagger); | ||
}; | ||
/* jshint ignore:end */ | ||
if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') { | ||
this.clientAuthorizations.apply(http); | ||
} | ||
new SwaggerHttp().execute(http); | ||
@@ -589,6 +593,7 @@ } | ||
} | ||
if(definition.grantTypes.authorization_code) { | ||
/* jshint ignore:start */ | ||
if(definition.grantTypes['authorization_code']) { | ||
if(!securityDefinition.flow) { | ||
// cannot set if flow is already defined | ||
var authCode = definition.grantTypes.authorization_code; | ||
var authCode = definition.grantTypes['authorization_code']; | ||
securityDefinition.flow = 'accessCode'; | ||
@@ -600,2 +605,3 @@ securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url; | ||
} | ||
/* jshint ignore:end */ | ||
} | ||
@@ -602,0 +608,0 @@ } |
'use strict'; | ||
var _ = { | ||
cloneDeep: require('lodash-compat/lang/cloneDeep'), | ||
forEach: require('lodash-compat/collection/forEach'), | ||
indexOf: require('lodash-compat/array/indexOf'), | ||
isArray: require('lodash-compat/lang/isArray'), | ||
isPlainObject: require('lodash-compat/lang/isPlainObject'), | ||
isString: require('lodash-compat/lang/isString'), | ||
isUndefined: require('lodash-compat/lang/isUndefined'), | ||
keys: require('lodash-compat/object/keys'), | ||
map: require('lodash-compat/collection/map') | ||
}; | ||
var helpers = require('../helpers'); | ||
var SchemaMarkup = require('../schema-markup.js'); | ||
var jsyaml = require('js-yaml'); | ||
var Model = module.exports = function (name, definition, models, modelPropertyMacro) { | ||
@@ -28,371 +23,2 @@ this.definition = definition || {}; | ||
var schemaToHTML = function (name, schema, models, modelPropertyMacro) { | ||
var strongOpen = '<span class="strong">'; | ||
var strongClose = '</span>'; | ||
var references = {}; | ||
var seenModels = []; | ||
var inlineModels = 0; | ||
var addReference = function (schema, name, skipRef) { | ||
var modelName = name; | ||
var model; | ||
if (schema.$ref) { | ||
modelName = schema.title || helpers.simpleRef(schema.$ref); | ||
model = models[modelName]; | ||
} else if (_.isUndefined(name)) { | ||
modelName = schema.title || 'Inline Model ' + (++inlineModels); | ||
model = new Model(modelName, schema, models, modelPropertyMacro); | ||
} | ||
if (skipRef !== true) { | ||
references[modelName] = _.isUndefined(model) ? {} : model.definition; | ||
} | ||
return modelName; | ||
}; | ||
var primitiveToHTML = function (schema) { | ||
var html = '<span class="propType">'; | ||
var type = schema.type || 'object'; | ||
if (schema.$ref) { | ||
html += addReference(schema, helpers.simpleRef(schema.$ref)); | ||
} else if (type === 'object') { | ||
if (!_.isUndefined(schema.properties)) { | ||
html += addReference(schema); | ||
} else { | ||
html += 'object'; | ||
} | ||
} else if (type === 'array') { | ||
html += 'Array['; | ||
if (_.isArray(schema.items)) { | ||
html += _.map(schema.items, addReference).join(','); | ||
} else if (_.isPlainObject(schema.items)) { | ||
if (_.isUndefined(schema.items.$ref)) { | ||
if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) { | ||
html += schema.items.type; | ||
} else { | ||
html += addReference(schema.items); | ||
} | ||
} else { | ||
html += addReference(schema.items, helpers.simpleRef(schema.items.$ref)); | ||
} | ||
} else { | ||
helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process'); | ||
html += 'object'; | ||
} | ||
html += ']'; | ||
} else { | ||
html += schema.type; | ||
} | ||
html += '</span>'; | ||
return html; | ||
}; | ||
var primitiveToOptionsHTML = function (schema, html) { | ||
var options = ''; | ||
var type = schema.type || 'object'; | ||
var isArray = type === 'array'; | ||
if (isArray) { | ||
if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) { | ||
type = schema.items.type; | ||
} else { | ||
type = 'object'; | ||
} | ||
} | ||
if (!_.isUndefined(schema.default)) { | ||
options += helpers.optionHtml('Default', schema.default); | ||
} | ||
switch (type) { | ||
case 'string': | ||
if (schema.minLength) { | ||
options += helpers.optionHtml('Min. Length', schema.minLength); | ||
} | ||
if (schema.maxLength) { | ||
options += helpers.optionHtml('Max. Length', schema.maxLength); | ||
} | ||
if (schema.pattern) { | ||
options += helpers.optionHtml('Reg. Exp.', schema.pattern); | ||
} | ||
break; | ||
case 'integer': | ||
case 'number': | ||
if (schema.minimum) { | ||
options += helpers.optionHtml('Min. Value', schema.minimum); | ||
} | ||
if (schema.exclusiveMinimum) { | ||
options += helpers.optionHtml('Exclusive Min.', 'true'); | ||
} | ||
if (schema.maximum) { | ||
options += helpers.optionHtml('Max. Value', schema.maximum); | ||
} | ||
if (schema.exclusiveMaximum) { | ||
options += helpers.optionHtml('Exclusive Max.', 'true'); | ||
} | ||
if (schema.multipleOf) { | ||
options += helpers.optionHtml('Multiple Of', schema.multipleOf); | ||
} | ||
break; | ||
} | ||
if (isArray) { | ||
if (schema.minItems) { | ||
options += helpers.optionHtml('Min. Items', schema.minItems); | ||
} | ||
if (schema.maxItems) { | ||
options += helpers.optionHtml('Max. Items', schema.maxItems); | ||
} | ||
if (schema.uniqueItems) { | ||
options += helpers.optionHtml('Unique Items', 'true'); | ||
} | ||
if (schema.collectionFormat) { | ||
options += helpers.optionHtml('Coll. Format', schema.collectionFormat); | ||
} | ||
} | ||
if (_.isUndefined(schema.items)) { | ||
if (_.isArray(schema.enum)) { | ||
var enumString; | ||
if (type === 'number' || type === 'integer') { | ||
enumString = schema.enum.join(', '); | ||
} else { | ||
enumString = '"' + schema.enum.join('", "') + '"'; | ||
} | ||
options += helpers.optionHtml('Enum', enumString); | ||
} | ||
} | ||
if (options.length > 0) { | ||
html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>'; | ||
} | ||
return html; | ||
}; | ||
var processModel = function (schema, name) { | ||
var type = schema.type || 'object'; | ||
var isArray = schema.type === 'array'; | ||
var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose; | ||
if (name) { | ||
seenModels.push(name); | ||
} | ||
if (isArray) { | ||
if (_.isArray(schema.items)) { | ||
html += '<div>' + _.map(schema.items, function (item) { | ||
var type = item.type || 'object'; | ||
if (_.isUndefined(item.$ref)) { | ||
if (_.indexOf(['array', 'object'], type) > -1) { | ||
if (type === 'object' && _.isUndefined(item.properties)) { | ||
return 'object'; | ||
} else { | ||
return addReference(item); | ||
} | ||
} else { | ||
return primitiveToOptionsHTML(item, type); | ||
} | ||
} else { | ||
return addReference(item, helpers.simpleRef(item.$ref)); | ||
} | ||
}).join(',</div><div>'); | ||
} else if (_.isPlainObject(schema.items)) { | ||
if (_.isUndefined(schema.items.$ref)) { | ||
if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) { | ||
if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) { | ||
html += '<div>object</div>'; | ||
} else { | ||
html += '<div>' + addReference(schema.items) + '</div>'; | ||
} | ||
} else { | ||
html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>'; | ||
} | ||
} else { | ||
html += '<div>' + addReference(schema.items, helpers.simpleRef(schema.items.$ref)) + '</div>'; | ||
} | ||
} else { | ||
helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); | ||
html += '<div>object</div>'; | ||
} | ||
} else { | ||
if (schema.$ref) { | ||
html += '<div>' + addReference(schema, name) + '</div>'; | ||
} else if (type === 'object') { | ||
html += '<div>'; | ||
if (_.isPlainObject(schema.properties)) { | ||
html += _.map(schema.properties, function (property, name) { | ||
var propertyIsRequired = (_.indexOf(schema.required, name) >= 0); | ||
var cProperty = _.cloneDeep(property); | ||
var requiredClass = propertyIsRequired ? 'required' : ''; | ||
var html = '<span class="propName ' + requiredClass + '">' + name + '</span> ('; | ||
var model; | ||
// Allow macro to set the default value | ||
cProperty.default = modelPropertyMacro(cProperty); | ||
// Resolve the schema (Handle nested schemas) | ||
cProperty = helpers.resolveSchema(cProperty); | ||
// We need to handle property references to primitives (Issue 339) | ||
if (!_.isUndefined(cProperty.$ref)) { | ||
model = models[helpers.simpleRef(cProperty.$ref)]; | ||
if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) { | ||
// Use referenced schema | ||
cProperty = helpers.resolveSchema(model.definition); | ||
} | ||
} | ||
html += primitiveToHTML(cProperty); | ||
if(!propertyIsRequired) { | ||
html += ', <span class="propOptKey">optional</span>'; | ||
} | ||
html += ')'; | ||
if (!_.isUndefined(cProperty.description)) { | ||
html += ': ' + cProperty.description; | ||
} | ||
if (cProperty.enum) { | ||
html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>'; | ||
} | ||
return primitiveToOptionsHTML(cProperty, html); | ||
}).join(',</div><div>'); | ||
} | ||
html += '</div>'; | ||
} else { | ||
html = '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; | ||
} | ||
} | ||
return html + strongOpen + (isArray ? ']' : '}') + strongClose; | ||
}; | ||
// Resolve the schema (Handle nested schemas) | ||
schema = helpers.resolveSchema(schema); | ||
// Generate current HTML | ||
var html = processModel(schema, name); | ||
// Generate references HTML | ||
while (_.keys(references).length > 0) { | ||
_.forEach(references, function (schema, name) { | ||
var seenModel = _.indexOf(seenModels, name) > -1; | ||
delete references[name]; | ||
if (!seenModel) { | ||
seenModels.push(name); | ||
html += '<br />' + processModel(schema, name); | ||
} | ||
}); | ||
} | ||
return html; | ||
}; | ||
var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) { | ||
// Resolve the schema (Handle nested schemas) | ||
schema = helpers.resolveSchema(schema); | ||
var type = schema.type || 'object'; | ||
var format = schema.format; | ||
var model; | ||
var output; | ||
if (schema.example) { | ||
output = schema.example; | ||
} else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) { | ||
output = schema.enum[0]; | ||
} | ||
if (_.isUndefined(output)) { | ||
if (schema.$ref) { | ||
model = models[helpers.simpleRef(schema.$ref)]; | ||
if (!_.isUndefined(model)) { | ||
if (_.isUndefined(modelsToIgnore[model.name])) { | ||
modelsToIgnore[model.name] = model; | ||
output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro); | ||
delete modelsToIgnore[model.name]; | ||
} else { | ||
if (model.type === 'array') { | ||
output = []; | ||
} else { | ||
output = {}; | ||
} | ||
} | ||
} | ||
} else if (!_.isUndefined(schema.default)) { | ||
output = schema.default; | ||
} else if (type === 'string') { | ||
if (format === 'date-time') { | ||
output = new Date().toISOString(); | ||
} else if (format === 'date') { | ||
output = new Date().toISOString().split('T')[0]; | ||
} else { | ||
output = 'string'; | ||
} | ||
} else if (type === 'integer') { | ||
output = 0; | ||
} else if (type === 'number') { | ||
output = 0.0; | ||
} else if (type === 'boolean') { | ||
output = true; | ||
} else if (type === 'object') { | ||
output = {}; | ||
_.forEach(schema.properties, function (property, name) { | ||
var cProperty = _.cloneDeep(property); | ||
// Allow macro to set the default value | ||
cProperty.default = modelPropertyMacro(property); | ||
output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro); | ||
}); | ||
} else if (type === 'array') { | ||
output = []; | ||
if (_.isArray(schema.items)) { | ||
_.forEach(schema.items, function (item) { | ||
output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro)); | ||
}); | ||
} else if (_.isPlainObject(schema.items)) { | ||
output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro)); | ||
} else if (_.isUndefined(schema.items)) { | ||
output.push({}); | ||
} else { | ||
helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process'); | ||
} | ||
} | ||
} | ||
return output; | ||
}; | ||
Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) { | ||
@@ -408,3 +34,3 @@ modelsToIgnore = modelsToIgnore || {}; | ||
if (_.isString(this.definition.example)) { | ||
this.definition.example = JSON.parse(this.definition.example); | ||
this.definition.example = jsyaml.safeLoad(this.definition.example); | ||
} | ||
@@ -415,7 +41,7 @@ } else if (!this.definition.example) { | ||
return schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro); | ||
return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro); | ||
}; | ||
Model.prototype.getMockSignature = function () { | ||
return schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro); | ||
return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro); | ||
}; |
@@ -5,3 +5,5 @@ 'use strict'; | ||
cloneDeep: require('lodash-compat/lang/cloneDeep'), | ||
isUndefined: require('lodash-compat/lang/isUndefined') | ||
isUndefined: require('lodash-compat/lang/isUndefined'), | ||
isEmpty: require('lodash-compat/lang/isEmpty'), | ||
isObject: require('lodash-compat/lang/isObject') | ||
}; | ||
@@ -18,2 +20,6 @@ var helpers = require('../helpers'); | ||
if(parent && parent.options) { | ||
this.client = parent.options.client || null; | ||
this.responseInterceptor = parent.options.responseInterceptor || null; | ||
} | ||
this.authorizations = args.security; | ||
@@ -37,3 +43,3 @@ this.basePath = parent.basePath || '/'; | ||
this.scheme = scheme || parent.scheme || 'http'; | ||
this.schemes = parent.schemes; | ||
this.schemes = args.schemes || parent.schemes; | ||
this.security = args.security; | ||
@@ -43,3 +49,3 @@ this.summary = args.summary || ''; | ||
this.useJQuery = parent.useJQuery; | ||
this.parameterMacro = parent.parameterMacro || function (parameter) { | ||
this.parameterMacro = parent.parameterMacro || function (operation, parameter) { | ||
return parameter.default; | ||
@@ -80,2 +86,5 @@ }; | ||
} | ||
else { | ||
definitions = {}; | ||
} | ||
@@ -86,3 +95,3 @@ for (i = 0; i < this.parameters.length; i++) { | ||
// Allow macro to set the default value | ||
param.default = this.parameterMacro(param); | ||
param.default = this.parameterMacro(this, param); | ||
@@ -106,2 +115,9 @@ if (param.type === 'array') { | ||
if(param['x-examples']) { | ||
var d = param['x-examples'].default; | ||
if(typeof d !== 'undefined') { | ||
param.default = d; | ||
} | ||
} | ||
if (typeof param['enum'] !== 'undefined') { | ||
@@ -590,3 +606,3 @@ var id; | ||
return sampleJson; | ||
} else if (typeof sampleJson === 'object') { | ||
} else if (_.isObject(sampleJson)) { | ||
var t = sampleJson; | ||
@@ -625,3 +641,3 @@ | ||
if (typeof arg2 === 'object') { | ||
if (_.isObject(arg2)) { | ||
opts = arg2; | ||
@@ -632,2 +648,10 @@ success = arg3; | ||
if(this.client) { | ||
opts.client = this.client; | ||
} | ||
if(this.responseInterceptor) { | ||
opts.responseInterceptor = this.responseInterceptor; | ||
} | ||
if (typeof arg2 === 'function') { | ||
@@ -641,6 +665,6 @@ success = arg2; | ||
if (typeof opts.useJQuery === 'undefined') { | ||
opts.useJQuery = this.useJQuery; | ||
} | ||
var missingParams = this.getMissingParams(args); | ||
@@ -703,2 +727,19 @@ | ||
function itemByPriority(col, itemPriority) { | ||
// No priorities? return first... | ||
if(_.isEmpty(itemPriority)) { | ||
return col[0]; | ||
} | ||
for (var i = 0, len = itemPriority.length; i < len; i++) { | ||
if(col.indexOf(itemPriority[i]) > -1) { | ||
return itemPriority[i]; | ||
} | ||
} | ||
// Otherwise return first | ||
return col[0]; | ||
} | ||
Operation.prototype.setContentTypes = function (args, opts) { | ||
@@ -708,4 +749,4 @@ // default type | ||
var body; | ||
var consumes = args.parameterContentType || this.consumes[0]; | ||
var accepts = opts.responseContentType || this.produces[0]; | ||
var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']); | ||
var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']); | ||
var definedFileParams = []; | ||
@@ -739,3 +780,4 @@ var definedFormParams = []; | ||
// if there's a body, need to set the consumes header via requestContentType | ||
if (this.method === 'post' || this.method === 'put' || this.method === 'patch') { | ||
if (this.method === 'post' || this.method === 'put' || this.method === 'patch' || | ||
(this.method === 'delete' && body) ) { | ||
if (opts.requestContentType) { | ||
@@ -765,6 +807,4 @@ consumes = opts.requestContentType; | ||
if (accepts && this.produces) { | ||
if (this.produces.indexOf(accepts) === -1) { | ||
helpers.log('server can\'t produce ' + accepts); | ||
} | ||
if (!this.matchesAccept(accepts)) { | ||
helpers.log('server can\'t produce ' + accepts); | ||
} | ||
@@ -783,5 +823,25 @@ | ||
Operation.prototype.asCurl = function (args) { | ||
var obj = this.execute(args, {mock: true}); | ||
/** | ||
* Returns true if the request accepts header matches anything in this.produces. | ||
* If this.produces contains * / *, ignore the accept header. | ||
* @param {string=} accepts The client request accept header. | ||
* @return {boolean} | ||
*/ | ||
Operation.prototype.matchesAccept = function(accepts) { | ||
// no accepts or produces, no problem! | ||
if (!accepts || !this.produces) { | ||
return true; | ||
} | ||
return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1; | ||
}; | ||
Operation.prototype.asCurl = function (args1, args2) { | ||
var opts = {mock: true}; | ||
if (typeof args2 === 'object') { | ||
for (var argKey in args2) { | ||
opts[argKey] = args2[argKey]; | ||
} | ||
} | ||
var obj = this.execute(args1, opts); | ||
this.clientAuthorizations.apply(obj); | ||
@@ -804,3 +864,3 @@ | ||
if (typeof obj.body === 'object') { | ||
if (_.isObject(obj.body)) { | ||
body = JSON.stringify(obj.body); | ||
@@ -896,18 +956,3 @@ } else { | ||
Operation.prototype.encodePathParam = function (pathParam) { | ||
var encParts, parts, i, len; | ||
pathParam = pathParam.toString(); | ||
if (pathParam.indexOf('/') === -1) { | ||
return encodeURIComponent(pathParam); | ||
} else { | ||
parts = pathParam.split('/'); | ||
encParts = []; | ||
for (i = 0, len = parts.length; i < len; i++) { | ||
encParts.push(encodeURIComponent(parts[i])); | ||
} | ||
return encParts.join('/'); | ||
} | ||
return encodeURIComponent(pathParam); | ||
}; |
{ | ||
"name": "swagger-client", | ||
"author": "Tony Tam <fehguy@gmail.com>", | ||
"contributors": [{ | ||
"name": "Jeremy Whitlock", | ||
"email": "jcscoobyrs@gmail.com" | ||
}], | ||
"contributors": [ | ||
{ | ||
"name": "Jeremy Whitlock", | ||
"email": "jcscoobyrs@gmail.com" | ||
} | ||
], | ||
"description": "swagger-client is a javascript client for use with swaggering APIs.", | ||
"version": "2.1.5-M2", | ||
"version": "2.1.5", | ||
"homepage": "http://swagger.io", | ||
@@ -19,3 +21,4 @@ "repository": { | ||
"dev": "gulp watch", | ||
"test": "gulp test" | ||
"test": "gulp test", | ||
"browsertest": "gulp browsertest" | ||
}, | ||
@@ -26,3 +29,3 @@ "files": [ | ||
"browser", | ||
"index.js" | ||
"index.js" | ||
], | ||
@@ -36,4 +39,5 @@ "engines": { | ||
"jquery": "^2.1.3", | ||
"js-yaml": "^3.3.0", | ||
"lodash-compat": "^3.5.0", | ||
"superagent": "^0.21.0" | ||
"superagent": "^1.2" | ||
}, | ||
@@ -44,6 +48,10 @@ "devDependencies": { | ||
"browserify": "^9.0.3", | ||
"chai": "^2.3.0", | ||
"connect-cors": "^0.5.6", | ||
"del": "^1.1.1", | ||
"expect": "1.4.0", | ||
"faux-jax": "^4.0.0", | ||
"gulp": "^3.8.10", | ||
"gulp-buffer": "0.0.2", | ||
"gulp-connect": "^2.2.0", | ||
"gulp-header": "^1.2.2", | ||
@@ -53,9 +61,17 @@ "gulp-istanbul": "^0.5.0", | ||
"gulp-mocha": "^2.0.0", | ||
"http-server": "git://github.com/nodeapps/http-server.git", | ||
"jshint-stylish": "^1.0.1", | ||
"karma": "^0.12.35", | ||
"karma-browserify": "^4.2.1", | ||
"karma-firefox-launcher": "^0.1.6", | ||
"karma-mocha": "^0.1.10", | ||
"karma-source-map-support": "^1.0.0", | ||
"mocha": "^1.21.3", | ||
"object.assign": "^3.0.0", | ||
"selenium-webdriver": "^2.45.1", | ||
"uglifyify": "^3.0.1", | ||
"unit.js": "1.1.2", | ||
"unit.js": "^2.0.0", | ||
"vinyl-source-stream": "^1.1.0" | ||
}, | ||
"license": "apache 2.0" | ||
"license": "Apache-2.0" | ||
} |
# Swagger JS library | ||
[![Build Status](https://api.travis-ci.org/swagger-api/swagger-js.png)](https://travis-ci.org/swagger-api/swagger-js) | ||
[![Build Status](https://travis-ci.org/swagger-api/swagger-js.svg?branch=master)](https://travis-ci.org/swagger-api/swagger-js) | ||
@@ -18,5 +18,11 @@ This is the Swagger javascript client for use with [swagger](http://swagger.io) enabled APIs. | ||
or: | ||
``` | ||
bower install swagger-js | ||
``` | ||
Then let swagger do the work! | ||
```js | ||
var client = require("swagger-client") | ||
var client = require('swagger-client'); | ||
@@ -26,8 +32,11 @@ var swagger = new client({ | ||
success: function() { | ||
swagger.apis.pet.getPetById({petId:1}); | ||
swagger.pet.getPetById({petId:7},{responseContentType: 'application/json'},function(pet){ | ||
console.log('pet', pet); | ||
}); | ||
} | ||
}); | ||
``` | ||
NOTE: we're explicitly setting the responseContentType, because we don't want you getting stuck when there is more than one content type available. | ||
That's it! You'll get a JSON response with the default callback handler: | ||
@@ -73,2 +82,17 @@ | ||
...or with the swagger-client constructor: | ||
```js | ||
var swagger = new client({ | ||
url: 'http://example.com/spec.json', | ||
success: function() {}, | ||
authorizations : { | ||
easyapi_basic: new client.PasswordAuthorization('<name>', '<username>', '<password>'), | ||
someHeaderAuth: new client.ApiKeyAuthorization('<nameOfHeader>', '<value>', 'header'), | ||
someQueryAuth: new client.ApiKeyAuthorization('<nameOfQueryKey>', '<value>', 'query'), | ||
someCookieAuth: new client.CookieAuthorization('<cookie>'), | ||
} | ||
}); | ||
``` | ||
### Calling an API with swagger + the browser! | ||
@@ -86,3 +110,3 @@ | ||
// upon connect, fetch a pet and set contents to element "mydata" | ||
swagger.apis.pet.getPetById({petId:1}, function(data) { | ||
swagger.apis.pet.getPetById({petId:1},{responseContentType: 'application/json'}, function(data) { | ||
document.getElementById("mydata").innerHTML = JSON.stringify(data.obj); | ||
@@ -156,3 +180,3 @@ }); | ||
Please [fork the code](https://github.com/swagger-api/swagger-js) and help us improve | ||
swagger-client.js. Send us a pull request to the `develop_2.0` branch! Tests make merges get accepted more quickly. | ||
swagger-client.js. Send us a pull request to the `master` branch! Tests make merges get accepted more quickly. | ||
@@ -195,3 +219,3 @@ swagger-js use gulp for Node.js. | ||
Copyright 2011-2015 Reverb Technologies, Inc. | ||
Copyright 2011-2015 SmartBear Software | ||
@@ -198,0 +222,0 @@ Licensed under the Apache License, Version 2.0 (the "License"); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
High entropy strings
Supply chain riskContains high entropy strings. This could be a sign of encrypted data, leaked secrets or obfuscated code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
2736542
17
35436
1
226
6
28
1
8
+ Addedjs-yaml@^3.3.0
+ Addedargparse@1.0.10(transitive)
+ Addedasync@1.5.2(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcomponent-emitter@1.2.1(transitive)
+ Addedcookiejar@2.0.6(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedesprima@4.0.1(transitive)
+ Addedextend@3.0.0(transitive)
+ Addedform-data@1.0.0-rc3(transitive)
+ Addedformidable@1.0.17(transitive)
+ Addedjs-yaml@3.14.1(transitive)
+ Addedmethods@1.1.2(transitive)
+ Addedmime@1.3.4(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedqs@2.3.3(transitive)
+ Addedsprintf-js@1.0.3(transitive)
+ Addedsuperagent@1.8.5(transitive)
- Removedasync@0.9.2(transitive)
- Removedcombined-stream@0.0.7(transitive)
- Removedcomponent-emitter@1.1.2(transitive)
- Removedcookiejar@2.0.1(transitive)
- Removeddelayed-stream@0.0.5(transitive)
- Removedextend@1.2.1(transitive)
- Removedform-data@0.1.3(transitive)
- Removedformidable@1.0.14(transitive)
- Removedmethods@1.0.1(transitive)
- Removedmime@1.2.11(transitive)
- Removedqs@1.2.0(transitive)
- Removedsuperagent@0.21.0(transitive)
Updatedsuperagent@^1.2