3.8 KiB
schemas/vault-item
Purpose
Zod schemas describing the wire shape of every body, parameter, and
response handled by the 5 vault routes. Every schema is the single
source of truth: RouteBuilder registers them on the OpenAPI document,
Hono's c.req.valid("json") inference flows from them, and downstream
test fixtures derive sample data from them via z.infer.
The schemas exist at the boundary, not inside the encrypted container —
they describe what clients send and receive, not what is persisted on
disk. Persistence schemas live with @suaveplan/vault itself.
Features
- 8 schemas:
VaultItemMetadataSchema,VaultItemSummarySchema,VaultItemSchema,VaultItemResponseSchema,VaultItemListResponseSchema,CreateVaultItemBodySchema,UpdateVaultItemBodySchema(strict mode),DeleteVaultItemResponseSchema, plusVaultItemParamsSchemafor the URL{id}segment. UpdateVaultItemBodySchemauses.strict()so unknown fields cause a Zod parse error — protects against typos and prevents schema-drift by silently accepting client-side keys the server does not understand.bodyisz.string()so clients can carry arbitrary JSON, base64, or text; size enforcement happens at the route layer againstoptions.maxItemSizeBytes.- Paginated response carries
meta: { total }— sufficient for v1; a cursor field will land in a follow-up change once the underlying vault library exposes one.
Usage: Basic
import { CreateVaultItemBodySchema } from "@suaveplan/api-plugin-vault";
const parsed = CreateVaultItemBodySchema.parse({
title: "API key",
kind: "credential",
body: JSON.stringify({ user: "alice", key: "k..." }),
});
Usage: Advanced
import {
type CreateVaultItemBody,
type UpdateVaultItemBody,
UpdateVaultItemBodySchema,
} from "@suaveplan/api-plugin-vault";
const result = UpdateVaultItemBodySchema.safeParse({
title: "X",
evil: "Y",
});
// result.success === false; result.error lists "Unrecognized key(s): evil"
API Reference
VaultItemSummarySchema
Object with id, ownerId, title (1..512), kind (1..128),
metadata (optional record), createdAt, updatedAt.
VaultItemSchema
Extends VaultItemSummarySchema with body: string.
VaultItemResponseSchema, VaultItemListResponseSchema,
DeleteVaultItemResponseSchema
Envelope responses returned by the 5 routes. The success envelope is
the standard { success: true, data } shape used across suaveplan;
errors use the shared ErrorResponseSchema from
@suaveplan/api-openapi.
CreateVaultItemBodySchema
POST body: title, kind, body, optional metadata. All four
fields validated as non-empty/length-bounded where applicable.
UpdateVaultItemBodySchema
PATCH body (strict). Every field optional; metadata may be set to
omit. Unknown fields rejected.
VaultItemParamsSchema
URL params: { id: string }.
Type aliases
VaultItemSummaryType, VaultItemType, VaultItemResponseType,
VaultItemListResponseType, CreateVaultItemBody,
UpdateVaultItemBody, DeleteVaultItemResponseType, VaultItemParams.
Implementation Notes
metadatausesz.record(z.string(), z.unknown())rather than an explicit nested shape because callers attach app-specific fields (tags, labels, custom expiry hints) that vary across consumers. The strictUpdateVaultItemBodySchemamode does NOT recurse intometadata— strict only blocks unknown top-level keys.createdAt/updatedAtare ISO-8601 strings, not numbers. SurrealDB serialisesdatetimeas ISO strings; the wire matches the persistence layer.bodyis intentionally string-typed, not byte-typed. Clients base64-encode binary payloads before sending. This keeps the wire JSON-safe and consistent across HTTP/2, HTTP/3, and SSE transports without forcing a multipart envelope.