first commit
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user