swagger-client
Advanced tools
Comparing version 2.1.1-M2 to 2.1.1
11
index.js
@@ -20,4 +20,11 @@ 'use strict'; | ||
}; | ||
}; | ||
} | ||
/* Here for IE8 Support */ | ||
if (!String.prototype.trim) { | ||
String.prototype.trim = function () { | ||
return this.replace(/^\s+|\s+$/g, ''); | ||
}; | ||
} | ||
/* Here for node 10.x support */ | ||
@@ -28,3 +35,3 @@ if (!String.prototype.endsWith) { | ||
}; | ||
}; | ||
} | ||
@@ -31,0 +38,0 @@ module.exports = SwaggerClient; |
@@ -5,2 +5,8 @@ 'use strict'; | ||
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') | ||
}; | ||
@@ -10,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(name && typeof name === 'object') { | ||
for (var key in name) { | ||
this.authz[key] = name[key]; | ||
} | ||
} else if(typeof name === 'string' ){ | ||
this.authz[name] = auth; | ||
} | ||
@@ -25,51 +42,26 @@ return auth; | ||
SwaggerAuthorizations.prototype.apply = function (obj, authorizations) { | ||
SwaggerAuthorizations.prototype.apply = function (obj, securities) { | ||
var status = null; | ||
var key, name, value, result; | ||
var applyAll = !securities; | ||
var flattenedSecurities = []; | ||
// if the 'authorizations' key is undefined, or has an empty array, add all keys | ||
if (typeof authorizations === 'undefined' || Object.keys(authorizations).length === 0) { | ||
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)) { | ||
status = status || !!auth.apply(obj); // logical ORs regarding status | ||
} | ||
} | ||
}); | ||
@@ -76,0 +68,0 @@ return status; |
@@ -26,2 +26,3 @@ 'use strict'; | ||
var reservedClientTags = [ | ||
'apis', | ||
'authorizationScheme', | ||
@@ -48,5 +49,7 @@ 'authorizations', | ||
'isValid', | ||
'modelPropertyMacro', | ||
'models', | ||
'modelsArray', | ||
'options', | ||
'parameterMacro', | ||
'parseUri', | ||
@@ -83,4 +86,4 @@ 'progress', | ||
var SwaggerClient = module.exports = function (url, options) { | ||
this.authorizations = null; | ||
this.authorizationScheme = null; | ||
this.authorizations = null; | ||
this.basePath = null; | ||
@@ -96,2 +99,4 @@ this.debug = false; | ||
this.clientAuthorizations = new auth.SwaggerAuthorizations(); | ||
if (typeof url !== 'undefined') { | ||
@@ -108,4 +113,2 @@ return this.initialize(url, options); | ||
options = (options || {}); | ||
if (typeof url === 'string') { | ||
@@ -118,5 +121,9 @@ this.url = url; | ||
options = options || {}; | ||
this.clientAuthorizations.add(options.authorizations); | ||
this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*'; | ||
this.defaultSuccessCallback = options.defaultSuccessCallback || null; | ||
this.defaultErrorCallback = options.defaultErrorCallback || null; | ||
this.modelPropertyMacro = options.modelPropertyMacro || null; | ||
this.parameterMacro = options.modelPropertyMacro || null; | ||
@@ -131,7 +138,3 @@ if (typeof options.success === 'function') { | ||
if (options.authorizations) { | ||
this.clientAuthorizations = options.authorizations; | ||
} else { | ||
this.clientAuthorizations = new auth.SwaggerAuthorizations(); | ||
} | ||
this.options = options || {}; | ||
@@ -142,3 +145,2 @@ this.supportedSubmitMethods = options.supportedSubmitMethods || []; | ||
this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document | ||
this.options = options; | ||
@@ -180,3 +182,8 @@ if (typeof options.success === 'function') { | ||
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; | ||
@@ -187,3 +194,3 @@ | ||
new Resolver().resolve(responseObj, self.buildFromSpec, self); | ||
new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self); | ||
@@ -194,4 +201,4 @@ self.isValid = true; | ||
converter.setDocumentationLocation(self.url); | ||
converter.convert(responseObj, function(spec) { | ||
new Resolver().resolve(spec, self.buildFromSpec, self); | ||
converter.convert(responseObj, self.clientAuthorizations, function(spec) { | ||
new Resolver().resolve(spec, self.url, self.buildFromSpec, self); | ||
self.isValid = true; | ||
@@ -215,3 +222,3 @@ }); | ||
new SwaggerHttp().execute(obj); | ||
new SwaggerHttp().execute(obj, this.options); | ||
} | ||
@@ -253,3 +260,2 @@ | ||
var t = response.tags[k]; | ||
definedTags[t.name] = t; | ||
@@ -263,17 +269,24 @@ } | ||
location = this.parseUri(this.url); | ||
} | ||
if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { | ||
this.scheme = location.scheme || 'http'; | ||
} else { | ||
this.scheme = this.schemes[0]; | ||
} | ||
if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { | ||
this.scheme = location.scheme || 'http'; | ||
} else { | ||
this.scheme = this.schemes[0]; | ||
} | ||
if (typeof this.host === 'undefined' || this.host === '') { | ||
this.host = location.host; | ||
if (typeof this.host === 'undefined' || this.host === '') { | ||
this.host = location.host; | ||
if (location.port) { | ||
this.host = this.host + ':' + location.port; | ||
if (location.port) { | ||
this.host = this.host + ':' + location.port; | ||
} | ||
} | ||
} | ||
else { | ||
if (typeof this.schemes === 'undefined' || this.schemes.length === 0) { | ||
this.scheme = 'http'; | ||
} | ||
else { | ||
this.scheme = this.schemes[0]; | ||
} | ||
} | ||
@@ -285,3 +298,3 @@ this.definitions = response.definitions; | ||
for (key in this.definitions) { | ||
var model = new Model(key, this.definitions[key], this.models); | ||
var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro); | ||
@@ -317,3 +330,3 @@ if (model) { | ||
} | ||
var tags = operation.tags; | ||
@@ -326,4 +339,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); | ||
@@ -379,3 +399,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); | ||
@@ -382,0 +402,0 @@ self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help, |
'use strict'; | ||
var _ = { | ||
isPlainObject: require('lodash-compat/lang/isPlainObject') | ||
}; | ||
module.exports.__bind = function (fn, me) { | ||
@@ -10,5 +14,2 @@ return function(){ | ||
var log = module.exports.log = function() { | ||
log.history = log.history || []; | ||
log.history.push(arguments); | ||
// Only log if available and we're not testing | ||
@@ -28,2 +29,10 @@ if (console && process.env.NODE_ENV !== 'test') { | ||
var resolveSchema = module.exports.resolveSchema = function (schema) { | ||
if (_.isPlainObject(schema.schema)) { | ||
schema = resolveSchema(schema.schema); | ||
} | ||
return schema; | ||
}; | ||
module.exports.typeFromJsonSchema = function (type, format) { | ||
@@ -30,0 +39,0 @@ var str; |
@@ -6,2 +6,3 @@ 'use strict'; | ||
var request = require('superagent'); | ||
var jsyaml = require('js-yaml'); | ||
@@ -24,8 +25,30 @@ /* | ||
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); | ||
} | ||
// 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 (obj && typeof obj.body === 'object') { | ||
@@ -42,11 +65,6 @@ // special processing for file uploads via jquery | ||
} | ||
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 +152,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 +184,5 @@ cb.response(out); | ||
} | ||
var headers = obj.headers || {}; | ||
var r = request[method](obj.url); | ||
var name; | ||
for (name in headers) { | ||
@@ -182,2 +196,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 +223,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 +243,0 @@ response.statusText = res.text; |
@@ -10,18 +10,38 @@ 'use strict'; | ||
Resolver.prototype.resolve = function (spec, callback, scope) { | ||
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]; | ||
this.resolveTo(root, property, resolutionTable, '/definitions'); | ||
} | ||
for (propertyName in model.properties) { | ||
property = model.properties[propertyName]; | ||
this.resolveTo(property, resolutionTable); | ||
if(definition.allOf) { | ||
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); | ||
} | ||
} | ||
@@ -33,3 +53,2 @@ } | ||
var method, operation, responseCode; | ||
path = spec.paths[name]; | ||
@@ -40,3 +59,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 +67,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 +79,3 @@ | ||
// parameter reference | ||
this.resolveInline(spec, parameter, resolutionTable, unresolvedRefs); | ||
this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref); | ||
} | ||
@@ -65,11 +86,13 @@ } | ||
var response = operation.responses[responseCode]; | ||
location = '/paths' + name + '/' + method + '/responses/' + responseCode; | ||
if(typeof response === 'object') { | ||
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 +103,239 @@ } | ||
// 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('#'); | ||
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 { | ||
var 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') { | ||
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) { | ||
// local resolve | ||
self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item); | ||
processedCalls += 1; | ||
host = name; | ||
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] = null; | ||
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 | ||
}; | ||
} | ||
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, _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('/'); | ||
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]; | ||
var key = item.key; | ||
var resolvedTo = resolvedRefs[key]; | ||
if (resolvedTo) { | ||
spec.definitions = spec.definitions || {}; | ||
if (item.resolveAs === 'ref') { | ||
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 (resolvedTo) { | ||
if (!spec.definitions) { | ||
spec.definitions = {}; | ||
for (key in resolvedTo.obj) { | ||
var abs = this.retainRoot(resolvedTo.obj[key], item.root); | ||
targetObj[key] = abs; | ||
} | ||
} | ||
} | ||
} | ||
var existingUnresolved = this.countUnresolvedRefs(spec); | ||
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; | ||
if(existingUnresolved.length === 0 || this.iteration > 5) { | ||
this.resolveAllOf(spec.definitions); | ||
callback.call(this.scope, spec, unresolvedRefs); | ||
} | ||
else { | ||
this.iteration += 1; | ||
this.resolve(spec, root, callback, this.scope); | ||
} | ||
}; | ||
delete targetObj.$ref; | ||
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); | ||
} | ||
} | ||
for (key in resolvedTo.obj) { | ||
targetObj[key] = resolvedTo.obj[key]; | ||
} | ||
// verify possible keys | ||
for(i in keys) { | ||
var part = keys[i]; | ||
var parts = part.split('/'); | ||
var obj = spec; | ||
for(var k in parts) { | ||
var key = parts[k]; | ||
if(key !== '') { | ||
obj = obj[key]; | ||
if(typeof obj === 'undefined') { | ||
unresolvedKeys.push(part); | ||
break; | ||
} | ||
@@ -239,11 +345,42 @@ } | ||
} | ||
return unresolvedKeys.length; | ||
}; | ||
// TODO need to check if we're done instead of just resolving 2x | ||
if(this.iteration === 2) { | ||
callback.call(this.scope, spec, unresolvedRefs); | ||
Resolver.prototype.getRefs = function(spec, obj) { | ||
obj = obj || spec; | ||
var output = {}; | ||
for(var key in obj) { | ||
var item = obj[key]; | ||
if(key === '$ref' && typeof item === 'string') { | ||
output[item] = null; | ||
} | ||
else if(typeof item === 'object') { | ||
var o = this.getRefs(item); | ||
for(var k in o) { | ||
output[k] = null; | ||
} | ||
} | ||
} | ||
else { | ||
this.iteration += 1; | ||
this.resolve(spec, callback, this.scope); | ||
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(typeof item === 'object') { | ||
this.retainRoot(item, root); | ||
} | ||
} | ||
return obj; | ||
}; | ||
@@ -255,58 +392,151 @@ | ||
*/ | ||
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('http') === 0) { | ||
if (Array.isArray(objs[ref])) { | ||
objs[ref].push({obj: property, resolveAs: 'inline'}); | ||
} else { | ||
objs[ref] = [{obj: property, resolveAs: 'inline'}]; | ||
} | ||
} else if (ref.indexOf('#') === 0) { | ||
// local resolve | ||
var shortenedRef = ref.substring(1); | ||
var i, parts = shortenedRef.split('/'), location = spec; | ||
for (i = 0; i < parts.length; i++) { | ||
var part = parts[i]; | ||
if (part.length > 0) { | ||
location = location[part]; | ||
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]; | ||
} | ||
} | ||
if (location) { | ||
delete property.$ref; | ||
var key; | ||
for (key in location) { | ||
property[key] = location[key]; | ||
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]; | ||
} | ||
} else { | ||
unresolvedRefs[ref] = null; | ||
location = rs[1]; | ||
} | ||
} | ||
if (ref.indexOf('http') === 0) { | ||
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) { | ||
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(property.items, objs); | ||
this.resolveTo(root, property.items, resolutionTable, location); | ||
} | ||
}; | ||
Resolver.prototype.resolveTo = function (property, objs) { | ||
Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) { | ||
var ref = property.$ref; | ||
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'}]; | ||
} | ||
if(ref.indexOf('#') >= 0) { | ||
location = ref.split('#')[1]; | ||
} | ||
resolutionTable.push({ | ||
obj: property, resolveAs: 'ref', root: root, key: ref, location: location | ||
}); | ||
} else if (property.type === 'array') { | ||
var items = property.items; | ||
this.resolveTo(root, items, resolutionTable, location); | ||
} | ||
}; | ||
this.resolveTo(items, objs); | ||
Resolver.prototype.resolveAllOf = function(spec, obj, depth) { | ||
depth = depth || 0; | ||
obj = obj || spec; | ||
var name; | ||
for(var key in obj) { | ||
var item = obj[key]; | ||
if(item && typeof item.allOf !== 'undefined') { | ||
var allOf = item.allOf; | ||
if(Array.isArray(allOf)) { | ||
var output = {}; | ||
output['x-composed'] = true; | ||
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]; | ||
} | ||
for(var part in component) { | ||
if(!output.hasOwnProperty(part)) { | ||
output[part] = 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] = properties[name]; | ||
output.properties[name]['x-resolved-from'] = source; | ||
} | ||
} | ||
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; | ||
} | ||
} | ||
if(typeof item === 'object') { | ||
this.resolveAllOf(spec, item, depth + 1); | ||
} | ||
} | ||
}; |
'use strict'; | ||
var SwaggerClient = require('./client'); | ||
var SwaggerHttp = require('./http'); | ||
@@ -19,3 +18,3 @@ | ||
**/ | ||
SwaggerSpecConverter.prototype.convert = function (obj, callback) { | ||
SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, callback) { | ||
// not a valid spec | ||
@@ -25,2 +24,3 @@ if(!obj || !Array.isArray(obj.apis)) { | ||
} | ||
this.clientAuthorizations = clientAuthorizations; | ||
@@ -43,2 +43,7 @@ // create a new swagger object to return | ||
// take basePath into account | ||
if (obj.basePath) { | ||
this.setDocumentationLocation(obj.basePath); | ||
} | ||
// see if this is a single-file swagger definition | ||
@@ -63,3 +68,3 @@ var isSingleFileSwagger = false; | ||
SwaggerSpecConverter.prototype.declaration = function(obj, swagger) { | ||
var name, i; | ||
var name, i, p, pos; | ||
if(!obj.apis) { | ||
@@ -69,15 +74,28 @@ return; | ||
var basePath = obj.basePath; | ||
if(obj.basePath.indexOf('http://') === 0) { | ||
var p = obj.basePath.substring('http://'.length); | ||
var pos = p.indexOf('/'); | ||
if(pos > 0) { | ||
if (obj.basePath.indexOf('http://') === 0) { | ||
p = obj.basePath.substring('http://'.length); | ||
pos = p.indexOf('/'); | ||
if (pos > 0) { | ||
swagger.host = p.substring(0, pos); | ||
swagger.basePath = p.substring(pos); | ||
} | ||
else{ | ||
else { | ||
swagger.host = p; | ||
swagger.basePath = '/'; | ||
} | ||
} else if (obj.basePath.indexOf('https://') === 0) { | ||
p = obj.basePath.substring('https://'.length); | ||
pos = p.indexOf('/'); | ||
if (pos > 0) { | ||
swagger.host = p.substring(0, pos); | ||
swagger.basePath = p.substring(pos); | ||
} | ||
else { | ||
swagger.host = p; | ||
swagger.basePath = '/'; | ||
} | ||
} else { | ||
swagger.basePath = obj.basePath; | ||
} | ||
var resourceLevelAuth; | ||
@@ -110,3 +128,3 @@ if(obj.authorizations) { | ||
var models = obj.models; | ||
var models = obj.models || {}; | ||
this.models(models, swagger); | ||
@@ -148,2 +166,4 @@ }; | ||
} | ||
schema.required = existingModel.required; | ||
swagger.definitions[name] = schema; | ||
@@ -159,4 +179,7 @@ } | ||
} | ||
if(pathString.endsWith('.json')) { | ||
pathString = pathString.substring(0, pathString.length - '.json'.length); | ||
} | ||
return pathString.replace('/',''); | ||
} | ||
}; | ||
@@ -198,2 +221,3 @@ SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) { | ||
if(typeof existingAuthorizations !== 'undefined') { | ||
var scopesObject; | ||
for(var key in existingAuthorizations) { | ||
@@ -207,3 +231,3 @@ operation.security = operation.security || []; | ||
} | ||
var scopesObject = {}; | ||
scopesObject = {}; | ||
scopesObject[key] = securityScopes; | ||
@@ -213,3 +237,3 @@ operation.security.push(scopesObject); | ||
else { | ||
var scopesObject = {}; | ||
scopesObject = {}; | ||
scopesObject[key] = []; | ||
@@ -256,3 +280,3 @@ operation.security.push(scopesObject); | ||
SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation, swagger) { | ||
SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) { | ||
if(typeof existingOperation !== 'object') { | ||
@@ -264,3 +288,5 @@ return; | ||
this.dataType(existingOperation, defaultResponse); | ||
if(!defaultResponse.schema) { | ||
// TODO: look into the real problem of rendering responses in swagger-ui | ||
// ....should reponseType have an implicit schema? | ||
if(!defaultResponse.schema && defaultResponse.type) { | ||
defaultResponse = {schema: defaultResponse}; | ||
@@ -282,4 +308,7 @@ } | ||
} | ||
// Convert responseModel -> schema{$ref: responseModel} | ||
if(existingResponse.responseModel) { | ||
response.schema = {'$ref': existingResponse.responseModel}; | ||
} | ||
operation.responses['' + existingResponse.code] = response; | ||
// TODO: schema | ||
} | ||
@@ -296,3 +325,3 @@ } | ||
SwaggerSpecConverter.prototype.authorizations = function(obj, swagger) { | ||
SwaggerSpecConverter.prototype.authorizations = function(obj) { | ||
// TODO | ||
@@ -304,3 +333,3 @@ if(typeof obj !== 'object') { | ||
SwaggerSpecConverter.prototype.parameters = function(operation, obj, swagger) { | ||
SwaggerSpecConverter.prototype.parameters = function(operation, obj) { | ||
if(!Array.isArray(obj)) { | ||
@@ -326,2 +355,6 @@ return; | ||
if(existingParameter.enum) { | ||
parameter.enum = existingParameter.enum; | ||
} | ||
if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') { | ||
@@ -360,3 +393,5 @@ var innerType = {}; | ||
} | ||
if(source.defaultValue) { | ||
// default can be 'false' | ||
if(typeof source.defaultValue !== 'undefined') { | ||
target.default = source.defaultValue; | ||
@@ -426,2 +461,4 @@ } | ||
} | ||
else if(lcType === 'void' || lcType === '') | ||
{return {};} | ||
else { | ||
@@ -433,6 +470,7 @@ return {$ref: '#/definitions/' + this.modelMap[source.type] || source.type}; | ||
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 | ||
@@ -454,3 +492,3 @@ if(expectedCount === 0) { | ||
}); | ||
}; | ||
} | ||
var http = { | ||
@@ -462,6 +500,8 @@ url: absolutePath, | ||
}; | ||
/* jshint ignore:start */ | ||
http.on.response = function(data) { | ||
processedCount += 1; | ||
if(data.obj) { | ||
self.declaration(data.obj, _swagger); | ||
var obj = data.obj; | ||
if(obj) { | ||
self.declaration(obj, _swagger); | ||
} | ||
@@ -479,2 +519,8 @@ if(processedCount === expectedCount) { | ||
}; | ||
/* jshint ignore:end */ | ||
if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') { | ||
this.clientAuthorizations.apply(http); | ||
} | ||
new SwaggerHttp().execute(http); | ||
@@ -532,3 +578,3 @@ } | ||
if(i > 0) { | ||
securityDefinition.scopes = scopes; | ||
securityDefinition.scopes = scopes; | ||
} | ||
@@ -542,6 +588,7 @@ if(definition.grantTypes) { | ||
} | ||
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'; | ||
@@ -553,2 +600,3 @@ securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url; | ||
} | ||
/* jshint ignore:end */ | ||
} | ||
@@ -600,2 +648,2 @@ } | ||
callback(obj); | ||
}; | ||
}; |
'use strict'; | ||
var _ = { | ||
cloneDeep: require('lodash-compat/lang/cloneDeep'), | ||
forEach: require('lodash-compat/collection/forEach'), | ||
@@ -14,30 +15,5 @@ indexOf: require('lodash-compat/array/indexOf'), | ||
var helpers = require('../helpers'); | ||
var jsyaml = require('js-yaml'); | ||
/** | ||
* allows override of the default value based on the parameter being | ||
* supplied | ||
**/ | ||
var applyParameterMacro = function (operation, parameter) { | ||
// TODO the reference to operation.api is not available | ||
if (operation.api && operation.api.parameterMacro) { | ||
return operation.api.parameterMacro(operation, parameter); | ||
} else { | ||
return parameter.defaultValue; | ||
} | ||
}; | ||
/** | ||
* allows overriding the default value of an model property | ||
**/ | ||
var applyModelPropertyMacro = function (model, property) { | ||
// TODO the reference to model.api is not available | ||
if (model.api && model.api.modelPropertyMacro) { | ||
return model.api.modelPropertyMacro(model, property); | ||
} else { | ||
return property.default; | ||
} | ||
}; | ||
var Model = module.exports = function (name, definition, models) { | ||
var Model = module.exports = function (name, definition, models, modelPropertyMacro) { | ||
this.definition = definition || {}; | ||
@@ -47,2 +23,5 @@ this.isArray = definition.type === 'array'; | ||
this.name = definition.title || name || 'Inline Model'; | ||
this.modelPropertyMacro = modelPropertyMacro || function (property) { | ||
return property.default; | ||
}; | ||
@@ -52,3 +31,3 @@ return this; | ||
var schemaToHTML = function (name, schema, models) { | ||
var schemaToHTML = function (name, schema, models, modelPropertyMacro) { | ||
var strongOpen = '<span class="strong">'; | ||
@@ -68,3 +47,3 @@ var strongClose = '</span>'; | ||
modelName = schema.title || 'Inline Model ' + (++inlineModels); | ||
model = new Model(modelName, schema, models); | ||
model = new Model(modelName, schema, models, modelPropertyMacro); | ||
} | ||
@@ -78,2 +57,3 @@ | ||
}; | ||
var primitiveToHTML = function (schema) { | ||
@@ -268,8 +248,28 @@ var html = '<span class="propType">'; | ||
html += _.map(schema.properties, function (property, name) { | ||
var required = _.indexOf(schema.required || [], name) > -1; | ||
var html = '<span class="propName ' + required + '">' + name + '</span> ('; | ||
var propertyIsRequired = (_.indexOf(schema.required, name) >= 0); | ||
var cProperty = _.cloneDeep(property); | ||
html += primitiveToHTML(property); | ||
var requiredClass = propertyIsRequired ? 'required' : ''; | ||
var html = '<span class="propName ' + requiredClass + '">' + name + '</span> ('; | ||
var model; | ||
if (!required) { | ||
// 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>'; | ||
@@ -280,11 +280,11 @@ } | ||
if (!_.isUndefined(property.description)) { | ||
html += ': ' + property.description; | ||
if (!_.isUndefined(cProperty.description)) { | ||
html += ': ' + '<span class="propDesc">' + cProperty.description + '</span>'; | ||
} | ||
if (property.enum) { | ||
html += ' = <span class="propVals">[\'' + property.enum.join('\' or \'') + '\']</span>'; | ||
if (cProperty.enum) { | ||
html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>'; | ||
} | ||
return primitiveToOptionsHTML(property, html); | ||
return primitiveToOptionsHTML(cProperty, html); | ||
}).join(',</div><div>'); | ||
@@ -295,3 +295,3 @@ } | ||
} else { | ||
html = '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; | ||
html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>'; | ||
} | ||
@@ -303,8 +303,11 @@ } | ||
// 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) { | ||
/* jshint ignore:start */ | ||
_.forEach(references, function (schema, name) { | ||
@@ -321,2 +324,3 @@ var seenModel = _.indexOf(seenModels, name) > -1; | ||
}); | ||
/* jshint ignore:end */ | ||
} | ||
@@ -327,4 +331,8 @@ | ||
var schemaToJSON = function (schema, models, modelsToIgnore) { | ||
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; | ||
@@ -346,3 +354,3 @@ var output; | ||
modelsToIgnore[model.name] = model; | ||
output = schemaToJSON(model.definition, models, modelsToIgnore); | ||
output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro); | ||
delete modelsToIgnore[model.name]; | ||
@@ -359,20 +367,16 @@ } else { | ||
output = schema.default; | ||
} else if (type === 'date-time') { | ||
output = new Date().toISOString(); | ||
} else if (type === 'date') { | ||
output = new Date().toISOString().split('T')[0]; | ||
} else if (type === 'string') { | ||
output = '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 === 'long') { | ||
output = 0; | ||
} else if (type === 'float') { | ||
} else if (type === 'number') { | ||
output = 0.0; | ||
} else if (type === 'double') { | ||
output = 0.0; | ||
} else if (type === 'boolean') { | ||
output = true; | ||
} else if (type === 'number') { | ||
output = 0.0; | ||
} else if (type === 'object') { | ||
@@ -382,3 +386,8 @@ output = {}; | ||
_.forEach(schema.properties, function (property, name) { | ||
output[name] = schemaToJSON(property, models, modelsToIgnore); | ||
var cProperty = _.cloneDeep(property); | ||
// Allow macro to set the default value | ||
cProperty.default = modelPropertyMacro(property); | ||
output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro); | ||
}); | ||
@@ -390,6 +399,6 @@ } else if (type === 'array') { | ||
_.forEach(schema.items, function (item) { | ||
output.push(schemaToJSON(item, models, modelsToIgnore)); | ||
output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro)); | ||
}); | ||
} else if (_.isPlainObject(schema.items)) { | ||
output.push(schemaToJSON(schema.items, models, modelsToIgnore)); | ||
output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro)); | ||
} else if (_.isUndefined(schema.items)) { | ||
@@ -416,14 +425,13 @@ output.push({}); | ||
if (_.isString(this.definition.example)) { | ||
this.definition.example = JSON.parse(this.definition.example); | ||
this.definition.example = jsyaml.safeLoad(this.definition.example); | ||
} | ||
} else { | ||
} else if (!this.definition.example) { | ||
this.definition.example = this.examples; | ||
} | ||
return schemaToJSON(this.definition, this.models, modelsToIgnore); | ||
return schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro); | ||
}; | ||
Model.prototype.getMockSignature = function () { | ||
return schemaToHTML(this.name, this.definition, this.models); | ||
return schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro); | ||
}; |
'use strict'; | ||
var _ = { | ||
isUndefined: require('lodash-compat/lang/isUndefined') | ||
cloneDeep: require('lodash-compat/lang/cloneDeep'), | ||
isUndefined: require('lodash-compat/lang/isUndefined'), | ||
isEmpty: require('lodash-compat/lang/isEmpty') | ||
}; | ||
@@ -16,6 +18,11 @@ var helpers = require('../helpers'); | ||
if(parent && parent.options) { | ||
this.client = parent.options.client || null; | ||
this.responseInterceptor = parent.options.responseInterceptor || null; | ||
} | ||
this.authorizations = args.security; | ||
this.basePath = parent.basePath || '/'; | ||
this.clientAuthorizations = clientAuthorizations; | ||
this.consumes = args.consumes; | ||
this.consumes = args.consumes || parent.consumes || ['application/json']; | ||
this.produces = args.produces || parent.produces || ['application/json']; | ||
this.deprecated = args.deprecated; | ||
@@ -32,3 +39,2 @@ this.description = args.description; | ||
this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.')); | ||
this.produces = args.produces; | ||
this.responses = (args.responses || {}); | ||
@@ -41,3 +47,8 @@ this.scheme = scheme || parent.scheme || 'http'; | ||
this.useJQuery = parent.useJQuery; | ||
this.parameterMacro = parent.parameterMacro || function (parameter) { | ||
return parameter.default; | ||
}; | ||
this.inlineModels = []; | ||
if (typeof this.deprecated === 'string') { | ||
@@ -65,4 +76,4 @@ switch(this.deprecated.toLowerCase()) { | ||
for (key in this.definitions) { | ||
model = new Model(key, definitions[key], this.models); | ||
for (key in definitions) { | ||
model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro); | ||
@@ -74,8 +85,16 @@ if (model) { | ||
} | ||
for (i = 0; i < this.parameters.length; i++) { | ||
var param = this.parameters[i]; | ||
// Allow macro to set the default value | ||
param.default = this.parameterMacro(param); | ||
if (param.type === 'array') { | ||
param.isList = true; | ||
param.allowMultiple = true; | ||
// the enum can be defined at the items level | ||
if (param.items && param.items.enum) { | ||
param['enum'] = param.items.enum; | ||
} | ||
} | ||
@@ -88,3 +107,3 @@ | ||
param.isList = true; | ||
param['enum'] = ['true', 'false']; | ||
param['enum'] = [true, false]; // use actual primitives | ||
} | ||
@@ -101,6 +120,7 @@ | ||
var value = param['enum'][id]; | ||
var isDefault = (value === param.default) ? true : false; | ||
var isDefault = (value === param.default || value+'' === param.default); | ||
param.allowableValues.values.push(value); | ||
param.allowableValues.descriptiveValues.push({value : value, isDefault: isDefault}); | ||
// Always have string for descriptive values.... | ||
param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault}); | ||
} | ||
@@ -151,3 +171,3 @@ } | ||
} | ||
if (response && response.schema) { | ||
@@ -161,7 +181,7 @@ var resolvedModel = this.resolveModel(response.schema, definitions); | ||
this.successResponse = {}; | ||
successResponse = this.successResponse[defaultResponseCode] = resolvedModel; | ||
successResponse = this.successResponse[defaultResponseCode] = resolvedModel; | ||
} else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') { | ||
// Inline model | ||
this.successResponse = {}; | ||
successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models); | ||
successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro); | ||
} else { | ||
@@ -200,2 +220,9 @@ // Primitive | ||
Operation.prototype.isDefaultArrayItemValue = function(value, param) { | ||
if (param.default && Array.isArray(param.default)) { | ||
return param.default.indexOf(value) !== -1; | ||
} | ||
return value === param.default; | ||
}; | ||
Operation.prototype.getType = function (param) { | ||
@@ -238,3 +265,3 @@ var type = param.type; | ||
if (param.$ref) { | ||
str = param.$ref; | ||
str = helpers.simpleRef(param.$ref); | ||
} | ||
@@ -256,2 +283,6 @@ | ||
} else { | ||
// If inline schema, we add it our interal hash -> which gives us it's ID (int) | ||
if(schema.type === 'object') { | ||
return this.addInlineModel(schema); | ||
} | ||
return this.getType(schema); | ||
@@ -267,2 +298,32 @@ } | ||
/** | ||
* adds an inline schema (model) to a hash, where we can ref it later | ||
* @param {object} schema a schema | ||
* @return {number} the ID of the schema being added, or null | ||
**/ | ||
Operation.prototype.addInlineModel = function (schema) { | ||
var len = this.inlineModels.length; | ||
var model = this.resolveModel(schema, {}); | ||
if(model) { | ||
this.inlineModels.push(model); | ||
return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel) | ||
} | ||
return null; // report errors? | ||
}; | ||
/** | ||
* gets the internal ref to an inline model | ||
* @param {string} inline_str a string reference to an inline model | ||
* @return {Model} the model being referenced. Or null | ||
**/ | ||
Operation.prototype.getInlineModel = function(inlineStr) { | ||
if(/^Inline Model \d+$/.test(inlineStr)) { | ||
var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); // | ||
var model = this.inlineModels[id]; | ||
return model; | ||
} | ||
// I'm returning null here, should I rather throw an error? | ||
return null; | ||
}; | ||
Operation.prototype.resolveModel = function (schema, definitions) { | ||
@@ -277,6 +338,8 @@ if (typeof schema.$ref !== 'undefined') { | ||
if (definitions[ref]) { | ||
return new Model(ref, definitions[ref], this.models); | ||
return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro); | ||
} | ||
} else if (schema.type === 'object' || _.isUndefined(schema.type)) { | ||
return new Model(undefined, schema, this.models); | ||
// schema must at least be an object to get resolved to an inline Model | ||
} else if (schema && typeof schema === 'object' && | ||
(schema.type === 'object' || _.isUndefined(schema.type))) { | ||
return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro); | ||
} | ||
@@ -310,10 +373,21 @@ | ||
type = type[0]; | ||
} else if (typeof type === 'undefined') { | ||
type = 'undefined'; | ||
} | ||
if (type === 'string') { | ||
// Convert undefined to string of 'undefined' | ||
if (typeof type === 'undefined') { | ||
type = 'undefined'; | ||
isPrimitive = true; | ||
} else if (definitions[type]){ | ||
// a model def exists? | ||
type = definitions[type]; /* Model */ | ||
isPrimitive = false; | ||
} else if (this.getInlineModel(type)) { | ||
type = this.getInlineModel(type); /* Model */ | ||
isPrimitive = false; | ||
} else { | ||
isPrimitive = (listType && definitions[listType]) || (definitions[type]) ? false : true; | ||
// We default to primitive | ||
isPrimitive = true; | ||
} | ||
@@ -329,5 +403,5 @@ | ||
if (listType) { | ||
return 'Array[' + definitions[type].getMockSignature() + ']'; | ||
return 'Array[' + type.getMockSignature() + ']'; | ||
} else { | ||
return definitions[type].getMockSignature(); | ||
return type.getMockSignature(); | ||
} | ||
@@ -436,3 +510,3 @@ } | ||
Operation.prototype.getBody = function (headers, args, opts) { | ||
var formParams = {}, body, key, value; | ||
var formParams = {}, body, key, value, hasBody = false; | ||
@@ -449,4 +523,17 @@ for (var i = 0; i < this.parameters.length; i++) { | ||
} | ||
else { | ||
if(param.in === 'body') { | ||
hasBody = true; | ||
} | ||
} | ||
} | ||
// if body is null and hasBody is true, AND a JSON body is requested, send empty {} | ||
if(hasBody && typeof body === 'undefined') { | ||
var contentType = headers['Content-Type']; | ||
if(contentType && contentType.indexOf('application/json') === 0) { | ||
body = '{}'; | ||
} | ||
} | ||
// handle form params | ||
@@ -501,8 +588,15 @@ if (headers['Content-Type'] === 'application/x-www-form-urlencoded') { | ||
Operation.prototype.getModelSampleJSON = function (type, models) { | ||
var isPrimitive, listType, sampleJson; | ||
var listType, sampleJson, innerType; | ||
models = models || {}; | ||
listType = (type instanceof Array); | ||
isPrimitive = models[type] ? false : true; | ||
sampleJson = isPrimitive ? void 0 : models[type].createJSONSample(); | ||
innerType = listType ? type[0] : type; | ||
if(models[innerType]) { | ||
sampleJson = models[innerType].createJSONSample(); | ||
} else if (this.getInlineModel(innerType)){ | ||
sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct | ||
} | ||
if (sampleJson) { | ||
@@ -553,2 +647,10 @@ sampleJson = listType ? [sampleJson] : sampleJson; | ||
if(this.client) { | ||
opts.client = this.client; | ||
} | ||
if(this.responseInterceptor) { | ||
opts.responseInterceptor = this.responseInterceptor; | ||
} | ||
if (typeof arg2 === 'function') { | ||
@@ -559,9 +661,9 @@ success = arg2; | ||
success = (success || helpers.log); | ||
error = (error || helpers.log); | ||
success = (success || this.parent.defaultSuccessCallback || helpers.log); | ||
error = (error || this.parent.defaultErrorCallback || helpers.log); | ||
if (opts.useJQuery) { | ||
this.useJQuery = opts.useJQuery; | ||
if (typeof opts.useJQuery === 'undefined') { | ||
opts.useJQuery = this.useJQuery; | ||
} | ||
var missingParams = this.getMissingParams(args); | ||
@@ -573,2 +675,3 @@ | ||
helpers.fail(message); | ||
error(message); | ||
@@ -585,3 +688,3 @@ return; | ||
var body = this.getBody(headers, args, opts); | ||
var body = this.getBody(contentTypeHeaders, args, opts); | ||
var url = this.urlify(args); | ||
@@ -605,3 +708,3 @@ | ||
body: body, | ||
useJQuery: this.useJQuery, | ||
useJQuery: opts.useJQuery, | ||
headers: headers, | ||
@@ -626,8 +729,25 @@ on: { | ||
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) { | ||
// default type | ||
var accepts = 'application/json'; | ||
var allDefinedParams = this.parameters; | ||
var body; | ||
var consumes = args.parameterContentType || 'application/json'; | ||
var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']); | ||
var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']); | ||
var definedFileParams = []; | ||
@@ -661,7 +781,6 @@ var definedFormParams = []; | ||
// 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 (this.method === 'post' || this.method === 'put' || this.method === 'patch') { | ||
if (opts.requestContentType) { | ||
consumes = opts.requestContentType; | ||
} | ||
} else { | ||
// if any form params, content type must be set | ||
@@ -676,8 +795,7 @@ if (definedFormParams.length > 0) { | ||
} | ||
} else if (this.type === 'DELETE') { | ||
body = '{}'; | ||
} else if (this.type !== 'DELETE') { | ||
consumes = null; | ||
} | ||
} | ||
else { | ||
consumes = null; | ||
} | ||
@@ -690,14 +808,6 @@ if (consumes && this.consumes) { | ||
if (opts.responseContentType) { | ||
accepts = opts.responseContentType; | ||
} else { | ||
accepts = 'application/json'; | ||
if (!this.matchesAccept(accepts)) { | ||
helpers.log('server can\'t produce ' + accepts); | ||
} | ||
if (accepts && this.produces) { | ||
if (this.produces.indexOf(accepts) === -1) { | ||
helpers.log('server can\'t produce ' + accepts); | ||
} | ||
} | ||
if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) { | ||
@@ -714,2 +824,16 @@ headers['Content-Type'] = consumes; | ||
/** | ||
* 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 (args) { | ||
@@ -794,3 +918,3 @@ var obj = this.execute(args, {mock: true}); | ||
separator = '|'; | ||
} else if (type === 'brackets') { | ||
} else if (type === 'brackets') { | ||
for (i = 0; i < value.length; i++) { | ||
@@ -827,18 +951,3 @@ if (i !== 0) { | ||
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.1-M2", | ||
"version": "2.1.1", | ||
"homepage": "http://swagger.io", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/swagger-api/swagger-client.git" | ||
"url": "https://github.com/swagger-api/swagger-js.git" | ||
}, | ||
@@ -19,3 +21,4 @@ "main": "index.js", | ||
"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,6 +61,14 @@ "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" | ||
@@ -59,0 +75,0 @@ }, |
@@ -8,7 +8,2 @@ # Swagger JS library | ||
## What's Swagger? | ||
The goal of Swagger™ is to define a standard, language-agnostic interface to REST APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined via Swagger, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interfaces have done for lower-level programming, Swager removes the guesswork in calling the service. | ||
Check out [Swagger-Spec](https://github.com/swagger-api/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more. | ||
@@ -26,3 +21,3 @@ | ||
```js | ||
var client = require("swagger-client") | ||
var client = require('swagger-client'); | ||
@@ -32,8 +27,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: | ||
@@ -81,13 +79,13 @@ | ||
Download `browser/swagger-client.js` into your lib folder | ||
Download `browser/swagger-client.js` into your webapp: | ||
```js | ||
<script src='lib/swagger-client.js' type='text/javascript'></script> | ||
<script src='browser/swagger-client.js' type='text/javascript'></script> | ||
<script type="text/javascript"> | ||
// initialize swagger, point to a resource listing | ||
window.swagger = new client.SwaggerClient({ | ||
window.swagger = new SwaggerClient({ | ||
url: "http://petstore.swagger.io/api/api-docs", | ||
success: function() { | ||
// 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); | ||
@@ -97,4 +95,7 @@ }); | ||
}); | ||
</script> | ||
</script> | ||
<body> | ||
<div id="mydata"></div> | ||
</body> | ||
``` | ||
@@ -197,3 +198,3 @@ | ||
Copyright 2011-2015 Reverb Technologies, Inc. | ||
Copyright 2011-2015 SmartBear Software | ||
@@ -200,0 +201,0 @@ Licensed under the Apache License, Version 2.0 (the "License"); |
Sorry, the diff of this file is not supported yet
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
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
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
3187813
58459
0
205
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