3.6 KiB
plugin/plugin
(no submodules)
Purpose
createVaultPlugin(options) is the factory that returns a typed
PluginDescriptor<VaultPluginConfig> ready to register with the host's
PluginRegistry. Third instance of the 3-way plug-and-play contract:
the plugin owns its .surql DDL, its Zod schemas, and its OpenAPI
routes, and applies all three during onInit. Depends on
api-plugin-auth so every route's principal scoping has a typed
upstream supplier.
Features
- Zod-validated options via
VaultPluginOptionsSchema— invalid input raisesVaultPluginError(VAULT_PLUGIN_INVALID_INPUT)carrying theZodError. - Declares
dependencies: ["auth"]so the registry refuses to load the plugin withoutapi-plugin-authregistered upstream. - 6-step
onInitlifecycle: resolve services → apply schema → constructvaultService→ registervaultService→ register routes → (no global middleware —requireAuth()is per-route). routePrefix-aware route mounting — paths are rebuilt at the prefix the operator chose, both in the served Hono app and in theOpenAPIRegistrysnapshot. Default/vault.- Collision detection — pre-existing routes under the configured
prefix raise
VAULT_PLUGIN_ROUTE_PREFIX_COLLISION. - Graceful degradation — when
openAPIRegistryis absent, routes mount on the Hono app directly (no doc); when neithermigrationRunnernordbis available withapplySchemaOnInit: true, init fails fast withVAULT_PLUGIN_SERVICE_NOT_AVAILABLE.
Usage: Basic
import { defineApp } from "@suaveplan/api";
import { createAuthPlugin } from "@suaveplan/api-plugin-auth";
import { createVaultPlugin } from "@suaveplan/api-plugin-vault";
const app = await defineApp()
.name("my-api")
.use(createAuthPlugin({ betterAuth: { /* ... */ } }))
.use(createVaultPlugin({ storage: driveAdapter }))
.start();
Usage: Advanced
const plugin = createVaultPlugin({
storage: driveAdapter,
routePrefix: "/v1/vault",
maxItemSizeBytes: 4 * 1024 * 1024,
serverPepper: process.env["VAULT_SERVER_PEPPER"]!,
unlockExtractor: (c) =>
c.req.header("X-Custom-Vault-Unlock") ?? null,
applySchemaOnInit: false, // operator runs migrations externally
});
API Reference
createVaultPlugin(options: VaultPluginOptions): PluginDescriptor<VaultPluginConfig>
Returns a definePlugin descriptor. name: "vault", version: "0.1.0",
dependencies: ["auth"].
The defaults field carries every resolved option after Zod
validation — the registry passes that to onInit via ctx.getOwnConfig().
onInit(ctx) resolves services, applies the schema, constructs the
service, registers it, and registers the 5 routes.
Implementation Notes
- The plugin DOES NOT install global middleware.
requireAuth()fromapi-plugin-authis applied per-route insidebuildVaultRoutesso the public/openapi.jsondoc only carries vault routes for the authenticated scope and operators can leave the vault prefix out of public-facing API documentation tooling. - The
rewritePathhelper preserves{id}segments verbatim — when the operator chooses/v1/vault, the route path/vault/items/{id}becomes/v1/vault/items/{id}. - The collision check inspects every previously registered route whose path starts with the configured prefix — operators wiring multiple vault plugin instances under different prefixes are unaffected.
- The plugin does not provide an
onClosehook because thevaultServiceis stateless across requests — every handle is opened + closed within a single request lifecycle.