js-formdata-validator
Version: 
JS Form Validator is a simple form data validation library for JavaScript. It provides a set of base rules for checking the type and value of various inputs, and allows you to define custom rules as well.
524 lines (523 loc) • 13.3 kB
JavaScript
var g = Object.defineProperty;
var c = (t, e, r) => e in t ? g(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
var o = (t, e, r) => (c(t, typeof e != "symbol" ? e + "" : e, r), r);
const f = {
  required: "The {field} cannot be empty",
  array: "The {field} must be instance of Array",
  integer: "The {field} must be integer",
  numeric: "The {field} must be numeric",
  string: "The {field} must be string",
  boolean: "The {field} must be a boolean",
  allowed: "The {field} must be one of the following: {args}",
  email: "The {field} is not a valid email address",
  min: "The {field} has minimum of {minSize} but it got value {value}",
  max: "The {field} has maximum of {maxSize} but it got value {value}",
  ipv4: "The {field} must be an IPv4 address",
  ipv6: "The {field} must be an IPv6 address",
  accepted: "The {field} must be accepted",
  declined: "The {field} must be declined"
}, l = ({
  fieldName: t,
  rule: e,
  customValidatorErrorMessage: r = {}
}) => ({ ...f, ...r })[e].replace("{field}", t), u = {
  required({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (t === void 0 || t === "" || t === null)
      return l({
        fieldName: e,
        rule: "required",
        customValidatorErrorMessage: r
      });
  },
  array({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (!(t instanceof Array))
      return l({
        fieldName: e,
        rule: "array",
        customValidatorErrorMessage: r
      });
  },
  integer({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (!Number.isInteger(t))
      return l({
        fieldName: e,
        rule: "integer",
        customValidatorErrorMessage: r
      });
  },
  numeric({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (typeof t != "number")
      return l({
        fieldName: e,
        rule: "numeric",
        customValidatorErrorMessage: r
      });
  },
  string({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (typeof t != "string")
      return l({
        fieldName: e,
        rule: "string",
        customValidatorErrorMessage: r
      });
  },
  boolean({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (typeof t != "boolean")
      return l({
        fieldName: e,
        rule: "boolean",
        customValidatorErrorMessage: r
      });
  },
  allowed({ value: t, fieldName: e, customValidatorErrorMessage: r }, ...a) {
    if (!a.includes(t))
      return l({
        fieldName: e,
        rule: "allowed",
        customValidatorErrorMessage: r
      }).replace("{args}", a.join(", "));
  },
  email({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (!/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(t))
      return l({
        fieldName: e,
        rule: "email",
        customValidatorErrorMessage: r
      });
  },
  min({ value: t, fieldName: e, customValidatorErrorMessage: r }, a) {
    if (a === void 0)
      return "Please define the min value. Example min:26";
    if (Number.isFinite(Number(t))) {
      const s = parseInt(t);
      if (s < a)
        return l({
          fieldName: e,
          rule: "min",
          customValidatorErrorMessage: r
        }).replace("{minSize}", a.toString()).replace("{value}", s.toString());
    } else if (typeof t == "string") {
      const s = t.length;
      if (s < a)
        return l({
          fieldName: e,
          rule: "min",
          customValidatorErrorMessage: r
        }).replace("{minSize}", a.toString()).replace("{value}", s.toString());
    }
  },
  max({ value: t, fieldName: e, customValidatorErrorMessage: r }, a) {
    if (a === void 0)
      return "Please define the max value. Example: max:26";
    if (Number.isFinite(Number(t))) {
      const s = parseInt(t);
      if (s > a)
        return l({
          fieldName: e,
          rule: "max",
          customValidatorErrorMessage: r
        }).replace("{maxSize}", a.toString()).replace("{value}", s.toString());
    } else if (typeof t == "string") {
      const s = t.length;
      if (s > a)
        return l({
          fieldName: e,
          rule: "max",
          customValidatorErrorMessage: r
        }).replace("{maxSize}", a.toString()).replace("{value}", s.toString());
    }
  },
  ipv4({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    const a = "(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}";
    if (!new RegExp(`^${a}$`).test(
      t && t.toString()
    ))
      return l({
        fieldName: e,
        rule: "ipv4",
        customValidatorErrorMessage: r
      });
  },
  ipv6({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    const a = "((([0-9a-fA-F]){1,4}):){7}([0-9a-fA-F]){1,4}";
    if (!new RegExp(`^${a}$`).test(
      t && t.toString()
    ))
      return l({
        fieldName: e,
        rule: "ipv6",
        customValidatorErrorMessage: r
      });
  },
  accepted({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (!["yes", "on", 1, !0].includes(t))
      return l({
        fieldName: e,
        rule: "accepted",
        customValidatorErrorMessage: r
      });
  },
  declined({
    value: t,
    fieldName: e,
    customValidatorErrorMessage: r
  }) {
    if (!["no", "off", 0, !1].includes(t))
      return l({
        fieldName: e,
        rule: "declined",
        customValidatorErrorMessage: r
      });
  }
};
class m {
  constructor() {
    o(this, "errorMessage");
    o(this, "errorBag", {});
  }
  add(e, r) {
    this.errorBag[e] ? this.errorBag[e].push(r) : this.errorBag[e] = [r];
  }
  clearErrorBag() {
    this.errorBag = {};
  }
  getErrorBag() {
    return this.errorBag;
  }
  setFieldErrors(e, r) {
    this.errorBag[e] = r;
  }
  setErrorMessage(e) {
    this.errorMessage = e;
  }
  getErrorMessage() {
    return this.errorMessage || this.defaultErrorMessage();
  }
  defaultErrorMessage() {
    return `${Object.keys(this.errorBag).length} error occured`;
  }
  hasErrors() {
    return Object.keys(this.errorBag).length > 0;
  }
}
class E {
  constructor({
    formData: e,
    customRules: r,
    rules: a,
    stopOnFirstFailure: s
  } = {}) {
    o(this, "formData");
    o(this, "rules");
    o(this, "validatorError");
    o(this, "validator");
    o(this, "stopOnFirstFailure");
    o(this, "customFieldNames", {});
    o(this, "customValidatorErrorMessage", {});
    this.formData = e ?? {}, this.rules = a ?? {}, this.validatorError = new m(), this.stopOnFirstFailure = s ?? !1, this.mergeCustomRules(r);
  }
  mergeCustomRules(e) {
    return this.setValidator({ ...u, ...e }), this;
  }
  async validate() {
    if (this.stopOnFirstFailure)
      for (const e in this.rules) {
        if (this.validatorError.hasErrors())
          break;
        await this.validateField({ field: e, fieldRules: this.rules[e] });
      }
    else {
      const e = Object.entries(this.rules).map(
        ([r, a]) => this.validateField({ field: r, fieldRules: a })
      );
      await Promise.all(e);
    }
    return this;
  }
  async validateField({
    field: e,
    fieldRules: r
  }) {
    const a = e.split(".");
    a.includes("*") ? await this.validateArrayObjects(e, a, r) : await this.validateFieldValue(e, a, r);
  }
  async validateArrayObjects(e, r, a) {
    const s = r.indexOf("*"), d = this.formData[r[s - 1]];
    for (let i = 0; i < d.length; i++)
      if (!a.every((n) => {
        typeof this.getValidatorResult(e, d[i], n) > "u";
      })) {
        const n = e.replace("*", `${i}`);
        await this.validateField({
          field: n,
          fieldRules: a
        });
      }
  }
  async validateFieldValue(e, r, a) {
    let s = this.formData;
    for (const d of r)
      s = s[d];
    if (this.stopOnFirstFailure)
      for (const d of a) {
        const i = await this.getValidatorResult(e, s, d);
        if (i) {
          this.validatorError.add(e, i);
          break;
        }
      }
    else
      (await Promise.all(
        a.map(
          (i) => typeof this.getValidatorResult(e, s, i) == "object" ? this.getValidatorResult(e, s, i) : Promise.resolve(this.getValidatorResult(e, s, i))
        )
      )).forEach((i) => {
        i && this.validatorError.add(e, i);
      });
  }
  getValidatorResult(e, r, a) {
    let s;
    switch (typeof a) {
      case "string": {
        s = this.handleStringRule(e, a);
        break;
      }
      case "function": {
        s = a(r, this.formData);
        break;
      }
    }
    return s;
  }
  handleStringRule(e, r) {
    const [a, s] = this.parseRule(r);
    if (!(a in this.validator) || e.includes("*"))
      return;
    const d = e.split(".").reduce((h, n) => h[n], this.formData);
    let i = e;
    return Object.keys(this.customFieldNames).includes(e) && (i = this.customFieldNames[i]), this.validator[a](
      {
        value: d,
        formdata: this.formData,
        fieldName: i,
        customValidatorErrorMessage: this.customValidatorErrorMessage
      },
      ...s
    );
  }
  parseRule(e) {
    const [r, a] = e.split(":"), s = a ? a.split(",").map((d) => d.trim()) : [];
    return [r, s];
  }
  getErrorBag() {
    return this.validatorError.getErrorBag();
  }
  getErrorMessage() {
    return this.validatorError.getErrorMessage();
  }
  setErrorMessage(e) {
    return this.validatorError.setErrorMessage(e);
  }
  getError(e) {
    var r;
    return (r = this.validatorError.getErrorBag()[e]) == null ? void 0 : r[0];
  }
  getFailedFields() {
    return Object.keys(this.getErrorBag());
  }
  pass() {
    return Object.keys(this.getErrorBag()).length === 0;
  }
  fail() {
    return !this.pass();
  }
  clearErrors() {
    return this.validatorError.clearErrorBag(), this;
  }
  getFormData() {
    return this.formData;
  }
  setFormData(e) {
    return this.formData = e, this;
  }
  setFieldErrors(e, r) {
    this.validatorError.setFieldErrors(e, r);
  }
  setFormKeyValue(e, r) {
    this.formData[e] = r;
  }
  getValidator() {
    return this.validator;
  }
  setValidator(e) {
    return this.validator = e, this;
  }
  getRules() {
    return this.rules;
  }
  setRules(e) {
    return this.rules = e, this;
  }
  setCustomFieldName(e) {
    this.customFieldNames = e;
  }
  getCustomFieldName() {
    return this.customFieldNames;
  }
  setCustomValidatorErrorMessage(e) {
    this.customValidatorErrorMessage = e;
  }
  getCustomValidatorErrorMessage() {
    return this.customValidatorErrorMessage;
  }
}
class v {
  constructor() {
    o(this, "fieldName");
    o(this, "fieldValue");
    o(this, "fieldRules");
    o(this, "validatorError");
    o(this, "validator");
    o(this, "formData");
    o(this, "customFieldName");
    o(this, "customValidatorErrorMessage", {});
    this.fieldName = "", this.fieldRules = [], this.fieldValue = null, this.validatorError = new m(), this.validator = u, this.formData = {};
  }
  setCustomRules(e) {
    this.mergeCustomRules(e);
  }
  setFieldName(e) {
    this.fieldName = e;
  }
  setFormData(e) {
    this.formData = e;
  }
  getFormData() {
    return this.formData;
  }
  getFieldName() {
    return this.fieldName;
  }
  setFieldRules(e) {
    this.fieldRules = e;
  }
  getFieldRules() {
    return this.fieldRules;
  }
  setFieldValue(e) {
    this.fieldValue = e;
  }
  getFieldValue() {
    return this.fieldValue;
  }
  async validate() {
    this.validatorError.clearErrorBag(), (await Promise.all(
      this.fieldRules.map(
        (r) => typeof this.getValidatorResult(r) == "object" ? this.getValidatorResult(r) : Promise.resolve(this.getValidatorResult(r))
      )
    )).forEach((r) => {
      r && this.validatorError.add(this.fieldName, r);
    });
  }
  async getValidatorResult(e) {
    let r;
    switch (typeof e) {
      case "string": {
        r = this.handleStringRule(e);
        break;
      }
      case "function": {
        r = e(this.fieldValue, this.formData);
        break;
      }
    }
    return r;
  }
  handleStringRule(e) {
    const [r, a] = this.parseRule(e);
    return this.validator[r](
      {
        value: this.fieldValue,
        fieldName: this.customFieldName || this.fieldName,
        formdata: this.formData,
        customValidatorErrorMessage: this.customValidatorErrorMessage
      },
      ...a
    );
  }
  parseRule(e) {
    const [r, a] = e.split(":"), s = a ? a.split(",").map((d) => d.trim()) : [];
    return [r, s];
  }
  pass() {
    return !this.validatorError.hasErrors();
  }
  fail() {
    return !this.pass();
  }
  getErrorBag() {
    return this.validatorError.getErrorBag()[this.fieldName];
  }
  mergeCustomRules(e) {
    return this.setValidator({ ...u, ...e }), this;
  }
  setValidator(e) {
    return this.validator = e, this;
  }
  setCustomFieldName(e) {
    this.customFieldName = e;
  }
  getCustomFieldName() {
    return this.customFieldName;
  }
  setCustomValidatorErrorMessage(e) {
    this.customValidatorErrorMessage = e;
  }
  getCustomValidatorErrorMessage() {
    return this.customValidatorErrorMessage;
  }
}
export {
  v as FieldValidator,
  E as Validator
};