Skip to content

Create "Masked" validator#1652

Merged
henriquemoody merged 2 commits intoRespect:mainfrom
henriquemoody:rule/masked
Jan 30, 2026
Merged

Create "Masked" validator#1652
henriquemoody merged 2 commits intoRespect:mainfrom
henriquemoody:rule/masked

Conversation

@henriquemoody
Copy link
Member

The Masked validator decorates other validators to mask sensitive input values in error messages while still validating the original unmasked data.

This validator is essential for applications handling sensitive information such as passwords, credit cards, or email addresses. Without it, users would need to implement a custom layer between Validation and the end user to prevent PII from appearing in error messages or logs.

With Masked, sensitive data protection is built directly into the validation workflow with no additional abstraction required.

@henriquemoody henriquemoody requested a review from Copilot January 30, 2026 19:27
@henriquemoody henriquemoody changed the title Create "Masked" rule Create "Masked" validator Jan 30, 2026
@henriquemoody henriquemoody force-pushed the rule/masked branch 4 times, most recently from 9174105 to 4861e53 Compare January 30, 2026 19:30
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Masked validator that decorates an inner validator to mask the input value used in validation error messages (PII-safe), plus supporting Result input propagation and documentation/tests.

Changes:

  • Introduces Masked validator and exposes it through mixin builder/chain APIs (e.g., v::masked(...), nullOrMasked(...), etc.).
  • Adds Result::withInput() to propagate masked input through adjacent results and selected child results.
  • Adds unit/feature tests, fixtures updates, and documentation for the new validator.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/unit/Validators/MaskedTest.php Unit tests for Masked construction, type handling, and masking behavior.
tests/unit/ResultTest.php Unit tests for new Result::withInput() propagation behavior.
tests/src/TestCase.php Adds data providers for “string values” vs “non-string values” used by new tests.
tests/src/Stubs/ToStringStub.php Updates stub to implement Stringable for StringVal-compatible test coverage.
tests/fixtures/data-provider.php Extends fixture tags to support stringVal-driven data providers and adds a Stringable object case.
tests/feature/Validators/MaskedTest.php Feature tests verifying masking and error messages via the public API (v::masked).
src/Validators/Masked.php Implements the new Masked validator using MaskFormatter and StringVal.
src/Result.php Adds withInput() and refactors adjacent handling to support masked inputs in result trees.
src/Mixins/UndefOrChain.php Declares undefOrMasked(...) chain method.
src/Mixins/UndefOrBuilder.php Declares undefOrMasked(...) builder method.
src/Mixins/PropertyChain.php Declares propertyMasked(...) chain method.
src/Mixins/PropertyBuilder.php Declares propertyMasked(...) builder method.
src/Mixins/NullOrChain.php Declares nullOrMasked(...) chain method.
src/Mixins/NullOrBuilder.php Declares nullOrMasked(...) builder method.
src/Mixins/NotChain.php Declares notMasked(...) chain method.
src/Mixins/NotBuilder.php Declares notMasked(...) builder method.
src/Mixins/KeyChain.php Declares keyMasked(...) chain method.
src/Mixins/KeyBuilder.php Declares keyMasked(...) builder method.
src/Mixins/Chain.php Declares base masked(...) chain method.
src/Mixins/Builder.php Declares base masked(...) builder method.
src/Mixins/AllChain.php Declares allMasked(...) chain method.
src/Mixins/AllBuilder.php Declares allMasked(...) builder method.
src-dev/Markdown/Linters/ValidatorHeaderLinter.php Updates doc linting rules to treat *TextMasker types as special-cased.
src-dev/Commands/LintMixinCommand.php Updates mixin lint command to handle *TextMasker types and imports str_ends_with.
docs/validators/Masked.md Adds end-user documentation for the new validator and examples.
docs/validators.md Adds Masked to the validator index and categorization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Adjacent results are results that treat the same input. When overwriting
the input of a result, we should also overwrite the input of its adjacent
result to maintain consistency. Currently, there are no cases where this
has caused issues, but this change prevents potential problems.

Assisted-by: Claude Code (Opus 4.5)
@henriquemoody henriquemoody force-pushed the rule/masked branch 3 times, most recently from 06d264c to 7fbecc1 Compare January 30, 2026 19:50
@codecov
Copy link

codecov bot commented Jan 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.20%. Comparing base (ec16b3d) to head (882f24b).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #1652      +/-   ##
============================================
+ Coverage     99.19%   99.20%   +0.01%     
- Complexity      908      915       +7     
============================================
  Files           190      191       +1     
  Lines          2117     2146      +29     
============================================
+ Hits           2100     2129      +29     
  Misses           17       17              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@henriquemoody henriquemoody force-pushed the rule/masked branch 6 times, most recently from 11328bf to eece812 Compare January 30, 2026 20:04
The Masked validator decorates other validators to mask sensitive input
values in error messages while still validating the original unmasked
data.

This validator is essential for applications handling sensitive
information such as passwords, credit cards, or email addresses. Without
it, users would need to implement a custom layer between Validation and
the end user to prevent PII from appearing in error messages or logs.

With Masked, sensitive data protection is built directly into the
validation workflow with no additional abstraction required.

Assisted-by: Claude Code (Opus 4.5)
@henriquemoody henriquemoody marked this pull request as ready for review January 30, 2026 20:06
@henriquemoody henriquemoody requested a review from alganet January 30, 2026 20:06
@henriquemoody henriquemoody merged commit 882f24b into Respect:main Jan 30, 2026
7 checks passed
@henriquemoody henriquemoody deleted the rule/masked branch January 30, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants