mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 22:51:30 -07:00
mono updates
This commit is contained in:
+11
-3
@@ -7,11 +7,19 @@ discover every service host (Accounts, API, Auth, Econ, Matchmaking,
|
||||
Notifications, …).
|
||||
|
||||
Each host is built at runtime from the `DOMAIN` var (the base domain) plus the
|
||||
service → subdomain map in `src/endpoints.ts`. `DOMAIN` is injected at deploy
|
||||
time from `RECFLARE_DOMAIN` (see `run-wrangler-deploy`) and defaults to
|
||||
`rec.example.com` in `wrangler.jsonc` for local dev.
|
||||
service → subdomain map in `src/endpoints.ts`. `DOMAIN` is injected from
|
||||
`RECFLARE_DOMAIN` by both `run-wrangler-dev` and `run-wrangler-deploy`, and
|
||||
defaults to `rec.example.com` in `wrangler.jsonc` when that isn't set.
|
||||
|
||||
## Updating endpoints
|
||||
|
||||
- To change the base domain, set `RECFLARE_DOMAIN` (in `.env`) and redeploy.
|
||||
- To add or rename a service host, edit the map in `src/endpoints.ts`.
|
||||
|
||||
## ENDPOINT_STYLE
|
||||
|
||||
With `ENDPOINT_STYLE=path`, every service is advertised as `https://<domain>/<slug>`
|
||||
instead of `https://<slug>.<domain>`. That's for the combined `mono` worker alone —
|
||||
it's a single Worker that routes on the first path segment, so one host serves the
|
||||
lot. Unset (the split deployment, where each service is its own Worker on its own
|
||||
host) gives the subdomain document.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { HonoApp } from '@repo/hono-helpers'
|
||||
import type { SharedHonoEnv, SharedHonoVariables } from '@repo/hono-helpers/src/types'
|
||||
import type { EndpointStyle } from './endpoints'
|
||||
|
||||
export type Env = SharedHonoEnv & {
|
||||
/**
|
||||
@@ -8,6 +9,13 @@ export type Env = SharedHonoEnv & {
|
||||
* for local dev and tests.
|
||||
*/
|
||||
DOMAIN: string
|
||||
/**
|
||||
* `path` to serve every service from a path on `DOMAIN` (`https://<domain>/rooms`)
|
||||
* instead of from its own subdomain. Set only by the combined `mono` worker, which is
|
||||
* one Worker routing on that first path segment; anything else (the split deployment)
|
||||
* leaves it unset and gets the per-service hosts.
|
||||
*/
|
||||
ENDPOINT_STYLE?: EndpointStyle
|
||||
}
|
||||
|
||||
/** Variables can be extended */
|
||||
|
||||
@@ -44,9 +44,25 @@ const SERVICE_SUBDOMAINS = {
|
||||
WWW: 'www',
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Where the services live, relative to the base domain:
|
||||
*
|
||||
* `subdomain` — one host each, `https://rooms.<domain>`. The split deployment, and the
|
||||
* default, since that's what every worker in `apps/` is deployed as.
|
||||
* `path` — one host, first path segment names the service: `https://<domain>/rooms`.
|
||||
* Only the combined `mono` worker, which is a single Worker routing on that segment.
|
||||
*/
|
||||
export type EndpointStyle = 'subdomain' | 'path'
|
||||
|
||||
/** Builds the endpoints document for `domain`, e.g. `rec.example.com`. */
|
||||
export function buildEndpoints(domain: string): Record<string, string> {
|
||||
export function buildEndpoints(
|
||||
domain: string,
|
||||
style: EndpointStyle = 'subdomain'
|
||||
): Record<string, string> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(SERVICE_SUBDOMAINS).map(([label, sub]) => [label, `https://${sub}.${domain}`])
|
||||
Object.entries(SERVICE_SUBDOMAINS).map(([label, sub]) => [
|
||||
label,
|
||||
style === 'path' ? `https://${domain}/${sub}` : `https://${sub}.${domain}`,
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ const app = new Hono<App>()
|
||||
.onError(withOnError())
|
||||
.notFound(withNotFound())
|
||||
|
||||
// Endpoints document, derived from the deploy-time base domain.
|
||||
.get('/', (c) => c.json(buildEndpoints(c.env.DOMAIN)))
|
||||
// Endpoints document, derived from the deploy-time base domain. ENDPOINT_STYLE is set
|
||||
// only by the combined `mono` worker, to advertise the services on paths of that one
|
||||
// domain rather than on a host each; unset (the split deployment) means subdomains.
|
||||
.get('/', (c) => c.json(buildEndpoints(c.env.DOMAIN, c.env.ENDPOINT_STYLE)))
|
||||
|
||||
export default app
|
||||
|
||||
@@ -18,6 +18,20 @@ describe('ns endpoints', () => {
|
||||
expect(body).toEqual(buildEndpoints(TEST_DOMAIN))
|
||||
})
|
||||
|
||||
test('the path style puts every service on the base domain', async () => {
|
||||
const doc = buildEndpoints(TEST_DOMAIN, 'path')
|
||||
expect(doc.Rooms).toBe(`https://${TEST_DOMAIN}/rooms`)
|
||||
expect(doc.Matchmaking).toBe(`https://${TEST_DOMAIN}/match`)
|
||||
expect(doc.Images).toBe(`https://${TEST_DOMAIN}/img`)
|
||||
expect(Object.values(doc).every((url) => url.startsWith(`https://${TEST_DOMAIN}/`))).toBe(true)
|
||||
})
|
||||
|
||||
test('the default style gives every service its own host', async () => {
|
||||
const doc = buildEndpoints(TEST_DOMAIN)
|
||||
expect(doc.Rooms).toBe(`https://rooms.${TEST_DOMAIN}`)
|
||||
expect(doc.Images).toBe(`https://img.${TEST_DOMAIN}`)
|
||||
})
|
||||
|
||||
test('unknown path returns 404', async () => {
|
||||
const res = await exports.default.fetch(`${ORIGIN}/nope`)
|
||||
expect(res.status).toBe(404)
|
||||
|
||||
Reference in New Issue
Block a user