UNPKG

@dvsa/appdev-api-common

Version:

Utils library for common API functionality

50 lines (49 loc) 2.63 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidateRequestBody = ValidateRequestBody; const ajv_1 = __importDefault(require("ajv")); const ajv_formats_1 = __importDefault(require("ajv-formats")); const http_status_codes_1 = require("../api/http-status-codes"); const validation_error_1 = require("./validation-error"); const ajv = new ajv_1.default({ removeAdditional: true, allErrors: true }); (0, ajv_formats_1.default)(ajv); ajv.addKeyword("tsEnumNames"); /** * Decorator tp validate an express request body against a specified schema * @param {object} schema - the json schema you wish to use as the validator * @param {ValidateRequestBodyOptions} opts * - isArray: whether the body is expected to be an array * - errorDetails: whether to return detailed error messages (Note: errors are logged regardless of this setting) */ function ValidateRequestBody(schema, opts = { isArray: false, errorDetails: true }) { return (_target, _propertyKey, descriptor) => { const originalMethod = descriptor.value; // biome-ignore lint/suspicious/noExplicitAny: tuples should be any in this instance descriptor.value = async function (...args) { const [body] = args; // just to be safe, check the bodies existence before attempting to validate it if (!body) { throw new validation_error_1.ValidationError(http_status_codes_1.HttpStatus.BAD_REQUEST, "No request body detected"); } const payload = Buffer.isBuffer(body) ? JSON.parse(body.toString("utf-8")) : body; // Create the appropriate schema based on whether we're validating an array or a single object const schemaToValidate = opts?.isArray ? { type: "array", items: schema } : schema; const validateFunction = ajv.compile(schemaToValidate); // validate the request body against the schema passed in const isValid = validateFunction(payload); // if an error exists, then return a 400 with details if (!isValid) { throw new validation_error_1.ValidationError(http_status_codes_1.HttpStatus.BAD_REQUEST, "Validation failed", opts?.errorDetails ? validateFunction.errors : null); } // proceed with attached method if schema is valid return originalMethod.apply(this, args); }; }; }