'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var _regeneratorRuntime = _interopDefault(require('@babel/runtime/regenerator'));
var _asyncToGenerator = _interopDefault(require('@babel/runtime/helpers/asyncToGenerator'));
var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck'));
var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass'));
var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn'));
var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf'));
var _assertThisInitialized = _interopDefault(require('@babel/runtime/helpers/assertThisInitialized'));
var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits'));
var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty'));
var Common = _interopDefault(require('./Common'));
var CustomDate = _interopDefault(require('./CustomDate'));
var utils = require('@forensic-js/utils');
var Constants = require('./Constants');
var Util = require('./Util');
var FileType = _interopDefault(require('file-type'));
var fs = require('fs');
var crypto = require('crypto');
var path = require('path');
var DirectoryNotFoundException = _interopDefault(require('./Exceptions/DirectoryNotFoundException'));
var FileMoveException = _interopDefault(require('./Exceptions/FileMoveException'));
var libphonenumberJs = require('libphonenumber-js');

var Validator =
/*#__PURE__*/
function (_Common) {
  _inherits(Validator, _Common);

  function Validator() {
    var _getPrototypeOf2;

    var _this;

    _classCallCheck(this, Validator);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Validator)).call.apply(_getPrototypeOf2, [this].concat(args)));

    _defineProperty(_assertThisInitialized(_this), "files", {});

    _defineProperty(_assertThisInitialized(_this), "fileName", '');

    _defineProperty(_assertThisInitialized(_this), "phoneNumberErrors", {
      INVALID_COUNTRY: 'invalid phone number country code',
      NOT_A_NUMBER: '{this} is not a phone number',
      TOO_LONG: 'phone number is too long',
      TOO_SHORT: 'phone number too short'
    });

    return _this;
  }

  _createClass(Validator, [{
    key: "getFileType",

    /**
     * gets the file type of the given file
     * @param filePath
     */
    value: function getFileType(filePath) {
      return new Promise(function (resolve) {
        fs.open(filePath, 'r', function (err, fd) {
          var buffer = Buffer.alloc(FileType.minimumBytes);
          fs.read(fd, buffer, 0, FileType.minimumBytes, null, function (err, bytesRead, buffer) {
            fs.close(fd, function (err) {
              resolve(FileType(buffer));
            });
          });
        });
      });
    }
    /**
     * validate match against rule
     */

  }, {
    key: "matchAgainst",
    value: function matchAgainst(value, options, prefix) {
      var shouldMatch = options.shouldMatch;

      if (utils.isObject(shouldMatch) && shouldMatch.target.toString() !== value) {
        this.setError(utils.pickValue('err', shouldMatch, prefix + ' did not match'), value);
      }
    }
    /**
     * runs post validation
     */

  }, {
    key: "postValidate",
    value: function postValidate(value, options) {
      var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '{_this}';

      if (this.succeeds()) {
        this.matchAgainst(value, options, prefix);
      }

      return this.succeeds();
    }
    /**
     * resolves regex, returning a regex object
     * @param regex
     */

  }, {
    key: "resolveRegex",
    value: function resolveRegex(regex) {
      if (utils.isRegex(regex)) {
        return {
          pattern: regex
        };
      } else {
        return regex;
      }
    }
    /**
     * validates regex check none rules
     */

  }, {
    key: "regexCheckNone",
    value: function regexCheckNone(value, options) {
      if (this.succeeds() && options.regexNone) {
        var regexes = utils.makeArray(options.regexNone);
        var _iteratorNormalCompletion = true;
        var _didIteratorError = false;
        var _iteratorError = undefined;

        try {
          for (var _iterator = regexes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
            var current = _step.value;
            var regex = this.resolveRegex(current);

            if (regex.pattern.test(value)) {
              this.setError(utils.pickValue('err', regex, '{this} is not a valid {_this}'), value);
              break;
            }
          }
        } catch (err) {
          _didIteratorError = true;
          _iteratorError = err;
        } finally {
          try {
            if (!_iteratorNormalCompletion && _iterator.return != null) {
              _iterator.return();
            }
          } finally {
            if (_didIteratorError) {
              throw _iteratorError;
            }
          }
        }
      }

      return this.succeeds();
    }
    /**
     * validates regex check any rules
     */

  }, {
    key: "regexCheckAny",
    value: function regexCheckAny(value, options) {
      if (this.succeeds() && options.regexAny) {
        if (!options.regexAny.patterns.some(function (pattern) {
          return pattern.test(value);
        })) {
          this.setError(utils.pickValue('err', options.regexAny, '{this} is not a valid {_this}'), value);
        }
      }

      return this.succeeds();
    }
    /**
     * validates regex check all rules
     */

  }, {
    key: "regexCheckAll",
    value: function regexCheckAll(value, options) {
      if (this.succeeds() && options.regexAll) {
        var _iteratorNormalCompletion2 = true;
        var _didIteratorError2 = false;
        var _iteratorError2 = undefined;

        try {
          for (var _iterator2 = options.regexAll[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
            var current = _step2.value;
            var regex = this.resolveRegex(current);

            if (!regex.pattern.test(value)) {
              this.setError(utils.pickValue('err', regex, '{this} is not a valid {_this}'), value);
              break;
            }
          }
        } catch (err) {
          _didIteratorError2 = true;
          _iteratorError2 = err;
        } finally {
          try {
            if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
              _iterator2.return();
            }
          } finally {
            if (_didIteratorError2) {
              throw _iteratorError2;
            }
          }
        }
      }

      return this.succeeds();
    }
    /**
     * check if value matches a pattern
     */

  }, {
    key: "regexCheck",
    value: function regexCheck(value, options) {
      if (this.succeeds() && options.regex) {
        var regex = this.resolveRegex(options.regex);

        if (!regex.pattern.test(value)) {
          this.setError(utils.pickValue('err', regex, '{this} is not a valid {_this}'), value);
        }
      }

      return this.succeeds();
    }
    /**
     * runs regex rule checks
     */

  }, {
    key: "checkRegexRules",
    value: function checkRegexRules(value, options) {
      //check for regex rule
      this.regexCheck(value, options); //check for regexAll rule

      this.regexCheckAll(value, options); //check for regexAny rule

      this.regexCheckAny(value, options); //check for regexNone rule

      this.regexCheckNone(value, options);
      return this.succeeds();
    }
    /**
     * constructs error message for limiting rule errors
     */

  }, {
    key: "constructLRErrorMessage",
    value: function constructLRErrorMessage(prefix, template, value, unit) {
      var formatter = new Intl.NumberFormat();
      var constructedMessage = '';
      prefix += ' ';

      switch (unit) {
        case 'character':
          constructedMessage = prefix + template + ' ' + formatter.format(value) + ' characters';
          break;

        case 'number':
          constructedMessage = prefix + template + ' ' + formatter.format(value);
          break;

        case 'date':
          constructedMessage = prefix + template + ' ' + value;
          break;

        case 'file':
          constructedMessage = prefix + template + ' ' + utils.convertToMemoryUnit(value);
          break;
      }

      return constructedMessage;
    }
    /**
     * checks the limiting rules such as min, max, lt, gt
     */

  }, {
    key: "checkLimitingRules",
    value: function checkLimitingRules(value, length, options, unit, dateConverter) {
      var prefix = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : '{_this}';

      var resolveValue = function resolveValue(value) {
        if (dateConverter) {
          return dateConverter(value.toString());
        } else {
          return utils.expandToNumeric(value);
        }
      };

      var errorMessage = '';
      var template = ''; //check the min limit

      if (!utils.isUndefined(options.min)) {
        var min = resolveValue(options.min);
        template = 'should not be less than';

        if (length < min) {
          errorMessage = this.constructLRErrorMessage(prefix, template, min, unit);
          return this.setError(utils.pickValue('minErr', options, errorMessage), value);
        }
      } //check the max limit


      if (!utils.isUndefined(options.max)) {
        var max = resolveValue(options.max);
        template = 'should not be greater than';

        if (length > max) {
          errorMessage = this.constructLRErrorMessage(prefix, template, max, unit);
          return this.setError(utils.pickValue('maxErr', options, errorMessage), value);
        }
      } //check the gt limit


      if (!utils.isUndefined(options.gt)) {
        var gt = resolveValue(options.gt);
        template = 'should be greater than';

        if (length <= gt) {
          errorMessage = this.constructLRErrorMessage(prefix, template, gt, unit);
          return this.setError(utils.pickValue('gtErr', options, errorMessage), value);
        }
      } //check the lt limit


      if (!utils.isUndefined(options.lt)) {
        var lt = resolveValue(options.lt);
        template = 'should be less than';

        if (length >= lt) {
          errorMessage = this.constructLRErrorMessage(prefix, template, lt, unit);
          return this.setError(utils.pickValue('ltErr', options, errorMessage), value);
        }
      }

      return this.succeeds();
    }
  }, {
    key: "setup",
    value: function setup(required, field, value, options, index) {
      var isFile = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
      this.reset(field, options, index);
      this.fileName = '';

      if (isFile) {
        if (typeof this.files[field] !== 'undefined') {
          return this.shouldProceed = true;
        } else {
          if (required) {
            this.setError('{_this} is required', value);
          }

          return this.shouldProceed = false;
        }
      } else {
        if (value !== '') {
          return this.shouldProceed = true;
        } else {
          if (required) {
            this.setError('{_this} is required', value);
          }

          return this.shouldProceed = false;
        }
      }
    }
    /**
     * sets the files source
     */

  }, {
    key: "setFiles",
    value: function setFiles(files) {
      this.files = files;
      return this;
    }
    /**
     * returns the computed file name for the last file validation that involved a moveTo
     * operation. Returns empty string if there is non
     */

  }, {
    key: "getFileName",
    value: function getFileName() {
      return this.fileName;
    }
    /**
     * validate text
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateText",
    value: function validateText(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        this.checkLimitingRules(value, value.length, options, 'character'); //check for formatting rules

        this.checkRegexRules(value, options);
      }

      return this.postValidate(value, options);
    }
    /**
     * validate email address
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateEmail",
    value: function validateEmail(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        /*
         * email validation https://www.w3resource.com/javascript/form/email-validation.php
         * https://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax
         */
        var err = '{this} is not a valid email address';
        var internalOptions = {
          regexAll: [//email must contain two parts; personal-info and domain part
          {
            pattern: /^[-\w!#$%&'*+/=?^`{|}~.]{1,64}@[-a-z0-9.]{1,253}$/i,
            err: err
          }, //personal info must start with a word character
          {
            pattern: /^\w/,
            err: err
          }, // domain consists of labels that are each 63 characters max, each label
          // cannot start or end with highen
          {
            pattern: new RegExp('@[a-z0-9](?:[-a-z0-9]*[a-z0-9])?' + //match first label
            '(?:\\.[a-z0-9](?:[-a-z0-9]*[a-z0-9])?)*' + //followed by one or more labels
            '(\\.[a-z]{2,4})$', //then must have a top level domain
            'i'),
            err: err
          }],
          //in the personal info, there cant be two or more adjacent dots
          regexNone: {
            pattern: /\.{2,}.*@/,
            err: err
          }
        };
        this.checkLimitingRules(value, value.length, options, 'character');
        this.checkRegexRules(value, internalOptions);
        this.checkRegexRules(value, options);
      }

      return this.postValidate(value, options);
    }
    /**
     * validate url
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateURL",
    value: function validateURL(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        /*
         * email validation https://www.w3resource.com/javascript/form/email-validation.php
         * https://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax
         */
        var schemes = utils.pickValue('schemes', options, Constants.URL_SCHEMES);
        var err = '{this} is not a valid url';
        var internalOptions = {
          regex: {
            /*
             * domain consists of optional scheme, and consists of labels that are each
             * 63 characters max, each label cannot start or end with highen
             */
            pattern: new RegExp( //match optional scheme
            '^(?:(?:' + schemes.join('|') + ')://)' + (options.mustHaveScheme ? '' : '?') + '[a-z0-9](?:[-a-z0-9]*[a-z0-9])?' + //match first label
            '(?:\\.[a-z0-9](?:[-a-z0-9]*[a-z0-9])?)*' + // followed by one or more labels
            '(\\.[a-z]{2,4})' + //then must have a top level domain
            '(?:\\:\\d{1,4})?' + //match optional port number
            '(?:[#/?][-\\w()/#~:.?+=&%@]*)?$', //match optional part, hash, query
            'i'),
            err: err
          }
        };
        this.checkLimitingRules(value, value.length, options, 'character');
        this.checkRegexRules(value, internalOptions);
        this.checkRegexRules(value, options);
      }

      return this.postValidate(value, options);
    }
    /**
     * validate phone number
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validatePhoneNumber",
    value: function validatePhoneNumber(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        try {
          var country = options.country ? options.country.substring(0, 2).toUpperCase() : undefined;
          var phoneNumber = libphonenumberJs.parsePhoneNumber(value, country);
          var error = '';

          if (phoneNumber.country === '001') {
            if (country && options.enforceCountry !== false) {
              error = "non geographical phone numbers are not recognised. please use your country's phone number";
            }
          } else if (country && phoneNumber.country !== country) {
            error = "phone number does not belong to your country. please use your country's phone number";
          }

          if (error) {
            this.setError(error, value);
          }
        } catch (ex) {
          this.setError(this.phoneNumberErrors[ex.message], value);
        }

        this.checkLimitingRules(value, value.length, options, 'character', undefined, 'Phone number');
        this.checkRegexRules(value, options);
      }

      return this.postValidate(value, options);
    }
    /**
     * validate password
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validatePassword",
    value: function validatePassword(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (utils.pickValue('preValidate', options, true)) {
          var internalOptions = {
            min: Constants.MIN_PASSWORD_LENGTH,
            max: Constants.MAX_PASSWORD_LENGTH,
            regexAll: [//password should contain at least two alphabets
            {
              pattern: /[a-z].*[a-z]/i,
              err: 'Password must contain at least two letter alphabets'
            }, //password should contain at least two non letter alphabets
            {
              pattern: /[^a-z].*[^a-z]/i,
              err: 'Password must contain at least two non letter alphabets'
            }]
          };
          this.checkLimitingRules(value, value.length, internalOptions, 'character', undefined, 'Password');
          this.checkRegexRules(value, internalOptions);
        }

        this.checkLimitingRules(value, value.length, options, 'character', undefined, 'Password');
        this.checkRegexRules(value, options);
      }

      return this.postValidate(value, options, 'Passwords');
    }
    /**
     * validates date
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateDate",
    value: function validateDate(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (!Constants.DATE_FORMAT.test(value)) {
          return this.setError('{this} is not a correct date format', value);
        } //if date is not valid, return immediately


        var date = CustomDate.isValid(value);

        if (date === false) {
          return this.setError('{this} is not a valid date', value);
        } //validate the limiting rules


        this.checkLimitingRules(value, date, options, 'date', Util.dateConverter);
      }

      return this.postValidate(value, options);
    }
    /**
     * validates integer
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateInt",
    value: function validateInt(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (/^[-+]?\d+$/.test(value)) {
          this.checkLimitingRules(value, parseInt(value), options, 'number');
        } else {
          this.setError(utils.pickValue('err', options, '{this} is not a valid integer'), value);
        }
      }

      return this.postValidate(value, options);
    }
    /**
     * validates positive integer
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validatePInt",
    value: function validatePInt(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (/^[+]?\d+$/.test(value)) {
          this.checkLimitingRules(value, parseInt(value), options, 'number');
        } else {
          this.setError(utils.pickValue('err', options, '{this} is not a valid positive integer'), value);
        }
      }

      return this.postValidate(value, options);
    }
    /**
     * validates negative integer
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateNInt",
    value: function validateNInt(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (/^-\d+$/.test(value)) {
          this.checkLimitingRules(value, parseInt(value), options, 'number');
        } else {
          this.setError(utils.pickValue('err', options, '{this} is not a valid negative integer'), value);
        }
      }

      return this.postValidate(value, options);
    }
    /**
     * validates floating point numbers
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateNumber",
    value: function validateNumber(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (/^(?:[-+]?\d+(\.\d+)?|\.\d+)$/.test(value)) {
          this.checkLimitingRules(value, parseFloat(value), options, 'number');
        } else {
          this.setError(utils.pickValue('err', options, '{this} is not a valid number'), value);
        }
      }

      return this.postValidate(value, options);
    }
    /**
     * validates positive floating point numbers
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validatePNumber",
    value: function validatePNumber(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (/^(?:[+]?\d+(\.\d+)?|\.\d+)$/.test(value)) {
          this.checkLimitingRules(value, parseFloat(value), options, 'number');
        } else {
          this.setError(utils.pickValue('err', options, '{this} is not a valid positive number'), value);
        }
      }

      return this.postValidate(value, options);
    }
    /**
     * validates negative floating point numbers
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateNNumber",
    value: function validateNNumber(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        if (/^(?:[-]\d+(\.\d+)?|\.\d+)$/.test(value)) {
          this.checkLimitingRules(value, parseFloat(value), options, 'number');
        } else {
          this.setError(utils.pickValue('err', options, '{this} is not a valid negative number'), value);
        }
      }

      return this.postValidate(value, options);
    }
    /**
     * validates choice
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateChoice",
    value: function validateChoice(required, field, value, options, index) {
      if (this.setup(required, field, value, options, index)) {
        var choices = options.choices;
        var exists = choices.some(function (current) {
          return current.toString() === value;
        });

        if (!exists) {
          this.setError(utils.pickValue('err', options, '{this} is not an acceptable choice'), value);
        }
      }

      return this.postValidate(value, options);
    }
    /**
     * validates range
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateRange",
    value: function validateRange(required, field, value, options, index) {
      var choices = [];

      if (utils.isString(options.from)) {
        choices = utils.range(options.from, options.to, options.step);
      } else {
        choices = utils.range(options.from, options.to, options.step);
      }

      var choiceOptions = {
        choices: choices
      };
      choiceOptions.shouldMatch = options.shouldMatch;
      choiceOptions.err = options.err;
      return this.validateChoice(required, field, value, choiceOptions, index);
    }
    /**
     * validates files
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateFile",
    value: function () {
      var _validateFile = _asyncToGenerator(
      /*#__PURE__*/
      _regeneratorRuntime.mark(function _callee(required, field, value, options, index, category, label) {
        var file, exts, tempPath, fileType, destFolder, fileName, dest;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (!this.setup(required, field, value, options, index, true)) {
                  _context.next = 34;
                  break;
                }

                file = this.files[field];
                value = utils.makeArray(file.name)[index];
                this.fileName = value; //check limiting rules

                if (this.checkLimitingRules(value, utils.makeArray(file.size)[index], options, 'file')) {
                  _context.next = 6;
                  break;
                }

                return _context.abrupt("return", false);

              case 6:
                //check extensions and file category
                exts = utils.makeArray(options.exts).map(function (ext) {
                  return ext.replace(/^\./, '').toLowerCase();
                });
                tempPath = utils.makeArray(file.path)[index];
                category = utils.makeArray(category);
                _context.next = 11;
                return this.getFileType(tempPath);

              case 11:
                fileType = _context.sent;

                if (!utils.isNull(fileType)) {
                  _context.next = 14;
                  break;
                }

                return _context.abrupt("return", this.setError('{this} file extension could not be detected. Please check file', value));

              case 14:
                if (!(category.length > 0 && !category.includes(fileType.mime.split('/')[0]))) {
                  _context.next = 16;
                  break;
                }

                return _context.abrupt("return", this.setError(utils.pickValue('err', options, "{this} is not ".concat(label, " file")), value));

              case 16:
                if (!(exts.length > 0 && !exts.includes(fileType.ext))) {
                  _context.next = 18;
                  break;
                }

                return _context.abrupt("return", this.setError(utils.pickValue('extErr', options, ".".concat(fileType.ext, " files are not allowed")), value));

              case 18:
                if (!options.moveTo) {
                  _context.next = 34;
                  break;
                }

                destFolder = options.moveTo;

                if (!(fs.existsSync(destFolder) && fs.statSync(destFolder).isDirectory())) {
                  _context.next = 33;
                  break;
                }

                fileName = crypto.randomBytes(32).toString('hex') + '.' + fileType.ext;
                dest = path.join(destFolder, fileName);
                _context.prev = 23;
                fs.renameSync(tempPath, dest);
                this.fileName = fileName;
                _context.next = 31;
                break;

              case 28:
                _context.prev = 28;
                _context.t0 = _context["catch"](23);
                throw new FileMoveException(_context.t0.message);

              case 31:
                _context.next = 34;
                break;

              case 33:
                throw new DirectoryNotFoundException("".concat(destFolder, " moveTo path does not exist, or it is not a folder"));

              case 34:
                return _context.abrupt("return", this.postValidate(value, options));

              case 35:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this, [[23, 28]]);
      }));

      function validateFile(_x, _x2, _x3, _x4, _x5, _x6, _x7) {
        return _validateFile.apply(this, arguments);
      }

      return validateFile;
    }()
    /**
     * validates image files
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateImage",
    value: function validateImage(required, field, value, options, index) {
      return this.validateFile(required, field, value, options, index, 'image', 'an image');
    }
    /**
     * validates audio files
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateAudio",
    value: function validateAudio(required, field, value, options, index) {
      return this.validateFile(required, field, value, options, index, 'audio', 'an audio');
    }
    /**
     * validates video files
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateVideo",
    value: function validateVideo(required, field, value, options, index) {
      return this.validateFile(required, field, value, options, index, 'video', 'a video');
    }
    /**
     * validates media files
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateMedia",
    value: function validateMedia(required, field, value, options, index) {
      return this.validateFile(required, field, value, options, index, ['image', 'video', 'video'], 'a media');
    }
    /**
     * validates document files
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateDocument",
    value: function validateDocument(required, field, value, options, index) {
      options.exts = utils.pickValue('exts', options, Constants.DEFAULT_DOCUMENT_FILES);
      return this.validateFile(required, field, value, options, index);
    }
    /**
     * validates document files
     *
     * @param required boolean indicating if field is required
     * @param field field name under validation
     * @param value field value under validation
     * @param options validation options
     * @param index field value index position
     */

  }, {
    key: "validateArchive",
    value: function validateArchive(required, field, value, options, index) {
      options.exts = utils.pickValue('exts', options, Constants.DEFAULT_ARCHIVE_FILES);
      return this.validateFile(required, field, value, options, index);
    }
  }]);

  return Validator;
}(Common);

module.exports = Validator;
//# sourceMappingURL=Validator.js.map
