first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
# Schemas — `schemas.ts`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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 an `ElectrobunError` carrying `details.issues`.
## Usage: Basic
```ts
import { ProjectOptionsSchema } from "@suaveplan/electrobun/schemas";
const parsed = ProjectOptionsSchema.safeParse(input);
if (!parsed.success) {
console.error(parsed.error.issues);
}
```
## Usage: Advanced
```ts
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` — full `ProjectOptions` shape; rejects empty
`name`, `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
throws `ElectrobunError(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`.