UNPKG

rule-filter-validator

Version:

A object and scope validator based on structured rules

137 lines 5.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validatePayload = validatePayload; exports.isValidPayload = isValidPayload; const lodash_es_1 = require("lodash-es"); const calculate_payload_functions_js_1 = require("./calculate-payload-functions.js"); const is_valid_js_1 = require("./is-valid.js"); const parse_filter_js_1 = require("./parse-filter.js"); const FieldFilterText = { _eq: 'equal to', _neq: 'not equal to', _contains: 'contains', _ncontains: 'does not contain', _starts_with: 'starts with', _nstarts_with: 'does not start with', _ends_with: 'ends with', _nends_with: 'does not end with', _in: 'in', _nin: 'not in', _between: 'between', _nbetween: 'not between', _gt: 'greater than', _gte: 'greater than or equal to', _lt: 'less than', _lte: 'less than or equal to', _null: 'null =', _nnull: 'not null =', _empty: 'empty =', _nempty: 'not empty =', _submitted: 'submitted =', _regex: 'matching regex', }; /** * Validate the payload against the given filter rules * * @param {Filter} filter - The filter rules to check against * @param {Record<string, any>} payload - The payload to validate * @param {boolean} strict(false) - Type and Case-sensitive validation * @returns Array<string> errors if any */ function validatePayload(filter, payload, strict = false) { const errors = []; filter = (0, parse_filter_js_1.parseFilter)(filter); payload = (0, calculate_payload_functions_js_1.calculatePayloadFunctions)(payload, filter); validate(filter, payload, errors, '', strict); errors.reverse(); return errors; } /** * A shorthand function to check if the payload is valid */ function isValidPayload(filter, payload, strict = false) { return validatePayload(filter, payload, strict).length === 0; } /** * Validate the payload against the given filter rules * * @param {Filter} filter - The filter rules to check against * @param {Record<string, any>} payload - The payload to validate * @param errors * @param {string} path - Optional options to pass to Joi * @param {boolean} strict(false) - Type and Case-sensitive validation * @returns { errors: Array<string> } */ function validate(filter, payload, errors = [], path = '', strict = false) { if (typeof filter !== 'object' && !filter) { throw new Error('Filter rule is not valid'); } return Object.keys(filter).every(key => { const compareValue = (0, lodash_es_1.get)(filter, key); if (String(key).startsWith('_')) { switch (key) { case '_and': return compareValue.every(subFilter => validate(subFilter, payload, errors, path, strict)); case '_or': { const swallowErrors = []; const result = compareValue.some(subFilter => validate(subFilter, payload, swallowErrors, path, strict)); if (!result) { // If errors then will be false if all checks fail thus && errors.push(swallowErrors.join(' and ')); } return result; } case '_$': { const testValue = (0, lodash_es_1.get)(payload, path, undefined); if (!Array.isArray(testValue)) { return errors.push('Failed: ' + path + ' is not an array'); } const swallowErrors = []; const result = testValue.some(subItem => validate(compareValue, subItem, swallowErrors, '', strict)); if (!result) { // If errors then will be false if all checks fail thus && errors.push(swallowErrors.join(' and ')); } return result; } case '_some': { const testValue = (0, lodash_es_1.get)(payload, path, undefined); if (!Array.isArray(testValue)) { return errors.push('Failed: ' + path + ' is not an array'); } const swallowErrors = []; const result = testValue.some(subItem => validate(compareValue, subItem, swallowErrors, '', strict)); if (!result) { errors.push(swallowErrors.join(' and ')); } return result; } case '_none': { const testValue = (0, lodash_es_1.get)(payload, path, undefined); if (!Array.isArray(testValue)) { return errors.push('Failed: ' + path + ' is not an array'); } const swallowErrors = []; const hasMatch = testValue.some(subItem => validate(compareValue, subItem, swallowErrors, '', strict)); if (hasMatch) { errors.push('Failed: ' + path + ' has at least one matching related item'); } return !hasMatch; } } const testValue = (0, lodash_es_1.get)(payload, path, undefined); const result = (0, is_valid_js_1.isValid)(compareValue, key, testValue, strict); if (result !== null) { if (!result) { errors.push(`Failed: ${path .split('.') .reverse() .join(' of ')} is ${JSON.stringify(testValue)} and is not ${FieldFilterText[key]} ${JSON.stringify(compareValue)}`); } return result; } } return validate(compareValue, payload, errors, [path, key].filter(s => s).join('.'), strict); }); } //# sourceMappingURL=validate-payload.js.map