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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@

// Spell Checker
"cSpell.words": [
"cnpj",
"DMYS",
"injectables",
"Luma",
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

## [1.6.0] - 2021-11-03

### Added

- `isCnpj`
- `isMaskedCnpj`

### Changed

### Removed

## [1.5.0] - 2021-10-27

### Added
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ npm i @techmmunity/utils
| -------------------- | ----------------------------------------------------------------- |
| `isBetween` | Return true if value is a number between 2 values |
| `isBrazilianPhone` | Return true if value is a brazilian phone |
| `isCnpj` | Return true if value is a CNPJ |
| `isCpf` | Return true if value is a CPF |
| `isDarkHexColor` | Return true if value is a dark hex color |
| `isDate` | Return true if value is a valid date in the specified format |
Expand All @@ -102,6 +103,7 @@ npm i @techmmunity/utils
| `isIsoDate` | Return true if value is a ISO Date |
| `isLeap` | Return true if value is a leap year |
| `isLightHexColor` | Return true if value is a light hex color |
| `isMaskedCnpj` | Return true if value is a masked CNPJ |
| `isMaskedCpf` | Return true if value is a masked CPF |
| `isNumeric` | Return true if value is a numeric string |
| `isOdd` | Return true if value is a odd number |
Expand Down
6 changes: 3 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ module.exports = {
testTimeout: 15000,
coverageThreshold: {
global: {
statements: 99.17,
branches: 98.14,
statements: 99.04,
branches: 97.86,
functions: 100,
lines: 99.64,
lines: 99.68,
},
},
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@techmmunity/utils",
"version": "1.5.0",
"version": "1.6.0",
"main": "index.js",
"types": "index.d.ts",
"license": "Apache-2.0",
Expand Down
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export * from "./lib/has-url";

export * from "./lib/is-between";
export * from "./lib/is-brazilian-phone";
export * from "./lib/is-cnpj";
export * from "./lib/is-cpf";
export * from "./lib/is-dark-hex-color";
export * from "./lib/is-date";
Expand All @@ -68,6 +69,10 @@ export * from "./lib/is-int";
export * from "./lib/is-ipv4";
export * from "./lib/is-ipv4-with-mask";
export * from "./lib/is-iso-date";
export * from "./lib/is-leap";
export * from "./lib/is-light-hex-color";
export * from "./lib/is-masked-cnpj";
export * from "./lib/is-masked-cpf";
export * from "./lib/is-numeric";
export * from "./lib/is-odd";
export * from "./lib/is-package-installed";
Expand Down
76 changes: 76 additions & 0 deletions src/lib/is-cnpj/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* eslint-disable @typescript-eslint/no-magic-numbers */

import { getTypeof } from "../get-typeof";

/*
* CPF validation according to Receita Federal
* More info: https://www.geradorcnpj.com/algoritmo_do_cnpj.htm
*/

const notCnpj = [
"00000000000000",
"11111111111111",
"22222222222222",
"33333333333333",
"44444444444444",
"55555555555555",
"66666666666666",
"77777777777777",
"88888888888888",
"99999999999999",
];

/**
* Check if a string is a valid cpf
* - 55357314047
*/
export const isCnpj = (cnpj: string) => {
if (getTypeof(cnpj) !== "string") return false;

if (cnpj === "") return false;

if (cnpj.length !== 14) return false;

if (notCnpj.includes(cnpj)) return false;

let length = cnpj.length - 2;
let numbers = cnpj.substring(0, length);
const digits = cnpj.substring(length);
let sum = 0;
let pos = length - 7;

for (let i = length; i >= 1; i--) {
const nbr = parseInt(numbers.charAt(length - i), 10);

sum += nbr * pos--;

if (pos < 2) pos = 9;
}

let result = sum % 11 < 2 ? 0 : 11 - (sum % 11);

const firstChar = parseInt(digits.charAt(0), 10);

if (result !== firstChar) return false;

length += 1;
numbers = cnpj.substring(0, length);
sum = 0;
pos = length - 7;

for (let i = length; i >= 1; i--) {
const nbr = parseInt(numbers.charAt(length - i), 10);

sum += nbr * pos--;

if (pos < 2) pos = 9;
}

result = sum % 11 < 2 ? 0 : 11 - (sum % 11);

const secondChar = parseInt(digits.charAt(1), 10);

if (result !== secondChar) return false;

return true;
};
2 changes: 2 additions & 0 deletions src/lib/is-cpf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const notCpf = [
export const isCpf = (cpf: string) => {
if (getTypeof(cpf) !== "string") return false;

if (cpf === "") return false;

let temp: string;
let count: number;
let total: number;
Expand Down
9 changes: 9 additions & 0 deletions src/lib/is-masked-cnpj/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getTypeof } from "../get-typeof";
import { isCnpj } from "../is-cnpj";

const MASKED_CNPJ = /^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/;

export const isMaskedCNPJ = (maskedCNPJ: string) =>
getTypeof(maskedCNPJ) === "string" &&
MASKED_CNPJ.test(maskedCNPJ) &&
isCnpj(maskedCNPJ.replace(/[^\d]+/g, ""));
2 changes: 1 addition & 1 deletion src/lib/is-masked-cpf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ const MASKED_CPF = /^\d{3}\.\d{3}\.\d{3}-\d{2}$/;
export const isMaskedCpf = (maskedCPF: string) =>
getTypeof(maskedCPF) === "string" &&
MASKED_CPF.test(maskedCPF) &&
isCpf(maskedCPF.replace(/\D/g, ""));
isCpf(maskedCPF.replace(/[^\d]+/g, ""));
57 changes: 57 additions & 0 deletions src/tests/is-cnpj.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { isCnpj } from "../lib/is-cnpj";

/**
*
* True
*
*/

describe("isCnpj (return True)", () => {
it("with valid cnpj (1)", () => {
expect(isCnpj("25024527000187")).toBe(true);
});

it("with valid cnpj (2)", () => {
expect(isCnpj("46884275000136")).toBe(true);
});

it("with valid cnpj (3)", () => {
expect(isCnpj("60722144000183")).toBe(true);
});

it("with valid cnpj (4)", () => {
expect(isCnpj("82304005000172")).toBe(true);
});

it("with valid cnpj (5)", () => {
expect(isCnpj("67141300000161")).toBe(true);
});
});

/**
*
* False
*
*/

describe("isCnpj (return False)", () => {
it("with empty cnpj", () => {
expect(isCnpj("")).toBe(false);
});

it("with masked cnpj", () => {
expect(isCnpj("67.141.300/0001-61")).toBe(false);
});

it("with invalid cnpj (1)", () => {
expect(isCnpj("00000000000000")).toBe(false);
});

it("with invalid cnpj (2)", () => {
expect(isCnpj("38048166000151")).toBe(false);
});

it("with invalid type", () => {
expect(isCnpj(32457606000147 as any)).toBe(false);
});
});
4 changes: 4 additions & 0 deletions src/tests/is-cpf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ describe("isCpf (return True)", () => {
*/

describe("isCpf (return False)", () => {
it("with empty cpf", () => {
expect(isCpf("")).toBe(false);
});

it("with masked cpf", () => {
expect(isCpf("553.573.140-47")).toBe(false);
});
Expand Down
49 changes: 49 additions & 0 deletions src/tests/is-masked-cnpj.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { isMaskedCNPJ } from "../lib/is-masked-cnpj";

/**
*
* True
*
*/

describe("isMaskedCNPJ (return True)", () => {
it("with valid cnpj (1)", () => {
expect(isMaskedCNPJ("30.424.723/0001-89")).toBe(true);
});

it("with valid cnpj (2)", () => {
expect(isMaskedCNPJ("17.024.335/0001-42")).toBe(true);
});

it("with valid cnpj (3)", () => {
expect(isMaskedCNPJ("56.440.046/0001-86")).toBe(true);
});

it("with valid cnpj (4)", () => {
expect(isMaskedCNPJ("63.551.672/0001-05")).toBe(true);
});

it("with valid cnpj (5)", () => {
expect(isMaskedCNPJ("58.410.040/0001-91")).toBe(true);
});
});

/**
*
* False
*
*/

describe("isMaskedCNPJ (return False)", () => {
it("with unmasked cnpj (1)", () => {
expect(isMaskedCNPJ("58410040000191")).toBe(false);
});

it("with invalid cnpj (1)", () => {
expect(isMaskedCNPJ("00.000.000/0000-00")).toBe(false);
});

it("with invalid cnpj (2)", () => {
expect(isMaskedCNPJ("18.424.560/0001-31")).toBe(false);
});
});