{"_id":"@bigrandall/rrangler","_rev":"5-7b153651e6007bbd1794a433eafe6f4b","name":"@bigrandall/rrangler","dist-tags":{"latest":"0.4.9"},"versions":{"0.1.0":{"name":"@bigrandall/rrangler","version":"0.1.0","keywords":["rrangler","wrangler","cloudflare","workers","workerd","edge","serverless","cli","randallflare","bigrandall","d1","kv","r2","durable-objects"],"author":{"name":"Randall","email":"me@bigrandall.io"},"license":"MIT","_id":"@bigrandall/rrangler@0.1.0","maintainers":[{"name":"bigrandall","email":"me@bigrandall.io"}],"homepage":"https://github.com/RandallAnjie/bigrandall.io/tree/main/rrangler#readme","bugs":{"url":"https://github.com/RandallAnjie/bigrandall.io/issues"},"bin":{"rrangler":"bin/rrangler.mjs"},"dist":{"shasum":"741fe8dcd6e7b1ac081cdc77b18d1a3802c33d9d","tarball":"https://registry.npmjs.org/@bigrandall/rrangler/-/rrangler-0.1.0.tgz","fileCount":9,"integrity":"sha512-fuE6opDSi0geN/qIh7m2H1480wxXZDiP4JDvZmiF8skIP0lC1FwBTuOItN5UtM8eKaSQSU6ESHyNlx3iCSbe2A==","signatures":[{"sig":"MEUCIQDeo6++BCdwqCS9CRImGAffIWsarPHuwGe1m+818UNa5AIgaSlYHi+gYtE+ZnVMiO9EHHizVY1nsmjaKN9a7CqG14M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49477},"type":"module","engines":{"node":">=20"},"gitHead":"8d0fd228317746456a144bd91f6d7334c25a832b","scripts":{"test":"node bin/rrangler.mjs --version","prepublishOnly":"node bin/rrangler.mjs --version"},"_npmUser":{"name":"bigrandall","email":"me@bigrandall.io"},"repository":{"url":"git+https://github.com/RandallAnjie/bigrandall.io.git","type":"git","directory":"rrangler"},"_npmVersion":"11.16.0","description":"wrangler-compatible CLI for RandallFlare — the self-hosted Cloudflare-Workers edge platform in bigrandall.io. Deploy workers, manage D1/KV/R2, tail logs, run locally on workerd.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/rrangler_0.1.0_1783261186559_0.46115310526239917","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bigrandall/rrangler","version":"0.2.0","keywords":["rrangler","wrangler","cloudflare","workers","workerd","edge","serverless","cli","randallflare","bigrandall","d1","kv","r2","durable-objects"],"author":{"name":"Randall","email":"me@bigrandall.io"},"license":"MIT","_id":"@bigrandall/rrangler@0.2.0","maintainers":[{"name":"bigrandall","email":"me@bigrandall.io"}],"homepage":"https://github.com/RandallAnjie/bigrandall.io/tree/main/rrangler#readme","bugs":{"url":"https://github.com/RandallAnjie/bigrandall.io/issues"},"bin":{"rrangler":"bin/rrangler.mjs"},"dist":{"shasum":"8b206678bbaedd99768ef8171093d5cb30b96a32","tarball":"https://registry.npmjs.org/@bigrandall/rrangler/-/rrangler-0.2.0.tgz","fileCount":9,"integrity":"sha512-Jay4HGmh0jvYLJ/igVt0+3FGgW8bLeBb5dJh1qfgUeulj/s97GESp5UC6THLLmCHOw7KDXMmMkBWnYoxemzZhw==","signatures":[{"sig":"MEUCIQCt4d4+YluOCEWbpEqVQK+Expx+x3TbBH2H7gYLEkvSiAIgUh0kguClDisbxbLcFG2pqsK0R5A/UO0ZYkw4NWj8IjI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56242},"type":"module","engines":{"node":">=20"},"gitHead":"f9cb26d00f1f4971428f2fd8d19f84bb347a49d3","scripts":{"test":"node bin/rrangler.mjs --version","prepublishOnly":"node bin/rrangler.mjs --version"},"_npmUser":{"name":"bigrandall","email":"me@bigrandall.io"},"repository":{"url":"git+https://github.com/RandallAnjie/bigrandall.io.git","type":"git","directory":"rrangler"},"_npmVersion":"10.8.2","description":"wrangler-compatible CLI for RandallFlare — the self-hosted Cloudflare-Workers edge platform in bigrandall.io. Deploy workers, manage D1/KV/R2, tail logs, run locally on workerd.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/rrangler_0.2.0_1783310095552_0.9313287732736162","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bigrandall/rrangler","version":"0.4.0","keywords":["rrangler","wrangler","cloudflare","workers","workerd","edge","serverless","cli","randallflare","bigrandall","d1","kv","r2","durable-objects"],"author":{"name":"Randall","email":"me@bigrandall.io"},"license":"MIT","_id":"@bigrandall/rrangler@0.4.0","maintainers":[{"name":"bigrandall","email":"me@bigrandall.io"}],"homepage":"https://github.com/RandallAnjie/bigrandall.io/tree/main/rrangler#readme","bugs":{"url":"https://github.com/RandallAnjie/bigrandall.io/issues"},"bin":{"rrangler":"bin/rrangler.mjs"},"dist":{"shasum":"662747b7aeb99c988d0f846ec0272820523694c7","tarball":"https://registry.npmjs.org/@bigrandall/rrangler/-/rrangler-0.4.0.tgz","fileCount":9,"integrity":"sha512-QEDXd46TtpHj365oUZjT/zFYNjOUlj0o/KMqpgzZIlc20z1lT+t+cF8PIvOwqap1exBec80ivkJ6pr3L8E1iJQ==","signatures":[{"sig":"MEQCIFZzNMVJdGqrSpWh6khgSM7uHQp/OKiB0GsCKN0MqGzeAiAk65uMsTcelML0gXegDdHVdWlHF71HzxoI89R14+JD5w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64292},"type":"module","engines":{"node":">=20"},"gitHead":"9c91fed2ab6e55b536bebae9c0f8b4281b94ec44","scripts":{"test":"node bin/rrangler.mjs --version","prepublishOnly":"node bin/rrangler.mjs --version"},"_npmUser":{"name":"bigrandall","email":"me@bigrandall.io"},"repository":{"url":"git+https://github.com/RandallAnjie/bigrandall.io.git","type":"git","directory":"rrangler"},"_npmVersion":"10.8.2","description":"wrangler-compatible CLI for RandallFlare — the self-hosted Cloudflare-Workers edge platform in bigrandall.io. Deploy workers, manage D1/KV/R2, tail logs, run locally on workerd.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/rrangler_0.4.0_1783393795230_0.9920293586584097","host":"s3://npm-registry-packages-npm-production"}},"0.4.8":{"name":"@bigrandall/rrangler","version":"0.4.8","keywords":["rrangler","wrangler","cloudflare","workers","workerd","edge","serverless","cli","randallflare","bigrandall","d1","kv","r2","cdn","durable-objects"],"author":{"name":"Randall","email":"me@bigrandall.io"},"license":"MIT","_id":"@bigrandall/rrangler@0.4.8","maintainers":[{"name":"bigrandall","email":"me@bigrandall.io"}],"homepage":"https://github.com/RandallAnjie/bigrandall.io/tree/main/rrangler#readme","bugs":{"url":"https://github.com/RandallAnjie/bigrandall.io/issues"},"bin":{"rr":"bin/rrangler.mjs","rrangler":"bin/rrangler.mjs"},"dist":{"shasum":"8beeba69346dca70f9dc191ceb01070138129f90","tarball":"https://registry.npmjs.org/@bigrandall/rrangler/-/rrangler-0.4.8.tgz","fileCount":17,"integrity":"sha512-4yWMkNWJBbKf+ogUULM1eVtishAOXDhK3SA8nu8hGk3NBGGEbceHNcTdudQNhZFa5gGYpNuhQLV9/ygNtuVyBA==","signatures":[{"sig":"MEUCIE4ydXx89H88WyKZbpXBiVEv+9aAZQk1ZbC8XeP5SyK2AiEAjLuKQ5zxui6lJrHkmLhg2BEtzH9yoeUeFqw80E8ocnU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICEK8H/jNqvz9a1RYQrfL9n0+AKLpvDGXrQuD4Blx3nMAiAPnjOutEe4/3UjR0RchMI6MUAz1zMlBwGNomD+ZuLzrw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":153474},"type":"module","engines":{"node":">=20"},"gitHead":"a09261b0c9680ecbcd7a3b7a223f5c1003825f18","scripts":{"test":"node --test test/*.test.mjs && node bin/rrangler.mjs --version","prepublishOnly":"node bin/rrangler.mjs --version"},"_npmUser":{"name":"bigrandall","email":"me@bigrandall.io"},"repository":{"url":"git+https://github.com/RandallAnjie/bigrandall.io.git","type":"git","directory":"rrangler"},"_npmVersion":"11.16.0","description":"wrangler-compatible CLI for RandallFlare — the self-hosted Cloudflare-Workers edge platform in bigrandall.io. Deploy workers, manage D1/KV/R2/CDN, tail logs, run locally on workerd.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/rrangler_0.4.8_1788848886452_0.31658800203480997","host":"s3://npm-registry-packages-npm-production"}},"0.4.9":{"_id":"@bigrandall/rrangler@0.4.9","bin":{"rr":"bin/rrangler.mjs","rrangler":"bin/rrangler.mjs"},"bugs":{"url":"https://github.com/RandallAnjie/bigrandall.io/issues"},"dist":{"shasum":"4f1661ce7dc32683960f60a8e8dee867fd135855","tarball":"https://registry.npmjs.org/@bigrandall/rrangler/-/rrangler-0.4.9.tgz","fileCount":17,"integrity":"sha512-JDfL8C8685I02Zzgvyql7u9kaI6h/ohjBQYZgILGnxaCt64f0uRzueJrKlqaU5/pc6lqUML+x9IMqSUgQIBWBA==","signatures":[{"sig":"MEYCIQD85t1O+Ega05RQ77jGGGrXeFsQhjMvSxj8kYJLtLckzgIhALkIR/OWgicaZS96XZBbj7zS40dnfVM8JidQ1QRYlE+x","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC35IrE6bVG+zZnOycYaiaQPxdx3y1ALLXdjpgE/VDevwIgLbj1g2+Qg7QLcPptuMPMXzc/2amH/OCLjFfMxKUMCFU="}],"unpackedSize":160186},"name":"@bigrandall/rrangler","type":"module","author":{"name":"Randall","email":"me@bigrandall.io"},"engines":{"node":">=20"},"gitHead":"4b126f34aece9e4113eb5eb17c968ff31cee7355","license":"MIT","scripts":{"test":"node --test test/*.test.mjs && node bin/rrangler.mjs --version","prepublishOnly":"node bin/rrangler.mjs --version"},"version":"0.4.9","_npmUser":{"name":"bigrandall","email":"me@bigrandall.io"},"homepage":"https://github.com/RandallAnjie/bigrandall.io/tree/main/rrangler#readme","keywords":["rrangler","wrangler","cloudflare","workers","compute","pages","workerd","edge","serverless","cli","randallflare","bigrandall","d1","kv","r2","cdn","durable-objects"],"repository":{"url":"git+https://github.com/RandallAnjie/bigrandall.io.git","type":"git","directory":"rrangler"},"_npmVersion":"11.16.0","description":"wrangler-compatible CLI for RandallFlare — deploy Compute (isolate + assets), manage D1/KV/R2/CDN, tail logs, run locally on workerd.","directories":{},"maintainers":[{"name":"bigrandall","email":"me@bigrandall.io"}],"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rrangler_0.4.9_1789018394279_0.2533847306351875"}}},"time":{"created":"2026-07-05T14:19:46.285Z","modified":"2026-09-10T05:33:14.523Z","0.1.0":"2026-07-05T14:19:46.701Z","0.2.0":"2026-07-06T03:54:55.683Z","0.4.0":"2026-07-07T03:09:55.344Z","0.4.8":"2026-09-08T06:28:06.540Z","0.4.9":"2026-09-10T05:33:14.370Z"},"bugs":{"url":"https://github.com/RandallAnjie/bigrandall.io/issues"},"author":{"name":"Randall","email":"me@bigrandall.io"},"license":"MIT","homepage":"https://github.com/RandallAnjie/bigrandall.io/tree/main/rrangler#readme","keywords":["rrangler","wrangler","cloudflare","workers","compute","pages","workerd","edge","serverless","cli","randallflare","bigrandall","d1","kv","r2","cdn","durable-objects"],"repository":{"url":"git+https://github.com/RandallAnjie/bigrandall.io.git","type":"git","directory":"rrangler"},"description":"wrangler-compatible CLI for RandallFlare — deploy Compute (isolate + assets), manage D1/KV/R2/CDN, tail logs, run locally on workerd.","maintainers":[{"name":"bigrandall","email":"me@bigrandall.io"}],"readme":"# rrangler\n\nA **wrangler-compatible CLI for RandallFlare** — the edge platform inside\nbigrandall.io. Where `wrangler` talks to Cloudflare, `rrangler` talks to your\nRandallFlare account's edge API (`/api/edge/v1/*`). Same command shape, so\nmuscle memory (and `wrangler.toml`) carry over.\n\nZero dependencies — plain Node ≥ 20 ESM.\n\n## Install\n\n```bash\nnpm i -g @bigrandall/rrangler    # installs both `rrangler` and `rr`\nrr --version\nrr whoami\n```\n\nOr run without installing:\n\n```bash\nnpx @bigrandall/rrangler whoami\n```\n\nFrom a checkout of this repo:\n\n```bash\nnpm i -g ./rrangler          # or `npm link` inside rrangler/\n# or directly: node rrangler/bin/rrangler.mjs <command>\n```\n\nZero runtime dependencies — just Node ≥ 20.\n\n## Auth\n\nCreate an **API token** in bigrandall.io → `/flare` → API tokens (pick the\nscopes you need: `worker:*` / `pages:*` for Compute, `d1:*`, `r2:*`, `kv:*`, `cdn:read` / `cdn:write`, or `*`). Then:\n\n```bash\nrr login --token rft_xxx               # saved to ~/.rrangler.json (chmod 600)\nrr whoami\nrr doctor                              # connectivity + which endpoints your scopes allow\n```\n\nOr per-invocation: `RRANGLER_TOKEN=… rrangler …` / `--token …`.\nPoint at another instance with `RRANGLER_API` / `--api https://…`.\n\n## Commands\n\nMirrors wrangler — `publish` aliases to `deploy`, `kv:namespace` works too.\n`rr` is the same binary as `rrangler`. Bare resource names list (`rr compute`, `rr d1`, `rr cdn`).\n`worker` and `pages` remain aliases for isolate-only / assets-only filters.\n\n| rr / rrangler | does |\n| --- | --- |\n| `init [name]` | scaffold `rrangler.json` + `main.js` |\n| `deploy [--name s]` | end-to-end isolate Compute: create-if-missing, sync d1/kv bindings, push files, set `vars`, publish (`--no-publish` → DRAFT) |\n| `compute list` / `compute get <slug>` | all Compute units (`kind` isolate or assets) |\n| `compute create <name> [--assets]` | mint a Compute unit (DRAFT); `--assets` is a static site |\n| `tail <slug>` | stream runtime logs (isolate or assets) |\n| `compute env set <slug> K=V …` / `delete` | env vars (`--secret` to mask) |\n| `compute builds <slug>` / `build` / `build-log` | git builds |\n| `compute git get \\| set \\| disconnect <slug>` | connect a repo (see [Git connect](#git-connect)) |\n| `worker list` / `pages list` | isolate-only / assets-only filters |\n| `worker cron <slug> [--dlq]` / `cron replay <slug> <runId>` | cron runs + DLQ replay (isolate) |\n| `secret put <KEY> --compute <slug>` | set a secret (value from `--value` or stdin); `--worker` still works |\n| `secret list \\| delete` | manage secrets |\n| `d1 list \\| create <name> \\| info <db>` | Durable SQLite databases |\n| `d1 execute <db> --command '<sql>'` | run SQL (`--file f.sql` too) |\n| `d1 export <db> [--output f]` | dump schema + data as SQL |\n| `d1 migrations create \\| list \\| apply` | file-based migrations (`--dir migrations`) |\n| `kv namespace list \\| create <title>` | KV namespaces |\n| `kv key put <ns> <key> <value>` / `get` / `list` / `delete` | KV entries |\n| `kv bulk put \\| delete <ns> <file.json>` | bulk KV |\n| `dev [--port]` | run the worker locally on **workerd** (prod runtime) |\n| `types [--out f]` | generate a bindings `Env` d.ts |\n| `secret bulk <file.json> --compute <slug>` | bulk secrets (`--worker` still works) |\n| `r2 bucket list \\| create <name> [--public]` | R2 buckets |\n| `r2 object put <bucket> <key> <file>` / `get` / `delete` | R2 objects |\n| `cdn list` / `cdn create <name> [--origin]` / `cdn get <id>` | list / create / inspect CDN sites |\n| `cdn enable <id>` / `cdn disable <id>` | `PATCH` site status `ENABLED` / `DISABLED` |\n| `cdn update <id> [--headers] [--redirects] [--compression] [--websocket] [--hotlink] [--user-agent] [--cors] [--security-policy] [--url-auth] [--dns] [--ip-allow] [--ip-deny]` | `PATCH` P1 fields (only supplied keys) |\n| `cdn update <id> [--origin-shield] [--http3] [--waf-rules]` | `PATCH` HTTP-site P2 fields (`originShield` / `http3` / `waf`) |\n| `cdn tcp list\\|create\\|get` / `cdn udp list\\|create\\|get` / `cdn l4 list` | `GET`/`POST` `/tcp`, `/udp`, `/l4` |\n| `cdn shield` | `GET` `/cdn-shield` (L2 parents) |\n| `cdn logs <id> [--limit N]` | `GET` `/cdn/:id/logs` |\n| `cdn purge <id> [--all] [--key url] [--prefix /path]` | purge CDN cache |\n| `dns list\\|create\\|get\\|delete\\|update` / `dns doh enable\\|disable` | authoritative zones + DoH (`/dns`) |\n| `dns record list\\|add\\|delete` | zone records `A`/`AAAA`/`CNAME`/`MX`/`NS`/`SOA` |\n| `dns routes get\\|put <zoneId>` | `GET`/`PUT` `/dns/:zoneId/routes` |\n| `dns intent get\\|put <zoneId>` | `GET`/`PUT` `/dns/:id/intent` (`mode` smart\\|off, `distribution` china\\|overseas\\|both) |\n| `dns vendor list\\|catalog\\|create\\|get\\|put\\|delete\\|push` | Aliyun / DNSPod / Huawei / HTTP line sync (`/dns/vendors`) |\n| `nodes isp-map get\\|put` | `GET`/`PUT` `/nodes/isp-map` (routeCodes: default / isp:china_telecom / isp:china_unicom / isp:china_mobile) |\n| `cdn smart-dns get <id>` / `cdn smart-dns <id> --enable\\|--disable` | `GET`/`PATCH` `/cdn/:id/smart-dns` |\n| `node sched get\\|put <id>` | `GET`/`PUT` `/nodes/:id/sched` |\n| `node ips get\\|put <id>` | `GET`/`PUT` `/nodes/:id/ips` |\n| `cluster health get\\|put\\|check` | `GET`/`PUT` `/cluster/health` + `POST` `/cluster/health/check` |\n| `waf list\\|create\\|get\\|delete\\|update` / `waf rule add` / `waf attach` | reusable WAF policies (`/waf`); attach via `PATCH` `/cdn/:id` `{ waf }` |\n| `pages get` / `env` / `builds` / `git` | assets-only aliases of `compute` |\n| `flow list` / `flow get <slug>` | list / inspect visual Flows |\n| `flow run <slug> [--input '<json>'] [--wait]` | trigger a Flow run (`--wait` = synchronous, returns output) |\n| `flow import <file.json>` | import a Flow export |\n| `post list` | list blog posts |\n| `post publish <file.md> [--title] [--slug] [--tags a,b] [--draft]` | publish (or draft) an MDX blog post |\n| `status` | fleet health — machines + services + open incidents |\n| `machine list` / `service list` / `incident list [--open]` | monitoring detail |\n| `api <METHOD> <path> [--data '<json>']` | raw API passthrough |\n\nGlobal flags: `--json` (machine-readable stdout), `--api`, `--token`.\n\n## Deploy config\n\n`rrangler.json`:\n\n```json\n{\n  \"name\": \"my-worker\",\n  \"main\": \"main.js\",\n  \"files\": [\"main.js\", \"lib/util.js\"],\n  \"compatibilityDate\": \"2026-07-05\",\n  \"d1_databases\":  [{ \"binding\": \"DB\", \"database_name\": \"my-db\" }],\n  \"kv_namespaces\": [{ \"binding\": \"RL\", \"title\": \"my-rl\" }],\n  \"r2_buckets\":    [{ \"binding\": \"R2\", \"bucket_name\": \"my-bucket\" }],\n  \"vars\": { \"READ_LIMIT\": \"600\" },\n  \"publish\": true\n}\n```\n\n`name` is the worker slug — an unknown one is **created on first deploy**\n(no UI needed). `d1_databases` / `kv_namespaces` / `r2_buckets` are\nwrangler-style resource declarations: missing databases/namespaces/buckets are\ncreated (matched by name) and their bindings synced on every deploy;\n`<BINDING>` + `<BINDING>_ID`/`_NS` land in `env` as usual. `vars` sets\nnon-secret env (secrets stay on `rrangler secret put`). Deploy publishes by\ndefault — `--no-publish` or `\"publish\": false` keeps DRAFT. `files` is\noptional — omit it to send just `main`; nested paths are **kept relative to\nthe common root** of `main` + `files` (so `src/index.js` importing\n`./lib/util.js` resolves and same-named files in different dirs don't\ncollide). A `wrangler.toml` with `name` / `main` is read as a fallback for\ndrop-in compatibility.\n\n> **Binding merge:** `deploy` only PATCHes the binding types it manages\n> (`d1_databases` / `kv_namespaces` / `r2_buckets` when present). Binding types\n> *not* in your config are left untouched — e.g. an R2 binding set once by hand\n> survives redeploys. Put a resource in the config to make deploy authoritative\n> for it.\n\n## Static assets (`env.ASSETS`)\n\nHost a browser frontend (like Cloudflare Workers Assets) — add an `assets`\nblock:\n\n```json\n{\n  \"name\": \"my-site\",\n  \"main\": \"src/index.js\",\n  \"assets\": { \"directory\": \"public\", \"binding\": \"ASSETS\", \"spa\": false }\n}\n```\n\nOn `deploy` (and `dev`) rrangler bundles `public/` and wraps your worker so\n`env.ASSETS.fetch(request)` serves those files — your Cloudflare-style code\nruns unmodified:\n\n```js\nexport default {\n  async fetch(request, env) {\n    if (request.method === \"GET\") {\n      const res = await env.ASSETS.fetch(request);   // static file if it exists\n      if (res.status !== 404) return res;\n    }\n    return handleApi(request, env);                    // your worker logic\n  },\n};\n```\n\n`binding` defaults to `ASSETS`; `spa: true` serves `index.html` for unmatched\nroutes (client-side routing). The bundle rides in the worker (base64), so keep\nit to app-sized assets. No plane-side asset store is needed — it's generated at\ndeploy time. For manual wiring without the config block:\n`rrangler assets bundle <dir> [-o out.mjs] [--spa]` writes a module exporting\n`makeAssets()`.\n\n## Durable Objects (`env.ROOM`)\n\nA single, globally-consistent stateful object — ideal for realtime/turn-based\nstate (a game room, a chat channel) where you want *one* instance all clients\nroute to, instead of many edge nodes hammering a central DB. Declare it:\n\n```json\n{\n  \"name\": \"chess\",\n  \"main\": \"src/index.js\",\n  \"durable_objects\": { \"bindings\": [{ \"name\": \"ROOM\", \"class_name\": \"GameRoom\" }] }\n}\n```\n\nThen write **standard Cloudflare DO code** — `export` the class, bind by name:\n\n```js\nexport class GameRoom {\n  constructor(state, env) { this.state = state; this.env = env; }\n  async fetch(req) {\n    let board = (await this.state.storage.get(\"board\")) ?? initialBoard();\n    // …apply the move, persist, respond. this.env.KV/D1/… are wired too.\n    await this.state.storage.put(\"board\", board);\n    return Response.json(board);\n  }\n}\n\nexport default {\n  async fetch(req, env) {\n    const game = new URL(req.url).searchParams.get(\"game\") || \"lobby\";\n    return env.ROOM.idFromName(game).get().fetch(req);   // one instance per game id\n  },\n};\n```\n\n`env.ROOM` is a full CF `DurableObjectNamespace` (`idFromName` / `idFromString`\n/ `newUniqueId` / `get`). The instance runs single-homed on one node (recorded\nin the plane; re-homed if that node dies), with `state.storage`\n(get/put/delete/list/transaction + `state.storage.sql`), alarms\n(`setAlarm`/`getAlarm`), and WebSocket hibernation (`state.acceptWebSocket`).\nNo central-DB round trips on the hot path.\n\n## Git connect\n\nBeyond wrangler: point a worker or Pages project at a GitHub repo so it\nauto-builds on push. This is server-side (the edge build runner clones + builds)\n— distinct from `deploy`, which uploads your local files directly.\n\n```sh\n# connect a repo, monorepo subdirectory + build command\nrrangler compute git set my-api \\\n  --repo https://github.com/me/monorepo.git \\\n  --branch main \\\n  --root-dir apps/api \\\n  --build-command 'npm ci && npm run build' \\\n  --output-file dist/index.js\n\nrrangler compute git get my-api          # inspect current config\nrrangler compute git disconnect my-api   # back to editor/upload mode\n\n# asset sites (legacy Pages) skip isolate-only output-file/entry flags\nrrangler compute git set my-site --repo … --root-dir apps/site --output-dir dist\nrrangler pages git set my-site --repo … --root-dir apps/site --output-dir dist\n```\n\nFlags (all optional; only the ones you pass change — it's a partial update):\n\n| flag | meaning |\n| --- | --- |\n| `--repo <url>` | HTTPS clone URL (empty to clear) |\n| `--branch <b>` | production branch (default `main`) |\n| `--root-dir <path>` | **monorepo**: subdir the project lives in; build runs there, output paths are relative to it |\n| `--build-command '<cmd>'` | shell build (blank = zero-config) |\n| `--output-dir <d>` | build output dir |\n| `--output-file <f>` / `--output-entry <e>` | worker-only: single-bundle file / entry |\n| `--git-token <t>` | PAT for private repos (`-` to clear; omit to keep) |\n| `--use-app-auth` / `--no-app-auth` | use the GitHub App for clones instead of a PAT |\n| `--build-env '<json>'` | build-time env vars, as a JSON object |\n\nSetting git config doesn't trigger a build — run one with\n`rrangler compute build <slug>` afterwards (`worker build` / `pages build` still work).\n\n## CDN\n\nRandallFlare CDN sites are hostnames that terminate on every public edge\nnode and reverse-proxy one or more origins. Tokens need `cdn:read` /\n`cdn:write`.\n\n```sh\nrrangler cdn create docs --origin https://origin.example.com\nrrangler cdn list\nrrangler cdn get <id>\nrrangler cdn enable <id>          # PATCH { \"status\": \"ENABLED\" }\nrrangler cdn disable <id>         # PATCH { \"status\": \"DISABLED\" }\nrrangler cdn update <id> --websocket --cors '{\"enabled\":true,\"allowOrigin\":[\"*\"]}'\nrrangler cdn update <id> --ip-allow 10.0.0.0/8 --ip-deny 1.2.3.4\nrrangler cdn update <id> --url-auth '{\"enabled\":true,\"mode\":\"typeA\",\"secret\":\"s\"}'\nrrangler cdn update <id> --dns '{\"provider\":\"cloudflare\",\"target\":\"edge.bigrandall.io\"}'\nrrangler cdn update <id> --origin-shield --http3\nrrangler cdn update <id> --waf-rules '[{\"param\":\"requestPath\",\"operator\":\"eq\",\"action\":\"PAGE\",\"value\":\"/x\",\"status\":403}]'\nrrangler cdn tcp create game --port 8081 --origin 10.0.0.8:25565\nrrangler cdn udp create voice --ports 2500-2600 --origin 10.0.0.8:3478\nrrangler cdn l4 list\nrrangler cdn shield\nrrangler dns create example.com --doh\nrrangler dns record add <zoneId> --type A --name www --value 203.0.113.10\nrrangler dns routes get <zoneId>\nrrangler dns routes put <zoneId> --data '{\"routes\":[{\"recordId\":\"r1\",\"line\":\"isp:china_telecom\"}]}'\nrrangler dns intent get <zoneId>\nrrangler dns intent put <zoneId> --mode smart --distribution both\nrrangler nodes isp-map get\nrrangler nodes isp-map put --data '{\"isp:china_telecom\":[\"<nodeId>\"],\"isp:china_unicom\":[],\"isp:china_mobile\":[],\"default\":[]}'\nrrangler cdn smart-dns get <id>\nrrangler cdn smart-dns <id> --enable\nrrangler cdn smart-dns <id> --disable\nrrangler node sched get <id>\nrrangler node sched put <id> --data '{\"standby\":true}'\nrrangler node ips get <id>\nrrangler node ips put <id> --data '{\"ips\":[\"203.0.113.10\"]}'\nrrangler cluster health get\nrrangler cluster health put --data '{\"enabled\":true,\"intervalSec\":30}'\nrrangler cluster health check\nrrangler waf create site-policy\nrrangler waf rule add <policyId> --param requestPath --operator eq --action PAGE --value /admin --status 403\nrrangler waf attach <policyId> --site <id>\nrrangler cdn logs <id>\nrrangler cdn purge <id> --all\nrrangler cdn purge <id> --prefix https://cdn.example.com/assets/\n```\n\nTCP/UDP sites are a separate L4 object on `/tcp`, `/udp`, and `/l4`.\nDo not create or PATCH them through `/cdn`. `waf attach` refuses L4.\nL2 (`features.originShield`) and HTTP/3 (`features.http3`) are HTTP-site\nswitches. Authoritative DNS + DoH is `/api/edge/v1/dns`, not\nthe main-site Cloudflare zone and not P1 `--dns` provider sync. P3-sched follows `/dns/:zoneId/routes`, `/nodes/:id/sched`, `/nodes/:id/ips`, and `/cluster/health` (no extra CLI shape). Full WAF\nrules live on `/api/edge/v1/waf` (`rules[]` plus country / province / IP\nlists); `cdn update --waf` is still the P1 `securityPolicy` alias.\n\n## Beyond wrangler\n\n- `doctor` — one-shot health + capability probe (what your token can actually do).\n- `api` — raw authenticated call to any `/api/edge/v1/*` endpoint for scripting.\n- `--json` on every read command for piping into `jq`.\n- Reads `rrangler.json` **or** `wrangler.toml`, so an existing CF project deploys\n  to RandallFlare without a rewrite.\n","readmeFilename":"README.md"}