cnpj-gen 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84e5f2e407246901858a1a047955ed4c8e6d44849ae4714651ab006a035dba14
4
- data.tar.gz: 61eef6bffad1f5bfbf5ba39db37b3c7f3225d47e10290299bb2a661eea154acd
3
+ metadata.gz: 71c9ef958732ebe391234b5a8f19e4b7ff2eab40261cdb1f374b9ec891ef6a3b
4
+ data.tar.gz: d7bafe712dc0215c9495c4b19f4c5254278ea664185ef42905d26949813904b5
5
5
  SHA512:
6
- metadata.gz: '07123961a4928576fb4fd3e306f8814654df3cf06a26ba5474f46146918f2a02bd17165fa3771ddc89739d472f9362a18289a9d40c89a07a08b85b4448c8e7f9'
7
- data.tar.gz: '097a2a4b9e7ec07e9b99188ef5490f1b1d6a650b7cc45e7ca01b3906db4bfc0091daad9561df3eca47a2fe45c349aea541c440e90e35d3d0348bd391ce2238df'
6
+ metadata.gz: 82ecbd22bf718d56e2fd65c04930ad0e172d81c30bfa37b837084591893d9535275635c19f205a141daae9b0feedaea83890349a5be6306da079d11fa3242b30
7
+ data.tar.gz: 55971d470cd95bda3446fefdaebab63ec6b1652fb5be89fad2a7451ef1e6042b1dbf83fe2077fe24ea90a89f58d0838db270b68d84b2aa1ab0c788eeba830b65
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # cnpj-gen
2
+
3
+ ## 1.0.0
4
+
5
+ ### πŸš€ Stable Version Released!
6
+
7
+ Utility module to generate valid CNPJ (Brazilian legal entity ID) strings. Main features:
8
+
9
+ - **Multiple interfaces**: supports `CnpjGen.cnpj_gen` and `CnpjGen::CnpjGenerator` with shared `CnpjGen::CnpjGeneratorOptions` defaults; an `options` argument (instance or `Hash`) is never merged with keyword overrides β€” passing both at once raises `InvalidArgumentCombinationError`.
10
+ - **Alphanumeric CNPJ**: generates 14-character alphanumeric identifiers (`0-9A-Z`) aligned with the new [14-character alphanumeric CNPJ](https://www.gov.br/receitafederal/pt-br/assuntos/noticias/2023/julho/cnpj-alfa-numerico); optional `numeric` or `alphabetic` via the `type` option.
11
+ - **`type` option**: controls character set for randomly generated segments (`numeric`, `alphabetic`, or `alphanumeric`, default `alphanumeric`).
12
+ - **Prefix support**: partial start strings are sanitized (alphanumeric only, uppercased) and validated β€” rejects zeroed base ID, zeroed branch ID, and 12 repeated digits via `ValidationError`; only missing characters up to 12 are randomly generated.
13
+ - **Optional formatting**: `format: true` returns the standard masked `XX.XXX.XXX/XXXX-XX` layout; default output is unformatted.
14
+ - **Strict options merging**: `CnpjGeneratorOptions.new`/`#set` fold positional `Hash`/instance layers left to right, then apply keyword overrides with the highest precedence, filling any still-unresolved option with its `DEFAULT_*` value; property setters (`format=`, `prefix=`, `type=`) never accept `nil` directly β€” pass the matching `DEFAULT_*` constant to reset explicitly.
15
+ - **Structured errors**: `CnpjGen::Error` marker with misuse leaves (`TypeMismatchError`, `InvalidArgumentCombinationError`) and domain leaf (`ValidationError` under `DomainError`).
16
+ - **Check digits**: computed via `cnpj-dv`; generator retries when check-digit computation rejects a random body candidate.
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,359 @@
1
+ ![cnpj-gen for Ruby](https://br-utils.vercel.app/img/cover_cnpj-gen.jpg)
2
+
3
+ [![Gem Version](https://img.shields.io/gem/v/cnpj-gen)](https://rubygems.org/gems/cnpj-gen)
4
+ [![Gem Downloads](https://img.shields.io/gem/dt/cnpj-gen)](https://rubygems.org/gems/cnpj-gen)
5
+ [![Ruby Version](https://img.shields.io/gem/rv/cnpj-gen)](https://www.ruby-lang.org/)
6
+ [![Test Status](https://img.shields.io/github/actions/workflow/status/LacusSolutions/br-utils-ruby/ci.yml?label=ci/cd)](https://github.com/LacusSolutions/br-utils-ruby/actions)
7
+ [![Last Update Date](https://img.shields.io/github/last-commit/LacusSolutions/br-utils-ruby)](https://github.com/LacusSolutions/br-utils-ruby)
8
+ [![Project License](https://img.shields.io/github/license/LacusSolutions/br-utils-ruby)](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 utility to generate valid CNPJ (Brazilian Business Tax ID) values.
15
+
16
+ ## Ruby Support
17
+
18
+ | ![Ruby 3.2](https://img.shields.io/badge/Ruby-3.2-CC342D?logo=ruby&logoColor=white) | ![Ruby 3.3](https://img.shields.io/badge/Ruby-3.3-CC342D?logo=ruby&logoColor=white) | ![Ruby 3.4](https://img.shields.io/badge/Ruby-3.4-CC342D?logo=ruby&logoColor=white) |
19
+ | --- | --- | --- |
20
+ | Passing βœ” | Passing βœ” | Passing βœ” |
21
+
22
+ Requires Ruby **β‰₯ 3.1** (see `required_ruby_version` in the gemspec).
23
+
24
+ ## Features
25
+
26
+ - βœ… **Alphanumeric CNPJ**: Generates 14-character CNPJ with optional numeric, alphabetic, or alphanumeric (default) character sets
27
+ - βœ… **Optional prefix**: Provide 0–12 alphanumeric characters to fix the start of the CNPJ (e.g. base ID) and generate the rest with valid check digits
28
+ - βœ… **Formatting**: Option to return the standard formatted string (`00.000.000/0000-00`)
29
+ - βœ… **Reusable generator**: `CnpjGen::CnpjGenerator` class with default options and per-call overrides
30
+ - βœ… **Keyword overrides**: Pass `format:`, `prefix:`, and `type:` on `cnpj_gen`, `CnpjGenerator#generate`, and constructors
31
+ - βœ… **Minimal dependencies**: Only [`cnpj-dv`](https://rubygems.org/gems/cnpj-dv) and [`lacus-utils`](https://rubygems.org/gems/lacus-utils)
32
+ - βœ… **Error handling**: API misuse vs domain errors with a `CnpjGen::Error` marker for library-wide rescue
33
+
34
+ ## Installation
35
+
36
+ Install the gem directly:
37
+
38
+ ```bash
39
+ gem install cnpj-gen
40
+ ```
41
+
42
+ Or add it to your `Gemfile` and run `bundle install`:
43
+
44
+ ```ruby
45
+ gem 'cnpj-gen'
46
+ ```
47
+
48
+ ## Require
49
+
50
+ ```ruby
51
+ require 'cnpj-gen'
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ```ruby
57
+ require 'cnpj-gen'
58
+
59
+ CnpjGen.cnpj_gen # => e.g. "AB123CDE000155" (14-char alphanumeric)
60
+
61
+ CnpjGen.cnpj_gen(format: true) # => e.g. "AB.123.CDE/0001-55"
62
+
63
+ CnpjGen.cnpj_gen(prefix: '45623767') # => e.g. "45623767ABCD96"
64
+ CnpjGen.cnpj_gen( # => e.g. "45.623.767/ABCD-96"
65
+ prefix: '45623767',
66
+ format: true
67
+ )
68
+
69
+ CnpjGen.cnpj_gen(type: 'numeric') # => e.g. "65453043000178" (digits only)
70
+ CnpjGen.cnpj_gen(type: 'alphabetic') # => e.g. "ABCDEFGHIJKL80" (letters only, except check digits)
71
+ ```
72
+
73
+ Options can also be passed as a `Hash`:
74
+
75
+ ```ruby
76
+ CnpjGen.cnpj_gen({ format: true, type: 'numeric' })
77
+ ```
78
+
79
+ ## Usage
80
+
81
+ The main entry points are the module helper `CnpjGen.cnpj_gen`, the class `CnpjGen::CnpjGenerator`, and the options class `CnpjGen::CnpjGeneratorOptions`.
82
+
83
+ ### Generator options
84
+
85
+ All options are optional:
86
+
87
+ | Option | Type | Default | Description |
88
+ |--------|------|---------|-------------|
89
+ | `format` | `Boolean` | `false` | When truthy, return the generated CNPJ in standard format (`00.000.000/0000-00`). Non-boolean values are coerced (`false`, `''`, and `0` become `false`; other values become truthy). |
90
+ | `prefix` | `String` | `''` | Partial start string (0–12 alphanumeric chars). Only alphanumeric characters are kept and uppercased; missing characters are generated randomly and check digits are computed. |
91
+ | `type` | `String` | `'alphanumeric'` | Character set for the randomly generated part (`prefix` is kept as-is after sanitization). Must be one of `'numeric'`, `'alphabetic'`, or `'alphanumeric'`. **Check digits are always numeric.** |
92
+
93
+ Prefix rules: base ID (first 8 chars) and branch ID (chars 9–12) cannot be all zeros; 12 repeated digits (e.g. `777777777777`) are also not allowed.
94
+
95
+ `nil` is accepted as a keyword argument on `cnpj_gen`, `CnpjGenerator.new`, `CnpjGenerator#generate`, and `CnpjGeneratorOptions.new`/`#set` β€” it simply means "no override for this option". It is **not** accepted by the `CnpjGeneratorOptions` property setters (`options.format = value`, `options.prefix = value`, `options.type = value`): calling a setter with `nil` directly raises `CnpjGen::TypeMismatchError`. To reset a property to its default value through a setter, pass the literal constant instead, e.g. `options.format = CnpjGen::CnpjGeneratorOptions::DEFAULT_FORMAT`.
96
+
97
+ ### `CnpjGen.cnpj_gen` (helper)
98
+
99
+ Generates a valid CNPJ string. With no options, returns a 14-character alphanumeric CNPJ. This is a convenience wrapper around `CnpjGen::CnpjGenerator.new(...).generate`.
100
+
101
+ - **`options`** (optional): `CnpjGen::CnpjGeneratorOptions` instance, a `Hash` of option keys, or `nil`. See [Generator options](#generator-options).
102
+ - **`format`**, **`prefix`**, **`type`** (keyword arguments): Only used when `options` is omitted (`nil`). Passing `options` **and** any non-`nil` of these keywords at the same time raises `InvalidArgumentCombinationError` β€” the two ways of passing options are never merged.
103
+
104
+ ### `CnpjGen::CnpjGenerator` (class)
105
+
106
+ For reusable defaults or per-call overrides, use the class:
107
+
108
+ ```ruby
109
+ require 'cnpj-gen'
110
+
111
+ generator = CnpjGen::CnpjGenerator.new(type: 'numeric', format: true)
112
+
113
+ generator.generate # => e.g. "73.008.535/0005-06"
114
+ generator.generate(prefix: '12345678') # override for this call only
115
+ generator.options # current default options (CnpjGen::CnpjGeneratorOptions)
116
+ ```
117
+
118
+ - **`initialize(options = nil, **keywords)`**: Optional default options. When `options` is given (a `CnpjGen::CnpjGeneratorOptions` instance or a `Hash`) alone, it determines the default options; a `CnpjGen::CnpjGeneratorOptions` instance is stored by reference (mutating it later affects future `generate` calls that do not pass per-call options), while a `Hash` builds a new instance. When `options` is omitted (`nil`), the default options are built exclusively from the keyword arguments (`format:`, `prefix:`, `type:`). Passing `options` together with any non-`nil` keyword raises `InvalidArgumentCombinationError` instead of silently ignoring the keywords.
119
+ - **`generate(options = nil, **keywords)`**: Returns a valid CNPJ. `options` and the keyword arguments are never merged: a given `options` argument alone fully overrides the instance defaults for this call; otherwise, any given keyword overrides the instance defaults for this call. When neither is given, the instance defaults are used as-is. The instance defaults are never mutated by a per-call override. Passing `options` together with any non-`nil` keyword raises `InvalidArgumentCombinationError`.
120
+ - **`options`**: Reader returning the default options used when per-call options are not provided (same instance as used internally; mutating it affects future `generate` calls).
121
+
122
+ Default options on the instance; per-call overrides:
123
+
124
+ ```ruby
125
+ require 'cnpj-gen'
126
+
127
+ generator = CnpjGen::CnpjGenerator.new(format: true)
128
+
129
+ generator.generate # formatted CNPJ
130
+ generator.generate(format: false) # this call only: unformatted
131
+ generator.generate # formatted again (instance defaults preserved)
132
+ ```
133
+
134
+ ### `CnpjGen::CnpjGeneratorOptions` (class)
135
+
136
+ Holds options (`format`, `prefix`, `type`) with validation and merge support:
137
+
138
+ ```ruby
139
+ require 'cnpj-gen'
140
+
141
+ options = CnpjGen::CnpjGeneratorOptions.new(
142
+ prefix: 'AB123XYZ',
143
+ type: 'numeric',
144
+ format: true
145
+ )
146
+ options.prefix # => "AB123XYZ"
147
+ options.type # => "numeric"
148
+ options.format # => true
149
+ options.set(format: false) # merge and return self
150
+ options.all # => { format: false, prefix: "AB123XYZ", type: "numeric" }
151
+
152
+ # Resetting a property to its default value requires the literal constant β€”
153
+ # a bare `nil` on a setter raises TypeMismatchError:
154
+ options.format = CnpjGen::CnpjGeneratorOptions::DEFAULT_FORMAT
155
+ ```
156
+
157
+ - **`initialize(*options, **keywords)`**: Every positional `options` argument (each a `Hash` or another `CnpjGen::CnpjGeneratorOptions` instance) is folded left to right β€” later arguments win β€” then the keyword arguments (`format:`, `prefix:`, `type:`) are applied on top with the highest precedence. At every step, a `nil` value for a given key is ignored in favor of whatever was resolved so far. Any option still unresolved after that is set to its `DEFAULT_*` value.
158
+ - **`format`**, **`prefix`**, **`type`**: Accessors with setters; `prefix` is validated (base/branch ineligible, repeated digits). The setters **never accept `nil`** β€” pass the matching `DEFAULT_*` constant (e.g. `CnpjGeneratorOptions::DEFAULT_PREFIX`) to reset a property explicitly.
159
+ - **`set(*options, **keywords)`**: Updates multiple options at once, using the same fold-then-keywords, ignore-`nil` resolution as `initialize`. Any option left unresolved after merging keeps its **current** value on the instance (a partial update, not a re-initialization). Returns `self`.
160
+ - **`all`**: Shallow `Hash` copy of current options (`:format`, `:prefix`, `:type`).
161
+
162
+ ## API
163
+
164
+ ### Exports
165
+
166
+ After `require 'cnpj-gen'`:
167
+
168
+ - **`CnpjGen.cnpj_gen`**: `(options = nil, **keywords) -> String` β€” convenience helper.
169
+ - **`CnpjGen::CnpjGenerator`**: Class to generate CNPJ with optional default options and per-call overrides.
170
+ - **`CnpjGen::CnpjGeneratorOptions`**: Class holding options with validation and merge.
171
+ - **`CnpjGen::CNPJ_LENGTH`**: `14` (constant).
172
+ - **`CnpjGen::CNPJ_PREFIX_MAX_LENGTH`**: `12` (constant).
173
+ - **`CnpjGen::CNPJ_TYPE_VALUES`**: `%w[alphabetic alphanumeric numeric]` β€” allowed `type` values.
174
+ - **`CnpjGen::VERSION`**: gem version string.
175
+ - **Errors**: `CnpjGen::Error`, `CnpjGen::DomainError`, `CnpjGen::InvalidArgumentCombinationError`, `CnpjGen::TypeMismatchError`, `CnpjGen::ValidationError`.
176
+
177
+ ### Error handling
178
+
179
+ Errors fall into two categories:
180
+
181
+ | Category | Meaning |
182
+ |---|---|
183
+ | **API misuse** | The caller invoked the library incorrectly (wrong type for an option, or an invalid argument combination). |
184
+ | **Domain error** | The call was structurally correct, but a value violates a business rule (invalid `prefix`, or `type` not in the allowed set). |
185
+
186
+ Every custom error includes the `CnpjGen::Error` marker module. Domain failures (`ValidationError`) inherit from `CnpjGen::DomainError` (`RangeError`).
187
+
188
+ **Important:** passing both an `options` instance/`Hash` and any non-`nil` keyword argument raises `InvalidArgumentCombinationError`.
189
+
190
+ #### Summary
191
+
192
+ | Class | Inherits from | Category | Trigger condition |
193
+ |---|---|---|---|
194
+ | `CnpjGen::InvalidArgumentCombinationError` | `ArgumentError` (+ `include Error`) | API misuse | Both an `options` instance/`Hash` and any non-`nil` keyword argument are passed at once |
195
+ | `CnpjGen::TypeMismatchError` | `TypeError` (+ `include Error`) | API misuse | A generator option has the wrong data type |
196
+ | `CnpjGen::ValidationError` | `CnpjGen::DomainError` | Domain error | `prefix` is ineligible, or `type` is not one of the allowed values |
197
+
198
+ #### `CnpjGen::Error` (marker module)
199
+
200
+ - **Inheritance:** module marker mixed into every library error via `include` (not a class).
201
+ - **Category:** N/A (rescue target only) β€” not a failure mode by itself.
202
+ - **When it is raised:** Never raised directly; included by every custom error the library raises.
203
+ - **Example:** N/A
204
+ - **How to rescue it:**
205
+
206
+ ```ruby
207
+ rescue CnpjGen::Error
208
+ # everything this library raises
209
+ ```
210
+
211
+ #### `CnpjGen::DomainError`
212
+
213
+ - **Inheritance:** `CnpjGen::DomainError < RangeError` (includes `CnpjGen::Error`)
214
+ - **Category:** Domain error β€” ancestor for all domain failures.
215
+ - **When it is raised:** Not raised directly; prefer raising a leaf subclass.
216
+ - **Example:** Prefer `raise CnpjGen::ValidationError` over raising `DomainError` directly.
217
+ - **How to rescue it:**
218
+
219
+ ```ruby
220
+ rescue CnpjGen::DomainError
221
+ # ValidationError and other DomainError subclasses
222
+ ```
223
+
224
+ #### `CnpjGen::TypeMismatchError`
225
+
226
+ - **Inheritance:** `CnpjGen::TypeMismatchError < TypeError` (includes `CnpjGen::Error`)
227
+ - **Category:** API misuse β€” the caller passed a value of the wrong type.
228
+ - **When it is raised:** Raised when a generator option (`format`, `prefix`, or `type`) has the wrong runtime type.
229
+ - **Example:**
230
+
231
+ ```ruby
232
+ CnpjGen.cnpj_gen(prefix: 123) # raises CnpjGen::TypeMismatchError
233
+ ```
234
+
235
+ - **How to rescue it:**
236
+
237
+ ```ruby
238
+ rescue CnpjGen::TypeMismatchError
239
+ # this library's type-contract violation
240
+
241
+ rescue TypeError
242
+ # native type errors, including this library's TypeMismatchError
243
+ ```
244
+
245
+ #### `CnpjGen::InvalidArgumentCombinationError`
246
+
247
+ - **Inheritance:** `CnpjGen::InvalidArgumentCombinationError < ArgumentError` (includes `CnpjGen::Error`)
248
+ - **Category:** API misuse β€” the caller mixed mutually exclusive argument patterns.
249
+ - **When it is raised:** Raised when `CnpjGenerator.new`, `#generate`, or `cnpj_gen` receives both an `options` argument (instance or `Hash`) and any non-`nil` keyword argument at the same time.
250
+ - **Example:**
251
+
252
+ ```ruby
253
+ begin
254
+ CnpjGen::CnpjGenerator.new({ format: true }, prefix: 'AB')
255
+ rescue CnpjGen::InvalidArgumentCombinationError => e
256
+ puts e.message
257
+ # Pass either an options instance/Hash to `options`, or keyword arguments (format:, prefix:, type:), not both.
258
+ end
259
+ ```
260
+
261
+ - **How to rescue it:**
262
+
263
+ ```ruby
264
+ rescue CnpjGen::InvalidArgumentCombinationError
265
+ # this library's invalid argument combination
266
+
267
+ rescue ArgumentError
268
+ # native argument errors, including this library's InvalidArgumentCombinationError
269
+ ```
270
+
271
+ #### `CnpjGen::ValidationError`
272
+
273
+ - **Inheritance:** `CnpjGen::ValidationError < CnpjGen::DomainError < RangeError` (includes `CnpjGen::Error`)
274
+ - **Category:** Domain error β€” a value fails a non-numeric, non-length domain rule.
275
+ - **When it is raised:** Raised when `prefix` is ineligible (zeroed base/branch ID, or 12 repeated digits), or when `type` is not one of `'alphabetic'`, `'alphanumeric'`, or `'numeric'`.
276
+ - **Example:**
277
+
278
+ ```ruby
279
+ CnpjGen.cnpj_gen(prefix: '000000000001') # raises CnpjGen::ValidationError
280
+ CnpjGen.cnpj_gen(type: 'invalid') # raises CnpjGen::ValidationError
281
+ ```
282
+
283
+ - **How to rescue it:**
284
+
285
+ ```ruby
286
+ rescue CnpjGen::ValidationError
287
+ # this exact domain validation failure
288
+
289
+ rescue CnpjGen::DomainError
290
+ # RangeError-rooted domain failures from this library
291
+ ```
292
+
293
+ #### Rescue granularity
294
+
295
+ ```ruby
296
+ # 1) Single native class β€” catches type misuse from this library (and other TypeErrors).
297
+ rescue TypeError
298
+ # CnpjGen::TypeMismatchError and any other TypeError (library or not)
299
+
300
+ # 2) CnpjGen::DomainError β€” catches business-rule violations under DomainError.
301
+ rescue CnpjGen::DomainError
302
+ # CnpjGen::ValidationError and other DomainError subclasses
303
+
304
+ # 3) CnpjGen::Error β€” catches everything the library raises.
305
+ rescue CnpjGen::Error
306
+ # every custom error that includes CnpjGen::Error
307
+
308
+ # 4) Specific leaf class β€” catches only that exact failure mode.
309
+ rescue CnpjGen::ValidationError
310
+ # only CnpjGen::ValidationError
311
+ ```
312
+
313
+ Notable attributes:
314
+
315
+ - `TypeMismatchError`: `option_name`, `actual_input`, `actual_type`, `expected_type`
316
+ - `ValidationError`: `option_name`, `actual_input`, `reason` (prefix failures), `expected_values` (type failures)
317
+
318
+ Property setters never accept `nil` directly β€” pass the matching `DEFAULT_*` constant to reset:
319
+
320
+ ```ruby
321
+ options = CnpjGen::CnpjGeneratorOptions.new
322
+ begin
323
+ options.prefix = nil
324
+ rescue CnpjGen::TypeMismatchError => e
325
+ puts e.message
326
+ # CNPJ generator option "prefix" must be of type string. Got nil.
327
+ end
328
+
329
+ options.prefix = CnpjGen::CnpjGeneratorOptions::DEFAULT_PREFIX # explicit reset instead
330
+ ```
331
+
332
+ Check-digit computation failures from `cnpj-dv` are handled internally by retrying generation with the same resolved options; they are not raised to callers under normal operation.
333
+
334
+ ### Other available resources
335
+
336
+ - **`CnpjGen::CnpjGeneratorOptions::CNPJ_LENGTH`**: `14`.
337
+ - **`CnpjGen::CnpjGeneratorOptions::CNPJ_PREFIX_MAX_LENGTH`**: `12`.
338
+ - **`CnpjGen::CnpjGeneratorOptions::DEFAULT_FORMAT`**, **`DEFAULT_PREFIX`**, **`DEFAULT_TYPE`**: Class-level default constants.
339
+
340
+ ## Contribution & Support
341
+
342
+ 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:
343
+
344
+ - ⭐ Starring the repository
345
+ - 🀝 Contributing to the codebase
346
+ - πŸ’‘ [Suggesting new features](https://github.com/LacusSolutions/br-utils-ruby/issues)
347
+ - πŸ› [Reporting bugs](https://github.com/LacusSolutions/br-utils-ruby/issues)
348
+
349
+ ## License
350
+
351
+ This project is licensed under the MIT License β€” see the [LICENSE](https://github.com/LacusSolutions/br-utils-ruby/blob/main/LICENSE) file for details.
352
+
353
+ ## Changelog
354
+
355
+ See [CHANGELOG](./CHANGELOG.md) for a list of changes and version history.
356
+
357
+ ---
358
+
359
+ Made with ❀️ by [Lacus Solutions](https://github.com/LacusSolutions)