mexican-utils
Version:
Library that handles validations for several Mexican related fields
258 lines (256 loc) • 6.82 kB
JavaScript
// src/utils/curp-utils.ts
var GENDERS = {
male: "H",
female: "M"
};
var STATES = {
aguascalientes: "AS",
baja_california: "BC",
baja_california_sur: "BS",
campeche: "CC",
chiapas: "CS",
chihuahua: "CH",
ciudad_de_m\u00E9xico: "DF",
coahuila_de_zaragoza: "CL",
colima: "CM",
durango: "DG",
guanajuato: "GT",
guerrero: "GR",
hidalgo: "HG",
jalisco: "JC",
m\u00E9xico: "MC",
michoac\u00E1n_de_ocampo: "MN",
morelos: "MS",
nayarit: "NT",
nuevo_le\u00F3n: "NL",
oaxaca: "OC",
puebla: "PL",
quer\u00E9taro: "QT",
quintana_roo: "QR",
san_luis_potos\u00ED: "SP",
sinaloa: "SL",
sonora: "SR",
tabasco: "TC",
tamaulipas: "TS",
tlaxcala: "TL",
veracruz_de_ignacio_de_la_llave: "VZ",
yucat\u00E1n: "YN",
zacatecas: "ZS",
no_especificado: "NE"
};
var COMMON_NAMES = [
"MARIA DEL ",
"MARIA DE LOS ",
"MARIA ",
"JOSE DE ",
"JOSE ",
"MA. ",
"MA ",
"M. ",
"J. ",
"J ",
"M "
];
var BAD_WORDS = {
BACA: "BXCA",
BAKA: "BXKA",
BUEI: "BXEI",
BUEY: "BXEY",
CACA: "CXCA",
CACO: "CXCO",
CAGA: "CXGA",
CAGO: "CXGO",
CAKA: "CXKA",
CAKO: "CXKO",
COGE: "CXGE",
COGI: "CXGI",
COJA: "CXJA",
COJE: "CXJE",
COJI: "CXJI",
COJO: "CXJO",
COLA: "CXLA",
CULO: "CXLO",
FALO: "FXLO",
FETO: "FXTO",
GETA: "GXTA",
GUEI: "GXEI",
GUEY: "GXEY",
JETA: "JXTA",
JOTO: "JXTO",
KACA: "KXCA",
KACO: "KXCO",
KAGA: "KXGA",
KAGO: "KXGO",
KAKA: "KXKA",
KAKO: "KXKO",
KOGE: "KXGE",
KOGI: "KXGI",
KOJA: "KXJA",
KOJE: "KXJE",
KOJI: "KXJI",
KOJO: "KXJO",
KOLA: "KXLA",
KULO: "KXLO",
LILO: "LXLO",
LOCA: "LXCA",
LOCO: "LXCO",
LOKA: "LXKA",
LOKO: "LXKO",
MAME: "MXME",
MAMO: "MXMO",
MEAR: "MXAR",
MEAS: "MXAS",
MEON: "MXON",
MIAR: "MXAR",
MION: "MXON",
MOCO: "MXCO",
MOKO: "MXKO",
MULA: "MXLA",
MULO: "MXLO",
NACA: "NXCA",
NACO: "NXCO",
PEDA: "PXDA",
PEDO: "PXDO",
PENE: "PXNE",
PIPI: "PXPI",
PITO: "PXTO",
POPO: "PXPO",
PUTA: "PXTA",
PUTO: "PXTO",
QULO: "QXLO",
RATA: "RXTA",
ROBA: "RXBA",
ROBE: "RXBE",
ROBO: "RXBO",
RUIN: "RXIN",
SENO: "SXNO",
TETA: "TXTA",
VACA: "VXCA",
VAGA: "VXGA",
VAGO: "VXGO",
VAKA: "VXKA",
VUEI: "VXEI",
VUEY: "VXEY",
WUEI: "WXEI",
WUEY: "WXEY"
};
var removeCompoundWords = (input) => {
const compoundWords = /\b(DA|DAS|DE|DEL|DER|DI|DIE|DD|EL|LA|LOS|LAS|LE|LES|MAC|MC|VAN|VON|Y)\b/gi;
return input.replace(compoundWords, "").replace(/\s+/g, " ").trim();
};
var getPrimaryName = (name) => {
const names = name.split(/\s+/);
if (names.length === 1) return names[0];
const isCommonName = COMMON_NAMES.some(
(commonName) => name.startsWith(commonName)
);
return isCommonName ? names[1] : names[0];
};
var replaceBadWords = (word) => {
return BAD_WORDS[word.toUpperCase()] || word;
};
var getSpecialChar = (birthYear) => {
return birthYear.startsWith("1") ? "0" : "A";
};
var calculateVerificationDigit = (incompleteCURP) => {
const characterSet = "0123456789ABCDEFGHIJKLMN\xD1OPQRSTUVWXYZ";
let sum = 0;
for (let i = 0; i < 17; i++) {
sum += characterSet.indexOf(incompleteCURP.charAt(i)) * (18 - i);
}
const verificationDigit = 10 - sum % 10;
return verificationDigit === 10 ? "0" : verificationDigit.toString();
};
// src/utils/index.ts
var normalizeString = (input) => {
return input.toLowerCase().trim().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
};
var replaceNonAlphabetic = (input, replacement = "X") => {
return input.replace(/[\d_\-./\\,]/g, replacement);
};
var findFirstConsonant = (input) => {
const internalConsonant = input.substring(1).replace(/[AEIOU]/gi, "").charAt(0).trim();
return internalConsonant === "" || internalConsonant === "\xD1" ? "X" : internalConsonant;
};
var isValidDate = (date) => {
if (typeof date === "string") {
const regex = /^\d{4}-\d{2}-\d{2}$/;
if (!regex.test(date)) return false;
const parsedDate = /* @__PURE__ */ new Date(`${date}T00:00:00Z`);
return parsedDate instanceof Date && !Number.isNaN(parsedDate.getTime()) && parsedDate.toISOString().startsWith(date);
}
if (typeof date === "number") {
const parsedDate = new Date(date);
return !Number.isNaN(parsedDate.getTime());
}
if (date instanceof Date) {
return !Number.isNaN(date.getTime());
}
return false;
};
var parseDate = (date) => {
const parsedDate = new Date(date instanceof Date ? date.getTime() : date);
const day = String(parsedDate.getUTCDate()).padStart(2, "0");
const month = String(parsedDate.getUTCMonth() + 1).padStart(2, "0");
const year = String(parsedDate.getUTCFullYear()).slice(-2);
const fullYear = String(parsedDate.getUTCFullYear());
return { day, month, year, fullYear };
};
// src/index.ts
var createCURP = (name, paternalSurname, gender, state, birthDate, maternalSurname = "") => {
var _a;
if (!isValidDate(birthDate)) {
throw new Error(
"The date of birth is an invalid date or is in an invalid format."
);
}
const cName = removeCompoundWords(normalizeString(name).toUpperCase());
const cPaternalSurname = removeCompoundWords(
normalizeString(paternalSurname).toUpperCase()
);
const cMaternalSurname = removeCompoundWords(
normalizeString(maternalSurname).toUpperCase()
);
const letterName = getPrimaryName(cName).charAt(0);
const vowelPaternalSurname = ((_a = cPaternalSurname.substring(1).match(/[AEIOU]/i)) == null ? void 0 : _a[0]) || "X";
const letterPaternalSurname = cPaternalSurname.charAt(0) === "\xD1" ? "X" : cPaternalSurname.charAt(0);
let letterMaternalSurname = cMaternalSurname.charAt(0) || "X";
letterMaternalSurname = letterMaternalSurname === "\xD1" ? "X" : letterMaternalSurname;
const firstCompositionJoin = [
letterPaternalSurname,
vowelPaternalSurname,
letterMaternalSurname,
letterName
].join("");
const firstComposition = replaceBadWords(
replaceNonAlphabetic(firstCompositionJoin)
);
const consonants = replaceNonAlphabetic(
[
findFirstConsonant(cPaternalSurname),
findFirstConsonant(cMaternalSurname),
findFirstConsonant(getPrimaryName(cName))
].join("")
);
const { day, month, year, fullYear } = parseDate(birthDate);
const incompleteCURP = [
firstComposition,
year,
month,
day,
GENDERS[gender],
STATES[state],
consonants,
getSpecialChar(fullYear)
].join("");
return [incompleteCURP, calculateVerificationDigit(incompleteCURP)].join("");
};
var validateCURP = (curp) => {
const regex = /^([A-Z][AEIOUX][A-Z]{2}\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])[HM](?:AS|B[CS]|C[CLMSH]|D[FG]|G[TR]|HG|JC|M[CNS]|N[ETL]|OC|PL|Q[TR]|S[PLR]|T[CSL]|VZ|YN|ZS)[B-DF-HJ-NP-TV-Z]{3}[A-Z\d])(\d)$/;
return regex.test(curp);
};
export {
createCURP,
validateCURP
};
//# sourceMappingURL=index.mjs.map