remove hard coded routes

This commit is contained in:
Devin Zuczek
2026-06-29 22:41:17 -04:00
parent 69b89e2dc4
commit 81815ef06c
29 changed files with 122 additions and 256 deletions
+6 -1
View File
@@ -2,7 +2,12 @@ import type { HonoApp } from '@repo/hono-helpers'
import type { SharedHonoEnv, SharedHonoVariables } from '@repo/hono-helpers/src/types'
export type Env = SharedHonoEnv & {
// add additional Bindings here
/**
* Base domain the service hosts are derived from, e.g. `rec.example.com`.
* Injected at deploy time via `--var DOMAIN`; defaults in `wrangler.jsonc`
* for local dev and tests.
*/
DOMAIN: string
}
/** Variables can be extended */
+52
View File
@@ -0,0 +1,52 @@
/**
* Service-discovery map: service label → subdomain. The game client fetches the
* generated `{ label: "https://<subdomain>.<domain>" }` document from `/`.
*
* The base domain is injected at deploy time via the `DOMAIN` var (see
* `run-wrangler-deploy`), so the real domain never lives in a versioned file.
*/
const SERVICE_SUBDOMAINS = {
Accounts: 'accounts',
AI: 'ai',
API: 'api',
Auth: 'auth',
BugReporting: 'bugreporting',
Cards: 'cards',
CDN: 'cdn',
Chat: 'chat',
Clubs: 'clubs',
CMS: 'cms',
Commerce: 'commerce',
Data: 'data',
DataCollection: 'datacollection',
Discovery: 'discovery',
Econ: 'econ',
GameLogs: 'gamelogs',
Geo: 'geo',
Images: 'img',
Leaderboard: 'leaderboard',
Link: 'link',
Lists: 'lists',
Matchmaking: 'match',
Moderation: 'api',
Notifications: 'notify',
PlatformNotifications: 'platformnotifications',
PlayerSettings: 'playersettings',
RoomComments: 'roomcomments',
RoomieIntegrations: 'roomieintegrations',
Rooms: 'rooms',
Storage: 'storage',
Strings: 'strings',
StringsCDN: 'strings-cdn',
Studio: 'studio',
Thorn: 'thorn',
Videos: 'videos',
WWW: 'www',
} as const
/** Builds the endpoints document for `domain`, e.g. `rec.example.com`. */
export function buildEndpoints(domain: string): Record<string, string> {
return Object.fromEntries(
Object.entries(SERVICE_SUBDOMAINS).map(([label, sub]) => [label, `https://${sub}.${domain}`])
)
}
+6 -5
View File
@@ -3,15 +3,16 @@ import { useWorkersLogger } from 'workers-tagged-logger'
import { withNotFound, withOnError } from '@repo/hono-helpers'
import endpoints from '../static/endpoints.json'
import { buildEndpoints } from './endpoints'
import type { App } from './context'
/**
* Name-server / service-discovery worker served at the apex domain.
* Returns the endpoints document the game client fetches to discover every
* service host. Generated from `env.json` by `runx sync` — run it after
* changing the domain (see `apps/ns/static/endpoints.json`).
* service host. Hosts are derived from the `DOMAIN` var, which is injected at
* deploy time (see `run-wrangler-deploy`) and defaults in `wrangler.jsonc` for
* local dev.
*/
const app = new Hono<App>()
.use(
@@ -27,7 +28,7 @@ const app = new Hono<App>()
.onError(withOnError())
.notFound(withNotFound())
// Endpoints document. TODO: generate this dynamically per environment.
.get('/', (c) => c.json(endpoints))
// Endpoints document, derived from the deploy-time base domain.
.get('/', (c) => c.json(buildEndpoints(c.env.DOMAIN)))
export default app
+5 -2
View File
@@ -2,16 +2,19 @@ import { exports } from 'cloudflare:workers'
import { describe, expect, test } from 'vitest'
import '../../ns.app'
import endpoints from '../../../static/endpoints.json'
import { buildEndpoints } from '../../endpoints'
const ORIGIN = 'https://example.com'
// Must match the DOMAIN var default in apps/ns/wrangler.jsonc.
const TEST_DOMAIN = 'rec.example.com'
describe('ns endpoints', () => {
test('GET / returns the endpoints document', async () => {
const res = await exports.default.fetch(`${ORIGIN}/`)
expect(res.status).toBe(200)
const body = await res.json()
expect(body).toEqual(endpoints)
expect(body).toEqual(buildEndpoints(TEST_DOMAIN))
})
test('unknown path returns 404', async () => {