3.8 KiB
Schemas — schemas.ts
(no submodules)
Purpose
Owns the Zod schemas that gate every public boundary of
@suaveplan/electrobun. Each interface in src/types/electrobun.types.ts
has a matching schema here, and the parseOrThrow helper folds the
parse + throw pattern into one call so every entry point reads the same
way: validate, then operate on the inferred type. The schemas are the
runtime contract — when a downstream library passes a stale
ProjectOptions shape, the schema fails at the boundary rather than
silently producing a broken project.
The schemas use Zod 4's enum / object / readonly-array helpers to keep
the TypeScript inference cheap, and parseOrThrow always raises
ElectrobunError(ELECTROBUN.INVALID_OPTIONS) so consumers can branch on
error.code === "ELECTROBUN.INVALID_OPTIONS" regardless of which entry
point validated.
Features
- Enum schemas (
FeatureModuleSchema,NetworkingComplexitySchema,R3fModuleSchema,BuildTargetSchema). - Composite schemas (
ProjectOptionsSchema,ElectrobunConfigSchema,GenerateIconsOptionsSchema,DevCommandOptionsSchema,BuildCommandOptionsSchema,PackageCommandOptionsSchema,SignCommandOptionsSchema). parseOrThrow(schema, value, context)— single helper that converts a Zod failure into anElectrobunErrorcarryingdetails.issues.
Usage: Basic
import { ProjectOptionsSchema } from "@suaveplan/electrobun/schemas";
const parsed = ProjectOptionsSchema.safeParse(input);
if (!parsed.success) {
console.error(parsed.error.issues);
}
Usage: Advanced
import {
ProjectOptionsSchema,
parseOrThrow,
} from "@suaveplan/electrobun/schemas";
import { ElectrobunError } from "@suaveplan/electrobun/error-codes";
try {
const validated = parseOrThrow(
ProjectOptionsSchema,
input,
"ProjectOptions"
);
await generate(validated);
} catch (err) {
if (err instanceof ElectrobunError) {
process.stderr.write(`${err.code}: ${err.message}\n`);
for (const issue of err.details["issues"] as Array<{
path: ReadonlyArray<string>;
message: string;
}>) {
process.stderr.write(` - ${issue.path.join(".")}: ${issue.message}\n`);
}
}
}
API Reference
FeatureModuleSchema,NetworkingComplexitySchema,R3fModuleSchema,BuildTargetSchema— closed Zod enums.ProjectOptionsSchema— fullProjectOptionsshape; rejects emptyname,identifier,version,outputDir.ElectrobunConfigSchema— partial config; every field optional.GenerateIconsOptionsSchema—{ inputPath, outputDir }.DevCommandOptionsSchema,BuildCommandOptionsSchema,PackageCommandOptionsSchema,SignCommandOptionsSchema— per-command option shapes.parseOrThrow<T>(schema, value, context)— returns the parsed value or throwsElectrobunError(ELECTROBUN.INVALID_OPTIONS, "${context}: invalid options", { details: { context, issues } }).
Implementation Notes
z.array(...).readonly() produces a readonly-typed inference that
matches the readonly-array fields on ProjectOptions, so the consumer
gets a parsed object whose mutability matches the interface. This is
important because the generator iterates the feature list and would
otherwise need an explicit Array.from(...) to avoid a structural
mismatch.
parseOrThrow uses safeParse rather than parse so the Zod issue list
lands on details.issues. The thrown error carries the original cause
slot empty — the Zod issues are the cause, surfaced as structured data
rather than a child Error. Consumers who want to log a single line
should format err.message; consumers who want to drive remediation
should walk details.issues.