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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@useblu/utils",
"version": "1.2.2",
"version": "1.2.3",
"private": false,
"license": "MIT",
"main": "lib/index.js",
Expand Down
13 changes: 3 additions & 10 deletions src/masks/maskBankAccount.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import VMasker from 'vanilla-masker';
import {
BANK_ACCOUNT_MASKS,
DEFAULT_BANK_ACCOUNT_MASK,
ALPHANUMERIC_BANK_CODES,
} from './masks';
import { stripAlphanumeric, stripNumeric } from './strip';
import { BANK_ACCOUNT_MASKS, DEFAULT_BANK_ACCOUNT_MASK } from './masks';
import { stripNumeric } from './strip';
import type { BankCompensationCode } from './types';

export default function maskBankAccount(
Expand All @@ -15,9 +11,6 @@ export default function maskBankAccount(

const code = compensationCode as BankCompensationCode;
const pattern = BANK_ACCOUNT_MASKS[code] ?? DEFAULT_BANK_ACCOUNT_MASK;
const stripped = ALPHANUMERIC_BANK_CODES.includes(code)
? stripAlphanumeric(String(value))
: stripNumeric(String(value));

return VMasker.toPattern(stripped, pattern);
return VMasker.toPattern(stripNumeric(String(value)), pattern);
}
11 changes: 6 additions & 5 deletions src/masks/maskBankBranch.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import VMasker from 'vanilla-masker';
import { BANK_BRANCH_MASKS, DEFAULT_BANK_BRANCH_MASK } from './masks';
import { DEFAULT_BANK_BRANCH_MASK } from './masks';
import { stripNumeric } from './strip';
import type { BankCompensationCode } from './types';

export default function maskBankBranch(
value: string | null | undefined,
// Mantido por compatibilidade de API e simetria com maskBankAccount: a
// agência usa sempre 4 dígitos, independente do banco (o DV, quando há, é
// calculado pelo backend).
// eslint-disable-next-line @typescript-eslint/no-unused-vars
compensationCode?: string,
): string {
if (value === null || value === undefined || value === '') return '';

const stripped = stripNumeric(String(value));
const pattern = BANK_BRANCH_MASKS[compensationCode as BankCompensationCode]
?? DEFAULT_BANK_BRANCH_MASK;

return VMasker.toPattern(stripped, pattern);
return VMasker.toPattern(stripped, DEFAULT_BANK_BRANCH_MASK);
}
16 changes: 2 additions & 14 deletions src/masks/maskComplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import {
MASKS,
DEFAULT_BANK_BRANCH_MASK,
DEFAULT_BANK_ACCOUNT_MASK,
BANK_BRANCH_MASKS,
BANK_ACCOUNT_MASKS,
ALPHANUMERIC_BANK_CODES,
} from './masks';
import { stripAlphanumeric, stripNumeric, PATTERN_PLACEHOLDER_REGEX } from './strip';
import type { MaskType, BankCompensationCode } from './types';
Expand All @@ -31,13 +29,7 @@ const patternFor = (
case 'barCodeUtilities': return MASKS.BAR_CODE_UTILITIES;
case 'darf': return MASKS.DARF;
case 'number': return MASKS.NUMBER;
case 'bank_branch': {
if (compensationCode) {
const mapped = BANK_BRANCH_MASKS[compensationCode as BankCompensationCode];
if (mapped) return mapped;
}
return DEFAULT_BANK_BRANCH_MASK;
}
case 'bank_branch': return DEFAULT_BANK_BRANCH_MASK;
case 'bank_account': {
if (compensationCode) {
const mapped = BANK_ACCOUNT_MASKS[compensationCode as BankCompensationCode];
Expand Down Expand Up @@ -76,11 +68,7 @@ export default function maskComplete(

const expected = placeholdersInPattern(pattern);

const isAlphanumeric = ALPHANUMERIC_MASKS.includes(type)
|| (
(type === 'bank_account' || type === 'bank_branch')
&& ALPHANUMERIC_BANK_CODES.includes(compensationCode as BankCompensationCode)
);
const isAlphanumeric = ALPHANUMERIC_MASKS.includes(type);

const stripped = isAlphanumeric
? stripAlphanumeric(value)
Expand Down
22 changes: 3 additions & 19 deletions src/masks/maskValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import {
PERCENTAGE_MASK_DEFAULTS,
DEFAULT_BANK_BRANCH_MASK,
DEFAULT_BANK_ACCOUNT_MASK,
BANK_BRANCH_MASKS,
BANK_ACCOUNT_MASKS,
ALPHANUMERIC_BANK_CODES,
} from './masks';
import { stripAlphanumeric, stripNumeric } from './strip';
import type { MaskType, CurrencyMaskOptions, BankCompensationCode } from './types';
Expand All @@ -23,25 +21,11 @@ export interface MaskValueOptions extends CurrencyMaskOptions {

const ALPHANUMERIC_MASKS: ReadonlyArray<MaskType> = ['cnpj', 'cpf_cnpj'];

const stripFor = (value: string, type: MaskType, compensationCode?: string): string => {
const stripFor = (value: string, type: MaskType): string => {
if (ALPHANUMERIC_MASKS.includes(type)) return stripAlphanumeric(value);
if (
(type === 'bank_account' || type === 'bank_branch')
&& ALPHANUMERIC_BANK_CODES.includes(compensationCode as BankCompensationCode)
) {
return stripAlphanumeric(value);
}
return stripNumeric(value);
};

const bankBranchPattern = (code?: string): string => {
if (code) {
const mapped = BANK_BRANCH_MASKS[code as BankCompensationCode];
if (mapped) return mapped;
}
return DEFAULT_BANK_BRANCH_MASK;
};

const bankAccountPattern = (code?: string): string => {
if (code) {
const mapped = BANK_ACCOUNT_MASKS[code as BankCompensationCode];
Expand Down Expand Up @@ -71,7 +55,7 @@ const patternFor = (
case 'barCodeUtilities': return MASKS.BAR_CODE_UTILITIES;
case 'darf': return MASKS.DARF;
case 'number': return MASKS.NUMBER;
case 'bank_branch': return bankBranchPattern(compensationCode);
case 'bank_branch': return DEFAULT_BANK_BRANCH_MASK;
case 'bank_account': return bankAccountPattern(compensationCode);
default: return '';
}
Expand All @@ -94,7 +78,7 @@ export default function maskValue(
return VMasker.toMoney(stringValue, { ...PERCENTAGE_MASK_DEFAULTS, ...(options || {}) });
}

const stripped = stripFor(stringValue, type, options?.compensationCode);
const stripped = stripFor(stringValue, type);
const pattern = patternFor(type, stripped, options?.compensationCode);

if (!pattern) return stringValue;
Expand Down
16 changes: 7 additions & 9 deletions src/masks/masks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,18 @@ export const PERCENTAGE_MASK_DEFAULTS: CurrencyMaskOptions = {
zeroCents: false,
};

export const BANK_BRANCH_MASKS: Partial<Record<BankCompensationCode, string>> = {
341: '99999-9',
};

// Toda agência bancária é informada com 4 dígitos no frontend; quando há DV
// na agência (BB, Banrisul, Bradesco, Arbi) ele é calculado/validado pelo
// backend a partir desses 4 dígitos. Por isso a agência não tem máscara por
// banco — todos usam este default.
export const DEFAULT_BANK_BRANCH_MASK = '9999';

export const ALPHANUMERIC_BANK_CODES: ReadonlyArray<BankCompensationCode> = ['1'];

export const BANK_ACCOUNT_MASKS: Partial<Record<BankCompensationCode, string>> = {
1: '99999999-S',
1: '99999999-9',
33: '99999999-9',
41: '999999999-9',
104: '999999999999-9',
213: '9999999-9',
104: '999999999-9',
213: '99999-9',
237: '9999999-9',
341: '99999-9',
399: '999999-9',
Expand Down
12 changes: 8 additions & 4 deletions tests/masks/maskBankAccount.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ describe('maskBankAccount', () => {
test('formata conta com dígito', () => {
expect(maskBankAccount('123456789', '1')).toBe('12345678-9');
});

test('DV é numérico: caractere não numérico é removido', () => {
expect(maskBankAccount('12345678X', '1')).toBe('12345678');
});
});

describe('Santander (33)', () => {
Expand All @@ -28,8 +32,8 @@ describe('maskBankAccount', () => {
});

describe('CEF (104)', () => {
test('formata conta longa com dígito', () => {
expect(maskBankAccount('1234567890123', '104')).toBe('123456789012-3');
test('formata conta com dígito (9 dígitos, sem operação)', () => {
expect(maskBankAccount('1234567890123', '104')).toBe('123456789-0');
});
});

Expand All @@ -51,9 +55,9 @@ describe('maskBankAccount', () => {
});
});

describe('Banco Original (213)', () => {
describe('Arbi (213)', () => {
test('formata conta com dígito', () => {
expect(maskBankAccount('12345678', '213')).toBe('1234567-8');
expect(maskBankAccount('12345678', '213')).toBe('12345-6');
});
});

Expand Down
6 changes: 3 additions & 3 deletions tests/masks/maskBankBranch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ describe('maskBankBranch', () => {
expect(maskBankBranch('1234', '33')).toBe('1234');
});

test('agência Itaú (341) com dígito verificador', () => {
expect(maskBankBranch('123456', '341')).toBe('12345-6');
test('agência Itaú (341) tem 4 dígitos sem DV', () => {
expect(maskBankBranch('123456', '341')).toBe('1234');
});

test('agência Itaú (341) parcial', () => {
test('agência Itaú (341) com 4 dígitos', () => {
expect(maskBankBranch('1234', '341')).toBe('1234');
});

Expand Down
10 changes: 5 additions & 5 deletions tests/masks/maskComplete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ describe('maskComplete', () => {
expect(maskComplete('12', 'bank_branch')).toBe(false);
});

test('bank_branch completo com compensationCode Itaú (341)', () => {
expect(maskComplete('123456', 'bank_branch', '341')).toBe(true);
test('bank_branch completo com compensationCode Itaú (341) são 4 dígitos', () => {
expect(maskComplete('1234', 'bank_branch', '341')).toBe(true);
});

test('bank_branch incompleto com compensationCode Itaú (341)', () => {
expect(maskComplete('1234', 'bank_branch', '341')).toBe(false);
expect(maskComplete('12', 'bank_branch', '341')).toBe(false);
});

test('bank_account completo (noop 12+1 dígitos)', () => {
Expand All @@ -83,8 +83,8 @@ describe('maskComplete', () => {
expect(maskComplete('123456789', 'bank_account', { compensationCode: '1' })).toBe(true);
});

test('bank_account completo com DV alfanumérico BB (1)', () => {
expect(maskComplete('12345678X', 'bank_account', { compensationCode: '1' })).toBe(true);
test('bank_account BB (1) com DV não numérico não conta como completo', () => {
expect(maskComplete('12345678X', 'bank_account', { compensationCode: '1' })).toBe(false);
});

test('bank_account incompleto com compensationCode BB (1)', () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/masks/maskHintBankAccount.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('maskHintBankAccount', () => {
});

test('CEF (104)', () => {
expect(maskHintBankAccount('104')).toBe('000000000000-0');
expect(maskHintBankAccount('104')).toBe('000000000-0');
});

test('código desconhecido retorna placeholder default (noop)', () => {
Expand Down
10 changes: 5 additions & 5 deletions tests/masks/maskValue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ describe('maskValue', () => {
test('strip de caracteres não numéricos', () => {
expect(maskValue('12-34', 'bank_branch')).toBe('1234');
});
test('com compensationCode Itaú (341) usa padrão 99999-9', () => {
expect(maskValue('123456', 'bank_branch', { compensationCode: '341' })).toBe('12345-6');
test('com compensationCode Itaú (341) usa 4 dígitos (sem DV)', () => {
expect(maskValue('123456', 'bank_branch', { compensationCode: '341' })).toBe('1234');
});
test('com compensationCode desconhecido usa padrão noop', () => {
expect(maskValue('1234', 'bank_branch', { compensationCode: '999' })).toBe('1234');
Expand All @@ -109,11 +109,11 @@ describe('maskValue', () => {
test('strip de separadores antes de aplicar', () => {
expect(maskValue('123456789012-3', 'bank_account')).toBe('123456789012-3');
});
test('com compensationCode BB (1) usa padrão 99999999-S', () => {
test('com compensationCode BB (1) usa padrão 99999999-9', () => {
expect(maskValue('123456789', 'bank_account', { compensationCode: '1' })).toBe('12345678-9');
});
test('com compensationCode BB (1) preserva DV alfanumérico', () => {
expect(maskValue('12345678X', 'bank_account', { compensationCode: '1' })).toBe('12345678-X');
test('com compensationCode BB (1) usa DV numérico (X é removido)', () => {
expect(maskValue('12345678X', 'bank_account', { compensationCode: '1' })).toBe('12345678');
});
test('com compensationCode Bradesco (237) usa padrão 9999999-9', () => {
expect(maskValue('12345678', 'bank_account', { compensationCode: '237' })).toBe('1234567-8');
Expand Down
Loading