"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Validator = void 0;

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _tsFns = require("ts-fns");

var _utils = require("./shared/utils.js");

var Validator = /*#__PURE__*/function () {
  function Validator() {
    var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    (0, _classCallCheck2.default)(this, Validator);
    var properties = (0, _utils.ofChain)(this, Validator);
    Object.assign(this, properties, attrs);
  }

  (0, _createClass2.default)(Validator, [{
    key: "extend",
    value: function extend(attrs) {
      var Constructor = (0, _tsFns.getConstructorOf)(this);
      var validator = new Constructor(this);
      Object.assign(validator, attrs);
      return validator;
    }
  }]);
  return Validator;
}();

exports.Validator = Validator;
(0, _defineProperty2.default)(Validator, "required", required);
(0, _defineProperty2.default)(Validator, "maxLen", maxLen);
(0, _defineProperty2.default)(Validator, "minLen", minLen);
(0, _defineProperty2.default)(Validator, "max", max);
(0, _defineProperty2.default)(Validator, "min", min);
(0, _defineProperty2.default)(Validator, "integer", integer);
(0, _defineProperty2.default)(Validator, "decimal", decimal);
(0, _defineProperty2.default)(Validator, "email", email);
(0, _defineProperty2.default)(Validator, "url", url);
(0, _defineProperty2.default)(Validator, "date", date);
(0, _defineProperty2.default)(Validator, "match", match);
(0, _defineProperty2.default)(Validator, "allOf", allOf);
(0, _defineProperty2.default)(Validator, "anyOf", anyOf);

function required(message, emptyFn) {
  return new Validator({
    name: 'required',
    determine: function determine(_, key) {
      var _this$$views;

      if (this !== null && this !== void 0 && (_this$$views = this.$views) !== null && _this$$views !== void 0 && _this$$views[key]) {
        return this.$views[key].required;
      }

      return true;
    },
    validate: function validate(value, key) {
      var _this$$views2;

      // emptyFn has higher priority
      if (emptyFn) {
        return !emptyFn(value);
      }

      if (this !== null && this !== void 0 && (_this$$views2 = this.$views) !== null && _this$$views2 !== void 0 && _this$$views2[key]) {
        return !this.$views[key].empty;
      }

      return !(0, _tsFns.isEmpty)(value);
    },
    message: message,
    break: true
  });
}

function maxLen(message, len) {
  return new Validator({
    name: 'maxLen',
    determine: function determine(_, key) {
      var _this$$views3, _this$$views3$key;

      if ((0, _tsFns.isNumber)(len)) {
        return true;
      }

      if ((0, _tsFns.isNumber)(this === null || this === void 0 ? void 0 : (_this$$views3 = this.$views) === null || _this$$views3 === void 0 ? void 0 : (_this$$views3$key = _this$$views3[key]) === null || _this$$views3$key === void 0 ? void 0 : _this$$views3$key.maxLen)) {
        return true;
      }

      return false;
    },
    validate: function validate(value, key) {
      var _this$$views4, _this$$views4$key;

      if (!(0, _tsFns.isString)(value)) {
        return false;
      }

      var attr = this === null || this === void 0 ? void 0 : (_this$$views4 = this.$views) === null || _this$$views4 === void 0 ? void 0 : (_this$$views4$key = _this$$views4[key]) === null || _this$$views4$key === void 0 ? void 0 : _this$$views4$key.maxLen;
      var maxNum = (0, _tsFns.isNumber)(len) ? len : (0, _tsFns.isNumber)(attr) ? attr : NaN;
      return value.length <= maxNum;
    },
    message: message,
    break: true
  });
}

function minLen(message, len) {
  return new Validator({
    name: 'minLen',
    determine: function determine(_, key) {
      var _this$$views5, _this$$views5$key;

      if ((0, _tsFns.isNumber)(len)) {
        return true;
      }

      if ((0, _tsFns.isNumber)(this === null || this === void 0 ? void 0 : (_this$$views5 = this.$views) === null || _this$$views5 === void 0 ? void 0 : (_this$$views5$key = _this$$views5[key]) === null || _this$$views5$key === void 0 ? void 0 : _this$$views5$key.minLen)) {
        return true;
      }

      return false;
    },
    validate: function validate(value, key) {
      var _this$$views6, _this$$views6$key;

      if (!(0, _tsFns.isString)(value)) {
        return false;
      }

      var attr = this === null || this === void 0 ? void 0 : (_this$$views6 = this.$views) === null || _this$$views6 === void 0 ? void 0 : (_this$$views6$key = _this$$views6[key]) === null || _this$$views6$key === void 0 ? void 0 : _this$$views6$key.minLen;
      var minNum = (0, _tsFns.isNumber)(len) ? len : (0, _tsFns.isNumber)(attr) ? attr : NaN;
      return value.length >= minNum;
    },
    message: message,
    break: true
  });
}

