indicative-compiler
Version:
Indicative compiler to compile parsed schema into highly optimized functions
181 lines (180 loc) • 5.94 kB
JavaScript
"use strict";
/**
* @module compiler/validator
*/
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 lodash_get_1 = __importDefault(require("lodash.get"));
/**
* Wraps the [[ValidationsRunner]] and executes them based upon the length of
* an array at runtime.
*/
class ArrayWrapper {
constructor(field, index, childrenValidators, dotPath) {
this.field = field;
this.index = index;
this.childrenValidators = childrenValidators;
this.dotPath = dotPath;
/**
* The pointer to read the value of the field inside the data tip
*/
this.pointer = this.dotPath.concat(this.field).join('.');
/**
* A boolean to know if any of the children inside the wrapper
* has async validators.
*/
this.async = !!this.childrenValidators.find((validator) => validator.async);
}
/**
* Returns data copy to the passed to all the children of the
* array.
*/
getDataCopy(data) {
const value = lodash_get_1.default(data.tip, this.pointer);
/**
* Ensure value is array, otherwise mark the validation as passed.
* The top level value must be validated for an array for same.
*/
if (!Array.isArray(value)) {
return null;
}
/**
* Since we are adding new properties to the data object. We have
* to create a new copy, otherwise the array specific values
* will leak this info to other validations as well.
*/
return {
original: data.original,
pointer: '',
tip: null,
parentArray: value,
currentIndex: this.index === '*' ? 0 : Number(this.index),
arrayPointer: data.arrayPointer
? `${data.arrayPointer}.${data.currentIndex}.${this.pointer}`
: this.pointer,
};
}
/**
* Executes all validations for a given index value inside the array.
*/
executeValidations(data, collector, config, bail) {
let hasFailures = false;
for (let validator of this.childrenValidators) {
const passed = validator.exec(data, collector, config, bail);
if (!passed) {
hasFailures = true;
if (bail) {
break;
}
}
}
return !hasFailures;
}
/**
* Same as [[ArrayWrapper.executeValidations]] but async.
*/
async executeAsyncValidations(data, collector, config, bail) {
let hasFailures = false;
for (let validator of this.childrenValidators) {
let passed = true;
if (validator.async) {
passed = await validator.execAsync(data, collector, config, bail);
}
else {
passed = validator.exec(data, collector, config, bail);
}
if (!passed) {
hasFailures = true;
if (bail) {
break;
}
}
}
return !hasFailures;
}
/**
* Execute series of validations for values inside an array
*/
exec(data, collector, config, bail = false) {
const dataCopy = this.getDataCopy(data);
if (!dataCopy) {
return true;
}
/**
* If index is a not a wildcard, then we run validations
* just for the given index.
*/
if (this.index !== '*') {
dataCopy.tip = dataCopy.parentArray[dataCopy.currentIndex];
return this.executeValidations(dataCopy, collector, config, bail);
}
let index = 0;
let hasFailures = false;
/**
* Loop over all the entire array and execute validations
* for each field.
*/
for (let item of dataCopy.parentArray) {
dataCopy.tip = item;
dataCopy.currentIndex = index;
let passed = true;
passed = this.executeValidations(dataCopy, collector, config, bail);
if (!passed) {
hasFailures = true;
if (bail) {
break;
}
}
index++;
}
return !hasFailures;
}
/**
* Execute series of async validations for values inside an array. Same
* as [[ArrayWrapper.exec]] but async.
*/
async execAsync(data, collector, config, bail = false) {
const dataCopy = this.getDataCopy(data);
if (!dataCopy) {
return true;
}
/**
* If index is a not a wildcard, then we run validations
* just for the given index.
*/
if (this.index !== '*') {
dataCopy.tip = dataCopy.parentArray[dataCopy.currentIndex];
return this.executeAsyncValidations(dataCopy, collector, config, bail);
}
let index = 0;
let hasFailures = false;
/**
* Loop over all the entire array and execute validations
* for each field.
*/
for (let item of dataCopy.parentArray) {
dataCopy.tip = item;
dataCopy.currentIndex = index;
const passed = await this.executeAsyncValidations(dataCopy, collector, config, bail);
if (!passed) {
hasFailures = true;
if (bail) {
break;
}
}
index++;
}
return !hasFailures;
}
}
exports.ArrayWrapper = ArrayWrapper;