@realiizlabs/admin 0.13.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,7 +31,7 @@ declare function AccountMenu({ user, role, theme, onTheme, signOutPath, accountH
31
31
  signOutPath: string;
32
32
  /** The Account page (My Profile · Change Password · Team · Business). Omit to hide the item. */
33
33
  accountHref?: string;
34
- /** The Help centre. Omit to hide the item. */
34
+ /** The Help center. Omit to hide the item. */
35
35
  helpHref?: string;
36
36
  }): react.JSX.Element;
37
37
 
@@ -31,7 +31,7 @@ declare function AccountMenu({ user, role, theme, onTheme, signOutPath, accountH
31
31
  signOutPath: string;
32
32
  /** The Account page (My Profile · Change Password · Team · Business). Omit to hide the item. */
33
33
  accountHref?: string;
34
- /** The Help centre. Omit to hide the item. */
34
+ /** The Help center. Omit to hide the item. */
35
35
  helpHref?: string;
36
36
  }): react.JSX.Element;
37
37
 
@@ -78,7 +78,7 @@ function coreShape(kinds) {
78
78
  heroImage: zod.z.string().min(1, "heroImage must be a path when present").optional().meta({ label: "Picture", help: "Optional. Choose a picture and we size it for the web." }),
79
79
  heroImageAlt: zod.z.string().min(1, MESSAGES.heroImageAlt).optional().meta({ label: "Picture description", placeholder: "What the picture shows", help: "A sentence describing the picture, for screen readers and Google Images." }),
80
80
  ogImage: zod.z.string().min(1, "ogImage must be a path when present").optional().meta({ label: "Social share image", help: "Shown when someone shares the link. Leave blank to reuse the picture." }),
81
- cancelled: zod.z.boolean().optional().meta({ label: "Cancelled", help: "Keeps the event on the page, marked cancelled." }),
81
+ cancelled: zod.z.boolean().optional().meta({ label: "Canceled", help: "Keeps the event on the page, marked canceled." }),
82
82
  cancelledNote: zod.z.string().max(300, "keep the note under 300 characters").optional().meta({ label: "Cancellation note", placeholder: "e.g. Postponed \u2014 new date coming soon", help: "A short line shown with the cancelled event." }),
83
83
  rescheduledTo: zod.z.string().regex(SLUG_RE, "rescheduledTo must be the web address (slug) of the replacement event").optional().meta({ label: "Moved to", placeholder: "the slug of the new event", help: "If this moved to a new date, the web address of the replacement." }),
84
84
  previousDate: zod.z.string().regex(DATE_RE, "previousDate must be YYYY-MM-DD").optional().meta({ label: "Previous date", help: "If this event moved, the date it was originally on." })
@@ -198,7 +198,7 @@ function eventRegistryDefaults(options = {}) {
198
198
  if (on.has("appearances")) groups.push({ label: "Appearance details", fields: ["host", "recordingUrl", "slidesUrl"] });
199
199
  groups.push({ label: "Pictures", fields: ["heroImage", "heroImageAlt", "ogImage"] });
200
200
  groups.push({ label: "Changes", fields: ["cancelled", "cancelledNote", "rescheduledTo", "previousDate"] });
201
- return { order, groups, images: ["heroImage", "ogImage"], inputs: {} };
201
+ return { order, groups, images: ["heroImage", "ogImage"], inputs: {}, icon: "events" };
202
202
  }
203
203
 
204
204
  exports.DEFAULT_KINDS = DEFAULT_KINDS;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/events/groups.ts","../../src/events/zones.ts","../../src/events/schema.ts","../../src/events/when.ts","../../src/events/status.ts","../../src/events/registry.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The optional field groups a site can switch on. Each is a zod shape fragment\n * merged into the core by eventSchema; nothing here knows about the others.\n *\n * zod is imported directly: it is external in tsup and a peer dependency, so\n * this resolves to the host site's copy — the same instance its own schemas use.\n */\n\nimport { z } from \"zod\";\n\nexport const EVENT_GROUPS = [\"venues\", \"tickets\", \"appearances\"] as const;\nexport type EventGroup = (typeof EVENT_GROUPS)[number];\n\n/** A reference to a venues collection. The SITE resolves the options (registry `options.venue`). */\nexport const venuesShape = {\n venue: z.string().min(1, \"pick a venue\")\n .meta({ label: \"Venue\", help: \"Where this happens. Venues are kept in their own list so the address is typed once.\" }),\n};\n\nexport const ticketsShape = {\n rsvpUrl: z.string().url(\"the RSVP link must be a full web address, starting with https://\").optional()\n .meta({ label: \"RSVP or ticket link\", placeholder: \"https://…\", help: \"Where people go to sign up or buy a ticket. Leave blank if there is nothing to book.\" }),\n capacity: z.number().int(\"capacity must be a whole number\").positive(\"capacity must be more than zero\").optional()\n .meta({ label: \"Capacity\", help: \"How many people can come. Leave blank if there is no limit.\" }),\n closed: z.boolean().optional()\n .meta({ label: \"Sign-ups closed\", help: \"Tick this to stop taking sign-ups while still showing the event.\" }),\n private: z.boolean().optional()\n .meta({ label: \"Private event\", help: \"Invited guests only. The event still shows, but nobody can sign up from the website.\" }),\n};\n\nexport const appearancesShape = {\n host: z.string().min(1, \"host must not be empty when present\").optional()\n .meta({ label: \"Hosted or published by\", placeholder: \"e.g. The SoundPlex, or the name of the podcast\", help: \"The organisation, venue, podcast or publication behind this appearance.\" }),\n recordingUrl: z.string().url(\"the recording link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Recording link\", placeholder: \"https://…\", help: \"A video or audio recording to watch or listen to afterwards — YouTube, Spotify, the episode page.\" }),\n slidesUrl: z.string().url(\"the slides link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Slides link\", placeholder: \"https://…\", help: \"Where the slides live, if you want to share them.\" }),\n};\n\nexport const GROUP_SHAPES = {\n venues: venuesShape,\n tickets: ticketsShape,\n appearances: appearancesShape,\n} as const;\n","/**\n * Time zones a client can pick from — friendly names, because \"America/Phoenix\"\n * means nothing to someone booking a talk. zoneToIana turns them back into what\n * Intl needs. US-only for now; extending the list is the whole change.\n */\n\nexport const ZONES = [\"Eastern\", \"Central\", \"Mountain\", \"Arizona\", \"Pacific\", \"Alaska\", \"Hawaii\"] as const;\nexport type Zone = (typeof ZONES)[number];\n\nconst IANA: Record<Zone, string> = {\n Eastern: \"America/New_York\",\n Central: \"America/Chicago\",\n Mountain: \"America/Denver\",\n Arizona: \"America/Phoenix\",\n Pacific: \"America/Los_Angeles\",\n Alaska: \"America/Anchorage\",\n Hawaii: \"Pacific/Honolulu\",\n};\n\nexport function zoneToIana(zone: Zone): string {\n return IANA[zone];\n}\n\nexport function isZone(value: unknown): value is Zone {\n return typeof value === \"string\" && (ZONES as readonly string[]).includes(value);\n}\n","/**\n * eventSchema — one events model for every site, assembled from a core plus the\n * groups a site switches on. Labels and help live here as .meta() so the form\n * needs no registry overrides.\n *\n * Time is stored the way a person wrote it — a date, a wall-clock time, a zone —\n * never a UTC instant. That is what survives a hand edit on GitHub. when.ts turns\n * it into instants at render time.\n */\n\nimport { z } from \"zod\";\nimport { EVENT_GROUPS, GROUP_SHAPES, type EventGroup } from \"./groups\";\nimport { ZONES, type Zone } from \"./zones\";\n\nexport const DEFAULT_KINDS = [\"talk\", \"panel\", \"workshop\", \"webinar\", \"podcast\", \"interview\", \"article\"] as const;\nexport type DefaultKind = (typeof DEFAULT_KINDS)[number];\n\n/** Always accepted, whatever the site's list: unlocks the free-text kindLabel. */\nexport const OTHER_KIND = \"other\";\n\nexport const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nexport const TIME_RE = /^([01]\\d|2[0-3]):[0-5]\\d$/;\n\nexport const MESSAGES = {\n date: \"that date doesn’t exist — check the month has that many days\",\n time: \"use a 24-hour time like 19:00\",\n endTime: \"add a start time first\",\n heroImageAlt: \"describe the picture so screen readers and Google can read it\",\n kindLabel: \"say what kind of event this is\",\n} as const;\n\nexport interface EventSchemaOptions<G extends EventGroup = never, K extends string = DefaultKind> {\n /** Optional groups to switch on. */\n with?: readonly G[];\n /** The site's own list of kinds; \"other\" is always added. Defaults to DEFAULT_KINDS. */\n kinds?: readonly [K, ...K[]];\n}\n\nfunction realDate(value: string): boolean {\n const [y, m, d] = value.split(\"-\").map(Number);\n const dt = new Date(Date.UTC(y, m - 1, d));\n return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;\n}\n\nconst time = (label: string, help: string) =>\n z.string().regex(TIME_RE, MESSAGES.time).optional().meta({ label, help, input: \"time\" });\n\nfunction coreShape<K extends string>(kinds: readonly [K, ...K[]]) {\n const kindValues = [...kinds, OTHER_KIND] as [string, ...string[]];\n return {\n title: z.string().min(1, \"give the event a title\")\n .meta({ label: \"Title\", placeholder: \"What it's called\", help: \"The headline people see on the page and in the list.\" }),\n slug: z.string().min(1, \"slug is required\").regex(SLUG_RE, \"slug must be lowercase words joined by hyphens, e.g. ai-talk-soundplex\")\n .meta({ label: \"Web address (slug)\", placeholder: \"e.g. ai-talk-soundplex\", help: \"The last part of the link. Lowercase words joined by hyphens, no spaces.\" }),\n summary: z.string().min(1, \"write a one-line summary\").max(200, \"keep the summary under 200 characters\")\n .meta({ label: \"One-line summary\", input: \"textarea\", help: \"One or two sentences shown in the list. The longer description goes in the body below.\" }),\n kind: z.enum(kindValues).optional()\n .meta({ label: \"What kind of event\", help: \"Pick the closest. Choose “other” to type your own.\" }),\n kindLabel: z.string().min(1, MESSAGES.kindLabel).max(40, \"keep the custom kind under 40 characters\").optional()\n .meta({ label: \"Custom kind\", placeholder: \"e.g. Fireside chat\", help: \"Only used when the kind is “other”.\" }),\n date: z.string().regex(DATE_RE, \"date must be written as YYYY-MM-DD, e.g. 2026-09-28\").refine(realDate, { message: MESSAGES.date })\n .meta({ label: \"Date\", input: \"date\", help: \"The day it happens. For a podcast or article, the day it comes out.\" }),\n startTime: time(\"Start time\", \"Leave blank for an all-day item or something without a set time.\"),\n endTime: time(\"End time\", \"Optional. Needs a start time.\"),\n timezone: z.enum(ZONES).optional()\n .meta({ label: \"Time zone\", help: \"Leave blank for the site's usual zone.\" }),\n location: z.string().min(1, \"location must not be empty when present\").optional()\n .meta({ label: \"Where\", placeholder: \"e.g. The SoundPlex, Pennsauken, NJ — or Online\", help: \"A place name and town, or “Online”. Shown under the title.\" }),\n url: z.string().url(\"the link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Link for details\", placeholder: \"https://…\", help: \"The event's own page, if it has one.\" }),\n heroImage: z.string().min(1, \"heroImage must be a path when present\").optional()\n .meta({ label: \"Picture\", help: \"Optional. Choose a picture and we size it for the web.\" }),\n heroImageAlt: z.string().min(1, MESSAGES.heroImageAlt).optional()\n .meta({ label: \"Picture description\", placeholder: \"What the picture shows\", help: \"A sentence describing the picture, for screen readers and Google Images.\" }),\n ogImage: z.string().min(1, \"ogImage must be a path when present\").optional()\n .meta({ label: \"Social share image\", help: \"Shown when someone shares the link. Leave blank to reuse the picture.\" }),\n cancelled: z.boolean().optional()\n .meta({ label: \"Cancelled\", help: \"Keeps the event on the page, marked cancelled.\" }),\n cancelledNote: z.string().max(300, \"keep the note under 300 characters\").optional()\n .meta({ label: \"Cancellation note\", placeholder: \"e.g. Postponed — new date coming soon\", help: \"A short line shown with the cancelled event.\" }),\n rescheduledTo: z.string().regex(SLUG_RE, \"rescheduledTo must be the web address (slug) of the replacement event\").optional()\n .meta({ label: \"Moved to\", placeholder: \"the slug of the new event\", help: \"If this moved to a new date, the web address of the replacement.\" }),\n previousDate: z.string().regex(DATE_RE, \"previousDate must be YYYY-MM-DD\").optional()\n .meta({ label: \"Previous date\", help: \"If this event moved, the date it was originally on.\" }),\n };\n}\n\ntype Core<K extends string> = {\n title: string; slug: string; summary: string;\n kind?: K | typeof OTHER_KIND; kindLabel?: string;\n date: string; startTime?: string; endTime?: string; timezone?: Zone;\n location?: string; url?: string;\n heroImage?: string; heroImageAlt?: string; ogImage?: string;\n cancelled?: boolean; cancelledNote?: string; rescheduledTo?: string; previousDate?: string;\n};\ntype Venues = { venue: string };\ntype Tickets = { rsvpUrl?: string; capacity?: number; closed?: boolean; private?: boolean };\ntype Appearances = { host?: string; recordingUrl?: string; slidesUrl?: string };\n\nexport type EventFrontmatter<G extends EventGroup = never, K extends string = DefaultKind> =\n Core<K>\n & (\"venues\" extends G ? Venues : object)\n & (\"tickets\" extends G ? Tickets : object)\n & (\"appearances\" extends G ? Appearances : object);\n\nexport function eventSchema<G extends EventGroup = never, K extends string = DefaultKind>(\n options: EventSchemaOptions<G, K> = {},\n): z.ZodType<EventFrontmatter<G, K>> {\n const kinds = (options.kinds ?? DEFAULT_KINDS) as unknown as readonly [K, ...K[]];\n const groups = (options.with ?? []).filter((g) => (EVENT_GROUPS as readonly string[]).includes(g));\n const shape = { ...coreShape(kinds), ...Object.assign({}, ...groups.map((g) => GROUP_SHAPES[g])) };\n\n const schema = z.object(shape).strict()\n .refine((d) => !d.endTime || !!d.startTime, { message: MESSAGES.endTime, path: [\"endTime\"] })\n .refine((d) => !d.heroImage || !!d.heroImageAlt, { message: MESSAGES.heroImageAlt, path: [\"heroImageAlt\"] })\n .refine((d) => d.kind !== OTHER_KIND || !!d.kindLabel, { message: MESSAGES.kindLabel, path: [\"kindLabel\"] })\n .refine((d) => d.kind === OTHER_KIND || !d.kindLabel, { message: \"a custom kind is only used when the kind is “other”\", path: [\"kindLabel\"] });\n return schema as unknown as z.ZodType<EventFrontmatter<G, K>>;\n}\n\n/** The chip text: the custom label for \"other\", else the kind in Title Case, else null. */\nexport function kindOf(fm: { kind?: string; kindLabel?: string }): string | null {\n if (fm.kind === OTHER_KIND) return fm.kindLabel?.trim() || null;\n if (!fm.kind) return null;\n return fm.kind.replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\n/** 5degrees-style file names: 2026-09-28-ai-talk.mdx. */\nexport function eventFilename(fm: Record<string, unknown>): string {\n return `${String(fm.date)}-${String(fm.slug)}.mdx`;\n}\n\n/** slugFromFilename for eventFilename: \"2026-09-28-ai-talk.mdx\" → \"ai-talk\". */\nexport function slugFromEventFilename(fileName: string): string | null {\n const m = /^\\d{4}-\\d{2}-\\d{2}-([a-z0-9]+(?:-[a-z0-9]+)*)\\.mdx$/.exec(fileName);\n return m ? m[1] : null;\n}\n\n/** Blog-style file names: ai-talk.mdx. */\nexport function slugFilename(fm: Record<string, unknown>): string {\n return `${String(fm.slug)}.mdx`;\n}\n","/**\n * Turn \"a date, a wall-clock time, a zone\" into instants, and back into words.\n * No date library: zone offsets come from Intl.DateTimeFormat, which every\n * runtime we target ships with full tz data.\n */\n\nimport { isZone, zoneToIana } from \"./zones\";\n\nexport interface WhenInput {\n date: string;\n startTime?: string;\n endTime?: string;\n timezone?: string;\n}\n\nexport interface When {\n start: Date;\n end: Date | null;\n /** IANA zone the event is in. */\n zone: string;\n allDay: boolean;\n}\n\nexport interface WhenOptions {\n /** IANA zone used when the event has none, e.g. \"America/New_York\". */\n defaultZone: string;\n}\n\nexport function zoneFor(fm: { timezone?: string }, opts: WhenOptions): string {\n return isZone(fm.timezone) ? zoneToIana(fm.timezone) : opts.defaultZone;\n}\n\n/** Offset (ms) of `zone` from UTC at the given instant. */\nfunction offsetAt(instant: Date, zone: string): number {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: zone, hourCycle: \"h23\",\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\",\n }).formatToParts(instant);\n const n = (t: string) => Number(parts.find((p) => p.type === t)?.value ?? 0);\n const asUtc = Date.UTC(n(\"year\"), n(\"month\") - 1, n(\"day\"), n(\"hour\"), n(\"minute\"), n(\"second\"));\n return asUtc - instant.getTime();\n}\n\n/** The instant at which the wall clock in `zone` reads y-m-d h:mm. */\nexport function zonedInstant(date: string, hhmm: string, zone: string): Date {\n const [y, m, d] = date.split(\"-\").map(Number);\n const [h, min] = hhmm.split(\":\").map(Number);\n const wall = Date.UTC(y, m - 1, d, h, min);\n // Guess with the offset at the wall time read as UTC, then correct once — the\n // second pass lands exactly except inside a DST gap, where it picks the later side.\n let guess = wall - offsetAt(new Date(wall), zone);\n guess = wall - offsetAt(new Date(guess), zone);\n return new Date(guess);\n}\n\nexport function eventWhen(fm: WhenInput, opts: WhenOptions): When {\n const zone = zoneFor(fm, opts);\n if (!fm.startTime) {\n return { start: zonedInstant(fm.date, \"00:00\", zone), end: null, zone, allDay: true };\n }\n const start = zonedInstant(fm.date, fm.startTime, zone);\n const end = fm.endTime ? zonedInstant(fm.date, fm.endTime, zone) : null;\n return { start, end, zone, allDay: false };\n}\n\n/** Midnight at the start of the day AFTER the event, in its zone — when an all-day item is over. */\nexport function endOfDay(when: When): Date {\n const next = new Date(when.start.getTime() + 36 * 3_600_000); // safely into the next day\n const ymd = new Intl.DateTimeFormat(\"en-CA\", { timeZone: when.zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(next);\n return zonedInstant(ymd, \"00:00\", when.zone);\n}\n\n/** The moment the event is over: its end, else its start, else the end of its day. */\nexport function endsAt(when: When): Date {\n if (when.allDay) return endOfDay(when);\n return when.end ?? when.start;\n}\n\nexport function formatWhen(when: When, opts: { locale?: string } = {}): string {\n const locale = opts.locale ?? \"en-US\";\n const day = new Intl.DateTimeFormat(locale, { timeZone: when.zone, weekday: \"short\", month: \"short\", day: \"numeric\", year: \"numeric\" }).format(when.start);\n if (when.allDay) return day;\n\n const clock = (d: Date) =>\n new Intl.DateTimeFormat(locale, { timeZone: when.zone, hour: \"numeric\", minute: \"2-digit\", hour12: true }).format(d).toLowerCase();\n const zoneName = new Intl.DateTimeFormat(locale, { timeZone: when.zone, timeZoneName: \"short\" })\n .formatToParts(when.start).find((p) => p.type === \"timeZoneName\")?.value ?? \"\";\n\n if (!when.end) return `${day} · ${clock(when.start)} ${zoneName}`.trim();\n\n // \"7:00–9:00 pm\" when both share a meridiem; \"11:00 am–1:00 pm\" otherwise.\n const s = clock(when.start);\n const e = clock(when.end);\n const [sTime, sMer] = s.split(\" \");\n const [, eMer] = e.split(\" \");\n const range = sMer === eMer ? `${sTime}–${e}` : `${s}–${e}`;\n return `${day} · ${range} ${zoneName}`.trim();\n}\n\n/** The calendar day (YYYY-MM-DD) of an instant in a zone. */\nexport function dayIn(instant: Date, zone: string): string {\n return new Intl.DateTimeFormat(\"en-CA\", { timeZone: zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(instant);\n}\n","/**\n * Where an event sits relative to now, and how a list should order them.\n * Pure: everything takes `now` so tests and static builds are deterministic.\n */\n\nimport { dayIn, endsAt, eventWhen, type WhenInput, type WhenOptions } from \"./when\";\n\nexport type EventStatus = \"cancelled\" | \"rescheduled\" | \"past\" | \"today\" | \"upcoming\";\n\nexport interface StatusInput extends WhenInput {\n cancelled?: boolean;\n rescheduledTo?: string;\n}\n\nexport function eventStatus(fm: StatusInput, now: Date, opts: WhenOptions): EventStatus {\n if (fm.cancelled) return \"cancelled\";\n if (fm.rescheduledTo) return \"rescheduled\";\n const when = eventWhen(fm, opts);\n if (endsAt(when).getTime() < now.getTime()) return \"past\";\n if (dayIn(when.start, when.zone) === dayIn(now, when.zone)) return \"today\";\n return \"upcoming\";\n}\n\nexport interface SplitResult<T> {\n /** Soonest first. */\n upcoming: T[];\n /** Most recent first. */\n past: T[];\n}\n\n/**\n * Upcoming = not yet over (today's items included). Cancelled and rescheduled\n * items stay wherever their date puts them — the page marks them, it does not hide them.\n */\nexport function splitEvents<T extends StatusInput>(items: readonly T[], now: Date, opts: WhenOptions): SplitResult<T> {\n const stamped = items.map((fm) => ({ fm, when: eventWhen(fm, opts) }));\n const over = (x: (typeof stamped)[number]) => endsAt(x.when).getTime() < now.getTime();\n const upcoming = stamped.filter((x) => !over(x)).sort((a, b) => a.when.start.getTime() - b.when.start.getTime());\n const past = stamped.filter(over).sort((a, b) => b.when.start.getTime() - a.when.start.getTime());\n return { upcoming: upcoming.map((x) => x.fm), past: past.map((x) => x.fm) };\n}\n","/**\n * What a site spreads into defineContentType so an events type is ten lines:\n * field order, the grouped sections, the image fields.\n */\n\nimport type { EventGroup } from \"./groups\";\n\nexport interface EventRegistryDefaults {\n order: string[];\n groups: { label: string; fields: string[] }[];\n images: string[];\n inputs: Record<string, never>;\n}\n\nexport function eventRegistryDefaults(options: { with?: readonly EventGroup[] } = {}): EventRegistryDefaults {\n const on = new Set(options.with ?? []);\n const where = on.has(\"venues\") ? \"venue\" : \"location\";\n\n const order = [\"title\", \"slug\", \"summary\", \"kind\", \"kindLabel\", \"date\", \"startTime\", \"endTime\", \"timezone\", where, \"url\"];\n if (on.has(\"venues\")) order.push(\"location\"); // extra directions under the venue\n\n const groups: EventRegistryDefaults[\"groups\"] = [];\n if (on.has(\"tickets\")) groups.push({ label: \"Tickets & RSVP\", fields: [\"rsvpUrl\", \"capacity\", \"closed\", \"private\"] });\n if (on.has(\"appearances\")) groups.push({ label: \"Appearance details\", fields: [\"host\", \"recordingUrl\", \"slidesUrl\"] });\n groups.push({ label: \"Pictures\", fields: [\"heroImage\", \"heroImageAlt\", \"ogImage\"] });\n groups.push({ label: \"Changes\", fields: [\"cancelled\", \"cancelledNote\", \"rescheduledTo\", \"previousDate\"] });\n\n // Inputs come from .meta() in the schema; the key is here so a site can spread and then override.\n return { order, groups, images: [\"heroImage\", \"ogImage\"], inputs: {} };\n}\n"]}
