first commit
This commit is contained in:
88
docs/foundation/data/data-masking/src/utils/path-matcher.md
Normal file
88
docs/foundation/data/data-masking/src/utils/path-matcher.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# path-matcher
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Implements a lightweight glob-style matcher for dot-notation object-path
|
||||
strings used by `@suaveplan/data-masking`'s rule engine. When a `MaskRule`
|
||||
declares `fields: ['user.*']` the path matcher is responsible for deciding
|
||||
whether a path like `'user.email'` satisfies that pattern during object
|
||||
traversal. Zero external dependencies are required — the entire implementation
|
||||
is a recursive backtracking segment comparator that handles the three modes
|
||||
callers need in practice.
|
||||
|
||||
## Features
|
||||
|
||||
- Exact matching: `"user.email"` matches `"user.email"`.
|
||||
- Single-segment wildcard `*`: matches any one dot-separated segment.
|
||||
- Multi-segment wildcard `**`: matches zero or more consecutive dot-separated
|
||||
segments, enabling patterns like `"**.email"` or `"user.**"`.
|
||||
- Correct handling of leading, trailing, and adjacent wildcards through
|
||||
backtracking.
|
||||
- Pure function — no state, no side-effects, zero allocations beyond the
|
||||
initial `split`.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { matchPath } from '@suaveplan/data-masking/utils/path-matcher';
|
||||
|
||||
matchPath('user.email', 'user.email'); // true — exact
|
||||
matchPath('user.name', 'user.email'); // false — no match
|
||||
matchPath('user.email', 'user.*'); // true — single wildcard
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { matchPath } from '@suaveplan/data-masking/utils/path-matcher';
|
||||
|
||||
// Match any path ending in .email regardless of depth
|
||||
matchPath('billing.contact.email', '**.email'); // true
|
||||
matchPath('email', '**.email'); // true (** matches zero segs)
|
||||
|
||||
// Match everything under user.*
|
||||
matchPath('user.address.city', 'user.**'); // true
|
||||
matchPath('user.address.city', 'user.*'); // false — * is single-segment only
|
||||
matchPath('user.address', 'user.*'); // true
|
||||
|
||||
// Combine wildcards
|
||||
matchPath('a.b.c.d', '*.b.**.d'); // true
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `matchPath(fieldPath, pattern)`
|
||||
|
||||
```ts
|
||||
function matchPath(fieldPath: string, pattern: string): boolean;
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-------------|----------|--------------------------------------------------------|
|
||||
| `fieldPath` | `string` | Concrete dot-notation path, e.g. `"user.address.zip"`. |
|
||||
| `pattern` | `string` | Glob pattern with optional `*` / `**` wildcards. |
|
||||
|
||||
**Returns** `true` when `fieldPath` satisfies `pattern`, `false` otherwise.
|
||||
|
||||
**Does not throw.** Both empty strings are treated as single empty-segment
|
||||
paths and will only match each other or a lone `*` / `**` pattern.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The implementation splits both inputs on `"."` and feeds the resulting
|
||||
arrays into a recursive `matchSegments` helper. The recursion depth is
|
||||
bounded by `Math.max(pathSegments, patternSegments)`, which in practice is
|
||||
small (typically < 10 for real object paths).
|
||||
- The `**` wildcard uses a greedy-with-backtrack strategy: it first attempts
|
||||
to match zero path segments (advance only the pattern pointer), then
|
||||
progressively tries consuming one more path segment per recursive call.
|
||||
This guarantees correct results for patterns like `"**.email"` where `**`
|
||||
must match zero leading segments.
|
||||
- No regular expressions are used, avoiding edge-case escaping issues with
|
||||
field names that contain regex metacharacters (dots, brackets, etc.).
|
||||
- The function is intentionally kept free of any optional parameters or
|
||||
configuration — the three modes (exact, `*`, `**`) cover every use case
|
||||
encountered in PII field-path matching.
|
||||
Reference in New Issue
Block a user