validation-box
Version:
The only validation library - with flexible regex - you need.
559 lines (553 loc) • 15.8 kB
JavaScript
"use strict";
// 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/manual/generics-countries.ts
var runTest = (label, testCases, validator) => {
console.log(`
\u{1F535} Testing ${label}:`);
testCases.forEach(({ description, value, options, expected }) => {
const result = validator(value, options).valid;
console.log(
`${result ? "\u2705" : "\u274C"} ${description}: "${value}" \u2192 ${result ? "\u2705" : "\u274C"}`
);
});
};
var runTestCountries = (label, testCases, validator) => {
console.log(`
\u{1F535} Testing ${label}:`);
testCases.forEach(({ description, value, expected }) => {
const result = validator(value);
console.log(
`${result ? "\u2705" : "\u274C"} ${description}: "${value}" \u2192 ${result ? "\u2705" : "\u274C"}`
);
});
};
runTest(
"Username",
[
{ description: "Valid username", value: "otoniel123", expected: true },
{ description: "Too short", value: "ot", expected: false },
{
description: "Too long",
value: "otoniel_emanuel_luanda_dev",
expected: false
},
{ description: "Invalid characters", value: "otoniel!@#", expected: false },
{
description: "Contains banned word",
value: "badwordUser",
options: { bannedWords: ["badword"] },
expected: false
},
{
description: "Custom length (5-15)",
value: "otoni123",
options: { min: 5, max: 15 },
expected: true
}
],
validateUsername
);
runTest(
"User",
[
{ description: "Valid name", value: "Otoniel", expected: true },
{ description: "Too short", value: "O", expected: false },
{
description: "Banned word",
value: "HackerMaster",
options: { bannedWords: ["Hacker"] },
expected: false
},
{
description: "Custom allowed special chars",
value: "D'Angelo",
options: { allowSpecialChars: "'-" },
expected: true
}
],
validateUser
);
runTest(
"Email",
[
{ description: "Valid email", value: "test@example.com", expected: true },
{ description: "Invalid format", value: "invalid-email", expected: false },
{
description: "Not in allowed domains",
value: "user@gmail.com",
options: { allowedDomains: ["outlook.com"] },
expected: false
},
{
description: "Allowed domain",
value: "user@outlook.com",
options: { allowedDomains: ["outlook.com"] },
expected: true
}
],
validateEmail
);
runTest(
"Password",
[
{ description: "Valid password", value: "Pass1234!", expected: true },
{ description: "Too short", value: "short1!", expected: false },
{
description: "Missing special character",
value: "Password123",
expected: false
},
{
description: "Contains banned word",
value: "badpassword!",
options: { bannedWords: ["badpassword"] },
expected: false
},
{
description: "Custom length (12-50)",
value: "StrongPass123!",
options: { min: 12, max: 50 },
expected: true
}
],
validatePassword
);
runTest(
"Birth Date",
[
{ description: "Valid birthdate", value: "2000-01-01", expected: true },
{ description: "Future date", value: "2050-01-01", expected: false },
{ description: "Invalid format", value: "not-a-date", expected: false }
],
validateBirthDate
);
runTest(
"Age",
[
{ description: "Valid age", value: 25, expected: true },
{ description: "Too high", value: 150, expected: false },
{ description: "Negative age", value: -5, expected: false },
{
description: "Below minimum age",
value: 18,
options: { min: 21 },
expected: false
},
{
description: "Above maximum age",
value: 40,
options: { max: 35 },
expected: false
}
],
validateAge
);
runTestCountries(
"Angola - NIF",
[
{ description: "Valid NIF", value: "123456789", expected: true },
{
description: "Invalid NIF (letters)",
value: "ABC123456",
expected: false
}
],
validateNIFAO
);
runTestCountries(
"Angola - Phone",
[
{
description: "Valid number",
value: "+244923456789",
expected: true,
requireCountryCode: true
},
{
description: "Invalid number (short)",
value: "92345",
expected: false,
requireCountryCode: true
},
{
description: "Number with spaces",
value: "+244 923 456 789",
expected: true,
requireCountryCode: true
},
{
description: "Number with separators",
value: "+244-923-456-789",
expected: false,
requireCountryCode: true
},
{
description: "Number longer than expected",
value: "+244923456789123",
expected: false,
requireCountryCode: true
},
{
description: "Number without country code",
value: "923456789",
expected: true,
requireCountryCode: false
},
{
description: "Number without country code",
value: "923 456 789",
expected: true,
requireCountryCode: false
}
],
validatePhoneAO
);
runTestCountries(
"Brazil - CPF",
[
{ description: "Valid CPF", value: "123.456.789-09", expected: true },
{
description: "Invalid CPF (repeated sequence)",
value: "111.111.111-11",
expected: false
}
],
validateCPF
);
runTestCountries(
"Brazil - CNPJ",
[
{ description: "Valid CNPJ", value: "12.345.678/0001-95", expected: true },
{
description: "Invalid CNPJ (incorrect length)",
value: "12345",
expected: false
}
],
validateCNPJ
);
runTestCountries(
"Brazil - Phone",
[
{
description: "Valid number",
value: "+5511987654321",
expected: true,
requireCountryCode: true
},
{
description: "Invalid number (short)",
value: "1198765",
expected: false,
requireCountryCode: true
},
{
description: "Number with spaces",
value: "+55 11 98765 4321",
expected: true,
requireCountryCode: true
},
{
description: "Number with separators",
value: "+55-11-98765-4321",
expected: false,
requireCountryCode: true
},
{
description: "Number longer than expected",
value: "+5511987654321123",
expected: false,
requireCountryCode: true
},
{
description: "Number without country code",
value: "11987654321",
expected: true,
requireCountryCode: false
},
{
description: "Number without country code",
value: "11 98765 4321",
expected: true,
requireCountryCode: false
}
],
validatePhoneBR
);
runTestCountries(
"USA - SSN",
[
{ description: "Valid SSN", value: "123-45-6789", expected: true },
{
description: "Invalid SSN (wrong format)",
value: "123456789",
expected: false
}
],
validateSSN
);
runTestCountries(
"USA - Phone",
[
{
description: "Valid number",
value: "+11234567890",
expected: true,
requireCountryCode: true
},
{
description: "Invalid number (short)",
value: "12345",
expected: false,
requireCountryCode: true
},
{
description: "Number with spaces",
value: "+1 123 456 7890",
expected: true,
requireCountryCode: true
},
{
description: "Number with separators",
value: "+1-123-456-7890",
expected: false,
requireCountryCode: true
},
{
description: "Number longer than expected",
value: "+11234567890123",
expected: false,
requireCountryCode: true
},
{
description: "Number without country code",
value: "1234567890",
expected: true,
requireCountryCode: false
},
{
description: "Number without country code",
value: "123 456 7890",
expected: true,
requireCountryCode: false
}
],
validatePhoneUS
);
runTestCountries(
"USA - ZIP Code",
[
{ description: "Valid ZIP", value: "12345", expected: true },
{ description: "Invalid ZIP (short)", value: "12", expected: false }
],
validateZIPCode
);
//# sourceMappingURL=generics-countries.js.map