UNPKG

swagger-generator-koa

Version:
112 lines (111 loc) 4.56 kB
'use strict'; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = __importDefault(require("lodash")); const joi_1 = __importDefault(require("@hapi/joi")); const validation_error_1 = __importDefault(require("./validation-error")); const defaultOptions = { contextRequest: false, allowUnknownHeaders: true, allowUnknownBody: true, allowUnknownQuery: true, allowUnknownParams: true, allowUnknownCookies: true, status: 400, statusText: 'Bad Request' }; let globalOptions = {}; // maps the corresponding request object to an `express-validation` option const unknownMap = { headers: 'allowUnknownHeaders', body: 'allowUnknownBody', query: 'allowUnknownQuery', params: 'allowUnknownParams', cookies: 'allowUnknownCookies' }; class Validation { validate(schema = {}, opt = {}) { return (ctx, next) => __awaiter(this, void 0, void 0, function* () { const errors = []; const options = lodash_1.default.defaults({}, schema.options || {}, globalOptions, defaultOptions); const requestInputType = ['headers', 'body', 'query', 'params', 'cookies']; // tslint:disable-next-line:prefer-for-of for (let index = 0; index < requestInputType.length; index++) { const key = requestInputType[index]; const allowUnknown = options[unknownMap[key]]; const entireContext = options.contextRequest ? ctx.request : null; if (schema[key]) { const toValidateObj = key === 'body' ? ctx.request.body : ctx[key]; yield validate(errors, toValidateObj, schema[key], key, allowUnknown, entireContext); } } if (errors.length !== 0) { throw new validation_error_1.default(errors, options); } yield next(); }); } } /** * validate checks the current `Request` for validations * NOTE: mutates `request` in case the object is valid. */ function validate(errObj, request, schema, location, allowUnknown, context) { return __awaiter(this, void 0, void 0, function* () { if (!request || !schema) { return; } const joiOptions = { context: context || request, allowUnknown, abortEarly: false }; const { error, value } = yield joi_1.default.object(schema).validate(request, joiOptions); const errors = error; if (!errors || errors.details.length === 0) { lodash_1.default.assignIn(request, value); // joi responses are parsed into JSON return; } // tslint:disable-next-line:no-shadowed-variable errors.details.forEach((error) => { const errorExists = lodash_1.default.find(errObj, (item) => { if (item && item.field === error.path && item.location === location) { item.messages.push(error.message); item.types.push(error.type); return item; } return; }); if (!errorExists) { errObj.push({ field: error.path, location, messages: [error.message], types: [error.type] }); } }); return errObj; }); } exports.options = (opts) => { if (!opts) { globalOptions = {}; return; } globalOptions = lodash_1.default.defaults({}, globalOptions, opts); }; const defaultValidation = new Validation(); module.exports = defaultValidation.validate.bind(defaultValidation); module.exports.ValidationError = validation_error_1.default; exports.default = Validation;