@dvsa/appdev-api-common
Version:
Utils library for common API functionality
50 lines (49 loc) • 2.63 kB
JavaScript
;
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);
};
};
}