[v2][cnpj-dv] Upgrade to latest API and add support to alphanumeric CNPJ format#38
[v2][cnpj-dv] Upgrade to latest API and add support to alphanumeric CNPJ format#38juliolmuller merged 30 commits intomainfrom
v2][cnpj-dv] Upgrade to latest API and add support to alphanumeric CNPJ format#38Conversation
BREAKING CHANGE: PHP v8.1 is no longer supported. Package will now support PHP v8.2+.
📝 WalkthroughWalkthroughAdds alphanumeric CNPJ support and a new options model to cnpj-fmt; introduces a typed exception hierarchy and getName() on cnpj-dv/cpf-dv exceptions; migrates cnpj-fmt tests from PHPUnit to Pest; updates namespaces to Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant CnpjFormatter
participant CnpjFormatterOptions
participant Normalizer
participant Validator
participant Encoder
Client->>CnpjFormatter: format(cnpjInput, options?)
CnpjFormatter->>CnpjFormatterOptions: merge per-call overrides
CnpjFormatter->>Normalizer: toStringInput(cnpjInput)
Normalizer->>Normalizer: remove /[^0-9A-Za-z]/, strtoupper
Normalizer->>Validator: check type && length
alt invalid type
Validator-->>Client: throw CnpjFormatterInputTypeError
else length != 14
Validator->>CnpjFormatterOptions: invoke onFail(actual, CnpjFormatterInputLengthException)
CnpjFormatterOptions-->>Client: onFail result (string)
else valid
CnpjFormatter->>Encoder: apply hidden mask, insert delimiters
alt escape enabled
Encoder->>Encoder: HtmlUtils::escape(result)
end
alt encode enabled
Encoder->>Encoder: UrlUtils::encodeUriComponent(result)
end
Encoder-->>Client: formatted string
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/cnpj-dv/CHANGELOG.md`:
- Line 7: The changelog sentence has a pronoun agreement error: change "can
return its class names" to "can return their class names" in the entry
describing getName(); update the line mentioning getName(),
CnpjCheckDigitsException, CnpjCheckDigitsTypeError and their subclasses so the
plural pronoun "their" is used to refer to the subclasses.
In `@packages/cnpj-dv/src/Exceptions/CnpjCheckDigitsTypeError.php`:
- Around line 34-36: Docblock for the CnpjCheckDigitsTypeError class contains a
redundant word ("name") — update the comment for the method getName (or the
method that returns the class instance name) to read clearly, e.g. "Get the
class instance name." or "Get the name of the class instance." so it matches the
CPF counterpart and removes the duplicated "name".
In `@packages/cnpj-fmt/CHANGELOG.md`:
- Line 17: The CHANGELOG contains a typo: "isntance" should be "instance" in the
sentence describing CnpjFormatterOptions; update the sentence mentioning
CnpjFormatterOptions::merge(), CnpjFormatterOptions and the overrides parameter
to replace "isntance" with "instance" so the wording reads correctly (e.g.,
"construct an instance of the class passing the argument overrides").
In `@packages/cnpj-fmt/README.md`:
- Around line 10-12: Remove the blank line between the two blockquote lines so
they form a single contiguous blockquote; specifically, merge the lines
beginning with "🚀 **Full support for the [new alphanumeric CNPJ format]" and
"🌎 [Acessar documentação em português]" into one blockquote (or remove the
empty line between them) to eliminate the MD028 warning.
In `@packages/cnpj-fmt/README.pt.md`:
- Line 130: Fix the grammatical agreement in the README Portuguese sentence
under the "**Array de strings:**" description: change "cada elemento deve ser
string" to use the plural predicate, e.g. "cada elemento deve ser strings" or
better "cada elemento deve ser uma string" (preferred). Update the phrase
following the "**Array de strings:**" heading so the subject and predicate
agree.
- Around line 3-5: Merge the two separate blockquote lines into a single
continuous blockquote in README.pt.md to eliminate the blank line that triggers
MD028; specifically combine the lines starting with "🚀 **Suporte total ao [novo
formato..." and "🌎 [Access documentation in English]..." into one blockquote
(one leading '>' and a single blank-free paragraph or multiple lines each
prefixed with '>' without an empty line between them) so the markdown linter no
longer reports the blank-line warning.
In `@packages/cnpj-fmt/src/cnpj-fmt.php`:
- Line 44: The parameter $cnpjInput in the function signature is missing a type
hint; update the function declaration that contains $cnpjInput to use a union
type compatible with the documented phpdoc (use string|array for PHP union types
to represent string|list<string>), update the accompanying PHPDoc if necessary
to keep it consistent, and verify any callers still work with the new signature
(the symbol to change is the function that declares $cnpjInput).
- Around line 43-72: The wrapper in packages/cnpj-utils/src/cnpj_utils.php calls
\Lacus\CnpjFmt\cnpj_fmt() with the old positional argument order causing $escape
and $options/$onFail to be misaligned; update that wrapper to call cnpj_fmt with
the new parameter ordering (or use PHP named arguments) so $options is passed as
the 2nd parameter, $escape as the 10th, and $onFail as the 11th/12th per the new
cnpj_fmt signature, ensuring the values originally intended for $escape and
$onFail are moved to the correct parameters when invoking CnpjFormatter::format.
In `@packages/cnpj-fmt/src/Exceptions/CnpjFormatterException.php`:
- Around line 27-30: The getName() method in CnpjFormatterException returns the
fully-qualified class name (static::class); change it to return the short
(non-namespaced) class name by using ReflectionClass($this)->getShortName()
inside CnpjFormatterException::getName(), so it matches the cnpj-dv
implementation and the BR Utils API alignment (use ReflectionClass and
getShortName() rather than static::class).
In `@packages/cnpj-fmt/tests/Specs/Exceptions.spec.php`:
- Around line 106-110: Tests and implementations are inconsistent: update
CnpjFormatterTypeError::getName() to return the short class name (use
ReflectionClass(static::class)->getShortName()) so it matches the other
packages, and change the spec assertion in Specs/Exceptions.spec.php to use
toBe('CnpjFormatterInputTypeError') (replace toEndWith with toBe) so tests
assert the short name returned by CnpjFormatterInputTypeError::getName().
In `@packages/cpf-dv/CHANGELOG.md`:
- Line 7: The CHANGELOG.md entry incorrectly references CNPJ classes; update the
text to reference the CPF-specific class names and context — replace mentions of
CnpjCheckDigitsException and CnpjCheckDigitsTypeError with the CPF equivalents
(e.g., CpfCheckDigitsException and CpfCheckDigitsTypeError) and ensure the
sentence still describes the addition of getName() for package-specific errors
and exceptions across the cpf-dv package.
In `@packages/cpf-dv/src/Exceptions/CpfCheckDigitsTypeError.php`:
- Around line 34-36: Update the docblock on the CpfCheckDigitsTypeError class
method that returns the class instance name to remove the redundant word "name"
(currently reads "Get the name of the class instance name"); change it to a
concise description such as "Get the class instance name" or "Get the name of
the class instance" in the docblock above the relevant method in
CpfCheckDigitsTypeError.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: b5db72e8-f71d-4e55-b083-711716bae203
📒 Files selected for processing (32)
packages/cnpj-dv/CHANGELOG.mdpackages/cnpj-dv/src/Exceptions/CnpjCheckDigitsException.phppackages/cnpj-dv/src/Exceptions/CnpjCheckDigitsTypeError.phppackages/cnpj-dv/tests/Specs/Exceptions.spec.phppackages/cnpj-fmt/CHANGELOG.mdpackages/cnpj-fmt/README.mdpackages/cnpj-fmt/README.pt.mdpackages/cnpj-fmt/composer.jsonpackages/cnpj-fmt/phpunit.xmlpackages/cnpj-fmt/src/CnpjFormatter.phppackages/cnpj-fmt/src/CnpjFormatterOptions.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterException.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterInputLengthException.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterInputTypeError.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterOptionsForbiddenKeyCharacterException.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterOptionsHiddenRangeInvalidException.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterOptionsTypeError.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterTypeError.phppackages/cnpj-fmt/src/cnpj-fmt.phppackages/cnpj-fmt/tests/CnpjFormatterClassTest.phppackages/cnpj-fmt/tests/CnpjFormatterFunctionTest.phppackages/cnpj-fmt/tests/CnpjFormatterOptionsTest.phppackages/cnpj-fmt/tests/CnpjFormatterTestCases.phppackages/cnpj-fmt/tests/Pest.phppackages/cnpj-fmt/tests/Specs/CnpjFormatter.spec.phppackages/cnpj-fmt/tests/Specs/CnpjFormatterOptions.spec.phppackages/cnpj-fmt/tests/Specs/Exceptions.spec.phppackages/cnpj-fmt/tests/Specs/cnpj-fmt.spec.phppackages/cpf-dv/CHANGELOG.mdpackages/cpf-dv/src/Exceptions/CpfCheckDigitsException.phppackages/cpf-dv/src/Exceptions/CpfCheckDigitsTypeError.phppackages/cpf-dv/tests/Specs/Exceptions.spec.php
💤 Files with no reviewable changes (4)
- packages/cnpj-fmt/tests/CnpjFormatterOptionsTest.php
- packages/cnpj-fmt/tests/CnpjFormatterFunctionTest.php
- packages/cnpj-fmt/tests/CnpjFormatterClassTest.php
- packages/cnpj-fmt/tests/CnpjFormatterTestCases.php
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment.
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment.
Fix as per @coderabbitai review comment #38 (comment) and #38 (comment).
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (3)
packages/cnpj-dv/CHANGELOG.md (1)
7-7:⚠️ Potential issue | 🟡 MinorPolish changelog phrasing for clarity.
Line 7 reads awkwardly (“Created
getName()to all…”). Prefer “CreatedgetName()for all…”.📝 Suggested patch
-- a90dd0a89b18a19bbb8ad72200d65df01c465fdb Created **`getName()`** to all package-specific errors and exceptions. Now `CnpjCheckDigitsException`, `CnpjCheckDigitsTypeError` and all their subclasses can return their class names without namespaces. This change is an API alignment across all **BR Utils** initiatives. +- a90dd0a89b18a19bbb8ad72200d65df01c465fdb Created **`getName()`** for all package-specific errors and exceptions. Now `CnpjCheckDigitsException`, `CnpjCheckDigitsTypeError`, and all their subclasses can return their class names without namespaces. This change is an API alignment across all **BR Utils** initiatives.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cnpj-dv/CHANGELOG.md` at line 7, The changelog sentence uses awkward phrasing ("Created `getName()` to all..."); update the line to use clearer wording such as "Created `getName()` for all package-specific errors and exceptions" and keep the references to `CnpjCheckDigitsException`, `CnpjCheckDigitsTypeError` and their subclasses intact so the line reads: Created `getName()` for all package-specific errors and exceptions. Now `CnpjCheckDigitsException`, `CnpjCheckDigitsTypeError` and all their subclasses can return their class names without namespaces. This change is an API alignment across all BR Utils initiatives.packages/cnpj-fmt/README.pt.md (1)
130-130:⚠️ Potential issue | 🟡 MinorGrammar: "são string" should be "são strings".
The predicate should agree in number with the subject ("Elementos que não são strings").
📝 Suggested fix
-**Array de strings:** cada elemento deve ser string; os valores são concatenados (por dígito, grupos ou misturados com pontuação — tudo é removido na normalização). Elementos que não são string não são permitidos. +**Array de strings:** cada elemento deve ser string; os valores são concatenados (por dígito, grupos ou misturados com pontuação — tudo é removido na normalização). Elementos que não são strings não são permitidos.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cnpj-fmt/README.pt.md` at line 130, Fix the grammatical agreement in the README sentence: change "cada elemento deve ser string" to "cada elemento deve ser strings" (or better, "cada elemento deve ser uma string") so it matches the plural subject used later ("Elementos que não são strings"); update the phrase in the line beginning "**Array de strings:** cada elemento..." accordingly to use the correct plural form.packages/cnpj-fmt/CHANGELOG.md (1)
17-17:⚠️ Potential issue | 🟡 MinorGrammar: "a instance" should be "an instance".
The article should be "an" before a word starting with a vowel sound.
📝 Suggested fix
-- **`CnpjFormatterOptions::merge()`** method no longer exists. Now, to create a new version of `CnpjFormatterOptions` merged with other customized options, just construct a instance of the class passing the argument **`overrides`**, which accepts an array of options, with the reference instance and the attributes you want to override. +- **`CnpjFormatterOptions::merge()`** method no longer exists. Now, to create a new version of `CnpjFormatterOptions` merged with other customized options, just construct an instance of the class passing the argument **`overrides`**, which accepts an array of options, with the reference instance and the attributes you want to override.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cnpj-fmt/CHANGELOG.md` at line 17, Fix the grammar in the CHANGELOG entry describing CnpjFormatterOptions: change the phrase "a instance of the class" to "an instance of the class" in the sentence that explains constructing a new CnpjFormatterOptions with the overrides array (the line referencing CnpjFormatterOptions::merge() and the overrides argument).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/cnpj-fmt/tests/Specs/Exceptions.spec.php`:
- Around line 127-128: In Exceptions.spec.php remove the extra blank line
between the two test blocks around the failing area (near line 128) so the test
cases are directly adjacent; update the spacing to match the surrounding test
block formatting in the Specs/Exceptions.spec.php file to maintain consistency
with other spec files.
In `@packages/cpf-dv/CHANGELOG.md`:
- Line 14: The changelog entry contains a typo: replace "dedicate private
method" with "dedicated private method" in the line mentioning the
CpfCheckDigits class so the entry reads "Moved some input parsing logic to
dedicated private method inside class `CpfCheckDigits`"; update the text in
CHANGELOG.md accordingly to correct the grammar.
---
Duplicate comments:
In `@packages/cnpj-dv/CHANGELOG.md`:
- Line 7: The changelog sentence uses awkward phrasing ("Created `getName()` to
all..."); update the line to use clearer wording such as "Created `getName()`
for all package-specific errors and exceptions" and keep the references to
`CnpjCheckDigitsException`, `CnpjCheckDigitsTypeError` and their subclasses
intact so the line reads: Created `getName()` for all package-specific errors
and exceptions. Now `CnpjCheckDigitsException`, `CnpjCheckDigitsTypeError` and
all their subclasses can return their class names without namespaces. This
change is an API alignment across all BR Utils initiatives.
In `@packages/cnpj-fmt/CHANGELOG.md`:
- Line 17: Fix the grammar in the CHANGELOG entry describing
CnpjFormatterOptions: change the phrase "a instance of the class" to "an
instance of the class" in the sentence that explains constructing a new
CnpjFormatterOptions with the overrides array (the line referencing
CnpjFormatterOptions::merge() and the overrides argument).
In `@packages/cnpj-fmt/README.pt.md`:
- Line 130: Fix the grammatical agreement in the README sentence: change "cada
elemento deve ser string" to "cada elemento deve ser strings" (or better, "cada
elemento deve ser uma string") so it matches the plural subject used later
("Elementos que não são strings"); update the phrase in the line beginning
"**Array de strings:** cada elemento..." accordingly to use the correct plural
form.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d6590ac7-95f0-4c2b-8842-33c85de71e90
📒 Files selected for processing (13)
packages/cnpj-dv/CHANGELOG.mdpackages/cnpj-dv/README.pt.mdpackages/cnpj-dv/src/Exceptions/CnpjCheckDigitsException.phppackages/cnpj-dv/src/Exceptions/CnpjCheckDigitsTypeError.phppackages/cnpj-fmt/CHANGELOG.mdpackages/cnpj-fmt/README.pt.mdpackages/cnpj-fmt/src/CnpjFormatterOptions.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterException.phppackages/cnpj-fmt/src/Exceptions/CnpjFormatterTypeError.phppackages/cnpj-fmt/tests/Specs/Exceptions.spec.phppackages/cpf-dv/CHANGELOG.mdpackages/cpf-dv/src/Exceptions/CpfCheckDigitsException.phppackages/cpf-dv/src/Exceptions/CpfCheckDigitsTypeError.php
Fix as per @coderabbitai review.
Fix as per @coderabbitai review at #38 (comment).
Fix as per @coderabbitai review at #38 (comment).
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/cnpj-fmt/tests/Specs/Exceptions.spec.php`:
- Around line 345-354: The test's expected message builds the string using
$forbiddenCharacters[0], which diverges from the implementation in
CnpjFormatterOptionsForbiddenKeyCharacterException that uses implode('", "',
$forbiddenCharacters); update the spec inside the it('has the correct message')
block to construct $message by using the same implode('"', '", "',
$forbiddenCharacters) pattern (i.e., interpolate the joined forbidden
characters) so the expected message matches the class's implementation for
single and multiple forbidden characters.
In `@packages/cpf-dv/CHANGELOG.md`:
- Line 7: Change the CHANGELOG entry wording to clearer English: replace
“Created `getName()` to all package-specific errors and exceptions” with “Added
`getName()` for all package-specific errors and exceptions”, keeping the rest of
the sentence (including references to `CpfCheckDigitsException`,
`CpfCheckDigitsTypeError`, and the note about API alignment) unchanged.
- Line 14: Fix the duplicated article in the changelog entry: change "to a a
dedicated private method inside class `CpfCheckDigits`" to "to a dedicated
private method inside class `CpfCheckDigits`" so the sentence reads correctly
and mentions the class name unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 93b222ae-f302-4afb-9159-4701bdd2add1
📒 Files selected for processing (3)
packages/cnpj-dv/src/CnpjCheckDigits.phppackages/cnpj-fmt/tests/Specs/Exceptions.spec.phppackages/cpf-dv/CHANGELOG.md
💤 Files with no reviewable changes (1)
- packages/cnpj-dv/src/CnpjCheckDigits.php
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/cpf-dv/CHANGELOG.md (1)
7-7:⚠️ Potential issue | 🟡 MinorUse clearer wording in the feature entry.
Line 7 still reads awkwardly (“Created
getName()to all…”). Prefer “AddedgetName()for all package-specific errors and exceptions.”✏️ Proposed patch
-- 4866d4089da3b8b79d7fd3b0b9fe56ad607e4dbd Created **`getName()`** to all package-specific errors and exceptions. Now `CpfCheckDigitsException`, `CpfCheckDigitsTypeError` and all their subclasses can return their class names without namespaces. This change is an API alignment across all **BR Utils** initiatives. +- 4866d4089da3b8b79d7fd3b0b9fe56ad607e4dbd Added **`getName()`** for all package-specific errors and exceptions. Now `CpfCheckDigitsException`, `CpfCheckDigitsTypeError` and all their subclasses can return their class names without namespaces. This change is an API alignment across all **BR Utils** initiatives.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/cpf-dv/CHANGELOG.md` at line 7, The changelog entry wording is awkward; update the sentence to use clearer phrasing such as "Added `getName()` for all package-specific errors and exceptions." Edit the line referencing `getName()`, `CpfCheckDigitsException`, and `CpfCheckDigitsTypeError` so it reads succinctly (e.g., "Added `getName()` for all package-specific errors and exceptions; now `CpfCheckDigitsException`, `CpfCheckDigitsTypeError` and their subclasses can return class names without namespaces.") and ensure the rest of the entry preserves the API alignment note.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/cnpj-fmt/tests/Specs/Exceptions.spec.php`:
- Around line 19-58: The tests repeatedly instantiate exceptions (e.g., new
TestTypeError(123, 'number', 'string', 'some error')) in each it block; reduce
duplication by introducing a shared setup: add a beforeEach (or a local factory
function) inside the describe block that creates the TestTypeError instance
(store it in a variable like $error or provide a createError() helper) and
update each it to use that shared instance/factory; apply the same refactor
pattern for the other exception describe blocks that repeat constructors (the
sections around lines 65-109, 116-167, 178-199, 206-250, 257-308, 315-358) using
their respective exception classes.
---
Duplicate comments:
In `@packages/cpf-dv/CHANGELOG.md`:
- Line 7: The changelog entry wording is awkward; update the sentence to use
clearer phrasing such as "Added `getName()` for all package-specific errors and
exceptions." Edit the line referencing `getName()`, `CpfCheckDigitsException`,
and `CpfCheckDigitsTypeError` so it reads succinctly (e.g., "Added `getName()`
for all package-specific errors and exceptions; now `CpfCheckDigitsException`,
`CpfCheckDigitsTypeError` and their subclasses can return class names without
namespaces.") and ensure the rest of the entry preserves the API alignment note.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f06bae63-fb4d-4ef4-bf8a-d75fe8b22265
📒 Files selected for processing (2)
packages/cnpj-fmt/tests/Specs/Exceptions.spec.phppackages/cpf-dv/CHANGELOG.md
Fix as per @coderabbitai review comment at LacusSolutions/br-utils-php#38 (comment).
Fix as per @coderabbitai review comment at LacusSolutions/br-utils-php#38 (comment).
Fix as per @coderabbitai review comment at LacusSolutions/br-utils-php#38 (comment).
Fix as per @coderabbitai review comment at LacusSolutions/br-utils-php#38 (comment).
Fix as per @coderabbitai review at LacusSolutions/br-utils-php#38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review comment at LacusSolutions/br-utils-php#38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
Fix as per @coderabbitai review at #38 (comment).
Fix as per @coderabbitai review comment at #38 (comment).
Summary by CodeRabbit
New Features
Breaking Changes
Documentation