Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export { default as normalizeSocialNumber } from './normalizers/normalizeSocialN
// utils
export { default as maskString } from './utils/maskString';
export { default as stripNumbers } from './utils/stripNumbers';
export { default as stripCpfCnpj } from './utils/stripCpfCnpj';
export { default as getStates } from './utils/getStates';
export { default as snakeToCamel } from './utils/snakeToCamel';
export { default as camelToSnake } from './utils/camelToSnake';
Expand Down
25 changes: 25 additions & 0 deletions src/utils/stripCpfCnpj.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { stripAlphanumeric } from '../masks/strip';

/**
* Sanitiza um CPF/CNPJ removendo os separadores da máscara (qualquer caractere
* não-alfanumérico: `.`, `/`, `-`, espaços) e normalizando para upper-case,
* **preservando as letras** do CNPJ alfanumérico (Receita Federal —
* Nota Técnica NT 49/2024, vigente a partir de 2026).
*
* Use no lugar de `stripNumbers` / `value.replace(/\D/g, '')` em qualquer fluxo
* de CNPJ (validação, envio, lookup, navegação): essas abordagens descartam as
* letras A–Z e transformam um CNPJ alfanumérico válido em um identificador
* inválido.
*
* É o inverso de {@link normalizeCpfOrCnpj} (que aplica a máscara visual).
*
* @example
* stripCpfCnpj('824.007.050-70'); // '82400705070' (CPF)
* stripCpfCnpj('12.345.678/0001-95'); // '12345678000195' (CNPJ numérico)
* stripCpfCnpj('AB.345.678/XY01-74'); // 'AB345678XY0174' (CNPJ alfanumérico)
* stripCpfCnpj('ab.345.678/xy01-74'); // 'AB345678XY0174' (normaliza upper-case)
* stripCpfCnpj(undefined); // ''
*/
export default function stripCpfCnpj(value?: string): string {
return stripAlphanumeric(value ?? '');
}
32 changes: 32 additions & 0 deletions tests/stripCpfCnpj.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'jest';

import { stripCpfCnpj } from '../src';

describe('stripCpfCnpj', () => {
test('CPF mascarado → apenas dígitos', () => {
expect(stripCpfCnpj('824.007.050-70')).toBe('82400705070');
});

test('CNPJ numérico mascarado → apenas dígitos', () => {
expect(stripCpfCnpj('12.345.678/0001-95')).toBe('12345678000195');
});

// RFB NT 49/2024 — as letras fazem parte do identificador e não podem ser
// descartadas (o que aconteceria com stripNumbers / /\D/g).
test('CNPJ alfanumérico preserva as letras', () => {
expect(stripCpfCnpj('AB.345.678/XY01-74')).toBe('AB345678XY0174');
});

test('CNPJ alfanumérico minúsculo é normalizado para upper-case', () => {
expect(stripCpfCnpj('ab.345.678/xy01-74')).toBe('AB345678XY0174');
});

test('valor já sem máscara é idempotente', () => {
expect(stripCpfCnpj('AB345678XY0174')).toBe('AB345678XY0174');
});

test('undefined / vazio → string vazia', () => {
expect(stripCpfCnpj(undefined)).toBe('');
expect(stripCpfCnpj('')).toBe('');
});
});
Loading