validation-box
Version:
The only validation library - with flexible regex - you need.
371 lines (364 loc) • 12.2 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
validateAge: () => validateAge,
validateBirthDate: () => validateBirthDate,
validateCNPJ: () => validateCNPJ,
validateCPF: () => validateCPF,
validateEmail: () => validateEmail,
validateNIFAO: () => validateNIFAO,
validatePassword: () => validatePassword,
validatePhoneAO: () => validatePhoneAO,
validatePhoneBR: () => validatePhoneBR,
validatePhoneUS: () => validatePhoneUS,
validateSSN: () => validateSSN,
validateUser: () => validateUser,
validateUsername: () => validateUsername,
validateZIPCode: () => validateZIPCode,
validator: () => validator,
vboxSchema: () => vboxSchema
});
module.exports = __toCommonJS(src_exports);
// src/helpers/index.ts
var containsBannedWords = (value, bannedWords) => {
if (!bannedWords || bannedWords.length === 0) return false;
return bannedWords.some(
(word) => value.toLowerCase().includes(word.toLowerCase())
);
};
// src/validators/generics.ts
var validateUsername = (username, options = {}) => {
const errors = [];
const min = options.min ?? 3;
const max = options.max ?? 20;
const specialChars = options.allowSpecialChars ?? "_";
if (username.length < min) {
errors.push(options.messages?.min || `Username must be at least ${min} characters`);
}
if (username.length > max) {
errors.push(options.messages?.max || `Username must be at most ${max} characters`);
}
if (containsBannedWords(username, options.bannedWords)) {
errors.push(options.messages?.bannedWords || "Username contains banned words");
}
if (/^\d+$/.test(username)) {
errors.push(options.messages?.onlyNumbers || "Username cannot contain only numbers");
}
const regex = new RegExp(`^[a-zA-Z0-9${specialChars}]+$`);
if (!regex.test(username)) {
errors.push(options.messages?.invalidFormat || `Username can only contain letters, numbers and ${specialChars}`);
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : void 0
};
};
var validateUser = (user, options = {}) => {
const errors = [];
const min = options.min ?? 3;
const max = options.max ?? 30;
const specialChars = options.allowSpecialChars ?? "''\\s";
if (user.length < min) {
errors.push(options.messages?.min || `Name must be at least ${min} characters`);
}
if (user.length > max) {
errors.push(options.messages?.max || `Name must be at most ${max} characters`);
}
if (containsBannedWords(user, options.bannedWords)) {
errors.push(options.messages?.bannedWords || "Name contains banned words");
}
if (/^\s*$/.test(user)) {
errors.push(options.messages?.emptySpace || "Name cannot be empty or contain only spaces");
}
const regex = new RegExp(`^[a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\xFF${specialChars}]+$`);
if (!regex.test(user)) {
errors.push(options.messages?.invalidFormat || `Name can only contain letters and ${specialChars}`);
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : void 0
};
};
var validateEmail = (email, options = {}) => {
const errors = [];
const emailRegex = /^[a-zA-Z0-9._%+-]+@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/;
const match = email.match(emailRegex);
if (!match) {
errors.push(options.messages?.invalidFormat || "Invalid email format");
} else if (options.allowedDomains && !options.allowedDomains.includes(match[1])) {
errors.push(options.messages?.allowedDomains || `Email domain must be one of: ${options.allowedDomains.join(", ")}`);
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : void 0
};
};
var validatePassword = (password, options = {}) => {
const errors = [];
const min = options.min ?? 8;
const max = options.max ?? 100;
const specialChars = options.allowSpecialChars ?? "!@#$%^&*()_+";
if (password.length < min) {
errors.push(options.messages?.min || `Password must be at least ${min} characters`);
}
if (password.length > max) {
errors.push(options.messages?.max || `Password must be at most ${max} characters`);
}
if (containsBannedWords(password, options.bannedWords)) {
errors.push(options.messages?.bannedWords || "Password contains banned words");
}
const regex = new RegExp(
`^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[${specialChars}])[A-Za-z\\d${specialChars}]+$`
);
if (!regex.test(password)) {
errors.push(options.messages?.invalidFormat || "Password must contain at least one uppercase letter, one lowercase letter, one number and one special character");
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : void 0
};
};
var validateBirthDate = (date, options = {}) => {
const errors = [];
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
if (!dateRegex.test(date)) {
errors.push(options.messages?.invalidFormat || "Date must be in YYYY-MM-DD format");
}
const birthDate = new Date(date);
if (isNaN(birthDate.getTime())) {
errors.push(options.messages?.invalidFormat || "Invalid date");
} else if (birthDate >= /* @__PURE__ */ new Date()) {
errors.push(options.messages?.invalidFormat || "Birth date must be in the past");
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : void 0
};
};
var validateAge = (age, options = {}) => {
const errors = [];
const min = options.min ?? 18;
const max = options.max ?? 120;
if (!Number.isInteger(age)) {
errors.push(options.messages?.invalidFormat || "Age must be an integer");
}
if (age < min) {
errors.push(options.messages?.min || `Age must be at least ${min} years`);
}
if (age > max) {
errors.push(options.messages?.max || `Age must be at most ${max} years`);
}
return {
valid: errors.length === 0,
errors: errors.length > 0 ? errors : void 0
};
};
// src/validators/countries/angola.ts
var validateNIFAO = (nif) => {
return /^\d{9}$/.test(nif);
};
var validatePhoneAO = (phone, requireCountryCode = false) => {
const countryCodeRegex = requireCountryCode ? "(\\+244|244)" : "(\\+244|244)?";
const regex = new RegExp(
`^${countryCodeRegex}\\s?\\d{3}\\s?\\d{3}\\s?\\d{3}$`
);
return regex.test(phone);
};
// src/validators/countries/brasil.ts
var validateCPF = (cpf) => {
cpf = cpf.replace(/\D/g, "");
if (cpf.length !== 11) return false;
if (/^(\d)\1{10}$/.test(cpf)) return false;
let sum = 0;
for (let i = 0; i < 9; i++) {
sum += parseInt(cpf.charAt(i)) * (10 - i);
}
let remainder = sum * 10 % 11;
if (remainder === 10 || remainder === 11) remainder = 0;
if (remainder !== parseInt(cpf.charAt(9))) return false;
sum = 0;
for (let i = 0; i < 10; i++) {
sum += parseInt(cpf.charAt(i)) * (11 - i);
}
remainder = sum * 10 % 11;
if (remainder === 10 || remainder === 11) remainder = 0;
if (remainder !== parseInt(cpf.charAt(10))) return false;
return true;
};
var validateCNPJ = (cnpj) => {
cnpj = cnpj.replace(/\D/g, "");
if (cnpj.length !== 14) return false;
if (/^(\d)\1{13}$/.test(cnpj)) return false;
let sum = 0;
let weight = 5;
for (let i = 0; i < 12; i++) {
sum += parseInt(cnpj.charAt(i)) * weight;
weight = weight === 2 ? 9 : weight - 1;
}
let remainder = sum % 11;
let digit1 = remainder < 2 ? 0 : 11 - remainder;
sum = 0;
weight = 6;
for (let i = 0; i < 13; i++) {
sum += parseInt(cnpj.charAt(i)) * weight;
weight = weight === 2 ? 9 : weight - 1;
}
remainder = sum % 11;
let digit2 = remainder < 2 ? 0 : 11 - remainder;
return digit1 === parseInt(cnpj.charAt(12)) && digit2 === parseInt(cnpj.charAt(13));
};
var validatePhoneBR = (phone, requireCountryCode = false) => {
const countryCodeRegex = requireCountryCode ? "(\\+55|55)" : "(\\+55|55)?";
const regex = new RegExp(
`^${countryCodeRegex}\\s?\\d{2}\\s?\\d{4,5}\\s?\\d{4}$`
);
return regex.test(phone);
};
// src/validators/countries/usa.ts
var validateSSN = (ssn) => {
return /^\d{3}-\d{2}-\d{4}$/.test(ssn);
};
var validatePhoneUS = (phone, requireCountryCode = false) => {
const countryCodeRegex = requireCountryCode ? "(\\+1|1)" : "(\\+1|1)?";
const regex = new RegExp(
`^${countryCodeRegex}\\s?\\d{3}\\s?\\d{3}\\s?\\d{4}$`
);
return regex.test(phone);
};
var validateZIPCode = (zipCode) => {
return /^\d{5}(-\d{4})?$/.test(zipCode);
};
// src/schemas/index.ts
var vboxSchema = class _vboxSchema {
rules;
validateAll;
showErrors;
constructor(rules, options) {
this.rules = rules;
this.validateAll = options?.validateAll ?? false;
this.showErrors = options?.showErrors ?? true;
}
transformValue(value, transforms) {
if (!transforms) return value;
return transforms.reduce((acc, transform) => transform(acc), value);
}
validate(data) {
const validatedData = {};
const errors = {};
let isValid = true;
for (const field in this.rules) {
const rule = this.rules[field];
const value = data[field];
const options = rule.options || {};
if (options.required && (value === void 0 || value === null || value === "")) {
isValid = false;
const message = options.messages?.required || `${field} is required`;
errors[field] = [message];
if (!this.validateAll) break;
continue;
}
if (!options.required && (value === void 0 || value === null || value === "")) {
continue;
}
const transformedValue = this.transformValue(value, rule.transform);
const validation = rule.fn(transformedValue, options);
if (validation.valid) {
validatedData[field] = transformedValue;
} else {
isValid = false;
const errorMessages = validation.errors || [];
errors[field] = errorMessages;
if (!this.validateAll) break;
}
}
return {
success: isValid,
data: isValid ? validatedData : void 0,
errors: !isValid && this.showErrors ? errors : void 0
};
}
// Method to add custom validation rule
addRule(field, rule) {
this.rules[field] = rule;
return this;
}
// Method to extend schema with another schema
extend(schema) {
return new _vboxSchema({ ...this.rules, ...schema["rules"] });
}
// Method to resolve validation for form data
resolve(data, returnAllErrors = false) {
const result = this.validate(data);
return {
values: result.success ? data : {},
errors: result.errors ? Object.keys(result.errors).reduce((acc, key) => {
const errorMessages = result.errors?.[key] || [];
acc[key] = {
type: "manual",
messages: returnAllErrors ? errorMessages : [errorMessages[0]]
};
return acc;
}, {}) : {}
};
}
};
var validator = {
username: (options) => ({
fn: validateUsername,
options
}),
user: (options) => ({
fn: validateUser,
options
}),
email: (options) => ({
fn: validateEmail,
options
}),
password: (options) => ({
fn: validatePassword,
options
}),
age: (options) => ({
fn: validateAge,
options
})
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
validateAge,
validateBirthDate,
validateCNPJ,
validateCPF,
validateEmail,
validateNIFAO,
validatePassword,
validatePhoneAO,
validatePhoneBR,
validatePhoneUS,
validateSSN,
validateUser,
validateUsername,
validateZIPCode,
validator,
vboxSchema
});
//# sourceMappingURL=index.js.map