Files
skills/docs/security-stack/security/license/src/schemas/schemas.md
2026-05-29 08:20:56 +01:00

3.1 KiB

@suaveplan/license — schemas

(no submodules)

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 LicenseErrors.

Usage: Basic

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:

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.