opencodekit 0.15.3 → 0.15.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/template/.opencode/AGENTS.md +209 -77
- package/dist/template/.opencode/agent/plan.md +4 -0
- package/dist/template/.opencode/command/cloudflare.md +70 -0
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/skill/cloudflare/SKILL.md +233 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/README.md +35 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/api.md +100 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/configuration.md +99 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/gotchas.md +59 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/patterns.md +89 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-gateway/README.md +695 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/api.md +38 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/configuration.md +52 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/gotchas.md +41 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/patterns.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/api.md +27 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/configuration.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/gotchas.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/patterns.md +36 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/README.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/api.md +31 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/configuration.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/gotchas.md +28 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/patterns.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/README.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/api.md +78 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/configuration.md +128 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/gotchas.md +51 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/patterns.md +145 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/api.md +50 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/configuration.md +53 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/gotchas.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/patterns.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/configuration.md +58 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/gotchas.md +35 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/patterns.md +37 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/README.md +71 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/api.md +168 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/configuration.md +114 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/gotchas.md +99 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/patterns.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/api.md +54 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/configuration.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/gotchas.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/patterns.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/c3/README.md +264 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/README.md +93 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/api.md +176 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/configuration.md +164 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/gotchas.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/patterns.md +180 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/api.md +43 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/configuration.md +56 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/gotchas.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/patterns.md +40 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/README.md +85 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/api.md +198 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/configuration.md +151 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/gotchas.md +129 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/patterns.md +122 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/README.md +92 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/api.md +141 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/configuration.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/gotchas.md +70 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/patterns.md +144 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/README.md +34 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/api.md +136 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/configuration.md +67 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/gotchas.md +114 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/patterns.md +158 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/README.md +62 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/api.md +89 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/configuration.md +116 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/gotchas.md +93 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/patterns.md +112 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/README.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/api.md +152 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/configuration.md +148 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/gotchas.md +158 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/patterns.md +255 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/README.md +18 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/api.md +46 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/configuration.md +63 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/gotchas.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/patterns.md +46 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-workers/README.md +598 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/README.md +62 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/api.md +137 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/configuration.md +133 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/gotchas.md +184 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/patterns.md +176 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/configuration.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/gotchas.md +23 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/patterns.md +31 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/README.md +60 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/api.md +114 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/configuration.md +92 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/gotchas.md +117 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/patterns.md +139 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/README.md +64 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/api.md +144 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/configuration.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/gotchas.md +187 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/patterns.md +211 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/README.md +60 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/api.md +240 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/configuration.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/gotchas.md +171 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/patterns.md +171 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/README.md +18 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/api.md +51 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/configuration.md +60 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/gotchas.md +36 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/patterns.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/README.md +76 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/api.md +200 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/configuration.md +228 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/gotchas.md +161 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/patterns.md +145 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/README.md +57 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/api.md +201 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/configuration.md +159 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/gotchas.md +151 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/patterns.md +190 -0
- package/dist/template/.opencode/skill/cloudflare/references/pipelines/README.md +664 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/README.md +107 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/api.md +194 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/configuration.md +216 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/gotchas.md +223 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/patterns.md +139 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/README.md +69 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/api.md +138 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/configuration.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/gotchas.md +112 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/patterns.md +155 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/README.md +61 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/api.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/configuration.md +76 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/gotchas.md +94 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/patterns.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/README.md +18 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/api.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/configuration.md +39 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/gotchas.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/patterns.md +46 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-sql/README.md +512 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/README.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/api.md +135 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/configuration.md +63 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/gotchas.md +75 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/patterns.md +102 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/README.md +81 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/api.md +164 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/configuration.md +147 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/gotchas.md +172 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/patterns.md +155 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/README.md +90 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/api.md +178 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/configuration.md +131 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/gotchas.md +156 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/patterns.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/README.md +58 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/api.md +182 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/configuration.md +140 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/gotchas.md +129 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/patterns.md +218 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/README.md +91 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/api.md +139 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/configuration.md +129 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/gotchas.md +87 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/patterns.md +135 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/README.md +15 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/api.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/configuration.md +33 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/gotchas.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/patterns.md +34 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/api.md +24 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/configuration.md +43 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/gotchas.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/patterns.md +40 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/configuration.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/gotchas.md +44 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/patterns.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/README.md +103 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/api.md +204 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/configuration.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/gotchas.md +131 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/patterns.md +152 -0
- package/dist/template/.opencode/skill/cloudflare/references/tail-workers/README.md +640 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/README.md +76 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/api.md +159 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/configuration.md +156 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/gotchas.md +207 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/patterns.md +135 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/README.md +82 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/api.md +105 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/configuration.md +113 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/gotchas.md +115 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/patterns.md +157 -0
- package/dist/template/.opencode/skill/cloudflare/references/turn/README.md +699 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/configuration.md +19 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/gotchas.md +27 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/patterns.md +41 -0
- package/dist/template/.opencode/skill/cloudflare/references/vectorize/README.md +682 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/configuration.md +44 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/gotchas.md +24 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/patterns.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/README.md +19 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/api.md +52 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/configuration.md +31 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/gotchas.md +28 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/patterns.md +52 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/README.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/api.md +199 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/configuration.md +185 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/gotchas.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/patterns.md +216 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/README.md +96 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/api.md +137 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/configuration.md +147 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/gotchas.md +99 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/patterns.md +149 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-ai/README.md +116 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/README.md +48 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/api.md +169 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/configuration.md +136 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/gotchas.md +130 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/patterns.md +170 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/api.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/configuration.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/gotchas.md +35 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/patterns.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-vpc/README.md +579 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/README.md +62 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/api.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/configuration.md +177 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/gotchas.md +136 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/patterns.md +132 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/README.md +90 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/api.md +140 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/configuration.md +128 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/gotchas.md +93 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/patterns.md +150 -0
- package/dist/template/.opencode/skill/cloudflare/references/zaraz/README.md +360 -0
- package/dist/template/.opencode/skill/react-best-practices/AGENTS.md +2410 -0
- package/dist/template/.opencode/skill/react-best-practices/README.md +123 -0
- package/dist/template/.opencode/skill/react-best-practices/SKILL.md +125 -0
- package/dist/template/.opencode/skill/react-best-practices/metadata.json +15 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/_sections.md +46 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/_template.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-api-routes.md +38 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-defer-await.md +80 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-dependencies.md +36 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-parallel.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-conditional.md +31 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-preload.md +50 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-event-listeners.md +74 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-cache-storage.md +70 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-early-exit.md +50 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-index-maps.md +37 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-length-check-first.md +49 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-activity.md +26 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-memo.md +44 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-transitions.md +40 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-cache-lru.md +41 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-cache-react.md +76 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-serialization.md +38 -0
- package/dist/template/.opencode/skill/supabase/SKILL.md +120 -0
- package/dist/template/.opencode/skill/supabase/mcp.json +27 -0
- package/dist/template/.opencode/skill/vercel-deploy-claimable/SKILL.md +112 -0
- package/dist/template/.opencode/skill/vercel-deploy-claimable/scripts/deploy.sh +249 -0
- package/dist/template/.opencode/skill/web-design-guidelines/SKILL.md +39 -0
- package/package.json +1 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
See [README.md](./README.md) for overview, [configuration.md](./configuration.md) for setup.
|
|
4
|
+
|
|
5
|
+
## Binding Interface
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
interface Hyperdrive {
|
|
9
|
+
connectionString: string; // PostgreSQL
|
|
10
|
+
// MySQL properties:
|
|
11
|
+
host: string;
|
|
12
|
+
port: number;
|
|
13
|
+
user: string;
|
|
14
|
+
password: string;
|
|
15
|
+
database: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface Env {
|
|
19
|
+
HYPERDRIVE: Hyperdrive;
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## PostgreSQL (node-postgres) - RECOMMENDED
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { Client } from "pg"; // pg@^8.16.3, @types/pg
|
|
27
|
+
|
|
28
|
+
export default {
|
|
29
|
+
async fetch(req: Request, env: Env): Promise<Response> {
|
|
30
|
+
const client = new Client({connectionString: env.HYPERDRIVE.connectionString});
|
|
31
|
+
try {
|
|
32
|
+
await client.connect();
|
|
33
|
+
const result = await client.query("SELECT * FROM users WHERE id = $1", [123]);
|
|
34
|
+
return Response.json(result.rows);
|
|
35
|
+
} finally {
|
|
36
|
+
await client.end();
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## PostgreSQL (postgres.js)
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import postgres from "postgres"; // postgres@^3.4.5
|
|
46
|
+
|
|
47
|
+
const sql = postgres(env.HYPERDRIVE.connectionString, {
|
|
48
|
+
max: 5, // Limit per Worker
|
|
49
|
+
prepare: true, // ⚠️ CRITICAL for caching
|
|
50
|
+
fetch_types: false, // Reduce latency if not using arrays
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const users = await sql`SELECT * FROM users WHERE active = ${true} LIMIT 10`;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**⚠️ `prepare: true` required for Hyperdrive caching.** `false` disables prepared statements + cache.
|
|
57
|
+
|
|
58
|
+
## MySQL (mysql2)
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { createConnection } from "mysql2/promise"; // mysql2@^3.13.0
|
|
62
|
+
|
|
63
|
+
const conn = await createConnection({
|
|
64
|
+
host: env.HYPERDRIVE.host,
|
|
65
|
+
user: env.HYPERDRIVE.user,
|
|
66
|
+
password: env.HYPERDRIVE.password,
|
|
67
|
+
database: env.HYPERDRIVE.database,
|
|
68
|
+
port: env.HYPERDRIVE.port,
|
|
69
|
+
disableEval: true, // ⚠️ REQUIRED for Workers
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const [results] = await conn.query("SELECT * FROM users WHERE active = ? LIMIT ?", [true, 10]);
|
|
73
|
+
ctx.waitUntil(conn.end());
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Query Caching
|
|
77
|
+
|
|
78
|
+
**Cacheable:**
|
|
79
|
+
```sql
|
|
80
|
+
SELECT * FROM posts WHERE published = true;
|
|
81
|
+
SELECT COUNT(*) FROM users;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**NOT cacheable:**
|
|
85
|
+
```sql
|
|
86
|
+
-- Writes
|
|
87
|
+
INSERT/UPDATE/DELETE
|
|
88
|
+
|
|
89
|
+
-- Volatile functions
|
|
90
|
+
SELECT NOW();
|
|
91
|
+
SELECT random();
|
|
92
|
+
SELECT LASTVAL(); -- PostgreSQL
|
|
93
|
+
SELECT UUID(); -- MySQL
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Cache config:**
|
|
97
|
+
- Default: `max_age=60s`, `swr=15s`
|
|
98
|
+
- Max `max_age`: 3600s
|
|
99
|
+
- Disable: `--caching-disabled=true`
|
|
100
|
+
|
|
101
|
+
**Multiple configs pattern:**
|
|
102
|
+
```typescript
|
|
103
|
+
// Reads: cached
|
|
104
|
+
const sqlCached = postgres(env.HYPERDRIVE_CACHED.connectionString);
|
|
105
|
+
const posts = await sqlCached`SELECT * FROM posts ORDER BY views DESC LIMIT 10`;
|
|
106
|
+
|
|
107
|
+
// Writes/time-sensitive: no cache
|
|
108
|
+
const sqlNoCache = postgres(env.HYPERDRIVE_NO_CACHE.connectionString);
|
|
109
|
+
const orders = await sqlNoCache`SELECT * FROM orders WHERE created_at > NOW() - INTERVAL 5 MINUTE`;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## ORMs
|
|
113
|
+
|
|
114
|
+
**Drizzle:**
|
|
115
|
+
```typescript
|
|
116
|
+
import { drizzle } from "drizzle-orm/postgres-js"; // drizzle-orm@^0.26.2
|
|
117
|
+
import postgres from "postgres";
|
|
118
|
+
|
|
119
|
+
const client = postgres(env.HYPERDRIVE.connectionString, {max: 5, prepare: true});
|
|
120
|
+
const db = drizzle(client);
|
|
121
|
+
const users = await db.select().from(users).where(eq(users.active, true)).limit(10);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Kysely:**
|
|
125
|
+
```typescript
|
|
126
|
+
import { Kysely, PostgresDialect } from "kysely"; // kysely@^0.26.3
|
|
127
|
+
import postgres from "postgres";
|
|
128
|
+
|
|
129
|
+
const db = new Kysely({
|
|
130
|
+
dialect: new PostgresDialect({
|
|
131
|
+
postgres: postgres(env.HYPERDRIVE.connectionString, {max: 5, prepare: true}),
|
|
132
|
+
}),
|
|
133
|
+
});
|
|
134
|
+
const users = await db.selectFrom("users").selectAll().where("active", "=", true).execute();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
See [patterns.md](./patterns.md) for use cases, [gotchas.md](./gotchas.md) for limits.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
See [README.md](./README.md) for overview.
|
|
4
|
+
|
|
5
|
+
## Create Config
|
|
6
|
+
|
|
7
|
+
**PostgreSQL:**
|
|
8
|
+
```bash
|
|
9
|
+
# Basic
|
|
10
|
+
npx wrangler hyperdrive create my-db \
|
|
11
|
+
--connection-string="postgres://user:pass@host:5432/db"
|
|
12
|
+
|
|
13
|
+
# Custom cache
|
|
14
|
+
npx wrangler hyperdrive create my-db \
|
|
15
|
+
--connection-string="postgres://..." \
|
|
16
|
+
--max-age=120 --swr=30
|
|
17
|
+
|
|
18
|
+
# No cache
|
|
19
|
+
npx wrangler hyperdrive create my-db \
|
|
20
|
+
--connection-string="postgres://..." \
|
|
21
|
+
--caching-disabled=true
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**MySQL:**
|
|
25
|
+
```bash
|
|
26
|
+
npx wrangler hyperdrive create my-db \
|
|
27
|
+
--connection-string="mysql://user:pass@host:3306/db"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## wrangler.jsonc
|
|
31
|
+
|
|
32
|
+
```jsonc
|
|
33
|
+
{
|
|
34
|
+
"compatibility_date": "2024-09-23",
|
|
35
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
36
|
+
"hyperdrive": [
|
|
37
|
+
{
|
|
38
|
+
"binding": "HYPERDRIVE",
|
|
39
|
+
"id": "<HYPERDRIVE_ID>",
|
|
40
|
+
"localConnectionString": "postgres://user:pass@localhost:5432/dev"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Multiple configs:**
|
|
47
|
+
```jsonc
|
|
48
|
+
{
|
|
49
|
+
"hyperdrive": [
|
|
50
|
+
{"binding": "HYPERDRIVE_CACHED", "id": "<ID1>"},
|
|
51
|
+
{"binding": "HYPERDRIVE_NO_CACHE", "id": "<ID2>"}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Management
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx wrangler hyperdrive list
|
|
60
|
+
npx wrangler hyperdrive get <ID>
|
|
61
|
+
npx wrangler hyperdrive update <ID> --max-age=180
|
|
62
|
+
npx wrangler hyperdrive delete <ID>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Config Options
|
|
66
|
+
|
|
67
|
+
| Option | Default | Notes |
|
|
68
|
+
|--------|---------|-------|
|
|
69
|
+
| `--caching-disabled` | `false` | Disable caching |
|
|
70
|
+
| `--max-age` | `60` | Cache TTL (max 3600s) |
|
|
71
|
+
| `--swr` | `15` | Stale-while-revalidate |
|
|
72
|
+
| `--origin-connection-limit` | 20/100 | Free/paid |
|
|
73
|
+
| `--access-client-id` | - | Tunnel auth |
|
|
74
|
+
| `--access-client-secret` | - | Tunnel auth |
|
|
75
|
+
| `--sslmode` | `require` | PostgreSQL only |
|
|
76
|
+
|
|
77
|
+
## Private DB via Tunnel
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
Worker → Hyperdrive → Access → Tunnel → Private Network → DB
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Setup:**
|
|
84
|
+
```bash
|
|
85
|
+
# 1. Create tunnel
|
|
86
|
+
cloudflared tunnel create my-db-tunnel
|
|
87
|
+
|
|
88
|
+
# 2. Configure hostname in Zero Trust dashboard
|
|
89
|
+
# Domain: db-tunnel.example.com
|
|
90
|
+
# Service: TCP -> localhost:5432
|
|
91
|
+
|
|
92
|
+
# 3. Create service token (Zero Trust > Service Auth)
|
|
93
|
+
# Save Client ID/Secret
|
|
94
|
+
|
|
95
|
+
# 4. Create Access app (db-tunnel.example.com)
|
|
96
|
+
# Policy: Service Auth token from step 3
|
|
97
|
+
|
|
98
|
+
# 5. Create Hyperdrive
|
|
99
|
+
npx wrangler hyperdrive create my-private-db \
|
|
100
|
+
--host=db-tunnel.example.com \
|
|
101
|
+
--user=dbuser --password=dbpass --database=prod \
|
|
102
|
+
--access-client-id=<ID> --access-client-secret=<SECRET>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**⚠️ Don't specify `--port` with Tunnel** - port configured in tunnel service settings.
|
|
106
|
+
|
|
107
|
+
## Local Dev
|
|
108
|
+
|
|
109
|
+
**Option 1: Local (RECOMMENDED):**
|
|
110
|
+
```bash
|
|
111
|
+
# Env var (takes precedence)
|
|
112
|
+
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgres://user:pass@localhost:5432/dev"
|
|
113
|
+
npx wrangler dev
|
|
114
|
+
|
|
115
|
+
# wrangler.jsonc
|
|
116
|
+
{"hyperdrive": [{"binding": "HYPERDRIVE", "localConnectionString": "postgres://..."}]}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Remote DB locally:**
|
|
120
|
+
```bash
|
|
121
|
+
# PostgreSQL
|
|
122
|
+
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgres://user:pass@remote:5432/db?sslmode=require"
|
|
123
|
+
|
|
124
|
+
# MySQL
|
|
125
|
+
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="mysql://user:pass@remote:3306/db?sslMode=REQUIRED"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Option 2: Remote execution:**
|
|
129
|
+
```bash
|
|
130
|
+
npx wrangler dev --remote # Uses deployed config, affects production
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
See [api.md](./api.md), [patterns.md](./patterns.md), [gotchas.md](./gotchas.md).
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Gotchas
|
|
2
|
+
|
|
3
|
+
See [README.md](./README.md), [configuration.md](./configuration.md), [api.md](./api.md), [patterns.md](./patterns.md).
|
|
4
|
+
|
|
5
|
+
## Limits
|
|
6
|
+
|
|
7
|
+
**Config:**
|
|
8
|
+
| Limit | Free | Paid |
|
|
9
|
+
|-------|------|------|
|
|
10
|
+
| Max configs | 10 | 25 |
|
|
11
|
+
| Username/DB name | 63 bytes | 63 bytes |
|
|
12
|
+
|
|
13
|
+
**Connections:**
|
|
14
|
+
| Limit | Free | Paid |
|
|
15
|
+
|-------|------|------|
|
|
16
|
+
| Connection timeout | 15s | 15s |
|
|
17
|
+
| Idle timeout | 10min | 10min |
|
|
18
|
+
| Max origin connections | ~20 | ~100 |
|
|
19
|
+
|
|
20
|
+
**Queries:**
|
|
21
|
+
| Limit | Value |
|
|
22
|
+
|-------|-------|
|
|
23
|
+
| Max duration | 60s |
|
|
24
|
+
| Max cached response | 50MB |
|
|
25
|
+
|
|
26
|
+
**Note:** Queries >60s terminated. Responses >50MB returned but not cached.
|
|
27
|
+
|
|
28
|
+
## Common Errors
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
try {
|
|
32
|
+
const result = await client.query("SELECT * FROM users");
|
|
33
|
+
} catch (error: any) {
|
|
34
|
+
const msg = error.message || "";
|
|
35
|
+
|
|
36
|
+
// Pool exhausted
|
|
37
|
+
if (msg.includes("Failed to acquire a connection")) {
|
|
38
|
+
console.error("Pool exhausted - long transactions?");
|
|
39
|
+
return new Response("Service busy", {status: 503});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Connection refused
|
|
43
|
+
if (msg.includes("connection_refused")) {
|
|
44
|
+
console.error("DB refusing - firewall/limits?");
|
|
45
|
+
return new Response("DB unavailable", {status: 503});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Timeout
|
|
49
|
+
if (msg.includes("timeout") || msg.includes("deadline exceeded")) {
|
|
50
|
+
console.error("Query timeout - exceeded 60s");
|
|
51
|
+
return new Response("Query timeout", {status: 504});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Auth failure
|
|
55
|
+
if (msg.includes("password authentication failed")) {
|
|
56
|
+
console.error("Auth failed - check credentials");
|
|
57
|
+
return new Response("Config error", {status: 500});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// SSL/TLS
|
|
61
|
+
if (msg.includes("SSL") || msg.includes("TLS")) {
|
|
62
|
+
console.error("TLS issue - check sslmode");
|
|
63
|
+
return new Response("Connection security error", {status: 500});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.error("Unknown DB error:", error);
|
|
67
|
+
return new Response("Internal error", {status: 500});
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Monitor Connections
|
|
72
|
+
|
|
73
|
+
**PostgreSQL:**
|
|
74
|
+
```sql
|
|
75
|
+
-- Show Hyperdrive connections
|
|
76
|
+
SELECT usename, application_name, client_addr, state
|
|
77
|
+
FROM pg_stat_activity
|
|
78
|
+
WHERE application_name = 'Cloudflare Hyperdrive';
|
|
79
|
+
|
|
80
|
+
-- Count active
|
|
81
|
+
SELECT COUNT(*) FROM pg_stat_activity WHERE application_name = 'Cloudflare Hyperdrive';
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Troubleshooting
|
|
85
|
+
|
|
86
|
+
**Connection refused:**
|
|
87
|
+
1. Check firewall allows Cloudflare IPs
|
|
88
|
+
2. Verify DB listening on port
|
|
89
|
+
3. Confirm service running
|
|
90
|
+
4. Check credentials
|
|
91
|
+
|
|
92
|
+
**Pool exhausted:**
|
|
93
|
+
1. Reduce transaction duration
|
|
94
|
+
2. Avoid long queries (>60s)
|
|
95
|
+
3. Don't hold connections during external calls
|
|
96
|
+
4. Upgrade to paid plan
|
|
97
|
+
|
|
98
|
+
**SSL/TLS failed:**
|
|
99
|
+
1. Add `sslmode=require` (Postgres) or `sslMode=REQUIRED` (MySQL)
|
|
100
|
+
2. Upload CA cert if self-signed
|
|
101
|
+
3. Verify DB has SSL enabled
|
|
102
|
+
4. Check cert expiry
|
|
103
|
+
|
|
104
|
+
**Queries not cached:**
|
|
105
|
+
1. Verify non-mutating (SELECT)
|
|
106
|
+
2. Check for volatile functions (NOW(), RANDOM())
|
|
107
|
+
3. Confirm caching not disabled
|
|
108
|
+
4. Use `wrangler dev --remote` to test
|
|
109
|
+
5. Check `prepare=true` for postgres.js
|
|
110
|
+
|
|
111
|
+
**Query timeout (>60s):**
|
|
112
|
+
1. Optimize with indexes
|
|
113
|
+
2. Reduce dataset (LIMIT)
|
|
114
|
+
3. Break into smaller queries
|
|
115
|
+
4. Use async processing
|
|
116
|
+
|
|
117
|
+
**Local DB connection:**
|
|
118
|
+
1. Verify `localConnectionString` correct
|
|
119
|
+
2. Check DB running
|
|
120
|
+
3. Confirm env var name matches binding
|
|
121
|
+
4. Test with psql/mysql client
|
|
122
|
+
|
|
123
|
+
**Env var not working:**
|
|
124
|
+
1. Format: `CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_<BINDING>`
|
|
125
|
+
2. Binding matches wrangler.jsonc
|
|
126
|
+
3. Variable exported in shell
|
|
127
|
+
4. Restart wrangler dev
|
|
128
|
+
|
|
129
|
+
## Migration Checklist
|
|
130
|
+
|
|
131
|
+
- [ ] Create config via Wrangler
|
|
132
|
+
- [ ] Add binding to wrangler.jsonc
|
|
133
|
+
- [ ] Enable `nodejs_compat` flag
|
|
134
|
+
- [ ] Set `compatibility_date` >= `2024-09-23`
|
|
135
|
+
- [ ] Update code to `env.HYPERDRIVE.connectionString` (Postgres) or properties (MySQL)
|
|
136
|
+
- [ ] Configure `localConnectionString`
|
|
137
|
+
- [ ] Set `prepare: true` (postgres.js) or `disableEval: true` (mysql2)
|
|
138
|
+
- [ ] Test locally with `wrangler dev`
|
|
139
|
+
- [ ] Deploy + monitor pool usage
|
|
140
|
+
- [ ] Validate cache with `wrangler dev --remote`
|
|
141
|
+
- [ ] Update firewall (Cloudflare IPs)
|
|
142
|
+
- [ ] Configure observability
|
|
143
|
+
|
|
144
|
+
## Supported Databases
|
|
145
|
+
|
|
146
|
+
**PostgreSQL:**
|
|
147
|
+
- PostgreSQL 11+
|
|
148
|
+
- CockroachDB, Timescale, Materialize
|
|
149
|
+
- Neon, Supabase
|
|
150
|
+
|
|
151
|
+
Recommended: `pg` >= 8.16.3
|
|
152
|
+
|
|
153
|
+
**MySQL:**
|
|
154
|
+
- MySQL 5.7+
|
|
155
|
+
- PlanetScale
|
|
156
|
+
|
|
157
|
+
Recommended: `mysql2` >= 3.13.0
|
|
158
|
+
|
|
159
|
+
**SSL/TLS:**
|
|
160
|
+
- PostgreSQL `sslmode`: `require`, `verify-ca`, `verify-full`
|
|
161
|
+
- MySQL `sslMode`: `REQUIRED`, `VERIFY_CA`, `VERIFY_IDENTITY`
|
|
162
|
+
|
|
163
|
+
## When NOT to Use
|
|
164
|
+
|
|
165
|
+
❌ Write-heavy workloads (limited cache benefit)
|
|
166
|
+
❌ Real-time data requirements (<1s freshness)
|
|
167
|
+
❌ Single-region apps close to DB
|
|
168
|
+
❌ Very simple apps (overhead unjustified)
|
|
169
|
+
❌ DB with strict connection limits already exceeded
|
|
170
|
+
|
|
171
|
+
**Alternatives:**
|
|
172
|
+
- D1 - Cloudflare native distributed SQL
|
|
173
|
+
- Durable Objects - Stateful Workers
|
|
174
|
+
- KV - Global key-value
|
|
175
|
+
- R2 - Object storage
|
|
176
|
+
|
|
177
|
+
## Resources
|
|
178
|
+
|
|
179
|
+
- [Docs](https://developers.cloudflare.com/hyperdrive/)
|
|
180
|
+
- [Getting Started](https://developers.cloudflare.com/hyperdrive/get-started/)
|
|
181
|
+
- [Wrangler Reference](https://developers.cloudflare.com/hyperdrive/reference/wrangler-commands/)
|
|
182
|
+
- [Supported DBs](https://developers.cloudflare.com/hyperdrive/reference/supported-databases-and-features/)
|
|
183
|
+
- [Discord #hyperdrive](https://discord.cloudflare.com)
|
|
184
|
+
- [Limit Increase Form](https://forms.gle/ukpeZVLWLnKeixDu7)
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Patterns
|
|
2
|
+
|
|
3
|
+
See [README.md](./README.md), [configuration.md](./configuration.md), [api.md](./api.md).
|
|
4
|
+
|
|
5
|
+
## High-Traffic Read-Heavy
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
const sql = postgres(env.HYPERDRIVE.connectionString, {max: 5, prepare: true});
|
|
9
|
+
|
|
10
|
+
// Cacheable: popular content
|
|
11
|
+
const posts = await sql`SELECT * FROM posts WHERE published = true ORDER BY views DESC LIMIT 20`;
|
|
12
|
+
|
|
13
|
+
// Cacheable: user profiles
|
|
14
|
+
const [user] = await sql`SELECT id, username, bio FROM users WHERE id = ${userId}`;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Benefits:** Trending/profiles cached (60s), connection pooling handles spikes.
|
|
18
|
+
|
|
19
|
+
## Mixed Read/Write
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
interface Env {
|
|
23
|
+
HYPERDRIVE_CACHED: Hyperdrive; // max_age=120
|
|
24
|
+
HYPERDRIVE_REALTIME: Hyperdrive; // caching disabled
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Reads: cached
|
|
28
|
+
if (req.method === "GET") {
|
|
29
|
+
const sql = postgres(env.HYPERDRIVE_CACHED.connectionString, {prepare: true});
|
|
30
|
+
const products = await sql`SELECT * FROM products WHERE category = ${cat}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Writes: no cache (immediate consistency)
|
|
34
|
+
if (req.method === "POST") {
|
|
35
|
+
const sql = postgres(env.HYPERDRIVE_REALTIME.connectionString, {prepare: true});
|
|
36
|
+
await sql`INSERT INTO orders ${sql(data)}`;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Analytics Dashboard
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
const client = new Client({connectionString: env.HYPERDRIVE.connectionString});
|
|
44
|
+
await client.connect();
|
|
45
|
+
|
|
46
|
+
// Aggregate queries cached
|
|
47
|
+
const dailyStats = await client.query(`
|
|
48
|
+
SELECT DATE(created_at) as date, COUNT(*) as orders, SUM(amount) as revenue
|
|
49
|
+
FROM orders WHERE created_at >= NOW() - INTERVAL '30 days'
|
|
50
|
+
GROUP BY DATE(created_at) ORDER BY date DESC
|
|
51
|
+
`);
|
|
52
|
+
|
|
53
|
+
const topProducts = await client.query(`
|
|
54
|
+
SELECT p.name, COUNT(oi.id) as count, SUM(oi.quantity * oi.price) as revenue
|
|
55
|
+
FROM order_items oi JOIN products p ON oi.product_id = p.id
|
|
56
|
+
WHERE oi.created_at >= NOW() - INTERVAL '7 days'
|
|
57
|
+
GROUP BY p.id, p.name ORDER BY revenue DESC LIMIT 10
|
|
58
|
+
`);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Benefits:** Expensive aggregations cached, dashboard instant, reduced DB load.
|
|
62
|
+
|
|
63
|
+
## Multi-Tenant
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const tenantId = req.headers.get("X-Tenant-ID");
|
|
67
|
+
const sql = postgres(env.HYPERDRIVE.connectionString, {prepare: true});
|
|
68
|
+
|
|
69
|
+
// Tenant-scoped queries cached separately
|
|
70
|
+
const docs = await sql`
|
|
71
|
+
SELECT * FROM documents
|
|
72
|
+
WHERE tenant_id = ${tenantId} AND deleted_at IS NULL
|
|
73
|
+
ORDER BY updated_at DESC LIMIT 50
|
|
74
|
+
`;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Benefits:** Per-tenant caching, shared connection pool, protects DB from multi-tenant load.
|
|
78
|
+
|
|
79
|
+
## Geographically Distributed
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Worker runs at edge nearest user
|
|
83
|
+
// Connection setup at edge (fast), pooling near DB (efficient)
|
|
84
|
+
const sql = postgres(env.HYPERDRIVE.connectionString, {prepare: true});
|
|
85
|
+
const [user] = await sql`SELECT * FROM users WHERE id = ${userId}`;
|
|
86
|
+
|
|
87
|
+
return Response.json({
|
|
88
|
+
user,
|
|
89
|
+
serverRegion: req.cf?.colo, // Edge location
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Benefits:** Edge setup + DB pooling = global → single-region DB without replication.
|
|
94
|
+
|
|
95
|
+
## Connection Pooling
|
|
96
|
+
|
|
97
|
+
Operates in **transaction mode**: connection acquired per transaction, `RESET` on return.
|
|
98
|
+
|
|
99
|
+
**SET statements:**
|
|
100
|
+
```typescript
|
|
101
|
+
// ✅ Within transaction
|
|
102
|
+
await client.query("BEGIN");
|
|
103
|
+
await client.query("SET work_mem = '256MB'");
|
|
104
|
+
await client.query("SELECT * FROM large_table"); // Uses SET
|
|
105
|
+
await client.query("COMMIT"); // RESET after
|
|
106
|
+
|
|
107
|
+
// ✅ Single statement
|
|
108
|
+
await client.query("SET work_mem = '256MB'; SELECT * FROM large_table");
|
|
109
|
+
|
|
110
|
+
// ❌ Across queries (may get different connection)
|
|
111
|
+
await client.query("SET work_mem = '256MB'");
|
|
112
|
+
await client.query("SELECT * FROM large_table"); // SET not applied
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Best practices:**
|
|
116
|
+
```typescript
|
|
117
|
+
// ❌ Long transactions block pooling
|
|
118
|
+
await client.query("BEGIN");
|
|
119
|
+
await processThousands(); // Connection held entire time
|
|
120
|
+
await client.query("COMMIT");
|
|
121
|
+
|
|
122
|
+
// ✅ Short transactions
|
|
123
|
+
await client.query("BEGIN");
|
|
124
|
+
await client.query("UPDATE users SET status = $1 WHERE id = $2", [status, id]);
|
|
125
|
+
await client.query("COMMIT");
|
|
126
|
+
|
|
127
|
+
// ✅ SET LOCAL within transaction
|
|
128
|
+
await client.query("BEGIN");
|
|
129
|
+
await client.query("SET LOCAL work_mem = '256MB'");
|
|
130
|
+
await client.query("SELECT * FROM large_table");
|
|
131
|
+
await client.query("COMMIT");
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Performance Tips
|
|
135
|
+
|
|
136
|
+
**1. Enable prepared statements:**
|
|
137
|
+
```typescript
|
|
138
|
+
// ✅ Best
|
|
139
|
+
const sql = postgres(connectionString, {prepare: true}); // Caching enabled
|
|
140
|
+
|
|
141
|
+
// ❌ Slower
|
|
142
|
+
const sql = postgres(connectionString, {prepare: false}); // Extra round-trips
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**2. Optimize settings:**
|
|
146
|
+
```typescript
|
|
147
|
+
const sql = postgres(connectionString, {
|
|
148
|
+
max: 5, // Limit per Worker
|
|
149
|
+
fetch_types: false, // Skip if not using arrays
|
|
150
|
+
prepare: true,
|
|
151
|
+
idle_timeout: 60, // Match Worker lifetime
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**3. Cache-friendly queries:**
|
|
156
|
+
```typescript
|
|
157
|
+
// ✅ Cacheable (deterministic)
|
|
158
|
+
await sql`SELECT * FROM products WHERE category = 'electronics' LIMIT 10`;
|
|
159
|
+
|
|
160
|
+
// ❌ Not cacheable (volatile)
|
|
161
|
+
await sql`SELECT * FROM logs WHERE created_at > NOW()`;
|
|
162
|
+
|
|
163
|
+
// ✅ Make cacheable (parameterize)
|
|
164
|
+
const ts = Date.now();
|
|
165
|
+
await sql`SELECT * FROM logs WHERE created_at > ${ts}`;
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**4. Monitor cache hits:**
|
|
169
|
+
```typescript
|
|
170
|
+
const start = Date.now();
|
|
171
|
+
const result = await sql`SELECT * FROM users LIMIT 10`;
|
|
172
|
+
const duration = Date.now() - start;
|
|
173
|
+
console.log({duration, likelyCached: duration < 10}); // <10ms = cache hit
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
See [gotchas.md](./gotchas.md) for limits, troubleshooting.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Cloudflare Images Skill Reference
|
|
2
|
+
|
|
3
|
+
**Cloudflare Images** is an end-to-end image management solution providing storage, transformation, optimization, and delivery at scale via Cloudflare's global network....
|
|
4
|
+
|
|
5
|
+
## In This Reference
|
|
6
|
+
|
|
7
|
+
- **[configuration.md](./configuration.md)** - Setup, deployment, configuration
|
|
8
|
+
- **[api.md](./api.md)** - API endpoints, methods, interfaces
|
|
9
|
+
- **[patterns.md](./patterns.md)** - Common patterns, use cases, examples
|
|
10
|
+
- **[gotchas.md](./gotchas.md)** - Troubleshooting, best practices, limitations
|
|
11
|
+
|
|
12
|
+
## See Also
|
|
13
|
+
|
|
14
|
+
- [Cloudflare Docs](https://developers.cloudflare.com/)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
## Wrangler Integration
|
|
2
|
+
|
|
3
|
+
### Upload via Wrangler
|
|
4
|
+
|
|
5
|
+
Wrangler doesn't have built-in Cloudflare Images commands, but you can use the API:
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// scripts/upload-image.ts
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import FormData from 'form-data';
|
|
11
|
+
import fetch from 'node-fetch';
|
|
12
|
+
|
|
13
|
+
async function uploadImage(filePath: string) {
|
|
14
|
+
const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
15
|
+
const apiToken = process.env.CLOUDFLARE_API_TOKEN;
|
|
16
|
+
|
|
17
|
+
const formData = new FormData();
|
|
18
|
+
formData.append('file', fs.createReadStream(filePath));
|
|
19
|
+
|
|
20
|
+
const response = await fetch(
|
|
21
|
+
`https://api.cloudflare.com/client/v4/accounts/${accountId}/images/v1`,
|
|
22
|
+
{
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'Authorization': `Bearer ${apiToken}`,
|
|
26
|
+
},
|
|
27
|
+
body: formData,
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const result = await response.json();
|
|
32
|
+
console.log('Uploaded:', result);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
uploadImage('./photo.jpg');
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Access Images from Workers
|
|
39
|
+
|
|
40
|
+
Store account hash as an environment variable:
|
|
41
|
+
|
|
42
|
+
```toml
|
|
43
|
+
# wrangler.toml
|
|
44
|
+
[vars]
|
|
45
|
+
IMAGES_ACCOUNT
|