UNPKG

cpf-cnpj-validator

Version:

Valida, formata e gera strings de CPF ou CNPJ, com suporte ao novo formato alfanumérico da RFB e adapters para joi, yup e zod.

184 lines (180 loc) • 5.11 kB
// src/core/modulo11.ts function cpfDigit(digits) { let sum = 0; const n = digits.length; for (let i = n - 1; i >= 0; i--) { sum += (digits.charCodeAt(i) - 48) * (n - i + 1); } const mod = sum % 11; return mod < 2 ? 0 : 11 - mod; } function cnpjDigit(digits) { let sum = 0; let weight = 2; for (let i = digits.length - 1; i >= 0; i--) { sum += (digits.charCodeAt(i) - 48) * weight; weight = weight === 9 ? 2 : weight + 1; } const mod = sum % 11; return mod < 2 ? 0 : 11 - mod; } // src/cnpj.ts var BLACKLIST = /* @__PURE__ */ new Set([ "00000000000000", "11111111111111", "22222222222222", "33333333333333", "44444444444444", "55555555555555", "66666666666666", "77777777777777", "88888888888888", "99999999999999" ]); var STRICT_STRIP_REGEX = /[./-]/g; var LOOSE_STRIP_REGEX = /[^\dA-Z]/g; var STRICT_MASK_REGEX = /^(?:[\dA-Z]{2}\.[\dA-Z]{3}\.[\dA-Z]{3}\/[\dA-Z]{4}-\d{2}|[\dA-Z]{12}\d{2})$/; var VALID_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; function strip(value, strict) { if (typeof value !== "string") return ""; const normalized = strict ? value : value.toUpperCase(); const regex = strict ? STRICT_STRIP_REGEX : LOOSE_STRIP_REGEX; return normalized.replace(regex, ""); } function format(value) { return strip(value).replace( /^([\dA-Z]{2})([\dA-Z]{3})([\dA-Z]{3})([\dA-Z]{4})(\d{2})$/, "$1.$2.$3/$4-$5" ); } function isValid(value, strict) { if (strict && (typeof value !== "string" || !STRICT_MASK_REGEX.test(value))) { return false; } const stripped = strip(value, strict); if (!stripped || stripped.length !== 14 || BLACKLIST.has(stripped)) { return false; } if (!/^\d{2}$/.test(stripped.slice(-2))) { return false; } let numbers = stripped.slice(0, 12); numbers += cnpjDigit(numbers); numbers += cnpjDigit(numbers); return numbers.slice(-2) === stripped.slice(-2); } function generate(options) { const opts = typeof options === "boolean" ? { formatted: options } : options ?? {}; let numbers = ""; for (let i = 0; i < 12; i++) { numbers += VALID_CHARS.charAt(Math.floor(Math.random() * VALID_CHARS.length)); } numbers += cnpjDigit(numbers); numbers += cnpjDigit(numbers); return opts.formatted ? format(numbers) : numbers; } var cnpj_default = { verifierDigit: cnpjDigit, strip, format, isValid, generate }; // src/cpf.ts var BLACKLIST2 = /* @__PURE__ */ new Set([ "00000000000", "11111111111", "22222222222", "33333333333", "44444444444", "55555555555", "66666666666", "77777777777", "88888888888", "99999999999", "12345678909" ]); var STRICT_STRIP_REGEX2 = /[.-]/g; var LOOSE_STRIP_REGEX2 = /[^\d]/g; var STRICT_MASK_REGEX2 = /^(?:\d{3}\.\d{3}\.\d{3}-\d{2}|\d{11})$/; var FISCAL_REGION_BY_UF = { DF: 1, GO: 1, MS: 1, MT: 1, TO: 1, AC: 2, AM: 2, AP: 2, PA: 2, RO: 2, RR: 2, CE: 3, MA: 3, PI: 3, AL: 4, PB: 4, PE: 4, RN: 4, BA: 5, SE: 5, MG: 6, ES: 7, RJ: 7, SP: 8, PR: 9, SC: 9, RS: 0 }; function strip2(value, strict) { if (typeof value !== "string") return ""; const regex = strict ? STRICT_STRIP_REGEX2 : LOOSE_STRIP_REGEX2; return value.replace(regex, ""); } function format2(value) { return strip2(value).replace(/^(\d{3})(\d{3})(\d{3})(\d{2})$/, "$1.$2.$3-$4"); } function isValid2(value, strict) { if (strict && (typeof value !== "string" || !STRICT_MASK_REGEX2.test(value))) { return false; } const stripped = strip2(value, strict); if (!stripped || stripped.length !== 11 || BLACKLIST2.has(stripped)) { return false; } let numbers = stripped.slice(0, 9); numbers += cpfDigit(numbers); numbers += cpfDigit(numbers); return numbers.slice(-2) === stripped.slice(-2); } function generate2(options) { const opts = typeof options === "boolean" ? { formatted: options } : options ?? {}; let numbers = ""; for (let i = 0; i < 8; i++) { numbers += Math.floor(Math.random() * 10); } if (opts.state !== void 0) { if (!Object.hasOwn(FISCAL_REGION_BY_UF, opts.state)) { throw new TypeError( `UF '${opts.state}' desconhecida \u2014 use uma das: ${Object.keys(FISCAL_REGION_BY_UF).join(", ")}` ); } numbers += FISCAL_REGION_BY_UF[opts.state]; } else { numbers += Math.floor(Math.random() * 10); } numbers += cpfDigit(numbers); numbers += cpfDigit(numbers); return opts.formatted ? format2(numbers) : numbers; } var cpf_default = { verifierDigit: cpfDigit, strip: strip2, format: format2, isValid: isValid2, generate: generate2, FISCAL_REGION_BY_UF }; // src/adapters/angular.ts var cpfValidator = () => (control) => { const value = control.value; return !value || cpf_default.isValid(value) ? null : { cpf: value }; }; var cnpjValidator = () => (control) => { const value = control.value; return !value || cnpj_default.isValid(value) ? null : { cnpj: value }; }; var AngularValidator = class { static cpf = cpfValidator(); static cnpj = cnpjValidator(); }; export { AngularValidator, cnpjValidator, cpfValidator }; //# sourceMappingURL=angular.js.map //# sourceMappingURL=angular.js.map