Files
2026-05-27 23:29:53 +01:00

3.2 KiB

schemas/options

Purpose

Zod schema validating the input options to createVaultPlugin. Every field has a Zod-derived default (or optional()) so callers can pass just the required storage adapter and get sensible behaviour; operators tightening security policy override defaults at the call site. The schema runs at the factory boundary and safeParse failures raise VaultPluginError(VAULT_PLUGIN_INVALID_INPUT) with the underlying ZodError attached as cause for diagnostic surfaces (logs, span events).

Features

  • Structural z.custom check for the storage adapter — Zod cannot introspect the DriveLike interface, but a four-method duck-type check covers every DriveLike implementation shipping today.
  • Tight routePrefix regex matching the shared prefix-validation rule used by @suaveplan/api-plugin-auth.
  • maxItemSizeBytes capped at 256 MiB — bodies larger than that route through the attachments surface (not in v1).
  • serverPepper is a free-form opaque string; the default value is a package-level constant, but production deployments SHOULD supply a per-deployment secret loaded from @suaveplan/env.

Usage: Basic

import { VaultPluginOptionsSchema } from "@suaveplan/api-plugin-vault";

const parsed = VaultPluginOptionsSchema.parse({
    storage: myDriveAdapter,
});
console.log(parsed.routePrefix); // "/vault"
console.log(parsed.maxItemSizeBytes); // 10485760

Usage: Advanced

import {
    type VaultPluginOptionsInput,
    VaultPluginOptionsSchema,
} from "@suaveplan/api-plugin-vault";

const input: VaultPluginOptionsInput = {
    storage: myDriveAdapter,
    routePrefix: "/v1/vault",
    maxItemSizeBytes: 1024 * 1024,
    serverPepper: process.env["VAULT_SERVER_PEPPER"] ?? "",
    unlockExtractor: (c) => c.req.header("Authorization")?.slice(7) ?? null,
};

const resolved = VaultPluginOptionsSchema.safeParse(input);
if (!resolved.success) {
    throw new Error("Invalid vault options: " + resolved.error.message);
}

API Reference

VaultPluginOptionsSchema

Top-level Zod object. Fields:

  • storage (required, z.custom<DriveLike>).
  • routePrefix (default "/vault", regex-validated).
  • maxItemSizeBytes (default 10 * 1024 * 1024, range [1, 256 MiB]).
  • applySchemaOnInit (default true).
  • unlockExtractor (optional, function).
  • serverPepper (default "suaveplan-vault-plugin-pepper-v1", non-empty).
  • logger (optional, structural LoggerLike check).

VaultPluginOptionsInput

z.input of the schema — what callers MAY pass.

VaultPluginOptionsResolved

z.output of the schema — every default applied.

Implementation Notes

  • The schema does not enforce mutual exclusion between routePrefix ending in / and routes carrying leading / paths — the route builder normalises this at registration time.
  • serverPepper is not constrained beyond non-empty; if operators re-deploy with a different pepper, existing vaults become unreadable by design. Document this in the deployment runbook.
  • storage is intentionally checked structurally rather than via instanceof so any package implementing DriveLike (@suaveplan/drive, bespoke S3 adapters, in-memory test doubles) passes.