import { locales } from "@openstatus/locales"; import type { ThemeKey } from "@openstatus/theme-store"; import { hasCustomTheme, sanitizeCustomTheme, THEME_KEYS, validateCustomTheme, } from "@openstatus/theme-store"; import { createInsertSchema, createSelectSchema } from "drizzle-zod"; import { z } from "zod"; import { pageAccessTypes } from "./constants"; import { page } from "./page"; // Exported so `@openstatus/services` can reuse the canonical rules in // its own `NewPageInput` / `UpdatePage*Input` schemas without // duplicating the regex. Keep these as the single source of truth for // slug and custom-domain shape validation. export const slugSchema = z .string() .regex( /^[A-Za-z0-9-]+$/, "Only use digits (0-9), hyphen (-) or characters (A-Z, a-z).", ) .min(3) .toLowerCase(); export const customDomainSchema = z .string() .regex( /^(?!https?:\/\/|www.)([a-zA-Z0-9]+(.[a-zA-Z0-9]+)+.*)$/, "Should not start with http://, https:// or www.", ) .or(z.enum([""])); const stringToArray = z.preprocess((val) => { if (val && String(val).length > 0) { return String(val).split(","); } return []; }, z.array(z.string())); // Loose { light, dark } var maps — write paths enforce the supported var // names / safe values; `.catch(null)` degrades corrupt stored json to "no // overrides" instead of tanking every page read. const themeVarsSchema = z.record(z.string(), z.string()); export const customThemeSchema = z.object({ light: themeVarsSchema.optional(), dark: themeVarsSchema.optional(), }); // Strict write-side counterpart: only supported var names and values that // can't break out of the inline