function max(message, num) {
  return new Validator({
    name: 'max',
    determine: function determine(_, key) {
      var _this$$views7, _this$$views7$key;

      if ((0, _tsFns.isNumber)(num)) {
        return true;
      }

      if ((0, _tsFns.isNumber)(this === null || this === void 0 ? void 0 : (_this$$views7 = this.$views) === null || _this$$views7 === void 0 ? void 0 : (_this$$views7$key = _this$$views7[key]) === null || _this$$views7$key === void 0 ? void 0 : _this$$views7$key.max)) {
        return true;
      }

      return false;
    },
    validate: function validate(value, key) {
      if ((0, _tsFns.isNumber)(value) || (0, _tsFns.isNumeric)(value)) {
        var _this$$views8, _this$$views8$key;

        var v = +value;
        var attr = this === null || this === void 0 ? void 0 : (_this$$views8 = this.$views) === null || _this$$views8 === void 0 ? void 0 : (_this$$views8$key = _this$$views8[key]) === null || _this$$views8$key === void 0 ? void 0 : _this$$views8$key.max;
        var n = (0, _tsFns.isNumber)(num) ? num : (0, _tsFns.isNumber)(attr) ? attr : NaN;
        return v <= n;
      }

      return false;
    },
    message: message,
    break: true
  });
}

function min(message, num) {
  return new Validator({
    name: 'min',
    determine: function determine(_, key) {
      var _this$$views9, _this$$views9$key;

      if ((0, _tsFns.isNumber)(num)) {
        return true;
      }

      if ((0, _tsFns.isNumber)(this === null || this === void 0 ? void 0 : (_this$$views9 = this.$views) === null || _this$$views9 === void 0 ? void 0 : (_this$$views9$key = _this$$views9[key]) === null || _this$$views9$key === void 0 ? void 0 : _this$$views9$key.min)) {
        return true;
      }

      return false;
    },
    validate: function validate(value, key) {
      if ((0, _tsFns.isNumber)(value) || (0, _tsFns.isNumeric)(value)) {
        var _this$$views10, _this$$views10$key;

        var v = +value;
        var attr = this === null || this === void 0 ? void 0 : (_this$$views10 = this.$views) === null || _this$$views10 === void 0 ? void 0 : (_this$$views10$key = _this$$views10[key]) === null || _this$$views10$key === void 0 ? void 0 : _this$$views10$key.min;
        var n = (0, _tsFns.isNumber)(num) ? num : (0, _tsFns.isNumber)(attr) ? attr : NaN;
        return v >= n;
      }

      return false;
    },
    message: message,
    break: true
  });
}

function integer(message, len) {
  return new Validator({
    name: 'integer',
    determine: function determine(_, key) {
      var _this$$views11, _this$$views11$key;

      if ((0, _tsFns.isNumber)(len)) {
        return true;
      }

      if ((0, _tsFns.isNumber)(this === null || this === void 0 ? void 0 : (_this$$views11 = this.$views) === null || _this$$views11 === void 0 ? void 0 : (_this$$views11$key = _this$$views11[key]) === null || _this$$views11$key === void 0 ? void 0 : _this$$views11$key.integer)) {
        return true;
      }

      return false;
    },
    validate: function validate(value, key) {
      var _this$$views12, _this$$views12$key;

      if (!(0, _tsFns.isNumber)(value) && !(0, _tsFns.isNumeric)(value)) {
        return false;
      }

      var num = (0, _tsFns.numerify)(value).replace('-', '');

      var _num$split = num.split('.'),
          _num$split2 = (0, _slicedToArray2.default)(_num$split, 1),
          intPart = _num$split2[0];

      var integer = this === null || this === void 0 ? void 0 : (_this$$views12 = this.$views) === null || _this$$views12 === void 0 ? void 0 : (_this$$views12$key = _this$$views12[key]) === null || _this$$views12$key === void 0 ? void 0 : _this$$views12$key.integer;
      var limit = (0, _tsFns.isNumber)(len) ? len : (0, _tsFns.isNumber)(integer) ? integer : null;

      if (limit === null) {
        return true;
      }

      if (intPart.length > limit) {
        return false;
      }

      return true;
    },
    message: message,
    break: true
  });
}

