1// The Worker's bindings (wrangler.json). HUB exists only in `--env dev`: 2// the MCP bridge is for developing songs locally, so a production deploy 3// has no hub to reach and its MCP routes answer 404. The song list the 4// votes check against comes from ASSETS (production and preview, which 5// deploy the static build) or SONGS_URL (dev's Astro server); votes.ts 6// takes whichever is there. DB is the site's D1 database, the same in both 7// (its schema is worker/migrations/). EVENTS is the telemetry dataset 8// (events.ts), CACHE the relay's answer cache (answer-cache.ts). BUDGET is 9// one JevBudget object per signed-in user (budget.ts), charged 10// JEV_DAILY_PER_USER relay calls a UTC day at most. LISTEN_LIMIT and 11// RECORD_LIMIT are listening's (listening.ts). PARTY is the listening 12// parties' rooms, one Durable Object each (party.ts), in both environments, 13// and PARTY_LIMIT the per-visitor limit on joining one. COVERS is the R2 14// bucket of listener songs' cover images (content.ts); CONTENT_LIMIT and 15// COVER_LIMIT are per author, BROWSE_LIMIT per visitor, for listeners' 16// content. The hosted MCP (hosted-mcp.ts, everywhere, OAuth-protected by 17// oauth.ts) keeps its clients, grants and tokens in OAUTH_KV, reaches a 18// user's own tabs through TAB_HUB (one TabHub per account, tab-hub.ts), and 19// is rate-limited per user by MCP_LIMIT. LOBBY is the site's one lobby 20// (lobby.ts: who is listening to what), and LOBBY_LIMIT the per-visitor 21// limit on joining it. PARTY_DIRECTORY is the site's one list of live 22// parties (party-directory.ts), and DATA_LIMIT the per-visitor limit on 23// reading what the site stores (data.ts). 24import type { JevBudget } from './budget'; 25import type { Hub } from './hub'; 26import type { LobbyRoom } from './lobby'; 27import type { Party, PartyDirectory } from './party'; 28import type { TabHub } from './tab-hub'; 29 30type RateLimit = { limit(options: { key: string }): Promise<{ success: boolean }> }; 31 32export interface Env { 33 JEVSTRUDEL_TYPESAFE_API_KEY?: string; 34 JEV_LIMIT: RateLimit; 35 VOTE_LIMIT: RateLimit; 36 AUTH_LIMIT: RateLimit; 37 LISTEN_LIMIT: RateLimit; 38 RECORD_LIMIT: RateLimit; 39 PARTY_LIMIT: RateLimit; 40 CONTENT_LIMIT: RateLimit; 41 COVER_LIMIT: RateLimit; 42 BROWSE_LIMIT: RateLimit; 43 MCP_LIMIT: RateLimit; 44 LOBBY_LIMIT: RateLimit; 45 DATA_LIMIT: RateLimit; 46 DB: D1Database; 47 EVENTS: AnalyticsEngineDataset; 48 CACHE: KVNamespace; 49 OAUTH_KV: KVNamespace; 50 COVERS: R2Bucket; 51 BUDGET: DurableObjectNamespace<JevBudget>; 52 JEV_DAILY_PER_USER: number | string; 53 HUB?: DurableObjectNamespace<Hub>; 54 PARTY: DurableObjectNamespace<Party>; 55 TAB_HUB: DurableObjectNamespace<TabHub>; 56 LOBBY: DurableObjectNamespace<LobbyRoom>; 57 PARTY_DIRECTORY: DurableObjectNamespace<PartyDirectory>; 58 ASSETS?: Fetcher; 59 SONGS_URL?: string; 60}