validation-br 0.8.3 → 1.0.0-b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.js +76 -11
  3. package/.github/workflows/test.yml +39 -0
  4. package/.prettierignore +1 -0
  5. package/.prettierrc.js +7 -0
  6. package/dist/cnh.js +123 -0
  7. package/dist/cnh.js.map +1 -0
  8. package/dist/cnh.test.js +117 -0
  9. package/dist/cnh.test.js.map +1 -0
  10. package/dist/cnpj.js +112 -0
  11. package/dist/cnpj.js.map +1 -0
  12. package/dist/cnpj.test.js +141 -0
  13. package/dist/cnpj.test.js.map +1 -0
  14. package/dist/cpf.js +134 -0
  15. package/dist/cpf.js.map +1 -0
  16. package/dist/cpf.test.js +130 -0
  17. package/dist/cpf.test.js.map +1 -0
  18. package/dist/index.js +24 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/index.test.js +33 -0
  21. package/dist/index.test.js.map +1 -0
  22. package/dist/judicialProcess.js +153 -0
  23. package/dist/judicialProcess.js.map +1 -0
  24. package/dist/judicialProcess.test.js +123 -0
  25. package/dist/judicialProcess.test.js.map +1 -0
  26. package/dist/pisPasep.js +113 -0
  27. package/dist/pisPasep.js.map +1 -0
  28. package/dist/pisPasep.test.js +129 -0
  29. package/dist/pisPasep.test.js.map +1 -0
  30. package/dist/postalCode.js +150 -0
  31. package/dist/postalCode.js.map +1 -0
  32. package/dist/postalCode.test.js +135 -0
  33. package/dist/postalCode.test.js.map +1 -0
  34. package/dist/renavam.js +108 -0
  35. package/dist/renavam.js.map +1 -0
  36. package/dist/renavam.test.js +113 -0
  37. package/dist/renavam.test.js.map +1 -0
  38. package/dist/tituloEleitor.js +130 -0
  39. package/dist/tituloEleitor.js.map +1 -0
  40. package/dist/tituloEleitor.test.js +132 -0
  41. package/dist/tituloEleitor.test.js.map +1 -0
  42. package/dist/utils-applyMask.test.js +17 -0
  43. package/dist/utils-applyMask.test.js.map +1 -0
  44. package/dist/utils-clearValue.test.js +50 -0
  45. package/dist/utils-clearValue.test.js.map +1 -0
  46. package/dist/utils-fakeNumber.test.js +17 -0
  47. package/dist/utils-fakeNumber.test.js.map +1 -0
  48. package/dist/utils-insertAtPosition.test.js +16 -0
  49. package/dist/utils-insertAtPosition.test.js.map +1 -0
  50. package/dist/utils-invalidListGenerator.test.js +23 -0
  51. package/dist/utils-invalidListGenerator.test.js.map +1 -0
  52. package/dist/utils-removeFromPosition.test.js +16 -0
  53. package/dist/utils-removeFromPosition.test.js.map +1 -0
  54. package/dist/utils-sumElementsByMultipliers.test.js +32 -0
  55. package/dist/utils-sumElementsByMultipliers.test.js.map +1 -0
  56. package/dist/utils-sumToDV.test.js +16 -0
  57. package/dist/utils-sumToDV.test.js.map +1 -0
  58. package/dist/utils.js +167 -0
  59. package/dist/utils.js.map +1 -0
  60. package/jest.config.js +14 -0
  61. package/package.json +40 -48
  62. package/readme.md +243 -88
  63. package/src/cnh.test.ts +114 -0
  64. package/src/cnh.ts +140 -0
  65. package/src/cnpj.test.ts +136 -0
  66. package/{dist/documents/cnpj.js → src/cnpj.ts} +74 -21
  67. package/src/cpf.test.ts +125 -0
  68. package/src/cpf.ts +150 -0
  69. package/src/index.test.ts +35 -0
  70. package/src/index.ts +19 -0
  71. package/src/judicialProcess.test.ts +118 -0
  72. package/src/judicialProcess.ts +167 -0
  73. package/src/pisPasep.test.ts +124 -0
  74. package/src/pisPasep.ts +128 -0
  75. package/src/postalCode.test.ts +132 -0
  76. package/src/postalCode.ts +164 -0
  77. package/src/renavam.test.ts +110 -0
  78. package/src/renavam.ts +122 -0
  79. package/src/tituloEleitor.test.ts +129 -0
  80. package/src/tituloEleitor.ts +146 -0
  81. package/src/utils-applyMask.test.ts +17 -0
  82. package/src/utils-clearValue.test.ts +55 -0
  83. package/src/utils-fakeNumber.test.ts +19 -0
  84. package/src/utils-insertAtPosition.test.ts +15 -0
  85. package/src/utils-invalidListGenerator.test.ts +27 -0
  86. package/src/utils-removeFromPosition.test.ts +15 -0
  87. package/src/utils-sumElementsByMultipliers.test.ts +34 -0
  88. package/src/utils-sumToDV.test.ts +16 -0
  89. package/src/utils.ts +172 -0
  90. package/tsconfig.json +23 -0
  91. package/.babelrc +0 -15
  92. package/.prettierrc +0 -9
  93. package/dist/documents/cnh.js +0 -77
  94. package/dist/documents/cnh.js.map +0 -1
  95. package/dist/documents/cnpj.js.map +0 -1
  96. package/dist/documents/cpf.js +0 -83
  97. package/dist/documents/cpf.js.map +0 -1
  98. package/dist/documents/index.js +0 -23
  99. package/dist/documents/index.js.map +0 -1
  100. package/dist/documents/pis-pasep.js +0 -71
  101. package/dist/documents/pis-pasep.js.map +0 -1
  102. package/dist/documents/postal-code.js +0 -72
  103. package/dist/documents/postal-code.js.map +0 -1
  104. package/dist/documents/titulo-eleitor.js +0 -74
  105. package/dist/documents/titulo-eleitor.js.map +0 -1
  106. package/dist/lib/utils.js +0 -60
  107. package/dist/lib/utils.js.map +0 -1
  108. package/docs.md +0 -0
  109. package/index.js +0 -3
