Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
94 lines
3.1 KiB
TypeScript
94 lines
3.1 KiB
TypeScript
/**
|
|
* Zod schemas for ModifierProfile serialization and validation.
|
|
*
|
|
* The `value` field on TypeModifier and InstanceModifier uses `z.any()`
|
|
* rather than `z.unknown()` — Zod v4 infers `z.unknown()` object fields as
|
|
* optional (`value?: unknown`) which conflicts with the required `value:
|
|
* unknown` in the TypeModifier/InstanceModifier interfaces. `z.any()` infers
|
|
* as a required `any` field while still accepting all values.
|
|
*
|
|
* Per-kind value validation happens at descriptor registration time, not at
|
|
* profile-parse time. This keeps the schema forwards-compatible.
|
|
*/
|
|
import { z } from "zod";
|
|
import type { ModifierProfile } from "./types.js";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Primitives
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const ModifierKindIdSchema = z.enum([
|
|
"hp-bonus",
|
|
"range-bonus",
|
|
"direction-additions",
|
|
"capture-flags",
|
|
"promotion-override",
|
|
"damage-resistance",
|
|
]);
|
|
|
|
const PieceTypeSchema = z.enum([
|
|
"pawn",
|
|
"knight",
|
|
"bishop",
|
|
"rook",
|
|
"queen",
|
|
"king",
|
|
]);
|
|
|
|
// PieceColor extended with "both" for TypeModifier.color
|
|
const PieceColorExtSchema = z.enum(["white", "black", "both"]);
|
|
|
|
/** Algebraic notation square: "a1".."h8" */
|
|
const SquareStringSchema = z
|
|
.string()
|
|
.regex(/^[a-h][1-8]$/, "Must be algebraic notation (a1-h8)");
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// TypeModifier
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const TypeModifierSchema = z.object({
|
|
kind: ModifierKindIdSchema,
|
|
pieceType: PieceTypeSchema,
|
|
color: PieceColorExtSchema,
|
|
value: z.any() as z.ZodType<unknown>,
|
|
});
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// InstanceModifier
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const InstanceModifierSchema = z.object({
|
|
kind: ModifierKindIdSchema,
|
|
square: SquareStringSchema,
|
|
value: z.any() as z.ZodType<unknown>,
|
|
});
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ModifierProfile
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const ModifierProfileSchema = z.object({
|
|
id: z.string().min(1),
|
|
name: z.string().min(1),
|
|
description: z.string(),
|
|
layoutId: z.string().optional(),
|
|
perType: z.array(TypeModifierSchema),
|
|
perInstance: z.array(InstanceModifierSchema),
|
|
version: z.literal(1),
|
|
source: z.enum(["premade", "custom"]),
|
|
});
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Public API
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/** Parse an unknown value as a ModifierProfile. Throws ZodError on failure. */
|
|
export function parseModifierProfile(raw: unknown): ModifierProfile {
|
|
return ModifierProfileSchema.parse(raw) as ModifierProfile;
|
|
}
|
|
|
|
/** Serialize a ModifierProfile to a JSON-safe plain object. */
|
|
export function serializeModifierProfile(profile: ModifierProfile): unknown {
|
|
return ModifierProfileSchema.parse(profile);
|
|
}
|