Files
dynamic-sites-simple/shared/src/repo-validation.ts
2026-04-17 16:08:31 -05:00

43 lines
1.6 KiB
TypeScript

import { z } from 'zod';
import {
siteContextSchema,
sectionFileSchema,
eventsFileSchema,
smsSitesConfigSchema,
} from './schemas/index.js';
const EDITABLE_PATTERNS: Array<{ pattern: RegExp; schema: z.ZodTypeAny }> = [
{ pattern: /^content\/sections\/[^/]+\.json$/, schema: sectionFileSchema },
{ pattern: /^content\/events\.json$/, schema: eventsFileSchema },
{ pattern: /^site-context\.json$/, schema: siteContextSchema },
{ pattern: /^config\/sms-sites\.json$/, schema: smsSitesConfigSchema },
];
export function schemaForRepoRelativePath(relativePath: string): z.ZodTypeAny | null {
for (const { pattern, schema } of EDITABLE_PATTERNS) {
if (pattern.test(relativePath)) return schema;
}
return null;
}
export function isEditableContentRepoPath(relativePath: string): boolean {
return EDITABLE_PATTERNS.some(({ pattern }) => pattern.test(relativePath));
}
export function parseAndValidateRepoJson(
repoRelativePath: string,
rawText: string
): { success: true; data: unknown } | { success: false; error: string } {
const schema = schemaForRepoRelativePath(repoRelativePath);
if (!schema) return { success: false, error: `No schema found for path: ${repoRelativePath}` };
try {
const parsed = JSON.parse(rawText);
const result = schema.safeParse(parsed);
if (result.success) return { success: true, data: result.data };
return { success: false, error: result.error.issues.map(i => `${i.path.join('.')}: ${i.message}`).join('; ') };
} catch (e) {
return { success: false, error: `Invalid JSON: ${(e as Error).message}` };
}
}