From a21eb72781da851b16ff45da12c817aeda7be55d Mon Sep 17 00:00:00 2001 From: Breno A Date: Fri, 14 Jun 2024 17:32:49 -0300 Subject: [PATCH 1/6] Enhance validation and documentation --- README.md | 13 +++-- packages/typescript/src/cpfValidator.ts | 66 +++++++------------------ packages/typescript/src/isEmail.ts | 26 +++++++++- 3 files changed, 48 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 2158b77..742547a 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ # Multiform-validator -MyLibrary is a multilanguage library designed to validate various form fields. It can validate fields such as email, phone, password, CPF (Brazilian Individual Taxpayer Registry), credit card numbers, and more. +Multiform-validator is a comprehensive, multilanguage library designed to validate various form fields. It supports validation for fields such as email, phone, password, CPF (Brazilian Individual Taxpayer Registry), credit card numbers, and more, ensuring data integrity and security across different programming languages. ## Supported Languages -This library can validate data in the following programming languages: +This library provides validation functionalities in the following programming languages: - [TypeScript (TS/JS/NPM)](https://github.com/gabriel-logan/multiform-validator/tree/main/packages/typescript/README.md) (stable) - [Java](https://github.com/gabriel-logan/multiform-validator/tree/main/packages/java/README.md) (coming soon) @@ -17,16 +17,15 @@ This library can validate data in the following programming languages: ## Usage -To use this library, please refer to the specific README file in the directory of the programming language you are using. -For example, if you are using TypeScript, you can find the usage instructions in the [TypeScript README](https://github.com/gabriel-logan/multiform-validator/tree/main/packages/typescript/README.md). +For detailed usage instructions, please refer to the README file in the directory of the programming language you are using. For instance, TypeScript users can find the usage instructions in the [TypeScript README](https://github.com/gabriel-logan/multiform-validator/tree/main/packages/typescript/README.md). ## Installation -Please refer to the specific installation instructions in the README file of the respective programming language directory. +Installation instructions are available in the README file of the respective programming language directory. ## Contributing -Contributions are welcome! Please read the contributing guidelines before getting started. +We welcome contributions! Please consult the contributing guidelines before starting. ## Contributors @@ -36,4 +35,4 @@ Contributions are welcome! Please read the contributing guidelines before gettin ## License -This project is licensed under the MIT License. \ No newline at end of file +This project is licensed under the MIT License. diff --git a/packages/typescript/src/cpfValidator.ts b/packages/typescript/src/cpfValidator.ts index 5889ddc..67bf125 100644 --- a/packages/typescript/src/cpfValidator.ts +++ b/packages/typescript/src/cpfValidator.ts @@ -6,20 +6,17 @@ const defaultErrorMsg: string[] = [ ]; /** - * @param cpf - * @param errorMsg optional - * @example cpfIsValid('123.456.789.10'); - * @example cpfIsValid('12345678910'); - * @example cpfIsValid('12345678910', ['CPF ta errado','Tem que ter pelo menos 11']); - * @description This function returns four errors in the following order, + * Validates a Brazilian CPF number for correctness. * - * If you want to use a default parameter, use null or leave Empty.. + * The CPF (Cadastro de Pessoas Físicas) is a Brazilian tax identification number. + * It consists of 11 digits in the format XXX.XXX.XXX-XX. This function checks the + * validity of a CPF number using its calculation algorithm. * - * Default: - * ['CPF invalid', 'CPF must have 11 numerical digits', 'CPF is not valid', 'Unknown error'] - * . - * - * Create a list of errors separated by commas in strings + * @param cpf The CPF number as a string. + * @param errorMsg An optional array of custom error messages. + * @example cpfIsValid('123.456.789-09'); + * @example cpfIsValid('12345678909'); + * @example cpfIsValid('12345678909', ['Custom invalid CPF message','Custom length error']); * @returns An object with 'isValid' (boolean) and 'errorMsg' (string) properties. */ function cpfIsValid( @@ -32,8 +29,6 @@ function cpfIsValid( if (typeof cpf !== "string") { throw new TypeError("The input should be a string."); } - // Check para saber se as mensagens que sao passadas sao validas - // caso contrario retorna um ERRO if (errorMsg) { if (!Array.isArray(errorMsg)) throw new TypeError("Must be an Array"); for (let index: number = 0; index < errorMsg.length; index += 1) { @@ -44,7 +39,7 @@ function cpfIsValid( } } } - // Função interna para obter a mensagem de erro + function getErrorMessage(index: number): string { const errorMessage: string | null = errorMsg ? errorMsg[index] : null; return errorMessage != null ? errorMessage : defaultErrorMsg[index]; @@ -58,51 +53,26 @@ function cpfIsValid( }; } - let numeroBase: number = 10; - let numeroBase2: number = 11; - let somaTotal: number = 0; - let somaTotal2: number = 0; - if (cpf.length !== 11 && cpf.length !== 14) { + const cpfClean: string = cpf.replace(/\D+/g, ""); + if (cpfClean.length !== 11) { return { isValid: false, errorMsg: getErrorMessage(1), }; } - const cpfLimpo: string = cpf.replace(/\D+/g, ""); // Transforma o cpf em um valor limpo sem caracter especial - // Validação para verificar se todos os dígitos são iguais (condição de CPF inválido). - if (/^(\d)\1{10}$/.test(cpfLimpo)) { + if (/^(\d)\1{10}$/.test(cpfClean)) { return { isValid: false, errorMsg: getErrorMessage(2), }; } - let primeiroVerificador: number = 0; - let segundoVerificador: number = 0; + const cpfArray: number[] = cpfClean.split('').map(Number); + const validator = (sum: number) => (sum % 11 < 2 ? 0 : 11 - (sum % 11)); + const sum1 = cpfArray.slice(0, 9).reduce((acc, val, i) => acc + val * (10 - i), 0); + const sum2 = cpfArray.slice(0, 10).reduce((acc, val, i) => acc + val * (11 - i), 0); - for (let repetidor: number = 0; repetidor < 11; repetidor += 1) { - // Executa os códigos 11 vezes em sequência. - // Faz a soma numérica de todos os números gerados por multiplicador. - const multiplicador: number = Number(cpfLimpo[repetidor]) * numeroBase; - numeroBase -= 1; - somaTotal += multiplicador; - // Faz a soma numérica de todos os números gerados por multiplicador2. - const multiplicador2: number = Number(cpfLimpo[repetidor]) * numeroBase2; - numeroBase2 -= 1; - somaTotal2 += multiplicador2; - // Calculo de verificação dos digitos - const valorDeVerificacao: number = somaTotal - Number(cpfLimpo[9]); // Coleta a soma apenas até o 9° número da sequência - const valorDeVerificacao2: number = somaTotal2 - Number(cpfLimpo[10]); // Coleta a soma apenas até o 10° número da sequência - primeiroVerificador = 11 - (valorDeVerificacao % 11); // Calcula o Primeiro dígito verificador - segundoVerificador = 11 - (valorDeVerificacao2 % 11); // Calcula o Segundo Dígito verificador - } - if (primeiroVerificador > 9) primeiroVerificador = 0; - if (segundoVerificador > 9) segundoVerificador = 0; - // Valida o Número gerado, se = true, CPF GERADO. - if ( - primeiroVerificador === Number(cpfLimpo[9]) && - segundoVerificador === Number(cpfLimpo[10]) - ) { + if (cpfArray[9] === validator(sum1) && cpfArray[10] === validator(sum2)) { return { isValid: true, errorMsg: null, diff --git a/packages/typescript/src/isEmail.ts b/packages/typescript/src/isEmail.ts index 27af60a..278b62c 100644 --- a/packages/typescript/src/isEmail.ts +++ b/packages/typescript/src/isEmail.ts @@ -1,6 +1,28 @@ /** - * @example isEmail('foor@bar.com') true; - * @example isEmail('foor@bar') false; + * Validates if the given string is a valid email address. + * + * @example isEmail('foo@bar.com') // returns true; + * @example isEmail('foo@bar') // returns false; + * @example isEmail('1foo@bar.com') // returns false, starts with a number. + * @example isEmail('foo@1bar.com') // returns false, domain starts with a number. + * @example isEmail('foo@bar.1com') // returns false, TLD starts with a number. + * @example isEmail('..foo@bar.com') // returns false, starts with consecutive dots. + * @example isEmail('foo..bar@baz.com') // returns false, local part contains consecutive dots. + * @example isEmail('foo@..bar.com') // returns false, domain contains consecutive dots. + * @example isEmail('foo@bar..com') // returns false, domain contains consecutive dots before TLD. + * @example isEmail('foo@bar.com..') // returns false, ends with consecutive dots. + * @example isEmail('foo@@bar.com') // returns false, contains multiple @ symbols. + * @example isEmail('foo@bar.com.br') // returns true, valid country code TLD. + * @example isEmail('foo@bar.com.com') // returns false, domain repetition. + * @example isEmail('foo@bar.c') // returns false, TLD too short. + * @example isEmail('!foo@bar.com') // returns false, starts with a special character. + * @example isEmail('foo bar@baz.com') // returns false, contains spaces. + * @example isEmail('foo@bar!com') // returns false, domain contains special characters. + * @example isEmail('foo!@bar.com') // returns false, local part contains special characters. + * @example isEmail('foo@bar.c') // returns false, invalid TLD. + * @description This function checks if the provided string is a valid email address according to the standard email formatting rules. It checks for the presence of an @ symbol, valid characters in the local part and domain, the absence of forbidden characters and patterns, and a valid top-level domain. + * @param email The email address to validate. + * @returns {boolean} True if the email address is valid, false otherwise. */ function isEmail(email: string): boolean { if (typeof email !== "string") { From b6059dae6441dc76a15b933a4a640f724c290c46 Mon Sep 17 00:00:00 2001 From: Breno A Date: Fri, 14 Jun 2024 17:52:16 -0300 Subject: [PATCH 2/6] fix: add char size check for cpf string --- packages/typescript/src/cpfValidator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typescript/src/cpfValidator.ts b/packages/typescript/src/cpfValidator.ts index 67bf125..064cbaa 100644 --- a/packages/typescript/src/cpfValidator.ts +++ b/packages/typescript/src/cpfValidator.ts @@ -54,7 +54,7 @@ function cpfIsValid( } const cpfClean: string = cpf.replace(/\D+/g, ""); - if (cpfClean.length !== 11) { + if (cpfClean.length !== 11 && cpfClean.length !== 14) { return { isValid: false, errorMsg: getErrorMessage(1), From e1188a8876bfd7b6f4b844d4d5355ca7e91b9b50 Mon Sep 17 00:00:00 2001 From: Breno A Date: Fri, 14 Jun 2024 17:59:45 -0300 Subject: [PATCH 3/6] refactor: cpfvalidation cleanup --- packages/typescript/src/cpfValidator.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/typescript/src/cpfValidator.ts b/packages/typescript/src/cpfValidator.ts index 064cbaa..d958a02 100644 --- a/packages/typescript/src/cpfValidator.ts +++ b/packages/typescript/src/cpfValidator.ts @@ -54,13 +54,7 @@ function cpfIsValid( } const cpfClean: string = cpf.replace(/\D+/g, ""); - if (cpfClean.length !== 11 && cpfClean.length !== 14) { - return { - isValid: false, - errorMsg: getErrorMessage(1), - }; - } - if (/^(\d)\1{10}$/.test(cpfClean)) { + if ((cpfClean.length !== 11 && cpfClean.length !== 14) || /^(\d)\1{10}$/.test(cpfClean)) { return { isValid: false, errorMsg: getErrorMessage(2), From a41600f9adb290157f8a3abe3f4d2e1b1a2511f8 Mon Sep 17 00:00:00 2001 From: Gabriel Logan <96627244+gabriel-logan@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:06:24 -0300 Subject: [PATCH 4/6] Update cpfValidator.ts --- packages/typescript/src/cpfValidator.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/typescript/src/cpfValidator.ts b/packages/typescript/src/cpfValidator.ts index d958a02..570bb9a 100644 --- a/packages/typescript/src/cpfValidator.ts +++ b/packages/typescript/src/cpfValidator.ts @@ -54,13 +54,20 @@ function cpfIsValid( } const cpfClean: string = cpf.replace(/\D+/g, ""); - if ((cpfClean.length !== 11 && cpfClean.length !== 14) || /^(\d)\1{10}$/.test(cpfClean)) { + if (/^(\d)\1{10}$/.test(cpfLimpo)) { return { isValid: false, errorMsg: getErrorMessage(2), }; } + if (cpfLimpo.length !== 11) { + return { + isValid: false, + errorMsg: getErrorMessage(1), + }; + } + const cpfArray: number[] = cpfClean.split('').map(Number); const validator = (sum: number) => (sum % 11 < 2 ? 0 : 11 - (sum % 11)); const sum1 = cpfArray.slice(0, 9).reduce((acc, val, i) => acc + val * (10 - i), 0); From 4f6aca2cc668e8efcab2bee1ce6174827ed83853 Mon Sep 17 00:00:00 2001 From: Gabriel Logan <96627244+gabriel-logan@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:07:00 -0300 Subject: [PATCH 5/6] Update cpfValidator.ts --- packages/typescript/src/cpfValidator.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/typescript/src/cpfValidator.ts b/packages/typescript/src/cpfValidator.ts index 570bb9a..6ac1467 100644 --- a/packages/typescript/src/cpfValidator.ts +++ b/packages/typescript/src/cpfValidator.ts @@ -54,6 +54,7 @@ function cpfIsValid( } const cpfClean: string = cpf.replace(/\D+/g, ""); + if (/^(\d)\1{10}$/.test(cpfLimpo)) { return { isValid: false, From d383ac728cf8b9803d1a2df9db35964298714bde Mon Sep 17 00:00:00 2001 From: Gabriel Logan <96627244+gabriel-logan@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:08:45 -0300 Subject: [PATCH 6/6] Update cpfValidator.ts --- packages/typescript/src/cpfValidator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typescript/src/cpfValidator.ts b/packages/typescript/src/cpfValidator.ts index 6ac1467..453cdf9 100644 --- a/packages/typescript/src/cpfValidator.ts +++ b/packages/typescript/src/cpfValidator.ts @@ -55,14 +55,14 @@ function cpfIsValid( const cpfClean: string = cpf.replace(/\D+/g, ""); - if (/^(\d)\1{10}$/.test(cpfLimpo)) { + if (/^(\d)\1{10}$/.test(cpfClean)) { return { isValid: false, errorMsg: getErrorMessage(2), }; } - if (cpfLimpo.length !== 11) { + if (cpfClean.length !== 11) { return { isValid: false, errorMsg: getErrorMessage(1),