pi-cloudflare 0.1.0
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/LICENSE +674 -0
- package/README.md +67 -0
- package/bin/setup.mjs +103 -0
- package/dist/auth-flow.d.ts +15 -0
- package/dist/auth-flow.d.ts.map +1 -0
- package/dist/auth-flow.js +90 -0
- package/dist/auth-flow.js.map +1 -0
- package/dist/client.d.ts +18 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +47 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth.d.ts +44 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +135 -0
- package/dist/oauth.js.map +1 -0
- package/dist/proxy.d.ts +29 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +39 -0
- package/dist/proxy.js.map +1 -0
- package/dist/servers.d.ts +19 -0
- package/dist/servers.d.ts.map +1 -0
- package/dist/servers.js +40 -0
- package/dist/servers.js.map +1 -0
- package/dist/token-store.d.ts +23 -0
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +47 -0
- package/dist/token-store.js.map +1 -0
- package/package.json +67 -0
- package/skills/agents-sdk/SKILL.md +221 -0
- package/skills/agents-sdk/references/browse-the-web.md +63 -0
- package/skills/agents-sdk/references/callable.md +92 -0
- package/skills/agents-sdk/references/client-sdk.md +110 -0
- package/skills/agents-sdk/references/codemode.md +110 -0
- package/skills/agents-sdk/references/configuration.md +72 -0
- package/skills/agents-sdk/references/durable-execution.md +51 -0
- package/skills/agents-sdk/references/email.md +146 -0
- package/skills/agents-sdk/references/human-in-the-loop.md +67 -0
- package/skills/agents-sdk/references/mcp.md +188 -0
- package/skills/agents-sdk/references/observability.md +44 -0
- package/skills/agents-sdk/references/queue-retries.md +79 -0
- package/skills/agents-sdk/references/routing.md +75 -0
- package/skills/agents-sdk/references/server-driven-messages.md +63 -0
- package/skills/agents-sdk/references/state-scheduling.md +171 -0
- package/skills/agents-sdk/references/streaming-chat.md +198 -0
- package/skills/agents-sdk/references/think.md +112 -0
- package/skills/agents-sdk/references/voice.md +68 -0
- package/skills/agents-sdk/references/webhooks-push.md +86 -0
- package/skills/agents-sdk/references/workflows.md +132 -0
- package/skills/cloudflare/SKILL.md +248 -0
- package/skills/cloudflare/references/agents-sdk/README.md +89 -0
- package/skills/cloudflare/references/agents-sdk/api.md +190 -0
- package/skills/cloudflare/references/agents-sdk/configuration.md +182 -0
- package/skills/cloudflare/references/agents-sdk/gotchas.md +158 -0
- package/skills/cloudflare/references/agents-sdk/patterns.md +192 -0
- package/skills/cloudflare/references/ai-gateway/README.md +175 -0
- package/skills/cloudflare/references/ai-gateway/configuration.md +111 -0
- package/skills/cloudflare/references/ai-gateway/dynamic-routing.md +82 -0
- package/skills/cloudflare/references/ai-gateway/features.md +96 -0
- package/skills/cloudflare/references/ai-gateway/sdk-integration.md +114 -0
- package/skills/cloudflare/references/ai-gateway/troubleshooting.md +88 -0
- package/skills/cloudflare/references/ai-search/README.md +138 -0
- package/skills/cloudflare/references/ai-search/api.md +87 -0
- package/skills/cloudflare/references/ai-search/configuration.md +88 -0
- package/skills/cloudflare/references/ai-search/gotchas.md +81 -0
- package/skills/cloudflare/references/ai-search/patterns.md +85 -0
- package/skills/cloudflare/references/analytics-engine/README.md +94 -0
- package/skills/cloudflare/references/analytics-engine/api.md +112 -0
- package/skills/cloudflare/references/analytics-engine/configuration.md +112 -0
- package/skills/cloudflare/references/analytics-engine/gotchas.md +85 -0
- package/skills/cloudflare/references/analytics-engine/patterns.md +83 -0
- package/skills/cloudflare/references/api/README.md +66 -0
- package/skills/cloudflare/references/api/api.md +204 -0
- package/skills/cloudflare/references/api/configuration.md +160 -0
- package/skills/cloudflare/references/api/gotchas.md +225 -0
- package/skills/cloudflare/references/api/patterns.md +204 -0
- package/skills/cloudflare/references/api-shield/README.md +44 -0
- package/skills/cloudflare/references/api-shield/api.md +141 -0
- package/skills/cloudflare/references/api-shield/configuration.md +192 -0
- package/skills/cloudflare/references/api-shield/gotchas.md +125 -0
- package/skills/cloudflare/references/api-shield/patterns.md +180 -0
- package/skills/cloudflare/references/argo-smart-routing/README.md +90 -0
- package/skills/cloudflare/references/argo-smart-routing/api.md +240 -0
- package/skills/cloudflare/references/argo-smart-routing/configuration.md +197 -0
- package/skills/cloudflare/references/argo-smart-routing/gotchas.md +111 -0
- package/skills/cloudflare/references/argo-smart-routing/patterns.md +104 -0
- package/skills/cloudflare/references/artifacts/README.md +79 -0
- package/skills/cloudflare/references/artifacts/api.md +128 -0
- package/skills/cloudflare/references/artifacts/configuration.md +92 -0
- package/skills/cloudflare/references/bindings/README.md +122 -0
- package/skills/cloudflare/references/bindings/api.md +203 -0
- package/skills/cloudflare/references/bindings/configuration.md +188 -0
- package/skills/cloudflare/references/bindings/gotchas.md +208 -0
- package/skills/cloudflare/references/bindings/patterns.md +200 -0
- package/skills/cloudflare/references/bot-management/README.md +94 -0
- package/skills/cloudflare/references/bot-management/api.md +169 -0
- package/skills/cloudflare/references/bot-management/configuration.md +163 -0
- package/skills/cloudflare/references/bot-management/gotchas.md +114 -0
- package/skills/cloudflare/references/bot-management/patterns.md +182 -0
- package/skills/cloudflare/references/browser-rendering/README.md +78 -0
- package/skills/cloudflare/references/browser-rendering/api.md +108 -0
- package/skills/cloudflare/references/browser-rendering/configuration.md +78 -0
- package/skills/cloudflare/references/browser-rendering/gotchas.md +88 -0
- package/skills/cloudflare/references/browser-rendering/patterns.md +91 -0
- package/skills/cloudflare/references/c3/README.md +111 -0
- package/skills/cloudflare/references/c3/api.md +71 -0
- package/skills/cloudflare/references/c3/configuration.md +81 -0
- package/skills/cloudflare/references/c3/gotchas.md +92 -0
- package/skills/cloudflare/references/c3/patterns.md +82 -0
- package/skills/cloudflare/references/cache-reserve/README.md +147 -0
- package/skills/cloudflare/references/cache-reserve/api.md +194 -0
- package/skills/cloudflare/references/cache-reserve/configuration.md +169 -0
- package/skills/cloudflare/references/cache-reserve/gotchas.md +132 -0
- package/skills/cloudflare/references/cache-reserve/patterns.md +197 -0
- package/skills/cloudflare/references/containers/README.md +85 -0
- package/skills/cloudflare/references/containers/api.md +187 -0
- package/skills/cloudflare/references/containers/configuration.md +188 -0
- package/skills/cloudflare/references/containers/gotchas.md +178 -0
- package/skills/cloudflare/references/containers/patterns.md +202 -0
- package/skills/cloudflare/references/cron-triggers/README.md +99 -0
- package/skills/cloudflare/references/cron-triggers/api.md +196 -0
- package/skills/cloudflare/references/cron-triggers/configuration.md +180 -0
- package/skills/cloudflare/references/cron-triggers/gotchas.md +199 -0
- package/skills/cloudflare/references/cron-triggers/patterns.md +190 -0
- package/skills/cloudflare/references/d1/README.md +133 -0
- package/skills/cloudflare/references/d1/api.md +196 -0
- package/skills/cloudflare/references/d1/configuration.md +191 -0
- package/skills/cloudflare/references/d1/gotchas.md +98 -0
- package/skills/cloudflare/references/d1/patterns.md +189 -0
- package/skills/cloudflare/references/ddos/README.md +41 -0
- package/skills/cloudflare/references/ddos/api.md +164 -0
- package/skills/cloudflare/references/ddos/configuration.md +93 -0
- package/skills/cloudflare/references/ddos/gotchas.md +107 -0
- package/skills/cloudflare/references/ddos/patterns.md +174 -0
- package/skills/cloudflare/references/do-storage/README.md +75 -0
- package/skills/cloudflare/references/do-storage/api.md +102 -0
- package/skills/cloudflare/references/do-storage/configuration.md +112 -0
- package/skills/cloudflare/references/do-storage/gotchas.md +150 -0
- package/skills/cloudflare/references/do-storage/patterns.md +194 -0
- package/skills/cloudflare/references/do-storage/testing.md +183 -0
- package/skills/cloudflare/references/durable-objects/README.md +185 -0
- package/skills/cloudflare/references/durable-objects/api.md +187 -0
- package/skills/cloudflare/references/durable-objects/configuration.md +160 -0
- package/skills/cloudflare/references/durable-objects/gotchas.md +197 -0
- package/skills/cloudflare/references/durable-objects/patterns.md +201 -0
- package/skills/cloudflare/references/email-routing/README.md +89 -0
- package/skills/cloudflare/references/email-routing/api.md +195 -0
- package/skills/cloudflare/references/email-routing/configuration.md +186 -0
- package/skills/cloudflare/references/email-routing/gotchas.md +196 -0
- package/skills/cloudflare/references/email-routing/patterns.md +229 -0
- package/skills/cloudflare/references/email-workers/README.md +151 -0
- package/skills/cloudflare/references/email-workers/api.md +237 -0
- package/skills/cloudflare/references/email-workers/configuration.md +112 -0
- package/skills/cloudflare/references/email-workers/gotchas.md +125 -0
- package/skills/cloudflare/references/email-workers/patterns.md +102 -0
- package/skills/cloudflare/references/flagship/README.md +59 -0
- package/skills/cloudflare/references/flagship/api.md +390 -0
- package/skills/cloudflare/references/flagship/configuration.md +202 -0
- package/skills/cloudflare/references/flagship/gotchas.md +178 -0
- package/skills/cloudflare/references/flagship/patterns.md +469 -0
- package/skills/cloudflare/references/graphql-api/README.md +147 -0
- package/skills/cloudflare/references/graphql-api/api.md +175 -0
- package/skills/cloudflare/references/graphql-api/configuration.md +118 -0
- package/skills/cloudflare/references/graphql-api/gotchas.md +110 -0
- package/skills/cloudflare/references/graphql-api/patterns.md +225 -0
- package/skills/cloudflare/references/hyperdrive/README.md +82 -0
- package/skills/cloudflare/references/hyperdrive/api.md +143 -0
- package/skills/cloudflare/references/hyperdrive/configuration.md +159 -0
- package/skills/cloudflare/references/hyperdrive/gotchas.md +77 -0
- package/skills/cloudflare/references/hyperdrive/patterns.md +190 -0
- package/skills/cloudflare/references/images/README.md +61 -0
- package/skills/cloudflare/references/images/api.md +96 -0
- package/skills/cloudflare/references/images/configuration.md +211 -0
- package/skills/cloudflare/references/images/gotchas.md +99 -0
- package/skills/cloudflare/references/images/patterns.md +115 -0
- package/skills/cloudflare/references/kv/README.md +89 -0
- package/skills/cloudflare/references/kv/api.md +160 -0
- package/skills/cloudflare/references/kv/configuration.md +144 -0
- package/skills/cloudflare/references/kv/gotchas.md +131 -0
- package/skills/cloudflare/references/kv/patterns.md +196 -0
- package/skills/cloudflare/references/miniflare/README.md +105 -0
- package/skills/cloudflare/references/miniflare/api.md +187 -0
- package/skills/cloudflare/references/miniflare/configuration.md +173 -0
- package/skills/cloudflare/references/miniflare/gotchas.md +160 -0
- package/skills/cloudflare/references/miniflare/patterns.md +181 -0
- package/skills/cloudflare/references/network-interconnect/README.md +99 -0
- package/skills/cloudflare/references/network-interconnect/api.md +199 -0
- package/skills/cloudflare/references/network-interconnect/configuration.md +114 -0
- package/skills/cloudflare/references/network-interconnect/gotchas.md +165 -0
- package/skills/cloudflare/references/network-interconnect/patterns.md +166 -0
- package/skills/cloudflare/references/observability/README.md +88 -0
- package/skills/cloudflare/references/observability/api.md +164 -0
- package/skills/cloudflare/references/observability/configuration.md +169 -0
- package/skills/cloudflare/references/observability/gotchas.md +115 -0
- package/skills/cloudflare/references/observability/patterns.md +105 -0
- package/skills/cloudflare/references/pages/README.md +88 -0
- package/skills/cloudflare/references/pages/api.md +204 -0
- package/skills/cloudflare/references/pages/configuration.md +201 -0
- package/skills/cloudflare/references/pages/gotchas.md +203 -0
- package/skills/cloudflare/references/pages/patterns.md +204 -0
- package/skills/cloudflare/references/pages-functions/README.md +98 -0
- package/skills/cloudflare/references/pages-functions/api.md +143 -0
- package/skills/cloudflare/references/pages-functions/configuration.md +122 -0
- package/skills/cloudflare/references/pages-functions/gotchas.md +94 -0
- package/skills/cloudflare/references/pages-functions/patterns.md +137 -0
- package/skills/cloudflare/references/pipelines/README.md +90 -0
- package/skills/cloudflare/references/pipelines/api.md +124 -0
- package/skills/cloudflare/references/pipelines/configuration.md +155 -0
- package/skills/cloudflare/references/pipelines/gotchas.md +58 -0
- package/skills/cloudflare/references/pipelines/patterns.md +130 -0
- package/skills/cloudflare/references/pulumi/README.md +100 -0
- package/skills/cloudflare/references/pulumi/api.md +200 -0
- package/skills/cloudflare/references/pulumi/configuration.md +198 -0
- package/skills/cloudflare/references/pulumi/gotchas.md +181 -0
- package/skills/cloudflare/references/pulumi/patterns.md +191 -0
- package/skills/cloudflare/references/queues/README.md +96 -0
- package/skills/cloudflare/references/queues/api.md +206 -0
- package/skills/cloudflare/references/queues/configuration.md +144 -0
- package/skills/cloudflare/references/queues/gotchas.md +206 -0
- package/skills/cloudflare/references/queues/patterns.md +220 -0
- package/skills/cloudflare/references/r2/README.md +95 -0
- package/skills/cloudflare/references/r2/api.md +200 -0
- package/skills/cloudflare/references/r2/configuration.md +165 -0
- package/skills/cloudflare/references/r2/gotchas.md +190 -0
- package/skills/cloudflare/references/r2/patterns.md +193 -0
- package/skills/cloudflare/references/r2-data-catalog/README.md +75 -0
- package/skills/cloudflare/references/r2-data-catalog/api.md +122 -0
- package/skills/cloudflare/references/r2-data-catalog/configuration.md +98 -0
- package/skills/cloudflare/references/r2-data-catalog/gotchas.md +55 -0
- package/skills/cloudflare/references/r2-data-catalog/patterns.md +122 -0
- package/skills/cloudflare/references/r2-sql/README.md +64 -0
- package/skills/cloudflare/references/r2-sql/api.md +121 -0
- package/skills/cloudflare/references/r2-sql/configuration.md +50 -0
- package/skills/cloudflare/references/r2-sql/gotchas.md +39 -0
- package/skills/cloudflare/references/r2-sql/patterns.md +118 -0
- package/skills/cloudflare/references/realtime-sfu/README.md +65 -0
- package/skills/cloudflare/references/realtime-sfu/api.md +158 -0
- package/skills/cloudflare/references/realtime-sfu/configuration.md +137 -0
- package/skills/cloudflare/references/realtime-sfu/gotchas.md +133 -0
- package/skills/cloudflare/references/realtime-sfu/patterns.md +174 -0
- package/skills/cloudflare/references/realtimekit/README.md +113 -0
- package/skills/cloudflare/references/realtimekit/api.md +212 -0
- package/skills/cloudflare/references/realtimekit/configuration.md +203 -0
- package/skills/cloudflare/references/realtimekit/gotchas.md +169 -0
- package/skills/cloudflare/references/realtimekit/patterns.md +223 -0
- package/skills/cloudflare/references/sandbox/README.md +96 -0
- package/skills/cloudflare/references/sandbox/api.md +198 -0
- package/skills/cloudflare/references/sandbox/configuration.md +143 -0
- package/skills/cloudflare/references/sandbox/gotchas.md +194 -0
- package/skills/cloudflare/references/sandbox/patterns.md +201 -0
- package/skills/cloudflare/references/secrets-store/README.md +74 -0
- package/skills/cloudflare/references/secrets-store/api.md +200 -0
- package/skills/cloudflare/references/secrets-store/configuration.md +185 -0
- package/skills/cloudflare/references/secrets-store/gotchas.md +97 -0
- package/skills/cloudflare/references/secrets-store/patterns.md +207 -0
- package/skills/cloudflare/references/smart-placement/README.md +138 -0
- package/skills/cloudflare/references/smart-placement/api.md +183 -0
- package/skills/cloudflare/references/smart-placement/configuration.md +196 -0
- package/skills/cloudflare/references/smart-placement/gotchas.md +174 -0
- package/skills/cloudflare/references/smart-placement/patterns.md +183 -0
- package/skills/cloudflare/references/snippets/README.md +68 -0
- package/skills/cloudflare/references/snippets/api.md +198 -0
- package/skills/cloudflare/references/snippets/configuration.md +227 -0
- package/skills/cloudflare/references/snippets/gotchas.md +86 -0
- package/skills/cloudflare/references/snippets/patterns.md +135 -0
- package/skills/cloudflare/references/spectrum/README.md +52 -0
- package/skills/cloudflare/references/spectrum/api.md +181 -0
- package/skills/cloudflare/references/spectrum/configuration.md +194 -0
- package/skills/cloudflare/references/spectrum/gotchas.md +145 -0
- package/skills/cloudflare/references/spectrum/patterns.md +196 -0
- package/skills/cloudflare/references/static-assets/README.md +65 -0
- package/skills/cloudflare/references/static-assets/api.md +199 -0
- package/skills/cloudflare/references/static-assets/configuration.md +186 -0
- package/skills/cloudflare/references/static-assets/gotchas.md +162 -0
- package/skills/cloudflare/references/static-assets/patterns.md +189 -0
- package/skills/cloudflare/references/stream/README.md +114 -0
- package/skills/cloudflare/references/stream/api-live.md +195 -0
- package/skills/cloudflare/references/stream/api.md +199 -0
- package/skills/cloudflare/references/stream/configuration.md +141 -0
- package/skills/cloudflare/references/stream/gotchas.md +130 -0
- package/skills/cloudflare/references/stream/patterns.md +184 -0
- package/skills/cloudflare/references/tail-workers/README.md +89 -0
- package/skills/cloudflare/references/tail-workers/api.md +200 -0
- package/skills/cloudflare/references/tail-workers/configuration.md +176 -0
- package/skills/cloudflare/references/tail-workers/gotchas.md +192 -0
- package/skills/cloudflare/references/tail-workers/patterns.md +180 -0
- package/skills/cloudflare/references/terraform/README.md +102 -0
- package/skills/cloudflare/references/terraform/api.md +178 -0
- package/skills/cloudflare/references/terraform/configuration.md +197 -0
- package/skills/cloudflare/references/terraform/gotchas.md +150 -0
- package/skills/cloudflare/references/terraform/patterns.md +174 -0
- package/skills/cloudflare/references/tunnel/README.md +129 -0
- package/skills/cloudflare/references/tunnel/api.md +193 -0
- package/skills/cloudflare/references/tunnel/configuration.md +157 -0
- package/skills/cloudflare/references/tunnel/gotchas.md +147 -0
- package/skills/cloudflare/references/tunnel/networking.md +168 -0
- package/skills/cloudflare/references/tunnel/patterns.md +192 -0
- package/skills/cloudflare/references/turn/README.md +82 -0
- package/skills/cloudflare/references/turn/api.md +239 -0
- package/skills/cloudflare/references/turn/configuration.md +179 -0
- package/skills/cloudflare/references/turn/gotchas.md +231 -0
- package/skills/cloudflare/references/turn/patterns.md +213 -0
- package/skills/cloudflare/references/turnstile/README.md +99 -0
- package/skills/cloudflare/references/turnstile/api.md +240 -0
- package/skills/cloudflare/references/turnstile/configuration.md +222 -0
- package/skills/cloudflare/references/turnstile/gotchas.md +218 -0
- package/skills/cloudflare/references/turnstile/patterns.md +193 -0
- package/skills/cloudflare/references/vectorize/README.md +133 -0
- package/skills/cloudflare/references/vectorize/api.md +88 -0
- package/skills/cloudflare/references/vectorize/configuration.md +88 -0
- package/skills/cloudflare/references/vectorize/gotchas.md +76 -0
- package/skills/cloudflare/references/vectorize/patterns.md +90 -0
- package/skills/cloudflare/references/waf/README.md +113 -0
- package/skills/cloudflare/references/waf/api.md +202 -0
- package/skills/cloudflare/references/waf/configuration.md +203 -0
- package/skills/cloudflare/references/waf/gotchas.md +204 -0
- package/skills/cloudflare/references/waf/patterns.md +197 -0
- package/skills/cloudflare/references/web-analytics/README.md +141 -0
- package/skills/cloudflare/references/web-analytics/configuration.md +76 -0
- package/skills/cloudflare/references/web-analytics/gotchas.md +82 -0
- package/skills/cloudflare/references/web-analytics/integration.md +60 -0
- package/skills/cloudflare/references/web-analytics/patterns.md +91 -0
- package/skills/cloudflare/references/workerd/README.md +78 -0
- package/skills/cloudflare/references/workerd/api.md +185 -0
- package/skills/cloudflare/references/workerd/configuration.md +183 -0
- package/skills/cloudflare/references/workerd/gotchas.md +139 -0
- package/skills/cloudflare/references/workerd/patterns.md +192 -0
- package/skills/cloudflare/references/workers/README.md +108 -0
- package/skills/cloudflare/references/workers/api.md +195 -0
- package/skills/cloudflare/references/workers/configuration.md +185 -0
- package/skills/cloudflare/references/workers/frameworks.md +197 -0
- package/skills/cloudflare/references/workers/gotchas.md +137 -0
- package/skills/cloudflare/references/workers/patterns.md +198 -0
- package/skills/cloudflare/references/workers-ai/README.md +197 -0
- package/skills/cloudflare/references/workers-ai/api.md +112 -0
- package/skills/cloudflare/references/workers-ai/configuration.md +97 -0
- package/skills/cloudflare/references/workers-ai/gotchas.md +114 -0
- package/skills/cloudflare/references/workers-ai/patterns.md +120 -0
- package/skills/cloudflare/references/workers-for-platforms/README.md +89 -0
- package/skills/cloudflare/references/workers-for-platforms/api.md +196 -0
- package/skills/cloudflare/references/workers-for-platforms/configuration.md +167 -0
- package/skills/cloudflare/references/workers-for-platforms/gotchas.md +134 -0
- package/skills/cloudflare/references/workers-for-platforms/patterns.md +188 -0
- package/skills/cloudflare/references/workers-playground/README.md +127 -0
- package/skills/cloudflare/references/workers-playground/api.md +101 -0
- package/skills/cloudflare/references/workers-playground/configuration.md +163 -0
- package/skills/cloudflare/references/workers-playground/gotchas.md +88 -0
- package/skills/cloudflare/references/workers-playground/patterns.md +132 -0
- package/skills/cloudflare/references/workers-vpc/README.md +127 -0
- package/skills/cloudflare/references/workers-vpc/api.md +202 -0
- package/skills/cloudflare/references/workers-vpc/configuration.md +147 -0
- package/skills/cloudflare/references/workers-vpc/gotchas.md +167 -0
- package/skills/cloudflare/references/workers-vpc/patterns.md +209 -0
- package/skills/cloudflare/references/workflows/README.md +77 -0
- package/skills/cloudflare/references/workflows/api.md +218 -0
- package/skills/cloudflare/references/workflows/configuration.md +152 -0
- package/skills/cloudflare/references/workflows/gotchas.md +90 -0
- package/skills/cloudflare/references/workflows/patterns.md +175 -0
- package/skills/cloudflare/references/wrangler/README.md +135 -0
- package/skills/cloudflare/references/wrangler/api.md +188 -0
- package/skills/cloudflare/references/wrangler/configuration.md +197 -0
- package/skills/cloudflare/references/wrangler/gotchas.md +197 -0
- package/skills/cloudflare/references/wrangler/patterns.md +209 -0
- package/skills/cloudflare/references/zaraz/IMPLEMENTATION_SUMMARY.md +121 -0
- package/skills/cloudflare/references/zaraz/README.md +111 -0
- package/skills/cloudflare/references/zaraz/api.md +112 -0
- package/skills/cloudflare/references/zaraz/configuration.md +90 -0
- package/skills/cloudflare/references/zaraz/gotchas.md +81 -0
- package/skills/cloudflare/references/zaraz/patterns.md +74 -0
- package/skills/cloudflare-email-service/SKILL.md +103 -0
- package/skills/cloudflare-email-service/references/cli-and-mcp.md +125 -0
- package/skills/cloudflare-email-service/references/deliverability.md +285 -0
- package/skills/cloudflare-email-service/references/rest-api.md +184 -0
- package/skills/cloudflare-email-service/references/routing.md +199 -0
- package/skills/cloudflare-email-service/references/sending.md +252 -0
- package/skills/cloudflare-one/SKILL.md +176 -0
- package/skills/cloudflare-one-migrations/SKILL.md +110 -0
- package/skills/durable-objects/SKILL.md +186 -0
- package/skills/durable-objects/references/rules.md +295 -0
- package/skills/durable-objects/references/testing.md +264 -0
- package/skills/durable-objects/references/workers.md +346 -0
- package/skills/sandbox-migrate-to-next/SKILL.md +185 -0
- package/skills/sandbox-next/SKILL.md +91 -0
- package/skills/sandbox-next/references/api-quick-ref.md +94 -0
- package/skills/sandbox-next/references/examples.md +15 -0
- package/skills/sandbox-stable/SKILL.md +110 -0
- package/skills/turnstile-spin/README.md +51 -0
- package/skills/turnstile-spin/SKILL.md +330 -0
- package/skills/turnstile-spin/references/astro.md +199 -0
- package/skills/turnstile-spin/references/hugo.md +114 -0
- package/skills/turnstile-spin/references/nextjs-app.md +261 -0
- package/skills/turnstile-spin/references/nextjs-pages.md +82 -0
- package/skills/turnstile-spin/references/sveltekit.md +191 -0
- package/skills/turnstile-spin/references/vanilla-html.md +157 -0
- package/skills/turnstile-spin/scripts/auth-probe.sh +285 -0
- package/skills/turnstile-spin/scripts/persist-skill.sh +114 -0
- package/skills/turnstile-spin/scripts/validate.sh +137 -0
- package/skills/turnstile-spin/scripts/widget-create.sh +121 -0
- package/skills/turnstile-spin/tests/validation.md +62 -0
- package/skills/workers-best-practices/SKILL.md +127 -0
- package/skills/workers-best-practices/references/review.md +174 -0
- package/skills/workers-best-practices/references/rules.md +467 -0
- package/skills/wrangler/SKILL.md +922 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Common Patterns
|
|
2
|
+
|
|
3
|
+
## URL Transform Options
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
width=<PX> height=<PX> fit=scale-down|contain|cover|crop|pad
|
|
7
|
+
quality=85 format=auto|webp|avif|jpeg|png dpr=2
|
|
8
|
+
gravity=auto|face|left|right|top|bottom sharpen=2 blur=10
|
|
9
|
+
rotate=90|180|270 background=white metadata=none|copyright|keep
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Responsive Images (srcset)
|
|
13
|
+
|
|
14
|
+
```html
|
|
15
|
+
<img src="https://imagedelivery.net/{hash}/{id}/width=800"
|
|
16
|
+
srcset=".../{id}/width=400 400w, .../{id}/width=800 800w, .../{id}/width=1200 1200w"
|
|
17
|
+
sizes="(max-width: 600px) 400px, 800px" />
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Format Negotiation
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
24
|
+
const accept = request.headers.get('Accept') || '';
|
|
25
|
+
const format = /image\/avif/.test(accept) ? 'avif' : /image\/webp/.test(accept) ? 'webp' : 'jpeg';
|
|
26
|
+
return env.IMAGES.input(buffer).transform({ format, quality: 85 }).output().response();
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Direct Creator Upload
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Backend: Generate upload URL
|
|
34
|
+
const response = await fetch(
|
|
35
|
+
`https://api.cloudflare.com/client/v4/accounts/${env.ACCOUNT_ID}/images/v2/direct_upload`,
|
|
36
|
+
{ method: 'POST', headers: { 'Authorization': `Bearer ${env.API_TOKEN}` },
|
|
37
|
+
body: JSON.stringify({ requireSignedURLs: false, metadata: { userId } }) }
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Frontend: Upload to returned uploadURL
|
|
41
|
+
const formData = new FormData();
|
|
42
|
+
formData.append('file', file);
|
|
43
|
+
await fetch(result.uploadURL, { method: 'POST', body: formData });
|
|
44
|
+
// Use: https://imagedelivery.net/{hash}/${result.id}/public
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Transform & Store to R2
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
51
|
+
const file = (await request.formData()).get('image') as File;
|
|
52
|
+
const transformed = await env.IMAGES
|
|
53
|
+
.input(await file.arrayBuffer())
|
|
54
|
+
.transform({ width: 800, format: 'avif', quality: 80 })
|
|
55
|
+
.output();
|
|
56
|
+
await env.R2.put(`images/${Date.now()}.avif`, transformed.response().body);
|
|
57
|
+
return Response.json({ success: true });
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Watermarking
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
const watermark = await env.ASSETS.fetch(new URL('/watermark.png', request.url));
|
|
65
|
+
const result = await env.IMAGES
|
|
66
|
+
.input(await image.arrayBuffer())
|
|
67
|
+
.draw(env.IMAGES.input(watermark.body).transform({ width: 100 }), { bottom: 20, right: 20, opacity: 0.7 })
|
|
68
|
+
.transform({ format: 'avif' })
|
|
69
|
+
.output();
|
|
70
|
+
return result.response();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Device-Based Transforms
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const ua = request.headers.get('User-Agent') || '';
|
|
77
|
+
const isMobile = /Mobile|Android|iPhone/i.test(ua);
|
|
78
|
+
return env.IMAGES.input(buffer)
|
|
79
|
+
.transform({ width: isMobile ? 400 : 1200, quality: isMobile ? 75 : 85, format: 'avif' })
|
|
80
|
+
.output().response();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Caching Strategy
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
87
|
+
const cache = caches.default;
|
|
88
|
+
let response = await cache.match(request);
|
|
89
|
+
if (!response) {
|
|
90
|
+
response = await env.IMAGES.input(buffer).transform({ width: 800, format: 'avif' }).output().response();
|
|
91
|
+
response = new Response(response.body, { headers: { ...response.headers, 'Cache-Control': 'public, max-age=86400' } });
|
|
92
|
+
ctx.waitUntil(cache.put(request, response.clone()));
|
|
93
|
+
}
|
|
94
|
+
return response;
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Batch Processing
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const results = await Promise.all(images.map(buffer =>
|
|
102
|
+
env.IMAGES.input(buffer).transform({ width: 800, fit: 'cover', format: 'avif' }).output()
|
|
103
|
+
));
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Error Handling
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
try {
|
|
110
|
+
return (await env.IMAGES.input(buffer).transform({ width: 800 }).output()).response();
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error('Transform failed:', error);
|
|
113
|
+
return new Response('Image processing failed', { status: 500 });
|
|
114
|
+
}
|
|
115
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Cloudflare Workers KV
|
|
2
|
+
|
|
3
|
+
Globally-distributed, eventually-consistent key-value store optimized for high read volume and low latency.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
KV provides:
|
|
8
|
+
- Eventual consistency (60s global propagation)
|
|
9
|
+
- Read-optimized performance
|
|
10
|
+
- 25 MiB value limit per key
|
|
11
|
+
- Auto-replication to Cloudflare edge
|
|
12
|
+
- Metadata support (1024 bytes)
|
|
13
|
+
|
|
14
|
+
**Use cases:** Config storage, user sessions, feature flags, caching, A/B testing
|
|
15
|
+
|
|
16
|
+
## When to Use KV
|
|
17
|
+
|
|
18
|
+
| Need | Recommendation |
|
|
19
|
+
|------|----------------|
|
|
20
|
+
| Strong consistency | → [Durable Objects](../durable-objects/) |
|
|
21
|
+
| SQL queries | → [D1](../d1/) |
|
|
22
|
+
| Object storage (files) | → [R2](../r2/) |
|
|
23
|
+
| High read, low write volume | → KV ✅ |
|
|
24
|
+
| Sub-10ms global reads | → KV ✅ |
|
|
25
|
+
|
|
26
|
+
**Quick comparison:**
|
|
27
|
+
|
|
28
|
+
| Feature | KV | D1 | Durable Objects |
|
|
29
|
+
|---------|----|----|-----------------|
|
|
30
|
+
| Consistency | Eventual | Strong | Strong |
|
|
31
|
+
| Read latency | <10ms | ~50ms | <1ms |
|
|
32
|
+
| Write limit | 1/s per key | Unlimited | Unlimited |
|
|
33
|
+
| Use case | Config, cache | Relational data | Coordination |
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
wrangler kv namespace create MY_NAMESPACE
|
|
39
|
+
# Add binding to wrangler.jsonc
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// Write
|
|
44
|
+
await env.MY_KV.put("key", "value", { expirationTtl: 300 });
|
|
45
|
+
|
|
46
|
+
// Read
|
|
47
|
+
const value = await env.MY_KV.get("key");
|
|
48
|
+
const json = await env.MY_KV.get<Config>("config", "json");
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Core Operations
|
|
52
|
+
|
|
53
|
+
| Method | Purpose | Returns |
|
|
54
|
+
|--------|---------|---------|
|
|
55
|
+
| `get(key, type?)` | Single read | `string \| null` |
|
|
56
|
+
| `get(keys, type?)` | Bulk read (≤100) | `Map<string, T \| null>` |
|
|
57
|
+
| `put(key, value, options?)` | Write | `Promise<void>` |
|
|
58
|
+
| `delete(key)` | Delete | `Promise<void>` |
|
|
59
|
+
| `list(options?)` | List keys | `{ keys, list_complete, cursor? }` |
|
|
60
|
+
| `getWithMetadata(key)` | Get + metadata | `{ value, metadata }` |
|
|
61
|
+
|
|
62
|
+
## Consistency Model
|
|
63
|
+
|
|
64
|
+
- **Write visibility:** Immediate in same location, ≤60s globally
|
|
65
|
+
- **Read path:** Eventually consistent
|
|
66
|
+
- **Write rate:** 1 write/second per key (429 on exceed)
|
|
67
|
+
|
|
68
|
+
## Reading Order
|
|
69
|
+
|
|
70
|
+
| Task | Files to Read |
|
|
71
|
+
|------|---------------|
|
|
72
|
+
| Quick start | README → configuration.md |
|
|
73
|
+
| Implement feature | README → api.md → patterns.md |
|
|
74
|
+
| Debug issues | gotchas.md → api.md |
|
|
75
|
+
| Batch operations | api.md (bulk section) → patterns.md |
|
|
76
|
+
| Performance tuning | gotchas.md (performance) → patterns.md (caching) |
|
|
77
|
+
|
|
78
|
+
## In This Reference
|
|
79
|
+
|
|
80
|
+
- [configuration.md](./configuration.md) - wrangler.jsonc setup, namespace creation, TypeScript types
|
|
81
|
+
- [api.md](./api.md) - KV methods, bulk operations, cacheTtl, content types
|
|
82
|
+
- [patterns.md](./patterns.md) - Caching, sessions, rate limiting, A/B testing
|
|
83
|
+
- [gotchas.md](./gotchas.md) - Eventual consistency, concurrent writes, value limits
|
|
84
|
+
|
|
85
|
+
## See Also
|
|
86
|
+
|
|
87
|
+
- [workers](../workers/) - Worker runtime for KV access
|
|
88
|
+
- [d1](../d1/) - Use D1 for strong consistency needs
|
|
89
|
+
- [durable-objects](../durable-objects/) - Strongly consistent alternative
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# KV API Reference
|
|
2
|
+
|
|
3
|
+
## Read Operations
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// Single key (string)
|
|
7
|
+
const value = await env.MY_KV.get("user:123");
|
|
8
|
+
|
|
9
|
+
// JSON type (auto-parsed)
|
|
10
|
+
const config = await env.MY_KV.get<AppConfig>("config", "json");
|
|
11
|
+
|
|
12
|
+
// ArrayBuffer for binary
|
|
13
|
+
const buffer = await env.MY_KV.get("image", "arrayBuffer");
|
|
14
|
+
|
|
15
|
+
// Stream for large values
|
|
16
|
+
const stream = await env.MY_KV.get("large-file", "stream");
|
|
17
|
+
|
|
18
|
+
// With cache TTL (min 60s)
|
|
19
|
+
const value = await env.MY_KV.get("key", { type: "text", cacheTtl: 300 });
|
|
20
|
+
|
|
21
|
+
// Bulk get (max 100 keys, counts as 1 operation)
|
|
22
|
+
const keys = ["user:1", "user:2", "user:3", "missing:key"];
|
|
23
|
+
const results = await env.MY_KV.get(keys);
|
|
24
|
+
// Returns Map<string, string | null>
|
|
25
|
+
|
|
26
|
+
console.log(results.get("user:1")); // "John" (if exists)
|
|
27
|
+
console.log(results.get("missing:key")); // null
|
|
28
|
+
|
|
29
|
+
// Process results with null handling
|
|
30
|
+
for (const [key, value] of results) {
|
|
31
|
+
if (value !== null) {
|
|
32
|
+
// Handle found keys
|
|
33
|
+
console.log(`${key}: ${value}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// TypeScript with generics (type-safe JSON parsing)
|
|
38
|
+
interface UserProfile { name: string; email: string; }
|
|
39
|
+
const profile = await env.USERS.get<UserProfile>("user:123", "json");
|
|
40
|
+
// profile is typed as UserProfile | null
|
|
41
|
+
if (profile) {
|
|
42
|
+
console.log(profile.name); // Type-safe access
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Bulk get with type
|
|
46
|
+
const configs = await env.MY_KV.get<Config>(["config:app", "config:feature"], "json");
|
|
47
|
+
// Map<string, Config | null>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Write Operations
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// Basic put
|
|
54
|
+
await env.MY_KV.put("key", "value");
|
|
55
|
+
await env.MY_KV.put("config", JSON.stringify({ theme: "dark" }));
|
|
56
|
+
|
|
57
|
+
// With expiration (UNIX timestamp)
|
|
58
|
+
await env.MY_KV.put("session", token, {
|
|
59
|
+
expiration: Math.floor(Date.now() / 1000) + 3600
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// With TTL (seconds from now, min 60)
|
|
63
|
+
await env.MY_KV.put("cache", data, { expirationTtl: 300 });
|
|
64
|
+
|
|
65
|
+
// With metadata (max 1024 bytes)
|
|
66
|
+
await env.MY_KV.put("user:profile", userData, {
|
|
67
|
+
metadata: { version: 2, lastUpdated: Date.now() }
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Combined
|
|
71
|
+
await env.MY_KV.put("temp", value, {
|
|
72
|
+
expirationTtl: 3600,
|
|
73
|
+
metadata: { temporary: true }
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Get with Metadata
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Single key
|
|
81
|
+
const result = await env.MY_KV.getWithMetadata("user:profile");
|
|
82
|
+
// { value: string | null, metadata: any | null }
|
|
83
|
+
|
|
84
|
+
if (result.value && result.metadata) {
|
|
85
|
+
const { version, lastUpdated } = result.metadata;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Multiple keys (bulk)
|
|
89
|
+
const keys = ["key1", "key2", "key3"];
|
|
90
|
+
const results = await env.MY_KV.getWithMetadata(keys);
|
|
91
|
+
// Returns Map<string, { value, metadata, cacheStatus? }>
|
|
92
|
+
|
|
93
|
+
for (const [key, result] of results) {
|
|
94
|
+
if (result.value) {
|
|
95
|
+
console.log(`${key}: ${result.value}`);
|
|
96
|
+
console.log(`Metadata: ${JSON.stringify(result.metadata)}`);
|
|
97
|
+
// cacheStatus field indicates cache hit/miss (when available)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// With type
|
|
102
|
+
const result = await env.MY_KV.getWithMetadata<UserData>("user:123", "json");
|
|
103
|
+
// result: { value: UserData | null, metadata: any | null, cacheStatus?: string }
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Delete Operations
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
await env.MY_KV.delete("key"); // Always succeeds (even if key missing)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## List Operations
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// List all
|
|
116
|
+
const keys = await env.MY_KV.list();
|
|
117
|
+
// { keys: [...], list_complete: boolean, cursor?: string }
|
|
118
|
+
|
|
119
|
+
// With prefix
|
|
120
|
+
const userKeys = await env.MY_KV.list({ prefix: "user:" });
|
|
121
|
+
|
|
122
|
+
// Pagination
|
|
123
|
+
let cursor: string | undefined;
|
|
124
|
+
let allKeys = [];
|
|
125
|
+
do {
|
|
126
|
+
const result = await env.MY_KV.list({ cursor, limit: 1000 });
|
|
127
|
+
allKeys.push(...result.keys);
|
|
128
|
+
cursor = result.cursor;
|
|
129
|
+
} while (!result.list_complete);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Performance Considerations
|
|
133
|
+
|
|
134
|
+
### Type Selection
|
|
135
|
+
|
|
136
|
+
| Type | Use Case | Performance |
|
|
137
|
+
|------|----------|-------------|
|
|
138
|
+
| `stream` | Large values (>1MB) | Fastest - no buffering |
|
|
139
|
+
| `arrayBuffer` | Binary data | Fast - single allocation |
|
|
140
|
+
| `text` | String values | Medium |
|
|
141
|
+
| `json` | Objects (parse overhead) | Slowest - parsing cost |
|
|
142
|
+
|
|
143
|
+
### Parallel Reads
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Efficient parallel reads with Promise.all()
|
|
147
|
+
const [user, settings, cache] = await Promise.all([
|
|
148
|
+
env.USERS.get("user:123", "json"),
|
|
149
|
+
env.SETTINGS.get("config:app", "json"),
|
|
150
|
+
env.CACHE.get("data:latest")
|
|
151
|
+
]);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Error Handling
|
|
155
|
+
|
|
156
|
+
- **Missing keys:** Return `null` (not an error)
|
|
157
|
+
- **Rate limit (429):** Retry with exponential backoff (see gotchas.md)
|
|
158
|
+
- **Response too large (413):** Values >25MB fail with 413 error
|
|
159
|
+
|
|
160
|
+
See [gotchas.md](./gotchas.md) for detailed error patterns and solutions.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# KV Configuration
|
|
2
|
+
|
|
3
|
+
## Create Namespace
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
wrangler kv namespace create MY_NAMESPACE
|
|
7
|
+
# Output: { binding = "MY_NAMESPACE", id = "abc123..." }
|
|
8
|
+
|
|
9
|
+
wrangler kv namespace create MY_NAMESPACE --preview # For local dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Workers Binding
|
|
13
|
+
|
|
14
|
+
**wrangler.jsonc:**
|
|
15
|
+
```jsonc
|
|
16
|
+
{
|
|
17
|
+
"kv_namespaces": [
|
|
18
|
+
{
|
|
19
|
+
"binding": "MY_KV",
|
|
20
|
+
"id": "abc123xyz789"
|
|
21
|
+
},
|
|
22
|
+
// Optional: Different namespace for preview/development
|
|
23
|
+
{
|
|
24
|
+
"binding": "MY_KV",
|
|
25
|
+
"preview_id": "preview-abc123"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## TypeScript Types
|
|
32
|
+
|
|
33
|
+
**env.d.ts:**
|
|
34
|
+
```typescript
|
|
35
|
+
interface Env {
|
|
36
|
+
MY_KV: KVNamespace;
|
|
37
|
+
SESSIONS: KVNamespace;
|
|
38
|
+
CACHE: KVNamespace;
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**worker.ts:**
|
|
43
|
+
```typescript
|
|
44
|
+
export default {
|
|
45
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
46
|
+
// env.MY_KV is now typed as KVNamespace
|
|
47
|
+
const value = await env.MY_KV.get("key");
|
|
48
|
+
return new Response(value || "Not found");
|
|
49
|
+
}
|
|
50
|
+
} satisfies ExportedHandler<Env>;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Type-safe JSON operations:**
|
|
54
|
+
```typescript
|
|
55
|
+
interface UserProfile {
|
|
56
|
+
name: string;
|
|
57
|
+
email: string;
|
|
58
|
+
role: "admin" | "user";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const profile = await env.USERS.get<UserProfile>("user:123", "json");
|
|
62
|
+
// profile: UserProfile | null (type-safe!)
|
|
63
|
+
if (profile) {
|
|
64
|
+
console.log(profile.name); // TypeScript knows this is a string
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## CLI Operations
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Put
|
|
72
|
+
wrangler kv key put --binding=MY_KV "key" "value"
|
|
73
|
+
wrangler kv key put --binding=MY_KV "key" --path=./file.json --ttl=3600
|
|
74
|
+
|
|
75
|
+
# Get
|
|
76
|
+
wrangler kv key get --binding=MY_KV "key"
|
|
77
|
+
|
|
78
|
+
# Delete
|
|
79
|
+
wrangler kv key delete --binding=MY_KV "key"
|
|
80
|
+
|
|
81
|
+
# List
|
|
82
|
+
wrangler kv key list --binding=MY_KV --prefix="user:"
|
|
83
|
+
|
|
84
|
+
# Bulk operations (max 10,000 keys per file)
|
|
85
|
+
wrangler kv bulk put data.json --binding=MY_KV
|
|
86
|
+
wrangler kv bulk get keys.json --binding=MY_KV
|
|
87
|
+
wrangler kv bulk delete keys.json --binding=MY_KV --force
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Local Development
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
wrangler dev # Local KV (isolated)
|
|
94
|
+
wrangler dev --remote # Remote KV (production)
|
|
95
|
+
|
|
96
|
+
# Or in wrangler.jsonc:
|
|
97
|
+
# "kv_namespaces": [{ "binding": "MY_KV", "id": "...", "remote": true }]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## REST API
|
|
101
|
+
|
|
102
|
+
### Single Operations
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import Cloudflare from 'cloudflare';
|
|
106
|
+
|
|
107
|
+
const client = new Cloudflare({
|
|
108
|
+
apiEmail: process.env.CLOUDFLARE_EMAIL,
|
|
109
|
+
apiKey: process.env.CLOUDFLARE_API_KEY
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Single key operations
|
|
113
|
+
await client.kv.namespaces.values.update(namespaceId, 'key', {
|
|
114
|
+
account_id: accountId,
|
|
115
|
+
value: 'value',
|
|
116
|
+
expiration_ttl: 3600
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Bulk Operations
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Bulk update (up to 10,000 keys, max 100MB total)
|
|
124
|
+
await client.kv.namespaces.bulkUpdate(namespaceId, {
|
|
125
|
+
account_id: accountId,
|
|
126
|
+
body: [
|
|
127
|
+
{ key: "key1", value: "value1", expiration_ttl: 3600 },
|
|
128
|
+
{ key: "key2", value: "value2", metadata: { version: 1 } },
|
|
129
|
+
{ key: "key3", value: "value3" }
|
|
130
|
+
]
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Bulk get (up to 100 keys)
|
|
134
|
+
const results = await client.kv.namespaces.bulkGet(namespaceId, {
|
|
135
|
+
account_id: accountId,
|
|
136
|
+
keys: ["key1", "key2", "key3"]
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Bulk delete (up to 10,000 keys)
|
|
140
|
+
await client.kv.namespaces.bulkDelete(namespaceId, {
|
|
141
|
+
account_id: accountId,
|
|
142
|
+
keys: ["key1", "key2", "key3"]
|
|
143
|
+
});
|
|
144
|
+
```
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# KV Gotchas & Troubleshooting
|
|
2
|
+
|
|
3
|
+
## Common Errors
|
|
4
|
+
|
|
5
|
+
### "Stale Read After Write"
|
|
6
|
+
|
|
7
|
+
**Cause:** Eventual consistency means writes may not be immediately visible in other regions
|
|
8
|
+
**Solution:** Don't read immediately after write; return confirmation without reading or use the local value you just wrote. Writes visible immediately in same location, ≤60s globally
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
// ❌ BAD: Read immediately after write
|
|
12
|
+
await env.KV.put("key", "value");
|
|
13
|
+
const value = await env.KV.get("key"); // May be null in other regions!
|
|
14
|
+
|
|
15
|
+
// ✅ GOOD: Use the value you just wrote
|
|
16
|
+
const newValue = "value";
|
|
17
|
+
await env.KV.put("key", newValue);
|
|
18
|
+
return new Response(newValue); // Don't re-read
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### "429 Rate Limit on Concurrent Writes"
|
|
22
|
+
|
|
23
|
+
**Cause:** Multiple concurrent writes to same key exceeding 1 write/second limit
|
|
24
|
+
**Solution:** Use sequential writes, unique keys for concurrent operations, or implement retry with exponential backoff
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
async function putWithRetry(
|
|
28
|
+
kv: KVNamespace,
|
|
29
|
+
key: string,
|
|
30
|
+
value: string,
|
|
31
|
+
maxAttempts = 5
|
|
32
|
+
): Promise<void> {
|
|
33
|
+
let delay = 1000;
|
|
34
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
35
|
+
try {
|
|
36
|
+
await kv.put(key, value);
|
|
37
|
+
return;
|
|
38
|
+
} catch (err) {
|
|
39
|
+
if (err instanceof Error && err.message.includes("429")) {
|
|
40
|
+
if (i === maxAttempts - 1) throw err;
|
|
41
|
+
await new Promise(r => setTimeout(r, delay));
|
|
42
|
+
delay *= 2; // Exponential backoff
|
|
43
|
+
} else {
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### "Inefficient Multiple Gets"
|
|
52
|
+
|
|
53
|
+
**Cause:** Making multiple individual get() calls instead of bulk operation
|
|
54
|
+
**Solution:** Use bulk get with array of keys: `env.USERS.get(["user:1", "user:2", "user:3"])` to reduce to 1 operation
|
|
55
|
+
|
|
56
|
+
### "Null Reference Error"
|
|
57
|
+
|
|
58
|
+
**Cause:** Attempting to use value without checking for null when key doesn't exist
|
|
59
|
+
**Solution:** Always handle null returns - KV returns `null` for missing keys, not undefined
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// ❌ BAD: Assumes value exists
|
|
63
|
+
const config = await env.KV.get("config", "json");
|
|
64
|
+
return config.theme; // TypeError if null!
|
|
65
|
+
|
|
66
|
+
// ✅ GOOD: Null checks
|
|
67
|
+
const config = await env.KV.get("config", "json");
|
|
68
|
+
return config?.theme ?? "default";
|
|
69
|
+
|
|
70
|
+
// ✅ GOOD: Early return
|
|
71
|
+
const config = await env.KV.get("config", "json");
|
|
72
|
+
if (!config) return new Response("Not found", { status: 404 });
|
|
73
|
+
return new Response(config.theme);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### "Negative Lookup Caching"
|
|
77
|
+
|
|
78
|
+
**Cause:** Keys that don't exist are cached as "not found" for up to 60s
|
|
79
|
+
**Solution:** Creating a key after checking won't be visible until cache expires
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Check → create pattern has race condition
|
|
83
|
+
const exists = await env.KV.get("key"); // null, cached as "not found"
|
|
84
|
+
if (!exists) {
|
|
85
|
+
await env.KV.put("key", "value");
|
|
86
|
+
// Next get() may still return null for ~60s due to negative cache
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Alternative: Always assume key may not exist, use defaults
|
|
90
|
+
const value = await env.KV.get("key") ?? "default-value";
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Performance Tips
|
|
94
|
+
|
|
95
|
+
| Scenario | Recommendation | Why |
|
|
96
|
+
|----------|----------------|-----|
|
|
97
|
+
| Large values (>1MB) | Use `stream` type | Avoids buffering entire value in memory |
|
|
98
|
+
| Many small keys | Coalesce into one JSON object | Reduces operations, improves cache hit rate |
|
|
99
|
+
| High write volume | Spread across different keys | Avoid 1 write/second per-key limit |
|
|
100
|
+
| Cold reads | Increase `cacheTtl` parameter | Reduces latency for frequently-read data |
|
|
101
|
+
| Bulk operations | Use array form of get() | Single operation, better performance |
|
|
102
|
+
|
|
103
|
+
## Cost Examples
|
|
104
|
+
|
|
105
|
+
**Free tier:**
|
|
106
|
+
- 100K reads/day = 3M/month ✅
|
|
107
|
+
- 1K writes/day = 30K/month ✅
|
|
108
|
+
- 1GB storage ✅
|
|
109
|
+
|
|
110
|
+
**Example paid workload:**
|
|
111
|
+
- 10M reads/month = $5.00
|
|
112
|
+
- 100K writes/month = $0.50
|
|
113
|
+
- 1GB storage = $0.50
|
|
114
|
+
- **Total: ~$6/month**
|
|
115
|
+
|
|
116
|
+
## Limits
|
|
117
|
+
|
|
118
|
+
| Limit | Value | Notes |
|
|
119
|
+
|-------|-------|-------|
|
|
120
|
+
| Key size | 512 bytes | Maximum key length |
|
|
121
|
+
| Value size | 25 MiB | Maximum value; 413 error if exceeded |
|
|
122
|
+
| Metadata size | 1024 bytes | Maximum metadata per key |
|
|
123
|
+
| cacheTtl minimum | 60s | Minimum cache TTL |
|
|
124
|
+
| Write rate per key | 1 write/second | All plans; 429 error if exceeded |
|
|
125
|
+
| Propagation time | ≤60s | Global propagation time |
|
|
126
|
+
| Bulk get max | 100 keys | Maximum keys per bulk operation |
|
|
127
|
+
| Operations per Worker | 1,000 | Per request (bulk counts as 1) |
|
|
128
|
+
| Reads pricing | $0.50 per 1M | Per million reads |
|
|
129
|
+
| Writes pricing | $5.00 per 1M | Per million writes |
|
|
130
|
+
| Deletes pricing | $5.00 per 1M | Per million deletes |
|
|
131
|
+
| Storage pricing | $0.50 per GB-month | Per GB per month |
|