-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwrangler.toml
More file actions
435 lines (382 loc) · 20.2 KB
/
wrangler.toml
File metadata and controls
435 lines (382 loc) · 20.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
# ============================================================================
# wrangler.toml — API Worker configuration (Cloudflare)
# ============================================================================
#
# THREE ENVIRONMENTS:
#
# Local dev → `wrangler dev` (ENVIRONMENT auto-set to "local" via .dev.vars)
# Secrets and local overrides loaded from .dev.vars (gitignored).
# Copy .dev.vars.example → .dev.vars and fill in your values.
# Uses live Cloudflare resources by default; pass --local to
# run KV/D1/R2 entirely on-device instead.
#
# Dev → `wrangler deploy --env dev`
# Deploys to *.workers.dev subdomain (no custom domain routes).
# ENVIRONMENT = "development" — full source maps, unoptimised
# Worker code, verbose logging. Angular DevTools works here.
# Run: deno task wrangler:deploy:dev
#
# Production → `wrangler deploy`
# Deploys to api.bloqr.jaysonknight.com via the [[routes]] block.
# ENVIRONMENT = "production". No [env.production] block needed —
# this file IS the production configuration.
#
# SECRETS — never put in this file; use `wrangler secret put` for production
# and .dev.vars for local dev:
# wrangler secret put TURNSTILE_SECRET_KEY
# wrangler secret put BETTER_AUTH_SECRET
# wrangler secret put CF_ACCESS_AUD
# wrangler secret put CORS_ALLOWED_ORIGINS
# wrangler secret put SENTRY_DSN
# wrangler secret put ANALYTICS_ACCOUNT_ID
# wrangler secret put ANALYTICS_API_TOKEN
# wrangler secret put OTEL_EXPORTER_OTLP_ENDPOINT
# ============================================================================
name = "adblock-compiler"
main = "worker/worker.ts"
compatibility_date = "2026-01-01"
# Enable Node.js compatibility for dependencies that import Node built-ins
# (e.g. agents and @cloudflare/playwright-mcp use async_hooks and path).
compatibility_flags = ["nodejs_compat"]
# Expose the worker on the *.workers.dev subdomain (fine for beta; disable
# once a custom domain is configured via a route or Workers Custom Domain).
workers_dev = true
# Forward all worker logs to Cloudflare Logpush (production only; no-op locally).
logpush = true
[[routes]]
pattern = "api.bloqr.jaysonknight.com"
custom_domain = true
# ─── import.meta.url shim ────────────────────────────────────────────────────
# Provides a stable fallback so that Node.js-compat polyfills
# (fileURLToPath, createRequire) work in the bundled Worker where
# import.meta.url is undefined after esbuild inlines all modules.
# This lets fileURLToPath succeed (returning /worker.js) and __dirname
# resolve to "/" — harmless since the Worker never touches the filesystem.
[define]
"import.meta.url" = '"file:///worker.js"'
# ─── Build ───────────────────────────────────────────────────────────────────
# Builds the Angular frontend and generates static assets before deployment.
# Wrangler runs this automatically on `wrangler deploy`.
# The script skips the build when ./frontend/dist already exists (e.g. in CI
# where the frontend artifact is downloaded before wrangler runs). A dedicated
# script is used instead of inline shell operators because wrangler's execa
# tokenises the command string, preventing `||` from being interpreted by the
# shell.
[build]
command = "sh scripts/build-worker.sh"
# ─── Browser Rendering ────────────────────────────────────────────────────────
# Provides a headless Chromium instance at the edge via Cloudflare Browser Rendering.
# Used by PlaywrightMcpAgent (worker/mcp-agent.ts) for AI-driven browser automation.
# Requires Cloudflare Workers Paid plan.
#
# IMPORTANT: Use [browser] (scalar table).
# Do NOT use [[browser_rendering]] — that is array-of-tables syntax and is silently
# ignored by wrangler, causing env.BROWSER to be undefined at runtime.
#
# Verify the binding is active:
# wrangler dev --remote (local dev with real CF bindings)
# GET https://api.bloqr.jaysonknight.com/api/browser/health (production check)
[browser]
binding = "BROWSER"
# ─── Observability ───────────────────────────────────────────────────────────
[observability.logs]
enabled = true
head_sampling_rate = 1
persist = true
invocation_logs = true
destinations = [ "sentry-logs" ]
[observability.traces]
enabled = true
head_sampling_rate = 1
persist = true
destinations = [ "sentry-traces" ]
# ─── Static runtime vars (non-secret, Cloudflare-deployed only) ──────────────
# RULE: This [vars] block is ONLY for non-secret values that must be present
# in the deployed Worker runtime. Do NOT add secrets here.
# Local dev values belong in .dev.vars (gitignored).
# All secrets use `wrangler secret put`.
[vars]
# Keep in sync with VERSION in src/version.ts. Run `deno task version:sync` to propagate.
COMPILER_VERSION = "0.88.0"
ENVIRONMENT = "production"
# Public Turnstile site key — not a secret; safe to commit.
# For local dev, .dev.vars overrides this with the always-pass test key (1x000...AA).
TURNSTILE_SITE_KEY = "0x4AAAAAACMKiPZdJh8I8IEM"
# Keep in sync with URL_FRONTEND, URL_API, and URL_DOCS below.
# For production, prefer: wrangler secret put CORS_ALLOWED_ORIGINS
CORS_ALLOWED_ORIGINS = "http://localhost:4200,http://localhost:8787,https://app.bloqr.jaysonknight.com,https://api.bloqr.jaysonknight.com"
# ─── Project URLs ─────────────────────────────────────────────────────────────
# Single source of truth for all public-facing service URLs.
# When you switch to a custom domain, update these values only, or run:
# deno task domain:swap
URL_FRONTEND = "https://app.bloqr.jaysonknight.com"
URL_API = "https://api.bloqr.jaysonknight.com"
URL_DOCS = "https://docs.bloqr.jaysonknight.com"
URL_LANDING = "https://bloqr.jaysonknight.com"
CANONICAL_DOMAIN = "bloqr.ai"
# ─── KV Namespaces ───────────────────────────────────────────────────────────
# `wrangler dev` binds to these live namespaces by default.
# Use `wrangler dev --local` to run against an on-device KV store instead.
[[kv_namespaces]]
binding = "COMPILATION_CACHE"
id = "7772628dc4ae46fbb145a811d2de351e"
[[kv_namespaces]]
binding = "RATE_LIMIT"
id = "5dc36da36d9142cc9ced6c56328898ee"
[[kv_namespaces]]
binding = "METRICS"
id = "025c3f10527c46c0be559f299bdba994"
# FEATURE_FLAGS: KV-backed feature flag store.
# Toggle flags at runtime without redeployment:
# wrangler kv:key put --binding FEATURE_FLAGS flag:ENABLE_BATCH_STREAMING '{"enabled":true,"updatedAt":"2025-01-01T00:00:00.000Z"}'
# Create with: wrangler kv:namespace create FEATURE_FLAGS
# See: docs/feature-flags/KV_FEATURE_FLAGS.md
[[kv_namespaces]]
binding = "FEATURE_FLAGS"
id = "532484fdfff448bbb6efc7847bf41700"
# RULES_KV: optional dedicated rule-set storage. Worker falls back to
# COMPILATION_CACHE when absent. Create with:
# wrangler kv:namespace create RULES_KV
# then add a [[kv_namespaces]] entry here.
# CONFIG_STORE: optional dedicated KV namespace for user-created configuration
# files (POST /api/configuration/create). Isolates 24h config entries from the
# short-lived compilation cache. Falls back to COMPILATION_CACHE when absent.
# Create with: wrangler kv:namespace create CONFIG_STORE
# then add a [[kv_namespaces]] entry here.
# ─── R2 Bucket ───────────────────────────────────────────────────────────────
[[r2_buckets]]
binding = "FILTER_STORAGE"
bucket_name = "adblock-compiler-r2-storage"
[[r2_buckets]]
binding = "COMPILER_LOGS"
bucket_name = "adblock-compiler-logs"
# ERROR_BUCKET — dedicated R2 bucket for error dead-letter logs.
# Written by handleErrorQueue() as NDJSON batches under errors/YYYY/MM/DD/HH/.
# Create with: wrangler r2 bucket create adblock-compiler-error-logs
[[r2_buckets]]
binding = "ERROR_BUCKET"
bucket_name = "adblock-compiler-error-logs"
# ─── Placement ───────────────────────────────────────────────────────────────
# Smart placement: prefer colos near Neon (Azure East US 2)
[placement]
mode = "smart"
# ─── D1 Database ─────────────────────────────────────────────────────────────
[[d1_databases]]
binding = "DB"
database_name = "adblock-compiler-d1-database"
database_id = "3e8e7dfe-3213-452a-a671-6c18e6e74ce5"
migrations_dir = "migrations"
[[d1_databases]]
binding = "ADMIN_DB"
database_name = "adblock-compiler-admin-d1"
database_id = "7d5a2704-5033-4433-911f-d8368f36dcdf"
migrations_dir = "admin-migrations"
# ─── Durable Objects ─────────────────────────────────────────────────────────
#
# How to add a new agent Durable Object:
#
# 1. Create the DO class in worker/<agent-name>.ts and export it from worker/worker.ts.
# 2. Add a [[durable_objects.bindings]] entry below with:
# name = "MY_AGENT" (UPPER_SNAKE_CASE — must match Env binding key)
# class_name = "MyAgentClass" (exported DO class name)
# 3. Add a [[migrations]] entry below with `new_sqlite_classes = ["MyAgentClass"]`
# (SQLite-backed DOs support DO storage API without KV; use `new_classes` for non-SQLite).
# 4. Add the corresponding binding to the Env interface in worker/types.ts.
# 5. Add a registry entry to worker/agents/registry.ts — this wires routing, auth, and
# route-permission entries automatically.
# 6. Run `wrangler deploy` to provision the new DO class in Cloudflare.
#
# Agent endpoints are secured by ZTA authentication middleware (worker/agents/agent-auth.ts)
# before the DO stub is invoked. Only UserTier.Admin can connect by default.
# See: https://developers.cloudflare.com/agents/getting-started/add-to-existing-project/
[[durable_objects.bindings]]
class_name = "AdblockCompiler"
name = "ADBLOCK_COMPILER"
# MCP_AGENT — Playwright MCP Agent (Cloudflare Browser Rendering + Model Context Protocol)
# Slug: mcp-agent → /agents/mcp-agent/{instanceId}
# Auth: UserTier.Admin only (see worker/agents/registry.ts)
[[durable_objects.bindings]]
class_name = "PlaywrightMcpAgent"
name = "MCP_AGENT"
# COMPILATION_COORDINATOR — Global request deduplication coordinator
# Provides single coordination point across all Worker instances to deduplicate
# concurrent compilation requests for identical configurations.
[[durable_objects.bindings]]
class_name = "CompilationCoordinator"
name = "COMPILATION_COORDINATOR"
# RATE_LIMITER_DO — Atomic per-identity rate limiting (replaces KV-based rate limiting)
# Provides strongly-consistent, race-free rate limiting via DO shard per identity.
# Each unique user ID or IP address gets its own DO shard (idFromName).
# checkRateLimitTiered() prefers this DO when bound; falls back to RATE_LIMIT KV.
# @see worker/rate-limiter-do.ts
[[durable_objects.bindings]]
class_name = "RateLimiterDO"
name = "RATE_LIMITER_DO"
# WS_HIBERNATION_DO — Hibernatable WebSocket connections with session presence
# Keeps long-lived WebSocket connections alive across Worker isolate teardowns.
# DO hibernates between messages — zero idle cost while connections stay open.
# Also tracks session presence (connected clients) via DO Storage.
# @see worker/ws-hibernation-do.ts
[[durable_objects.bindings]]
class_name = "WsHibernationDO"
name = "WS_HIBERNATION_DO"
# ─── Containers ─────────────────────────────────────────────────────────
# Each AdblockCompiler Durable Object manages one Docker container.
# Wrangler builds the image from Dockerfile.container on `wrangler deploy`.
# Requires Docker running locally or in CI.
# See: https://developers.cloudflare.com/containers/
#
# instance_type valid values: "basic" | "small" | "large"
# (NOT "standard" — that value is rejected with VALIDATE_INPUT by the CF API)
# scheduling_policy valid values: "regional" (co-located with Worker) | "earth" (globally distributed)
# Required by wrangler 4.14+; omitting it causes VALIDATE_INPUT on the /rollouts API endpoint.
[[containers]]
class_name = "AdblockCompiler"
image = "./Dockerfile.container"
max_instances = 5
instance_type = "basic"
scheduling_policy = "regional"
# ─── Migrations ──────────────────────────────────────────────────────────────
[[migrations]]
tag = "v1"
new_sqlite_classes = ["AdblockCompiler"]
[[migrations]]
tag = "v2"
new_sqlite_classes = ["PlaywrightMcpAgent"]
[[migrations]]
tag = "v3"
new_sqlite_classes = ["CompilationCoordinator"]
[[migrations]]
tag = "v4"
new_sqlite_classes = ["RateLimiterDO", "WsHibernationDO"]
# ─── Tail Workers ────────────────────────────────────────────────────────────
# Deploy wrangler.tail.toml first; the tail worker must exist in your account
# before this binding can be registered.
[[tail_consumers]]
service = "adblock-tail"
# ─── Queues ──────────────────────────────────────────────────────────────────
# Create queues before deploying:
# wrangler queues create adblock-compiler-worker-queue
# wrangler queues create adblock-compiler-worker-queue-high-priority
# wrangler queues create adblock-compiler-dlq
# wrangler queues create adblock-compiler-error-queue
[[queues.producers]]
queue = "adblock-compiler-worker-queue"
binding = "ADBLOCK_COMPILER_QUEUE"
[[queues.producers]]
queue = "adblock-compiler-worker-queue-high-priority"
binding = "ADBLOCK_COMPILER_QUEUE_HIGH_PRIORITY"
# ERROR_QUEUE — dedicated dead-letter queue, isolated from compile queues.
# Receives error events from app.onError(); consumer persists batches to ERROR_BUCKET.
[[queues.producers]]
queue = "adblock-compiler-error-queue"
binding = "ERROR_QUEUE"
[[queues.consumers]]
queue = "adblock-compiler-worker-queue"
max_batch_size = 10
max_batch_timeout = 5
dead_letter_queue = "adblock-compiler-dlq"
[[queues.consumers]]
queue = "adblock-compiler-worker-queue-high-priority"
max_batch_size = 5
max_batch_timeout = 2
dead_letter_queue = "adblock-compiler-dlq"
# Error queue consumer — small batches, short timeout for fast R2 persistence.
[[queues.consumers]]
queue = "adblock-compiler-error-queue"
max_batch_size = 25
max_batch_timeout = 10
# ─── Analytics Engine ────────────────────────────────────────────────────────
[[analytics_engine_datasets]]
binding = "ANALYTICS_ENGINE"
dataset = "adguard-compiler-analytics-engine"
# ─── Pipelines ───────────────────────────────────────────────────────────────
# Scalable, batched ingestion of structured events into R2.
# See: https://developers.cloudflare.com/pipelines/
[[pipelines]]
binding = "METRICS_PIPELINE"
pipeline = "c846e37117874905a94b1ef9da2e138e"
# ─── Workflows ───────────────────────────────────────────────────────────────
[[workflows]]
name = "compilation-workflow"
binding = "COMPILATION_WORKFLOW"
class_name = "CompilationWorkflow"
execution_model = "stateful"
[[workflows]]
name = "batch-compilation-workflow"
binding = "BATCH_COMPILATION_WORKFLOW"
class_name = "BatchCompilationWorkflow"
execution_model = "stateful"
[[workflows]]
name = "cache-warming-workflow"
binding = "CACHE_WARMING_WORKFLOW"
class_name = "CacheWarmingWorkflow"
execution_model = "stateful"
[[workflows]]
name = "health-monitoring-workflow"
binding = "HEALTH_MONITORING_WORKFLOW"
class_name = "HealthMonitoringWorkflow"
execution_model = "stateful"
# ─── Hyperdrive ──────────────────────────────────────────────────────────────
# Production connection string is set via `wrangler hyperdrive update`.
# For local dev, set the connection string in .dev.vars (gitignored):
# CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE=postgresql://<user>:<password>@<branch>.neon.tech/<dbname>?sslmode=require
# Create a personal dev branch at https://console.neon.tech → your project → Branches → New Branch.
# Do NOT put credentials in localConnectionString here.
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "800f7e2edc86488ab24e8621982e9ad7"
# ─── Cron Triggers ───────────────────────────────────────────────────────────
[triggers]
crons = [
"0 */6 * * *", # Cache warming: every 6 hours
"0 * * * *", # Health monitoring: every hour
]
# ─── Local dev server ────────────────────────────────────────────────────────
# These settings apply ONLY to `wrangler dev`. Ignored on `wrangler deploy`.
[dev]
port = 8787
local_protocol = "http"
# Set to true on Linux/macOS or WSL. Must be false on native Windows
# because Cloudflare Containers requires a Linux Docker daemon.
# See: https://developers.cloudflare.com/containers/
enable_containers = true
# ── Dynamic Workers loader (optional — requires Cloudflare Dynamic Workers beta access)
# Uncomment when your account has Dynamic Workers enabled.
# See: https://developers.cloudflare.com/dynamic-workers/
# See: https://github.com/jaypatrick/adblock-compiler/issues/1386
# [[bindings]]
# type = "dynamic_worker_loader"
# name = "DYNAMIC_WORKER_LOADER"
# ============================================================================
# [env.dev] — Dev environment (workers.dev only, no custom domain routes)
#
# Deploy: deno task wrangler:deploy:dev
#
# ENVIRONMENT = "development" so Sentry tags requests correctly and debug
# middleware / verbose logging is enabled on the Worker side.
#
# Routes: NOT inherited from top-level. This environment is accessible only
# via the auto-generated *.workers.dev subdomain (workers_dev = true is
# inherited from the top-level config).
#
# Bindings (KV, D1, R2, Queues, etc.) are inherited from the top-level
# config. Dev and production share the same Cloudflare resources by default.
# Create separate namespaces/databases and override them here when isolation
# is needed.
#
# Secrets: the same Worker Secrets apply to all environments. Use
# wrangler secret put <KEY> --env dev
# to set env-specific secrets if needed.
# ============================================================================
[env.dev]
logpush = false
[env.dev.vars]
ENVIRONMENT = "development"
COMPILER_VERSION = "0.83.0-dev"
CANONICAL_DOMAIN = "bloqr.ai"
CORS_ALLOWED_ORIGINS = "http://localhost:4200,http://localhost:8787"
URL_FRONTEND = "https://app.bloqr.jaysonknight.com"
URL_API = "https://api.bloqr.jaysonknight.com"
URL_DOCS = "https://docs.bloqr.jaysonknight.com"
URL_LANDING = "https://bloqr.jaysonknight.com"