diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..fcf6103 Binary files /dev/null and b/.DS_Store differ diff --git a/index.js b/index.js old mode 100644 new mode 100755 diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..8367747 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "poo", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/brazilian-doc-validator": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/brazilian-doc-validator/-/brazilian-doc-validator-1.0.5.tgz", + "integrity": "sha512-Hesu44EXF6WUBU9MJl20jeG3utChzzfZrPIl4lVj/PlvRTMobvRO7kC+Exch2SZkm+wlmRecrS+iQQ+/djCmNw==" + } + } +} diff --git a/node_modules/brazilian-doc-validator/.DS_Store b/node_modules/brazilian-doc-validator/.DS_Store new file mode 100644 index 0000000..37f8c56 Binary files /dev/null and b/node_modules/brazilian-doc-validator/.DS_Store differ diff --git a/node_modules/brazilian-doc-validator/.eslintignore b/node_modules/brazilian-doc-validator/.eslintignore new file mode 100644 index 0000000..cb840ae --- /dev/null +++ b/node_modules/brazilian-doc-validator/.eslintignore @@ -0,0 +1,3 @@ +node_modules/ +coverage/ +dist \ No newline at end of file diff --git a/node_modules/brazilian-doc-validator/.eslintrc.json b/node_modules/brazilian-doc-validator/.eslintrc.json new file mode 100644 index 0000000..73f4fbb --- /dev/null +++ b/node_modules/brazilian-doc-validator/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "google" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + } +} diff --git a/node_modules/brazilian-doc-validator/LICENSE b/node_modules/brazilian-doc-validator/LICENSE new file mode 100644 index 0000000..07c2dd1 --- /dev/null +++ b/node_modules/brazilian-doc-validator/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 William Nakagawa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/brazilian-doc-validator/README.md b/node_modules/brazilian-doc-validator/README.md new file mode 100644 index 0000000..3ff40c9 --- /dev/null +++ b/node_modules/brazilian-doc-validator/README.md @@ -0,0 +1,145 @@ +# brazilian-doc-validator +Validator for common brazilian patterns, such as cpf and cnpj validations. +Generator and mask/unmask CPF or CNPJ document numbers. +It is a npm package to be used in javascript applications. + +# Table of contents + + +* [Installing](#installing) +* [Usage](#usage) + * [CPF](#cpf) + * [CNPJ](#cnpj) +* [Contributing](#contributing) +* [Testing](#testing) + + +# Installing + +Using npm: + +```bash +npm i brazilian-doc-validator +``` + +Using yarn: + +```bash +yarn add brazilian-doc-validator +``` + +# Usage + +## CPF + +```js +import {cpf} from 'brazilian-doc-validator'; +``` + +or + +```js +const {cpf} = require('brazilian-doc-validator'); +``` + +### Validation + +```js +cpf.validate("111.111.111-11"); +``` + +> **Result:** false + +### Mask Formated + +```js +const validCpf = "###########"; +cpf.mask(validCpf) +``` + +> **Result:** ###.###.###-## + +### Unmask CPF (only numbers) + +```js +const validCpf = "###.###.###-##"; +cpf.unmask(validCpf) +``` + +> **Result:** ########### + +### Generate Valid CPF + +```js +const newCpfMasked = cpf.generate({mask: true}); +``` + +> **Result:** ###.###.###-## + +```js +const newCpfOnlyNumbers = cpf.generate({mask: false}); +``` + +> **Result:** ########### + +## CNPJ + +```js +import {cnpj} from 'brazilian-doc-validator'; +``` + +or + +```js +const {cnpj} = require('brazilian-doc-validator'); +``` + +### Validation + +```js +cnpj.validate("11.111.111/1111-11"); +``` + +> **Result:** false + +### Mask Formated + +```js +const validCnpj = "##############"; +cnpj.mask(validCnpj) +``` + +> **Result:** ##.###.###/####-## + +### Unmask CNPJ (only numbers) + +```js +const validCnpj = "##.###.###/####-##"; +cnpj.unmask(validCnpj) +``` + +> **Result:** ############## + +### Generate Valid CNPJ + +```js +const newMaskedCnpj = cnpj.generate({mask: true}); +``` + +> **Result:** ##.###.###/####-## + +```js +const newCnpj = cnpj.generate({mask: false}; +``` + +> **Result:** ############## + +# Contributing + +To do + +# Testing + +```bash +npm run test +``` diff --git a/node_modules/brazilian-doc-validator/babel.config.js b/node_modules/brazilian-doc-validator/babel.config.js new file mode 100644 index 0000000..a50f080 --- /dev/null +++ b/node_modules/brazilian-doc-validator/babel.config.js @@ -0,0 +1,6 @@ +module.exports = { + presets: [ + ['@babel/preset-env', {targets: {node: 'current'}}], + '@babel/preset-typescript', + ], + }; \ No newline at end of file diff --git a/node_modules/brazilian-doc-validator/dist/index.js b/node_modules/brazilian-doc-validator/dist/index.js new file mode 100644 index 0000000..9d49bcf --- /dev/null +++ b/node_modules/brazilian-doc-validator/dist/index.js @@ -0,0 +1,10 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.cnpj = exports.cpf = void 0; +const cpf_1 = __importDefault(require("./src/validator/cpf")); +exports.cpf = cpf_1.default; +const cnpj_1 = __importDefault(require("./src/validator/cnpj")); +exports.cnpj = cnpj_1.default; diff --git a/node_modules/brazilian-doc-validator/dist/src/validator/cnpj.js b/node_modules/brazilian-doc-validator/dist/src/validator/cnpj.js new file mode 100644 index 0000000..5347d60 --- /dev/null +++ b/node_modules/brazilian-doc-validator/dist/src/validator/cnpj.js @@ -0,0 +1,136 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * CNPJ validation + * + * @param {string} cnpj + * + * @return {boolean} + * + */ +const cnpjValidate = (cnpj) => { + const invalidCnpjList = [ + '00000000000000', + '11111111111111', + '22222222222222', + '33333333333333', + '44444444444444', + '55555555555555', + '66666666666666', + '77777777777777', + '88888888888888', + '99999999999999', + ]; + if (!Boolean(cnpj) || invalidCnpjList.includes(cnpj)) + return false; + const onlyNumbers = cnpj.replace(/\D/g, ''); + if (onlyNumbers.length < 14) + return false; + let length = onlyNumbers.length - 2; + let numbers = onlyNumbers.substring(0, length); + const digits = onlyNumbers.substring(length); + let addition = 0; + let pos = length - 7; + for (let i = length; i >= 1; i--) { + addition += parseInt(numbers.charAt(length - i)) * pos--; + if (pos < 2) + pos = 9; + } + let result = addition % 11 < 2 ? 0 : 11 - addition % 11; + if (result !== parseInt(digits.charAt(0))) + return false; + length = length + 1; + numbers = onlyNumbers.substring(0, length); + addition = 0; + pos = length - 7; + for (let i = length; i >= 1; i--) { + addition += parseInt(numbers.charAt(length - i)) * pos--; + if (pos < 2) + pos = 9; + } + result = addition % 11 < 2 ? 0 : 11 - addition % 11; + if (result !== parseInt(digits.charAt(1))) + return false; + return true; +}; +/** + * CNPJ Mask + * + * @param {string} cnpj + * + * @return {string} + * + */ +const cnpjMask = (cnpj) => { + if (cnpjValidate(cnpj)) { + const onlyNumbers = cnpj.replace(/\D/g, ''); + return onlyNumbers + .replace(/^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})*/, '$1.$2.$3/$4-$5'); + } + return ''; +}; +/** + * CNPJ Unmask + * + * @param {string} cnpj + * + * @return {string} + * + */ +const cnpjUnmask = (cnpj) => { + if (cnpjValidate(cnpj)) { + return cnpj.replace(/\D/g, ''); + } + return ''; +}; +/** + * CNPJ Generation - Generates a valid CNPJ document. + * + * @param {Record} options + * + * @return {string} + * + */ +const cnpjGenerate = (options = { mask: true }) => { + const { mask } = options; + const createCnpjNumber = () => { + const numbersList = createListNumber(); + numbersList.push(calculateDigitCnpj(numbersList)); + return `${numbersList.join('')}${calculateDigitCnpj(numbersList)}`; + }; + const createListNumber = () => { + const numbersList = []; + for (let i = 0; i < 8; i++) { + numbersList.push(randomNumber()); + } + for (let i = 0; i < 3; i++) { + numbersList.push(0); + } + numbersList.push(1); + return numbersList; + }; + const randomNumber = () => Math.floor(Math.random() * 9); + const calculateRestCnpj = (sumDigit) => sumDigit % 11; + const calculateSumDigit = (numbersList) => { + let sumDigit = 0; + let salt = 9; + for (let i = numbersList.length - 1; i >= 0; i--) { + sumDigit += numbersList[i] * salt--; + if (salt < 2) + salt = 9; + } + return sumDigit; + }; + const calculateDigitCnpj = (numbersList) => { + const digit = calculateRestCnpj(calculateSumDigit(numbersList)); + return (digit >= 10) ? 0 : digit; + }; + const newCnpj = createCnpjNumber(); + return (mask) ? cnpjMask(newCnpj) : newCnpj; +}; +exports.default = { + validate: cnpjValidate, + mask: cnpjMask, + unmask: cnpjUnmask, + generate: cnpjGenerate, +}; diff --git a/node_modules/brazilian-doc-validator/dist/src/validator/cpf.js b/node_modules/brazilian-doc-validator/dist/src/validator/cpf.js new file mode 100644 index 0000000..564165f --- /dev/null +++ b/node_modules/brazilian-doc-validator/dist/src/validator/cpf.js @@ -0,0 +1,104 @@ +"use strict"; +/** + * CPF validation + * + * @param {string} cpf + * + * @returns {boolean} + * + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const cpfValidation = (cpf) => { + if (!Boolean(cpf)) + return false; + const onlyNumbers = cpf.replace(/\D/g, ''); + if (onlyNumbers.length < 11) + return false; + let adition; + let remainder; + adition = 0; + if (onlyNumbers === '00000000000') + return false; + for (let i = 1; i <= 9; i++) { + adition = adition + parseInt(onlyNumbers.substring(i - 1, i)) * (11 - i); + } + remainder = (adition * 10) % 11; + if ((remainder == 10) || (remainder == 11)) + remainder = 0; + if (remainder != parseInt(onlyNumbers.substring(9, 10))) + return false; + adition = 0; + for (let i = 1; i <= 10; i++) { + adition = adition + parseInt(onlyNumbers.substring(i - 1, i)) * (12 - i); + } + remainder = (adition * 10) % 11; + if ((remainder == 10) || (remainder == 11)) + remainder = 0; + if (remainder != parseInt(onlyNumbers.substring(10, 11))) + return false; + return true; +}; +/** + * CPF remove mask + * + * @param {string} cpf + * + * @returns {string} + * + */ +const cpfAddMask = (cpf) => { + if (cpfValidation(cpf)) { + const onlyNumbers = cpf.replace(/\D/g, ''); + return onlyNumbers.replace(/^(\d{3})(\d{3})(\d{3})(\d{2})*/, '$1.$2.$3-$4'); + } + return ''; +}; +/** + * CPF add mask + * + * @param {string} cpf + * + * @returns {string} + * + */ +const cpfRemoveMask = (cpf) => { + if (cpfValidation(cpf)) + return cpf.replace(/\D/g, ''); + return ''; +}; +/** + * CPF Generator + * + * @param {Record} options + * + * @return {string} + * + */ +const cpfGenerate = (options = { mask: true }) => { + const { mask } = options; + const createArray = (total, numero) => Array.from(Array(total), () => numberRandom(numero)); + const numberRandom = (number) => (Math.round(Math.random() * number)); + const mod = (dividendo, divisor) => Math.round(dividendo - (Math.floor(dividendo / divisor) * divisor)); + const array = createArray(9, 9); + const formulaReducer = (number, array) => { + return array.reduce((prevVal, elem, index) => { + return prevVal + elem * (number - index); + }, 0); + }; + let d1 = formulaReducer(10, array); + d1 = 11 - (mod(d1, 11)); + if (d1 >= 10) + d1 = 0; + let d2 = (d1 * 2) + formulaReducer(11, array); + d2 = 11 - (mod(d2, 11)); + if (d2 >= 10) + d2 = 0; + const newCpf = `${array.join('')}${d1}${d2}`; + return (mask) ? cpfAddMask(newCpf) : newCpf; +}; +exports.default = { + validate: cpfValidation, + mask: cpfAddMask, + unmask: cpfRemoveMask, + generate: cpfGenerate, +}; diff --git a/node_modules/brazilian-doc-validator/dist/tests/cnpj.test.js b/node_modules/brazilian-doc-validator/dist/tests/cnpj.test.js new file mode 100644 index 0000000..86b3ecc --- /dev/null +++ b/node_modules/brazilian-doc-validator/dist/tests/cnpj.test.js @@ -0,0 +1,65 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const cnpj_1 = __importDefault(require("../src/validator/cnpj")); +const emptyCnpj = ''; +const validCnpjMasked = '31.257.435/0001-40'; +const validCnpjUnmasked = '31257435000140'; +const invalidCnpjMasked = '31.257.435/0001-4'; +const invalidCnpjUnmasked = '3125743500014'; +describe('CNPJ Validation Test', () => { + it('Should validate a valid CNPJ number', () => { + const isValid = cnpj_1.default.validate(emptyCnpj); + expect(isValid).toBeFalsy(); + }); + it('Should validate a valid CNPJ masked number', () => { + const isValid = cnpj_1.default.validate(validCnpjMasked); + expect(isValid).toBeTruthy(); + }); + it('Should validate a valid CNPJ unmasked number', () => { + const isValid = cnpj_1.default.validate(validCnpjUnmasked); + expect(isValid).toBeTruthy(); + }); + it('Should validate a invalid CNPJ masked number', () => { + const isValid = cnpj_1.default.validate(invalidCnpjMasked); + expect(isValid).toBeFalsy(); + }); + it('Should validate a invalid CNPJ unmasked number', () => { + const isValid = cnpj_1.default.validate(invalidCnpjUnmasked); + expect(isValid).toBeFalsy(); + }); +}); +describe('CNPJ Mask Test', () => { + it('Should have mask on a valid cnpj or return empty string', () => { + const newCnpj = cnpj_1.default.mask(validCnpjUnmasked); + expect(newCnpj).toBe(validCnpjMasked); + }); + it('Should return empty string on invalid CNPJ', () => { + const newCnpj = cnpj_1.default.mask(invalidCnpjUnmasked); + expect(newCnpj).toBe(''); + }); +}); +describe('CNPJ Unmask Test', () => { + it('Should be unmasked string on a valid cnpj or return empty string', () => { + const newCnpj = cnpj_1.default.unmask(validCnpjMasked); + expect(newCnpj).toBe(validCnpjUnmasked); + }); + it('Should return empty string on invalid CNPJ', () => { + const newCnpj = cnpj_1.default.unmask(invalidCnpjUnmasked); + expect(newCnpj).toBe(''); + }); +}); +describe('CNPJ Generator Test', () => { + it('Should generate a valid cnpj', () => { + const newCnpj = cnpj_1.default.generate(); + const isValid = cnpj_1.default.validate(newCnpj); + expect(isValid).toBeTruthy(); + }); + it('Should generate a valid cnpj and formmat', () => { + const newCnpj = cnpj_1.default.generate({ format: true }); + const isValid = cnpj_1.default.validate(newCnpj); + expect(isValid).toBeTruthy(); + }); +}); diff --git a/node_modules/brazilian-doc-validator/dist/tests/cpf.test.js b/node_modules/brazilian-doc-validator/dist/tests/cpf.test.js new file mode 100644 index 0000000..c894aa4 --- /dev/null +++ b/node_modules/brazilian-doc-validator/dist/tests/cpf.test.js @@ -0,0 +1,74 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const cpf_1 = __importDefault(require("../src/validator/cpf")); +const emptyCpf = ''; +const validCpf = '047.145.880-52'; +const validOnlyNumbers = '04714588052'; +const invalidCpfLength = '047.145.880-5'; +const invalidCpf = '047.145.880-54'; +const invalidOnlyNumbers = '04714588054'; +describe('CPF Validation test', () => { + it('Correct check if CPF is null or empty', () => { + const isEmpty = cpf_1.default.validate(emptyCpf); + expect(isEmpty).toBeFalsy(); + }); + it('Correct check if CPF provided is valid', () => { + const isValid = cpf_1.default.validate(validCpf); + expect(isValid).toBeTruthy(); + }); + it('Correct check if CPF provided is invalid', () => { + const isValid = cpf_1.default.validate(invalidCpf); + expect(isValid).toBeFalsy(); + }); + it('Correct check if CPF provided has correct length', () => { + const isValid = cpf_1.default.validate(invalidCpfLength); + expect(isValid).toBeFalsy(); + }); + it('Correct check if CPF provided is 00000000000 ', () => { + const isValid = cpf_1.default.validate('00000000000'); + expect(isValid).toBeFalsy(); + }); +}); +describe('CPF Mask test', () => { + it('Correct check if CPF is null or empty', () => { + const isEmpty = cpf_1.default.mask(emptyCpf); + expect(isEmpty).toBe(''); + }); + it('Correct check if CPF is masked in the right format ', () => { + const valid = cpf_1.default.mask(validOnlyNumbers); + expect(valid).toBe(validCpf); + }); + it('Correct check if invalid CPF returns empty string', () => { + const invalid = cpf_1.default.mask(invalidOnlyNumbers); + expect(invalid).toBe(''); + }); +}); +describe('CPF Unmask test', () => { + it('Correct check if CPF is null or empty', () => { + const isEmpty = cpf_1.default.unmask(emptyCpf); + expect(isEmpty).toBe(''); + }); + it('Correct check if CPF unmasked (only numbers)', () => { + const valid = cpf_1.default.unmask(validCpf); + expect(valid).toBe(validOnlyNumbers); + }); + it('Correct check if invalid CPF returns empty string', () => { + const invalid = cpf_1.default.unmask(invalidOnlyNumbers); + expect(invalid).toBe(''); + }); +}); +describe('CPF Generator test', () => { + it('Correct check if generated CPF is valid and unmasked', () => { + const cpfGenerated = cpf_1.default.generate({ mask: true }); + const isValid = cpf_1.default.validate(cpfGenerated); + expect(isValid).toBeTruthy(); + }); + it('Correct check if generated CPF is valid and masked', () => { + const cpfGenerated = cpf_1.default.generate({ mask: false }); + const isValid = cpf_1.default.validate(cpfGenerated); + expect(isValid).toBeTruthy(); + }); +}); diff --git a/node_modules/brazilian-doc-validator/index.js b/node_modules/brazilian-doc-validator/index.js new file mode 100644 index 0000000..b91eb38 --- /dev/null +++ b/node_modules/brazilian-doc-validator/index.js @@ -0,0 +1 @@ +module.exports = require('./dist/index'); \ No newline at end of file diff --git a/node_modules/brazilian-doc-validator/index.ts b/node_modules/brazilian-doc-validator/index.ts new file mode 100644 index 0000000..2f2df48 --- /dev/null +++ b/node_modules/brazilian-doc-validator/index.ts @@ -0,0 +1,4 @@ +import cpf from "./src/validator/cpf"; +import cnpj from "./src/validator/cnpj"; + +export {cpf, cnpj}; \ No newline at end of file diff --git a/node_modules/brazilian-doc-validator/package.json b/node_modules/brazilian-doc-validator/package.json new file mode 100644 index 0000000..f34856a --- /dev/null +++ b/node_modules/brazilian-doc-validator/package.json @@ -0,0 +1,51 @@ +{ + "name": "brazilian-doc-validator", + "version": "1.0.5", + "description": "Validator for common brazilian patterns, such as cpf and cnpj validations. It is a npm package to be used in javascript applications", + "main": "index.js", + "scripts": { + "prepare": "npm run build", + "start": "tsc -b && node ./dist/index.js", + "build": "tsc -b", + "eslint": "eslint src/**/*.ts tests/**/*.ts", + "eslint-fix": "eslint --fix src/**/*.ts tests/**/*.ts", + "test": "jest --coverage" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/will-nakagawa/brazilian-doc-validator.git" + }, + "keywords": [ + "cpf", + "cnpj", + "validator", + "mask" + ], + "author": "William Nakagawa", + "license": "MIT", + "bugs": { + "url": "https://github.com/will-nakagawa/brazilian-doc-validator/issues" + }, + "homepage": "https://github.com/will-nakagawa/brazilian-doc-validator#readme", + "devDependencies": { + "@babel/preset-env": "^7.16.8", + "@babel/preset-typescript": "^7.16.7", + "@types/jest": "^27.4.0", + "@typescript-eslint/eslint-plugin": "^5.9.1", + "@typescript-eslint/parser": "^5.9.1", + "eslint": "^8.7.0", + "eslint-config-google": "^0.14.0", + "jest": "^27.4.7" + }, + "jest": { + "verbose": true, + "testPathIgnorePatterns": [ + "src/*", + "dist/*" + ], + "coverageDirectory": "coverage" + }, + "directories": { + "test": "tests" + } +} diff --git a/node_modules/brazilian-doc-validator/src/validator/cnpj.ts b/node_modules/brazilian-doc-validator/src/validator/cnpj.ts new file mode 100644 index 0000000..9b479e6 --- /dev/null +++ b/node_modules/brazilian-doc-validator/src/validator/cnpj.ts @@ -0,0 +1,158 @@ +/** + * CNPJ validation + * + * @param {string} cnpj + * + * @return {boolean} + * + */ +const cnpjValidate = (cnpj: string): boolean => { + const invalidCnpjList = [ + '00000000000000', + '11111111111111', + '22222222222222', + '33333333333333', + '44444444444444', + '55555555555555', + '66666666666666', + '77777777777777', + '88888888888888', + '99999999999999', + ]; + + if (!Boolean(cnpj) || invalidCnpjList.includes(cnpj)) return false; + + const onlyNumbers = cnpj.replace(/\D/g, ''); + + if (onlyNumbers.length < 14) return false; + + let length: number = onlyNumbers.length - 2; + let numbers: string = onlyNumbers.substring(0, length); + const digits: string = onlyNumbers.substring(length); + let addition: number = 0; + let pos: number = length - 7; + + for (let i = length; i >= 1; i--) { + addition += parseInt(numbers.charAt(length - i)) * pos--; + if (pos < 2) pos = 9; + } + + let result: number = addition % 11 < 2 ? 0 : 11 - addition % 11; + + if (result !== parseInt(digits.charAt(0))) return false; + + length = length + 1; + numbers = onlyNumbers.substring(0, length); + addition = 0; + pos = length - 7; + + for (let i = length; i >= 1; i--) { + addition += parseInt(numbers.charAt(length - i)) * pos--; + if (pos < 2) pos = 9; + } + + result = addition % 11 < 2 ? 0 : 11 - addition % 11; + + if (result !== parseInt(digits.charAt(1))) return false; + + return true; +}; + +/** + * CNPJ Mask + * + * @param {string} cnpj + * + * @return {string} + * + */ +const cnpjMask = (cnpj: string): string => { + if (cnpjValidate(cnpj)) { + const onlyNumbers: string = cnpj.replace(/\D/g, ''); + return onlyNumbers + .replace(/^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})*/, '$1.$2.$3/$4-$5'); + } + return ''; +}; + +/** + * CNPJ Unmask + * + * @param {string} cnpj + * + * @return {string} + * + */ +const cnpjUnmask = (cnpj: string): string => { + if (cnpjValidate(cnpj)) { + return cnpj.replace(/\D/g, ''); + } + return ''; +}; + +/** + * CNPJ Generation - Generates a valid CNPJ document. + * + * @param {Record} options + * + * @return {string} + * + */ +const cnpjGenerate = (options: Record = {mask: true}): string => { + const {mask} = options; + + const createCnpjNumber = (): string => { + const numbersList: number[] = createListNumber(); + + numbersList.push(calculateDigitCnpj(numbersList)); + return `${numbersList.join('')}${calculateDigitCnpj(numbersList)}`; + }; + + const createListNumber = () => { + const numbersList = []; + + for (let i = 0; i < 8; i++) { + numbersList.push(randomNumber()); + } + + for (let i = 0; i < 3; i++) { + numbersList.push(0); + } + + numbersList.push(1); + + return numbersList; + }; + + const randomNumber = () => Math.floor(Math.random() * 9); + + const calculateRestCnpj = (sumDigit: number) => sumDigit % 11; + + const calculateSumDigit = (numbersList: number[]) => { + let sumDigit: number = 0; + let salt: number = 9; + + for (let i = numbersList.length - 1; i >= 0; i--) { + sumDigit += numbersList[i] * salt--; + if (salt < 2) salt = 9; + } + + return sumDigit; + }; + + const calculateDigitCnpj = (numbersList:number[]) => { + const digit = calculateRestCnpj(calculateSumDigit(numbersList)); + return (digit >= 10) ? 0 : digit; + }; + + const newCnpj: string = createCnpjNumber(); + + return (mask) ? cnpjMask(newCnpj) : newCnpj; +}; + +export default { + validate: cnpjValidate, + mask: cnpjMask, + unmask: cnpjUnmask, + generate: cnpjGenerate, +}; diff --git a/node_modules/brazilian-doc-validator/src/validator/cpf.ts b/node_modules/brazilian-doc-validator/src/validator/cpf.ts new file mode 100644 index 0000000..f959197 --- /dev/null +++ b/node_modules/brazilian-doc-validator/src/validator/cpf.ts @@ -0,0 +1,128 @@ +/** + * CPF validation + * + * @param {string} cpf + * + * @returns {boolean} + * + */ + +const cpfValidation = (cpf: string): Boolean => { + if (!Boolean(cpf)) return false; + + const onlyNumbers: string = cpf.replace(/\D/g, ''); + + if (onlyNumbers.length < 11) return false; + + let adition: number; + let remainder: number; + + adition = 0; + + if (onlyNumbers === '00000000000') return false; + + for (let i = 1; i <= 9; i++) { + adition = adition + parseInt(onlyNumbers.substring(i - 1, i)) * (11 - i); + } + + remainder = (adition * 10) % 11; + + if ((remainder == 10) || (remainder == 11)) remainder = 0; + if (remainder != parseInt(onlyNumbers.substring(9, 10))) return false; + + adition = 0; + + for (let i = 1; i <= 10; i++) { + adition = adition + parseInt(onlyNumbers.substring(i - 1, i)) * (12 - i); + } + + remainder = (adition * 10) % 11; + + if ((remainder == 10) || (remainder == 11)) remainder = 0; + if (remainder != parseInt(onlyNumbers.substring(10, 11))) return false; + + return true; +}; + +/** + * CPF remove mask + * + * @param {string} cpf + * + * @returns {string} + * + */ + +const cpfAddMask = (cpf: string) => { + if (cpfValidation(cpf)) { + const onlyNumbers: string = cpf.replace(/\D/g, ''); + return onlyNumbers.replace(/^(\d{3})(\d{3})(\d{3})(\d{2})*/, '$1.$2.$3-$4'); + } + return ''; +}; + +/** + * CPF add mask + * + * @param {string} cpf + * + * @returns {string} + * + */ + +const cpfRemoveMask = (cpf: string): string => { + if (cpfValidation(cpf)) return cpf.replace(/\D/g, ''); + return ''; +}; + +/** + * CPF Generator + * + * @param {Record} options + * + * @return {string} + * + */ +const cpfGenerate = (options: Record = {mask: true}): string => { + const {mask} = options; + + const createArray = + (total: number, numero: number): number[] => Array.from( + Array(total), + () => numberRandom(numero), + ); + + const numberRandom = (number: number) => (Math.round(Math.random() * number)); + const mod = (dividendo: number, divisor: number): number => + Math.round(dividendo - (Math.floor(dividendo / divisor) * divisor)); + + const array: number[] = createArray(9, 9); + + const formulaReducer = (number: number, array: number[]): number => { + return array.reduce((prevVal, elem, index) => { + return prevVal + elem * (number - index); + }, 0); + }; + + let d1: number = formulaReducer(10, array); + + d1 = 11 - (mod(d1, 11)); + if (d1 >= 10) d1 = 0; + + let d2: number = (d1 * 2) + formulaReducer(11, array); + + d2 = 11 - (mod(d2, 11)); + + if (d2 >= 10) d2 = 0; + + const newCpf: string = `${array.join('')}${d1}${d2}`; + + return (mask) ? cpfAddMask(newCpf) : newCpf; +}; + +export default { + validate: cpfValidation, + mask: cpfAddMask, + unmask: cpfRemoveMask, + generate: cpfGenerate, +}; diff --git a/node_modules/brazilian-doc-validator/tests/cnpj.test.ts b/node_modules/brazilian-doc-validator/tests/cnpj.test.ts new file mode 100644 index 0000000..9d5cbbf --- /dev/null +++ b/node_modules/brazilian-doc-validator/tests/cnpj.test.ts @@ -0,0 +1,72 @@ +import cnpj from '../src/validator/cnpj'; + +const emptyCnpj = ''; +const validCnpjMasked = '31.257.435/0001-40'; +const validCnpjUnmasked = '31257435000140'; +const invalidCnpjMasked = '31.257.435/0001-4'; +const invalidCnpjUnmasked = '3125743500014'; + +describe('CNPJ Validation Test', () => { + it('Should validate a valid CNPJ number', () => { + const isValid = cnpj.validate(emptyCnpj); + expect(isValid).toBeFalsy(); + }); + + it('Should validate a valid CNPJ masked number', () => { + const isValid = cnpj.validate(validCnpjMasked); + expect(isValid).toBeTruthy(); + }); + + it('Should validate a valid CNPJ unmasked number', () => { + const isValid = cnpj.validate(validCnpjUnmasked); + expect(isValid).toBeTruthy(); + }); + + it('Should validate a invalid CNPJ masked number', () => { + const isValid = cnpj.validate(invalidCnpjMasked); + expect(isValid).toBeFalsy(); + }); + + it('Should validate a invalid CNPJ unmasked number', () => { + const isValid = cnpj.validate(invalidCnpjUnmasked); + expect(isValid).toBeFalsy(); + }); +}); + +describe('CNPJ Mask Test', () => { + it('Should have mask on a valid cnpj or return empty string', () => { + const newCnpj = cnpj.mask(validCnpjUnmasked); + expect(newCnpj).toBe(validCnpjMasked); + }); + + it('Should return empty string on invalid CNPJ', () => { + const newCnpj = cnpj.mask(invalidCnpjUnmasked); + expect(newCnpj).toBe(''); + }); +}); + +describe('CNPJ Unmask Test', () => { + it('Should be unmasked string on a valid cnpj or return empty string', () => { + const newCnpj = cnpj.unmask(validCnpjMasked); + expect(newCnpj).toBe(validCnpjUnmasked); + }); + + it('Should return empty string on invalid CNPJ', () => { + const newCnpj = cnpj.unmask(invalidCnpjUnmasked); + expect(newCnpj).toBe(''); + }); +}); + +describe('CNPJ Generator Test', () => { + it('Should generate a valid cnpj', () => { + const newCnpj = cnpj.generate(); + const isValid = cnpj.validate(newCnpj); + expect(isValid).toBeTruthy(); + }); + + it('Should generate a valid cnpj and formmat', () => { + const newCnpj = cnpj.generate({format: true}); + const isValid = cnpj.validate(newCnpj); + expect(isValid).toBeTruthy(); + }); +}); diff --git a/node_modules/brazilian-doc-validator/tests/cpf.test.ts b/node_modules/brazilian-doc-validator/tests/cpf.test.ts new file mode 100644 index 0000000..895a2e2 --- /dev/null +++ b/node_modules/brazilian-doc-validator/tests/cpf.test.ts @@ -0,0 +1,84 @@ +import cpf from '../src/validator/cpf'; + +const emptyCpf = ''; +const validCpf = '047.145.880-52'; +const validOnlyNumbers = '04714588052'; +const invalidCpfLength = '047.145.880-5'; +const invalidCpf = '047.145.880-54'; +const invalidOnlyNumbers = '04714588054'; + +describe('CPF Validation test', () => { + it('Correct check if CPF is null or empty', () => { + const isEmpty = cpf.validate(emptyCpf); + expect(isEmpty).toBeFalsy(); + }); + + it('Correct check if CPF provided is valid', () => { + const isValid = cpf.validate(validCpf); + expect(isValid).toBeTruthy(); + }); + + it('Correct check if CPF provided is invalid', () => { + const isValid = cpf.validate(invalidCpf); + expect(isValid).toBeFalsy(); + }); + + it('Correct check if CPF provided has correct length', () => { + const isValid = cpf.validate(invalidCpfLength); + expect(isValid).toBeFalsy(); + }); + + it('Correct check if CPF provided is 00000000000 ', () => { + const isValid = cpf.validate('00000000000'); + expect(isValid).toBeFalsy(); + }); +}); + +describe('CPF Mask test', () => { + it('Correct check if CPF is null or empty', () => { + const isEmpty = cpf.mask(emptyCpf); + expect(isEmpty).toBe(''); + }); + + it('Correct check if CPF is masked in the right format ', () => { + const valid = cpf.mask(validOnlyNumbers); + expect(valid).toBe(validCpf); + }); + + it('Correct check if invalid CPF returns empty string', () => { + const invalid = cpf.mask(invalidOnlyNumbers); + expect(invalid).toBe(''); + }); +}); + +describe('CPF Unmask test', () => { + it('Correct check if CPF is null or empty', () => { + const isEmpty = cpf.unmask(emptyCpf); + expect(isEmpty).toBe(''); + }); + + it('Correct check if CPF unmasked (only numbers)', () => { + const valid = cpf.unmask(validCpf); + expect(valid).toBe(validOnlyNumbers); + }); + + it('Correct check if invalid CPF returns empty string', () => { + const invalid = cpf.unmask(invalidOnlyNumbers); + expect(invalid).toBe(''); + }); +}); + +describe('CPF Generator test', () => { + it('Correct check if generated CPF is valid and unmasked', () => { + const cpfGenerated = cpf.generate({mask: true}); + const isValid = cpf.validate(cpfGenerated); + expect(isValid).toBeTruthy(); + }); + + it('Correct check if generated CPF is valid and masked', () => { + const cpfGenerated = cpf.generate({mask: false}); + const isValid = cpf.validate(cpfGenerated); + expect(isValid).toBeTruthy(); + }); +}); + diff --git a/node_modules/brazilian-doc-validator/tsconfig.json b/node_modules/brazilian-doc-validator/tsconfig.json new file mode 100644 index 0000000..e146310 --- /dev/null +++ b/node_modules/brazilian-doc-validator/tsconfig.json @@ -0,0 +1,101 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "resolveJsonModule": true, /* Enable importing .json files */ + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ab8f17a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,21 @@ +{ + "name": "poo", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "poo", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "brazilian-doc-validator": "^1.0.5" + } + }, + "node_modules/brazilian-doc-validator": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/brazilian-doc-validator/-/brazilian-doc-validator-1.0.5.tgz", + "integrity": "sha512-Hesu44EXF6WUBU9MJl20jeG3utChzzfZrPIl4lVj/PlvRTMobvRO7kC+Exch2SZkm+wlmRecrS+iQQ+/djCmNw==" + } + } +} diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 619e42e..ac70035 --- a/package.json +++ b/package.json @@ -9,5 +9,8 @@ }, "keywords": [], "author": "Luiz Picolo ", - "license": "MIT" + "license": "MIT", + "dependencies": { + "brazilian-doc-validator": "^1.0.5" + } } diff --git a/pessoa.js b/pessoa.js old mode 100644 new mode 100755 diff --git a/pessoa_fisica.js b/pessoa_fisica.js old mode 100644 new mode 100755 index 1c38b2a..e535a92 --- a/pessoa_fisica.js +++ b/pessoa_fisica.js @@ -1,4 +1,5 @@ import Pessoa from './pessoa.js' +import { cpf } from 'brazilian-doc-validator'; class PessoaFisica extends Pessoa { #_cpf @@ -7,8 +8,12 @@ class PessoaFisica extends Pessoa { super(nome) } - set cpf(cpf) { - this.#_cpf = cpf + set cpf(_cpf) { + if (cpf.validate(_cpf)){ + this.#_cpf = _cpf + } else { + throw new Error("CPF Inválido") + } } get cpf() { diff --git a/pessoa_juridica.js b/pessoa_juridica.js old mode 100644 new mode 100755