import * as yaml from "js-yaml"; import * as fs from "fs"; import * as path from "path"; import { z } from "zod"; export interface StoryConfig { metadata: { title: string; author: string; publication_year: number; public_domain_proof_url: string; reading_level: string; }; config: { chunk_size: number; tts_voice_id: string; tts_instructions?: string; image_style_prompts?: string; intro_audio_file: string; outro_audio_file: string; background_music_file: string; export_settings: { format?: string; resolution: string; }; }; } const StoryConfigSchema = z.object({ metadata: z.object({ title: z.string().min(1), author: z.string().min(1), publication_year: z.number().int(), public_domain_proof_url: z.string().min(1), reading_level: z.string().min(1), }), config: z.object({ chunk_size: z.number().int().positive(), tts_voice_id: z.string().min(1), tts_instructions: z.string().optional().default(""), image_style_prompts: z.string().optional().default(""), intro_audio_file: z.string().min(1), outro_audio_file: z.string().min(1), background_music_file: z.string().min(1), export_settings: z .object({ format: z.string().optional().default("mp4"), resolution: z .string() .regex(/^\d+x\d+$/) .default("1024x1024"), }) .default({ format: "mp4", resolution: "1024x1024" }), }), }); export function loadStoryConfig(storyName: string): StoryConfig { const configPath = path.join("stories", storyName, "config.yaml"); if (!fs.existsSync(configPath)) { throw new Error(`Configuration file not found for story: ${storyName}`); } const fileContents = fs.readFileSync(configPath, "utf8"); const loaded = yaml.load(fileContents); const parsed = StoryConfigSchema.parse(loaded); return parsed as unknown as StoryConfig; }