text: "use strict";
  var __importDefault = (this && this.__importDefault) || function (mod) {
      return (mod && mod.__esModule) ? mod : { "default": mod };
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const lodash_get_1 = __importDefault(require("lodash.get"));
  const isobject_1 = __importDefault(require("isobject"));
  class ValidationsRunner {
      constructor(_field, _type, _dotPath, rules, validations, _fieldMessages, _genericMessages) {
          this._field = _field;
          this._type = _type;
          this._dotPath = _dotPath;
          this._fieldMessages = _fieldMessages;
          this._genericMessages = _genericMessages;
          this.async = false;
          this._validations = [];
          this._pointer = this._dotPath.concat(this._field).join('.');
          this._computeValidations(validations, rules);
      }
      _computeValidations(validations, rules) {
          this._validations = rules.map((rule) => {
              const validation = validations[rule.name];
              if (!validation) {
                  throw new Error(`${rule.name} is not a registered as a validation`);
              }
              if (typeof (validation.validate) !== 'function') {
                  throw new Error(`${rule.name} is missing validate function`);
              }
              if (typeof (validation.compile) === 'function') {
                  rule.args = validation.compile(rule.args);
              }
              if (validation.async) {
                  this.async = true;
              }
              return { rule: rule, fn: validation.validate, async: validation.async };
          });
      }
      _getDataCopy(data) {
          const tip = this._dotPath.length ? lodash_get_1.default(data.tip, this._dotPath) : data.tip;
          const pointer = data.arrayPointer ?
              (this._pointer === '::tip::'
                  ? `${data.arrayPointer}.${data.currentIndex}`
                  : `${data.arrayPointer}.${data.currentIndex}.${this._pointer}`)
              : this._pointer;
          return Object.assign({}, data, {
              tip: this._field === '::tip::' ? { [this._field]: tip } : tip,
              pointer: pointer,
          });
      }
      _reportValueToCollector(passed, data, collector) {
          if (!passed || this._type !== 'literal') {
              return;
          }
          collector.setValue(data.pointer, data.tip[this._field]);
      }
      _reportErrorToCollector(pointer, rule, collector, exception) {
          const message = exception || this._fieldMessages[rule.name] || this._genericMessages[rule.name];
          collector.setError(pointer, rule, message);
      }
      exec(data, collector, config, bail = false) {
          const dataCopy = this._getDataCopy(data);
          if (!isobject_1.default(dataCopy.tip)) {
              return true;
          }
          let hasFailures = false;
          for (let validation of this._validations) {
              let exception = null;
              let passed = true;
              try {
                  passed = validation.fn(dataCopy, this._field, validation.rule.args, config);
              }
              catch (error) {
                  exception = error;
                  passed = false;
              }
              if (!passed) {
                  hasFailures = true;
                  this._reportErrorToCollector(dataCopy.pointer, validation.rule, collector, exception);
                  if (bail) {
                      break;
                  }
              }
          }
          this._reportValueToCollector(!hasFailures, dataCopy, collector);
          return !hasFailures;
      }
      async execAsync(data, collector, config, bail = false) {
          const dataCopy = this._getDataCopy(data);
          if (!isobject_1.default(dataCopy.tip)) {
              return true;
          }
          let hasFailures = false;
          for (let validation of this._validations) {
              let exception = null;
              let passed = true;
              try {
                  if (validation.async) {
                      passed = await validation.fn(dataCopy, this._field, validation.rule.args, config);
                  }
                  else {
                      passed = validation.fn(dataCopy, this._field, validation.rule.args, config);
                  }
              }
              catch (error) {
                  passed = false;
                  exception = error;
              }
              if (!passed) {
                  hasFailures = true;
                  this._reportErrorToCollector(dataCopy.pointer, validation.rule, collector, exception);
                  if (bail) {
                      break;
                  }
              }
          }
          this._reportValueToCollector(!hasFailures, dataCopy, collector);
          return !hasFailures;
      }
  }
  exports.ValidationsRunner = ValidationsRunner;
  