cnpj-utilities 0.0.0 → 1.0.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 +4 -4
- data/CHANGELOG.md +18 -0
- data/LICENSE +9 -0
- data/README.md +467 -0
- data/README.pt.md +452 -0
- data/src/cnpj-utilities/cnpj_fmt.rb +10 -0
- data/src/cnpj-utilities/cnpj_gen.rb +10 -0
- data/src/cnpj-utilities/cnpj_utils.rb +427 -0
- data/src/cnpj-utilities/cnpj_val.rb +10 -0
- data/src/cnpj-utilities/errors.rb +23 -0
- data/src/cnpj-utilities/version.rb +4 -1
- data/src/cnpj-utilities.rb +30 -8
- metadata +40 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dbde0213b7ccc92a1336f5a65850b30ce1f3c2c39cb26a1e038d30914f5ce2cb
|
|
4
|
+
data.tar.gz: 3efe21df6bdc6d9d5ac27ed38e42fa3eeca7d809c3f13c2c7a34abbc042f3077
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ed402960200f5c7f5c763c7cb1e5680cc2a08fe956a5cb5787a96b0fef159a90c5e7af39c716e5414926592c83bf4f2761eab31586f31866c41b4cd86c1f2a63
|
|
7
|
+
data.tar.gz: 459f193ed8572275e00bbabf8a37f0ce93553a75ec5f8efd2b63ff52a8ee5061b637e169e655a88b7198953989a07de428d4e664bf5ec21562815b0c23240916
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# cnpj-utilities
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### 🚀 Stable Version Released!
|
|
6
|
+
|
|
7
|
+
Unified toolkit to deal with CNPJ (Brazilian legal entity ID): formatting, generation, and validation. Main features:
|
|
8
|
+
|
|
9
|
+
- **Unified façade**: `CnpjUtils` delegates `#format`, `#generate`, and `#is_valid` to `cnpj-fmt`, `cnpj-gen`, and `cnpj-val`.
|
|
10
|
+
- **Alphanumeric CNPJ**: full support for the [14-character alphanumeric CNPJ](https://www.gov.br/receitafederal/pt-br/assuntos/noticias/2023/julho/cnpj-alfa-numerico); generate with `type` `"numeric"`, `"alphabetic"`, or `"alphanumeric"`.
|
|
11
|
+
- **Quick helpers**: `CnpjUtils.format` / `.generate` / `.is_valid` alias mutable `CnpjUtils::DEFAULT` (process-wide; prefer `CnpjUtils.new` / per-call options under concurrency).
|
|
12
|
+
- **Two-tier re-exports**: `CnpjUtils::CnpjFormatter` / `CnpjGenerator` / `CnpjValidator` at the façade root; full sibling surface under `CnpjUtils::CnpjFmt` / `CnpjGen` / `CnpjVal`.
|
|
13
|
+
- **Configurable components**: constructor and setters accept component instances, `*Options`, `Hash`, or `nil`; accessors expose `formatter`, `generator`, and `validator`.
|
|
14
|
+
- **Per-call overrides**: `#format`, `#generate`, and `#is_valid` accept an options `Hash`/instance or keyword overrides (not both).
|
|
15
|
+
- **Root siblings**: after `require 'cnpj-utilities'`, `CnpjFmt`, `CnpjGen`, and `CnpjVal` remain loadable (same objects as the nests).
|
|
16
|
+
- **Structured errors**: `CnpjUtils::TypeMismatchError` / `InvalidArgumentCombinationError` (+ `CnpjUtils::Error` marker); only `nil` means omitted for settings/options (e.g. `false` raises).
|
|
17
|
+
|
|
18
|
+
For detailed usage and API reference, see the [README](./README.md).
|
data/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Julio L. Muller
|
|
4
|
+
|
|
5
|
+
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:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
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.
|
data/README.md
ADDED
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
[](https://rubygems.org/gems/cnpj-utilities)
|
|
4
|
+
[](https://rubygems.org/gems/cnpj-utilities)
|
|
5
|
+
[](https://www.ruby-lang.org/)
|
|
6
|
+
[](https://github.com/LacusSolutions/br-utils-ruby/actions)
|
|
7
|
+
[](https://github.com/LacusSolutions/br-utils-ruby)
|
|
8
|
+
[](https://github.com/LacusSolutions/br-utils-ruby/blob/main/LICENSE)
|
|
9
|
+
|
|
10
|
+
> 🚀 **Full support for the [new alphanumeric CNPJ format](https://github.com/user-attachments/files/23937961/calculodvcnpjalfanaumerico.pdf).**
|
|
11
|
+
|
|
12
|
+
> 🌎 [Acessar documentação em português](./README.pt.md)
|
|
13
|
+
|
|
14
|
+
A Ruby toolkit to format, generate, and validate CNPJ (Brazilian Business Tax ID). It wraps [`cnpj-fmt`](https://rubygems.org/gems/cnpj-fmt), [`cnpj-gen`](https://rubygems.org/gems/cnpj-gen), and [`cnpj-val`](https://rubygems.org/gems/cnpj-val) in a single façade class (`CnpjUtils`).
|
|
15
|
+
|
|
16
|
+
## Ruby Support
|
|
17
|
+
|
|
18
|
+
|  |  |  |  |  |
|
|
19
|
+
| --- | --- | --- | --- | --- |
|
|
20
|
+
| Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ |
|
|
21
|
+
|
|
22
|
+
Requires Ruby **≥ 3.1** (see `required_ruby_version` in the gemspec).
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- ✅ **Unified API**: Class helpers `CnpjUtils.format` / `.generate` / `.is_valid`
|
|
27
|
+
- ✅ **Two-tier access**: Prefer `CnpjUtils::CnpjFormatter` / `CnpjGenerator` / `CnpjValidator` for the main classes; Options, helpers, and errors live under `CnpjUtils::CnpjFmt` / `CnpjGen` / `CnpjVal` (root siblings `CnpjFmt` / `CnpjGen` / `CnpjVal` still work)
|
|
28
|
+
- ✅ **Alphanumeric CNPJ**: Format, generate, and validate 14-character numeric or alphanumeric CNPJ
|
|
29
|
+
- ✅ **Reusable instance**: `CnpjUtils` class with optional default settings (formatter, generator, validator options or instances)
|
|
30
|
+
- ✅ **Flexible input**: `#format` and `#is_valid` accept a `String` or an `Array` of strings (elements concatenated in order)
|
|
31
|
+
- ✅ **Per-call overrides**: Instance defaults plus a per-call options `Hash`/`*Options` instance **or** keyword overrides (not both)
|
|
32
|
+
- ✅ **Error handling**: Component errors propagate unchanged; this gem defines `CnpjUtils::TypeMismatchError` and `CnpjUtils::InvalidArgumentCombinationError` for API misuse
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
Install the gem directly:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
gem install cnpj-utilities
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or add it to your `Gemfile` and run `bundle install`:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
gem 'cnpj-utilities'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This installs **`cnpj-utilities`** together with [`cnpj-fmt`](https://rubygems.org/gems/cnpj-fmt), [`cnpj-gen`](https://rubygems.org/gems/cnpj-gen), and [`cnpj-val`](https://rubygems.org/gems/cnpj-val). You do **not** need separate `gem install` / `gem` lines for the component packages when using **`cnpj-utilities`**.
|
|
49
|
+
|
|
50
|
+
## Require
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
require 'cnpj-utilities'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
Basic usage with class helpers (aliases of `CnpjUtils::DEFAULT`):
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
require 'cnpj-utilities'
|
|
62
|
+
|
|
63
|
+
cnpj = '03603568000195'
|
|
64
|
+
|
|
65
|
+
CnpjUtils.format(cnpj) # => "03.603.568/0001-95"
|
|
66
|
+
CnpjUtils.format(cnpj, hidden: true) # => "03.603.***/****-**"
|
|
67
|
+
CnpjUtils.format( # => "03603568|0001_95"
|
|
68
|
+
cnpj,
|
|
69
|
+
dot_key: '',
|
|
70
|
+
slash_key: '|',
|
|
71
|
+
dash_key: '_'
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
CnpjUtils.generate # => e.g. "AB123CDE000155" (14-char alphanumeric)
|
|
75
|
+
CnpjUtils.generate(format: true) # => e.g. "AB.123.CDE/0001-55"
|
|
76
|
+
CnpjUtils.generate(prefix: '45623767') # => e.g. "45623767000296"
|
|
77
|
+
CnpjUtils.generate(type: 'numeric') # => e.g. "65453043000178" (digits only)
|
|
78
|
+
|
|
79
|
+
CnpjUtils.is_valid('98765432000198') # => true
|
|
80
|
+
CnpjUtils.is_valid('98.765.432/0001-98') # => true
|
|
81
|
+
CnpjUtils.is_valid('1QB5UKALPYFP59') # => true (alphanumeric)
|
|
82
|
+
CnpjUtils.is_valid('98765432000199') # => false
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Usage
|
|
86
|
+
|
|
87
|
+
You can work in these equivalent ways:
|
|
88
|
+
|
|
89
|
+
1. **`CnpjUtils.format` / `.generate` / `.is_valid`** — class helpers for quick one-off calls (forward to `DEFAULT`).
|
|
90
|
+
2. **`CnpjUtils::DEFAULT`** — mutable shared singleton (same object the class helpers use; process-wide / not thread-isolated).
|
|
91
|
+
3. **`CnpjUtils.new`** — configurable instance with shared defaults across format, generate, and validate.
|
|
92
|
+
4. **Main classes under `CnpjUtils`** — `CnpjUtils::CnpjFormatter`, `CnpjUtils::CnpjGenerator`, `CnpjUtils::CnpjValidator`.
|
|
93
|
+
5. **Nested package modules** — Options, helpers, errors, and types via `CnpjUtils::CnpjFmt` / `CnpjGen` / `CnpjVal` (e.g. `CnpjUtils::CnpjFmt::CnpjFormatterOptions`, `CnpjUtils::CnpjFmt.cnpj_fmt`).
|
|
94
|
+
6. **Root sibling modules** (still supported) — `CnpjFmt`, `CnpjGen`, `CnpjVal` unchanged.
|
|
95
|
+
|
|
96
|
+
All approaches expose the same options and behavior. For exhaustive option tables and component-specific details, see the README of each [bundled package](#bundled-packages).
|
|
97
|
+
|
|
98
|
+
### Formatter options
|
|
99
|
+
|
|
100
|
+
When calling `#format(cnpj_input, options = nil, **keywords)`, all options are optional:
|
|
101
|
+
|
|
102
|
+
| Option | Type | Default | Description |
|
|
103
|
+
|--------|------|---------|-------------|
|
|
104
|
+
| `hidden` | `Boolean` | `false` | When `true`, mask characters in `hidden_start`–`hidden_end` with `hidden_key` |
|
|
105
|
+
| `hidden_key` | `String` | `'*'` | Character(s) used to replace masked characters |
|
|
106
|
+
| `hidden_start` | `Integer` | `5` | Start index (0–13, inclusive) of the range to hide |
|
|
107
|
+
| `hidden_end` | `Integer` | `13` | End index (0–13, inclusive) of the range to hide |
|
|
108
|
+
| `dot_key` | `String` | `'.'` | Dot delimiter (e.g. in `12.345.678`) |
|
|
109
|
+
| `slash_key` | `String` | `'/'` | Slash delimiter (e.g. before branch `…/0001-90`) |
|
|
110
|
+
| `dash_key` | `String` | `'-'` | Dash delimiter (e.g. before check digits `…-90`) |
|
|
111
|
+
| `escape` | `Boolean` | `false` | When `true`, escape HTML special characters in the result |
|
|
112
|
+
| `encode` | `Boolean` | `false` | When `true`, URL-encode the result (similar to JavaScript `encodeURIComponent`) |
|
|
113
|
+
| `on_fail` | `Proc` / callable | returns `''` | Callback when sanitized input length ≠ 14; return value is used as result |
|
|
114
|
+
|
|
115
|
+
### Generator options
|
|
116
|
+
|
|
117
|
+
When calling `#generate(options = nil, **keywords)`, all options are optional:
|
|
118
|
+
|
|
119
|
+
| Option | Type | Default | Description |
|
|
120
|
+
|--------|------|---------|-------------|
|
|
121
|
+
| `format` | `Boolean` | `false` | When `true`, return the generated CNPJ in standard format (`00.000.000/0000-00`) |
|
|
122
|
+
| `prefix` | `String` | `''` | Partial start string (0–12 alphanumeric chars). Missing characters are generated and check digits computed. |
|
|
123
|
+
| `type` | `String` | `'alphanumeric'` | Character set for the randomly generated part: `'numeric'`, `'alphabetic'`, or `'alphanumeric'`. **Check digits are always numeric.** |
|
|
124
|
+
|
|
125
|
+
Prefix rules: base ID (first 8 chars) and branch ID (chars 9–12) cannot be all zeros; 12 repeated digits (e.g. `111111111111`) are also not allowed.
|
|
126
|
+
|
|
127
|
+
### Validator options
|
|
128
|
+
|
|
129
|
+
When calling `#is_valid(cnpj_input, options = nil, **keywords)`, all options are optional:
|
|
130
|
+
|
|
131
|
+
| Option | Type | Default | Description |
|
|
132
|
+
|--------|------|---------|-------------|
|
|
133
|
+
| `case_sensitive` | `Boolean` | `true` | When `false`, lowercase letters are accepted for alphanumeric CNPJ (input is uppercased before validation). |
|
|
134
|
+
| `type` | `String` | `'alphanumeric'` | `'numeric'`: only digits (0–9); `'alphanumeric'`: digits and letters (0–9, A–Z). |
|
|
135
|
+
|
|
136
|
+
### Class helpers (`CnpjUtils.format` / `.generate` / `.is_valid`)
|
|
137
|
+
|
|
138
|
+
These class methods are aliases of the same methods on `CnpjUtils::DEFAULT`. Prefer them for one-off calls:
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
CnpjUtils.format('03603568000195')
|
|
142
|
+
CnpjUtils.generate(type: 'numeric')
|
|
143
|
+
CnpjUtils.is_valid('98765432000198')
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `CnpjUtils::DEFAULT` (default instance)
|
|
147
|
+
|
|
148
|
+
`CnpjUtils::DEFAULT` is the pre-built, **mutable** singleton behind the class helpers (parity with the JS default export / Python `cnpj_utils`). Its configuration is **process-wide and shared across threads**: mutating it (e.g. `DEFAULT.formatter = …`) affects subsequent `CnpjUtils.format` / `.generate` / `.is_valid` calls for every caller in the process. Prefer `CnpjUtils.new` or per-call options for concurrent or isolated work; custom instances stay independent of `DEFAULT`:
|
|
149
|
+
|
|
150
|
+
```ruby
|
|
151
|
+
CnpjUtils::DEFAULT.formatter = { slash_key: '|' }
|
|
152
|
+
CnpjUtils.format('01ABC234000X56') # => "01.ABC.234|000X-56"
|
|
153
|
+
|
|
154
|
+
custom = CnpjUtils.new
|
|
155
|
+
custom.format('01ABC234000X56') # => "01.ABC.234/000X-56" (unaffected)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Instance methods on `DEFAULT` (and any `CnpjUtils` instance):
|
|
159
|
+
|
|
160
|
+
- **`#format(cnpj_input, options = nil, **keywords)`**: Formats a CNPJ string or array of strings. Delegates to the internal formatter. Input must be 14 alphanumeric characters (after sanitization); otherwise `on_fail` is used.
|
|
161
|
+
- **`#generate(options = nil, **keywords)`**: Generates a valid CNPJ. Delegates to the internal generator.
|
|
162
|
+
- **`#is_valid(cnpj_input, options = nil, **keywords)`**: Returns `true` if the CNPJ is valid. Delegates to the internal validator.
|
|
163
|
+
|
|
164
|
+
### `CnpjUtils` (class)
|
|
165
|
+
|
|
166
|
+
For custom default formatter, generator, or validator, create your own instance:
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
require 'cnpj-utilities'
|
|
170
|
+
|
|
171
|
+
utils = CnpjUtils.new(
|
|
172
|
+
formatter: { hidden: true, hidden_key: '#' },
|
|
173
|
+
generator: { type: 'numeric', format: true },
|
|
174
|
+
validator: { type: 'numeric', case_sensitive: false }
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
utils.format('RK0CMT3W000100') # => "RK.0CM.###/####-##"
|
|
178
|
+
utils.generate # => e.g. "73.008.535/0005-06"
|
|
179
|
+
utils.is_valid('98.765.432/0001-98') # => true
|
|
180
|
+
|
|
181
|
+
# Access or replace internal instances
|
|
182
|
+
utils.formatter # => CnpjFmt::CnpjFormatter
|
|
183
|
+
utils.generator # => CnpjGen::CnpjGenerator
|
|
184
|
+
utils.validator # => CnpjVal::CnpjValidator
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
- **`CnpjUtils.new(settings = nil, **keywords)`**: Optional settings. Pass either a settings `Hash` with `:formatter`, `:generator`, and/or `:validator` keys, **or** the same keys as keyword arguments — not both (passing both raises `CnpjUtils::InvalidArgumentCombinationError`). Each value may be a component instance, a `*Options` instance (stored by reference — mutating it later affects subsequent calls with no per-call override), a plain options `Hash`, or omitted/`nil` for defaults.
|
|
188
|
+
- **`#format(cnpj_input, options = nil, **keywords)`**: Same as the default instance; per-call options override the formatter’s defaults for that call only. Pass either an options `Hash`/`CnpjFmt::CnpjFormatterOptions` **or** keyword overrides — not both.
|
|
189
|
+
- **`#generate(options = nil, **keywords)`**: Same as the default instance; per-call options override the generator’s defaults. Pass either an options `Hash`/`CnpjGen::CnpjGeneratorOptions` **or** keyword overrides — not both.
|
|
190
|
+
- **`#is_valid(cnpj_input, options = nil, **keywords)`**: Same as the default instance; per-call options override the validator’s defaults. Pass either an options `Hash`/`CnpjVal::CnpjValidatorOptions` **or** keyword overrides — not both.
|
|
191
|
+
- **`#formatter`**, **`#generator`**, **`#validator`**: Accessors (getters and setters) for the internal components. Setters accept the same shapes as the constructor. To change a single option without replacing the instance, mutate the component’s options (e.g. `utils.formatter.options.hidden = true`).
|
|
192
|
+
|
|
193
|
+
Instance defaults and per-call overrides:
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
require 'cnpj-utilities'
|
|
197
|
+
|
|
198
|
+
utils = CnpjUtils.new(
|
|
199
|
+
formatter: { hidden: true, hidden_key: '#' },
|
|
200
|
+
generator: { format: true },
|
|
201
|
+
validator: { type: 'numeric' }
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
cnpj = '03603568000195'
|
|
205
|
+
|
|
206
|
+
utils.format(cnpj) # masked (instance formatter defaults)
|
|
207
|
+
utils.format(cnpj, hidden: false) # this call only: unmasked
|
|
208
|
+
utils.generate(format: false) # this call only: compact output
|
|
209
|
+
utils.is_valid('1QB5UKALPYFP59') # => false (instance validator is numeric-only)
|
|
210
|
+
utils.is_valid( # => true for this call
|
|
211
|
+
'1QB5UKALPYFP59',
|
|
212
|
+
type: 'alphanumeric'
|
|
213
|
+
)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Options can also be passed as a `Hash` (or options instance) on each method — without keyword overrides:
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
utils.format(cnpj, { slash_key: '|' })
|
|
220
|
+
utils.generate({ prefix: '12345', type: 'numeric' })
|
|
221
|
+
utils.is_valid('1QB5UKALPYFP59', { case_sensitive: false })
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Using component classes and nested modules
|
|
225
|
+
|
|
226
|
+
Preferred paths after `require 'cnpj-utilities'`:
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
require 'cnpj-utilities'
|
|
230
|
+
|
|
231
|
+
# Main classes at the façade root
|
|
232
|
+
formatter = CnpjUtils::CnpjFormatter.new(hidden: true)
|
|
233
|
+
generator = CnpjUtils::CnpjGenerator.new(type: 'numeric')
|
|
234
|
+
validator = CnpjUtils::CnpjValidator.new
|
|
235
|
+
|
|
236
|
+
formatter.format('AB123XYZ000123') # => "AB.123.***/****-**"
|
|
237
|
+
|
|
238
|
+
# Options, helpers, and errors under nested package modules
|
|
239
|
+
options = CnpjUtils::CnpjFmt::CnpjFormatterOptions.new(slash_key: '|')
|
|
240
|
+
CnpjUtils::CnpjFmt.cnpj_fmt('03603568000195') # => "03.603.568/0001-95"
|
|
241
|
+
|
|
242
|
+
begin
|
|
243
|
+
CnpjUtils::CnpjFmt.cnpj_fmt(12_345)
|
|
244
|
+
rescue CnpjUtils::CnpjFmt::TypeMismatchError
|
|
245
|
+
# wrong input type
|
|
246
|
+
end
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Root siblings remain supported (same objects as the nests):
|
|
250
|
+
|
|
251
|
+
```ruby
|
|
252
|
+
CnpjFmt.cnpj_fmt('01ABC234000X56', slash_key: '|') # => "01.ABC.234|000X-56"
|
|
253
|
+
CnpjGen.cnpj_gen(type: 'numeric') # => e.g. "65453043000178"
|
|
254
|
+
CnpjVal.cnpj_val('9JN7MGLJZXIO50') # => true
|
|
255
|
+
CnpjFmt::CnpjFormatter.new(hidden: true)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
See [`cnpj-fmt`](../cnpj-fmt/README.md), [`cnpj-gen`](../cnpj-gen/README.md), and [`cnpj-val`](../cnpj-val/README.md) for full option and error details.
|
|
259
|
+
|
|
260
|
+
## API
|
|
261
|
+
|
|
262
|
+
### Exports
|
|
263
|
+
|
|
264
|
+
After `require 'cnpj-utilities'`:
|
|
265
|
+
|
|
266
|
+
- **`CnpjUtils`**: Façade class to create a utils instance with optional default formatter, generator, and validator settings.
|
|
267
|
+
- **`CnpjUtils.format` / `.generate` / `.is_valid`**: Class helpers that forward to `CnpjUtils::DEFAULT`.
|
|
268
|
+
- **`CnpjUtils::DEFAULT`**: Mutable pre-built `CnpjUtils` instance (same object the class helpers use). Process-wide / shared across threads — prefer `CnpjUtils.new` or per-call options under concurrency.
|
|
269
|
+
- **`CnpjUtils::VERSION`**: Gem version string.
|
|
270
|
+
- **Main-class shortcuts**: `CnpjUtils::CnpjFormatter`, `CnpjUtils::CnpjGenerator`, `CnpjUtils::CnpjValidator` (same objects as the sibling classes).
|
|
271
|
+
- **Nested package modules**: `CnpjUtils::CnpjFmt`, `CnpjUtils::CnpjGen`, `CnpjUtils::CnpjVal` — full sibling surface (Options, helpers, errors, types). Options/helpers/errors are **not** aliased at the `CnpjUtils` root.
|
|
272
|
+
- **Root sibling modules** (still supported): `CnpjFmt`, `CnpjGen`, `CnpjVal` — same objects as the nests.
|
|
273
|
+
|
|
274
|
+
### Errors & Exceptions
|
|
275
|
+
|
|
276
|
+
`CnpjUtils` defines only API-misuse errors for this gem’s argument rules. Component errors are raised by the bundled packages and propagate unchanged.
|
|
277
|
+
|
|
278
|
+
#### Defined by `cnpj-utilities`
|
|
279
|
+
|
|
280
|
+
Errors defined by this gem are **API misuse** only (wrong type or invalid argument combination). Every custom error includes the `CnpjUtils::Error` marker module. This gem defines **no** `CnpjUtils::DomainError` and no domain leaves — domain failures come only from the [bundled packages](#propagated-from-bundled-packages) and keep those packages’ namespaces (`CnpjFmt::…`, `CnpjGen::…`, `CnpjVal::…`).
|
|
281
|
+
|
|
282
|
+
`rescue CnpjUtils::Error` catches **only** errors this gem raises. It does **not** catch component errors that propagate unchanged.
|
|
283
|
+
|
|
284
|
+
##### Summary
|
|
285
|
+
|
|
286
|
+
| Class | Inherits from | Category | Trigger condition |
|
|
287
|
+
|-------|---------------|----------|-------------------|
|
|
288
|
+
| `CnpjUtils::InvalidArgumentCombinationError` | `CnpjUtils::InvalidArgumentCombinationError < ArgumentError < StandardError` (+ `include CnpjUtils::Error`) | API misuse | Non-`nil` settings/options `Hash` (or options instance) passed together with any non-`nil` keyword argument |
|
|
289
|
+
| `CnpjUtils::TypeMismatchError` | `CnpjUtils::TypeMismatchError < TypeError < StandardError` (+ `include CnpjUtils::Error`) | API misuse | Non-`nil` `settings` argument to `CnpjUtils.new` is not a `Hash` |
|
|
290
|
+
|
|
291
|
+
##### `CnpjUtils::Error` (marker module)
|
|
292
|
+
|
|
293
|
+
- **Inheritance:** module marker mixed into every custom error this gem raises via `include` (not a class).
|
|
294
|
+
- **Category:** N/A (rescue target only) — not a failure mode by itself.
|
|
295
|
+
- **When it is raised:** Never raised directly; included by every custom error this gem raises.
|
|
296
|
+
- **Example:** N/A
|
|
297
|
+
- **How to rescue it:**
|
|
298
|
+
|
|
299
|
+
```ruby
|
|
300
|
+
rescue CnpjUtils::Error
|
|
301
|
+
# TypeMismatchError, InvalidArgumentCombinationError from this gem only
|
|
302
|
+
# (not CnpjFmt::*, CnpjGen::*, or CnpjVal::* errors)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
##### `CnpjUtils::TypeMismatchError`
|
|
306
|
+
|
|
307
|
+
- **Inheritance:** `CnpjUtils::TypeMismatchError < TypeError < StandardError` (includes `CnpjUtils::Error`)
|
|
308
|
+
- **Category:** API misuse — the caller passed a value of the wrong type.
|
|
309
|
+
- **When it is raised:** Raised when `CnpjUtils.new` receives a non-`nil` `settings` argument that is not a `Hash`.
|
|
310
|
+
- **Example:**
|
|
311
|
+
|
|
312
|
+
```ruby
|
|
313
|
+
CnpjUtils.new('not-a-hash') # raises CnpjUtils::TypeMismatchError
|
|
314
|
+
CnpjUtils.new(false) # raises CnpjUtils::TypeMismatchError (false is non-nil)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
- **How to rescue it:**
|
|
318
|
+
|
|
319
|
+
```ruby
|
|
320
|
+
rescue CnpjUtils::TypeMismatchError
|
|
321
|
+
# this gem's type-contract violation
|
|
322
|
+
|
|
323
|
+
rescue TypeError
|
|
324
|
+
# native type errors, including this gem's TypeMismatchError
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
##### `CnpjUtils::InvalidArgumentCombinationError`
|
|
328
|
+
|
|
329
|
+
- **Inheritance:** `CnpjUtils::InvalidArgumentCombinationError < ArgumentError < StandardError` (includes `CnpjUtils::Error`)
|
|
330
|
+
- **Category:** API misuse — the caller mixed mutually exclusive argument patterns.
|
|
331
|
+
- **When it is raised:** Raised when `CnpjUtils.new`, `#format`, `#generate`, `#is_valid`, or the class helpers receive both a non-`nil` settings/options `Hash` (or options instance) and any non-`nil` keyword argument at the same time.
|
|
332
|
+
- **Example:**
|
|
333
|
+
|
|
334
|
+
```ruby
|
|
335
|
+
CnpjUtils.new({ formatter: { hidden: true } }, generator: { format: true })
|
|
336
|
+
# raises CnpjUtils::InvalidArgumentCombinationError
|
|
337
|
+
|
|
338
|
+
CnpjUtils.format('03603568000195', { hidden: true }, slash_key: '|')
|
|
339
|
+
# raises CnpjUtils::InvalidArgumentCombinationError
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
- **How to rescue it:**
|
|
343
|
+
|
|
344
|
+
```ruby
|
|
345
|
+
rescue CnpjUtils::InvalidArgumentCombinationError
|
|
346
|
+
# this gem's invalid signature combination
|
|
347
|
+
|
|
348
|
+
rescue ArgumentError
|
|
349
|
+
# native argument errors, including this gem's InvalidArgumentCombinationError
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
##### Rescue granularity
|
|
353
|
+
|
|
354
|
+
Each level is shown as its own standalone example (do not merge them into one `rescue` ladder — a broad native handler would make narrower clauses unreachable).
|
|
355
|
+
|
|
356
|
+
```ruby
|
|
357
|
+
require 'cnpj-utilities'
|
|
358
|
+
|
|
359
|
+
# 1) Single native class — catches misuse errors of that kind,
|
|
360
|
+
# including non-library ones already handled elsewhere in the consumer's code.
|
|
361
|
+
begin
|
|
362
|
+
CnpjUtils.new('not-a-hash')
|
|
363
|
+
rescue TypeError
|
|
364
|
+
# CnpjUtils::TypeMismatchError and any other TypeError (library or not)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
begin
|
|
368
|
+
CnpjUtils.new({ formatter: { hidden: true } }, generator: { format: true })
|
|
369
|
+
rescue ArgumentError
|
|
370
|
+
# CnpjUtils::InvalidArgumentCombinationError and any other ArgumentError (library or not)
|
|
371
|
+
end
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
```ruby
|
|
375
|
+
require 'cnpj-utilities'
|
|
376
|
+
|
|
377
|
+
# 2) CnpjUtils::DomainError — not applicable: this gem defines no DomainError
|
|
378
|
+
# (and no domain leaves). Domain failures come from bundled packages only.
|
|
379
|
+
# begin
|
|
380
|
+
# CnpjUtils.new.format(12_345)
|
|
381
|
+
# rescue CnpjUtils::DomainError # NameError — constant is not defined
|
|
382
|
+
# end
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
```ruby
|
|
386
|
+
require 'cnpj-utilities'
|
|
387
|
+
|
|
388
|
+
# 3) CnpjUtils::Error — catches everything this gem raises, regardless of native ancestry.
|
|
389
|
+
# Does not catch CnpjFmt::*, CnpjGen::*, or CnpjVal::* errors.
|
|
390
|
+
begin
|
|
391
|
+
CnpjUtils.new('not-a-hash')
|
|
392
|
+
rescue CnpjUtils::Error
|
|
393
|
+
# every custom error that includes CnpjUtils::Error
|
|
394
|
+
end
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
```ruby
|
|
398
|
+
require 'cnpj-utilities'
|
|
399
|
+
|
|
400
|
+
# 4) Specific leaf class — catches only that exact failure mode.
|
|
401
|
+
begin
|
|
402
|
+
CnpjUtils.new('not-a-hash')
|
|
403
|
+
rescue CnpjUtils::TypeMismatchError
|
|
404
|
+
# only CnpjUtils::TypeMismatchError
|
|
405
|
+
end
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
#### Propagated from bundled packages
|
|
409
|
+
|
|
410
|
+
- **Formatting** (`CnpjFmt`): `CnpjFmt::TypeMismatchError`, `CnpjFmt::OutOfRangeError`, `CnpjFmt::ValidationError`, `CnpjFmt::InvalidLengthError` (passed to `on_fail`, not raised by `#format`), and related classes.
|
|
411
|
+
- **Generation** (`CnpjGen`): `CnpjGen::TypeMismatchError`, `CnpjGen::ValidationError`, and related classes.
|
|
412
|
+
- **Validation** (`CnpjVal`): `CnpjVal::TypeMismatchError`, `CnpjVal::ValidationError`, and related classes.
|
|
413
|
+
|
|
414
|
+
Invalid option types are typically **`TypeError`** subclasses (`*::TypeMismatchError`); invalid option values are domain errors under each package’s `DomainError` hierarchy. Validation failure returns `false`; formatting length failure is handled by **`on_fail`** (default returns an empty string).
|
|
415
|
+
|
|
416
|
+
```ruby
|
|
417
|
+
require 'cnpj-utilities'
|
|
418
|
+
|
|
419
|
+
begin
|
|
420
|
+
CnpjUtils.new.format(12_345)
|
|
421
|
+
rescue CnpjFmt::TypeMismatchError => e
|
|
422
|
+
puts e.message
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
begin
|
|
426
|
+
CnpjUtils.new.is_valid(12_345_678_000_198)
|
|
427
|
+
rescue CnpjVal::TypeMismatchError => e
|
|
428
|
+
puts e.message
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
# Custom on_fail for invalid length
|
|
432
|
+
custom_fail = ->(value, _exception) { "Invalid CNPJ: #{value}" }
|
|
433
|
+
|
|
434
|
+
CnpjFmt.cnpj_fmt('123', on_fail: custom_fail) # => "Invalid CNPJ: 123"
|
|
435
|
+
CnpjFmt.cnpj_fmt('123') # => "" (default on_fail)
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### Bundled packages
|
|
439
|
+
|
|
440
|
+
| Package | Main resources | README |
|
|
441
|
+
|---------|----------------|--------|
|
|
442
|
+
| [`cnpj-fmt`](https://rubygems.org/gems/cnpj-fmt) | `CnpjFmt::CnpjFormatter`, `CnpjFmt::CnpjFormatterOptions`, `CnpjFmt.cnpj_fmt` | [docs](../cnpj-fmt/README.md) |
|
|
443
|
+
| [`cnpj-gen`](https://rubygems.org/gems/cnpj-gen) | `CnpjGen::CnpjGenerator`, `CnpjGen::CnpjGeneratorOptions`, `CnpjGen.cnpj_gen` | [docs](../cnpj-gen/README.md) |
|
|
444
|
+
| [`cnpj-val`](https://rubygems.org/gems/cnpj-val) | `CnpjVal::CnpjValidator`, `CnpjVal::CnpjValidatorOptions`, `CnpjVal.cnpj_val` | [docs](../cnpj-val/README.md) |
|
|
445
|
+
|
|
446
|
+
All of the above are pulled in as dependencies of **`cnpj-utilities`**. For exhaustive option tables, exception lists, and edge-case behavior, see each package README.
|
|
447
|
+
|
|
448
|
+
## Contribution & Support
|
|
449
|
+
|
|
450
|
+
We welcome contributions! Please see our [Contributing Guidelines](https://github.com/LacusSolutions/br-utils-ruby/blob/main/CONTRIBUTING.md) for details. If you find this project helpful, please consider:
|
|
451
|
+
|
|
452
|
+
- ⭐ Starring the repository
|
|
453
|
+
- 🤝 Contributing to the codebase
|
|
454
|
+
- 💡 [Suggesting new features](https://github.com/LacusSolutions/br-utils-ruby/issues)
|
|
455
|
+
- 🐛 [Reporting bugs](https://github.com/LacusSolutions/br-utils-ruby/issues)
|
|
456
|
+
|
|
457
|
+
## License
|
|
458
|
+
|
|
459
|
+
This project is licensed under the MIT License — see the [LICENSE](https://github.com/LacusSolutions/br-utils-ruby/blob/main/LICENSE) file for details.
|
|
460
|
+
|
|
461
|
+
## Changelog
|
|
462
|
+
|
|
463
|
+
See [CHANGELOG](./CHANGELOG.md) for a list of changes and version history.
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
Made with ❤️ by [Lacus Solutions](https://github.com/LacusSolutions)
|