▍ humdrum codex / soft
1.7 KB raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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<typeof SourceKind>;

// 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<typeof SourceSize>;

// 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<typeof SourceConfig>;

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<typeof Source>;

export const UpdateSource = Source.partial().omit({ id: true, kind: true });
export type UpdateSource = z.infer<typeof UpdateSource>;