brazil-validator 0.1.0
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.
- checksums.yaml +7 -0
- data/README.md +77 -0
- data/lib/br_validator/cep.rb +44 -0
- data/lib/br_validator/cnpj.rb +78 -0
- data/lib/br_validator/cpf.rb +63 -0
- data/lib/br_validator/email.rb +48 -0
- data/lib/br_validator/ie/ac.rb +48 -0
- data/lib/br_validator/ie/al.rb +46 -0
- data/lib/br_validator/ie/am.rb +52 -0
- data/lib/br_validator/ie/ap.rb +64 -0
- data/lib/br_validator/ie/ba.rb +76 -0
- data/lib/br_validator/ie/ce.rb +42 -0
- data/lib/br_validator/ie/df.rb +58 -0
- data/lib/br_validator/ie/es.rb +39 -0
- data/lib/br_validator/ie/go.rb +49 -0
- data/lib/br_validator/ie/ma.rb +41 -0
- data/lib/br_validator/ie/mg.rb +93 -0
- data/lib/br_validator/ie/mod11.rb +48 -0
- data/lib/br_validator/ie/ms.rb +45 -0
- data/lib/br_validator/ie/mt.rb +42 -0
- data/lib/br_validator/ie/pa.rb +44 -0
- data/lib/br_validator/ie/pb.rb +42 -0
- data/lib/br_validator/ie/pe.rb +52 -0
- data/lib/br_validator/ie/pi.rb +38 -0
- data/lib/br_validator/ie/pr.rb +53 -0
- data/lib/br_validator/ie/rj.rb +53 -0
- data/lib/br_validator/ie/rn.rb +58 -0
- data/lib/br_validator/ie/ro.rb +58 -0
- data/lib/br_validator/ie/rr.rb +47 -0
- data/lib/br_validator/ie/rs.rb +42 -0
- data/lib/br_validator/ie/sc.rb +42 -0
- data/lib/br_validator/ie/se.rb +42 -0
- data/lib/br_validator/ie/sp.rb +121 -0
- data/lib/br_validator/ie/to.rb +49 -0
- data/lib/br_validator/ie.rb +112 -0
- data/lib/br_validator/phone.rb +59 -0
- data/lib/br_validator/pix.rb +134 -0
- data/lib/br_validator/shared.rb +31 -0
- data/lib/br_validator/version.rb +5 -0
- data/lib/br_validator.rb +13 -0
- metadata +84 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "shared"
|
|
4
|
+
require_relative "cpf"
|
|
5
|
+
require_relative "cnpj"
|
|
6
|
+
require_relative "email"
|
|
7
|
+
require_relative "phone"
|
|
8
|
+
|
|
9
|
+
module BrValidator
|
|
10
|
+
# Validates, normalizes, and formats PIX keys (CPF, CNPJ, e-mail, phone,
|
|
11
|
+
# or random key).
|
|
12
|
+
module Pix
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
# Identifies which kind of PIX key a value looks like.
|
|
16
|
+
KEY_TYPES = %i[cpf cnpj email phone evp].freeze
|
|
17
|
+
|
|
18
|
+
# Formats verified against Bacen's official DICT schema
|
|
19
|
+
# (github.com/bacen/pix-dict-api openapi.yaml) and the Manual de
|
|
20
|
+
# Padrões para Iniciação do Pix:
|
|
21
|
+
# - CPF/CNPJ keys are digits-only (^[0-9]{11}$ / ^[0-9]{14}$). The DICT
|
|
22
|
+
# schema does not yet accept alphanumeric CNPJ as a key.
|
|
23
|
+
# - The EVP (random key) is a canonical, case-insensitive UUID
|
|
24
|
+
# (8-4-4-4-12).
|
|
25
|
+
# - Phone keys use the international format "+55AANNNNNNNNN", where AA
|
|
26
|
+
# is the DDD and NNNNNNNNN is a 9-digit mobile number -- Brazilian
|
|
27
|
+
# Pix only registers Brazilian mobile numbers, so the country code is
|
|
28
|
+
# fixed at 55.
|
|
29
|
+
# - Email keys are case-insensitive and capped at 77 characters.
|
|
30
|
+
EVP_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i.freeze
|
|
31
|
+
CPF_SHAPE = /\A\d{11}\z/.freeze
|
|
32
|
+
CNPJ_SHAPE = /\A\d{14}\z/.freeze
|
|
33
|
+
PHONE_CHARS = /\A[\d\s()+-]+\z/.freeze
|
|
34
|
+
PHONE_KEY_FORM = /\A\+55\d{11}\z/.freeze
|
|
35
|
+
MAX_EMAIL_KEY_LENGTH = 77
|
|
36
|
+
private_constant :EVP_REGEX, :CPF_SHAPE, :CNPJ_SHAPE, :PHONE_CHARS, :PHONE_KEY_FORM,
|
|
37
|
+
:MAX_EMAIL_KEY_LENGTH
|
|
38
|
+
|
|
39
|
+
# Detects which kind of PIX key value looks like, or nil if it matches
|
|
40
|
+
# none.
|
|
41
|
+
def key_type(value)
|
|
42
|
+
trimmed = value.strip
|
|
43
|
+
|
|
44
|
+
return :evp if trimmed.match?(EVP_REGEX)
|
|
45
|
+
return :email if trimmed.include?("@")
|
|
46
|
+
return :phone if trimmed.start_with?("+")
|
|
47
|
+
return :cpf if trimmed.match?(CPF_SHAPE)
|
|
48
|
+
return :cnpj if trimmed.match?(CNPJ_SHAPE)
|
|
49
|
+
|
|
50
|
+
nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def normalize_phone_key(value)
|
|
54
|
+
"+#{Shared.remove_non_digits(value)}"
|
|
55
|
+
end
|
|
56
|
+
private_class_method :normalize_phone_key
|
|
57
|
+
|
|
58
|
+
def valid_phone_key?(value)
|
|
59
|
+
return false unless value.match?(PHONE_CHARS)
|
|
60
|
+
|
|
61
|
+
phone = normalize_phone_key(value)
|
|
62
|
+
|
|
63
|
+
return false unless phone.match?(PHONE_KEY_FORM)
|
|
64
|
+
|
|
65
|
+
ddd = phone[3...5]
|
|
66
|
+
subscriber_first_digit = phone[5]
|
|
67
|
+
|
|
68
|
+
Shared::VALID_DDDS.include?(ddd) && subscriber_first_digit == "9"
|
|
69
|
+
end
|
|
70
|
+
private_class_method :valid_phone_key?
|
|
71
|
+
|
|
72
|
+
def format_phone_key(value)
|
|
73
|
+
phone = normalize_phone_key(value)
|
|
74
|
+
|
|
75
|
+
return value unless phone.match?(PHONE_KEY_FORM)
|
|
76
|
+
|
|
77
|
+
"+55 #{Phone.format(phone[3..])}"
|
|
78
|
+
end
|
|
79
|
+
private_class_method :format_phone_key
|
|
80
|
+
|
|
81
|
+
# Returns true if value is a valid PIX key of any recognized type.
|
|
82
|
+
def is_valid?(value)
|
|
83
|
+
type = key_type(value)
|
|
84
|
+
|
|
85
|
+
return false if type.nil?
|
|
86
|
+
|
|
87
|
+
trimmed = value.strip
|
|
88
|
+
|
|
89
|
+
case type
|
|
90
|
+
when :cpf then Cpf.is_valid?(trimmed)
|
|
91
|
+
when :cnpj then Cnpj.is_valid?(trimmed)
|
|
92
|
+
when :email then trimmed.length <= MAX_EMAIL_KEY_LENGTH && Email.is_valid?(trimmed)
|
|
93
|
+
when :phone then valid_phone_key?(trimmed)
|
|
94
|
+
when :evp then true
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Dispatches to the canonical normalize rule of value's detected key
|
|
99
|
+
# type. If the type cannot be detected, value is returned unchanged.
|
|
100
|
+
def normalize(value)
|
|
101
|
+
type = key_type(value)
|
|
102
|
+
|
|
103
|
+
return value if type.nil?
|
|
104
|
+
|
|
105
|
+
trimmed = value.strip
|
|
106
|
+
|
|
107
|
+
case type
|
|
108
|
+
when :cpf then Cpf.normalize(trimmed)
|
|
109
|
+
when :cnpj then Cnpj.normalize(trimmed)
|
|
110
|
+
when :email then Email.normalize(trimmed)
|
|
111
|
+
when :phone then normalize_phone_key(trimmed)
|
|
112
|
+
when :evp then trimmed.downcase
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Dispatches to the canonical format rule of value's detected key
|
|
117
|
+
# type. If the type cannot be detected, value is returned unchanged.
|
|
118
|
+
def format(value)
|
|
119
|
+
type = key_type(value)
|
|
120
|
+
|
|
121
|
+
return value if type.nil?
|
|
122
|
+
|
|
123
|
+
trimmed = value.strip
|
|
124
|
+
|
|
125
|
+
case type
|
|
126
|
+
when :cpf then Cpf.format(trimmed)
|
|
127
|
+
when :cnpj then Cnpj.format(trimmed)
|
|
128
|
+
when :email then Email.format(trimmed)
|
|
129
|
+
when :phone then format_phone_key(trimmed)
|
|
130
|
+
when :evp then trimmed.downcase
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BrValidator
|
|
4
|
+
# Small helpers reused by more than one validator.
|
|
5
|
+
#
|
|
6
|
+
# Not part of the public API of brazil-validator: this module holds
|
|
7
|
+
# implementation details shared across validators, not a stable contract.
|
|
8
|
+
module Shared
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
# Strips every character that is not 0-9.
|
|
12
|
+
def remove_non_digits(value)
|
|
13
|
+
value.gsub(/\D/, "")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Anatel's Plano de Numeração Brasileiro: exactly 67 valid DDD (area)
|
|
17
|
+
# codes, not every two-digit value from 11-99.
|
|
18
|
+
VALID_DDDS = %w[
|
|
19
|
+
11 12 13 14 15 16 17 18 19
|
|
20
|
+
21 22 24
|
|
21
|
+
27 28
|
|
22
|
+
31 32 33 34 35 37 38
|
|
23
|
+
41 42 43 44 45 46 47 48 49
|
|
24
|
+
51 53 54 55
|
|
25
|
+
61 62 63 64 65 66 67 68 69
|
|
26
|
+
71 73 74 75 77 79
|
|
27
|
+
81 82 83 84 85 86 87 88 89
|
|
28
|
+
91 92 93 94 95 96 97 98 99
|
|
29
|
+
].freeze
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/br_validator.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "br_validator/version"
|
|
4
|
+
require_relative "br_validator/cpf"
|
|
5
|
+
require_relative "br_validator/cnpj"
|
|
6
|
+
require_relative "br_validator/cep"
|
|
7
|
+
require_relative "br_validator/phone"
|
|
8
|
+
require_relative "br_validator/email"
|
|
9
|
+
require_relative "br_validator/pix"
|
|
10
|
+
require_relative "br_validator/ie"
|
|
11
|
+
|
|
12
|
+
module BrValidator
|
|
13
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: brazil-validator
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Matheus
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-09-13 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: CPF, CNPJ, CEP, phone numbers, e-mail, PIX keys, and Inscrição Estadual
|
|
14
|
+
validators for Ruby.
|
|
15
|
+
email:
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- README.md
|
|
21
|
+
- lib/br_validator.rb
|
|
22
|
+
- lib/br_validator/cep.rb
|
|
23
|
+
- lib/br_validator/cnpj.rb
|
|
24
|
+
- lib/br_validator/cpf.rb
|
|
25
|
+
- lib/br_validator/email.rb
|
|
26
|
+
- lib/br_validator/ie.rb
|
|
27
|
+
- lib/br_validator/ie/ac.rb
|
|
28
|
+
- lib/br_validator/ie/al.rb
|
|
29
|
+
- lib/br_validator/ie/am.rb
|
|
30
|
+
- lib/br_validator/ie/ap.rb
|
|
31
|
+
- lib/br_validator/ie/ba.rb
|
|
32
|
+
- lib/br_validator/ie/ce.rb
|
|
33
|
+
- lib/br_validator/ie/df.rb
|
|
34
|
+
- lib/br_validator/ie/es.rb
|
|
35
|
+
- lib/br_validator/ie/go.rb
|
|
36
|
+
- lib/br_validator/ie/ma.rb
|
|
37
|
+
- lib/br_validator/ie/mg.rb
|
|
38
|
+
- lib/br_validator/ie/mod11.rb
|
|
39
|
+
- lib/br_validator/ie/ms.rb
|
|
40
|
+
- lib/br_validator/ie/mt.rb
|
|
41
|
+
- lib/br_validator/ie/pa.rb
|
|
42
|
+
- lib/br_validator/ie/pb.rb
|
|
43
|
+
- lib/br_validator/ie/pe.rb
|
|
44
|
+
- lib/br_validator/ie/pi.rb
|
|
45
|
+
- lib/br_validator/ie/pr.rb
|
|
46
|
+
- lib/br_validator/ie/rj.rb
|
|
47
|
+
- lib/br_validator/ie/rn.rb
|
|
48
|
+
- lib/br_validator/ie/ro.rb
|
|
49
|
+
- lib/br_validator/ie/rr.rb
|
|
50
|
+
- lib/br_validator/ie/rs.rb
|
|
51
|
+
- lib/br_validator/ie/sc.rb
|
|
52
|
+
- lib/br_validator/ie/se.rb
|
|
53
|
+
- lib/br_validator/ie/sp.rb
|
|
54
|
+
- lib/br_validator/ie/to.rb
|
|
55
|
+
- lib/br_validator/phone.rb
|
|
56
|
+
- lib/br_validator/pix.rb
|
|
57
|
+
- lib/br_validator/shared.rb
|
|
58
|
+
- lib/br_validator/version.rb
|
|
59
|
+
homepage: https://github.com/matheuslm7/brazil-validator
|
|
60
|
+
licenses:
|
|
61
|
+
- MIT
|
|
62
|
+
metadata:
|
|
63
|
+
homepage_uri: https://github.com/matheuslm7/brazil-validator
|
|
64
|
+
source_code_uri: https://github.com/matheuslm7/brazil-validator/tree/master/ruby
|
|
65
|
+
post_install_message:
|
|
66
|
+
rdoc_options: []
|
|
67
|
+
require_paths:
|
|
68
|
+
- lib
|
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '3.0'
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '0'
|
|
79
|
+
requirements: []
|
|
80
|
+
rubygems_version: 3.5.22
|
|
81
|
+
signing_key:
|
|
82
|
+
specification_version: 4
|
|
83
|
+
summary: Validation, normalization, and formatting for Brazilian data.
|
|
84
|
+
test_files: []
|