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.

1 lines 20.5 kB
{"version":3,"sources":["../src/core/modulo11.ts","../src/cnpj.ts","../src/cpf.ts","../src/adapters/class-validator.ts"],"names":["BLACKLIST","STRICT_STRIP_REGEX","LOOSE_STRIP_REGEX","STRICT_MASK_REGEX","strip","format","isValid","generate","registerDecorator"],"mappings":"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","file":"class-validator.cjs","sourcesContent":["// Algoritmo Módulo 11 da Receita Federal. Cada caractere é convertido pelo\n// valor ASCII menos 48 (0-9 → 0-9, A-Z → 17-42) e multiplicado pelos pesos\n// respectivos. CPF e CNPJ compartilham a etapa final (mod 11 → DV) mas\n// usam pesos distintos:\n// - CPF: pesos 2, 3, 4, ... crescendo da direita pra esquerda sem ciclo.\n// - CNPJ: pesos cíclicos 2, 3, ..., 9, 2, 3, ... da direita pra esquerda\n// (necessário por ter 12+ posições; definido na Nota Técnica RFB 49/2024).\n\n/**\n * Calcula o dígito verificador de um CPF usando o algoritmo Módulo 11\n * com pesos lineares crescentes.\n *\n * @param digits - String com 9 dígitos (para DV1) ou 10 dígitos (para DV2).\n * @returns Dígito verificador (0..9).\n */\nexport function cpfDigit(digits: string): number {\n let sum = 0\n const n = digits.length\n for (let i = n - 1; i >= 0; i--) {\n sum += (digits.charCodeAt(i) - 48) * (n - i + 1)\n }\n const mod = sum % 11\n return mod < 2 ? 0 : 11 - mod\n}\n\n/**\n * Calcula o dígito verificador de um CNPJ usando o algoritmo Módulo 11\n * com pesos cíclicos 2..9.\n *\n * Aceita tanto CNPJs puramente numéricos quanto no formato alfanumérico\n * da Nota Técnica RFB 49/2024 (letras A-Z convertidas via ASCII - 48).\n *\n * @param digits - String com 12 dígitos (para DV1) ou 13 dígitos (para DV2).\n * @returns Dígito verificador (0..9).\n */\nexport function cnpjDigit(digits: string): number {\n let sum = 0\n let weight = 2\n for (let i = digits.length - 1; i >= 0; i--) {\n sum += (digits.charCodeAt(i) - 48) * weight\n weight = weight === 9 ? 2 : weight + 1\n }\n const mod = sum % 11\n return mod < 2 ? 0 : 11 - mod\n}\n","import { cnpjDigit as verifierDigit } from './core/modulo11'\n\nconst BLACKLIST = new Set<string>([\n '00000000000000',\n '11111111111111',\n '22222222222222',\n '33333333333333',\n '44444444444444',\n '55555555555555',\n '66666666666666',\n '77777777777777',\n '88888888888888',\n '99999999999999'\n])\n\nconst STRICT_STRIP_REGEX = /[./-]/g\nconst LOOSE_STRIP_REGEX = /[^\\dA-Z]/g\nconst STRICT_MASK_REGEX =\n /^(?:[\\dA-Z]{2}\\.[\\dA-Z]{3}\\.[\\dA-Z]{3}\\/[\\dA-Z]{4}-\\d{2}|[\\dA-Z]{12}\\d{2})$/\nconst VALID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n\n/** Opções para `cnpj.generate()`. */\nexport interface GenerateOptions {\n /** Retorna o CNPJ com máscara `XX.XXX.XXX/XXXX-YY` quando `true`. */\n formatted?: boolean\n}\n\n/**\n * Remove caracteres de máscara e normaliza um CNPJ.\n *\n * Em modo padrão (loose), converte minúsculas para maiúsculas e remove\n * qualquer caractere que não seja dígito ou letra A-Z. Em modo strict,\n * remove apenas `.`, `/` e `-` (máscara oficial) sem normalizar o case.\n *\n * @param value - Entrada a ser normalizada.\n * @param strict - Se `true`, só remove os caracteres da máscara oficial.\n * @returns Apenas dígitos e letras A-Z remanescentes.\n */\nfunction strip(value: string, strict?: boolean): string {\n if (typeof value !== 'string') return ''\n const normalized = strict ? value : value.toUpperCase()\n const regex = strict ? STRICT_STRIP_REGEX : LOOSE_STRIP_REGEX\n return normalized.replace(regex, '')\n}\n\n/**\n * Aplica a máscara oficial `XX.XXX.XXX/XXXX-YY` no CNPJ (numérico ou\n * alfanumérico). Os 2 últimos caracteres (DVs) são sempre numéricos.\n *\n * @param value - CNPJ cru ou já formatado.\n * @returns CNPJ mascarado, ou entrada normalizada quando não casar com o\n * padrão de 14 posições.\n */\nfunction format(value: string): string {\n return strip(value).replace(\n /^([\\dA-Z]{2})([\\dA-Z]{3})([\\dA-Z]{3})([\\dA-Z]{4})(\\d{2})$/,\n '$1.$2.$3/$4-$5'\n )\n}\n\n/**\n * Valida um CNPJ verificando tamanho, lista negra, shape dos DVs e os\n * dois dígitos verificadores via Módulo 11.\n *\n * Aceita tanto CNPJs puramente numéricos (formato legado) quanto\n * alfanuméricos (novo formato da Nota Técnica RFB 49/2024 — vigência\n * obrigatória em julho/2026).\n *\n * @param value - CNPJ (cru, formatado ou com lixo, conforme `strict`).\n * @param strict - Se `true`, só aceita máscara canônica ou 14 caracteres\n * `[0-9A-Z]` sem normalização de case.\n * @returns `true` se o CNPJ é válido; `false` caso contrário.\n *\n * @example\n * ```ts\n * cnpj.isValid('54.550.752/0001-55') // true\n * cnpj.isValid('54550752000155') // true\n * cnpj.isValid('12ABC34501DE35') // true (novo formato RFB)\n * cnpj.isValid('12.ABC.345/01DE-35') // true\n * ```\n */\nfunction isValid(value: string, strict?: boolean): boolean {\n if (strict && (typeof value !== 'string' || !STRICT_MASK_REGEX.test(value))) {\n return false\n }\n const stripped = strip(value, strict)\n if (!stripped || stripped.length !== 14 || BLACKLIST.has(stripped)) {\n return false\n }\n // DVs (últimas 2 posições) devem ser numéricos pela regra da RFB.\n if (!/^\\d{2}$/.test(stripped.slice(-2))) {\n return false\n }\n\n let numbers = stripped.slice(0, 12)\n numbers += verifierDigit(numbers)\n numbers += verifierDigit(numbers)\n return numbers.slice(-2) === stripped.slice(-2)\n}\n\n/**\n * Gera um CNPJ alfanumérico matematicamente válido, seguindo o formato\n * da Nota Técnica RFB 49/2024.\n *\n * @param options - Boolean legado (apenas `formatted`) ou objeto de opções.\n * @returns CNPJ gerado com 14 caracteres (12 alfanuméricos + 2 DVs\n * numéricos) ou a máscara oficial.\n *\n * @example\n * ```ts\n * cnpj.generate() // '58A0Z919U001O6'\n * cnpj.generate(true) // '58.A0Z.919/U001-O6' (nope — DVs sempre numéricos)\n * cnpj.generate({ formatted: true }) // '58.A0Z.919/U001-06'\n * ```\n */\nfunction generate(options?: boolean | GenerateOptions): string {\n const opts: GenerateOptions =\n typeof options === 'boolean' ? { formatted: options } : (options ?? {})\n\n let numbers = ''\n for (let i = 0; i < 12; i++) {\n numbers += VALID_CHARS.charAt(Math.floor(Math.random() * VALID_CHARS.length))\n }\n numbers += verifierDigit(numbers)\n numbers += verifierDigit(numbers)\n return opts.formatted ? format(numbers) : numbers\n}\n\nexport { format, generate, isValid, strip, verifierDigit }\nexport default { verifierDigit, strip, format, isValid, generate }\n","import { cpfDigit as verifierDigit } from './core/modulo11'\n\nconst BLACKLIST = new Set<string>([\n '00000000000',\n '11111111111',\n '22222222222',\n '33333333333',\n '44444444444',\n '55555555555',\n '66666666666',\n '77777777777',\n '88888888888',\n '99999999999',\n '12345678909'\n])\n\nconst STRICT_STRIP_REGEX = /[.-]/g\nconst LOOSE_STRIP_REGEX = /[^\\d]/g\nconst STRICT_MASK_REGEX = /^(?:\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}|\\d{11})$/\n\n/**\n * Mapa dos 27 UFs brasileiros para seus dígitos de Região Fiscal da\n * Receita Federal (0..9), codificados na 9ª posição do CPF.\n *\n * @example\n * ```ts\n * FISCAL_REGION_BY_UF.SP // 8 (São Paulo — 8ª Região Fiscal)\n * FISCAL_REGION_BY_UF.RS // 0 (Rio Grande do Sul — 10ª Região Fiscal)\n * ```\n */\nexport const FISCAL_REGION_BY_UF = {\n DF: 1,\n GO: 1,\n MS: 1,\n MT: 1,\n TO: 1,\n AC: 2,\n AM: 2,\n AP: 2,\n PA: 2,\n RO: 2,\n RR: 2,\n CE: 3,\n MA: 3,\n PI: 3,\n AL: 4,\n PB: 4,\n PE: 4,\n RN: 4,\n BA: 5,\n SE: 5,\n MG: 6,\n ES: 7,\n RJ: 7,\n SP: 8,\n PR: 9,\n SC: 9,\n RS: 0\n} as const\n\n/** Unidade da Federação — um dos 26 estados brasileiros ou DF. */\nexport type UF = keyof typeof FISCAL_REGION_BY_UF\n\n/** Opções para `cpf.generate()`. */\nexport interface GenerateOptions {\n /** Retorna o CPF com máscara `XXX.XXX.XXX-XX` quando `true`. */\n formatted?: boolean\n /** UF de emissão — controla o dígito da Região Fiscal (9ª posição). */\n state?: UF\n}\n\n/**\n * Remove caracteres de máscara e normaliza um CPF.\n *\n * @param value - Entrada a ser normalizada.\n * @param strict - Se `true`, remove apenas `.` e `-`. Se `false` ou omitido,\n * remove qualquer caractere não numérico.\n * @returns Apenas os dígitos remanescentes.\n */\nfunction strip(value: string, strict?: boolean): string {\n if (typeof value !== 'string') return ''\n const regex = strict ? STRICT_STRIP_REGEX : LOOSE_STRIP_REGEX\n return value.replace(regex, '')\n}\n\n/**\n * Aplica a máscara oficial `XXX.XXX.XXX-XX` no CPF.\n *\n * @param value - CPF cru ou já formatado.\n * @returns O CPF com máscara, ou a entrada normalizada quando não casar\n * com o padrão de 11 dígitos.\n */\nfunction format(value: string): string {\n return strip(value).replace(/^(\\d{3})(\\d{3})(\\d{3})(\\d{2})$/, '$1.$2.$3-$4')\n}\n\n/**\n * Valida um CPF verificando tamanho, lista negra e os dois dígitos\n * verificadores via Módulo 11.\n *\n * @param value - CPF (cru, formatado ou com lixo, conforme `strict`).\n * @param strict - Se `true`, só aceita máscara canônica `XXX.XXX.XXX-XX`\n * ou 11 dígitos puros. Se `false` ou omitido, remove qualquer lixo.\n * @returns `true` se o CPF é válido; `false` caso contrário.\n *\n * @example\n * ```ts\n * cpf.isValid('295.379.955-93') // true\n * cpf.isValid('29537995593') // true\n * cpf.isValid('00000000000') // false (blacklist)\n * ```\n */\nfunction isValid(value: string, strict?: boolean): boolean {\n if (strict && (typeof value !== 'string' || !STRICT_MASK_REGEX.test(value))) {\n return false\n }\n const stripped = strip(value, strict)\n if (!stripped || stripped.length !== 11 || BLACKLIST.has(stripped)) {\n return false\n }\n\n let numbers = stripped.slice(0, 9)\n numbers += verifierDigit(numbers)\n numbers += verifierDigit(numbers)\n return numbers.slice(-2) === stripped.slice(-2)\n}\n\n/**\n * Gera um CPF matematicamente válido, opcionalmente formatado ou\n * vinculado a uma UF específica (via Região Fiscal da RFB).\n *\n * @param options - Boolean legado (apenas `formatted`) ou objeto com\n * `formatted` e/ou `state`. Quando `state` é informado, a 9ª posição\n * recebe o dígito da Região Fiscal correspondente.\n * @returns CPF gerado, com 11 dígitos crus ou a máscara oficial.\n * @throws {TypeError} Se `options.state` for informado mas não for um UF\n * conhecido.\n *\n * @example\n * ```ts\n * cpf.generate() // '32564428777'\n * cpf.generate(true) // '325.644.287-77'\n * cpf.generate({ state: 'SP' }) // '...8??' (8ª posição = RF SP)\n * cpf.generate({ formatted: true, state: 'SP' }) // '325.644.287-77' (9ª = '8')\n * ```\n */\nfunction generate(options?: boolean | GenerateOptions): string {\n const opts: GenerateOptions =\n typeof options === 'boolean' ? { formatted: options } : (options ?? {})\n\n let numbers = ''\n for (let i = 0; i < 8; i++) {\n numbers += Math.floor(Math.random() * 10)\n }\n\n if (opts.state !== undefined) {\n if (!Object.hasOwn(FISCAL_REGION_BY_UF, opts.state)) {\n throw new TypeError(\n `UF '${opts.state}' desconhecida — use uma das: ${Object.keys(FISCAL_REGION_BY_UF).join(', ')}`\n )\n }\n numbers += FISCAL_REGION_BY_UF[opts.state]\n } else {\n numbers += Math.floor(Math.random() * 10)\n }\n\n numbers += verifierDigit(numbers)\n numbers += verifierDigit(numbers)\n return opts.formatted ? format(numbers) : numbers\n}\n\nexport { format, generate, isValid, strip, verifierDigit }\nexport default { verifierDigit, strip, format, isValid, generate, FISCAL_REGION_BY_UF }\n","import { registerDecorator, type ValidationOptions } from 'class-validator'\nimport cnpj from '../cnpj'\nimport cpf from '../cpf'\n\n/**\n * Decorator de propriedade que valida um CPF via class-validator.\n * Padrão idiomático em NestJS + DTOs.\n *\n * Requer `reflect-metadata` importado no bootstrap da aplicação e as\n * flags `experimentalDecorators` + `emitDecoratorMetadata` no tsconfig.\n *\n * @param options - `ValidationOptions` padrão do class-validator\n * (message, each, groups, always, context).\n *\n * @example\n * ```ts\n * import 'reflect-metadata'\n * import { IsCPF } from 'cpf-cnpj-validator/class-validator'\n *\n * class UserDTO {\n * @IsCPF({ message: 'CPF deve ser válido' })\n * cpf!: string\n * }\n * ```\n */\nexport function IsCPF(options?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n name: 'IsCPF',\n target: target.constructor,\n propertyName: propertyName as string,\n options: { message: 'CPF inválido', ...options },\n validator: {\n validate(value: unknown) {\n return typeof value === 'string' && cpf.isValid(value)\n }\n }\n })\n }\n}\n\n/**\n * Decorator de propriedade que valida um CNPJ via class-validator.\n * Aceita tanto CNPJs numéricos legados quanto o novo formato\n * alfanumérico da Nota Técnica RFB 49/2024.\n *\n * Requer `reflect-metadata` importado no bootstrap da aplicação e as\n * flags `experimentalDecorators` + `emitDecoratorMetadata` no tsconfig.\n *\n * @param options - `ValidationOptions` padrão do class-validator.\n *\n * @example\n * ```ts\n * import 'reflect-metadata'\n * import { IsCNPJ } from 'cpf-cnpj-validator/class-validator'\n *\n * class CompanyDTO {\n * @IsCNPJ()\n * cnpj!: string // aceita '12.ABC.345/01DE-35'\n * }\n * ```\n */\nexport function IsCNPJ(options?: ValidationOptions): PropertyDecorator {\n return (target, propertyName) => {\n registerDecorator({\n name: 'IsCNPJ',\n target: target.constructor,\n propertyName: propertyName as string,\n options: { message: 'CNPJ inválido', ...options },\n validator: {\n validate(value: unknown) {\n return typeof value === 'string' && cnpj.isValid(value)\n }\n }\n })\n }\n}\n"]}