1
+ {"version":3,"sources":["../../src/events/groups.ts","../../src/events/zones.ts","../../src/events/schema.ts","../../src/events/when.ts","../../src/events/status.ts","../../src/events/registry.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The optional field groups a site can switch on. Each is a zod shape fragment\n * merged into the core by eventSchema; nothing here knows about the others.\n *\n * zod is imported directly: it is external in tsup and a peer dependency, so\n * this resolves to the host site's copy — the same instance its own schemas use.\n */\n\nimport { z } from \"zod\";\n\nexport const EVENT_GROUPS = [\"venues\", \"tickets\", \"appearances\"] as const;\nexport type EventGroup = (typeof EVENT_GROUPS)[number];\n\n/** A reference to a venues collection. The SITE resolves the options (registry `options.venue`). */\nexport const venuesShape = {\n venue: z.string().min(1, \"pick a venue\")\n .meta({ label: \"Venue\", help: \"Where this happens. Venues are kept in their own list so the address is typed once.\" }),\n};\n\nexport const ticketsShape = {\n rsvpUrl: z.string().url(\"the RSVP link must be a full web address, starting with https://\").optional()\n .meta({ label: \"RSVP or ticket link\", placeholder: \"https://…\", help: \"Where people go to sign up or buy a ticket. Leave blank if there is nothing to book.\" }),\n capacity: z.number().int(\"capacity must be a whole number\").positive(\"capacity must be more than zero\").optional()\n .meta({ label: \"Capacity\", help: \"How many people can come. Leave blank if there is no limit.\" }),\n closed: z.boolean().optional()\n .meta({ label: \"Sign-ups closed\", help: \"Tick this to stop taking sign-ups while still showing the event.\" }),\n private: z.boolean().optional()\n .meta({ label: \"Private event\", help: \"Invited guests only. The event still shows, but nobody can sign up from the website.\" }),\n};\n\nexport const appearancesShape = {\n host: z.string().min(1, \"host must not be empty when present\").optional()\n .meta({ label: \"Hosted or published by\", placeholder: \"e.g. The SoundPlex, or the name of the podcast\", help: \"The organisation, venue, podcast or publication behind this appearance.\" }),\n recordingUrl: z.string().url(\"the recording link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Recording link\", placeholder: \"https://…\", help: \"A video or audio recording to watch or listen to afterwards — YouTube, Spotify, the episode page.\" }),\n slidesUrl: z.string().url(\"the slides link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Slides link\", placeholder: \"https://…\", help: \"Where the slides live, if you want to share them.\" }),\n};\n\nexport const GROUP_SHAPES = {\n venues: venuesShape,\n tickets: ticketsShape,\n appearances: appearancesShape,\n} as const;\n","/**\n * Time zones a client can pick from — friendly names, because \"America/Phoenix\"\n * means nothing to someone booking a talk. zoneToIana turns them back into what\n * Intl needs. US-only for now; extending the list is the whole change.\n */\n\nexport const ZONES = [\"Eastern\", \"Central\", \"Mountain\", \"Arizona\", \"Pacific\", \"Alaska\", \"Hawaii\"] as const;\nexport type Zone = (typeof ZONES)[number];\n\nconst IANA: Record<Zone, string> = {\n Eastern: \"America/New_York\",\n Central: \"America/Chicago\",\n Mountain: \"America/Denver\",\n Arizona: \"America/Phoenix\",\n Pacific: \"America/Los_Angeles\",\n Alaska: \"America/Anchorage\",\n Hawaii: \"Pacific/Honolulu\",\n};\n\nexport function zoneToIana(zone: Zone): string {\n return IANA[zone];\n}\n\nexport function isZone(value: unknown): value is Zone {\n return typeof value === \"string\" && (ZONES as readonly string[]).includes(value);\n}\n","/**\n * eventSchema — one events model for every site, assembled from a core plus the\n * groups a site switches on. Labels and help live here as .meta() so the form\n * needs no registry overrides.\n *\n * Time is stored the way a person wrote it — a date, a wall-clock time, a zone —\n * never a UTC instant. That is what survives a hand edit on GitHub. when.ts turns\n * it into instants at render time.\n */\n\nimport { z } from \"zod\";\nimport { EVENT_GROUPS, GROUP_SHAPES, type EventGroup } from \"./groups\";\nimport { ZONES, type Zone } from \"./zones\";\n\nexport const DEFAULT_KINDS = [\"talk\", \"panel\", \"workshop\", \"webinar\", \"podcast\", \"interview\", \"article\"] as const;\nexport type DefaultKind = (typeof DEFAULT_KINDS)[number];\n\n/** Always accepted, whatever the site's list: unlocks the free-text kindLabel. */\nexport const OTHER_KIND = \"other\";\n\nexport const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nexport const TIME_RE = /^([01]\\d|2[0-3]):[0-5]\\d$/;\n\nexport const MESSAGES = {\n date: \"that date doesn’t exist — check the month has that many days\",\n time: \"use a 24-hour time like 19:00\",\n endTime: \"add a start time first\",\n heroImageAlt: \"describe the picture so screen readers and Google can read it\",\n kindLabel: \"say what kind of event this is\",\n} as const;\n\nexport interface EventSchemaOptions<G extends EventGroup = never, K extends string = DefaultKind> {\n /** Optional groups to switch on. */\n with?: readonly G[];\n /** The site's own list of kinds; \"other\" is always added. Defaults to DEFAULT_KINDS. */\n kinds?: readonly [K, ...K[]];\n}\n\nfunction realDate(value: string): boolean {\n const [y, m, d] = value.split(\"-\").map(Number);\n const dt = new Date(Date.UTC(y, m - 1, d));\n return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;\n}\n\nconst time = (label: string, help: string) =>\n z.string().regex(TIME_RE, MESSAGES.time).optional().meta({ label, help, input: \"time\" });\n\nfunction coreShape<K extends string>(kinds: readonly [K, ...K[]]) {\n const kindValues = [...kinds, OTHER_KIND] as [string, ...string[]];\n return {\n title: z.string().min(1, \"give the event a title\")\n .meta({ label: \"Title\", placeholder: \"What it's called\", help: \"The headline people see on the page and in the list.\" }),\n slug: z.string().min(1, \"slug is required\").regex(SLUG_RE, \"slug must be lowercase words joined by hyphens, e.g. ai-talk-soundplex\")\n .meta({ label: \"Web address (slug)\", placeholder: \"e.g. ai-talk-soundplex\", help: \"The last part of the link. Lowercase words joined by hyphens, no spaces.\" }),\n summary: z.string().min(1, \"write a one-line summary\").max(200, \"keep the summary under 200 characters\")\n .meta({ label: \"One-line summary\", input: \"textarea\", help: \"One or two sentences shown in the list. The longer description goes in the body below.\" }),\n kind: z.enum(kindValues).optional()\n .meta({ label: \"What kind of event\", help: \"Pick the closest. Choose “other” to type your own.\" }),\n kindLabel: z.string().min(1, MESSAGES.kindLabel).max(40, \"keep the custom kind under 40 characters\").optional()\n .meta({ label: \"Custom kind\", placeholder: \"e.g. Fireside chat\", help: \"Only used when the kind is “other”.\" }),\n date: z.string().regex(DATE_RE, \"date must be written as YYYY-MM-DD, e.g. 2026-09-28\").refine(realDate, { message: MESSAGES.date })\n .meta({ label: \"Date\", input: \"date\", help: \"The day it happens. For a podcast or article, the day it comes out.\" }),\n startTime: time(\"Start time\", \"Leave blank for an all-day item or something without a set time.\"),\n endTime: time(\"End time\", \"Optional. Needs a start time.\"),\n timezone: z.enum(ZONES).optional()\n .meta({ label: \"Time zone\", help: \"Leave blank for the site's usual zone.\" }),\n location: z.string().min(1, \"location must not be empty when present\").optional()\n .meta({ label: \"Where\", placeholder: \"e.g. The SoundPlex, Pennsauken, NJ — or Online\", help: \"A place name and town, or “Online”. Shown under the title.\" }),\n url: z.string().url(\"the link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Link for details\", placeholder: \"https://…\", help: \"The event's own page, if it has one.\" }),\n heroImage: z.string().min(1, \"heroImage must be a path when present\").optional()\n .meta({ label: \"Picture\", help: \"Optional. Choose a picture and we size it for the web.\" }),\n heroImageAlt: z.string().min(1, MESSAGES.heroImageAlt).optional()\n .meta({ label: \"Picture description\", placeholder: \"What the picture shows\", help: \"A sentence describing the picture, for screen readers and Google Images.\" }),\n ogImage: z.string().min(1, \"ogImage must be a path when present\").optional()\n .meta({ label: \"Social share image\", help: \"Shown when someone shares the link. Leave blank to reuse the picture.\" }),\n cancelled: z.boolean().optional()\n .meta({ label: \"Canceled\", help: \"Keeps the event on the page, marked canceled.\" }),\n cancelledNote: z.string().max(300, \"keep the note under 300 characters\").optional()\n .meta({ label: \"Cancellation note\", placeholder: \"e.g. Postponed — new date coming soon\", help: \"A short line shown with the cancelled event.\" }),\n rescheduledTo: z.string().regex(SLUG_RE, \"rescheduledTo must be the web address (slug) of the replacement event\").optional()\n .meta({ label: \"Moved to\", placeholder: \"the slug of the new event\", help: \"If this moved to a new date, the web address of the replacement.\" }),\n previousDate: z.string().regex(DATE_RE, \"previousDate must be YYYY-MM-DD\").optional()\n .meta({ label: \"Previous date\", help: \"If this event moved, the date it was originally on.\" }),\n };\n}\n\ntype Core<K extends string> = {\n title: string; slug: string; summary: string;\n kind?: K | typeof OTHER_KIND; kindLabel?: string;\n date: string; startTime?: string; endTime?: string; timezone?: Zone;\n location?: string; url?: string;\n heroImage?: string; heroImageAlt?: string; ogImage?: string;\n cancelled?: boolean; cancelledNote?: string; rescheduledTo?: string; previousDate?: string;\n};\ntype Venues = { venue: string };\ntype Tickets = { rsvpUrl?: string; capacity?: number; closed?: boolean; private?: boolean };\ntype Appearances = { host?: string; recordingUrl?: string; slidesUrl?: string };\n\nexport type EventFrontmatter<G extends EventGroup = never, K extends string = DefaultKind> =\n Core<K>\n & (\"venues\" extends G ? Venues : object)\n & (\"tickets\" extends G ? Tickets : object)\n & (\"appearances\" extends G ? Appearances : object);\n\nexport function eventSchema<G extends EventGroup = never, K extends string = DefaultKind>(\n options: EventSchemaOptions<G, K> = {},\n): z.ZodType<EventFrontmatter<G, K>> {\n const kinds = (options.kinds ?? DEFAULT_KINDS) as unknown as readonly [K, ...K[]];\n const groups = (options.with ?? []).filter((g) => (EVENT_GROUPS as readonly string[]).includes(g));\n const shape = { ...coreShape(kinds), ...Object.assign({}, ...groups.map((g) => GROUP_SHAPES[g])) };\n\n const schema = z.object(shape).strict()\n .refine((d) => !d.endTime || !!d.startTime, { message: MESSAGES.endTime, path: [\"endTime\"] })\n .refine((d) => !d.heroImage || !!d.heroImageAlt, { message: MESSAGES.heroImageAlt, path: [\"heroImageAlt\"] })\n .refine((d) => d.kind !== OTHER_KIND || !!d.kindLabel, { message: MESSAGES.kindLabel, path: [\"kindLabel\"] })\n .refine((d) => d.kind === OTHER_KIND || !d.kindLabel, { message: \"a custom kind is only used when the kind is “other”\", path: [\"kindLabel\"] });\n return schema as unknown as z.ZodType<EventFrontmatter<G, K>>;\n}\n\n/** The chip text: the custom label for \"other\", else the kind in Title Case, else null. */\nexport function kindOf(fm: { kind?: string; kindLabel?: string }): string | null {\n if (fm.kind === OTHER_KIND) return fm.kindLabel?.trim() || null;\n if (!fm.kind) return null;\n return fm.kind.replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\n/** 5degrees-style file names: 2026-09-28-ai-talk.mdx. */\nexport function eventFilename(fm: Record<string, unknown>): string {\n return `${String(fm.date)}-${String(fm.slug)}.mdx`;\n}\n\n/** slugFromFilename for eventFilename: \"2026-09-28-ai-talk.mdx\" → \"ai-talk\". */\nexport function slugFromEventFilename(fileName: string): string | null {\n const m = /^\\d{4}-\\d{2}-\\d{2}-([a-z0-9]+(?:-[a-z0-9]+)*)\\.mdx$/.exec(fileName);\n return m ? m[1] : null;\n}\n\n/** Blog-style file names: ai-talk.mdx. */\nexport function slugFilename(fm: Record<string, unknown>): string {\n return `${String(fm.slug)}.mdx`;\n}\n","/**\n * Turn \"a date, a wall-clock time, a zone\" into instants, and back into words.\n * No date library: zone offsets come from Intl.DateTimeFormat, which every\n * runtime we target ships with full tz data.\n */\n\nimport { isZone, zoneToIana } from \"./zones\";\n\nexport interface WhenInput {\n date: string;\n startTime?: string;\n endTime?: string;\n timezone?: string;\n}\n\nexport interface When {\n start: Date;\n end: Date | null;\n /** IANA zone the event is in. */\n zone: string;\n allDay: boolean;\n}\n\nexport interface WhenOptions {\n /** IANA zone used when the event has none, e.g. \"America/New_York\". */\n defaultZone: string;\n}\n\nexport function zoneFor(fm: { timezone?: string }, opts: WhenOptions): string {\n return isZone(fm.timezone) ? zoneToIana(fm.timezone) : opts.defaultZone;\n}\n\n/** Offset (ms) of `zone` from UTC at the given instant. */\nfunction offsetAt(instant: Date, zone: string): number {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: zone, hourCycle: \"h23\",\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\",\n }).formatToParts(instant);\n const n = (t: string) => Number(parts.find((p) => p.type === t)?.value ?? 0);\n const asUtc = Date.UTC(n(\"year\"), n(\"month\") - 1, n(\"day\"), n(\"hour\"), n(\"minute\"), n(\"second\"));\n return asUtc - instant.getTime();\n}\n\n/** The instant at which the wall clock in `zone` reads y-m-d h:mm. */\nexport function zonedInstant(date: string, hhmm: string, zone: string): Date {\n const [y, m, d] = date.split(\"-\").map(Number);\n const [h, min] = hhmm.split(\":\").map(Number);\n const wall = Date.UTC(y, m - 1, d, h, min);\n // Guess with the offset at the wall time read as UTC, then correct once — the\n // second pass lands exactly except inside a DST gap, where it picks the later side.\n let guess = wall - offsetAt(new Date(wall), zone);\n guess = wall - offsetAt(new Date(guess), zone);\n return new Date(guess);\n}\n\nexport function eventWhen(fm: WhenInput, opts: WhenOptions): When {\n const zone = zoneFor(fm, opts);\n if (!fm.startTime) {\n return { start: zonedInstant(fm.date, \"00:00\", zone), end: null, zone, allDay: true };\n }\n const start = zonedInstant(fm.date, fm.startTime, zone);\n const end = fm.endTime ? zonedInstant(fm.date, fm.endTime, zone) : null;\n return { start, end, zone, allDay: false };\n}\n\n/** Midnight at the start of the day AFTER the event, in its zone — when an all-day item is over. */\nexport function endOfDay(when: When): Date {\n const next = new Date(when.start.getTime() + 36 * 3_600_000); // safely into the next day\n const ymd = new Intl.DateTimeFormat(\"en-CA\", { timeZone: when.zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(next);\n return zonedInstant(ymd, \"00:00\", when.zone);\n}\n\n/** The moment the event is over: its end, else its start, else the end of its day. */\nexport function endsAt(when: When): Date {\n if (when.allDay) return endOfDay(when);\n return when.end ?? when.start;\n}\n\nexport function formatWhen(when: When, opts: { locale?: string } = {}): string {\n const locale = opts.locale ?? \"en-US\";\n const day = new Intl.DateTimeFormat(locale, { timeZone: when.zone, weekday: \"short\", month: \"short\", day: \"numeric\", year: \"numeric\" }).format(when.start);\n if (when.allDay) return day;\n\n const clock = (d: Date) =>\n new Intl.DateTimeFormat(locale, { timeZone: when.zone, hour: \"numeric\", minute: \"2-digit\", hour12: true }).format(d).toLowerCase();\n const zoneName = new Intl.DateTimeFormat(locale, { timeZone: when.zone, timeZoneName: \"short\" })\n .formatToParts(when.start).find((p) => p.type === \"timeZoneName\")?.value ?? \"\";\n\n if (!when.end) return `${day} · ${clock(when.start)} ${zoneName}`.trim();\n\n // \"7:00–9:00 pm\" when both share a meridiem; \"11:00 am–1:00 pm\" otherwise.\n const s = clock(when.start);\n const e = clock(when.end);\n const [sTime, sMer] = s.split(\" \");\n const [, eMer] = e.split(\" \");\n const range = sMer === eMer ? `${sTime}–${e}` : `${s}–${e}`;\n return `${day} · ${range} ${zoneName}`.trim();\n}\n\n/** The calendar day (YYYY-MM-DD) of an instant in a zone. */\nexport function dayIn(instant: Date, zone: string): string {\n return new Intl.DateTimeFormat(\"en-CA\", { timeZone: zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(instant);\n}\n","/**\n * Where an event sits relative to now, and how a list should order them.\n * Pure: everything takes `now` so tests and static builds are deterministic.\n */\n\nimport { dayIn, endsAt, eventWhen, type WhenInput, type WhenOptions } from \"./when\";\n\nexport type EventStatus = \"cancelled\" | \"rescheduled\" | \"past\" | \"today\" | \"upcoming\";\n\nexport interface StatusInput extends WhenInput {\n cancelled?: boolean;\n rescheduledTo?: string;\n}\n\nexport function eventStatus(fm: StatusInput, now: Date, opts: WhenOptions): EventStatus {\n if (fm.cancelled) return \"cancelled\";\n if (fm.rescheduledTo) return \"rescheduled\";\n const when = eventWhen(fm, opts);\n if (endsAt(when).getTime() < now.getTime()) return \"past\";\n if (dayIn(when.start, when.zone) === dayIn(now, when.zone)) return \"today\";\n return \"upcoming\";\n}\n\nexport interface SplitResult<T> {\n /** Soonest first. */\n upcoming: T[];\n /** Most recent first. */\n past: T[];\n}\n\n/**\n * Upcoming = not yet over (today's items included). Cancelled and rescheduled\n * items stay wherever their date puts them — the page marks them, it does not hide them.\n */\nexport function splitEvents<T extends StatusInput>(items: readonly T[], now: Date, opts: WhenOptions): SplitResult<T> {\n const stamped = items.map((fm) => ({ fm, when: eventWhen(fm, opts) }));\n const over = (x: (typeof stamped)[number]) => endsAt(x.when).getTime() < now.getTime();\n const upcoming = stamped.filter((x) => !over(x)).sort((a, b) => a.when.start.getTime() - b.when.start.getTime());\n const past = stamped.filter(over).sort((a, b) => b.when.start.getTime() - a.when.start.getTime());\n return { upcoming: upcoming.map((x) => x.fm), past: past.map((x) => x.fm) };\n}\n","/**\n * What a site spreads into defineContentType so an events type is ten lines:\n * field order, the grouped sections, the image fields.\n */\n\nimport type { EventGroup } from \"./groups\";\n\nexport interface EventRegistryDefaults {\n order: string[];\n groups: { label: string; fields: string[] }[];\n images: string[];\n inputs: Record<string, never>;\n /** The calendar in the sidebar; a site overrides after spreading (e.g. icon: \"mic\" for talks). */\n icon: string;\n}\n\nexport function eventRegistryDefaults(options: { with?: readonly EventGroup[] } = {}): EventRegistryDefaults {\n const on = new Set(options.with ?? []);\n const where = on.has(\"venues\") ? \"venue\" : \"location\";\n\n const order = [\"title\", \"slug\", \"summary\", \"kind\", \"kindLabel\", \"date\", \"startTime\", \"endTime\", \"timezone\", where, \"url\"];\n if (on.has(\"venues\")) order.push(\"location\"); // extra directions under the venue\n\n const groups: EventRegistryDefaults[\"groups\"] = [];\n if (on.has(\"tickets\")) groups.push({ label: \"Tickets & RSVP\", fields: [\"rsvpUrl\", \"capacity\", \"closed\", \"private\"] });\n if (on.has(\"appearances\")) groups.push({ label: \"Appearance details\", fields: [\"host\", \"recordingUrl\", \"slidesUrl\"] });\n groups.push({ label: \"Pictures\", fields: [\"heroImage\", \"heroImageAlt\", \"ogImage\"] });\n groups.push({ label: \"Changes\", fields: [\"cancelled\", \"cancelledNote\", \"rescheduledTo\", \"previousDate\"] });\n\n // Inputs come from .meta() in the schema; the key is here so a site can spread and then override.\n return { order, groups, images: [\"heroImage\", \"ogImage\"], inputs: {}, icon: \"events\" };\n}\n"]}
@@ -168,6 +168,8 @@ interface EventRegistryDefaults {
168
168
  }[];