function decimal(message, len) {
  return new Validator({
    name: 'decimal',
    determine: function determine(_, key) {
      var _this$$views13, _this$$views13$key;

      if ((0, _tsFns.isNumber)(len)) {
        return true;
      }

      if ((0, _tsFns.isNumber)(this === null || this === void 0 ? void 0 : (_this$$views13 = this.$views) === null || _this$$views13 === void 0 ? void 0 : (_this$$views13$key = _this$$views13[key]) === null || _this$$views13$key === void 0 ? void 0 : _this$$views13$key.decimal)) {
        return true;
      }

      return false;
    },
    validate: function validate(value, key) {
      var _this$$views14, _this$$views14$key;

      if (!(0, _tsFns.isNumber)(value) && !(0, _tsFns.isNumeric)(value)) {
        return false;
      }

      var num = (0, _tsFns.numerify)(value).replace('-', '');

      var _num$split3 = num.split('.'),
          _num$split4 = (0, _slicedToArray2.default)(_num$split3, 2),
          _num$split4$ = _num$split4[1],
          deciPart = _num$split4$ === void 0 ? '' : _num$split4$;

      var decimal = this === null || this === void 0 ? void 0 : (_this$$views14 = this.$views) === null || _this$$views14 === void 0 ? void 0 : (_this$$views14$key = _this$$views14[key]) === null || _this$$views14$key === void 0 ? void 0 : _this$$views14$key.decimal;
      var limit = (0, _tsFns.isNumber)(len) ? len : (0, _tsFns.isNumber)(decimal) ? decimal : null;

      if (limit === null) {
        return true;
      }

      if (deciPart.length > limit) {
        return false;
      }

      return true;
    },
    message: message,
    break: true
  });
}

function email(message) {
  return match(/^[A-Za-z0-9]+[A-Za-z0-9._]*[A-Za-z0-9]+@[A-Za-z0-9]+[A-Za-z0-9.-]*[A-Za-z0-9]+\.[A-Za-z]{2,8}$/, message, 'email');
}

function url(message) {
  return match(/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?/, message, 'url');
}

function date(message) {
  return match(/^[1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9]/, message, 'date');
}

function match(validator, message) {
  var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'match';
  return new Validator({
    name: name,
    validate: function validate(value) {
      if ((0, _tsFns.isInstanceOf)(validator, RegExp)) {
        return typeof value === 'string' && validator.test(value);
      } else if (validator === String) {
        return (0, _tsFns.isString)(value);
      } else if (validator === Number) {
        return (0, _tsFns.isNumber)(value);
      } else if (validator === Boolean) {
        return (0, _tsFns.isBoolean)(value);
      } else if (validator === Function) {
        return typeof value === 'function';
      } else if ((0, _tsFns.isNaN)(validator)) {
        return (0, _tsFns.isNaN)(value);
      } // isConstructor should must come before isFunction
      else if ((0, _tsFns.isConstructor)(validator, 2)) {
        return (0, _tsFns.isInstanceOf)(value, validator);
      } else if ((0, _tsFns.isFunction)(validator)) {
        return validator.call(this, value);
      } else {
        return validator === value;
      }
    },
    message: message,
    break: true
  });
}

function allOf(validators, message) {
  return new Validator({
    name: 'allOf',
    validate: function validate(value) {
      for (var i = 0, len = validators.length; i < len; i++) {
        var validate = validators[i];

        if (!validate.call(this, value)) {
          return false;
        }
      }

      return true;
    },
    message: message,
    break: true
  });
}

function anyOf(validators, message) {
  return new Validator({
    name: 'anyOf',
    validate: function validate(value) {
      for (var i = 0, len = validators.length; i < len; i++) {
        var validate = validators[i];

        if (validate.call(this, value)) {
          return true;
        }
      }

      return false;
    },
    message: message,
    break: true
  });
}