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,79 @@
# preserve-format strategy
## Purpose
The `preserve-format` masking strategy replaces every alphanumeric character
with a placeholder of the same character class — digits become `0`, letters
become `X` — while leaving all punctuation, spaces, and special characters
unchanged. The result has the same total length and the same structural
"skeleton" as the original, which allows downstream systems (parsers, validators,
format checkers) to continue operating on the masked data without seeing any
real content. This is particularly useful in schema-validation pipelines that
process PII-bearing fields and must remain functional during testing against
production-shaped data.
## Features
- Length-preserving: output has exactly the same character count as input.
- Character-class-preserving: digits → `0`, letters → `X`, other → verbatim.
- No regex — single character-by-character pass, safe on all Unicode inputs
(only ASCII alphanumerics are substituted; non-ASCII passes through).
- Zero external dependencies.
## Usage: Basic Example
```ts
import { maskPreserveFormat } from '@suaveplan/data-masking/strategies/preserve-format';
const masked = maskPreserveFormat('Hello123', { fields: ['code'], strategy: 'preserve-format' });
// masked → 'XXXXX000'
```
## Usage: Advanced Example
```ts
import { maskPreserveFormat } from '@suaveplan/data-masking/strategies/preserve-format';
// Phone with separators
maskPreserveFormat('+1-555-123-4567', { fields: ['phone'], strategy: 'preserve-format' });
// → '+0-000-000-0000'
// Mixed alphanumeric code
maskPreserveFormat('AB12-CD34-EF56', { fields: ['serial'], strategy: 'preserve-format' });
// → 'XX00-XX00-XX00'
// Non-ASCII pass-through (accented chars preserved)
maskPreserveFormat('café 42', { fields: ['label'], strategy: 'preserve-format' });
// → 'XXXX 00' (é is non-ASCII and passes through as-is)
```
## API Reference
### `maskPreserveFormat(value, rule)`
```ts
function maskPreserveFormat(value: string, rule: MaskRule): string;
```
| Parameter | Type | Description |
|-----------|------------|----------------------------------------------------------------|
| `value` | `string` | The original string to format-preserve. |
| `rule` | `MaskRule` | Driving rule (no fields consumed by preserve-format strategy). |
**Returns** a same-length string with alphanumeric chars replaced by `0` / `X`
and all other chars preserved.
**Does not throw.**
## Implementation Notes
- Only ASCII alphanumerics (`a-z`, `A-Z`, `0-9`) are replaced. Non-ASCII
characters (including accented letters, CJK, emoji) pass through unchanged.
This is intentional: the strategy targets structured English-language data
formats (phone numbers, reference codes, account identifiers) where only
ASCII alphanumerics carry sensitive content.
- The `for...of` iteration correctly handles multi-code-unit Unicode characters
(surrogate pairs) because JavaScript iterates by codepoint in `for...of`.
The ASCII range check ensures non-ASCII characters are passed through intact.
- The `rule` parameter is silently voided to satisfy the uniform strategy
interface.