swagger-tools
Advanced tools
Comparing version 0.7.4 to 0.8.0
@@ -389,18 +389,17 @@ /* | ||
var childPath = modelDefPath.concat(['allOf', index.toString()]); | ||
var parentMetadata; | ||
var parentPath; | ||
if (_.isUndefined(schema.$ref) || JsonRefs.isRemotePointer(schema.$ref)) { | ||
parentPath = modelDefPath.concat(['allOf', index.toString()]); | ||
} else { | ||
parentMetadata = getDefinitionMetadata(JsonRefs.pathFromPointer(schema.$ref)); | ||
childPath.push('$ref'); | ||
parentPath = JsonRefs.pathFromPointer(schema.$ref); | ||
} | ||
modelMetadata.parents.push(JsonRefs.pathToPointer(parentPath)); | ||
if (parentMetadata) { | ||
addReference(documentMetadata, parentPath, childPath, results); | ||
} | ||
// If the parent model does not exist, do not create its metadata | ||
if (!_.isUndefined(traverse(documentMetadata.resolved).get(parentPath))) { | ||
getDefinitionMetadata(JsonRefs.pathFromPointer(schema.$ref)); | ||
modelMetadata.parents.push(JsonRefs.pathToPointer(parentPath)); | ||
} | ||
}); | ||
@@ -501,3 +500,3 @@ | ||
validateSchemaConstraints(documentMetadata, definition, defPath, results); | ||
// Identify redeclared properties | ||
@@ -513,5 +512,5 @@ _.each(definition.properties, function (property, name) { | ||
createErrorOrWarning('CHILD_' + code + '_REDECLARES_PROPERTY', | ||
'Child ' + code.toLowerCase() + ' declares property already declared by ancestor: ' + | ||
name, | ||
pPath, results.errors); | ||
'Child ' + code.toLowerCase() + ' declares property already declared by ancestor: ' + | ||
name, | ||
pPath, results.errors); | ||
} else { | ||
@@ -525,5 +524,7 @@ dProperties.push(name); | ||
_.each(definition.required || [], function (name, index) { | ||
var type = swaggerVersion === '1.2' ? 'Model' : 'Definition'; | ||
if (iProperties.indexOf(name) === -1 && dProperties.indexOf(name) === -1) { | ||
createErrorOrWarning('MISSING_REQUIRED_MODEL_PROPERTY', | ||
'Model requires property but it is not defined: ' + name, | ||
createErrorOrWarning('MISSING_REQUIRED_' + type.toUpperCase() + '_PROPERTY', | ||
type + ' requires property but it is not defined: ' + name, | ||
defPath.concat(['required', index.toString()]), results.errors); | ||
@@ -929,4 +930,7 @@ } | ||
_.each(operation.responses, function (response, responseCode) { | ||
// Validate validate inline constraints | ||
validateSchemaConstraints(documentMetadata, response, oPath.concat('responses', responseCode), results); | ||
// Do not process references to missing responses | ||
if (!_.isUndefined(response)) { | ||
// Validate validate inline constraints | ||
validateSchemaConstraints(documentMetadata, response, oPath.concat('responses', responseCode), results); | ||
} | ||
}); | ||
@@ -933,0 +937,0 @@ }); |
@@ -46,3 +46,3 @@ /* | ||
if (matches === null) { | ||
return false; | ||
return false; | ||
} | ||
@@ -77,3 +77,3 @@ | ||
if (!isValidDate(date)) { | ||
return false; | ||
return false; | ||
} | ||
@@ -84,3 +84,3 @@ | ||
if (matches === null) { | ||
return false; | ||
return false; | ||
} | ||
@@ -114,3 +114,3 @@ | ||
_.each(obj.inner, function (nObj) { | ||
removeParams(nObj); | ||
removeParams(nObj); | ||
}); | ||
@@ -133,8 +133,8 @@ } | ||
err.results = { | ||
errors: _.map(validator.getLastErrors(), function (err) { | ||
removeParams(err); | ||
errors: _.map(validator.getLastErrors(), function (err) { | ||
removeParams(err); | ||
return err; | ||
}), | ||
warnings: [] | ||
return err; | ||
}), | ||
warnings: [] | ||
}; | ||
@@ -191,4 +191,4 @@ | ||
if (pOrC.length > 0 && (isResponse ? | ||
true : | ||
['POST', 'PUT'].indexOf(reqOrRes.method) !== -1) && pOrC.indexOf(contentType) === -1) { | ||
true : | ||
['POST', 'PUT'].indexOf(reqOrRes.method) !== -1) && pOrC.indexOf(contentType) === -1) { | ||
throw new Error('Invalid content type (' + contentType + '). These are valid: ' + pOrC.join(', ')); | ||
@@ -288,3 +288,3 @@ } | ||
throwErrorWithCode('MAX_PROPERTIES', | ||
'Number of properties is too many (' + propCount + ' properties), maximum ' + maxProperties); | ||
'Number of properties is too many (' + propCount + ' properties), maximum ' + maxProperties); | ||
} | ||
@@ -369,3 +369,3 @@ }; | ||
throwErrorWithCode('MIN_PROPERTIES', | ||
'Number of properties is too few (' + propCount + ' properties), minimum ' + minProperties); | ||
'Number of properties is too few (' + propCount + ' properties), minimum ' + minProperties); | ||
} | ||
@@ -433,5 +433,5 @@ }; | ||
_.each(val, function (aVal, index) { | ||
if (!validateTypeAndFormat(aVal, type, format, true)) { | ||
throwErrorWithCode('INVALID_TYPE', 'Value at index ' + index + ' is not a valid ' + type + ': ' + aVal); | ||
} | ||
if (!validateTypeAndFormat(aVal, type, format, true)) { | ||
throwErrorWithCode('INVALID_TYPE', 'Value at index ' + index + ' is not a valid ' + type + ': ' + aVal); | ||
} | ||
}); | ||
@@ -441,25 +441,25 @@ } else { | ||
case 'boolean': | ||
result = _.isBoolean(val) || ['false', 'true'].indexOf(val) !== -1; | ||
break; | ||
result = _.isBoolean(val) || ['false', 'true'].indexOf(val) !== -1; | ||
break; | ||
case 'integer': | ||
result = !_.isNaN(parseInt(val, 10)); | ||
break; | ||
result = !_.isNaN(parseInt(val, 10)); | ||
break; | ||
case 'number': | ||
result = !_.isNaN(parseFloat(val)); | ||
break; | ||
result = !_.isNaN(parseFloat(val)); | ||
break; | ||
case 'string': | ||
if (!_.isUndefined(format)) { | ||
switch (format) { | ||
case 'date': | ||
result = isValidDate(val); | ||
break; | ||
case 'date-time': | ||
result = isValidDateTime(val); | ||
break; | ||
} | ||
} | ||
break; | ||
if (!_.isUndefined(format)) { | ||
switch (format) { | ||
case 'date': | ||
result = isValidDate(val); | ||
break; | ||
case 'date-time': | ||
result = isValidDateTime(val); | ||
break; | ||
} | ||
} | ||
break; | ||
case 'void': | ||
result = _.isUndefined(val); | ||
break; | ||
result = _.isUndefined(val); | ||
break; | ||
} | ||
@@ -472,5 +472,5 @@ } | ||
throwErrorWithCode('INVALID_TYPE', | ||
type !== 'void' ? | ||
'Not a valid ' + (_.isUndefined(format) ? '' : format + ' ') + type + ': ' + val : | ||
'Void does not allow a value'); | ||
type !== 'void' ? | ||
'Not a valid ' + (_.isUndefined(format) ? '' : format + ' ') + type + ': ' + val : | ||
'Void does not allow a value'); | ||
} | ||
@@ -515,2 +515,3 @@ }; | ||
}; | ||
var type = schema.type; | ||
@@ -520,3 +521,7 @@ | ||
if (!schema.schema) { | ||
type = 'void'; | ||
if (path[path.length - 2] === 'responses') { | ||
type = 'void'; | ||
} else { | ||
type = 'object'; | ||
} | ||
} else { | ||
@@ -548,8 +553,8 @@ schema = resolveSchema(schema); | ||
if (!_.isUndefined(schema.items)) { | ||
validateTypeAndFormat(val, type === 'array' ? schema.items.type : type, | ||
type === 'array' && schema.items.format ? | ||
schema.items.format : | ||
schema.format); | ||
validateTypeAndFormat(val, type === 'array' ? schema.items.type : type, | ||
type === 'array' && schema.items.format ? | ||
schema.items.format : | ||
schema.format); | ||
} else { | ||
validateTypeAndFormat(val, type, schema.format); | ||
validateTypeAndFormat(val, type, schema.format); | ||
} | ||
@@ -556,0 +561,0 @@ } else { |
@@ -80,2 +80,3 @@ /* | ||
var operation; | ||
var rErr; | ||
@@ -97,3 +98,7 @@ if (req.swagger) { | ||
if (!_.isUndefined(handler)) { | ||
return handler(req, res, next); | ||
try { | ||
return handler(req, res, next); | ||
} catch (err) { | ||
rErr = err; | ||
} | ||
} | ||
@@ -103,4 +108,4 @@ } | ||
return next(); | ||
return next(rErr); | ||
}; | ||
}; |
@@ -28,20 +28,4 @@ /* | ||
var async = require('async'); | ||
var helpers = require('../helpers'); | ||
function handleSecurityError (err, res) { | ||
var body = { | ||
'error_description': err.message, | ||
state: err.state, | ||
error: err.code || 'server_error' | ||
}; | ||
if (err.headers) { | ||
_.each(_.keys(err.headers), function(name) { | ||
res.setHeader(name, err.headers[name]); | ||
}); | ||
} | ||
res.statusCode = err.statusCode || 403; | ||
res.end(JSON.stringify(body)); | ||
} | ||
/** | ||
@@ -100,3 +84,3 @@ * Middleware for using Swagger security information to authenticate requests. | ||
handler(req, secDef, secReq[name], cb); | ||
handler(req, secDef, helpers.getScopeOrAPIKey('1.2', req, secDef, name, secReq), cb); | ||
}, function (err) { | ||
@@ -111,5 +95,5 @@ // swap normal err and result to short-circuit the logical OR | ||
handleSecurityError(errors[0], res); | ||
helpers.sendSecurityError(errors[0], res, next); | ||
}); | ||
}; | ||
}; |
@@ -28,2 +28,3 @@ /* | ||
var _ = require('lodash'); | ||
var fs = require('fs'); | ||
var parseurl = require('parseurl'); | ||
@@ -48,2 +49,3 @@ var path = require('path'); | ||
* @param {string=/docs} [options.swaggerUi] - The relative path to serve Swagger UI from | ||
* @param {string} [options.swaggerUiDir] - The filesystem path to your custom swagger-ui deployment to serve | ||
* | ||
@@ -55,3 +57,5 @@ * @returns the middleware function | ||
var apiDocsPaths = []; | ||
var staticMiddleware = serveStatic(path.join(__dirname, '..', 'swagger-ui'), staticOptions); | ||
var swaggerUiPath = options.swaggerUiDir ? | ||
path.resolve(options.swaggerUiDir) : | ||
path.join(__dirname, '..', 'swagger-ui'); | ||
var apiDocsHandler = function apiDocsHandler (res, path) { | ||
@@ -61,2 +65,3 @@ res.setHeader('Content-Type', 'application/json'); | ||
}; | ||
var staticMiddleware; | ||
@@ -76,2 +81,12 @@ // Validate arguments | ||
if (options.swaggerUiDir) { | ||
if (!fs.existsSync(swaggerUiPath)) { | ||
throw new Error('options.swaggerUiDir path does not exist: ' + swaggerUiPath); | ||
} else if (!fs.statSync(swaggerUiPath).isDirectory()) { | ||
throw new Error('options.swaggerUiDir path is not a directory: ' + swaggerUiPath); | ||
} | ||
} | ||
staticMiddleware = serveStatic(swaggerUiPath, staticOptions); | ||
// Set the defaults | ||
@@ -78,0 +93,0 @@ options = _.defaults(options || {}, defaultOptions); |
@@ -72,3 +72,3 @@ /* | ||
paramPath = req.swagger.operationPath.concat(['params', paramIndex.toString()]); | ||
val = req.swagger.params[paramName].value; | ||
val = req.swagger.params[paramName].originalValue; | ||
@@ -75,0 +75,0 @@ // Validate requiredness |
@@ -84,2 +84,3 @@ /* | ||
var operation; | ||
var rErr; | ||
@@ -101,3 +102,7 @@ if (req.swagger) { | ||
if (!_.isUndefined(handler)) { | ||
return handler(req, res, next); | ||
try { | ||
return handler(req, res, next); | ||
} catch (err) { | ||
rErr = err; | ||
} | ||
} | ||
@@ -107,4 +112,4 @@ } | ||
return next(); | ||
return next(rErr); | ||
}; | ||
}; |
@@ -26,22 +26,5 @@ /* | ||
var _ = require('lodash'); | ||
var async = require('async'); | ||
var helpers = require('../helpers'); | ||
function handleSecurityError (err, res) { | ||
var body = { | ||
'error_description': err.message, | ||
state: err.state, | ||
error: err.code || 'server_error' | ||
}; | ||
if (err.headers) { | ||
_.each(_.keys(err.headers), function(name) { | ||
res.setHeader(name, err.headers[name]); | ||
}); | ||
} | ||
res.statusCode = err.statusCode || 403; | ||
res.end(JSON.stringify(body)); | ||
} | ||
/** | ||
@@ -90,3 +73,3 @@ * Middleware for using Swagger security information to authenticate requests. | ||
handler(req, secDef, secReq[name], cb); | ||
handler(req, secDef, helpers.getScopeOrAPIKey('2.0', req, secDef, name, secReq), cb); | ||
}, function (err) { | ||
@@ -101,5 +84,5 @@ // swap normal err and result to short-circuit the logical OR | ||
handleSecurityError(errors[0], res); | ||
helpers.sendSecurityError(errors[0], res, next); | ||
}); | ||
}; | ||
}; |
@@ -28,2 +28,3 @@ /* | ||
var _ = require('lodash'); | ||
var fs = require('fs'); | ||
var parseurl = require('parseurl'); | ||
@@ -46,2 +47,3 @@ var path = require('path'); | ||
* @param {string=/docs} [options.swaggerUi] - The relative path to serve Swagger UI from | ||
* @param {string} [options.swaggerUiDir] - The filesystem path to your custom swagger-ui deployment to serve | ||
* | ||
@@ -51,4 +53,7 @@ * @returns the middleware function | ||
exports = module.exports = function swaggerUIMiddleware (swaggerObject, options) { | ||
var staticMiddleware = serveStatic(path.join(__dirname, '..', 'swagger-ui'), staticOptions); | ||
var swaggerUiPath = options.swaggerUiDir ? | ||
path.resolve(options.swaggerUiDir) : | ||
path.join(__dirname, '..', 'swagger-ui'); | ||
var apiDocs; | ||
var staticMiddleware; | ||
@@ -62,2 +67,12 @@ // Validate arguments | ||
if (options.swaggerUiDir) { | ||
if (!fs.existsSync(swaggerUiPath)) { | ||
throw new Error('options.swaggerUiDir path does not exist: ' + swaggerUiPath); | ||
} else if (!fs.statSync(swaggerUiPath).isDirectory()) { | ||
throw new Error('options.swaggerUiDir path is not a directory: ' + swaggerUiPath); | ||
} | ||
} | ||
staticMiddleware = serveStatic(swaggerUiPath, staticOptions); | ||
apiDocs = JSON.stringify(swaggerObject, null, 2); | ||
@@ -64,0 +79,0 @@ |
@@ -72,3 +72,3 @@ /* | ||
paramPath = paramMetadata.path; | ||
val = req.swagger.params[paramName].value; | ||
val = req.swagger.params[paramName].originalValue; | ||
@@ -75,0 +75,0 @@ // Validate requiredness |
@@ -39,5 +39,8 @@ /* | ||
var jsonBodyParser = bp.json(); | ||
var parseQueryString = function parseQueryString(req) { | ||
return req.url.indexOf('?') > -1 ? qs.parse(parseurl(req).query, {}) : {}; | ||
}; | ||
var queryParser = function (req, res, next) { | ||
if (!req.query) { | ||
req.query = req.url.indexOf('?') > -1 ? qs.parse(parseurl(req).query, {}) : {}; | ||
req.query = parseQueryString(req); | ||
} | ||
@@ -58,2 +61,61 @@ | ||
var convertValue = function convertValue (value, schema) { | ||
var type = schema.type; | ||
// If there is no value, do not convert it | ||
if (_.isUndefined(value)) { | ||
return value; | ||
} | ||
// TODO: Type resolution should become a helper function | ||
if (!type && schema.schema) { | ||
type = schema.type; | ||
} | ||
if (!type) { | ||
type = 'object'; | ||
} | ||
switch (type) { | ||
case 'array': | ||
value = _.map(value, function (item) { | ||
return convertValue(item, _.isArray(schema.items) ? schema.items[0] : schema.items); | ||
}); | ||
break; | ||
case 'boolean': | ||
if (!_.isBoolean(value)) { | ||
value = value === 'true' || value === true ? true : false; | ||
} | ||
break; | ||
case 'integer': | ||
if (!_.isNumber(value)) { | ||
value = parseInt(value, 10); | ||
} | ||
break; | ||
case 'number': | ||
if (!_.isNumber(value)) { | ||
value = parseFloat(value); | ||
} | ||
break; | ||
case 'string': | ||
if (['date', 'date-time'].indexOf(schema.format) > -1 && !_.isDate(value)) { | ||
value = new Date(value); | ||
} | ||
break; | ||
} | ||
return value; | ||
}; | ||
var isModelType = function isModelType (spec, type) { | ||
@@ -72,4 +134,4 @@ return spec.primitives.indexOf(type) === -1; | ||
} else if (param.type === 'array' && isModelType(spec, param.items ? | ||
param.items.type || param.items.$ref : | ||
undefined)) { | ||
param.items.type || param.items.$ref : | ||
undefined)) { | ||
isModel = true; | ||
@@ -146,3 +208,3 @@ } | ||
var getMockValue = function getMockValue (version, schema) { | ||
var type = schema.type; | ||
var type = _.isPlainObject(schema) ? schema.type : schema; | ||
var value; | ||
@@ -207,3 +269,3 @@ | ||
_.each(parentSchema.properties, function (property, propName) { | ||
value[propName] = getMockValue(version, property); | ||
value[propName] = getMockValue(version, property); | ||
}); | ||
@@ -257,2 +319,26 @@ }); | ||
module.exports.getScopeOrAPIKey = function getScopeOrAPIKey (swaggerVersion, req, secDef, secName, secReq) { | ||
var apiKeyPropName = swaggerVersion === '1.2' ? secDef.keyname : secDef.name; | ||
var apiKeyLocation = swaggerVersion === '1.2' ? secDef.passAs : secDef.in; | ||
var scopeOrKey; | ||
if (secDef.type === 'oauth2') { | ||
if (swaggerVersion === '1.2') { | ||
scopeOrKey = _.map(secReq[secName], function (scope) { | ||
return scope.scope; | ||
}); | ||
} else { | ||
scopeOrKey = secReq[secName]; | ||
} | ||
} else if (secDef.type === 'apiKey') { | ||
if (apiKeyLocation === 'query') { | ||
scopeOrKey = (req.query ? req.query : parseQueryString(req))[apiKeyPropName]; | ||
} else if (apiKeyLocation === 'header') { | ||
scopeOrKey = req.headers[apiKeyPropName.toLowerCase()]; | ||
} | ||
} | ||
return scopeOrKey; | ||
}; | ||
var mockResponse = function mockResponse (version, req, res, next, handlerName) { | ||
@@ -284,3 +370,9 @@ var method = req.method.toLowerCase(); | ||
if (method === 'post' && operation.responses['201']) { | ||
responseType = operation.responses['201'].schema; | ||
responseType = operation.responses['201']; | ||
res.statusCode = 201; | ||
} else if (method === 'delete' && operation.responses['204']) { | ||
responseType = operation.responses['204']; | ||
res.statusCode = 204; | ||
} else if (operation.responses['200']) { | ||
@@ -290,6 +382,4 @@ responseType = operation.responses['200']; | ||
responseType = operation.responses['default']; | ||
} else if (operation.schema) { | ||
responseType = operation.schema.type || 'object'; | ||
} else { | ||
responseType = operation.type; | ||
responseType = 'void'; | ||
} | ||
@@ -303,13 +393,15 @@ | ||
spec.composeModel(apiDOrSO, responseType, function (err, result) { | ||
if (err) { | ||
return sendResponse(undefined, err); | ||
} else { | ||
// Should we handle this differently as undefined typically means the model doesn't exist | ||
return sendResponse(undefined, _.isUndefined(result) ? | ||
stubResponse : | ||
JSON.stringify(getMockValue(version, result))); | ||
} | ||
if (err) { | ||
return sendResponse(undefined, err); | ||
} else { | ||
// Should we handle this differently as undefined typically means the model doesn't exist | ||
return sendResponse(undefined, _.isUndefined(result) ? | ||
stubResponse : | ||
JSON.stringify(getMockValue(version, result))); | ||
} | ||
}); | ||
} else { | ||
return sendResponse(undefined, JSON.stringify(getMockValue(version, responseType.schema))); | ||
return sendResponse(undefined, JSON.stringify(getMockValue(version, responseType.schema ? | ||
responseType.schema : | ||
responseType))); | ||
} | ||
@@ -338,15 +430,15 @@ } else { | ||
if (file.match(jsFileRegex)) { | ||
controller = require(path.resolve(path.join(dir, controllerName))); | ||
controller = require(path.resolve(path.join(dir, controllerName))); | ||
if (_.isPlainObject(controller)) { | ||
_.each(controller, function (value, name) { | ||
var handlerId = controllerName + '_' + name; | ||
if (_.isPlainObject(controller)) { | ||
_.each(controller, function (value, name) { | ||
var handlerId = controllerName + '_' + name; | ||
// TODO: Log this situation | ||
// TODO: Log this situation | ||
if (_.isFunction(value) && !handlerCache[handlerId]) { | ||
handlerCache[handlerId] = value; | ||
} | ||
}); | ||
} | ||
if (_.isFunction(value) && !handlerCache[handlerId]) { | ||
handlerCache[handlerId] = value; | ||
} | ||
}); | ||
} | ||
} | ||
@@ -370,3 +462,3 @@ }); | ||
var getParameterValue = module.exports.getParameterValue = function getParameterValue (version, parameter, pathKeys, | ||
match, req) { | ||
match, req) { | ||
var defaultVal = version === '1.2' ? parameter.defaultValue : parameter.default; | ||
@@ -395,3 +487,3 @@ var paramType = version === '1.2' ? parameter.paramType : parameter.in; | ||
if (key.name === parameter.name) { | ||
val = match[index + 1]; | ||
val = match[index + 1]; | ||
} | ||
@@ -416,7 +508,7 @@ }); | ||
module.exports.processOperationParameters = function processOperationParameters (version, pathKeys, pathMatch, req, res, | ||
next) { | ||
next) { | ||
var swaggerMetadata = req.swagger; | ||
var parameters = !_.isUndefined(swaggerMetadata) ? | ||
(version === '1.2' ? swaggerMetadata.operation.parameters : swaggerMetadata.operationParameters) : | ||
undefined; | ||
(version === '1.2' ? swaggerMetadata.operation.parameters : swaggerMetadata.operationParameters) : | ||
undefined; | ||
@@ -459,9 +551,11 @@ if (!parameters) { | ||
var parameter = version === '1.2' ? parameterOrMetadata : parameterOrMetadata.schema; | ||
var oVal = getParameterValue(version, parameter, pathKeys, pathMatch, req); | ||
swaggerMetadata.params[parameter.name] = { | ||
path: version === '1.2' ? | ||
swaggerMetadata.operationPath.concat(['parameters', index.toString()]) : | ||
parameterOrMetadata.path, | ||
schema: parameter, | ||
value: getParameterValue(version, parameter, pathKeys, pathMatch, req) | ||
path: version === '1.2' ? | ||
swaggerMetadata.operationPath.concat(['parameters', index.toString()]) : | ||
parameterOrMetadata.path, | ||
schema: parameter, | ||
originalValue: oVal, | ||
value: convertValue(oVal, parameter) | ||
}; | ||
@@ -492,5 +586,5 @@ }); | ||
if (err.code === 'INVALID_TYPE' && err.message.split(' ')[0] === 'Value') { | ||
validationMessage += err.message.split(' ').slice(1).join(' '); | ||
validationMessage += err.message.split(' ').slice(1).join(' '); | ||
} else { | ||
validationMessage += 'is ' + err.message.charAt(0).toLowerCase() + err.message.substring(1); | ||
validationMessage += 'is ' + err.message.charAt(0).toLowerCase() + err.message.substring(1); | ||
} | ||
@@ -527,5 +621,5 @@ | ||
var err = new Error('Route defined in Swagger specification (' + | ||
(_.isUndefined(req.swagger.api) ? req.swagger.apiPath : req.swagger.api.path) + | ||
') but there is no defined ' + | ||
(version === '1.2' ? req.method.toUpperCase() : req.method.toLowerCase()) + ' operation.'); | ||
(_.isUndefined(req.swagger.api) ? req.swagger.apiPath : req.swagger.api.path) + | ||
') but there is no defined ' + | ||
(version === '1.2' ? req.method.toUpperCase() : req.method.toLowerCase()) + ' operation.'); | ||
@@ -539,3 +633,3 @@ if (!_.isUndefined(req.swagger.api)) { | ||
if (helpers.swaggerOperationMethods.indexOf(method.toUpperCase()) !== -1) { | ||
allowedMethods.push(method.toUpperCase()); | ||
allowedMethods.push(method.toUpperCase()); | ||
} | ||
@@ -553,2 +647,23 @@ }); | ||
module.exports.sendSecurityError = function sendSecurityError (err, res, next) { | ||
// Populate default values if not present | ||
if (!err.code) { | ||
err.code = 'server_error'; | ||
} | ||
if (!err.statusCode) { | ||
err.statusCode = 403; | ||
} | ||
if (err.headers) { | ||
_.each(err.headers, function (header, name) { | ||
res.setHeader(name, header); | ||
}); | ||
} | ||
res.statusCode = err.statusCode; | ||
next(err); | ||
}; | ||
var validateValue = module.exports.validateValue = | ||
@@ -569,44 +684,43 @@ function validateValue (req, schema, path, val, callback) { | ||
if (_.isString(val)) { | ||
try { | ||
val = JSON.parse(val); | ||
} catch (err) { | ||
err.failedValidation = true; | ||
err.message = 'Value expected to be an array/object but is not'; | ||
try { | ||
val = JSON.parse(val); | ||
} catch (err) { | ||
err.failedValidation = true; | ||
err.message = 'Value expected to be an array/object but is not'; | ||
throw err; | ||
} | ||
throw err; | ||
} | ||
} | ||
async.map(schema.type === 'array' ? val : [val], function (aVal, oCallback) { | ||
if (version === '1.2') { | ||
spec.validateModel(document, '#/models/' + (schema.items ? | ||
schema.items.type || schema.items.$ref : | ||
schema.type), aVal, oCallback); | ||
} else { | ||
try { | ||
validators.validateAgainstSchema(schema.schema ? schema.schema : schema, val); | ||
if (version === '1.2') { | ||
spec.validateModel(document, '#/models/' + (schema.items ? | ||
schema.items.type || schema.items.$ref : | ||
schema.type), aVal, oCallback); | ||
} else { | ||
try { | ||
validators.validateAgainstSchema(schema.schema ? schema.schema : schema, val); | ||
oCallback(); | ||
} catch (err) { | ||
oCallback(err); | ||
} | ||
} | ||
oCallback(); | ||
} catch (err) { | ||
oCallback(err); | ||
} | ||
} | ||
}, function (err, allResults) { | ||
if (!err) { | ||
_.each(allResults, function (results) { | ||
if (results && helpers.getErrorCount(results) > 0) { | ||
err = new Error('Failed schema validation'); | ||
if (!err) { | ||
_.each(allResults, function (results) { | ||
if (results && helpers.getErrorCount(results) > 0) { | ||
err = new Error('Failed schema validation'); | ||
err.code = 'SCHEMA_VALIDATION_FAILED'; | ||
err.errors = results.errors; | ||
err.warnings = results.warnings; | ||
err.failedValidation = true; | ||
err.code = 'SCHEMA_VALIDATION_FAILED'; | ||
err.errors = results.errors; | ||
err.warnings = results.warnings; | ||
err.failedValidation = true; | ||
return false; | ||
} | ||
}); | ||
} | ||
return false; | ||
} | ||
}); | ||
} | ||
callback(err); | ||
callback(err); | ||
}); | ||
@@ -638,61 +752,61 @@ } else { | ||
try { | ||
validators.validateContentType(req.swagger.apiDeclaration ? | ||
req.swagger.apiDeclaration.produces : | ||
req.swagger.swaggerObject.produces, | ||
operation.produces, res); | ||
validators.validateContentType(req.swagger.apiDeclaration ? | ||
req.swagger.apiDeclaration.produces : | ||
req.swagger.swaggerObject.produces, | ||
operation.produces, res); | ||
} catch (err) { | ||
err.failedValidation = true; | ||
err.failedValidation = true; | ||
throw err; | ||
throw err; | ||
} | ||
if (_.isUndefined(schema.type)) { | ||
if (schema.schema) { | ||
schema = schema.schema; | ||
} else if (version === '1.2') { | ||
schema = _.find(operation.responseMessages, function (responseMessage, index) { | ||
if (responseMessage.code === res.statusCode) { | ||
vPath.push(['responseMessages', index.toString()]); | ||
if (schema.schema) { | ||
schema = schema.schema; | ||
} else if (version === '1.2') { | ||
schema = _.find(operation.responseMessages, function (responseMessage, index) { | ||
if (responseMessage.code === res.statusCode) { | ||
vPath.push('responseMessages', index.toString()); | ||
return true; | ||
} | ||
}); | ||
return true; | ||
} | ||
}); | ||
if (!_.isUndefined(schema)) { | ||
schema = schema.responseModel; | ||
} | ||
} else { | ||
schema = _.find(operation.responses, function (response, code) { | ||
if (code === res.statusCode.toString()) { | ||
vPath.push(['responses', code]); | ||
if (!_.isUndefined(schema)) { | ||
schema = schema.responseModel; | ||
} | ||
} else { | ||
schema = _.find(operation.responses, function (response, code) { | ||
if (code === res.statusCode.toString()) { | ||
vPath.push('responses', code); | ||
return true; | ||
} | ||
}); | ||
return true; | ||
} | ||
}); | ||
if (_.isUndefined(schema) && operation.responses.default) { | ||
schema = operation.responses.default; | ||
if (_.isUndefined(schema) && operation.responses.default) { | ||
schema = operation.responses.default; | ||
vPath.push(['responses', 'default']); | ||
} | ||
} | ||
vPath.push('responses', 'default'); | ||
} | ||
} | ||
} | ||
validateValue(req, schema, vPath, val, | ||
function (err) { | ||
if (err) { | ||
throw err; | ||
} | ||
function (err) { | ||
if (err) { | ||
throw err; | ||
} | ||
// 'res.end' requires a Buffer or String so if it's not one, create a String | ||
if (!(data instanceof Buffer) && !_.isString(data)) { | ||
data = JSON.stringify(data); | ||
} | ||
// 'res.end' requires a Buffer or String so if it's not one, create a String | ||
if (!(data instanceof Buffer) && !_.isString(data)) { | ||
data = JSON.stringify(data); | ||
} | ||
res.end(data, encoding); | ||
}); | ||
res.end(data, encoding); | ||
}); | ||
} catch (err) { | ||
if (err.failedValidation) { | ||
err.originalResponse = data; | ||
err.message = 'Response validation failed: ' + err.message.charAt(0).toLowerCase() + err.message.substring(1); | ||
err.originalResponse = data; | ||
err.message = 'Response validation failed: ' + err.message.charAt(0).toLowerCase() + err.message.substring(1); | ||
} | ||
@@ -699,0 +813,0 @@ |
{ | ||
"name": "swagger-tools", | ||
"version": "0.7.4", | ||
"version": "0.8.0", | ||
"description": "Various tools for using and integrating with Swagger.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
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
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
855330
17399
20