From eaeae328496e4149074193e336736ef8d4bea9b4 Mon Sep 17 00:00:00 2001 From: Kawa Date: Thu, 26 Mar 2026 10:21:11 +0100 Subject: [PATCH] feat(01-03): implement BACKEND_SCHEMAS Zod schema builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - buildZodSchema derives z.object() from BACKEND_REGISTRY field definitions - required fields map to z.string().min(1, label) — optional to z.string().optional() - BACKEND_SCHEMAS exported with entries for azureblob, s3, s3-compatible - BackendFormValues utility type infers TypeScript type from schema - No hardcoded field names — all shapes derived from registry loop - All 8 tests in index.test.ts pass (GREEN) --- src/schemas/index.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/schemas/index.ts diff --git a/src/schemas/index.ts b/src/schemas/index.ts new file mode 100644 index 0000000..ac35398 --- /dev/null +++ b/src/schemas/index.ts @@ -0,0 +1,28 @@ +// src/schemas/index.ts +// Zod schemas derived programmatically from the Backend Schema Registry. +// DO NOT hand-write z.object() calls with hardcoded field names — all shapes come from the registry. +// Adding a field to BACKEND_REGISTRY automatically adds it to validation. + +import { z } from 'zod'; +import { BACKEND_REGISTRY, BackendType } from './registry'; + +function buildZodSchema(backendType: BackendType): z.ZodObject> { + const fields = BACKEND_REGISTRY[backendType]; + const shape: Record = {}; + for (const field of fields) { + shape[field.key] = field.required + ? z.string().min(1, `${field.label} is required`) + : z.string().optional(); + } + return z.object(shape); +} + +export const BACKEND_SCHEMAS = { + azureblob: buildZodSchema('azureblob'), + s3: buildZodSchema('s3'), + 's3-compatible': buildZodSchema('s3-compatible'), +} as const; + +// Utility type: infer TypeScript type from a backend's Zod schema +export type BackendFormValues = + z.infer;