first commit
This commit is contained in:
91
docs/security-stack/security/license/src/schemas/schemas.md
Normal file
91
docs/security-stack/security/license/src/schemas/schemas.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# `@suaveplan/license` — schemas
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Zod schemas for every public input boundary in the license package.
|
||||
`generateLicense`, `validateLicense`, `createPayload`, and the
|
||||
`LicenseManager` methods parse their inputs against these schemas at
|
||||
entry; failed parses raise `LicenseError(LICENSE.INVALID_INPUT)` with
|
||||
the `ZodError` attached as `cause`. Centralising the schemas here keeps
|
||||
the runtime modules thin and ensures downstream Zod-aware consumers
|
||||
(form validators, OpenAPI generators) can reuse the same shapes.
|
||||
|
||||
## Features
|
||||
|
||||
- `LicensePayloadSchema` — every 9 payload fields bounded by the
|
||||
per-field maximums in `LICENSE_SCHEMA`.
|
||||
- `LicenseGenerationOptionsSchema` — wraps `SignKey` (with a `Uint8Array`
|
||||
secret), the optional `signingKeyIdOverride`, `useFullSignature`,
|
||||
`signal`, and `rng`.
|
||||
- `LicenseValidationOptionsSchema` — accepts `publicKeys` as either a
|
||||
`Map` or a `Record`, mirroring the upstream API.
|
||||
- `QuickLicenseOptionsSchema` — covers the quick-builder fields with the
|
||||
same per-field bounds.
|
||||
- Every schema is `safeParse`-friendly; the runtime callers turn parse
|
||||
failures into typed `LicenseError`s.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { LicensePayloadSchema } from "@suaveplan/license/schemas/schemas";
|
||||
|
||||
const parsed = LicensePayloadSchema.parse(input); // throws ZodError on failure
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Turn a parse failure into a typed `LicenseError`:
|
||||
|
||||
```ts
|
||||
import { LICENSE_CODES, LicenseError } from "@suaveplan/license";
|
||||
import { LicensePayloadSchema } from "@suaveplan/license/schemas/schemas";
|
||||
|
||||
function parsePayload(input: unknown) {
|
||||
const r = LicensePayloadSchema.safeParse(input);
|
||||
if (!r.success) {
|
||||
throw new LicenseError(
|
||||
LICENSE_CODES.INVALID_INPUT,
|
||||
"Invalid license payload",
|
||||
{ cause: r.error, context: { issues: r.error.issues.length } }
|
||||
);
|
||||
}
|
||||
return r.data;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `LicensePayloadSchema`
|
||||
|
||||
`z.object({ version, signingKeyId, productId, packageTier, flags,
|
||||
timeEncodingType, timeValue, featureMask, nonce })` with every field
|
||||
bounded by `LICENSE_SCHEMA`.
|
||||
|
||||
### `LicenseGenerationOptionsSchema`
|
||||
|
||||
`z.object({ signingKey, signingKeyIdOverride?, useFullSignature?, signal?,
|
||||
rng? })`. `signingKey` is `{ s: Uint8Array, p?: Uint8Array }`.
|
||||
|
||||
### `LicenseValidationOptionsSchema`
|
||||
|
||||
`z.object({ publicKeys, referenceDate?, creationDate?, signal? })`.
|
||||
`publicKeys` is a `Map` or `Record<number, { p: Uint8Array }>`.
|
||||
|
||||
### `QuickLicenseOptionsSchema`
|
||||
|
||||
`z.object({ productId?, tier?, expirationDays?, flags?, features?,
|
||||
useAbsoluteTime? })` with per-field bounds.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`rng` is intentionally typed as `z.unknown().optional()` because the
|
||||
`Rng` interface from `@suaveplan/types` is structural (a duck-typed bag
|
||||
of methods); attempting to validate it with a structural Zod schema
|
||||
would force consumers to surface every optional method even when their
|
||||
RNG implementation chooses not to. The runtime modules treat `rng` as
|
||||
opaque and call only the documented `nextUint32` method, so the loose
|
||||
schema is safe.
|
||||
Reference in New Issue
Block a user