169
169
  images: string[];
170
170
  inputs: Record<string, never>;
171
+ /** The calendar in the sidebar; a site overrides after spreading (e.g. icon: "mic" for talks). */
172
+ icon: string;
171
173
  }
172
174
  declare function eventRegistryDefaults(options?: {
173
175
  with?: readonly EventGroup[];
@@ -168,6 +168,8 @@ interface EventRegistryDefaults {
168
168
  }[];
169
169
  images: string[];
170
170
  inputs: Record<string, never>;
171
+ /** The calendar in the sidebar; a site overrides after spreading (e.g. icon: "mic" for talks). */
172
+ icon: string;
171
173
  }
172
174
  declare function eventRegistryDefaults(options?: {
173
175
  with?: readonly EventGroup[];
@@ -76,7 +76,7 @@ function coreShape(kinds) {
76
76
  heroImage: z.string().min(1, "heroImage must be a path when present").optional().meta({ label: "Picture", help: "Optional. Choose a picture and we size it for the web." }),
77
77
  heroImageAlt: z.string().min(1, MESSAGES.heroImageAlt).optional().meta({ label: "Picture description", placeholder: "What the picture shows", help: "A sentence describing the picture, for screen readers and Google Images." }),
78
78
  ogImage: z.string().min(1, "ogImage must be a path when present").optional().meta({ label: "Social share image", help: "Shown when someone shares the link. Leave blank to reuse the picture." }),
79
- cancelled: z.boolean().optional().meta({ label: "Cancelled", help: "Keeps the event on the page, marked cancelled." }),
79
+ cancelled: z.boolean().optional().meta({ label: "Canceled", help: "Keeps the event on the page, marked canceled." }),
80
80
  cancelledNote: z.string().max(300, "keep the note under 300 characters").optional().meta({ label: "Cancellation note", placeholder: "e.g. Postponed \u2014 new date coming soon", help: "A short line shown with the cancelled event." }),
81
81
  rescheduledTo: z.string().regex(SLUG_RE, "rescheduledTo must be the web address (slug) of the replacement event").optional().meta({ label: "Moved to", placeholder: "the slug of the new event", help: "If this moved to a new date, the web address of the replacement." }),
82
82
  previousDate: z.string().regex(DATE_RE, "previousDate must be YYYY-MM-DD").optional().meta({ label: "Previous date", help: "If this event moved, the date it was originally on." })
@@ -196,7 +196,7 @@ function eventRegistryDefaults(options = {}) {
196
196
  if (on.has("appearances")) groups.push({ label: "Appearance details", fields: ["host", "recordingUrl", "slidesUrl"] });
197
197
  groups.push({ label: "Pictures", fields: ["heroImage", "heroImageAlt", "ogImage"] });
198
198
  groups.push({ label: "Changes", fields: ["cancelled", "cancelledNote", "rescheduledTo", "previousDate"] });
199
- return { order, groups, images: ["heroImage", "ogImage"], inputs: {} };
199
+ return { order, groups, images: ["heroImage", "ogImage"], inputs: {}, icon: "events" };
200
200
  }
201
201
 
202
202
  export { DEFAULT_KINDS, EVENT_GROUPS, MESSAGES, OTHER_KIND, ZONES, dayIn, endsAt, eventFilename, eventRegistryDefaults, eventSchema, eventStatus, eventWhen, formatWhen, isZone, kindOf, slugFilename, slugFromEventFilename, splitEvents, zoneFor, zoneToIana, zonedInstant };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/events/groups.ts","../../src/events/zones.ts","../../src/events/schema.ts","../../src/events/when.ts","../../src/events/status.ts","../../src/events/registry.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The optional field groups a site can switch on. Each is a zod shape fragment\n * merged into the core by eventSchema; nothing here knows about the others.\n *\n * zod is imported directly: it is external in tsup and a peer dependency, so\n * this resolves to the host site's copy — the same instance its own schemas use.\n */\n\nimport { z } from \"zod\";\n\nexport const EVENT_GROUPS = [\"venues\", \"tickets\", \"appearances\"] as const;\nexport type EventGroup = (typeof EVENT_GROUPS)[number];\n\n/** A reference to a venues collection. The SITE resolves the options (registry `options.venue`). */\nexport const venuesShape = {\n venue: z.string().min(1, \"pick a venue\")\n .meta({ label: \"Venue\", help: \"Where this happens. Venues are kept in their own list so the address is typed once.\" }),\n};\n\nexport const ticketsShape = {\n rsvpUrl: z.string().url(\"the RSVP link must be a full web address, starting with https://\").optional()\n .meta({ label: \"RSVP or ticket link\", placeholder: \"https://…\", help: \"Where people go to sign up or buy a ticket. Leave blank if there is nothing to book.\" }),\n capacity: z.number().int(\"capacity must be a whole number\").positive(\"capacity must be more than zero\").optional()\n .meta({ label: \"Capacity\", help: \"How many people can come. Leave blank if there is no limit.\" }),\n closed: z.boolean().optional()\n .meta({ label: \"Sign-ups closed\", help: \"Tick this to stop taking sign-ups while still showing the event.\" }),\n private: z.boolean().optional()\n .meta({ label: \"Private event\", help: \"Invited guests only. The event still shows, but nobody can sign up from the website.\" }),\n};\n\nexport const appearancesShape = {\n host: z.string().min(1, \"host must not be empty when present\").optional()\n .meta({ label: \"Hosted or published by\", placeholder: \"e.g. The SoundPlex, or the name of the podcast\", help: \"The organisation, venue, podcast or publication behind this appearance.\" }),\n recordingUrl: z.string().url(\"the recording link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Recording link\", placeholder: \"https://…\", help: \"A video or audio recording to watch or listen to afterwards — YouTube, Spotify, the episode page.\" }),\n slidesUrl: z.string().url(\"the slides link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Slides link\", placeholder: \"https://…\", help: \"Where the slides live, if you want to share them.\" }),\n};\n\nexport const GROUP_SHAPES = {\n venues: venuesShape,\n tickets: ticketsShape,\n appearances: appearancesShape,\n} as const;\n","/**\n * Time zones a client can pick from — friendly names, because \"America/Phoenix\"\n * means nothing to someone booking a talk. zoneToIana turns them back into what\n * Intl needs. US-only for now; extending the list is the whole change.\n */\n\nexport const ZONES = [\"Eastern\", \"Central\", \"Mountain\", \"Arizona\", \"Pacific\", \"Alaska\", \"Hawaii\"] as const;\nexport type Zone = (typeof ZONES)[number];\n\nconst IANA: Record<Zone, string> = {\n Eastern: \"America/New_York\",\n Central: \"America/Chicago\",\n Mountain: \"America/Denver\",\n Arizona: \"America/Phoenix\",\n Pacific: \"America/Los_Angeles\",\n Alaska: \"America/Anchorage\",\n Hawaii: \"Pacific/Honolulu\",\n};\n\nexport function zoneToIana(zone: Zone): string {\n return IANA[zone];\n}\n\nexport function isZone(value: unknown): value is Zone {\n return typeof value === \"string\" && (ZONES as readonly string[]).includes(value);\n}\n","/**\n * eventSchema — one events model for every site, assembled from a core plus the\n * groups a site switches on. Labels and help live here as .meta() so the form\n * needs no registry overrides.\n *\n * Time is stored the way a person wrote it — a date, a wall-clock time, a zone —\n * never a UTC instant. That is what survives a hand edit on GitHub. when.ts turns\n * it into instants at render time.\n */\n\nimport { z } from \"zod\";\nimport { EVENT_GROUPS, GROUP_SHAPES, type EventGroup } from \"./groups\";\nimport { ZONES, type Zone } from \"./zones\";\n\nexport const DEFAULT_KINDS = [\"talk\", \"panel\", \"workshop\", \"webinar\", \"podcast\", \"interview\", \"article\"] as const;\nexport type DefaultKind = (typeof DEFAULT_KINDS)[number];\n\n/** Always accepted, whatever the site's list: unlocks the free-text kindLabel. */\nexport const OTHER_KIND = \"other\";\n\nexport const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nexport const TIME_RE = /^([01]\\d|2[0-3]):[0-5]\\d$/;\n\nexport const MESSAGES = {\n date: \"that date doesn’t exist — check the month has that many days\",\n time: \"use a 24-hour time like 19:00\",\n endTime: \"add a start time first\",\n heroImageAlt: \"describe the picture so screen readers and Google can read it\",\n kindLabel: \"say what kind of event this is\",\n} as const;\n\nexport interface EventSchemaOptions<G extends EventGroup = never, K extends string = DefaultKind> {\n /** Optional groups to switch on. */\n with?: readonly G[];\n /** The site's own list of kinds; \"other\" is always added. Defaults to DEFAULT_KINDS. */\n kinds?: readonly [K, ...K[]];\n}\n\nfunction realDate(value: string): boolean {\n const [y, m, d] = value.split(\"-\").map(Number);\n const dt = new Date(Date.UTC(y, m - 1, d));\n return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;\n}\n\nconst time = (label: string, help: string) =>\n z.string().regex(TIME_RE, MESSAGES.time).optional().meta({ label, help, input: \"time\" });\n\nfunction coreShape<K extends string>(kinds: readonly [K, ...K[]]) {\n const kindValues = [...kinds, OTHER_KIND] as [string, ...string[]];\n return {\n title: z.string().min(1, \"give the event a title\")\n .meta({ label: \"Title\", placeholder: \"What it's called\", help: \"The headline people see on the page and in the list.\" }),\n slug: z.string().min(1, \"slug is required\").regex(SLUG_RE, \"slug must be lowercase words joined by hyphens, e.g. ai-talk-soundplex\")\n .meta({ label: \"Web address (slug)\", placeholder: \"e.g. ai-talk-soundplex\", help: \"The last part of the link. Lowercase words joined by hyphens, no spaces.\" }),\n summary: z.string().min(1, \"write a one-line summary\").max(200, \"keep the summary under 200 characters\")\n .meta({ label: \"One-line summary\", input: \"textarea\", help: \"One or two sentences shown in the list. The longer description goes in the body below.\" }),\n kind: z.enum(kindValues).optional()\n .meta({ label: \"What kind of event\", help: \"Pick the closest. Choose “other” to type your own.\" }),\n kindLabel: z.string().min(1, MESSAGES.kindLabel).max(40, \"keep the custom kind under 40 characters\").optional()\n .meta({ label: \"Custom kind\", placeholder: \"e.g. Fireside chat\", help: \"Only used when the kind is “other”.\" }),\n date: z.string().regex(DATE_RE, \"date must be written as YYYY-MM-DD, e.g. 2026-09-28\").refine(realDate, { message: MESSAGES.date })\n .meta({ label: \"Date\", input: \"date\", help: \"The day it happens. For a podcast or article, the day it comes out.\" }),\n startTime: time(\"Start time\", \"Leave blank for an all-day item or something without a set time.\"),\n endTime: time(\"End time\", \"Optional. Needs a start time.\"),\n timezone: z.enum(ZONES).optional()\n .meta({ label: \"Time zone\", help: \"Leave blank for the site's usual zone.\" }),\n location: z.string().min(1, \"location must not be empty when present\").optional()\n .meta({ label: \"Where\", placeholder: \"e.g. The SoundPlex, Pennsauken, NJ — or Online\", help: \"A place name and town, or “Online”. Shown under the title.\" }),\n url: z.string().url(\"the link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Link for details\", placeholder: \"https://…\", help: \"The event's own page, if it has one.\" }),\n heroImage: z.string().min(1, \"heroImage must be a path when present\").optional()\n .meta({ label: \"Picture\", help: \"Optional. Choose a picture and we size it for the web.\" }),\n heroImageAlt: z.string().min(1, MESSAGES.heroImageAlt).optional()\n .meta({ label: \"Picture description\", placeholder: \"What the picture shows\", help: \"A sentence describing the picture, for screen readers and Google Images.\" }),\n ogImage: z.string().min(1, \"ogImage must be a path when present\").optional()\n .meta({ label: \"Social share image\", help: \"Shown when someone shares the link. Leave blank to reuse the picture.\" }),\n cancelled: z.boolean().optional()\n .meta({ label: \"Cancelled\", help: \"Keeps the event on the page, marked cancelled.\" }),\n cancelledNote: z.string().max(300, \"keep the note under 300 characters\").optional()\n .meta({ label: \"Cancellation note\", placeholder: \"e.g. Postponed — new date coming soon\", help: \"A short line shown with the cancelled event.\" }),\n rescheduledTo: z.string().regex(SLUG_RE, \"rescheduledTo must be the web address (slug) of the replacement event\").optional()\n .meta({ label: \"Moved to\", placeholder: \"the slug of the new event\", help: \"If this moved to a new date, the web address of the replacement.\" }),\n previousDate: z.string().regex(DATE_RE, \"previousDate must be YYYY-MM-DD\").optional()\n .meta({ label: \"Previous date\", help: \"If this event moved, the date it was originally on.\" }),\n };\n}\n\ntype Core<K extends string> = {\n title: string; slug: string; summary: string;\n kind?: K | typeof OTHER_KIND; kindLabel?: string;\n date: string; startTime?: string; endTime?: string; timezone?: Zone;\n location?: string; url?: string;\n heroImage?: string; heroImageAlt?: string; ogImage?: string;\n cancelled?: boolean; cancelledNote?: string; rescheduledTo?: string; previousDate?: string;\n};\ntype Venues = { venue: string };\ntype Tickets = { rsvpUrl?: string; capacity?: number; closed?: boolean; private?: boolean };\ntype Appearances = { host?: string; recordingUrl?: string; slidesUrl?: string };\n\nexport type EventFrontmatter<G extends EventGroup = never, K extends string = DefaultKind> =\n Core<K>\n & (\"venues\" extends G ? Venues : object)\n & (\"tickets\" extends G ? Tickets : object)\n & (\"appearances\" extends G ? Appearances : object);\n\nexport function eventSchema<G extends EventGroup = never, K extends string = DefaultKind>(\n options: EventSchemaOptions<G, K> = {},\n): z.ZodType<EventFrontmatter<G, K>> {\n const kinds = (options.kinds ?? DEFAULT_KINDS) as unknown as readonly [K, ...K[]];\n const groups = (options.with ?? []).filter((g) => (EVENT_GROUPS as readonly string[]).includes(g));\n const shape = { ...coreShape(kinds), ...Object.assign({}, ...groups.map((g) => GROUP_SHAPES[g])) };\n\n const schema = z.object(shape).strict()\n .refine((d) => !d.endTime || !!d.startTime, { message: MESSAGES.endTime, path: [\"endTime\"] })\n .refine((d) => !d.heroImage || !!d.heroImageAlt, { message: MESSAGES.heroImageAlt, path: [\"heroImageAlt\"] })\n .refine((d) => d.kind !== OTHER_KIND || !!d.kindLabel, { message: MESSAGES.kindLabel, path: [\"kindLabel\"] })\n .refine((d) => d.kind === OTHER_KIND || !d.kindLabel, { message: \"a custom kind is only used when the kind is “other”\", path: [\"kindLabel\"] });\n return schema as unknown as z.ZodType<EventFrontmatter<G, K>>;\n}\n\n/** The chip text: the custom label for \"other\", else the kind in Title Case, else null. */\nexport function kindOf(fm: { kind?: string; kindLabel?: string }): string | null {\n if (fm.kind === OTHER_KIND) return fm.kindLabel?.trim() || null;\n if (!fm.kind) return null;\n return fm.kind.replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\n/** 5degrees-style file names: 2026-09-28-ai-talk.mdx. */\nexport function eventFilename(fm: Record<string, unknown>): string {\n return `${String(fm.date)}-${String(fm.slug)}.mdx`;\n}\n\n/** slugFromFilename for eventFilename: \"2026-09-28-ai-talk.mdx\" → \"ai-talk\". */\nexport function slugFromEventFilename(fileName: string): string | null {\n const m = /^\\d{4}-\\d{2}-\\d{2}-([a-z0-9]+(?:-[a-z0-9]+)*)\\.mdx$/.exec(fileName);\n return m ? m[1] : null;\n}\n\n/** Blog-style file names: ai-talk.mdx. */\nexport function slugFilename(fm: Record<string, unknown>): string {\n return `${String(fm.slug)}.mdx`;\n}\n","/**\n * Turn \"a date, a wall-clock time, a zone\" into instants, and back into words.\n * No date library: zone offsets come from Intl.DateTimeFormat, which every\n * runtime we target ships with full tz data.\n */\n\nimport { isZone, zoneToIana } from \"./zones\";\n\nexport interface WhenInput {\n date: string;\n startTime?: string;\n endTime?: string;\n timezone?: string;\n}\n\nexport interface When {\n start: Date;\n end: Date | null;\n /** IANA zone the event is in. */\n zone: string;\n allDay: boolean;\n}\n\nexport interface WhenOptions {\n /** IANA zone used when the event has none, e.g. \"America/New_York\". */\n defaultZone: string;\n}\n\nexport function zoneFor(fm: { timezone?: string }, opts: WhenOptions): string {\n return isZone(fm.timezone) ? zoneToIana(fm.timezone) : opts.defaultZone;\n}\n\n/** Offset (ms) of `zone` from UTC at the given instant. */\nfunction offsetAt(instant: Date, zone: string): number {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: zone, hourCycle: \"h23\",\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\",\n }).formatToParts(instant);\n const n = (t: string) => Number(parts.find((p) => p.type === t)?.value ?? 0);\n const asUtc = Date.UTC(n(\"year\"), n(\"month\") - 1, n(\"day\"), n(\"hour\"), n(\"minute\"), n(\"second\"));\n return asUtc - instant.getTime();\n}\n\n/** The instant at which the wall clock in `zone` reads y-m-d h:mm. */\nexport function zonedInstant(date: string, hhmm: string, zone: string): Date {\n const [y, m, d] = date.split(\"-\").map(Number);\n const [h, min] = hhmm.split(\":\").map(Number);\n const wall = Date.UTC(y, m - 1, d, h, min);\n // Guess with the offset at the wall time read as UTC, then correct once — the\n // second pass lands exactly except inside a DST gap, where it picks the later side.\n let guess = wall - offsetAt(new Date(wall), zone);\n guess = wall - offsetAt(new Date(guess), zone);\n return new Date(guess);\n}\n\nexport function eventWhen(fm: WhenInput, opts: WhenOptions): When {\n const zone = zoneFor(fm, opts);\n if (!fm.startTime) {\n return { start: zonedInstant(fm.date, \"00:00\", zone), end: null, zone, allDay: true };\n }\n const start = zonedInstant(fm.date, fm.startTime, zone);\n const end = fm.endTime ? zonedInstant(fm.date, fm.endTime, zone) : null;\n return { start, end, zone, allDay: false };\n}\n\n/** Midnight at the start of the day AFTER the event, in its zone — when an all-day item is over. */\nexport function endOfDay(when: When): Date {\n const next = new Date(when.start.getTime() + 36 * 3_600_000); // safely into the next day\n const ymd = new Intl.DateTimeFormat(\"en-CA\", { timeZone: when.zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(next);\n return zonedInstant(ymd, \"00:00\", when.zone);\n}\n\n/** The moment the event is over: its end, else its start, else the end of its day. */\nexport function endsAt(when: When): Date {\n if (when.allDay) return endOfDay(when);\n return when.end ?? when.start;\n}\n\nexport function formatWhen(when: When, opts: { locale?: string } = {}): string {\n const locale = opts.locale ?? \"en-US\";\n const day = new Intl.DateTimeFormat(locale, { timeZone: when.zone, weekday: \"short\", month: \"short\", day: \"numeric\", year: \"numeric\" }).format(when.start);\n if (when.allDay) return day;\n\n const clock = (d: Date) =>\n new Intl.DateTimeFormat(locale, { timeZone: when.zone, hour: \"numeric\", minute: \"2-digit\", hour12: true }).format(d).toLowerCase();\n const zoneName = new Intl.DateTimeFormat(locale, { timeZone: when.zone, timeZoneName: \"short\" })\n .formatToParts(when.start).find((p) => p.type === \"timeZoneName\")?.value ?? \"\";\n\n if (!when.end) return `${day} · ${clock(when.start)} ${zoneName}`.trim();\n\n // \"7:00–9:00 pm\" when both share a meridiem; \"11:00 am–1:00 pm\" otherwise.\n const s = clock(when.start);\n const e = clock(when.end);\n const [sTime, sMer] = s.split(\" \");\n const [, eMer] = e.split(\" \");\n const range = sMer === eMer ? `${sTime}–${e}` : `${s}–${e}`;\n return `${day} · ${range} ${zoneName}`.trim();\n}\n\n/** The calendar day (YYYY-MM-DD) of an instant in a zone. */\nexport function dayIn(instant: Date, zone: string): string {\n return new Intl.DateTimeFormat(\"en-CA\", { timeZone: zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(instant);\n}\n","/**\n * Where an event sits relative to now, and how a list should order them.\n * Pure: everything takes `now` so tests and static builds are deterministic.\n */\n\nimport { dayIn, endsAt, eventWhen, type WhenInput, type WhenOptions } from \"./when\";\n\nexport type EventStatus = \"cancelled\" | \"rescheduled\" | \"past\" | \"today\" | \"upcoming\";\n\nexport interface StatusInput extends WhenInput {\n cancelled?: boolean;\n rescheduledTo?: string;\n}\n\nexport function eventStatus(fm: StatusInput, now: Date, opts: WhenOptions): EventStatus {\n if (fm.cancelled) return \"cancelled\";\n if (fm.rescheduledTo) return \"rescheduled\";\n const when = eventWhen(fm, opts);\n if (endsAt(when).getTime() < now.getTime()) return \"past\";\n if (dayIn(when.start, when.zone) === dayIn(now, when.zone)) return \"today\";\n return \"upcoming\";\n}\n\nexport interface SplitResult<T> {\n /** Soonest first. */\n upcoming: T[];\n /** Most recent first. */\n past: T[];\n}\n\n/**\n * Upcoming = not yet over (today's items included). Cancelled and rescheduled\n * items stay wherever their date puts them — the page marks them, it does not hide them.\n */\nexport function splitEvents<T extends StatusInput>(items: readonly T[], now: Date, opts: WhenOptions): SplitResult<T> {\n const stamped = items.map((fm) => ({ fm, when: eventWhen(fm, opts) }));\n const over = (x: (typeof stamped)[number]) => endsAt(x.when).getTime() < now.getTime();\n const upcoming = stamped.filter((x) => !over(x)).sort((a, b) => a.when.start.getTime() - b.when.start.getTime());\n const past = stamped.filter(over).sort((a, b) => b.when.start.getTime() - a.when.start.getTime());\n return { upcoming: upcoming.map((x) => x.fm), past: past.map((x) => x.fm) };\n}\n","/**\n * What a site spreads into defineContentType so an events type is ten lines:\n * field order, the grouped sections, the image fields.\n */\n\nimport type { EventGroup } from \"./groups\";\n\nexport interface EventRegistryDefaults {\n order: string[];\n groups: { label: string; fields: string[] }[];\n images: string[];\n inputs: Record<string, never>;\n}\n\nexport function eventRegistryDefaults(options: { with?: readonly EventGroup[] } = {}): EventRegistryDefaults {\n const on = new Set(options.with ?? []);\n const where = on.has(\"venues\") ? \"venue\" : \"location\";\n\n const order = [\"title\", \"slug\", \"summary\", \"kind\", \"kindLabel\", \"date\", \"startTime\", \"endTime\", \"timezone\", where, \"url\"];\n if (on.has(\"venues\")) order.push(\"location\"); // extra directions under the venue\n\n const groups: EventRegistryDefaults[\"groups\"] = [];\n if (on.has(\"tickets\")) groups.push({ label: \"Tickets & RSVP\", fields: [\"rsvpUrl\", \"capacity\", \"closed\", \"private\"] });\n if (on.has(\"appearances\")) groups.push({ label: \"Appearance details\", fields: [\"host\", \"recordingUrl\", \"slidesUrl\"] });\n groups.push({ label: \"Pictures\", fields: [\"heroImage\", \"heroImageAlt\", \"ogImage\"] });\n groups.push({ label: \"Changes\", fields: [\"cancelled\", \"cancelledNote\", \"rescheduledTo\", \"previousDate\"] });\n\n // Inputs come from .meta() in the schema; the key is here so a site can spread and then override.\n return { order, groups, images: [\"heroImage\", \"ogImage\"], inputs: {} };\n}\n"]}
1
+ {"version":3,"sources":["../../src/events/groups.ts","../../src/events/zones.ts","../../src/events/schema.ts","../../src/events/when.ts","../../src/events/status.ts","../../src/events/registry.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The optional field groups a site can switch on. Each is a zod shape fragment\n * merged into the core by eventSchema; nothing here knows about the others.\n *\n * zod is imported directly: it is external in tsup and a peer dependency, so\n * this resolves to the host site's copy — the same instance its own schemas use.\n */\n\nimport { z } from \"zod\";\n\nexport const EVENT_GROUPS = [\"venues\", \"tickets\", \"appearances\"] as const;\nexport type EventGroup = (typeof EVENT_GROUPS)[number];\n\n/** A reference to a venues collection. The SITE resolves the options (registry `options.venue`). */\nexport const venuesShape = {\n venue: z.string().min(1, \"pick a venue\")\n .meta({ label: \"Venue\", help: \"Where this happens. Venues are kept in their own list so the address is typed once.\" }),\n};\n\nexport const ticketsShape = {\n rsvpUrl: z.string().url(\"the RSVP link must be a full web address, starting with https://\").optional()\n .meta({ label: \"RSVP or ticket link\", placeholder: \"https://…\", help: \"Where people go to sign up or buy a ticket. Leave blank if there is nothing to book.\" }),\n capacity: z.number().int(\"capacity must be a whole number\").positive(\"capacity must be more than zero\").optional()\n .meta({ label: \"Capacity\", help: \"How many people can come. Leave blank if there is no limit.\" }),\n closed: z.boolean().optional()\n .meta({ label: \"Sign-ups closed\", help: \"Tick this to stop taking sign-ups while still showing the event.\" }),\n private: z.boolean().optional()\n .meta({ label: \"Private event\", help: \"Invited guests only. The event still shows, but nobody can sign up from the website.\" }),\n};\n\nexport const appearancesShape = {\n host: z.string().min(1, \"host must not be empty when present\").optional()\n .meta({ label: \"Hosted or published by\", placeholder: \"e.g. The SoundPlex, or the name of the podcast\", help: \"The organisation, venue, podcast or publication behind this appearance.\" }),\n recordingUrl: z.string().url(\"the recording link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Recording link\", placeholder: \"https://…\", help: \"A video or audio recording to watch or listen to afterwards — YouTube, Spotify, the episode page.\" }),\n slidesUrl: z.string().url(\"the slides link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Slides link\", placeholder: \"https://…\", help: \"Where the slides live, if you want to share them.\" }),\n};\n\nexport const GROUP_SHAPES = {\n venues: venuesShape,\n tickets: ticketsShape,\n appearances: appearancesShape,\n} as const;\n","/**\n * Time zones a client can pick from — friendly names, because \"America/Phoenix\"\n * means nothing to someone booking a talk. zoneToIana turns them back into what\n * Intl needs. US-only for now; extending the list is the whole change.\n */\n\nexport const ZONES = [\"Eastern\", \"Central\", \"Mountain\", \"Arizona\", \"Pacific\", \"Alaska\", \"Hawaii\"] as const;\nexport type Zone = (typeof ZONES)[number];\n\nconst IANA: Record<Zone, string> = {\n Eastern: \"America/New_York\",\n Central: \"America/Chicago\",\n Mountain: \"America/Denver\",\n Arizona: \"America/Phoenix\",\n Pacific: \"America/Los_Angeles\",\n Alaska: \"America/Anchorage\",\n Hawaii: \"Pacific/Honolulu\",\n};\n\nexport function zoneToIana(zone: Zone): string {\n return IANA[zone];\n}\n\nexport function isZone(value: unknown): value is Zone {\n return typeof value === \"string\" && (ZONES as readonly string[]).includes(value);\n}\n","/**\n * eventSchema — one events model for every site, assembled from a core plus the\n * groups a site switches on. Labels and help live here as .meta() so the form\n * needs no registry overrides.\n *\n * Time is stored the way a person wrote it — a date, a wall-clock time, a zone —\n * never a UTC instant. That is what survives a hand edit on GitHub. when.ts turns\n * it into instants at render time.\n */\n\nimport { z } from \"zod\";\nimport { EVENT_GROUPS, GROUP_SHAPES, type EventGroup } from \"./groups\";\nimport { ZONES, type Zone } from \"./zones\";\n\nexport const DEFAULT_KINDS = [\"talk\", \"panel\", \"workshop\", \"webinar\", \"podcast\", \"interview\", \"article\"] as const;\nexport type DefaultKind = (typeof DEFAULT_KINDS)[number];\n\n/** Always accepted, whatever the site's list: unlocks the free-text kindLabel. */\nexport const OTHER_KIND = \"other\";\n\nexport const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nexport const TIME_RE = /^([01]\\d|2[0-3]):[0-5]\\d$/;\n\nexport const MESSAGES = {\n date: \"that date doesn’t exist — check the month has that many days\",\n time: \"use a 24-hour time like 19:00\",\n endTime: \"add a start time first\",\n heroImageAlt: \"describe the picture so screen readers and Google can read it\",\n kindLabel: \"say what kind of event this is\",\n} as const;\n\nexport interface EventSchemaOptions<G extends EventGroup = never, K extends string = DefaultKind> {\n /** Optional groups to switch on. */\n with?: readonly G[];\n /** The site's own list of kinds; \"other\" is always added. Defaults to DEFAULT_KINDS. */\n kinds?: readonly [K, ...K[]];\n}\n\nfunction realDate(value: string): boolean {\n const [y, m, d] = value.split(\"-\").map(Number);\n const dt = new Date(Date.UTC(y, m - 1, d));\n return dt.getUTCFullYear() === y && dt.getUTCMonth() === m - 1 && dt.getUTCDate() === d;\n}\n\nconst time = (label: string, help: string) =>\n z.string().regex(TIME_RE, MESSAGES.time).optional().meta({ label, help, input: \"time\" });\n\nfunction coreShape<K extends string>(kinds: readonly [K, ...K[]]) {\n const kindValues = [...kinds, OTHER_KIND] as [string, ...string[]];\n return {\n title: z.string().min(1, \"give the event a title\")\n .meta({ label: \"Title\", placeholder: \"What it's called\", help: \"The headline people see on the page and in the list.\" }),\n slug: z.string().min(1, \"slug is required\").regex(SLUG_RE, \"slug must be lowercase words joined by hyphens, e.g. ai-talk-soundplex\")\n .meta({ label: \"Web address (slug)\", placeholder: \"e.g. ai-talk-soundplex\", help: \"The last part of the link. Lowercase words joined by hyphens, no spaces.\" }),\n summary: z.string().min(1, \"write a one-line summary\").max(200, \"keep the summary under 200 characters\")\n .meta({ label: \"One-line summary\", input: \"textarea\", help: \"One or two sentences shown in the list. The longer description goes in the body below.\" }),\n kind: z.enum(kindValues).optional()\n .meta({ label: \"What kind of event\", help: \"Pick the closest. Choose “other” to type your own.\" }),\n kindLabel: z.string().min(1, MESSAGES.kindLabel).max(40, \"keep the custom kind under 40 characters\").optional()\n .meta({ label: \"Custom kind\", placeholder: \"e.g. Fireside chat\", help: \"Only used when the kind is “other”.\" }),\n date: z.string().regex(DATE_RE, \"date must be written as YYYY-MM-DD, e.g. 2026-09-28\").refine(realDate, { message: MESSAGES.date })\n .meta({ label: \"Date\", input: \"date\", help: \"The day it happens. For a podcast or article, the day it comes out.\" }),\n startTime: time(\"Start time\", \"Leave blank for an all-day item or something without a set time.\"),\n endTime: time(\"End time\", \"Optional. Needs a start time.\"),\n timezone: z.enum(ZONES).optional()\n .meta({ label: \"Time zone\", help: \"Leave blank for the site's usual zone.\" }),\n location: z.string().min(1, \"location must not be empty when present\").optional()\n .meta({ label: \"Where\", placeholder: \"e.g. The SoundPlex, Pennsauken, NJ — or Online\", help: \"A place name and town, or “Online”. Shown under the title.\" }),\n url: z.string().url(\"the link must be a full web address, starting with https://\").optional()\n .meta({ label: \"Link for details\", placeholder: \"https://…\", help: \"The event's own page, if it has one.\" }),\n heroImage: z.string().min(1, \"heroImage must be a path when present\").optional()\n .meta({ label: \"Picture\", help: \"Optional. Choose a picture and we size it for the web.\" }),\n heroImageAlt: z.string().min(1, MESSAGES.heroImageAlt).optional()\n .meta({ label: \"Picture description\", placeholder: \"What the picture shows\", help: \"A sentence describing the picture, for screen readers and Google Images.\" }),\n ogImage: z.string().min(1, \"ogImage must be a path when present\").optional()\n .meta({ label: \"Social share image\", help: \"Shown when someone shares the link. Leave blank to reuse the picture.\" }),\n cancelled: z.boolean().optional()\n .meta({ label: \"Canceled\", help: \"Keeps the event on the page, marked canceled.\" }),\n cancelledNote: z.string().max(300, \"keep the note under 300 characters\").optional()\n .meta({ label: \"Cancellation note\", placeholder: \"e.g. Postponed — new date coming soon\", help: \"A short line shown with the cancelled event.\" }),\n rescheduledTo: z.string().regex(SLUG_RE, \"rescheduledTo must be the web address (slug) of the replacement event\").optional()\n .meta({ label: \"Moved to\", placeholder: \"the slug of the new event\", help: \"If this moved to a new date, the web address of the replacement.\" }),\n previousDate: z.string().regex(DATE_RE, \"previousDate must be YYYY-MM-DD\").optional()\n .meta({ label: \"Previous date\", help: \"If this event moved, the date it was originally on.\" }),\n };\n}\n\ntype Core<K extends string> = {\n title: string; slug: string; summary: string;\n kind?: K | typeof OTHER_KIND; kindLabel?: string;\n date: string; startTime?: string; endTime?: string; timezone?: Zone;\n location?: string; url?: string;\n heroImage?: string; heroImageAlt?: string; ogImage?: string;\n cancelled?: boolean; cancelledNote?: string; rescheduledTo?: string; previousDate?: string;\n};\ntype Venues = { venue: string };\ntype Tickets = { rsvpUrl?: string; capacity?: number; closed?: boolean; private?: boolean };\ntype Appearances = { host?: string; recordingUrl?: string; slidesUrl?: string };\n\nexport type EventFrontmatter<G extends EventGroup = never, K extends string = DefaultKind> =\n Core<K>\n & (\"venues\" extends G ? Venues : object)\n & (\"tickets\" extends G ? Tickets : object)\n & (\"appearances\" extends G ? Appearances : object);\n\nexport function eventSchema<G extends EventGroup = never, K extends string = DefaultKind>(\n options: EventSchemaOptions<G, K> = {},\n): z.ZodType<EventFrontmatter<G, K>> {\n const kinds = (options.kinds ?? DEFAULT_KINDS) as unknown as readonly [K, ...K[]];\n const groups = (options.with ?? []).filter((g) => (EVENT_GROUPS as readonly string[]).includes(g));\n const shape = { ...coreShape(kinds), ...Object.assign({}, ...groups.map((g) => GROUP_SHAPES[g])) };\n\n const schema = z.object(shape).strict()\n .refine((d) => !d.endTime || !!d.startTime, { message: MESSAGES.endTime, path: [\"endTime\"] })\n .refine((d) => !d.heroImage || !!d.heroImageAlt, { message: MESSAGES.heroImageAlt, path: [\"heroImageAlt\"] })\n .refine((d) => d.kind !== OTHER_KIND || !!d.kindLabel, { message: MESSAGES.kindLabel, path: [\"kindLabel\"] })\n .refine((d) => d.kind === OTHER_KIND || !d.kindLabel, { message: \"a custom kind is only used when the kind is “other”\", path: [\"kindLabel\"] });\n return schema as unknown as z.ZodType<EventFrontmatter<G, K>>;\n}\n\n/** The chip text: the custom label for \"other\", else the kind in Title Case, else null. */\nexport function kindOf(fm: { kind?: string; kindLabel?: string }): string | null {\n if (fm.kind === OTHER_KIND) return fm.kindLabel?.trim() || null;\n if (!fm.kind) return null;\n return fm.kind.replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\n/** 5degrees-style file names: 2026-09-28-ai-talk.mdx. */\nexport function eventFilename(fm: Record<string, unknown>): string {\n return `${String(fm.date)}-${String(fm.slug)}.mdx`;\n}\n\n/** slugFromFilename for eventFilename: \"2026-09-28-ai-talk.mdx\" → \"ai-talk\". */\nexport function slugFromEventFilename(fileName: string): string | null {\n const m = /^\\d{4}-\\d{2}-\\d{2}-([a-z0-9]+(?:-[a-z0-9]+)*)\\.mdx$/.exec(fileName);\n return m ? m[1] : null;\n}\n\n/** Blog-style file names: ai-talk.mdx. */\nexport function slugFilename(fm: Record<string, unknown>): string {\n return `${String(fm.slug)}.mdx`;\n}\n","/**\n * Turn \"a date, a wall-clock time, a zone\" into instants, and back into words.\n * No date library: zone offsets come from Intl.DateTimeFormat, which every\n * runtime we target ships with full tz data.\n */\n\nimport { isZone, zoneToIana } from \"./zones\";\n\nexport interface WhenInput {\n date: string;\n startTime?: string;\n endTime?: string;\n timezone?: string;\n}\n\nexport interface When {\n start: Date;\n end: Date | null;\n /** IANA zone the event is in. */\n zone: string;\n allDay: boolean;\n}\n\nexport interface WhenOptions {\n /** IANA zone used when the event has none, e.g. \"America/New_York\". */\n defaultZone: string;\n}\n\nexport function zoneFor(fm: { timezone?: string }, opts: WhenOptions): string {\n return isZone(fm.timezone) ? zoneToIana(fm.timezone) : opts.defaultZone;\n}\n\n/** Offset (ms) of `zone` from UTC at the given instant. */\nfunction offsetAt(instant: Date, zone: string): number {\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: zone, hourCycle: \"h23\",\n year: \"numeric\", month: \"2-digit\", day: \"2-digit\", hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\",\n }).formatToParts(instant);\n const n = (t: string) => Number(parts.find((p) => p.type === t)?.value ?? 0);\n const asUtc = Date.UTC(n(\"year\"), n(\"month\") - 1, n(\"day\"), n(\"hour\"), n(\"minute\"), n(\"second\"));\n return asUtc - instant.getTime();\n}\n\n/** The instant at which the wall clock in `zone` reads y-m-d h:mm. */\nexport function zonedInstant(date: string, hhmm: string, zone: string): Date {\n const [y, m, d] = date.split(\"-\").map(Number);\n const [h, min] = hhmm.split(\":\").map(Number);\n const wall = Date.UTC(y, m - 1, d, h, min);\n // Guess with the offset at the wall time read as UTC, then correct once — the\n // second pass lands exactly except inside a DST gap, where it picks the later side.\n let guess = wall - offsetAt(new Date(wall), zone);\n guess = wall - offsetAt(new Date(guess), zone);\n return new Date(guess);\n}\n\nexport function eventWhen(fm: WhenInput, opts: WhenOptions): When {\n const zone = zoneFor(fm, opts);\n if (!fm.startTime) {\n return { start: zonedInstant(fm.date, \"00:00\", zone), end: null, zone, allDay: true };\n }\n const start = zonedInstant(fm.date, fm.startTime, zone);\n const end = fm.endTime ? zonedInstant(fm.date, fm.endTime, zone) : null;\n return { start, end, zone, allDay: false };\n}\n\n/** Midnight at the start of the day AFTER the event, in its zone — when an all-day item is over. */\nexport function endOfDay(when: When): Date {\n const next = new Date(when.start.getTime() + 36 * 3_600_000); // safely into the next day\n const ymd = new Intl.DateTimeFormat(\"en-CA\", { timeZone: when.zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(next);\n return zonedInstant(ymd, \"00:00\", when.zone);\n}\n\n/** The moment the event is over: its end, else its start, else the end of its day. */\nexport function endsAt(when: When): Date {\n if (when.allDay) return endOfDay(when);\n return when.end ?? when.start;\n}\n\nexport function formatWhen(when: When, opts: { locale?: string } = {}): string {\n const locale = opts.locale ?? \"en-US\";\n const day = new Intl.DateTimeFormat(locale, { timeZone: when.zone, weekday: \"short\", month: \"short\", day: \"numeric\", year: \"numeric\" }).format(when.start);\n if (when.allDay) return day;\n\n const clock = (d: Date) =>\n new Intl.DateTimeFormat(locale, { timeZone: when.zone, hour: \"numeric\", minute: \"2-digit\", hour12: true }).format(d).toLowerCase();\n const zoneName = new Intl.DateTimeFormat(locale, { timeZone: when.zone, timeZoneName: \"short\" })\n .formatToParts(when.start).find((p) => p.type === \"timeZoneName\")?.value ?? \"\";\n\n if (!when.end) return `${day} · ${clock(when.start)} ${zoneName}`.trim();\n\n // \"7:00–9:00 pm\" when both share a meridiem; \"11:00 am–1:00 pm\" otherwise.\n const s = clock(when.start);\n const e = clock(when.end);\n const [sTime, sMer] = s.split(\" \");\n const [, eMer] = e.split(\" \");\n const range = sMer === eMer ? `${sTime}–${e}` : `${s}–${e}`;\n return `${day} · ${range} ${zoneName}`.trim();\n}\n\n/** The calendar day (YYYY-MM-DD) of an instant in a zone. */\nexport function dayIn(instant: Date, zone: string): string {\n return new Intl.DateTimeFormat(\"en-CA\", { timeZone: zone, year: \"numeric\", month: \"2-digit\", day: \"2-digit\" }).format(instant);\n}\n","/**\n * Where an event sits relative to now, and how a list should order them.\n * Pure: everything takes `now` so tests and static builds are deterministic.\n */\n\nimport { dayIn, endsAt, eventWhen, type WhenInput, type WhenOptions } from \"./when\";\n\nexport type EventStatus = \"cancelled\" | \"rescheduled\" | \"past\" | \"today\" | \"upcoming\";\n\nexport interface StatusInput extends WhenInput {\n cancelled?: boolean;\n rescheduledTo?: string;\n}\n\nexport function eventStatus(fm: StatusInput, now: Date, opts: WhenOptions): EventStatus {\n if (fm.cancelled) return \"cancelled\";\n if (fm.rescheduledTo) return \"rescheduled\";\n const when = eventWhen(fm, opts);\n if (endsAt(when).getTime() < now.getTime()) return \"past\";\n if (dayIn(when.start, when.zone) === dayIn(now, when.zone)) return \"today\";\n return \"upcoming\";\n}\n\nexport interface SplitResult<T> {\n /** Soonest first. */\n upcoming: T[];\n /** Most recent first. */\n past: T[];\n}\n\n/**\n * Upcoming = not yet over (today's items included). Cancelled and rescheduled\n * items stay wherever their date puts them — the page marks them, it does not hide them.\n */\nexport function splitEvents<T extends StatusInput>(items: readonly T[], now: Date, opts: WhenOptions): SplitResult<T> {\n const stamped = items.map((fm) => ({ fm, when: eventWhen(fm, opts) }));\n const over = (x: (typeof stamped)[number]) => endsAt(x.when).getTime() < now.getTime();\n const upcoming = stamped.filter((x) => !over(x)).sort((a, b) => a.when.start.getTime() - b.when.start.getTime());\n const past = stamped.filter(over).sort((a, b) => b.when.start.getTime() - a.when.start.getTime());\n return { upcoming: upcoming.map((x) => x.fm), past: past.map((x) => x.fm) };\n}\n","/**\n * What a site spreads into defineContentType so an events type is ten lines:\n * field order, the grouped sections, the image fields.\n */\n\nimport type { EventGroup } from \"./groups\";\n\nexport interface EventRegistryDefaults {\n order: string[];\n groups: { label: string; fields: string[] }[];\n images: string[];\n inputs: Record<string, never>;\n /** The calendar in the sidebar; a site overrides after spreading (e.g. icon: \"mic\" for talks). */\n icon: string;\n}\n\nexport function eventRegistryDefaults(options: { with?: readonly EventGroup[] } = {}): EventRegistryDefaults {\n const on = new Set(options.with ?? []);\n const where = on.has(\"venues\") ? \"venue\" : \"location\";\n\n const order = [\"title\", \"slug\", \"summary\", \"kind\", \"kindLabel\", \"date\", \"startTime\", \"endTime\", \"timezone\", where, \"url\"];\n if (on.has(\"venues\")) order.push(\"location\"); // extra directions under the venue\n\n const groups: EventRegistryDefaults[\"groups\"] = [];\n if (on.has(\"tickets\")) groups.push({ label: \"Tickets & RSVP\", fields: [\"rsvpUrl\", \"capacity\", \"closed\", \"private\"] });\n if (on.has(\"appearances\")) groups.push({ label: \"Appearance details\", fields: [\"host\", \"recordingUrl\", \"slidesUrl\"] });\n groups.push({ label: \"Pictures\", fields: [\"heroImage\", \"heroImageAlt\", \"ogImage\"] });\n groups.push({ label: \"Changes\", fields: [\"cancelled\", \"cancelledNote\", \"rescheduledTo\", \"previousDate\"] });\n\n // Inputs come from .meta() in the schema; the key is here so a site can spread and then override.\n return { order, groups, images: [\"heroImage\", \"ogImage\"], inputs: {}, icon: \"events\" };\n}\n"]}
@@ -283,7 +283,7 @@ function findShape(root) {
283
283
  function navFromContentTypes(entries, opts = {}) {
284
284
  const base = (opts.basePath ?? "/admin").replace(/\/+$/, "");
285
285
  const list = Array.isArray(entries) ? entries : Object.values(entries);
286
- return list.map((e) => ({ id: e.id, label: e.label, href: `${base}/${e.id}`, icon: e.id }));
286
+ return list.map((e) => ({ id: e.id, label: e.label, href: `${base}/${e.id}`, icon: e.icon ?? e.id }));
287
287
  }
288
288
 
289
289
  exports.defineContentType = defineContentType;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/forms/internals.ts","../../src/forms/checks.ts","../../src/forms/unwrap.ts","../../src/forms/inputs.ts","../../src/forms/labels.ts","../../src/forms/walk.ts","../../src/forms/registry.ts","../../src/forms/nav.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The slice of zod 4's `_zod.def` surface this module reads, typed loosely.\n *\n * Tested against zod 4.5.4. These are semi-public internals (the v4 \"core\"\n * shape), stable across 4.x so far but not covered by semver promises — hence\n * the peer-dep range and the fixture tests. No zod value is imported here.\n */\n\nexport interface ZodCheckDef {\n check?: string;\n format?: string;\n minimum?: number;\n maximum?: number;\n length?: number;\n value?: number;\n inclusive?: boolean;\n pattern?: RegExp;\n error?: string | ((issue: unknown) => string | { message?: string } | undefined);\n}\n\nexport interface ZodDef {\n type: string;\n shape?: Record<string, ZodNode>;\n innerType?: ZodNode;\n in?: ZodNode;\n out?: ZodNode;\n element?: ZodNode;\n entries?: Record<string, string | number>;\n checks?: Array<{ _zod: { def: ZodCheckDef } }>;\n coerce?: boolean;\n}\n\nexport interface ZodNode {\n _zod: { def: ZodDef };\n description?: string;\n}\n\n/** Narrow an unknown schema to the internal node shape, or throw a clear error. */\nexport function asNode(schema: unknown, what = \"schema\"): ZodNode {\n const n = schema as Partial<ZodNode> | null;\n if (!n || typeof n !== \"object\" || !n._zod?.def?.type) {\n throw new TypeError(`walkSchema: ${what} is not a zod 4 schema`);\n }\n return n as ZodNode;\n}\n\n/** Resolve a check's error to a plain string, if it has one. */\nexport function checkMessage(def: ZodCheckDef): string | undefined {\n const e = def.error;\n if (!e) return undefined;\n if (typeof e === \"string\") return e;\n const out = e({});\n if (typeof out === \"string\") return out;\n return out?.message;\n}\n","/**\n * checks[] → constraints + messages.\n *\n * Messages are keyed PER CHECK. The spike's walker wrote `out.message = …` on\n * every check, so a field with min and max kept only the max message and\n * showed the wrong error for a too-short value. Here each check kind gets its\n * own key; a renderer maps a failed issue to its message by that key.\n *\n * Unknown check kinds (e.g. a per-field `.refine`, which is `custom`) are kept\n * as a message when they carry one and otherwise skipped — never fatal.\n */\n\nimport type { Constraints, Messages } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { checkMessage } from \"./internals\";\n\nexport function readChecks(node: ZodNode): { constraints: Constraints; messages: Messages } {\n const constraints: Constraints = {};\n const messages: Messages = {};\n\n for (const c of node._zod.def.checks ?? []) {\n const d = c._zod.def;\n const msg = checkMessage(d);\n let key: string | undefined;\n\n switch (d.check) {\n case \"min_length\":\n constraints.min = d.minimum;\n key = \"min_length\";\n break;\n case \"max_length\":\n constraints.max = d.maximum;\n key = \"max_length\";\n break;\n case \"length_equals\":\n constraints.exact = d.length;\n key = \"length_equals\";\n break;\n case \"greater_than\":\n constraints.min = d.inclusive ? d.value : (d.value ?? 0) + 1;\n key = \"greater_than\";\n break;\n case \"less_than\":\n constraints.max = d.inclusive ? d.value : (d.value ?? 0) - 1;\n key = \"less_than\";\n break;\n case \"string_format\":\n if (d.format === \"regex\" && d.pattern) {\n constraints.pattern = d.pattern.source;\n constraints.format = \"regex\";\n key = \"regex\";\n } else if (d.format === \"url\" || d.format === \"email\") {\n constraints.format = d.format;\n key = d.format;\n } else {\n key = d.format;\n }\n break;\n case \"number_format\":\n if (d.format === \"safeint\" || d.format === \"int32\") {\n constraints.format = \"int\";\n key = \"int\";\n }\n break;\n case \"custom\":\n key = \"custom\";\n break;\n default:\n key = d.check;\n }\n\n if (key && msg) messages[key] = msg;\n }\n\n return { constraints, messages };\n}\n","/**\n * Peel wrapper types off a field until the real type is reached.\n *\n * optional / nullable / default → the field is not required.\n * pipe → follow `out` (older 4.x wrapped z.coerce.date in a pipe; 4.5 marks\n * the date itself with `coerce: true` — both land on the same node here).\n */\n\nimport type { ZodNode } from \"./internals\";\n\nexport interface Unwrapped {\n node: ZodNode;\n type: string;\n required: boolean;\n}\n\nexport function unwrap(start: ZodNode): Unwrapped {\n let node = start;\n let required = true;\n // Bounded so a malformed schema can't loop forever.\n for (let i = 0; i < 16; i++) {\n const def = node._zod.def;\n if (def.type === \"optional\" || def.type === \"nullable\" || def.type === \"default\") {\n required = false;\n if (!def.innerType) break;\n node = def.innerType;\n } else if (def.type === \"pipe\") {\n const next = def.out ?? def.in;\n if (!next) break;\n node = next;\n } else {\n break;\n }\n }\n return { node, type: node._zod.def.type, required };\n}\n","/**\n * zod type → InputKind, plus the extras some kinds carry (enum options, the\n * array item's constraints).\n *\n * Long strings become textareas by a simple rule: a max over 120 chars. That\n * is a heuristic, and the registry can't override it today — if a site needs\n * to, that is a one-line change here, not a per-site branch.\n */\n\nimport type { Constraints, InputKind, Messages } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { readChecks } from \"./checks\";\nimport { unwrap } from \"./unwrap\";\n\nconst TEXTAREA_MIN_MAX = 120;\n\nexport interface InputInfo {\n input: InputKind;\n constraints: Constraints;\n messages: Messages;\n options?: string[];\n}\n\nexport function inputFor(node: ZodNode): InputInfo {\n const def = node._zod.def;\n const { constraints, messages } = readChecks(node);\n\n switch (def.type) {\n case \"string\": {\n if (constraints.format === \"url\") return { input: \"url\", constraints, messages };\n const long = (constraints.max ?? 0) > TEXTAREA_MIN_MAX;\n return { input: long ? \"textarea\" : \"text\", constraints, messages };\n }\n case \"date\":\n return { input: \"date\", constraints, messages };\n case \"number\":\n case \"int\":\n return { input: \"number\", constraints, messages };\n case \"boolean\":\n return { input: \"boolean\", constraints, messages };\n case \"enum\":\n case \"literal\": {\n const options = Object.values(def.entries ?? {}).map(String);\n return { input: \"select\", constraints, messages, options };\n }\n case \"array\": {\n if (def.element) {\n const item = unwrap(def.element);\n const inner = readChecks(item.node);\n constraints.item = inner;\n }\n return { input: \"tags\", constraints, messages };\n }\n default:\n // Anything unrecognised (object, union, …) is presented as text so the\n // value can at least be carried; a renderer may choose to treat it as hidden.\n return { input: \"text\", constraints, messages };\n }\n}\n","/**\n * Labels and placeholders.\n *\n * Precedence (decided 2026-09-08):\n * label: registry.labels[name] → .meta({ label }) → .describe() → titlecase(name)\n * placeholder: registry.placeholders[name] → .meta({ placeholder }) → undefined\n *\n * The registry tier exists for schemas that can't be edited yet (5degrees\n * until its repo transfer). The meta tier is the intended home — one source of\n * truth beside the validation rules. Titlecase is the floor, and it is naive on\n * purpose: an acronym coming out as \"Rsvp url\" is the signal that a real label\n * is missing.\n *\n * Meta is read from zod's global registry via the schema's own `meta()` /\n * `description` accessors, so no zod value is imported here.\n */\n\nimport type { ContentTypeEntry, InputKind } from \"./types\";\n\ninterface MetaBearing {\n meta?: () => Record<string, unknown> | undefined;\n description?: string;\n}\n\ninterface FieldMeta {\n label?: string;\n placeholder?: string;\n description?: string;\n recommended?: [number, number];\n suffix?: string;\n help?: string;\n input?: InputKind;\n}\n\nexport function readMeta(schema: unknown): FieldMeta {\n const s = schema as MetaBearing;\n const raw = typeof s.meta === \"function\" ? (s.meta() ?? {}) : {};\n const pick = (k: keyof FieldMeta) => (typeof raw[k] === \"string\" ? (raw[k] as string) : undefined);\n const rec = raw.recommended;\n const recommended =\n Array.isArray(rec) && rec.length === 2 && rec.every((n) => typeof n === \"number\") ? ([rec[0], rec[1]] as [number, number]) : undefined;\n const INPUTS: InputKind[] = [\"text\", \"textarea\", \"date\", \"number\", \"boolean\", \"select\", \"tags\", \"image\", \"url\", \"time\"];\n const input = typeof raw.input === \"string\" && (INPUTS as string[]).includes(raw.input) ? (raw.input as InputKind) : undefined;\n return {\n label: pick(\"label\"),\n placeholder: pick(\"placeholder\"),\n description: pick(\"description\") ?? (typeof s.description === \"string\" ? s.description : undefined),\n recommended,\n suffix: pick(\"suffix\"),\n help: pick(\"help\"),\n input,\n };\n}\n\nexport function inputOverrideFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"inputs\">,\n): InputKind | undefined {\n return entry?.inputs?.[name] ?? readMeta(schema).input;\n}\n\nexport function recommendedFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"recommended\">,\n): [number, number] | undefined {\n return entry?.recommended?.[name] ?? readMeta(schema).recommended;\n}\n\nexport function titlecase(name: string): string {\n const words = name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[_-]+/g, \" \")\n .toLowerCase()\n .trim();\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\nexport function labelFor(name: string, schema: unknown, entry?: Pick<ContentTypeEntry, \"labels\">): string {\n const fromRegistry = entry?.labels?.[name];\n if (fromRegistry) return fromRegistry;\n const meta = readMeta(schema);\n return meta.label ?? meta.description ?? titlecase(name);\n}\n\nexport function placeholderFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"placeholders\">,\n): string | undefined {\n return entry?.placeholders?.[name] ?? readMeta(schema).placeholder;\n}\n\nexport function helpFor(name: string, schema: unknown, entry?: Pick<ContentTypeEntry, \"help\">): string | undefined {\n return entry?.help?.[name] ?? readMeta(schema).help;\n}\n","/**\n * walkSchema — a zod object schema (+ optional registry entry) → FieldSpec[].\n *\n * Synchronous and pure. Reads the schema's shape and checks; never parses a\n * value, never calls an options resolver, never imports zod at runtime.\n *\n * Roles from the registry override the schema-derived input kind: a field the\n * entry names as an image is `role: \"image\"` even though zod sees a string.\n * Hidden fields are still emitted so a renderer can carry their values through.\n */\n\nimport type { ContentTypeEntry, FieldRole, FieldSpec } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { asNode } from \"./internals\";\nimport { inputFor } from \"./inputs\";\nimport { helpFor, inputOverrideFor, labelFor, placeholderFor, readMeta, recommendedFor } from \"./labels\";\nimport { unwrap } from \"./unwrap\";\n\ntype Entry = Partial<Omit<ContentTypeEntry, \"schema\" | \"filename\" | \"id\" | \"label\" | \"folder\">>;\n\nexport function walkSchema(schema: unknown, entry: Entry = {}): FieldSpec[] {\n const root = asNode(schema);\n const shape = shapeOf(root);\n const names = Object.keys(shape);\n\n const specs = names.map((name): FieldSpec => {\n const raw = shape[name];\n const { node, required } = unwrap(raw);\n const info = inputFor(node);\n const role = roleFor(name, entry);\n\n return {\n name,\n label: labelFor(name, raw, entry),\n input: role === \"image\" ? \"image\" : (inputOverrideFor(name, raw, entry) ?? info.input),\n required,\n constraints: info.constraints,\n messages: info.messages,\n placeholder: placeholderFor(name, raw, entry),\n recommended: recommendedFor(name, raw, entry),\n suffix: readMeta(raw).suffix,\n help: helpFor(name, raw, entry),\n order: 0,\n role,\n options: entry.options?.[name] ?? info.options,\n };\n });\n\n return applyOrder(specs, entry.order ?? []);\n}\n\n/** `.strict()` and object-level `.refine()` both leave `shape` on the object def. */\nfunction shapeOf(root: ZodNode): Record<string, ZodNode> {\n let node = root;\n for (let i = 0; i < 8 && !node._zod.def.shape; i++) {\n const def = node._zod.def;\n const next = def.innerType ?? def.in;\n if (!next) break;\n node = next;\n }\n const shape = node._zod.def.shape;\n if (!shape) throw new TypeError(`walkSchema: expected an object schema, got \"${root._zod.def.type}\"`);\n return shape;\n}\n\nfunction roleFor(name: string, entry: Entry): FieldRole {\n if (entry.hidden?.includes(name)) return \"hidden\";\n if (entry.body === name) return \"body\";\n if (entry.images?.includes(name)) return \"image\";\n return \"field\";\n}\n\n/** Named fields first in the given order; the rest keep schema key order. */\nfunction applyOrder(specs: FieldSpec[], order: string[]): FieldSpec[] {\n const rank = new Map(order.map((n, i) => [n, i]));\n const named = specs.filter((s) => rank.has(s.name)).sort((a, b) => rank.get(a.name)! - rank.get(b.name)!);\n const rest = specs.filter((s) => !rank.has(s.name));\n return [...named, ...rest].map((s, i) => ({ ...s, order: i }));\n}\n","/**\n * defineContentType — validate a registry entry against the schema it describes.\n *\n * Validation is hand-rolled rather than a zod schema on purpose: this module\n * must not import zod at runtime (the host's instance is the only one that\n * should exist). The checks are small and the errors name the bad key.\n */\n\nimport type { ZodType } from \"zod\";\nimport type { ContentTypeEntry } from \"./types\";\nimport { asNode } from \"./internals\";\n\nexport function defineContentType<S extends ZodType>(entry: ContentTypeEntry<S>): ContentTypeEntry<S> {\n const where = `defineContentType(\"${entry.id}\")`;\n\n for (const key of [\"id\", \"label\", \"folder\"] as const) {\n if (typeof entry[key] !== \"string\" || entry[key].length === 0) {\n throw new TypeError(`${where}: \"${key}\" must be a non-empty string`);\n }\n }\n if (typeof entry.filename !== \"function\") {\n throw new TypeError(`${where}: \"filename\" must be a function (frontmatter) => string`);\n }\n if (entry.slugFromFilename !== undefined && typeof entry.slugFromFilename !== \"function\") {\n throw new TypeError(`${where}: \"slugFromFilename\" must be a function (fileName) => string | null`);\n }\n if (entry.body !== null && typeof entry.body !== \"string\") {\n throw new TypeError(`${where}: \"body\" must be a field name or null`);\n }\n\n const root = asNode(entry.schema, `${where}: schema`);\n const shape = findShape(root);\n const known = new Set(Object.keys(shape));\n\n const check = (list: string[] | undefined, key: string) => {\n for (const name of list ?? []) {\n if (!known.has(name)) throw new TypeError(`${where}: ${key} names \"${name}\", which is not a field of the schema`);\n }\n };\n\n if (entry.body !== null) check([entry.body], \"body\");\n check(entry.images, \"images\");\n check(entry.order, \"order\");\n check(entry.hidden, \"hidden\");\n check(Object.keys(entry.labels ?? {}), \"labels\");\n check(Object.keys(entry.placeholders ?? {}), \"placeholders\");\n check(Object.keys(entry.recommended ?? {}), \"recommended\");\n check(Object.keys(entry.inputs ?? {}), \"inputs\");\n check(Object.keys(entry.help ?? {}), \"help\");\n check(Object.keys(entry.options ?? {}), \"options\");\n for (const g of entry.groups ?? []) {\n if (typeof g.label !== \"string\" || g.label.length === 0) throw new TypeError(`${where}: every group needs a label`);\n check(g.fields, `groups[\"${g.label}\"]`);\n }\n\n return entry;\n}\n\nfunction findShape(root: ReturnType<typeof asNode>): Record<string, unknown> {\n let node = root;\n for (let i = 0; i < 8 && !node._zod.def.shape; i++) {\n const next = node._zod.def.innerType ?? node._zod.def.in;\n if (!next) break;\n node = next;\n }\n if (!node._zod.def.shape) throw new TypeError(\"defineContentType: schema must be a zod object\");\n return node._zod.def.shape;\n}\n","/**\n * navFromContentTypes — the sidebar derives from the registry.\n *\n * Adding a content type to a site (one defineContentType entry) puts it in\n * the nav with no shell change. Pure; lives in /forms so the server layout\n * can compute it without importing the client bundle.\n */\n\nimport type { ContentTypeEntry } from \"./types\";\n\nexport interface NavEntry {\n id: string;\n label: string;\n href: string;\n icon: string;\n}\n\nexport function navFromContentTypes(\n entries: Record<string, ContentTypeEntry> | ContentTypeEntry[],\n opts: { basePath?: string } = {},\n): NavEntry[] {\n const base = (opts.basePath ?? \"/admin\").replace(/\\/+$/, \"\");\n const list = Array.isArray(entries) ? entries : Object.values(entries);\n return list.map((e) => ({ id: e.id, label: e.label, href: `${base}/${e.id}`, icon: e.id }));\n}\n"]}
1
+ {"version":3,"sources":["../../src/forms/internals.ts","../../src/forms/checks.ts","../../src/forms/unwrap.ts","../../src/forms/inputs.ts","../../src/forms/labels.ts","../../src/forms/walk.ts","../../src/forms/registry.ts","../../src/forms/nav.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The slice of zod 4's `_zod.def` surface this module reads, typed loosely.\n *\n * Tested against zod 4.5.4. These are semi-public internals (the v4 \"core\"\n * shape), stable across 4.x so far but not covered by semver promises — hence\n * the peer-dep range and the fixture tests. No zod value is imported here.\n */\n\nexport interface ZodCheckDef {\n check?: string;\n format?: string;\n minimum?: number;\n maximum?: number;\n length?: number;\n value?: number;\n inclusive?: boolean;\n pattern?: RegExp;\n error?: string | ((issue: unknown) => string | { message?: string } | undefined);\n}\n\nexport interface ZodDef {\n type: string;\n shape?: Record<string, ZodNode>;\n innerType?: ZodNode;\n in?: ZodNode;\n out?: ZodNode;\n element?: ZodNode;\n entries?: Record<string, string | number>;\n checks?: Array<{ _zod: { def: ZodCheckDef } }>;\n coerce?: boolean;\n}\n\nexport interface ZodNode {\n _zod: { def: ZodDef };\n description?: string;\n}\n\n/** Narrow an unknown schema to the internal node shape, or throw a clear error. */\nexport function asNode(schema: unknown, what = \"schema\"): ZodNode {\n const n = schema as Partial<ZodNode> | null;\n if (!n || typeof n !== \"object\" || !n._zod?.def?.type) {\n throw new TypeError(`walkSchema: ${what} is not a zod 4 schema`);\n }\n return n as ZodNode;\n}\n\n/** Resolve a check's error to a plain string, if it has one. */\nexport function checkMessage(def: ZodCheckDef): string | undefined {\n const e = def.error;\n if (!e) return undefined;\n if (typeof e === \"string\") return e;\n const out = e({});\n if (typeof out === \"string\") return out;\n return out?.message;\n}\n","/**\n * checks[] → constraints + messages.\n *\n * Messages are keyed PER CHECK. The spike's walker wrote `out.message = …` on\n * every check, so a field with min and max kept only the max message and\n * showed the wrong error for a too-short value. Here each check kind gets its\n * own key; a renderer maps a failed issue to its message by that key.\n *\n * Unknown check kinds (e.g. a per-field `.refine`, which is `custom`) are kept\n * as a message when they carry one and otherwise skipped — never fatal.\n */\n\nimport type { Constraints, Messages } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { checkMessage } from \"./internals\";\n\nexport function readChecks(node: ZodNode): { constraints: Constraints; messages: Messages } {\n const constraints: Constraints = {};\n const messages: Messages = {};\n\n for (const c of node._zod.def.checks ?? []) {\n const d = c._zod.def;\n const msg = checkMessage(d);\n let key: string | undefined;\n\n switch (d.check) {\n case \"min_length\":\n constraints.min = d.minimum;\n key = \"min_length\";\n break;\n case \"max_length\":\n constraints.max = d.maximum;\n key = \"max_length\";\n break;\n case \"length_equals\":\n constraints.exact = d.length;\n key = \"length_equals\";\n break;\n case \"greater_than\":\n constraints.min = d.inclusive ? d.value : (d.value ?? 0) + 1;\n key = \"greater_than\";\n break;\n case \"less_than\":\n constraints.max = d.inclusive ? d.value : (d.value ?? 0) - 1;\n key = \"less_than\";\n break;\n case \"string_format\":\n if (d.format === \"regex\" && d.pattern) {\n constraints.pattern = d.pattern.source;\n constraints.format = \"regex\";\n key = \"regex\";\n } else if (d.format === \"url\" || d.format === \"email\") {\n constraints.format = d.format;\n key = d.format;\n } else {\n key = d.format;\n }\n break;\n case \"number_format\":\n if (d.format === \"safeint\" || d.format === \"int32\") {\n constraints.format = \"int\";\n key = \"int\";\n }\n break;\n case \"custom\":\n key = \"custom\";\n break;\n default:\n key = d.check;\n }\n\n if (key && msg) messages[key] = msg;\n }\n\n return { constraints, messages };\n}\n","/**\n * Peel wrapper types off a field until the real type is reached.\n *\n * optional / nullable / default → the field is not required.\n * pipe → follow `out` (older 4.x wrapped z.coerce.date in a pipe; 4.5 marks\n * the date itself with `coerce: true` — both land on the same node here).\n */\n\nimport type { ZodNode } from \"./internals\";\n\nexport interface Unwrapped {\n node: ZodNode;\n type: string;\n required: boolean;\n}\n\nexport function unwrap(start: ZodNode): Unwrapped {\n let node = start;\n let required = true;\n // Bounded so a malformed schema can't loop forever.\n for (let i = 0; i < 16; i++) {\n const def = node._zod.def;\n if (def.type === \"optional\" || def.type === \"nullable\" || def.type === \"default\") {\n required = false;\n if (!def.innerType) break;\n node = def.innerType;\n } else if (def.type === \"pipe\") {\n const next = def.out ?? def.in;\n if (!next) break;\n node = next;\n } else {\n break;\n }\n }\n return { node, type: node._zod.def.type, required };\n}\n","/**\n * zod type → InputKind, plus the extras some kinds carry (enum options, the\n * array item's constraints).\n *\n * Long strings become textareas by a simple rule: a max over 120 chars. That\n * is a heuristic, and the registry can't override it today — if a site needs\n * to, that is a one-line change here, not a per-site branch.\n */\n\nimport type { Constraints, InputKind, Messages } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { readChecks } from \"./checks\";\nimport { unwrap } from \"./unwrap\";\n\nconst TEXTAREA_MIN_MAX = 120;\n\nexport interface InputInfo {\n input: InputKind;\n constraints: Constraints;\n messages: Messages;\n options?: string[];\n}\n\nexport function inputFor(node: ZodNode): InputInfo {\n const def = node._zod.def;\n const { constraints, messages } = readChecks(node);\n\n switch (def.type) {\n case \"string\": {\n if (constraints.format === \"url\") return { input: \"url\", constraints, messages };\n const long = (constraints.max ?? 0) > TEXTAREA_MIN_MAX;\n return { input: long ? \"textarea\" : \"text\", constraints, messages };\n }\n case \"date\":\n return { input: \"date\", constraints, messages };\n case \"number\":\n case \"int\":\n return { input: \"number\", constraints, messages };\n case \"boolean\":\n return { input: \"boolean\", constraints, messages };\n case \"enum\":\n case \"literal\": {\n const options = Object.values(def.entries ?? {}).map(String);\n return { input: \"select\", constraints, messages, options };\n }\n case \"array\": {\n if (def.element) {\n const item = unwrap(def.element);\n const inner = readChecks(item.node);\n constraints.item = inner;\n }\n return { input: \"tags\", constraints, messages };\n }\n default:\n // Anything unrecognised (object, union, …) is presented as text so the\n // value can at least be carried; a renderer may choose to treat it as hidden.\n return { input: \"text\", constraints, messages };\n }\n}\n","/**\n * Labels and placeholders.\n *\n * Precedence (decided 2026-09-08):\n * label: registry.labels[name] → .meta({ label }) → .describe() → titlecase(name)\n * placeholder: registry.placeholders[name] → .meta({ placeholder }) → undefined\n *\n * The registry tier exists for schemas that can't be edited yet (5degrees\n * until its repo transfer). The meta tier is the intended home — one source of\n * truth beside the validation rules. Titlecase is the floor, and it is naive on\n * purpose: an acronym coming out as \"Rsvp url\" is the signal that a real label\n * is missing.\n *\n * Meta is read from zod's global registry via the schema's own `meta()` /\n * `description` accessors, so no zod value is imported here.\n */\n\nimport type { ContentTypeEntry, InputKind } from \"./types\";\n\ninterface MetaBearing {\n meta?: () => Record<string, unknown> | undefined;\n description?: string;\n}\n\ninterface FieldMeta {\n label?: string;\n placeholder?: string;\n description?: string;\n recommended?: [number, number];\n suffix?: string;\n help?: string;\n input?: InputKind;\n}\n\nexport function readMeta(schema: unknown): FieldMeta {\n const s = schema as MetaBearing;\n const raw = typeof s.meta === \"function\" ? (s.meta() ?? {}) : {};\n const pick = (k: keyof FieldMeta) => (typeof raw[k] === \"string\" ? (raw[k] as string) : undefined);\n const rec = raw.recommended;\n const recommended =\n Array.isArray(rec) && rec.length === 2 && rec.every((n) => typeof n === \"number\") ? ([rec[0], rec[1]] as [number, number]) : undefined;\n const INPUTS: InputKind[] = [\"text\", \"textarea\", \"date\", \"number\", \"boolean\", \"select\", \"tags\", \"image\", \"url\", \"time\"];\n const input = typeof raw.input === \"string\" && (INPUTS as string[]).includes(raw.input) ? (raw.input as InputKind) : undefined;\n return {\n label: pick(\"label\"),\n placeholder: pick(\"placeholder\"),\n description: pick(\"description\") ?? (typeof s.description === \"string\" ? s.description : undefined),\n recommended,\n suffix: pick(\"suffix\"),\n help: pick(\"help\"),\n input,\n };\n}\n\nexport function inputOverrideFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"inputs\">,\n): InputKind | undefined {\n return entry?.inputs?.[name] ?? readMeta(schema).input;\n}\n\nexport function recommendedFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"recommended\">,\n): [number, number] | undefined {\n return entry?.recommended?.[name] ?? readMeta(schema).recommended;\n}\n\nexport function titlecase(name: string): string {\n const words = name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[_-]+/g, \" \")\n .toLowerCase()\n .trim();\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\nexport function labelFor(name: string, schema: unknown, entry?: Pick<ContentTypeEntry, \"labels\">): string {\n const fromRegistry = entry?.labels?.[name];\n if (fromRegistry) return fromRegistry;\n const meta = readMeta(schema);\n return meta.label ?? meta.description ?? titlecase(name);\n}\n\nexport function placeholderFor(\n name: string,\n schema: unknown,\n entry?: Pick<ContentTypeEntry, \"placeholders\">,\n): string | undefined {\n return entry?.placeholders?.[name] ?? readMeta(schema).placeholder;\n}\n\nexport function helpFor(name: string, schema: unknown, entry?: Pick<ContentTypeEntry, \"help\">): string | undefined {\n return entry?.help?.[name] ?? readMeta(schema).help;\n}\n","/**\n * walkSchema — a zod object schema (+ optional registry entry) → FieldSpec[].\n *\n * Synchronous and pure. Reads the schema's shape and checks; never parses a\n * value, never calls an options resolver, never imports zod at runtime.\n *\n * Roles from the registry override the schema-derived input kind: a field the\n * entry names as an image is `role: \"image\"` even though zod sees a string.\n * Hidden fields are still emitted so a renderer can carry their values through.\n */\n\nimport type { ContentTypeEntry, FieldRole, FieldSpec } from \"./types\";\nimport type { ZodNode } from \"./internals\";\nimport { asNode } from \"./internals\";\nimport { inputFor } from \"./inputs\";\nimport { helpFor, inputOverrideFor, labelFor, placeholderFor, readMeta, recommendedFor } from \"./labels\";\nimport { unwrap } from \"./unwrap\";\n\ntype Entry = Partial<Omit<ContentTypeEntry, \"schema\" | \"filename\" | \"id\" | \"label\" | \"folder\">>;\n\nexport function walkSchema(schema: unknown, entry: Entry = {}): FieldSpec[] {\n const root = asNode(schema);\n const shape = shapeOf(root);\n const names = Object.keys(shape);\n\n const specs = names.map((name): FieldSpec => {\n const raw = shape[name];\n const { node, required } = unwrap(raw);\n const info = inputFor(node);\n const role = roleFor(name, entry);\n\n return {\n name,\n label: labelFor(name, raw, entry),\n input: role === \"image\" ? \"image\" : (inputOverrideFor(name, raw, entry) ?? info.input),\n required,\n constraints: info.constraints,\n messages: info.messages,\n placeholder: placeholderFor(name, raw, entry),\n recommended: recommendedFor(name, raw, entry),\n suffix: readMeta(raw).suffix,\n help: helpFor(name, raw, entry),\n order: 0,\n role,\n options: entry.options?.[name] ?? info.options,\n };\n });\n\n return applyOrder(specs, entry.order ?? []);\n}\n\n/** `.strict()` and object-level `.refine()` both leave `shape` on the object def. */\nfunction shapeOf(root: ZodNode): Record<string, ZodNode> {\n let node = root;\n for (let i = 0; i < 8 && !node._zod.def.shape; i++) {\n const def = node._zod.def;\n const next = def.innerType ?? def.in;\n if (!next) break;\n node = next;\n }\n const shape = node._zod.def.shape;\n if (!shape) throw new TypeError(`walkSchema: expected an object schema, got \"${root._zod.def.type}\"`);\n return shape;\n}\n\nfunction roleFor(name: string, entry: Entry): FieldRole {\n if (entry.hidden?.includes(name)) return \"hidden\";\n if (entry.body === name) return \"body\";\n if (entry.images?.includes(name)) return \"image\";\n return \"field\";\n}\n\n/** Named fields first in the given order; the rest keep schema key order. */\nfunction applyOrder(specs: FieldSpec[], order: string[]): FieldSpec[] {\n const rank = new Map(order.map((n, i) => [n, i]));\n const named = specs.filter((s) => rank.has(s.name)).sort((a, b) => rank.get(a.name)! - rank.get(b.name)!);\n const rest = specs.filter((s) => !rank.has(s.name));\n return [...named, ...rest].map((s, i) => ({ ...s, order: i }));\n}\n","/**\n * defineContentType — validate a registry entry against the schema it describes.\n *\n * Validation is hand-rolled rather than a zod schema on purpose: this module\n * must not import zod at runtime (the host's instance is the only one that\n * should exist). The checks are small and the errors name the bad key.\n */\n\nimport type { ZodType } from \"zod\";\nimport type { ContentTypeEntry } from \"./types\";\nimport { asNode } from \"./internals\";\n\nexport function defineContentType<S extends ZodType>(entry: ContentTypeEntry<S>): ContentTypeEntry<S> {\n const where = `defineContentType(\"${entry.id}\")`;\n\n for (const key of [\"id\", \"label\", \"folder\"] as const) {\n if (typeof entry[key] !== \"string\" || entry[key].length === 0) {\n throw new TypeError(`${where}: \"${key}\" must be a non-empty string`);\n }\n }\n if (typeof entry.filename !== \"function\") {\n throw new TypeError(`${where}: \"filename\" must be a function (frontmatter) => string`);\n }\n if (entry.slugFromFilename !== undefined && typeof entry.slugFromFilename !== \"function\") {\n throw new TypeError(`${where}: \"slugFromFilename\" must be a function (fileName) => string | null`);\n }\n if (entry.body !== null && typeof entry.body !== \"string\") {\n throw new TypeError(`${where}: \"body\" must be a field name or null`);\n }\n\n const root = asNode(entry.schema, `${where}: schema`);\n const shape = findShape(root);\n const known = new Set(Object.keys(shape));\n\n const check = (list: string[] | undefined, key: string) => {\n for (const name of list ?? []) {\n if (!known.has(name)) throw new TypeError(`${where}: ${key} names \"${name}\", which is not a field of the schema`);\n }\n };\n\n if (entry.body !== null) check([entry.body], \"body\");\n check(entry.images, \"images\");\n check(entry.order, \"order\");\n check(entry.hidden, \"hidden\");\n check(Object.keys(entry.labels ?? {}), \"labels\");\n check(Object.keys(entry.placeholders ?? {}), \"placeholders\");\n check(Object.keys(entry.recommended ?? {}), \"recommended\");\n check(Object.keys(entry.inputs ?? {}), \"inputs\");\n check(Object.keys(entry.help ?? {}), \"help\");\n check(Object.keys(entry.options ?? {}), \"options\");\n for (const g of entry.groups ?? []) {\n if (typeof g.label !== \"string\" || g.label.length === 0) throw new TypeError(`${where}: every group needs a label`);\n check(g.fields, `groups[\"${g.label}\"]`);\n }\n\n return entry;\n}\n\nfunction findShape(root: ReturnType<typeof asNode>): Record<string, unknown> {\n let node = root;\n for (let i = 0; i < 8 && !node._zod.def.shape; i++) {\n const next = node._zod.def.innerType ?? node._zod.def.in;\n if (!next) break;\n node = next;\n }\n if (!node._zod.def.shape) throw new TypeError(\"defineContentType: schema must be a zod object\");\n return node._zod.def.shape;\n}\n","/**\n * navFromContentTypes — the sidebar derives from the registry.\n *\n * Adding a content type to a site (one defineContentType entry) puts it in\n * the nav with no shell change. Pure; lives in /forms so the server layout\n * can compute it without importing the client bundle.\n */\n\nimport type { ContentTypeEntry } from \"./types\";\n\nexport interface NavEntry {\n id: string;\n label: string;\n href: string;\n icon: string;\n}\n\nexport function navFromContentTypes(\n entries: Record<string, ContentTypeEntry> | ContentTypeEntry[],\n opts: { basePath?: string } = {},\n): NavEntry[] {\n const base = (opts.basePath ?? \"/admin\").replace(/\\/+$/, \"\");\n const list = Array.isArray(entries) ? entries : Object.values(entries);\n return list.map((e) => ({ id: e.id, label: e.label, href: `${base}/${e.id}`, icon: e.icon ?? e.id }));\n}\n"]}