import { z } from "zod"; // Every kind of data source the dashboard knows how to show. // "todos" is local data (no fetcher) — the others pull from the network/disk. export const SOURCE_KINDS = [ "weather", "news", "briefs", "feeds", "onthisday", "sports", "calendar", "mastodon", "bluesky", "github", "vercel", "aqi", "markets", "hackernews", "uptime", "obsidian", "todos", "links", "cider", ] as const; export const SourceKind = z.enum(SOURCE_KINDS); export type SourceKind = z.infer; // Bento tile sizes → grid spans (see lib/layout.ts). export const SOURCE_SIZES = ["sm", "md", "wide", "tall", "lg"] as const; export const SourceSize = z.enum(SOURCE_SIZES); export type SourceSize = z.infer; // Per-source config is free-form JSON validated by each source module's own // configSchema. At the table level it's an opaque object. export const SourceConfig = z.record(z.string(), z.unknown()); export type SourceConfig = z.infer; export const Source = z.object({ id: z.string(), kind: SourceKind, label: z.string().min(1).max(80), enabled: z.boolean().default(true), config: SourceConfig.default({}), refreshSeconds: z.number().int().min(30).max(86_400).default(900), position: z.number().int().default(0), size: SourceSize.default("md"), // vestigial; layout now uses cols/rows cols: z.number().int().min(1).max(6).default(1), // grid column span rows: z.number().int().min(1).max(8).default(2), // grid row span }); export type Source = z.infer; export const UpdateSource = Source.partial().omit({ id: true, kind: true }); export type UpdateSource = z.infer;