wrangler.jsonc
Rama main · réplica de lectura del repositorio original.
{
"$schema": "node_modules/wrangler/config-schema.json",
// ─────────────────────────────────────────────────────────────────────────
// TOP LEVEL = the generic self-host / fork target. Deploying this as-is
// stands up a standalone Goldroad on your own workers.dev subdomain with your
// own D1. It carries NO custom routes and only a placeholder database_id, so
// a fork never inherits the hosted instance's domain or database.
// • Self-hosting: replace `database_id` with your own D1 id (the Deploy to
// Cloudflare button provisions one and rewrites it for you), set the
// secrets from `.dev.vars.example`, and set VITE_PUBLIC_ORIGIN to your
// public origin (see SELF_HOSTING.md).
// Environment-specific deploys live in the `env.*` blocks below. Bindings are
// non-inheritable, so each env repeats its own `d1_databases`.
// ─────────────────────────────────────────────────────────────────────────
"name": "goldroad",
"workers_dev": true,
// Off: each uploaded version would get a public URL on your live D1. Turn it
// on to review PRs on preview URLs (SELF_HOSTING.md).
"preview_urls": false,
"compatibility_date": "2025-09-02",
// NOTE: global_fetch_strictly_public was tried here as defense-in-depth for
// /api/import (writer-supplied feed URLs; same-zone fetches otherwise skip
// the platform front door). It broke outbound fetches to Cloudflare-fronted
// APIs on the deployed worker (handle resolution against public.api.bsky.app
// started failing), so it was removed — the app-level guard that refuses our
// own hostnames is the SSRF defense.
"compatibility_flags": ["nodejs_compat"],
"observability": {
"enabled": true,
"head_sampling_rate": 1
},
// Custom entry: canonical-hostname 301s in front of the Start handler.
"main": "src/server.ts",
// ONE hourly cron (free tier: ≤5 triggers/account) multiplexing every
// scheduled job: publish due scheduled posts, purge expired oauth_kv state
// rows, sample follower counts, check the backup heartbeat, alert on new
// abuse reports, and self-check core invariants — alerting via the optional
// WEBHOOK_URL secret. Adding a job means adding it to the handler, NOT
// adding a trigger.
// Handler: scheduled() in src/server.ts → runScheduled() in ~/lib/scheduled.
"triggers": {
"crons": ["0 * * * *"]
},
"d1_databases": [
{
"binding": "DB",
"database_name": "goldroad-db",
// Placeholder — replace with your own D1 database id when self-hosting.
// NOTHING REAL USES THIS. Both envs below carry their own id (d1
// bindings are non-inheritable), so any wrangler d1 command WITHOUT
// `--env` resolves to this placeholder and fails with "database
// 00000000-... could not be found". That is the intended outcome — it is
// a loud failure rather than a migration applied to the wrong database —
// but it means a hosted d1 command needs its env: see db:migrate:prod and
// db:migrate:staging in package.json. db:migrate:selfhost is the one that
// deliberately omits `--env` and so lands here, on the id a self-hoster
// has replaced with their own.
"database_id": "00000000-0000-0000-0000-000000000000",
"migrations_dir": "drizzle"
}
],
"env": {
// Staging: main-branch channel, Access-gated workers.dev URL, own D1.
// The staging database is provisioned by the operator; until then this id
// is a placeholder.
"staging": {
"name": "goldroad-staging",
"workers_dev": true,
"preview_urls": true,
"observability": {
"enabled": true,
"head_sampling_rate": 1
},
"triggers": {
"crons": ["0 * * * *"]
},
"d1_databases": [
{
"binding": "DB",
"database_name": "goldroad-db-staging",
"database_id": "3d671556-7602-462a-a327-b0da05344972",
"migrations_dir": "drizzle"
}
]
},
// Production: release-branch channel, serves the canonical zone route.
"production": {
"name": "goldroad",
"workers_dev": true,
// Off: each version would get a public URL on the production D1. PR previews are staging's.
"preview_urls": false,
// Both hostnames are routed on purpose. `www` resolves at the edge
// already, so without a route here Cloudflare matched nothing and served
// its own 404 — the request never reached the Worker, and every shared
// link carrying `www.` was dead. With the route, `canonicalRedirect`
// (~/lib/origin) 301s it to the apex like any other non-canonical host.
"routes": [
{ "pattern": "trygoldroad.com/*", "zone_name": "trygoldroad.com" },
{ "pattern": "www.trygoldroad.com/*", "zone_name": "trygoldroad.com" }
],
"observability": {
"enabled": true,
"head_sampling_rate": 1
},
"triggers": {
"crons": ["0 * * * *"]
},
"d1_databases": [
{
"binding": "DB",
"database_name": "goldroad-db",
"database_id": "7cf27d45-076c-4cda-8057-ddae78160b1a",
"migrations_dir": "drizzle"
}
]
}
}
}