diff --git a/infra/stats.ts b/infra/stats.ts index 67387ee5a..10a5fb20b 100644 --- a/infra/stats.ts +++ b/infra/stats.ts @@ -165,7 +165,7 @@ export const app = new sst.cloudflare.x.SolidStart("Stats", { domain: `stats.${domain}`, link: [database, EMAILOCTOPUS_API_KEY], environment: { - PUBLIC_URL: `https://${domain}/stats`, + PUBLIC_URL: `https://${domain}/data`, }, }) diff --git a/packages/console/app/src/lib/stats-proxy.ts b/packages/console/app/src/lib/stats-proxy.ts index c8c576ddc..7375170b0 100644 --- a/packages/console/app/src/lib/stats-proxy.ts +++ b/packages/console/app/src/lib/stats-proxy.ts @@ -1,6 +1,8 @@ import type { APIEvent } from "@solidjs/start/server" import { Resource } from "@opencode-ai/console-resource" +const dataPath = "/data" + export async function statsProxy(evt: APIEvent) { const req = evt.request.clone() const targetUrl = new URL(req.url) @@ -8,8 +10,8 @@ export async function statsProxy(evt: APIEvent) { targetUrl.hostname = Resource.App.stage === "production" ? "stats.opencode.ai" : "stats.dev.opencode.ai" targetUrl.port = "" - if (targetUrl.pathname.startsWith("/stats/_build/") || targetUrl.pathname === "/stats/banner.png") { - targetUrl.pathname = targetUrl.pathname.slice("/stats".length) + if (targetUrl.pathname.startsWith(`${dataPath}/_build/`) || targetUrl.pathname === `${dataPath}/banner.png`) { + targetUrl.pathname = targetUrl.pathname.slice(dataPath.length) } const response = await fetch(targetUrl, { @@ -32,6 +34,17 @@ export async function statsProxy(evt: APIEvent) { }) } -function rewriteStatsHtml(html: string) { - return html.replaceAll('"/_build/', '"/stats/_build/').replaceAll("'/_build/", "'/stats/_build/") +export function statsRedirect(evt: APIEvent) { + const url = new URL(evt.request.url) + url.pathname = `${dataPath}${url.pathname.slice("/stats".length)}` + return new Response(null, { + status: 308, + headers: { + Location: url.toString(), + }, + }) +} + +function rewriteStatsHtml(html: string) { + return html.replaceAll('"/_build/', `"${dataPath}/_build/`).replaceAll("'/_build/", `'${dataPath}/_build/`) } diff --git a/packages/console/app/src/routes/data/[...path].ts b/packages/console/app/src/routes/data/[...path].ts new file mode 100644 index 000000000..d1899215d --- /dev/null +++ b/packages/console/app/src/routes/data/[...path].ts @@ -0,0 +1,8 @@ +import { statsProxy } from "~/lib/stats-proxy" + +export const GET = statsProxy +export const POST = statsProxy +export const PUT = statsProxy +export const DELETE = statsProxy +export const OPTIONS = statsProxy +export const PATCH = statsProxy diff --git a/packages/console/app/src/routes/data/index.ts b/packages/console/app/src/routes/data/index.ts new file mode 100644 index 000000000..d1899215d --- /dev/null +++ b/packages/console/app/src/routes/data/index.ts @@ -0,0 +1,8 @@ +import { statsProxy } from "~/lib/stats-proxy" + +export const GET = statsProxy +export const POST = statsProxy +export const PUT = statsProxy +export const DELETE = statsProxy +export const OPTIONS = statsProxy +export const PATCH = statsProxy diff --git a/packages/console/app/src/routes/stats/[...path].ts b/packages/console/app/src/routes/stats/[...path].ts index d1899215d..4a387c039 100644 --- a/packages/console/app/src/routes/stats/[...path].ts +++ b/packages/console/app/src/routes/stats/[...path].ts @@ -1,8 +1,8 @@ -import { statsProxy } from "~/lib/stats-proxy" +import { statsRedirect } from "~/lib/stats-proxy" -export const GET = statsProxy -export const POST = statsProxy -export const PUT = statsProxy -export const DELETE = statsProxy -export const OPTIONS = statsProxy -export const PATCH = statsProxy +export const GET = statsRedirect +export const POST = statsRedirect +export const PUT = statsRedirect +export const DELETE = statsRedirect +export const OPTIONS = statsRedirect +export const PATCH = statsRedirect diff --git a/packages/console/app/src/routes/stats/index.ts b/packages/console/app/src/routes/stats/index.ts index d1899215d..4a387c039 100644 --- a/packages/console/app/src/routes/stats/index.ts +++ b/packages/console/app/src/routes/stats/index.ts @@ -1,8 +1,8 @@ -import { statsProxy } from "~/lib/stats-proxy" +import { statsRedirect } from "~/lib/stats-proxy" -export const GET = statsProxy -export const POST = statsProxy -export const PUT = statsProxy -export const DELETE = statsProxy -export const OPTIONS = statsProxy -export const PATCH = statsProxy +export const GET = statsRedirect +export const POST = statsRedirect +export const PUT = statsRedirect +export const DELETE = statsRedirect +export const OPTIONS = statsRedirect +export const PATCH = statsRedirect diff --git a/packages/stats/app/src/routes/index.tsx b/packages/stats/app/src/routes/index.tsx index cad1706bc..53d1bd154 100644 --- a/packages/stats/app/src/routes/index.tsx +++ b/packages/stats/app/src/routes/index.tsx @@ -50,7 +50,7 @@ const rangeLabels: Record = { } const statsHomeTitle = "OpenCode Stats" const statsHomeDescription = "OpenCode usage, market share, token cost, and session cost stats." -const statsHomeFallbackUrl = "https://opencode.ai/stats/" +const statsHomeFallbackUrl = "https://opencode.ai/data/" const statsUnfurlPath = "banner.png" const statsUnfurlAlt = "OpenCode Stats wordmark on a dark patterned background" const usageColors = [ @@ -184,8 +184,8 @@ export default function StatsHome() { function getStatsHomeUrl(base: string, requestUrl: string) { const url = new URL(base, requestUrl) - if (url.hostname === "stats.opencode.ai") return "https://opencode.ai/stats/" - if (url.hostname === "stats.dev.opencode.ai") return "https://dev.opencode.ai/stats/" + if (url.hostname === "stats.opencode.ai") return "https://opencode.ai/data/" + if (url.hostname === "stats.dev.opencode.ai") return "https://dev.opencode.ai/data/" return url.toString() } diff --git a/packages/stats/app/vite.config.ts b/packages/stats/app/vite.config.ts index adf384871..2c588e820 100644 --- a/packages/stats/app/vite.config.ts +++ b/packages/stats/app/vite.config.ts @@ -3,7 +3,7 @@ import { nitro } from "nitro/vite" import { defineConfig, type PluginOption } from "vite" export default defineConfig({ - base: "/stats/", + base: "/data/", plugins: [ solidStart() as PluginOption, nitro({