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,82 @@
# credit-card strategy
## Purpose
The `credit-card` masking strategy produces the PCI-DSS-compatible truncation
format for payment card numbers: last 4 digits visible, all preceding digit
positions replaced with `*`, formatting separators preserved. This aligns
with the PCI DSS 4.0 requirement that primary account numbers (PANs) must be
rendered unreadable in logs and displays, while retaining just enough
information for card identification and customer service operations.
## Features
- Last-4-digit preservation regardless of separator style.
- Hyphens, spaces, and other non-digit characters pass through unchanged.
- Handles formatted (`4111-1111-1111-1111`) and raw (`4111111111111111`) inputs.
- No regex capture groups — single linear pass, O(n) complexity.
## Usage: Basic Example
```ts
import { maskCreditCard } from '@suaveplan/data-masking/strategies/credit-card';
const masked = maskCreditCard('4111-1111-1111-1111', {
fields: ['cardNumber'],
strategy: 'credit-card',
});
// masked → '****-****-****-1111'
```
## Usage: Advanced Example
```ts
import { maskCreditCard } from '@suaveplan/data-masking/strategies/credit-card';
// No separators
maskCreditCard('5500005555555559', { fields: ['pan'], strategy: 'credit-card' });
// → '************5559'
// Space-separated format
maskCreditCard('4111 1111 1111 1111', { fields: ['pan'], strategy: 'credit-card' });
// → '**** **** **** 1111'
// Amex 15-digit
maskCreditCard('3714 496353 98431', { fields: ['pan'], strategy: 'credit-card' });
// → '**** ****** *8431'
// No digits at all → passthrough
maskCreditCard('CARD-ON-FILE', { fields: ['pan'], strategy: 'credit-card' });
// → 'CARD-ON-FILE'
```
## API Reference
### `maskCreditCard(value, rule)`
```ts
function maskCreditCard(value: string, rule: MaskRule): string;
```
| Parameter | Type | Description |
|-----------|------------|-----------------------------------------------------------|
| `value` | `string` | The original card number in any format. |
| `rule` | `MaskRule` | Driving rule (no fields consumed by credit-card strategy).|
**Returns** the masked card number 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 algorithm is identical in structure to the `phone` strategy: extract all
digits to find the `keepFrom` threshold, then rebuild the string in a single
pass. The two strategies are kept as separate files to allow divergent
evolution (e.g. future BIN-preservation or Luhn-check validation in the
credit-card variant).
- `Math.max(0, digits.length - 4)` ensures cards with 4 or fewer digits are
returned unchanged, consistent with the principle of least surprise.
- The `rule` parameter is silently voided to satisfy the uniform strategy
interface; no `MaskRule` fields are read.