first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
# phone strategy
## Purpose
The `phone` masking strategy anonymises phone numbers while preserving their
formatting separators, making masked values easy to read in logs and audit
trails. Only the last 4 digits are kept; all other digit positions are
replaced with `*`. Non-digit characters (hyphens, spaces, parentheses, dots,
`+`) pass through unchanged, so the output retains the same visual structure
as the input regardless of locale or formatting convention.
## Features
- Last-4-digit preservation regardless of phone format.
- Separator characters (`-`, ` `, `(`, `)`, `.`, `+`) are preserved verbatim.
- Handles international formats (`+1-…`), US formats (`(555) 123-4567`), and
unformatted digit strings (`5551234567`).
- No regex-based capture groups or lookaheads — single linear pass.
## Usage: Basic Example
```ts
import { maskPhone } from '@suaveplan/data-masking/strategies/phone';
const masked = maskPhone('+1-555-123-4567', { fields: ['phone'], strategy: 'phone' });
// masked → '*-***-***-4567'
```
## Usage: Advanced Example
```ts
import { maskPhone } from '@suaveplan/data-masking/strategies/phone';
// US format with parentheses
maskPhone('(555) 123-4567', { fields: ['phone'], strategy: 'phone' });
// → '(***) ***-4567'
// E.164 international
maskPhone('+447911123456', { fields: ['phone'], strategy: 'phone' });
// → '+*********3456'
// Unformatted
maskPhone('5551234567', { fields: ['phone'], strategy: 'phone' });
// → '******4567'
// No digits at all → passthrough
maskPhone('N/A', { fields: ['phone'], strategy: 'phone' });
// → 'N/A'
```
## API Reference
### `maskPhone(value, rule)`
```ts
function maskPhone(value: string, rule: MaskRule): string;
```
| Parameter | Type | Description |
|-----------|------------|----------------------------------------------------------|
| `value` | `string` | The original phone number in any format. |
| `rule` | `MaskRule` | Driving rule (no fields are consumed by phone strategy). |
**Returns** the masked phone string with last 4 digits preserved and all other
digit positions replaced by `*`.
**Does not throw.** Returns the original value unchanged when no digit
characters are found.
## Implementation Notes
- The strategy extracts all digits first to determine the `keepFrom` boundary
(total digits minus 4), then makes a single linear pass over the original
string to rebuild the result. This avoids multi-pass scanning and keeps
the logic O(n).
- `Math.max(0, digits.length - 4)` ensures that strings with 4 or fewer digits
are returned with all digits preserved (no masking applied), matching the
principle of least surprise.
- The `rule` parameter is accepted to satisfy the uniform strategy interface
but none of its fields are consumed.