indicative-compiler
Version:
Indicative compiler to compile parsed schema into highly optimized functions
92 lines (91 loc) • 3.3 kB
JavaScript
/**
* @module compiler/sanitizer
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* indicative-compiler
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
const isobject_1 = __importDefault(require("isobject"));
const lodash_get_1 = __importDefault(require("lodash.get"));
/**
* Runs an array of sanitizations on a given field.
*/
class SanitizationsRunner {
constructor(field, dotPath, rules, sanitizations) {
this.field = field;
this.dotPath = dotPath;
this.sanitizations = [];
this.computeSanitizations(sanitizations, rules);
}
/**
* Pull sanitizations for the list defined rules.
*/
computeSanitizations(sanitizations, rules) {
this.sanitizations = rules.map((rule) => {
const sanitization = sanitizations[rule.name];
/**
* Raise exception when sanitization implementation for a
* given rule is missing.
*/
if (!sanitization) {
throw new Error(`${rule.name} is not a registered as a sanitization`);
}
/**
* The sanitization node must have a `validate` function.
*/
if (typeof (sanitization.sanitize) !== 'function') {
throw new Error(`${rule.name} is missing sanitize function`);
}
/**
* Mutate args when `compile` function is defined. It is a way to
* normalize arguments before the sanitization process kicks in.
*/
if (typeof (sanitization.compile) === 'function') {
rule.args = sanitization.compile(rule.args);
}
return { rule: rule, fn: sanitization.sanitize };
});
}
/**
* Returns a fresh data copy by copying some of the values from the actual
* data and then mutating the `tip` and `pointer`. The tip and pointer
* are mutated so that the sanitization function receives the closest
* object from the pointer, resulting in performant code.
*/
getDataCopy(data) {
const tip = this.dotPath.length ? lodash_get_1.default(data.tip, this.dotPath) : data.tip;
/**
* Updating the tip and pointer
*/
return Object.assign({}, data, {
tip: this.field === '::tip::' ? { [this.field]: tip } : tip,
});
}
/**
* Execute all sanitization in series for a given filed
*/
exec(data, config) {
const dataCopy = this.getDataCopy(data);
/**
* Skip validations when the parent value of this field is not
* an object. The user must validate the parent to be object
* seperately.
*/
if (!isobject_1.default(dataCopy.tip)) {
return;
}
this.sanitizations.forEach((sanitization) => {
sanitization.fn(dataCopy, this.field, sanitization.rule.args, config);
});
}
}
exports.SanitizationsRunner = SanitizationsRunner;
;