feat(stats): route stats app

This commit is contained in:
Adam
2026-05-28 18:37:13 -05:00
parent 0d67d659fc
commit 58da1ea48e
9 changed files with 62 additions and 16 deletions
+10 -9
View File
@@ -1,4 +1,5 @@
import { lakeAthenaWorkgroup, lakeCatalog, lakeCluster, lakeQueryPermissions, lakeRegion, tableBucket } from "./lake" import { lakeAthenaWorkgroup, lakeCatalog, lakeCluster, lakeQueryPermissions, lakeRegion, tableBucket } from "./lake"
import { EMAILOCTOPUS_API_KEY } from "./app"
const domain = (() => { const domain = (() => {
if ($app.stage === "production") return "stats.opencode.ai" if ($app.stage === "production") return "stats.opencode.ai"
@@ -163,15 +164,15 @@ new sst.x.DevCommand("StatsStudio", {
// APP // APP
//////////////// ////////////////
// export const app = new sst.cloudflare.x.SolidStart("Stats", { export const app = new sst.cloudflare.x.SolidStart("Stats", {
// path: "packages/stats/app", path: "packages/stats/app",
// buildCommand: "bun run build", buildCommand: "bun run build",
// domain, domain,
// link: [database], link: [database, EMAILOCTOPUS_API_KEY],
// environment: { environment: {
// PUBLIC_URL: `https://${domain}`, PUBLIC_URL: `https://${domain}/stats`,
// }, },
// }) })
//////////////// ////////////////
// SERVICES // SERVICES
@@ -0,0 +1,22 @@
import type { APIEvent } from "@solidjs/start/server"
import { Resource } from "@opencode-ai/console-resource"
async function handler(evt: APIEvent) {
const req = evt.request.clone()
const url = new URL(req.url)
const host = Resource.App.stage === "production" ? "stats.opencode.ai" : "stats.dev.opencode.ai"
const targetUrl = `https://${host}${url.pathname}${url.search}`
return fetch(targetUrl, {
method: req.method,
headers: req.headers,
body: req.body,
})
}
export const GET = handler
export const POST = handler
export const PUT = handler
export const DELETE = handler
export const OPTIONS = handler
export const PATCH = handler
@@ -0,0 +1,22 @@
import type { APIEvent } from "@solidjs/start/server"
import { Resource } from "@opencode-ai/console-resource"
async function handler(evt: APIEvent) {
const req = evt.request.clone()
const url = new URL(req.url)
const host = Resource.App.stage === "production" ? "stats.opencode.ai" : "stats.dev.opencode.ai"
const targetUrl = `https://${host}${url.pathname}${url.search}`
return fetch(targetUrl, {
method: req.method,
headers: req.headers,
body: req.body,
})
}
export const GET = handler
export const POST = handler
export const PUT = handler
export const DELETE = handler
export const OPTIONS = handler
export const PATCH = handler
+1
View File
@@ -16,6 +16,7 @@ function AppMeta() {
export default function App() { export default function App() {
return ( return (
<Router <Router
base={import.meta.env.BASE_URL.replace(/\/$/, "")}
explicitLinks={true} explicitLinks={true}
root={(props) => ( root={(props) => (
<MetaProvider> <MetaProvider>
+2 -2
View File
@@ -1213,7 +1213,7 @@ function Header() {
return ( return (
<header data-component="top" data-menu-open={menuOpen() ? "true" : undefined}> <header data-component="top" data-menu-open={menuOpen() ? "true" : undefined}>
<div data-slot="header-bar"> <div data-slot="header-bar">
<a data-slot="brand" href="/" aria-label="OpenCode home"> <a data-slot="brand" href={import.meta.env.BASE_URL} aria-label="Stats home">
<StatsWordmark /> <StatsWordmark />
</a> </a>
<nav data-component="section-nav" aria-label="Stats sections"> <nav data-component="section-nav" aria-label="Stats sections">
@@ -1436,7 +1436,7 @@ function SubscribeModal(props: { onClose: () => void }) {
event.preventDefault() event.preventDefault()
setStatus("pending") setStatus("pending")
setMessage("") setMessage("")
fetch("/api/newsletter", { fetch(`${import.meta.env.BASE_URL}api/newsletter`, {
method: "POST", method: "POST",
body: new FormData(event.currentTarget), body: new FormData(event.currentTarget),
}).then( }).then(
@@ -0,0 +1 @@
export { GET } from "../../api/health"
@@ -0,0 +1 @@
export { POST } from "../../api/newsletter"
+1
View File
@@ -3,6 +3,7 @@ import { nitro } from "nitro/vite"
import { defineConfig, type PluginOption } from "vite" import { defineConfig, type PluginOption } from "vite"
export default defineConfig({ export default defineConfig({
base: "/stats/",
plugins: [ plugins: [
solidStart() as PluginOption, solidStart() as PluginOption,
nitro({ nitro({
+2 -5
View File
@@ -30,10 +30,7 @@ export default $config({
async run() { async run() {
const stage = await import("./infra/stage.js") const stage = await import("./infra/stage.js")
await import("./infra/app.js") await import("./infra/app.js")
if (stage.deployAws) { const stats = stage.deployAws ? await import("./infra/lake.js").then(() => import("./infra/stats.js")) : undefined
await import("./infra/lake.js")
await import("./infra/stats.js")
}
const { stat } = await import("./infra/console.js") const { stat } = await import("./infra/console.js")
await import("./infra/enterprise.js") await import("./infra/enterprise.js")
if ($app.stage === "production" || $app.stage === "vimtor") { if ($app.stage === "production" || $app.stage === "vimtor") {
@@ -42,7 +39,7 @@ export default $config({
return { return {
StatWorkerUrl: stat.url, StatWorkerUrl: stat.url,
// StatsUrl: stats.app.url, ...(stats ? { StatsUrl: stats.app.url } : {}),
AwsStage: stage.awsStage, AwsStage: stage.awsStage,
} }
}, },