Files
skills/docs/foundation/data/data-masking/src/schemas/mask-rule.schema.md
2026-05-29 08:20:56 +01:00

123 lines
3.8 KiB
Markdown

# mask-rule.schema
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Provides Zod schemas for all public configuration types in
`@suaveplan/data-masking`. Runtime validation of `MaskRule` and `MaskOptions`
objects is important when rules originate from external sources such as API
request bodies, configuration files, or database records. Using these schemas
before calling `maskObject` prevents silent mis-configurations — for example, a
rule with an empty `fields` array or an unrecognised `strategy` string — from
causing confusing runtime behaviour.
Exporting the schemas as a dedicated subpath (`./schemas`) allows tree-shaking
in production bundles that never parse external rule definitions.
## Features
- `MaskStrategySchema` — exhaustive `z.enum` of all eight strategy strings.
- `MaskRuleSchema` — validates `fields` (non-empty array of non-empty strings),
`strategy`, and optional `keepLast`, `keepFirst`, `replacement` fields.
- `MaskOptionsSchema` — validates `rules` (at least one required), `deep`,
`maskArrays`.
- Input types (`MaskStrategyInput`, `MaskRuleInput`, `MaskOptionsInput`)
exported for use in form and API validation pipelines.
## Usage: Basic Example
```ts
import { MaskRuleSchema } from '@suaveplan/data-masking/schemas';
const parsed = MaskRuleSchema.safeParse({
fields: ['user.email'],
strategy: 'email',
});
if (!parsed.success) {
console.error(parsed.error.issues);
} else {
console.log(parsed.data.strategy); // 'email'
}
```
## Usage: Advanced Example
```ts
import { MaskOptionsSchema } from '@suaveplan/data-masking/schemas';
import { maskObject } from '@suaveplan/data-masking';
function safeMaskObject(
data: Record<string, unknown>,
rawOptions: unknown,
) {
const options = MaskOptionsSchema.parse(rawOptions); // throws ZodError on invalid input
return maskObject(data, options);
}
// Use from an API request body
const result = safeMaskObject(userData, req.body.maskOptions);
```
## API Reference
### `MaskStrategySchema`
```ts
const MaskStrategySchema: z.ZodEnum<[
'full', 'partial', 'email', 'phone',
'credit-card', 'hash', 'tokenize', 'preserve-format'
]>;
```
Validates that a string is one of the eight supported masking strategy
identifiers.
### `MaskRuleSchema`
```ts
const MaskRuleSchema: z.ZodObject<{
fields: z.ZodArray<z.ZodString>; // min 1 item, each min 1 char
strategy: typeof MaskStrategySchema;
keepLast?: z.ZodNumber; // int, non-negative
keepFirst?: z.ZodNumber; // int, non-negative
replacement?: z.ZodString;
}>;
```
### `MaskOptionsSchema`
```ts
const MaskOptionsSchema: z.ZodObject<{
rules: z.ZodArray<typeof MaskRuleSchema>; // min 1 item
deep?: z.ZodBoolean;
maskArrays?: z.ZodBoolean;
}>;
```
### Input types
```ts
type MaskStrategyInput = z.input<typeof MaskStrategySchema>;
type MaskRuleInput = z.input<typeof MaskRuleSchema>;
type MaskOptionsInput = z.input<typeof MaskOptionsSchema>;
```
These are the raw (un-coerced) input types, useful for TypeScript annotations
in form handlers and API route definitions before calling `.parse()`.
## Implementation Notes
- `z.number().int().nonnegative()` is used for `keepLast` and `keepFirst` to
reject fractional or negative values that would produce nonsensical results
in the `partial` strategy.
- `z.array(...).min(1)` on both `fields` and `rules` prevents silent no-op
configurations — a rule with no fields or an options object with no rules
would be a programming error.
- The schema file is excluded from coverage measurement (via `*.schema.ts`
exclusion in `vitest.config.ts`) because it is declarative Zod schema
definition code; meaningful coverage comes from integration tests of the
schemas via `safeParse`/`parse`, not line-by-line execution tracing.