diff --git a/ogre/package.json b/ogre/package.json index 227cf709f..5b04a3ada 100644 --- a/ogre/package.json +++ b/ogre/package.json @@ -9,6 +9,7 @@ "scripts": { "dev": "wrangler dev", "deploy": "wrangler deploy", + "deploy:dev": "wrangler deploy --config wrangler.dev.jsonc", "typecheck": "tsc --noEmit", "test": "bun test", "knip": "knip" diff --git a/ogre/wrangler.dev.jsonc b/ogre/wrangler.dev.jsonc new file mode 100644 index 000000000..6266f16f6 --- /dev/null +++ b/ogre/wrangler.dev.jsonc @@ -0,0 +1,29 @@ +{ + "$schema": "node_modules/wrangler/config-schema.json", + "name": "ogre-dev", + "main": "src/index.tsx", + "account_id": "475a0795ff814187be629061103e5ba7", + "compatibility_date": "2026-03-07", + "observability": { + "enabled": true, + }, + "limits": { + "cpu_ms": 300000, + }, + "routes": [ + { + "pattern": "ogre-dev.tangled.network", + "custom_domain": true, + }, + ], + "vars": { + "ENVIRONMENT": "development", + }, + "rules": [ + { + "type": "Data", + "globs": ["**/*.wasm", "**/*.woff"], + "fallthrough": true, + }, + ], +} diff --git a/web/src/app.d.ts b/web/src/app.d.ts index a03311e76..a708f0d8a 100644 --- a/web/src/app.d.ts +++ b/web/src/app.d.ts @@ -12,6 +12,7 @@ declare global { camoEnabled: boolean; // when the server defers the diff fetch to the browser ssrDiffMaxBytes: number; + ogreUrl: string; }; } diff --git a/web/src/lib/seo/og.test.ts b/web/src/lib/seo/og.test.ts index 502c6a353..18d2f2580 100644 --- a/web/src/lib/seo/og.test.ts +++ b/web/src/lib/seo/og.test.ts @@ -5,7 +5,8 @@ describe("og card URL generation", () => { it("generates repository OG card URL with clean payload", () => { const url = repoCard( { name: "core", ownerHandle: "tangled.org", ownerDid: "did:plc:123" }, - { stars: 42, pulls: 5, issues: 12 } + { stars: 42, pulls: 5, issues: 12 }, + "https://ogre.tangled.network" ); expect(url).toContain("https://ogre.tangled.network/card?payload="); }); @@ -19,7 +20,8 @@ describe("og card URL generation", () => { state: "open", createdAt: "2026-03-01T00:00:00Z", author: { handle: "alice.tangled.org" } - } + }, + "https://ogre.tangled.network" ); expect(url).toContain("https://ogre.tangled.network/card?payload="); }); @@ -34,7 +36,8 @@ describe("og card URL generation", () => { createdAt: "2026-03-01T00:00:00Z", author: { handle: "bob.tangled.org" } }, - 3 + 3, + "https://ogre.tangled.network" ); expect(url).toContain("https://ogre.tangled.network/card?payload="); }); @@ -54,4 +57,13 @@ describe("og card URL generation", () => { expect(decoded.stars).toBeUndefined(); expect(decoded.languages).toBeUndefined(); }); + + it("uses custom baseUrl when provided", () => { + const url = repoCard( + { name: "core", ownerHandle: "tangled.org" }, + null, + "https://ogre-dev.tangled.network" + ); + expect(url).toContain("https://ogre-dev.tangled.network/card?payload="); + }); }); diff --git a/web/src/lib/seo/og.ts b/web/src/lib/seo/og.ts index aa68791b5..f470204e5 100644 --- a/web/src/lib/seo/og.ts +++ b/web/src/lib/seo/og.ts @@ -1,6 +1,14 @@ +import { page } from "$app/state"; import { avatarUrl } from "$lib/avatar"; -const DEFAULT_OGRE_URL = "https://ogre.tangled.network"; +export function resolveOgreUrl(baseUrl?: string): string { + if (baseUrl) return baseUrl; + try { + return page.data.publicConfig?.ogreUrl ?? ""; + } catch { + return ""; + } +} export interface OgRepoPayload { type: "repository"; @@ -58,8 +66,8 @@ export function encodeOgPayload(payload: OgPayload): string { return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); } -export function ogCardUrl(payload: OgPayload, baseUrl = DEFAULT_OGRE_URL): string { - return `${baseUrl}/card?payload=${encodeOgPayload(payload)}`; +export function ogCardUrl(payload: OgPayload, baseUrl?: string): string { + return `${resolveOgreUrl(baseUrl)}/card?payload=${encodeOgPayload(payload)}`; } export function repoCard( diff --git a/web/src/lib/server/config.ts b/web/src/lib/server/config.ts index 70f68d353..61a572c15 100644 --- a/web/src/lib/server/config.ts +++ b/web/src/lib/server/config.ts @@ -22,6 +22,7 @@ export type WebConfig = { sitesDomain: string; camoUrl: string; avatarUrl: string; + ogreUrl: string; /** the secrets camo and avatar sign with, so neither leaves the server */ camoSecret: string; avatarSecret: string; @@ -41,6 +42,7 @@ export type PublicWebConfig = Pick< | "moderationServiceDid" | "turnstileSiteKey" | "ssrDiffMaxBytes" + | "ogreUrl" > & { /** camo has a secret, so markup can route images through it */ camoEnabled: boolean; @@ -58,6 +60,7 @@ type WebConfigEnv = { CAMO_SHARED_SECRET?: string; AVATAR_URL?: string; AVATAR_SHARED_SECRET?: string; + OGRE_URL?: string; MODERATION_SERVICE_DID?: string; TURNSTILE_SITE_KEY?: string; /** diff payloads above this many bytes are not buffered through the ssr @@ -73,6 +76,7 @@ export const resolveConfig = (values: WebConfigEnv): WebConfig => ({ sitesDomain: values.SITES_DOMAIN?.trim() || "tngl.io", camoUrl: cleanUrl(values.CAMO_URL, "https://camo.tangled.sh"), avatarUrl: cleanUrl(values.AVATAR_URL, "https://avatar.tangled.sh"), + ogreUrl: cleanUrl(values.OGRE_URL, "https://ogre.tangled.network"), camoSecret: values.CAMO_SHARED_SECRET?.trim() ?? "", avatarSecret: values.AVATAR_SHARED_SECRET?.trim() ?? "", moderationServiceDid: values.MODERATION_SERVICE_DID?.trim() ?? "", @@ -95,6 +99,7 @@ export const getPublicConfig = (): PublicWebConfig => { moderationServiceDid: config.moderationServiceDid, turnstileSiteKey: config.turnstileSiteKey, ssrDiffMaxBytes: config.ssrDiffMaxBytes, + ogreUrl: config.ogreUrl, camoEnabled: config.camoSecret !== "" }; }; diff --git a/web/src/routes/[handle]/[repo]/+layout@.svelte b/web/src/routes/[handle]/[repo]/+layout@.svelte index bf045769b..ab73db2a6 100644 --- a/web/src/routes/[handle]/[repo]/+layout@.svelte +++ b/web/src/routes/[handle]/[repo]/+layout@.svelte @@ -150,7 +150,7 @@ description={repoDescription} canonical={canonicalRepoUrl} jsonLd={softwareSchema} - image={(resolvedRepo || repoMeta) ? repoCard((resolvedRepo || repoMeta)!) : undefined} + image={(resolvedRepo || repoMeta) ? repoCard((resolvedRepo || repoMeta)!, null, data.publicConfig?.ogreUrl) : undefined} /> {/if} diff --git a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte index 9dda25c0a..de703767a 100644 --- a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte +++ b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte @@ -49,7 +49,7 @@ ); - + {#snippet skeleton()} diff --git a/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte b/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte index 99123fd91..189c0cd07 100644 --- a/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte +++ b/web/src/routes/[handle]/[repo]/pulls/[aturi]/[version]/[[range]]/PullViewPage.svelte @@ -548,7 +548,7 @@ ); - +
diff --git a/web/wrangler.dev.jsonc b/web/wrangler.dev.jsonc index c8f301482..97fc67bc6 100644 --- a/web/wrangler.dev.jsonc +++ b/web/wrangler.dev.jsonc @@ -49,6 +49,7 @@ "DELIBERI_URL": "https://notifs-dev.tangled.network", "CAMO_URL": "https://camo-dev.tangled.org", "AVATAR_URL": "https://avatar-dev.tangled.org", + "OGRE_URL": "https://ogre-dev.tangled.network", "MODERATION_SERVICE_DID": "did:plc:3t4yxvxwjrl55odxe2rwwhfr" } }