Files
skills/docs/api-stack/api/api-manifest/src/schema/config.md
2026-05-29 08:20:56 +01:00

2.5 KiB

configSchema

Purpose

Plugin-level config block. schemaPath points at a JSON Schema the host validates user-supplied config against at install; defaults is a free-form record the host deep-merges on top of user-supplied config before validation runs.

Features

  • Optional schemaPath to a JSON Schema document
  • Optional defaults as Record<string, unknown>
  • Empty config block is valid (the plugin may need no config)
  • Layered on top of the host's @suaveplan/config for final resolution

Basic Example

import { configSchema } from "@suaveplan/api-manifest/schema";
configSchema.parse({ defaults: { trialDays: 14 } });

Advanced Example

import { configSchema } from "@suaveplan/api-manifest/schema";
const cfg = configSchema.parse({
  schemaPath: "config.schema.json",
  defaults: { trialDays: 14, currency: "USD" },
});

API Reference

  • configSchema: z.ZodObject<{ schemaPath?, defaults? }>
  • ConfigBlock = z.infer<typeof configSchema>

Implementation Notes

The schema deliberately doesn't validate the contents of defaults because they're plugin-specific by definition; the JSON Schema at schemaPath is the canonical validator for the user-supplied config. Defaults are merged in by the host using a deep-merge strategy that favours user-supplied values; arrays are replaced rather than concatenated to keep the merge total.

Cross-package Notes

This module is part of the @suaveplan/api-manifest Stage-1 contract package. It sits beneath every Stage-2 consumer (api-host, api-loader, the admin CLI, the IDE plugin) and above the foundation packages (@suaveplan/error, @suaveplan/types). The strict-mode top-level rejection of unknown keys means upgrading from manifest v1 to v2 is an OpenSpec-driven event: a new key landing in a consumer manifest is a parse failure rather than a silent drift, which is exactly the contract this stage exists to guarantee.

When the host reloads a plugin without a full restart, every manifest field this module validates is compared against the install-time manifestHash. A mismatch triggers a hard rollback via the RollbackJournal because the host's invariants (route mounts, registered capabilities, declared scopes) are derived from these exact bytes. Treat the schemas and validators here as the contract surface, not just an input filter — downstream code reads manifest.foo.bar and relies on those keys being present, well-typed, and non-undefined in the documented optionality regions.