From 068b8866d3137560b48968eae03a92a9717388d7 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 15:53:38 -0300 Subject: [PATCH 01/15] Cria formatador de CPF --- src/formatters/cpf.ts | 23 +++++++++++++++++++++++ tests/cpf.test.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/formatters/cpf.ts create mode 100644 tests/cpf.test.ts diff --git a/src/formatters/cpf.ts b/src/formatters/cpf.ts new file mode 100644 index 0000000..3a5363b --- /dev/null +++ b/src/formatters/cpf.ts @@ -0,0 +1,23 @@ +const maskCpf = (value: string) => { + if (!value) { + return ''; + } + + const cpf = value.replace(/\D/g, ''); + + if (cpf.length === 11) { + return `${cpf.substring(0, 3)}.${cpf.substring(3, 6)}.${cpf.substring(6, 9)}-${cpf.substring(9, 11)}`; + } + + return cpf; +}; + +const removeCpfMask = (value: string) => { + if (!value) { + return ''; + } + + return value.replace(/\D/g, ''); +}; + +export { maskCpf, removeCpfMask }; diff --git a/tests/cpf.test.ts b/tests/cpf.test.ts new file mode 100644 index 0000000..fae7a13 --- /dev/null +++ b/tests/cpf.test.ts @@ -0,0 +1,30 @@ +import { describe, test, expect } from 'vitest'; +import { maskCpf, removeCpfMask } from '../src/formatters/cpf'; + +describe('maskCpf', () => { + test('deve formatar cpf', () => { + expect(maskCpf('11111111111')).toBe('111.111.111-11'); + }); + + test('deve retornar string vazia quando cpf é vazio', () => { + expect(maskCpf('')).toBe(''); + }); + + test('deve retornar valor como está quando cpf é inválido', () => { + expect(maskCpf('1234567890')).toBe('1234567890'); + }); +}); + +describe('removeCpfMask', () => { + test('deve remover máscara de cpf', () => { + expect(removeCpfMask('111.111.111-11')).toBe('11111111111'); + }); + + test('deve retornar string vazia quando cpf é vazio', () => { + expect(removeCpfMask('')).toBe(''); + }); + + test('deve retornar valor como está quando cpf é inválido', () => { + expect(removeCpfMask('1234567890')).toBe('1234567890'); + }); +}); From 835b40e905627f8b5235bfaf41603d7d2041114a Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 15:56:44 -0300 Subject: [PATCH 02/15] Cria validador de telefone --- src/formatters/phone.ts | 26 +++++++++++++ tests/phone.test.ts | 84 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/formatters/phone.ts create mode 100644 tests/phone.test.ts diff --git a/src/formatters/phone.ts b/src/formatters/phone.ts new file mode 100644 index 0000000..f95b3be --- /dev/null +++ b/src/formatters/phone.ts @@ -0,0 +1,26 @@ +const maskPhone = (value: string) => { + if (!value || value.length === 0) { + return ''; + } + + const phone = value.replace(/[^0-9]+/g, ''); + + if (phone.length === 11) { + return `(${phone.substring(0, 2)}) ${phone.substring(2, 7)}-${phone.substring(7, 11)}`; + } + + if (phone.length === 10) { + return `(${phone.substring(0, 2)}) ${phone.substring(2, 6)}-${phone.substring(6, 10)}`; + } + return phone; +}; + +const removePhoneMask = (value: string) => { + if (!value || value.length === 0) { + return ''; + } + + return value.replace(/\(|\)|-|\s/g, ''); +}; + +export { maskPhone, removePhoneMask }; diff --git a/tests/phone.test.ts b/tests/phone.test.ts new file mode 100644 index 0000000..7a7705b --- /dev/null +++ b/tests/phone.test.ts @@ -0,0 +1,84 @@ +import { describe, test, expect } from 'vitest'; +import { maskPhone, removePhoneMask } from '../src/formatters/phone'; + +describe('maskPhone', () => { + test('deve formatar número de telefone com 11 dígitos (com 9)', () => { + expect(maskPhone('11987654321')).toBe('(11) 98765-4321'); + }); + + test('deve formatar número de telefone com 10 dígitos (sem 9)', () => { + expect(maskPhone('1187654321')).toBe('(11) 8765-4321'); + }); + + test('deve retornar string vazia quando o telefone é vazio', () => { + expect(maskPhone('')).toBe(''); + }); + + test('deve retornar string vazia quando o telefone é nulo/undefined', () => { + expect(maskPhone(null as any)).toBe(''); + expect(maskPhone(undefined as any)).toBe(''); + }); + + test('deve retornar apenas dígitos quando o telefone tem comprimento inválido', () => { + expect(maskPhone('123456789')).toBe('123456789'); + expect(maskPhone('123456789012')).toBe('123456789012'); + }); + + test('deve remover caracteres não numéricos antes de formatar', () => { + expect(maskPhone('(11) 98765-4321')).toBe('(11) 98765-4321'); + expect(maskPhone('11.98765.4321')).toBe('(11) 98765-4321'); + expect(maskPhone('11 98765 4321')).toBe('(11) 98765-4321'); + }); + + test('deve lidar com telefone com letras e caracteres especiais', () => { + expect(maskPhone('11abc98765def4321')).toBe('(11) 98765-4321'); + expect(maskPhone('11@98765#4321')).toBe('(11) 98765-4321'); + }); + + test('deve lidar com casos de números curtos', () => { + expect(maskPhone('1')).toBe('1'); + expect(maskPhone('11')).toBe('11'); + expect(maskPhone('119')).toBe('119'); + }); +}); + +describe('removePhoneMask', () => { + test('deve remover máscara de número de telefone com 11 dígitos', () => { + expect(removePhoneMask('(11) 98765-4321')).toBe('11987654321'); + }); + + test('deve remover máscara de número de telefone com 10 dígitos', () => { + expect(removePhoneMask('(11) 8765-4321')).toBe('1187654321'); + }); + + test('deve retornar string vazia quando o telefone é vazio', () => { + expect(removePhoneMask('')).toBe(''); + }); + + test('deve retornar string vazia quando o telefone é nulo/undefined', () => { + expect(removePhoneMask(null as any)).toBe(''); + expect(removePhoneMask(undefined as any)).toBe(''); + }); + + test('deve retornar valor como está quando o telefone não tem máscara', () => { + expect(removePhoneMask('11987654321')).toBe('11987654321'); + expect(removePhoneMask('1187654321')).toBe('1187654321'); + }); + + test('deve remover apenas caracteres de máscara específicos', () => { + expect(removePhoneMask('(11) 98765-4321')).toBe('11987654321'); + expect(removePhoneMask('11 98765 4321')).toBe('11987654321'); + expect(removePhoneMask('(11)98765-4321')).toBe('11987654321'); + }); + + test('deve preservar caracteres que não são de máscara', () => { + expect(removePhoneMask('11.98765.4321')).toBe('11.98765.4321'); + expect(removePhoneMask('11#98765#4321')).toBe('11#98765#4321'); + }); + + test('deve lidar com caracteres de máscara e não-máscara misturados', () => { + expect(removePhoneMask('(11) 98765-4321 ext.123')).toBe( + '11987654321ext.123' + ); + }); +}); From 5113363f9f211f2f602e9e77fd32e1f8bb7dd363 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 15:57:10 -0300 Subject: [PATCH 03/15] =?UTF-8?q?Adiciona=20exporta=C3=A7=C3=A3o=20de=20fo?= =?UTF-8?q?rmatadores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index b206d0f..3cdaeab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,3 @@ export * from './utils/pluralize'; +export { maskCpf, removeCpfMask } from './formatters/cpf'; +export { maskPhone, removePhoneMask } from './formatters/phone'; From b184573712a4c33d42d334aa8f726d92522b012a Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 15:57:24 -0300 Subject: [PATCH 04/15] =?UTF-8?q?Altera=20descri=C3=A7=C3=B5es=20de=20test?= =?UTF-8?q?es=20para=20portugu=C3=AAs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/pluralize.test.ts | 48 ++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/pluralize.test.ts b/tests/pluralize.test.ts index a187600..776b86c 100644 --- a/tests/pluralize.test.ts +++ b/tests/pluralize.test.ts @@ -3,37 +3,37 @@ import { pluralize, pluralizeWords, pluralizeWithCount, -} from '../src/utils/pluralize'; // Adjust the path +} from '../src/utils/pluralize'; describe('pluralize()', () => { - test('returns same word if count is 1', () => { + test('retorna a mesma palavra se a quantidade for 1', () => { expect(pluralize(1, 'carro')).toBe('carro'); }); - test('adds "s" for regular words ending in vowel', () => { + test('adiciona "s" para palavras regulares terminadas em vogal', () => { expect(pluralize(2, 'banana')).toBe('bananas'); }); - test('uses custom plural if provided', () => { + test('usa o plural personalizado se fornecido', () => { expect(pluralize(2, 'livro')).not.toBe('livrozinhos'); expect(pluralize(2, 'livro', 'livrozinhos')).toBe('livrozinhos'); }); - test('does not change words ending in s or x', () => { + test('não altera palavras terminadas em s ou x', () => { expect(pluralize(3, 'tórax')).toBe('tórax'); expect(pluralize(3, 'lápis')).toBe('lápis'); }); - test('converts -ão to -ões', () => { + test('converte -ão para -ões', () => { expect(pluralize(2, 'avião')).toBe('aviões'); }); - test('converts some irregulars properly', () => { + test('converte alguns irregulares corretamente', () => { expect(pluralize(2, 'pão')).toBe('pães'); expect(pluralize(2, 'alemão')).toBe('alemães'); }); - test('convert custom irregulars properly', () => { + test('converte irregulares customizados corretamente', () => { expect(pluralize(2, 'órgão')).toBe('órgãos'); expect(pluralize(2, 'cônsul')).not.toBe('cônsules'); expect(pluralize(2, 'cônsul', undefined, { cônsul: 'cônsules' })).toBe( @@ -42,74 +42,74 @@ describe('pluralize()', () => { expect(pluralize(2, 'maçã', undefined, { maçã: 'maçãs' })).toBe('maçãs'); }); - test('converts -m to -ns', () => { + test('converte -m para -ns', () => { expect(pluralize(2, 'homem')).toBe('homens'); }); - test('adds "es" for words ending in r or z', () => { + test('adiciona "es" para palavras terminadas em r ou z', () => { expect(pluralize(2, 'luz')).toBe('luzes'); expect(pluralize(2, 'motor')).toBe('motores'); }); - test('converts-ol to -óis', () => { + test('converte -ol para -óis', () => { expect(pluralize(2, 'sol')).toBe('sóis'); }); - test('converts -al, -ul to -ais, -uis', () => { + test('converte -al, -ul para -ais, -uis', () => { expect(pluralize(2, 'animal')).toBe('animais'); expect(pluralize(2, 'azul')).toBe('azuis'); }); - test('converts -el to -éis', () => { + test('converte -el para -éis', () => { expect(pluralize(2, 'papel')).toBe('papéis'); }); - test('converts -il to -is', () => { + test('converte -il para -is', () => { expect(pluralize(2, 'fuzil')).toBe('fuzis'); }); - test('uses plural when count is negative', () => { + test('usa o plural quando a quantidade é negativa', () => { expect(pluralize(-3, 'avião')).toBe('aviões'); }); - test('does not use plural when count is zero', () => { + test('não usa o plural quando a quantidade é zero', () => { expect(pluralize(0, 'mapa')).toBe('mapa'); }); - test('defaults count to 2 if null or undefined', () => { + test('usa o padrão de 2 se a quantidade for nula ou indefinida', () => { expect(pluralize(null, 'livro')).toBe('livros'); }); - test('treats first param as word if count is a string', () => { + test('trata o primeiro parâmetro como palavra se a quantidade for uma string', () => { expect(pluralize('carro', '')).toBe('carros'); }); }); describe('pluralizeWithCount()', () => { - test('includes the count in the result', () => { + test('inclui a quantidade no resultado', () => { expect(pluralizeWithCount(1, 'carro')).toBe('1 carro'); expect(pluralizeWithCount(2, 'carro')).toBe('2 carros'); }); - test('works with custom plural', () => { + test('funciona com plural personalizado', () => { expect(pluralizeWithCount(2, 'livro', 'livrozinhos')).toBe('2 livrozinhos'); }); }); describe('pluralizeWords()', () => { - test('works with one word', () => { + test('funciona com uma palavra', () => { expect(pluralizeWords(0, ['papel'])).toBe('papel'); expect(pluralizeWords(1, ['papel'])).toBe('papel'); expect(pluralizeWords(2, ['papel'])).toBe('papéis'); }); - test('works with two words', () => { + test('funciona com duas palavras', () => { expect(pluralizeWords(0, ['avião', 'antigo'])).toBe('avião antigo'); expect(pluralizeWords(1, ['avião', 'antigo'])).toBe('avião antigo'); expect(pluralizeWords(2, ['avião', 'antigo'])).toBe('aviões antigos'); }); - test('works with three words', () => { + test('funciona com três palavras', () => { expect(pluralizeWords(0, ['moto', 'branca', 'escolhida'])).toBe( 'moto branca escolhida' ); @@ -121,7 +121,7 @@ describe('pluralizeWords()', () => { ); }); - test('works with custom plurals', () => { + test('funciona com plurais personalizados', () => { expect( pluralizeWords( 2, From fe6e19f0413eb533627117781647f4b4d7ced456 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:09:11 -0300 Subject: [PATCH 05/15] =?UTF-8?q?Adiciona=20documenta=C3=A7=C3=A3o=20de=20?= =?UTF-8?q?formatadores=20de=20telefone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/formatters/phone.md | 109 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 docs/formatters/phone.md diff --git a/docs/formatters/phone.md b/docs/formatters/phone.md new file mode 100644 index 0000000..766b13a --- /dev/null +++ b/docs/formatters/phone.md @@ -0,0 +1,109 @@ +# Utilitários de Formatação de Telefone + +Este módulo fornece funções para aplicar e remover a máscara de números de telefone brasileiros, facilitando a manipulação e exibição de telefones fixos e celulares no padrão nacional. + +## Instalação e Importação + +```typescript +import { maskPhone, removePhoneMask } from '@sysvale/foundry'; +``` + +## Funções + +### `maskPhone()` + +Aplica a máscara de telefone brasileiro no formato `(XX) XXXXX-XXXX` para celulares (11 dígitos) ou `(XX) XXXX-XXXX` para fixos (10 dígitos). + +#### Sintaxe + +```typescript +maskPhone(value: string): string +``` + +#### Parâmetros + +- **`value`** (`string`): String contendo apenas números, telefone já formatado ou com caracteres especiais. + +#### Retorno + +`string` – O telefone formatado no padrão nacional, conforme a quantidade de dígitos. Se a entrada não tiver 10 ou 11 dígitos, retorna apenas os dígitos informados. + +#### Exemplos + +```typescript +maskPhone('11987654321'); // → '(11) 98765-4321' +maskPhone('1187654321'); // → '(11) 8765-4321' +maskPhone(''); // → '' +maskPhone('123456789'); // → '123456789' (menos de 10 dígitos, retorna sem máscara) +maskPhone('(11) 98765-4321'); // → '(11) 98765-4321' (já formatado) +maskPhone('11.98765.4321'); // → '(11) 98765-4321' +maskPhone('11abc98765def4321');// → '(11) 98765-4321' +maskPhone('1'); // → '1' +``` + +#### Casos de Uso + +- Exibir telefones formatados em formulários e relatórios. +- Garantir consistência visual de números de telefone em interfaces de usuário. +- Aceitar entradas com ou sem máscara, letras ou caracteres especiais. + +--- + +### `removePhoneMask()` + +Remove qualquer máscara de telefone, retornando apenas os dígitos numéricos. + +#### Sintaxe + +```typescript +removePhoneMask(value: string): string +``` + +#### Parâmetros + +- **`value`** (`string`): String contendo um telefone formatado ou não. + +#### Retorno + +`string` – String contendo apenas os números do telefone. + +#### Exemplos + +```typescript +removePhoneMask('(11) 98765-4321'); // → '11987654321' +removePhoneMask('(11) 8765-4321'); // → '1187654321' +removePhoneMask(''); // → '' +removePhoneMask('11987654321'); // → '11987654321' (sem máscara, retorna igual) +removePhoneMask('11 98765 4321'); // → '11987654321' +removePhoneMask('11.98765.4321'); // → '11.98765.4321' (pontos não são removidos) +removePhoneMask('11#98765#4321'); // → '11#98765#4321' (outros caracteres não são removidos) +removePhoneMask('(11) 98765-4321 ext.123'); // → '11987654321ext.123' +``` + +#### Casos de Uso + +- Armazenar telefones em banco de dados sem formatação. +- Validar ou comparar telefones independentemente do formato de entrada. +- Remover apenas os caracteres de máscara padrão: parênteses, hífens e espaços. + +## Casos de Uso Comuns + +### Formatação para exibição + +```typescript +const phone = '11987654321'; +const formatted = maskPhone(phone); // '(11) 98765-4321' +``` + +### Remoção de máscara para validação + +```typescript +const masked = '(11) 98765-4321'; +const digits = removePhoneMask(masked); // '11987654321' +``` + +## Limitações + +- As funções não validam se o número de telefone é válido, apenas formatam ou removem a máscara. +- Se a string de entrada não tiver 10 ou 11 dígitos, `maskPhone` retorna apenas os dígitos sem aplicar a máscara. +- `removePhoneMask` remove apenas parênteses, hífens e espaços; outros caracteres especiais permanecem. From 1b97139d7d9e4153eadd8d0e551a6c523c5e5432 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:10:24 -0300 Subject: [PATCH 06/15] =?UTF-8?q?Adiciona=20documenta=C3=A7=C3=A3o=20de=20?= =?UTF-8?q?formatador=20de=20CPF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/formatters/cpf.md | 97 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/formatters/cpf.md diff --git a/docs/formatters/cpf.md b/docs/formatters/cpf.md new file mode 100644 index 0000000..6b9d5d2 --- /dev/null +++ b/docs/formatters/cpf.md @@ -0,0 +1,97 @@ +# Utilitários de Formatação de CPF + +Este módulo fornece funções para aplicar e remover a máscara de CPF (Cadastro de Pessoas Físicas) em strings, facilitando a manipulação e exibição de documentos no padrão brasileiro. + +## Instalação e Importação + +```typescript +import { maskCpf, removeCpfMask } from '@sysvale/foundry'; +``` + +## Funções + +### `maskCpf()` + +Aplica a máscara de CPF no formato `XXX.XXX.XXX-XX` a uma string contendo apenas números. + +#### Sintaxe + +```typescript +maskCpf(value: string): string +``` + +#### Parâmetros + +- **`value`** (`string`): String contendo apenas números ou um CPF já formatado. + +#### Retorno + +`string` – O CPF formatado no padrão `XXX.XXX.XXX-XX` se a entrada tiver 11 dígitos. Caso contrário, retorna apenas os dígitos informados. + +#### Exemplos + +```typescript +maskCpf('11111111111'); // → '111.111.111-11' +maskCpf(''); // → '' +maskCpf('1234567890'); // → '1234567890' (menos de 11 dígitos, retorna sem máscara) +``` + +#### Casos de Uso + +- Exibir CPF formatado em formulários e relatórios. +- Garantir consistência visual de documentos em interfaces de usuário. + +--- + +### `removeCpfMask()` + +Remove qualquer máscara de CPF, retornando apenas os dígitos numéricos. + +#### Sintaxe + +```typescript +removeCpfMask(value: string): string +``` + +#### Parâmetros + +- **`value`** (`string`): String contendo um CPF formatado ou não. + +#### Retorno + +`string` – String contendo apenas os números do CPF. + +#### Exemplos + +```typescript +removeCpfMask('111.111.111-11'); // → '11111111111' +removeCpfMask(''); // → '' +removeCpfMask('1234567890'); // → '1234567890' (não altera se não houver máscara) +``` + +#### Casos de Uso + +- Armazenar CPFs em banco de dados sem formatação. +- Validar ou comparar CPFs independentemente do formato de entrada. + +## Casos de Uso Comuns + +### Formatação para exibição + +```typescript +const cpf = '12345678901'; +const formatted = maskCpf(cpf); // '123.456.789-01' +``` + +### Remoção de máscara para validação + +```typescript +const masked = '123.456.789-01'; +const digits = removeCpfMask(masked); // '12345678901' +``` + +## Limitações + +- As funções não validam se o CPF é válido, apenas formatam ou removem a máscara. +- Se a string de entrada não tiver 11 dígitos, `maskCpf` retorna apenas os dígitos sem aplicar a máscara. +- Caracteres não numéricos são removidos por `removeCpfMask`. From 1058e6ac9efb6c876c2c71f8d9665306f480ac71 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:11:53 -0300 Subject: [PATCH 07/15] =?UTF-8?q?Adiciona=20se=C3=A7=C3=A3o=20de=20formata?= =?UTF-8?q?dores=20na=20documenta=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/formatters/index.md | 17 +++++++++++++++++ docs/index.md | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 docs/formatters/index.md diff --git a/docs/formatters/index.md b/docs/formatters/index.md new file mode 100644 index 0000000..679d012 --- /dev/null +++ b/docs/formatters/index.md @@ -0,0 +1,17 @@ +# Utilitários de Formatação + +Este módulo fornece funções para formatar diversos tipos de dados. + +## Formatadores + +### CPF + +Funções para aplicação ou remoção de máscaras em CPFs. + +- [Documentação](./cpf.md) + +### Telefone + +Funções para aplicação ou remoção de máscaras em números telefônicos brasileiros. + +- [Documentação](./phone.md) diff --git a/docs/index.md b/docs/index.md index 798d96c..a0d9309 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,8 +8,11 @@ hero: features: - title: Utils - details: Métodos utilitários em TypesCript para facilitar tarefas comuns no front-end. + details: Métodos utilitários em TypeScript para facilitar tarefas comuns no front-end. link: /utils/pluralize + - title: Formatadores + details: Métodos em TypeScript para formatar diversos tipos de dados. + link: /formatters/index - title: Composables details: Composables Vue 3 reutilizáveis para lógica comum no front-end. link: /composables/ From ce3e90ceb56695bcf2ab6d5f759b08333aa5216c Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:12:22 -0300 Subject: [PATCH 08/15] =?UTF-8?q?Atualiza=20vers=C3=A3o=20do=20projeto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b8b9db8..a94c6e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sysvale/foundry", - "version": "1.0.0", + "version": "1.1.0", "description": "A forge for composables, helpers, and front-end utilities.", "type": "module", "main": "./dist/foundry.cjs.js", From 13bbdcc11975793bcefc1855c2f89e63c09f91cc Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:24:18 -0300 Subject: [PATCH 09/15] Adiciona trechos ignorados pelo prettier --- docs/formatters/phone.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/formatters/phone.md b/docs/formatters/phone.md index 766b13a..609f71e 100644 --- a/docs/formatters/phone.md +++ b/docs/formatters/phone.md @@ -30,6 +30,7 @@ maskPhone(value: string): string #### Exemplos + ```typescript maskPhone('11987654321'); // → '(11) 98765-4321' maskPhone('1187654321'); // → '(11) 8765-4321' @@ -69,6 +70,7 @@ removePhoneMask(value: string): string #### Exemplos + ```typescript removePhoneMask('(11) 98765-4321'); // → '11987654321' removePhoneMask('(11) 8765-4321'); // → '1187654321' From ae245afc742d19a12792671f08910211e44a150d Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:26:53 -0300 Subject: [PATCH 10/15] =?UTF-8?q?Adiciona=20exce=C3=A7=C3=B5es=20para=20o?= =?UTF-8?q?=20prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/phone.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/phone.test.ts b/tests/phone.test.ts index 7a7705b..becb2d1 100644 --- a/tests/phone.test.ts +++ b/tests/phone.test.ts @@ -15,7 +15,9 @@ describe('maskPhone', () => { }); test('deve retornar string vazia quando o telefone é nulo/undefined', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(maskPhone(null as any)).toBe(''); + // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(maskPhone(undefined as any)).toBe(''); }); @@ -56,7 +58,9 @@ describe('removePhoneMask', () => { }); test('deve retornar string vazia quando o telefone é nulo/undefined', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(removePhoneMask(null as any)).toBe(''); + // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(removePhoneMask(undefined as any)).toBe(''); }); From c5169e855ecbc0c42acab006f761239b1be4f1f1 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:29:24 -0300 Subject: [PATCH 11/15] =?UTF-8?q?Ajusta=20exce=C3=A7=C3=B5es=20do=20pretti?= =?UTF-8?q?er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/phone.test.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/phone.test.ts b/tests/phone.test.ts index becb2d1..459aded 100644 --- a/tests/phone.test.ts +++ b/tests/phone.test.ts @@ -15,9 +15,8 @@ describe('maskPhone', () => { }); test('deve retornar string vazia quando o telefone é nulo/undefined', () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // prettier-ignore expect(maskPhone(null as any)).toBe(''); - // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(maskPhone(undefined as any)).toBe(''); }); @@ -58,9 +57,8 @@ describe('removePhoneMask', () => { }); test('deve retornar string vazia quando o telefone é nulo/undefined', () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // prettier-ignore expect(removePhoneMask(null as any)).toBe(''); - // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(removePhoneMask(undefined as any)).toBe(''); }); From 0bbb48bf0649de9b6c568a01959b72ac60146dd8 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 7 Aug 2025 16:31:33 -0300 Subject: [PATCH 12/15] =?UTF-8?q?Ajusta=20tipo=20de=20par=C3=A2metro=20do?= =?UTF-8?q?=20telefone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/formatters/phone.ts | 4 ++-- tests/phone.test.ts | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/formatters/phone.ts b/src/formatters/phone.ts index f95b3be..25ece3f 100644 --- a/src/formatters/phone.ts +++ b/src/formatters/phone.ts @@ -1,4 +1,4 @@ -const maskPhone = (value: string) => { +const maskPhone = (value: string | null | undefined) => { if (!value || value.length === 0) { return ''; } @@ -15,7 +15,7 @@ const maskPhone = (value: string) => { return phone; }; -const removePhoneMask = (value: string) => { +const removePhoneMask = (value: string | null | undefined) => { if (!value || value.length === 0) { return ''; } diff --git a/tests/phone.test.ts b/tests/phone.test.ts index 459aded..5c298a1 100644 --- a/tests/phone.test.ts +++ b/tests/phone.test.ts @@ -16,8 +16,8 @@ describe('maskPhone', () => { test('deve retornar string vazia quando o telefone é nulo/undefined', () => { // prettier-ignore - expect(maskPhone(null as any)).toBe(''); - expect(maskPhone(undefined as any)).toBe(''); + expect(maskPhone(null)).toBe(''); + expect(maskPhone(undefined)).toBe(''); }); test('deve retornar apenas dígitos quando o telefone tem comprimento inválido', () => { @@ -57,9 +57,8 @@ describe('removePhoneMask', () => { }); test('deve retornar string vazia quando o telefone é nulo/undefined', () => { - // prettier-ignore - expect(removePhoneMask(null as any)).toBe(''); - expect(removePhoneMask(undefined as any)).toBe(''); + expect(removePhoneMask(null)).toBe(''); + expect(removePhoneMask(undefined)).toBe(''); }); test('deve retornar valor como está quando o telefone não tem máscara', () => { From 6abd97754dfede065c8b9a09ef84f2ed20b1430a Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 14 Aug 2025 16:12:02 -0300 Subject: [PATCH 13/15] Remove caso de uso confuso --- docs/formatters/phone.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/formatters/phone.md b/docs/formatters/phone.md index 609f71e..d22f6ac 100644 --- a/docs/formatters/phone.md +++ b/docs/formatters/phone.md @@ -46,7 +46,6 @@ maskPhone('1'); // → '1' - Exibir telefones formatados em formulários e relatórios. - Garantir consistência visual de números de telefone em interfaces de usuário. -- Aceitar entradas com ou sem máscara, letras ou caracteres especiais. --- From c63e2ae6c62384a40b63720fff739c893d5267d6 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 14 Aug 2025 16:12:18 -0300 Subject: [PATCH 14/15] =?UTF-8?q?Passa=20a=20considerar=20par=C3=A2metros?= =?UTF-8?q?=20que=20sejam=20n=C3=BAmero?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/formatters/cpf.ts | 16 ++++++++++------ src/formatters/phone.ts | 16 ++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/formatters/cpf.ts b/src/formatters/cpf.ts index 3a5363b..ec06861 100644 --- a/src/formatters/cpf.ts +++ b/src/formatters/cpf.ts @@ -1,9 +1,11 @@ -const maskCpf = (value: string) => { - if (!value) { +const maskCpf = (value: string | number) => { + let cpf = typeof value === 'number' ? value.toString() : value; + + if (!cpf) { return ''; } - const cpf = value.replace(/\D/g, ''); + cpf = cpf.replace(/\D/g, ''); if (cpf.length === 11) { return `${cpf.substring(0, 3)}.${cpf.substring(3, 6)}.${cpf.substring(6, 9)}-${cpf.substring(9, 11)}`; @@ -12,12 +14,14 @@ const maskCpf = (value: string) => { return cpf; }; -const removeCpfMask = (value: string) => { - if (!value) { +const removeCpfMask = (value: string | number) => { + let cpf = typeof value === 'number' ? value.toString() : value; + + if (!cpf) { return ''; } - return value.replace(/\D/g, ''); + return cpf.replace(/\D/g, ''); }; export { maskCpf, removeCpfMask }; diff --git a/src/formatters/phone.ts b/src/formatters/phone.ts index 25ece3f..0b068ce 100644 --- a/src/formatters/phone.ts +++ b/src/formatters/phone.ts @@ -1,9 +1,11 @@ -const maskPhone = (value: string | null | undefined) => { - if (!value || value.length === 0) { +const maskPhone = (value: string | null | number | undefined) => { + let phone = typeof value === 'number' ? value.toString() : value; + + if (!phone || phone.length === 0) { return ''; } - const phone = value.replace(/[^0-9]+/g, ''); + phone = phone.replace(/[^0-9]+/g, ''); if (phone.length === 11) { return `(${phone.substring(0, 2)}) ${phone.substring(2, 7)}-${phone.substring(7, 11)}`; @@ -15,12 +17,14 @@ const maskPhone = (value: string | null | undefined) => { return phone; }; -const removePhoneMask = (value: string | null | undefined) => { - if (!value || value.length === 0) { +const removePhoneMask = (value: string | null | number | undefined) => { + let phone = typeof value === 'number' ? value.toString() : value; + + if (!phone || phone.length === 0) { return ''; } - return value.replace(/\(|\)|-|\s/g, ''); + return phone.replace(/\(|\)|-|\s/g, ''); }; export { maskPhone, removePhoneMask }; From 99abf7001cd2757ba337af562b0e15475e0ce4d2 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 14 Aug 2025 16:13:22 -0300 Subject: [PATCH 15/15] =?UTF-8?q?Ajusta=20testes=20para=20aceitarem=20n?= =?UTF-8?q?=C3=BAmeros?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/cpf.test.ts | 1 + tests/phone.test.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/cpf.test.ts b/tests/cpf.test.ts index fae7a13..11385d0 100644 --- a/tests/cpf.test.ts +++ b/tests/cpf.test.ts @@ -4,6 +4,7 @@ import { maskCpf, removeCpfMask } from '../src/formatters/cpf'; describe('maskCpf', () => { test('deve formatar cpf', () => { expect(maskCpf('11111111111')).toBe('111.111.111-11'); + expect(maskCpf(11111111111)).toBe('111.111.111-11'); }); test('deve retornar string vazia quando cpf é vazio', () => { diff --git a/tests/phone.test.ts b/tests/phone.test.ts index 5c298a1..6672758 100644 --- a/tests/phone.test.ts +++ b/tests/phone.test.ts @@ -4,10 +4,12 @@ import { maskPhone, removePhoneMask } from '../src/formatters/phone'; describe('maskPhone', () => { test('deve formatar número de telefone com 11 dígitos (com 9)', () => { expect(maskPhone('11987654321')).toBe('(11) 98765-4321'); + expect(maskPhone(11987654321)).toBe('(11) 98765-4321'); }); test('deve formatar número de telefone com 10 dígitos (sem 9)', () => { expect(maskPhone('1187654321')).toBe('(11) 8765-4321'); + expect(maskPhone(1187654321)).toBe('(11) 8765-4321'); }); test('deve retornar string vazia quando o telefone é vazio', () => { @@ -15,7 +17,6 @@ describe('maskPhone', () => { }); test('deve retornar string vazia quando o telefone é nulo/undefined', () => { - // prettier-ignore expect(maskPhone(null)).toBe(''); expect(maskPhone(undefined)).toBe(''); });