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,295 @@
|
|
|
1
|
+
# Durable Objects Rules & Best Practices
|
|
2
|
+
|
|
3
|
+
## Design & Sharding
|
|
4
|
+
|
|
5
|
+
### Model Around Coordination Atoms
|
|
6
|
+
|
|
7
|
+
Create one DO per logical unit needing coordination: chat room, game session, document, user, tenant.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ Good: One DO per chat room
|
|
11
|
+
const stub = env.CHAT_ROOM.getByName(roomId);
|
|
12
|
+
|
|
13
|
+
// ❌ Bad: Single global DO
|
|
14
|
+
const stub = env.CHAT_ROOM.getByName("global"); // Bottleneck!
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Parent-Child Relationships
|
|
18
|
+
|
|
19
|
+
For hierarchical data, create separate child DOs. Parent tracks references, children handle own state.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// Parent: GameServer tracks match references
|
|
23
|
+
// Children: GameMatch handles individual match state
|
|
24
|
+
async createMatch(name: string): Promise<string> {
|
|
25
|
+
const matchId = crypto.randomUUID();
|
|
26
|
+
this.ctx.storage.sql.exec(
|
|
27
|
+
"INSERT INTO matches (id, name) VALUES (?, ?)",
|
|
28
|
+
matchId, name
|
|
29
|
+
);
|
|
30
|
+
const child = this.env.GAME_MATCH.getByName(matchId);
|
|
31
|
+
await child.init(matchId, name);
|
|
32
|
+
return matchId;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Location Hints
|
|
37
|
+
|
|
38
|
+
Influence DO creation location for latency-sensitive apps:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
const id = env.GAME.idFromName(gameId, { locationHint: "wnam" });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Available hints: `wnam`, `enam`, `sam`, `weur`, `eeur`, `apac`, `oc`, `afr`, `me`.
|
|
45
|
+
|
|
46
|
+
## Storage
|
|
47
|
+
|
|
48
|
+
### SQLite (Recommended)
|
|
49
|
+
|
|
50
|
+
Configure in wrangler:
|
|
51
|
+
```jsonc
|
|
52
|
+
{ "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyDO"] }] }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
SQL API is synchronous:
|
|
56
|
+
```typescript
|
|
57
|
+
// Write
|
|
58
|
+
this.ctx.storage.sql.exec(
|
|
59
|
+
"INSERT INTO items (name, value) VALUES (?, ?)",
|
|
60
|
+
name, value
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// Read
|
|
64
|
+
const rows = this.ctx.storage.sql.exec<{ id: number; name: string }>(
|
|
65
|
+
"SELECT * FROM items WHERE name = ?", name
|
|
66
|
+
).toArray();
|
|
67
|
+
|
|
68
|
+
// Single row
|
|
69
|
+
const row = this.ctx.storage.sql.exec<{ count: number }>(
|
|
70
|
+
"SELECT COUNT(*) as count FROM items"
|
|
71
|
+
).one();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Migrations
|
|
75
|
+
|
|
76
|
+
**Note:** `PRAGMA user_version` is **not supported** in Durable Objects SQLite storage. Use a `_sql_schema_migrations` table instead:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
constructor(ctx: DurableObjectState, env: Env) {
|
|
80
|
+
super(ctx, env);
|
|
81
|
+
ctx.blockConcurrencyWhile(async () => this.migrate());
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private migrate() {
|
|
85
|
+
this.ctx.storage.sql.exec(`
|
|
86
|
+
CREATE TABLE IF NOT EXISTS _sql_schema_migrations (
|
|
87
|
+
id INTEGER PRIMARY KEY,
|
|
88
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
89
|
+
)
|
|
90
|
+
`);
|
|
91
|
+
|
|
92
|
+
const currentVersion = this.ctx.storage.sql
|
|
93
|
+
.exec<{ version: number }>("SELECT COALESCE(MAX(id), 0) as version FROM _sql_schema_migrations")
|
|
94
|
+
.one().version;
|
|
95
|
+
|
|
96
|
+
if (currentVersion < 1) {
|
|
97
|
+
this.ctx.storage.sql.exec(`
|
|
98
|
+
CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, data TEXT);
|
|
99
|
+
CREATE INDEX IF NOT EXISTS idx_items_data ON items(data);
|
|
100
|
+
INSERT INTO _sql_schema_migrations (id) VALUES (1);
|
|
101
|
+
`);
|
|
102
|
+
}
|
|
103
|
+
if (currentVersion < 2) {
|
|
104
|
+
this.ctx.storage.sql.exec(`
|
|
105
|
+
ALTER TABLE items ADD COLUMN created_at INTEGER;
|
|
106
|
+
INSERT INTO _sql_schema_migrations (id) VALUES (2);
|
|
107
|
+
`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
For production apps, consider [`durable-utils`](https://github.com/lambrospetrou/durable-utils#sqlite-schema-migrations) — provides a `SQLSchemaMigrations` class that tracks executed migrations both in memory and in storage. Also see [`@cloudflare/actors` storage utilities](https://github.com/cloudflare/actors/blob/main/packages/storage/src/sql-schema-migrations.ts) — a reference implementation of the same pattern used by the Cloudflare Actors framework.
|
|
113
|
+
|
|
114
|
+
### State Types
|
|
115
|
+
|
|
116
|
+
| Type | Speed | Persistence | Use Case |
|
|
117
|
+
|------|-------|-------------|----------|
|
|
118
|
+
| Class properties | Fastest | Lost on eviction | Caching, active connections |
|
|
119
|
+
| SQLite storage | Fast | Durable | Primary data |
|
|
120
|
+
| External (R2, D1) | Variable | Durable, cross-DO | Large files, shared data |
|
|
121
|
+
|
|
122
|
+
**Rule**: Always persist critical state to SQLite first, then update in-memory cache.
|
|
123
|
+
|
|
124
|
+
## Concurrency
|
|
125
|
+
|
|
126
|
+
### Input/Output Gates
|
|
127
|
+
|
|
128
|
+
Storage operations automatically block other requests (input gates). Responses wait for writes (output gates).
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
async increment(): Promise<number> {
|
|
132
|
+
// Safe: input gates block interleaving during storage ops
|
|
133
|
+
const val = (await this.ctx.storage.get<number>("count")) ?? 0;
|
|
134
|
+
await this.ctx.storage.put("count", val + 1);
|
|
135
|
+
return val + 1;
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Write Coalescing
|
|
140
|
+
|
|
141
|
+
Multiple writes without `await` between them are batched atomically:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// ✅ Good: All three writes commit atomically
|
|
145
|
+
this.ctx.storage.sql.exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, fromId);
|
|
146
|
+
this.ctx.storage.sql.exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, toId);
|
|
147
|
+
this.ctx.storage.sql.exec("INSERT INTO transfers (from_id, to_id, amount) VALUES (?, ?, ?)", fromId, toId, amount);
|
|
148
|
+
|
|
149
|
+
// ❌ Bad: await breaks coalescing
|
|
150
|
+
await this.ctx.storage.put("key1", val1);
|
|
151
|
+
await this.ctx.storage.put("key2", val2); // Separate transaction!
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Race Conditions with External I/O
|
|
155
|
+
|
|
156
|
+
`fetch()` and other non-storage I/O allows interleaving:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// ⚠️ Race condition possible
|
|
160
|
+
async processItem(id: string) {
|
|
161
|
+
const item = await this.ctx.storage.get<Item>(`item:${id}`);
|
|
162
|
+
if (item?.status === "pending") {
|
|
163
|
+
await fetch("https://api.example.com/process"); // Other requests can run here!
|
|
164
|
+
await this.ctx.storage.put(`item:${id}`, { status: "completed" });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Solution**: Use optimistic locking (version numbers) or `transaction()`.
|
|
170
|
+
|
|
171
|
+
### blockConcurrencyWhile()
|
|
172
|
+
|
|
173
|
+
Blocks ALL concurrency. Use sparingly - only for initialization:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// ✅ Good: One-time init
|
|
177
|
+
constructor(ctx: DurableObjectState, env: Env) {
|
|
178
|
+
super(ctx, env);
|
|
179
|
+
ctx.blockConcurrencyWhile(async () => this.migrate());
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ❌ Bad: On every request (kills throughput)
|
|
183
|
+
async handleRequest() {
|
|
184
|
+
await this.ctx.blockConcurrencyWhile(async () => {
|
|
185
|
+
// ~5ms = max 200 req/sec
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Never** hold across external I/O (fetch, R2, KV).
|
|
191
|
+
|
|
192
|
+
## RPC Methods
|
|
193
|
+
|
|
194
|
+
Use RPC (compatibility date >= 2024-04-03) instead of fetch() handler:
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
export class ChatRoom extends DurableObject<Env> {
|
|
198
|
+
async sendMessage(userId: string, content: string): Promise<Message> {
|
|
199
|
+
// Public methods are RPC endpoints
|
|
200
|
+
const result = this.ctx.storage.sql.exec<{ id: number }>(
|
|
201
|
+
"INSERT INTO messages (user_id, content) VALUES (?, ?) RETURNING id",
|
|
202
|
+
userId, content
|
|
203
|
+
);
|
|
204
|
+
return { id: result.one().id, userId, content };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Caller
|
|
209
|
+
const stub = env.CHAT_ROOM.getByName(roomId);
|
|
210
|
+
const msg = await stub.sendMessage("user-123", "Hello!"); // Typed!
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Explicit init() Method
|
|
214
|
+
|
|
215
|
+
DOs don't know their own ID. Pass identity explicitly:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
async init(entityId: string, metadata: Metadata): Promise<void> {
|
|
219
|
+
await this.ctx.storage.put("entityId", entityId);
|
|
220
|
+
await this.ctx.storage.put("metadata", metadata);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Alarms
|
|
225
|
+
|
|
226
|
+
One alarm per DO. `setAlarm()` replaces existing.
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Schedule
|
|
230
|
+
await this.ctx.storage.setAlarm(Date.now() + 60_000);
|
|
231
|
+
|
|
232
|
+
// Handler
|
|
233
|
+
async alarm(): Promise<void> {
|
|
234
|
+
const tasks = this.ctx.storage.sql.exec<Task>(
|
|
235
|
+
"SELECT * FROM tasks WHERE due_at <= ?", Date.now()
|
|
236
|
+
).toArray();
|
|
237
|
+
|
|
238
|
+
for (const task of tasks) {
|
|
239
|
+
await this.processTask(task);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Reschedule if more work
|
|
243
|
+
const next = this.ctx.storage.sql.exec<{ due_at: number }>(
|
|
244
|
+
"SELECT MIN(due_at) as due_at FROM tasks WHERE due_at > ?", Date.now()
|
|
245
|
+
).one();
|
|
246
|
+
if (next?.due_at) {
|
|
247
|
+
await this.ctx.storage.setAlarm(next.due_at);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Get/Delete
|
|
252
|
+
const alarm = await this.ctx.storage.getAlarm();
|
|
253
|
+
await this.ctx.storage.deleteAlarm();
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Retry**: Alarms auto-retry on failure. Use idempotent handlers.
|
|
257
|
+
|
|
258
|
+
## WebSockets (Hibernation API)
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
async fetch(request: Request): Promise<Response> {
|
|
262
|
+
const pair = new WebSocketPair();
|
|
263
|
+
this.ctx.acceptWebSocket(pair[1]);
|
|
264
|
+
return new Response(null, { status: 101, webSocket: pair[0] });
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {
|
|
268
|
+
const data = JSON.parse(message as string);
|
|
269
|
+
// Handle message
|
|
270
|
+
ws.send(JSON.stringify({ type: "ack" }));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async webSocketClose(ws: WebSocket, code: number, reason: string) {
|
|
274
|
+
// Cleanup
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Broadcast
|
|
278
|
+
getWebSockets().forEach(ws => ws.send(JSON.stringify(payload)));
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Error Handling
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
async safeOperation(): Promise<Result> {
|
|
285
|
+
try {
|
|
286
|
+
return await this.riskyOperation();
|
|
287
|
+
} catch (error) {
|
|
288
|
+
console.error("Operation failed:", error);
|
|
289
|
+
// Log to external service if needed
|
|
290
|
+
throw error; // Re-throw to signal failure to caller
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Note**: Uncaught exceptions may terminate the DO instance. In-memory state is lost, but SQLite storage persists.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Testing Durable Objects
|
|
2
|
+
|
|
3
|
+
Use `@cloudflare/vitest-pool-workers` to test DOs inside the Workers runtime.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### Install Dependencies
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i -D vitest@~3.2.0 @cloudflare/vitest-pool-workers
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### vitest.config.ts
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";
|
|
17
|
+
|
|
18
|
+
export default defineWorkersConfig({
|
|
19
|
+
test: {
|
|
20
|
+
poolOptions: {
|
|
21
|
+
workers: {
|
|
22
|
+
wrangler: { configPath: "./wrangler.toml" },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### TypeScript Config (test/tsconfig.json)
|
|
30
|
+
|
|
31
|
+
```jsonc
|
|
32
|
+
{
|
|
33
|
+
"extends": "../tsconfig.json",
|
|
34
|
+
"compilerOptions": {
|
|
35
|
+
"moduleResolution": "bundler",
|
|
36
|
+
"types": ["@cloudflare/vitest-pool-workers"]
|
|
37
|
+
},
|
|
38
|
+
"include": ["./**/*.ts", "../src/worker-configuration.d.ts"]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Environment Types (env.d.ts)
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
declare module "cloudflare:test" {
|
|
46
|
+
interface ProvidedEnv extends Env {}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Unit Tests (Direct DO Access)
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { env } from "cloudflare:test";
|
|
54
|
+
import { describe, it, expect } from "vitest";
|
|
55
|
+
|
|
56
|
+
describe("Counter DO", () => {
|
|
57
|
+
it("should increment", async () => {
|
|
58
|
+
const stub = env.COUNTER.getByName("test-counter");
|
|
59
|
+
|
|
60
|
+
expect(await stub.increment()).toBe(1);
|
|
61
|
+
expect(await stub.increment()).toBe(2);
|
|
62
|
+
expect(await stub.getCount()).toBe(2);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("isolates different instances", async () => {
|
|
66
|
+
const stub1 = env.COUNTER.getByName("counter-1");
|
|
67
|
+
const stub2 = env.COUNTER.getByName("counter-2");
|
|
68
|
+
|
|
69
|
+
await stub1.increment();
|
|
70
|
+
await stub1.increment();
|
|
71
|
+
await stub2.increment();
|
|
72
|
+
|
|
73
|
+
expect(await stub1.getCount()).toBe(2);
|
|
74
|
+
expect(await stub2.getCount()).toBe(1);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Integration Tests (HTTP via SELF)
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { SELF } from "cloudflare:test";
|
|
83
|
+
import { describe, it, expect } from "vitest";
|
|
84
|
+
|
|
85
|
+
describe("Worker HTTP", () => {
|
|
86
|
+
it("should increment via POST", async () => {
|
|
87
|
+
const res = await SELF.fetch("http://example.com?id=test", {
|
|
88
|
+
method: "POST",
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(res.status).toBe(200);
|
|
92
|
+
const data = await res.json<{ count: number }>();
|
|
93
|
+
expect(data.count).toBe(1);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("should get count via GET", async () => {
|
|
97
|
+
await SELF.fetch("http://example.com?id=get-test", { method: "POST" });
|
|
98
|
+
await SELF.fetch("http://example.com?id=get-test", { method: "POST" });
|
|
99
|
+
|
|
100
|
+
const res = await SELF.fetch("http://example.com?id=get-test");
|
|
101
|
+
const data = await res.json<{ count: number }>();
|
|
102
|
+
expect(data.count).toBe(2);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Direct Internal Access
|
|
108
|
+
|
|
109
|
+
Use `runInDurableObject()` to access instance internals and storage:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { env, runInDurableObject } from "cloudflare:test";
|
|
113
|
+
import { describe, it, expect } from "vitest";
|
|
114
|
+
import { Counter } from "../src";
|
|
115
|
+
|
|
116
|
+
describe("DO internals", () => {
|
|
117
|
+
it("can verify storage directly", async () => {
|
|
118
|
+
const stub = env.COUNTER.getByName("direct-test");
|
|
119
|
+
await stub.increment();
|
|
120
|
+
await stub.increment();
|
|
121
|
+
|
|
122
|
+
await runInDurableObject(stub, async (instance: Counter, state) => {
|
|
123
|
+
expect(instance).toBeInstanceOf(Counter);
|
|
124
|
+
|
|
125
|
+
const result = state.storage.sql
|
|
126
|
+
.exec<{ value: number }>(
|
|
127
|
+
"SELECT value FROM counters WHERE name = ?",
|
|
128
|
+
"default"
|
|
129
|
+
)
|
|
130
|
+
.one();
|
|
131
|
+
expect(result.value).toBe(2);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## List DO IDs
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { env, listDurableObjectIds } from "cloudflare:test";
|
|
141
|
+
import { describe, it, expect } from "vitest";
|
|
142
|
+
|
|
143
|
+
describe("DO listing", () => {
|
|
144
|
+
it("can list all IDs in namespace", async () => {
|
|
145
|
+
const id1 = env.COUNTER.idFromName("list-1");
|
|
146
|
+
const id2 = env.COUNTER.idFromName("list-2");
|
|
147
|
+
|
|
148
|
+
await env.COUNTER.get(id1).increment();
|
|
149
|
+
await env.COUNTER.get(id2).increment();
|
|
150
|
+
|
|
151
|
+
const ids = await listDurableObjectIds(env.COUNTER);
|
|
152
|
+
expect(ids.length).toBe(2);
|
|
153
|
+
expect(ids.some(id => id.equals(id1))).toBe(true);
|
|
154
|
+
expect(ids.some(id => id.equals(id2))).toBe(true);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Testing Alarms
|
|
160
|
+
|
|
161
|
+
Use `runDurableObjectAlarm()` to trigger alarms immediately:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { env, runInDurableObject, runDurableObjectAlarm } from "cloudflare:test";
|
|
165
|
+
import { describe, it, expect } from "vitest";
|
|
166
|
+
|
|
167
|
+
describe("DO alarms", () => {
|
|
168
|
+
it("can trigger alarms immediately", async () => {
|
|
169
|
+
const stub = env.COUNTER.getByName("alarm-test");
|
|
170
|
+
await stub.increment();
|
|
171
|
+
await stub.increment();
|
|
172
|
+
expect(await stub.getCount()).toBe(2);
|
|
173
|
+
|
|
174
|
+
// Schedule alarm
|
|
175
|
+
await runInDurableObject(stub, async (instance, state) => {
|
|
176
|
+
await state.storage.setAlarm(Date.now() + 60_000);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Execute immediately without waiting
|
|
180
|
+
const ran = await runDurableObjectAlarm(stub);
|
|
181
|
+
expect(ran).toBe(true);
|
|
182
|
+
|
|
183
|
+
// Verify alarm handler ran (if it resets counter)
|
|
184
|
+
expect(await stub.getCount()).toBe(0);
|
|
185
|
+
|
|
186
|
+
// No alarm scheduled now
|
|
187
|
+
const ranAgain = await runDurableObjectAlarm(stub);
|
|
188
|
+
expect(ranAgain).toBe(false);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Example alarm handler:
|
|
194
|
+
```typescript
|
|
195
|
+
async alarm(): Promise<void> {
|
|
196
|
+
this.ctx.storage.sql.exec("DELETE FROM counters");
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Test Isolation
|
|
201
|
+
|
|
202
|
+
Each test gets isolated storage automatically. DOs from one test don't affect others:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
describe("Isolation", () => {
|
|
206
|
+
it("first test creates DO", async () => {
|
|
207
|
+
const stub = env.COUNTER.getByName("isolated");
|
|
208
|
+
await stub.increment();
|
|
209
|
+
expect(await stub.getCount()).toBe(1);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("second test has fresh state", async () => {
|
|
213
|
+
const ids = await listDurableObjectIds(env.COUNTER);
|
|
214
|
+
expect(ids.length).toBe(0); // Previous test's DO is gone
|
|
215
|
+
|
|
216
|
+
const stub = env.COUNTER.getByName("isolated");
|
|
217
|
+
expect(await stub.getCount()).toBe(0); // Fresh instance
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## SQLite Storage Testing
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
describe("SQLite", () => {
|
|
226
|
+
it("can verify SQL storage", async () => {
|
|
227
|
+
const stub = env.COUNTER.getByName("sqlite-test");
|
|
228
|
+
await stub.increment("page-views");
|
|
229
|
+
await stub.increment("page-views");
|
|
230
|
+
await stub.increment("api-calls");
|
|
231
|
+
|
|
232
|
+
await runInDurableObject(stub, async (instance, state) => {
|
|
233
|
+
const rows = state.storage.sql
|
|
234
|
+
.exec<{ name: string; value: number }>(
|
|
235
|
+
"SELECT name, value FROM counters ORDER BY name"
|
|
236
|
+
)
|
|
237
|
+
.toArray();
|
|
238
|
+
|
|
239
|
+
expect(rows).toEqual([
|
|
240
|
+
{ name: "api-calls", value: 1 },
|
|
241
|
+
{ name: "page-views", value: 2 },
|
|
242
|
+
]);
|
|
243
|
+
|
|
244
|
+
expect(state.storage.sql.databaseSize).toBeGreaterThan(0);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Running Tests
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npx vitest # Watch mode
|
|
254
|
+
npx vitest run # Single run
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
package.json:
|
|
258
|
+
```json
|
|
259
|
+
{
|
|
260
|
+
"scripts": {
|
|
261
|
+
"test": "vitest"
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|