@@ -0,0 +1,167 @@
1
+ /**
2
+ * judicialProcess
3
+ * Valida, mascara e cria números de processos judiciais
4
+ *
5
+ * @link
6
+ * https://juslaboris.tst.jus.br/bitstream/handle/20.500.12178/30318/2008_res0065_cnj_rep01.pdf?sequence=2
7
+ * http://ghiorzi.org/DVnew.htm#f
8
+ *
9
+ * @doc
10
+ * Os números de processos judiciais são usados a partir de 2010 para unificar a
11
+ * numeração de processos no Brasil e são usados em todos os tribunais.
12
+ *
13
+ * O número do processo, sem os caracteres especiais, devem possuir até 20 números
14
+ * e deve seguir o padrão abaixo:
15
+ *
16
+ * 1) Partes do número
17
+ * 0002080-25.2012.5.15.0049
18
+ * NNNNNNN-DD.AAAA.J.TR.OOOO
19
+ * |______|__|____|_|__|____|
20
+ * | | | | | |----> Unidade de origem do processo com 4 caracteres
21
+ * | | | | |--------> TR=Tribunal do segmento do poder judiciário com 2 caracteres
22
+ * | | | |----------> J=Órgão do poder Judiciário com 1 caractere
23
+ * | | |-------------> Ano do ajuizamento do processo com 4 caracteres
24
+ * | |-----------------> Dígito verificador com 2 caracteres
25
+ * |----------------------> Número sequencial do Processo, por unidade de
26
+ * origem, reiniciado anualmente com 7 caracteres
27
+ *
28
+ * Órgãos do Poder Judiciário
29
+ * 1 - Supremo Tribunal Federal
30
+ * 2 - Conselho Nacional de Justiça
31
+ * 3 - Superior Tribunal de Justiça
32
+ * 4 - Justiça Federal
33
+ * 5 - Justiça do Trabalho
34
+ * 6 - Justiça Eleitoral
35
+ * 7 - Justiça Militar da União
36
+ * 8 - Justiça dos Estados e do Distrito Federal e Territórios
37
+ * 9 - Justiça Militar Estadual
38
+ *
39
+ *
40
+ * 2) Dígito Verificador
41
+ *
42
+ * O algoritmo usado para o cálculo do DV chama-se Módulo 97 de Base 10 (ISO 7064).
43
+ *
44
+ * Nota: O número do processo possui 20 caracteres e ultrapassa o tamanho máximo
45
+ * do inteiro em javascript, impedindo que façamos o cálculo diretamente, desta
46
+ * forma, será nacessária uma fatoração para que o resultado seja o correto.
47
+ *
48
+ * 2.1) Cálculo do DV
49
+ * - Caso o DV seja conhecido, ele precisa ser removido do número e colocado
50
+ * como "00" ao final. Caso não esteja incluso no número, adicione '00' ao final.
51
+ *
52
+ * Ex.: O processo "00020802520125150049", cujo dv é "25", será calculado como
53
+ * "000208020125150049" e receberá "00" ao final. O número usado para o cálculo
54
+ * do DV será "00020802012515004900"
55
+ *
56
+ * 2.2) Etapas de Cálculo
57
+ *
58
+ * 00020802012515004900
59
+ * ↓↓
60
+ * DV ao final como "00"
61
+ *
62
+ * - Aplicamos o MOD 97 aos caracteres de 0 a 7 para calcular a primeira parte
63
+ * part1 = 0002080 % 97 = 43
64
+ *
65
+ * - Concatenamos part1 ao ano, órgão do poder judiciário e tribunal e aplicamos o MOD 97
66
+ * para obtermos o valor da part2
67
+ * part2 = ( part1 +''+ 2012 +''+ 5 +''+ 15 ) % 97 = 26
68
+ *
69
+ * - Concatemos part2 ao código do órgão de origem e ao "00" do final e aplicamos
70
+ * o MOD 97 ao resultado
71
+ * part3 = ( part2 + '0049' + '00') % 97 = 73
72
+ *
73
+ * - Subtraímos o resultado de 98
74
+ * dv = 98 - 73 = 25
75
+ *
76
+ * O Dígito verificador é 25 e deve ser aplicado após o 7º caractere do número do processo
77
+ *
78
+ * Fonte: https://juslaboris.tst.jus.br/bitstream/handle/20.500.12178/30318/2008_res0065_cnj_rep01.pdf?sequence=2
79
+ */
80
+
81
+ import { clearValue, fakeNumber, applyMask, insertAtPosition, removeFromPosition } from './utils'
82
+
83
+ /**
84
+ *
85
+ *
86
+ */
87
+ export const dv = (value: string): string => {
88
+ if (!value) throw new Error('Número do processo é obrigatório')
89
+ // if (typeof value !== 'string') throw new Error('Número do processo precisa ser string')
90
+
91
+ const judicialProcess = clearValue(value, 18)
92
+
93
+ const num = judicialProcess.substring(0, 7)
94
+ const yearAndCourt = judicialProcess.substring(7, 14)
95
+ const origin = judicialProcess.substring(14, 18)
96
+
97
+ return String(
98
+ 98 - (Number(`${Number(`${Number(num) % 97}${yearAndCourt}`) % 97}${origin}00`) % 97),
99
+ ).padStart(2, '0')
100
+ }
101
+
102
+ /**
103
+ * Aplica uma máscara ao número informado
104
+ *
105
+ * @param {String} value Número de Processo
106
+ * @returns {String} Valor com a máscara
107
+ */
108
+ export const mask = (value: string | number): string =>
109
+ applyMask(value, '0000000-00.0000.0.00.0000')
110
+
111
+ /**
112
+ *
113
+ *
114
+ */
115
+ export const fake = (withMask: boolean = false): string => {
116
+ const num = fakeNumber(7, true)
117
+ const year = new Date().getFullYear() - +fakeNumber(1)
118
+
119
+ const courte1 = fakeNumber(1, true) // Não pode ser '0'
120
+ const courte2 = fakeNumber(2, true)
121
+ const courte = `${courte1 === '0' || courte1 === '10' ? '1' : courte1}${courte2}`
122
+
123
+ const origin = fakeNumber(4, true)
124
+
125
+ const judicialProcess = `${num}${year}${courte}${origin}`
126
+ const digits = dv(judicialProcess)
127
+
128
+ const finalNumber = insertAtPosition(judicialProcess, digits, 7)
129
+
130
+ if (withMask) return mask(finalNumber)
131
+ return finalNumber
132
+ }
133
+
134
+ /**
135
+ * validate()
136
+ * Valida se um número de processo está correto
137
+ *
138
+ */
139
+ export const validateOrFail = (value: string | number): boolean => {
140
+ const judicialProcess = clearValue(value, 20)
141
+ const processWithoutDV = removeFromPosition(judicialProcess, 7, 9)
142
+
143
+ if (processWithoutDV.substring(11, 12) === '0') {
144
+ throw new Error('Código do Órgão Judiciário não pode ser "0"')
145
+ }
146
+
147
+ if (dv(processWithoutDV) !== judicialProcess.substring(7, 9)) {
148
+ throw new Error('Dígito verificador inválido')
149
+ }
150
+
151
+ return true
152
+ }
153
+
154
+ /**
155
+ * validate()
156
+ * Valida se um número de processo está correto
157
+ *
158
+ */
159
+ export const validate = (value: string | number): boolean => {
160
+ try {
161
+ return validateOrFail(value)
162
+ } catch (error) {
163
+ return false
164
+ }
165
+ }
166
+
167
+ export default validate
@@ -0,0 +1,124 @@
1
+ import isPIS, { dv, fake, mask, validate, validateOrFail } from './pisPasep'
2
+
3
+ describe('PIS', () => {
4
+ test('isPIS() - Números válidos', () => {
5
+ const list = [
6
+ // string
7
+ '71282677380',
8
+ '23795126955',
9
+ // integer
10
+ 50012973803,
11
+ 27890141144,
12
+ // masked
13
+ '268.27649.96-0',
14
+ '613.01862.91-7',
15
+ ]
16
+
17
+ list.forEach((pis) => {
18
+ expect(isPIS(pis)).toBeTruthy()
19
+ })
20
+ })
21
+
22
+ test('validate() - Números válidos', () => {
23
+ const list = [
24
+ // string
25
+ '71282677380',
26
+ '23795126955',
27
+ // integer
28
+ 50012973803,
29
+ 27890141144,
30
+ // masked
31
+ '268.27649.96-0',
32
+ '613.01862.91-7',
33
+ ]
34
+
35
+ list.forEach((pis) => {
36
+ expect(validate(pis)).toBeTruthy()
37
+ })
38
+ })
39
+
40
+ test('validate() - Números inválidos', () => {
41
+ const list = [
42
+ '712.82677.38-2',
43
+ '237.95126.95-4',
44
+ '500.12973.80-1',
45
+ '278.90141.14-9',
46
+ '268.27649.96-2',
47
+ '613.01862.91-4',
48
+ '111.11111.11-1',
49
+ ]
50
+
51
+ list.forEach((pis) => {
52
+ expect(validate(pis)).toBeFalsy()
53
+ })
54
+ })
55
+
56
+ test('validateOrFail() - Números inválidos', () => {
57
+ const list = [
58
+ '712.82677.38-2',
59
+ '237.95126.95-4',
60
+ '500.12973.80-1',
61
+ '278.90141.14-9',
62
+ '268.27649.96-2',
63
+ '613.01862.91-4',
64
+ '111.11111.11-1',
65
+ ]
66
+
67
+ list.forEach((pis) => {
68
+ expect(() => validateOrFail(pis)).toThrow()
69
+ })
70
+ })
71
+
72
+ test('Parâmetro não informado', () => {
73
+ expect(isPIS('')).toBeFalsy()
74
+ expect(validate('')).toBeFalsy()
75
+ expect(() => validateOrFail('')).toThrow()
76
+ expect(() => dv('')).toThrow()
77
+ })
78
+
79
+ test('fake() - Gera fakes sem máscara', () => {
80
+ for (let i = 0; i < 5; i += 1) {
81
+ const pis = fake()
82
+ expect(validate(pis)).toBeTruthy()
83
+ expect(pis).toHaveLength(11)
84
+ }
85
+ })
86
+
87
+ test('fake() - Gera fakes com máscara', () => {
88
+ for (let i = 0; i < 5; i += 1) {
89
+ const pis = fake(true)
90
+ expect(validate(pis)).toBeTruthy()
91
+ expect(pis).toHaveLength(14)
92
+ }
93
+ })
94
+
95
+ test('dv() - Verificando se o DV gerado está correto', () => {
96
+ const list = [
97
+ { num: '7128267738', expected: '0' },
98
+ { num: 2379512695, expected: '5' },
99
+ { num: '5001297380', expected: '3' },
100
+ ]
101
+
102
+ list.forEach((item) => {
103
+ const calcDv = dv(item.num)
104
+
105
+ expect(calcDv).toBe(item.expected)
106
+ expect(typeof calcDv).toBe('string')
107
+ })
108
+ })
109
+
110
+ test('mask() - Testando se a máscara foi gerada corretamente', () => {
111
+ const list = [
112
+ { num: '71282677380', expected: '712.82677.38-0' },
113
+ { num: 23795126955, expected: '237.95126.95-5' },
114
+ { num: '50012973803', expected: '500.12973.80-3' },
115
+ ]
116
+
117
+ list.forEach((item) => {
118
+ const masked = mask(item.num)
119
+
120
+ expect(masked).toBe(item.expected)
121
+ expect(masked).toHaveLength(14)
122
+ })
123
+ })
124
+ })
@@ -0,0 +1,128 @@
1
+ /**
2
+ * isPIS()
3
+ * Calcula se um código de PIS/PASEP/NIS/NIT no formato 268.27649.96-0 é válido. Não
4
+ * valida o formato, portanto, 26827649960 é equivalente a 268.27649.96-0 para efeitos
5
+ * desta validação.
6
+ *
7
+ * @doc
8
+ * - O número de PIS deve possuir 11 caracteres
9
+ *
10
+ * - Os caracteres de 1 a 10 são a numeração documento
11
+ *
12
+ * - O caractere 11 é o dígito verificador.
13
+ *
14
+ * 1) Partes do número
15
+ * _______________________________________________
16
+ * | Número | D V |
17
+ * | 2 6 8 . 2 7 6 4 9 . 9 6 - 0 |
18
+ * |_________________________________________|_____|
19
+ *
20
+ * 2) Cálculo do DV.
21
+ *
22
+ * - Soma-se o produto das algarismos 3 a 10 pelos números 3, 2, 9, 8, 7, 6, 5, 4, 3, 2
23
+ *
24
+ * 2 6 8 2 7 6 4 9 9 6
25
+ * x x x x x x x x x x
26
+ * 3 2 9 8 7 6 5 4 3 2
27
+ * = 6 +12 +72 +16 +49 +12 +20 +36 +27 +12 = 234
28
+ *
29
+ * - O somatório encontrado é dividido por 11 e o resultado é subtraído de 11
30
+ * 234 / 11 tem resto 3. 11 - 3 = 8. DV1 é 8.
31
+ * Obs.: Caso o cálculo de DV1 retorne 0, o resultado será 5.
32
+ * Caso retorne 1, o resto será 0
33
+ *
34
+ *
35
+ *
36
+ *
37
+ * Fonte: http://www.macoratti.net/alg_pis.htm
38
+ *
39
+ * @param {String} value Objeto postal no formato 268.27649.96-0
40
+ * @returns {Boolean}
41
+ */
42
+
43
+ import {
44
+ invalidListGenerator,
45
+ sumElementsByMultipliers,
46
+ sumToDV,
47
+ clearValue,
48
+ fakeNumber,
49
+ applyMask,
50
+ } from './utils'
51
+
52
+ /**
53
+ * dv()
54
+ * Calcula o dígito verificador
55
+ *
56
+ * @param {Number|String} value
57
+ * @returns {String}
58
+ */
59
+ export const dv = (value: string | number): string => {
60
+ if (!value) throw new Error('PIS não informado')
61
+
62
+ const pis = clearValue(value, 10)
63
+
64
+ const invalidList = invalidListGenerator(10)
65
+ if (invalidList.includes(pis)) {
66
+ throw new Error('PIS não pode ser uma sequência de números iguais')
67
+ }
68
+
69
+ const sum = sumElementsByMultipliers(pis, [3, 2, 9, 8, 7, 6, 5, 4, 3, 2])
70
+
71
+ return String(sumToDV(sum))
72
+ }
73
+
74
+ /**
75
+ * Aplica uma máscara ao número informado
76
+ *
77
+ * @param {String} value Número de Processo
78
+ * @returns {String} Valor com a máscara
79
+ */
80
+ export const mask = (value: string | number): string => applyMask(value, '000.00000.00-0')
81
+
82
+ /**
83
+ * fake()
84
+ * Gera um número válido
85
+ *
86
+ * @returns {String}
87
+ */
88
+ export const fake = (withMask: boolean = false): string => {
89
+ const num = fakeNumber(10, true)
90
+
91
+ const pis = `${num}${dv(num)}`
92
+
93
+ if (withMask) return mask(pis)
94
+ return pis
95
+ }
96
+
97
+ /**
98
+ * validateOrFail()
99
+ * Valida se um número de processo está correto e
100
+ * retorna uma exceção se não estiver
101
+ *
102
+ * @returns {Boolean}
103
+ */
104
+ export const validateOrFail = (value: string | number): boolean => {
105
+ const pis = clearValue(value, 11)
106
+
107
+ if (dv(pis) !== pis.substring(10, 11)) {
108
+ throw new Error('Dígito verificador inválido')
109
+ }
110
+
111
+ return true
112
+ }
113
+
114
+ /**
115
+ * validate()
116
+ * Valida se um número de processo está correto
117
+ *
118
+ * @returns {Boolean}
119
+ */
120
+ export const validate = (value: string | number): boolean => {
121
+ try {
122
+ return validateOrFail(value)
123
+ } catch (error) {
124
+ return false
125
+ }
126
+ }
127
+
128
+ export default validate
@@ -0,0 +1,132 @@
1
+ import isPostalCode, { dv, fake, mask, validate, validateOrFail } from './postalCode'
2
+
3
+ describe('PostalCode', () => {
4
+ test('isPostalCode() - Números válidos', () => {
5
+ const list = [
6
+ 'PN718252423BR',
7
+ 'PO925539762BR',
8
+ 'JT194690698BR',
9
+ 'SV143851674BR',
10
+ 'RG727348650CN',
11
+ 'RY747622885CN',
12
+ 'RY728187035CN',
13
+ 'RH940629235CN',
14
+ 'RY686586175CN',
15
+ 'RY648001205CN',
16
+ 'UJ776469464CN',
17
+ 'LZ667841882CN',
18
+ 'RS737783818NL',
19
+ ]
20
+
21
+ list.forEach((postalCode) => {
22
+ expect(isPostalCode(postalCode)).toBeTruthy()
23
+ })
24
+ })
25
+
26
+ test('validate() - Números válidos', () => {
27
+ const list = [
28
+ 'PN718252423BR',
29
+ 'PO925539762BR',
30
+ 'JT194690698BR',
31
+ 'SV143851674BR',
32
+ 'RG727348650CN',
33
+ 'RY747622885CN',
34
+ 'RY728187035CN',
35
+ 'RH940629235CN',
36
+ 'RY686586175CN',
37
+ 'RY648001205CN',
38
+ 'UJ776469464CN',
39
+ 'LZ667841882CN',
40
+ 'RS737783818NL',
41
+ ]
42
+
43
+ list.forEach((postalCode) => {
44
+ expect(validate(postalCode)).toBeTruthy()
45
+ })
46
+ })
47
+
48
+ test('validate() - Números inválidos', () => {
49
+ const list = [
50
+ 'PO925524762BR',
51
+ 'JT194624698BR',
52
+ 'SV143824674BR',
53
+ 'RG727324650CN',
54
+ 'RY747624885CN',
55
+ 'RY728114035CN',
56
+ ]
57
+
58
+ list.forEach((postalCode) => {
59
+ expect(validate(postalCode)).toBeFalsy()
60
+ })
61
+ })
62
+
63
+ test('validateOrFail() - Números inválidos', () => {
64
+ const list = [
65
+ 'PO925524762BR',
66
+ 'JT194624698BR',
67
+ 'SV143824674BR',
68
+ 'RG727324650CN',
69
+ 'RY747624885CN',
70
+ 'RY728114035CN',
71
+ ]
72
+
73
+ list.forEach((postalCode) => {
74
+ expect(() => validateOrFail(postalCode)).toThrow()
75
+ })
76
+ })
77
+
78
+ test('Parâmetro não informado', () => {
79
+ expect(isPostalCode('')).toBeFalsy()
80
+ expect(validate('')).toBeFalsy()
81
+ expect(() => validateOrFail('')).toThrow()
82
+ expect(() => dv('')).toThrow()
83
+ })
84
+
85
+ test('fake() - Gera fakes sem máscara', () => {
86
+ for (let i = 0; i < 5; i += 1) {
87
+ const postalCode = fake()
88
+
89
+ expect(validate(postalCode)).toBeTruthy()
90
+ expect(postalCode).toHaveLength(13)
91
+ }
92
+ })
93
+
94
+ test('fake() - Gera fakes com máscara', () => {
95
+ for (let i = 0; i < 5; i += 1) {
96
+ const postalCode = fake(true)
97
+
98
+ expect(validate(postalCode)).toBeTruthy()
99
+ expect(postalCode).toHaveLength(13)
100
+ }
101
+ })
102
+
103
+ test('dv() - Verificando se o DV gerado está correto', () => {
104
+ const list = [
105
+ { num: 'PN718252423BR', expected: '3' },
106
+ { num: 'PO925539762BR', expected: '2' },
107
+ { num: 'JT194690698BR', expected: '8' },
108
+ ]
109
+
110
+ list.forEach((item) => {
111
+ const calcDv = dv(item.num)
112
+
113
+ expect(calcDv).toBe(item.expected)
114
+ expect(typeof calcDv).toBe('string')
115
+ })
116
+ })
117
+
118
+ test('mask() - Testando se a máscara foi gerada corretamente', () => {
119
+ const list = [
120
+ { num: 'pn718252423br', expected: 'PN718252423BR' },
121
+ { num: 'po925539762br', expected: 'PO925539762BR' },
122
+ { num: 'jt194690698br', expected: 'JT194690698BR' },
123
+ ]
124
+
125
+ list.forEach((item) => {
126
+ const masked = mask(item.num)
127
+
128
+ expect(masked).toBe(item.expected)
129
+ expect(masked).toHaveLength(13)
130
+ })
131
+ })
132
+ })
@@ -0,0 +1,164 @@
1
+ /**
2
+ * isPostalCode()
3
+ * Calcula se um código de rastreamento postal no formato JT194690698BR é válido.
4
+ *
5
+ * @doc
6
+ * - O número de registro postal deve possuir 13 caracters no formato JT194690698BR.
7
+ *
8
+ * - Os caracteres 1 e 2 informam o tipo do objeto. Ex.: SX é Sedex, RC é carta registrada etc.
9
+ *
10
+ * - Os caracteres de 3 a 10 são a numeração sequencial do tipo do objeto.
11
+ *
12
+ * - O caractere 11 é o dígito verificador.
13
+ *
14
+ * - Os caracteres 12 e 13 representa o código do País de onde a postagem partiu.
15
+ *
16
+ * 1) Partes do número
17
+ * ______ ___________________________ ______ _______
18
+ * | Tipo | Número | DV | País |
19
+ * | J T 1 9 4 6 9 0 6 9 8 B R |
20
+ * |______|___________________________|______|_______|
21
+ *
22
+ * 2) Cálculo do DV.
23
+ *
24
+ * - Soma-se o produto das algarismos 3 a 10 pelos números 8, 6, 4, 2, 3, 5, 9, 7
25
+ *
26
+ * 1 9 4 6 9 0 6 9
27
+ * x x x x x x x x
28
+ * 8 6 4 2 3 5 9 7
29
+ * = 8 +54 +16 +12 +18 +0 +54 +63 = 234
30
+ *
31
+ * - O somatório encontrado é dividido por 11 e o resultado é subtraído de 11
32
+ * 234 / 11 tem resto 3. 11 - 3 = 8. DV1 é 8.
33
+ * Obs.: Caso o cálculo de DV1 retorne 0, o resultado será 5.
34
+ * Caso retorne 1, o resto será 0
35
+ *
36
+ *
37
+ *
38
+ *
39
+ * Fonte:
40
+ *
41
+ * @param {String} value Objeto postal no formato JT194690698BR
42
+ * @returns {Boolean}
43
+ */
44
+
45
+ import { sumElementsByMultipliers, clearValue, fakeNumber } from './utils'
46
+
47
+ /**
48
+ * dv()
49
+ * Calcula o dígito verificador
50
+ *
51
+ * @param {Number|String} value
52
+ * @returns {String}
53
+ */
54
+ export const dv = (value: string | number): string => {
55
+ if (!value) throw new Error('PIS não informado')
56
+
57
+ const postalCode = clearValue(value, 8)
58
+
59
+ const sum = sumElementsByMultipliers(postalCode, [8, 6, 4, 2, 3, 5, 9, 7])
60
+
61
+ const rest = sum % 11
62
+ // const specificities = { 0: { dv: 5 }, 1: { dv: 0 } }
63
+
64
+ const specificities = [
65
+ { rest: 0, dv: 5 },
66
+ { rest: 1, dv: 0 },
67
+ ]
68
+
69
+ const specifity = specificities.find((item) => item.rest === rest)
70
+
71
+ const DV = specifity ? specifity.dv : 11 - rest
72
+
73
+ return String(DV)
74
+ }
75
+
76
+ /**
77
+ * Aplica uma máscara ao número informado
78
+ *
79
+ * @param {String} value Número de Processo
80
+ * @returns {String} Valor com a máscara
81
+ */
82
+ export const mask = (value: string | number): string => String(value).toLocaleUpperCase()
83
+
84
+ /**
85
+ * fake()
86
+ * Gera um número válido
87
+ *
88
+ * @returns {String}
89
+ */
90
+ export const fake = (withMask: boolean = false): string => {
91
+ const num = fakeNumber(8, true)
92
+
93
+ const randLetter = (): string =>
94
+ [
95
+ 'A',
96
+ 'B',
97
+ 'C',
98
+ 'D',
99
+ 'E',
100
+ 'F',
101
+ 'G',
102
+ 'H',
103
+ 'I',
104
+ 'J',
105
+ 'K',
106
+ 'L',
107
+ 'M',
108
+ 'N',
109
+ 'O',
110
+ 'P',
111
+ 'Q',
112
+ 'R',
113
+ 'S',
114
+ 'T',
115
+ 'U',
116
+ 'V',
117
+ 'W',
118
+ 'X',
119
+ 'Y',
120
+ 'Z',
121
+ ][+(Math.random() * 25).toFixed(0)]
122
+
123
+ const postalCode = `${randLetter()}${randLetter()}${num}${dv(num)}BR`
124
+
125
+ if (withMask) return mask(postalCode)
126
+ return postalCode
127
+ }
128
+
129
+ /**
130
+ * validateOrFail()
131
+ * Valida se um número de processo está correto e
132
+ * retorna uma exceção se não estiver
133
+ *
134
+ * @returns {Boolean}
135
+ */
136
+ export const validateOrFail = (value: string | number): boolean => {
137
+ const postalCode = clearValue(value, 9)
138
+
139
+ if (!/^[a-z]{2}([\d]{9})[a-z]{2}$/gi.test(String(value))) {
140
+ throw new Error('O número não está no formato "XX000000000XX"')
141
+ }
142
+
143
+ if (dv(value) !== postalCode.substring(8, 9)) {
144
+ throw new Error('Dígito verificador inválido')
145
+ }
146
+
147
+ return true
148
+ }
149
+
150
+ /**
151
+ * validate()
152
+ * Valida se um número de processo está correto
153
+ *
154
+ * @returns {Boolean}
155
+ */
156
+ export const validate = (value: string | number): boolean => {
157
+ try {
158
+ return validateOrFail(value)
159
+ } catch (error) {
160
+ return false
161
+ }
162
+ }
163
+
164
+ export default validate