From 3dce6a6608a4745cbf05670dbb57f2312f950acc Mon Sep 17 00:00:00 2001 From: adamelmore <2363879+adamdottv@users.noreply.github.com> Date: Mon, 26 Jan 2026 09:53:03 -0600 Subject: [PATCH] chore: gen changelog page off changelog json --- .../console/app/src/routes/changelog.json.ts | 14 +- .../app/src/routes/changelog/index.tsx | 134 +++++------------- 2 files changed, 42 insertions(+), 106 deletions(-) diff --git a/packages/console/app/src/routes/changelog.json.ts b/packages/console/app/src/routes/changelog.json.ts index a9667ac6d..9e3b75e5c 100644 --- a/packages/console/app/src/routes/changelog.json.ts +++ b/packages/console/app/src/routes/changelog.json.ts @@ -98,19 +98,23 @@ export async function GET() { cacheTtl: 60 * 5, cacheEverything: true, }, - } as any) + } as any).catch(() => undefined) - if (!response.ok) { - return new Response(JSON.stringify({ releases: [] }), { + const fail = () => + new Response(JSON.stringify({ releases: [] }), { status: 503, headers: { "Content-Type": "application/json", "Cache-Control": error, }, }) - } - const releases = (await response.json()) as Release[] + if (!response?.ok) return fail() + + const data = await response.json().catch(() => undefined) + if (!Array.isArray(data)) return fail() + + const releases = data as Release[] return new Response( JSON.stringify({ diff --git a/packages/console/app/src/routes/changelog/index.tsx b/packages/console/app/src/routes/changelog/index.tsx index 87e021ec8..e05ad42e6 100644 --- a/packages/console/app/src/routes/changelog/index.tsx +++ b/packages/console/app/src/routes/changelog/index.tsx @@ -1,44 +1,12 @@ import "./index.css" import { Title, Meta, Link } from "@solidjs/meta" -import { createAsync, query } from "@solidjs/router" +import { createAsync } from "@solidjs/router" import { Header } from "~/component/header" import { Footer } from "~/component/footer" import { Legal } from "~/component/legal" import { config } from "~/config" import { For, Show, createSignal } from "solid-js" - -type Release = { - tag_name: string - name: string - body: string - published_at: string - html_url: string -} - -const getReleases = query(async () => { - "use server" - const response = await fetch("https://api.github.com/repos/anomalyco/opencode/releases?per_page=20", { - headers: { - Accept: "application/vnd.github.v3+json", - "User-Agent": "OpenCode-Console", - }, - cf: { - cacheTtl: 60 * 5, - cacheEverything: true, - }, - } as any) - if (!response.ok) return [] - return response.json() as Promise -}, "releases.get") - -function formatDate(dateString: string) { - const date = new Date(dateString) - return date.toLocaleDateString("en-US", { - year: "numeric", - month: "short", - day: "numeric", - }) -} +import { getRequestEvent } from "solid-js/web" type HighlightMedia = { type: "video"; src: string } | { type: "image"; src: string; width: string; height: string } @@ -54,68 +22,33 @@ type HighlightGroup = { items: HighlightItem[] } -function parseHighlights(body: string): HighlightGroup[] { - const groups = new Map() - const regex = /([\s\S]*?)<\/highlight>/g - let match - - while ((match = regex.exec(body)) !== null) { - const source = match[1] - const content = match[2] - - const titleMatch = content.match(/

([^<]+)<\/h2>/) - const pMatch = content.match(/([^<]+)<\/p>/) - const imgMatch = content.match(/ ({ source, items })) +type ChangelogRelease = { + tag: string + name: string + date: string + url: string + highlights: HighlightGroup[] + sections: { title: string; items: string[] }[] } -function parseMarkdown(body: string) { - const lines = body.split("\n") - const sections: { title: string; items: string[] }[] = [] - let current: { title: string; items: string[] } | null = null - let skip = false +async function getReleases() { + const event = getRequestEvent() + const url = event ? new URL("/changelog.json", event.request.url).toString() : "/changelog.json" - for (const line of lines) { - if (line.startsWith("## ")) { - if (current) sections.push(current) - const title = line.slice(3).trim() - current = { title, items: [] } - skip = false - } else if (line.startsWith("**Thank you")) { - skip = true - } else if (line.startsWith("- ") && !skip) { - current?.items.push(line.slice(2).trim()) - } - } - if (current) sections.push(current) + const response = await fetch(url).catch(() => undefined) + if (!response?.ok) return [] - const highlights = parseHighlights(body) + const json = await response.json().catch(() => undefined) + return Array.isArray(json?.releases) ? (json.releases as ChangelogRelease[]) : [] +} - return { sections, highlights } +function formatDate(dateString: string) { + const date = new Date(dateString) + return date.toLocaleDateString("en-US", { + year: "numeric", + month: "short", + day: "numeric", + }) } function ReleaseItem(props: { item: string }) { @@ -217,28 +150,27 @@ export default function Changelog() {
{(release) => { - const parsed = () => parseMarkdown(release.body || "") return (
- +
- 0}> + 0}>
- {(group) => } + {(group) => }
- 0 && parsed().sections.length > 0}> - + 0 && release.sections.length > 0}> + - - + + {(section) => (

{section.title}