Files
skills/docs/ui/react/react-ui/src/locales/schema.md
2026-05-29 08:20:56 +01:00

2.8 KiB

LocaleBundleSchema — Zod schema for @suaveplan/react-ui locale bundles

Purpose

Zod schema asserting that every locale bundle declares exactly the keys present in the canonical en-GB.json source-of-truth. The schema is built dynamically from en-GB.json itself so adding a key in English automatically tightens the contract for every other locale shipped by the package — there is no place for a translator to add a key that the English bundle has not blessed first.

Features

  • Strict mode (.strict()) rejects extra keys so a stray entry in cy-GB.json cannot silently leak into a consumer's t() call surface
  • Every key is required and typed as z.string()
  • REACT_UI_BUNDLE_KEYS exposes the exhaustive key list as a const array so other parts of the chassis (the <ReactUiProvider> mount hook, the registry-completeness CI gate, the augmentation generator) can iterate the contracted keys without re-importing the JSON file

Usage: Basic example

import { LocaleBundleSchema } from "@suaveplan/react-ui/locales";
import frFR from "./fr-FR.json";

const parsed = LocaleBundleSchema.safeParse(frFR);
if (!parsed.success) {
    throw new Error(`fr-FR is missing keys: ${parsed.error.message}`);
}

Usage: Advanced example

import {
    LocaleBundleSchema,
    REACT_UI_BUNDLE_KEYS,
    reactUiBundles,
    SUPPORTED_LOCALES,
} from "@suaveplan/react-ui/locales";

// Fail-fast key parity check at app startup
async function assertKeyParity(): Promise<void> {
    for (const locale of SUPPORTED_LOCALES) {
        const bundle = await reactUiBundles[locale]();
        const result = LocaleBundleSchema.safeParse(bundle);
        if (!result.success) {
            throw new Error(`Locale ${locale} failed schema: ${result.error.message}`);
        }
        for (const key of REACT_UI_BUNDLE_KEYS) {
            if (!(key in bundle)) {
                throw new Error(`Locale ${locale} missing key ${key}`);
            }
        }
    }
}

API Reference

  • LocaleBundleSchema: z.ZodObject<...> — Zod schema with one z.string() field per key in en-GB.json. Strict.
  • type LocaleBundle = z.infer<typeof LocaleBundleSchema> — typed bundle shape. Equivalent to a Record over the contracted key set.
  • REACT_UI_BUNDLE_KEYS: readonly string[] — exhaustive key list.

Implementation notes

The schema is built at module-load time by walking Object.keys(enGB) rather than at type-only level. That means adding a key to en-GB.json does not require regenerating any TypeScript file to extend the schema — the runtime build picks up the new key on the next module evaluation. The accompanying augmentation.ts file IS generated and DOES need to be regenerated when keys change; the scripts/check-locale-completeness.ts CI gate fails the build if a key appears in en-GB.json but is absent from any other locale bundle.