# @suaveplan/data-masking - PII/sensitive data masking for objects and strings: field-level masking rules, nested object traversal, format-preserving masking, tokenization, and FNV-1a hashing. ## Summary PII/sensitive data masking for objects and strings with field-level rules, nested traversal, eight masking strategies, and OpenTelemetry instrumentation. ## Documentation tree - [masker](./src/core/masker/object-masker.md) — _(no submodules)_ - [object-masker](./src/core/masker/object-masker.md) — _(no submodules)_ - [errors](./src/errors/data-masking-error.md) — _(no submodules)_ - [data-masking-error](./src/errors/data-masking-error.md) — _(no submodules)_ - [schemas](./src/schemas/mask-rule.schema.md) — _(no submodules)_ - [mask-rule.schema](./src/schemas/mask-rule.schema.md) — _(no submodules)_ - [credit-card](./src/strategies/credit-card.md) — The `credit-card` masking strategy produces the PCI-DSS-compatible truncation format for payment card numbers: last 4 d… - [email](./src/strategies/email.md) — The `email` masking strategy anonymises email addresses while keeping the output immediately recognisable as an email a… - [full](./src/strategies/full.md) — The `full` masking strategy completely replaces an input string with a configurable replacement sentinel. It is the mos… - [hash](./src/strategies/hash.md) — The `hash` masking strategy produces a deterministic, fixed-length 8-character hexadecimal token from any input string… - [partial](./src/strategies/partial.md) — The `partial` masking strategy preserves a configurable number of characters at the start and end of an input string wh… - [phone](./src/strategies/phone.md) — The `phone` masking strategy anonymises phone numbers while preserving their formatting separators, making masked value… - [preserve-format](./src/strategies/preserve-format.md) — The `preserve-format` masking strategy replaces every alphanumeric character with a placeholder of the same character c… - [tokenize](./src/strategies/tokenize.md) — The `tokenize` masking strategy replaces a sensitive value with a structured opaque token of the form `TOKEN_… - [types](./src/types/mask-types.md) — _(no submodules)_ - [mask-types](./src/types/mask-types.md) — _(no submodules)_ - [utils](./src/utils/path-matcher.md) — _(no submodules)_ - [path-matcher](./src/utils/path-matcher.md) — _(no submodules)_ - [object-masker](./src/core/masker/object-masker.md) — _(no submodules)_- [errors](./src/errors/data-masking-error.md) — _(no submodules)_- [data-masking-error](./src/errors/data-masking-error.md) — _(no submodules)_- [schemas](./src/schemas/mask-rule.schema.md) — _(no submodules)_- [mask-rule.schema](./src/schemas/mask-rule.schema.md) — _(no submodules)_- [credit-card](./src/strategies/credit-card.md) — The `credit-card` masking strategy produces the PCI-DSS-compatible truncation format for payment card numbers: last 4 d… - [email](./src/strategies/email.md) — The `email` masking strategy anonymises email addresses while keeping the output immediately recognisable as an email a… - [full](./src/strategies/full.md) — The `full` masking strategy completely replaces an input string with a configurable replacement sentinel. It is the mos… - [hash](./src/strategies/hash.md) — The `hash` masking strategy produces a deterministic, fixed-length 8-character hexadecimal token from any input string… - [partial](./src/strategies/partial.md) — The `partial` masking strategy preserves a configurable number of characters at the start and end of an input string wh… - [phone](./src/strategies/phone.md) — The `phone` masking strategy anonymises phone numbers while preserving their formatting separators, making masked value… - [preserve-format](./src/strategies/preserve-format.md) — The `preserve-format` masking strategy replaces every alphanumeric character with a placeholder of the same character c… - [tokenize](./src/strategies/tokenize.md) — The `tokenize` masking strategy replaces a sensitive value with a structured opaque token of the form `TOKEN_… - [types](./src/types/mask-types.md) — _(no submodules)_- [mask-types](./src/types/mask-types.md) — _(no submodules)_- [utils](./src/utils/path-matcher.md) — _(no submodules)_- [path-matcher](./src/utils/path-matcher.md) — _(no submodules)_- [object-masker](./src/core/masker/object-masker.md) — _(no submodules)_- [errors](./src/errors/data-masking-error.md) — _(no submodules)_- [data-masking-error](./src/errors/data-masking-error.md) — _(no submodules)_- [schemas](./src/schemas/mask-rule.schema.md) — _(no submodules)_- [mask-rule.schema](./src/schemas/mask-rule.schema.md) — _(no submodules)_- [credit-card](./src/strategies/credit-card.md) — The `credit-card` masking strategy produces the PCI-DSS-compatible truncation format for payment card numbers: last 4 d… - [email](./src/strategies/email.md) — The `email` masking strategy anonymises email addresses while keeping the output immediately recognisable as an email a… - [full](./src/strategies/full.md) — The `full` masking strategy completely replaces an input string with a configurable replacement sentinel. It is the mos… - [hash](./src/strategies/hash.md) — The `hash` masking strategy produces a deterministic, fixed-length 8-character hexadecimal token from any input string… - [partial](./src/strategies/partial.md) — The `partial` masking strategy preserves a configurable number of characters at the start and end of an input string wh… - [phone](./src/strategies/phone.md) — The `phone` masking strategy anonymises phone numbers while preserving their formatting separators, making masked value… - [preserve-format](./src/strategies/preserve-format.md) — The `preserve-format` masking strategy replaces every alphanumeric character with a placeholder of the same character c… - [tokenize](./src/strategies/tokenize.md) — The `tokenize` masking strategy replaces a sensitive value with a structured opaque token of the form `TOKEN_… - [types](./src/types/mask-types.md) — _(no submodules)_- [mask-types](./src/types/mask-types.md) — _(no submodules)_- [utils](./src/utils/path-matcher.md) — _(no submodules)_- [path-matcher](./src/utils/path-matcher.md) — _(no submodules)_- [object-masker](./src/core/masker/object-masker.md) — _(no submodules)_- [errors](./src/errors/data-masking-error.md) — _(no submodules)_- [data-masking-error](./src/errors/data-masking-error.md) — _(no submodules)_- [schemas](./src/schemas/mask-rule.schema.md) — _(no submodules)_- [mask-rule.schema](./src/schemas/mask-rule.schema.md) — _(no submodules)_- [credit-card](./src/strategies/credit-card.md) — The `credit-card` masking strategy produces the PCI-DSS-compatible truncation format for payment card numbers: last 4 d… - [email](./src/strategies/email.md) — The `email` masking strategy anonymises email addresses while keeping the output immediately recognisable as an email a… - [full](./src/strategies/full.md) — The `full` masking strategy completely replaces an input string with a configurable replacement sentinel. It is the mos… - [hash](./src/strategies/hash.md) — The `hash` masking strategy produces a deterministic, fixed-length 8-character hexadecimal token from any input string… - [partial](./src/strategies/partial.md) — The `partial` masking strategy preserves a configurable number of characters at the start and end of an input string wh… - [phone](./src/strategies/phone.md) — The `phone` masking strategy anonymises phone numbers while preserving their formatting separators, making masked value… - [preserve-format](./src/strategies/preserve-format.md) — The `preserve-format` masking strategy replaces every alphanumeric character with a placeholder of the same character c… - [tokenize](./src/strategies/tokenize.md) — The `tokenize` masking strategy replaces a sensitive value with a structured opaque token of the form `TOKEN_… - [types](./src/types/mask-types.md) — _(no submodules)_- [mask-types](./src/types/mask-types.md) — _(no submodules)_- [utils](./src/utils/path-matcher.md) — _(no submodules)_- [path-matcher](./src/utils/path-matcher.md) — _(no submodules)_- [object-masker](./src/core/masker/object-masker.md) — _(no submodules)_- [errors](./src/errors/data-masking-error.md) — _(no submodules)_ - [data-masking-error](./src/errors/data-masking-error.md) — _(no submodules)_- [schemas](./src/schemas/mask-rule.schema.md) — _(no submodules)_ - [mask-rule.schema](./src/schemas/mask-rule.schema.md) — _(no submodules)_- [credit-card](./src/strategies/credit-card.md) — The `credit-card` masking strategy produces the PCI-DSS-compatible truncation format for payment card numbers: last 4 d… - [email](./src/strategies/email.md) — The `email` masking strategy anonymises email addresses while keeping the output immediately recognisable as an email a… - [full](./src/strategies/full.md) — The `full` masking strategy completely replaces an input string with a configurable replacement sentinel. It is the mos… - [hash](./src/strategies/hash.md) — The `hash` masking strategy produces a deterministic, fixed-length 8-character hexadecimal token from any input string… - [partial](./src/strategies/partial.md) — The `partial` masking strategy preserves a configurable number of characters at the start and end of an input string wh… - [phone](./src/strategies/phone.md) — The `phone` masking strategy anonymises phone numbers while preserving their formatting separators, making masked value… - [preserve-format](./src/strategies/preserve-format.md) — The `preserve-format` masking strategy replaces every alphanumeric character with a placeholder of the same character c… - [tokenize](./src/strategies/tokenize.md) — The `tokenize` masking strategy replaces a sensitive value with a structured opaque token of the form `TOKEN_… - [types](./src/types/mask-types.md) — _(no submodules)_ - [mask-types](./src/types/mask-types.md) — _(no submodules)_- [utils](./src/utils/path-matcher.md) — _(no submodules)_ - [path-matcher](./src/utils/path-matcher.md) — _(no submodules)_ ## Installation ```bash bun add @suaveplan/data-masking ``` ## Quick Start ```ts import { maskObject } from '@suaveplan/data-masking'; const result = maskObject( { user: { name: 'John Doe', email: 'john@example.com', ssn: '123-45-6789' }, payment: { cardNumber: '4111-1111-1111-1111', cvv: '123' }, }, { rules: [ { fields: ['user.email'], strategy: 'email' }, { fields: ['user.ssn', 'payment.cvv'], strategy: 'full' }, { fields: ['payment.cardNumber'], strategy: 'credit-card' }, ], }, ); console.log(result.masked.user.email); // 'j***@e***.com' console.log(result.masked.payment.cardNumber); // '****-****-****-1111' console.log(result.fieldsAffected); // ['payment.cardNumber', 'payment.cvv', 'user.email', 'user.ssn'] ``` ## Strategies | Strategy | Description | Example output | |-------------------|------------------------------------------|-------------------------| | `full` | Replace entire value with `***` | `***` | | `partial` | Keep first/last N chars, mask middle | `sk_***...****789` | | `email` | Format-preserving email mask | `j***@e***.com` | | `phone` | Keep last 4 digits | `***-***-1234` | | `credit-card` | Keep last 4 digits | `****-****-****-1234` | | `hash` | FNV-1a 32-bit hex (deterministic) | `4f9f2cab` | | `tokenize` | Opaque token (not reversible) | `TOKEN_TOKENIZE_0` | | `preserve-format` | Replace alnum with type placeholder | `XXXXX000` | ## Field Path Patterns Rules use dot-notation paths with optional glob wildcards: ```ts { fields: ['user.email'] } // exact match { fields: ['user.*'] } // single-segment wildcard { fields: ['user.**'] } // multi-segment wildcard (any depth) { fields: ['**.email'] } // any path ending in .email ``` ## Modules | Subpath | Contents | |---------------------|--------------------------------------------| | `@suaveplan/data-masking` | Main exports (maskObject, maskString, maskValue, types, schemas) | | `@suaveplan/data-masking/masker` | [object-masker](src/core/masker/object-masker.md) — core traversal engine | | `@suaveplan/data-masking/strategies` | [full](src/strategies/full.md), [partial](src/strategies/partial.md), [email](src/strategies/email.md), [phone](src/strategies/phone.md), [credit-card](src/strategies/credit-card.md), [hash](src/strategies/hash.md), [tokenize](src/strategies/tokenize.md), [preserve-format](src/strategies/preserve-format.md) | | `@suaveplan/data-masking/errors` | [DataMaskingError](src/errors/data-masking-error.md), `DATA_MASKING_CODES` | | `@suaveplan/data-masking/schemas` | Zod schemas for `MaskRule`, `MaskOptions` | ## License MIT