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,184 @@
|
|
|
1
|
+
# Stream Patterns
|
|
2
|
+
|
|
3
|
+
Common workflows, full-stack flows, and best practices.
|
|
4
|
+
|
|
5
|
+
## React Stream Player
|
|
6
|
+
|
|
7
|
+
`npm install @cloudflare/stream-react`
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Stream } from '@cloudflare/stream-react';
|
|
11
|
+
|
|
12
|
+
export function VideoPlayer({ videoId, token }: { videoId: string; token?: string }) {
|
|
13
|
+
return <Stream controls src={token ? `${videoId}?token=${token}` : videoId} responsive />;
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Full-Stack Upload Flow
|
|
18
|
+
|
|
19
|
+
**Backend API (Workers/Pages)**
|
|
20
|
+
```typescript
|
|
21
|
+
import Cloudflare from 'cloudflare';
|
|
22
|
+
|
|
23
|
+
export default {
|
|
24
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
25
|
+
const { videoName } = await request.json();
|
|
26
|
+
const client = new Cloudflare({ apiToken: env.CF_API_TOKEN });
|
|
27
|
+
const { uploadURL, uid } = await client.stream.directUpload.create({
|
|
28
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
29
|
+
maxDurationSeconds: 3600,
|
|
30
|
+
requireSignedURLs: true,
|
|
31
|
+
meta: { name: videoName }
|
|
32
|
+
});
|
|
33
|
+
return Response.json({ uploadURL, uid });
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Frontend component**
|
|
39
|
+
```tsx
|
|
40
|
+
import { useState } from 'react';
|
|
41
|
+
|
|
42
|
+
export function VideoUploader() {
|
|
43
|
+
const [uploading, setUploading] = useState(false);
|
|
44
|
+
const [progress, setProgress] = useState(0);
|
|
45
|
+
|
|
46
|
+
async function handleUpload(file: File) {
|
|
47
|
+
setUploading(true);
|
|
48
|
+
const { uploadURL, uid } = await fetch('/api/upload-url', {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
body: JSON.stringify({ videoName: file.name })
|
|
51
|
+
}).then(r => r.json());
|
|
52
|
+
|
|
53
|
+
const xhr = new XMLHttpRequest();
|
|
54
|
+
xhr.upload.onprogress = (e) => setProgress((e.loaded / e.total) * 100);
|
|
55
|
+
xhr.onload = () => { setUploading(false); window.location.href = `/videos/${uid}`; };
|
|
56
|
+
xhr.open('POST', uploadURL);
|
|
57
|
+
const formData = new FormData();
|
|
58
|
+
formData.append('file', file);
|
|
59
|
+
xhr.send(formData);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div>
|
|
64
|
+
<input type="file" accept="video/*" onChange={(e) => e.target.files?.[0] && handleUpload(e.target.files[0])} disabled={uploading} />
|
|
65
|
+
{uploading && <progress value={progress} max={100} />}
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## TUS Resumable Upload
|
|
72
|
+
|
|
73
|
+
For large files (>500MB). `npm install tus-js-client`
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import * as tus from 'tus-js-client';
|
|
77
|
+
|
|
78
|
+
async function uploadWithTUS(file: File, uploadURL: string, onProgress?: (pct: number) => void) {
|
|
79
|
+
return new Promise<string>((resolve, reject) => {
|
|
80
|
+
const upload = new tus.Upload(file, {
|
|
81
|
+
endpoint: uploadURL,
|
|
82
|
+
retryDelays: [0, 3000, 5000, 10000, 20000],
|
|
83
|
+
chunkSize: 50 * 1024 * 1024,
|
|
84
|
+
metadata: { filename: file.name, filetype: file.type },
|
|
85
|
+
onError: reject,
|
|
86
|
+
onProgress: (up, total) => onProgress?.((up / total) * 100),
|
|
87
|
+
onSuccess: () => resolve(upload.url?.split('/').pop() || '')
|
|
88
|
+
});
|
|
89
|
+
upload.start();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Video State Polling
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
async function waitForVideoReady(client: Cloudflare, accountId: string, videoId: string) {
|
|
98
|
+
for (let i = 0; i < 60; i++) {
|
|
99
|
+
const video = await client.stream.videos.get(videoId, { account_id: accountId });
|
|
100
|
+
if (video.readyToStream || video.status.state === 'error') return video;
|
|
101
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
102
|
+
}
|
|
103
|
+
throw new Error('Video processing timeout');
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Webhook Handler
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
export default {
|
|
111
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
112
|
+
const signature = request.headers.get('Webhook-Signature');
|
|
113
|
+
const body = await request.text();
|
|
114
|
+
if (!signature || !await verifyWebhook(signature, body, env.WEBHOOK_SECRET)) {
|
|
115
|
+
return new Response('Unauthorized', { status: 401 });
|
|
116
|
+
}
|
|
117
|
+
const payload = JSON.parse(body);
|
|
118
|
+
if (payload.readyToStream) console.log(`Video ${payload.uid} ready`);
|
|
119
|
+
return new Response('OK');
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
async function verifyWebhook(sig: string, body: string, secret: string): Promise<boolean> {
|
|
124
|
+
const parts = Object.fromEntries(sig.split(',').map(p => p.split('=')));
|
|
125
|
+
const timestamp = parseInt(parts.time || '0', 10);
|
|
126
|
+
if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
|
|
127
|
+
|
|
128
|
+
const key = await crypto.subtle.importKey(
|
|
129
|
+
'raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
|
|
130
|
+
);
|
|
131
|
+
const computed = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${timestamp}.${body}`));
|
|
132
|
+
const hex = Array.from(new Uint8Array(computed), b => b.toString(16).padStart(2, '0')).join('');
|
|
133
|
+
return hex === parts.sig1;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Self-Sign JWT (High Volume Tokens)
|
|
138
|
+
|
|
139
|
+
For >1k tokens/day. Prerequisites: Create signing key (see configuration.md).
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
async function selfSignToken(keyId: string, jwkBase64: string, videoId: string, expiresIn = 3600) {
|
|
143
|
+
const key = await crypto.subtle.importKey(
|
|
144
|
+
'jwk', JSON.parse(atob(jwkBase64)), { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, ['sign']
|
|
145
|
+
);
|
|
146
|
+
const now = Math.floor(Date.now() / 1000);
|
|
147
|
+
const header = btoa(JSON.stringify({ alg: 'RS256', kid: keyId })).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
148
|
+
const payload = btoa(JSON.stringify({ sub: videoId, kid: keyId, exp: now + expiresIn, nbf: now }))
|
|
149
|
+
.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
150
|
+
const message = `${header}.${payload}`;
|
|
151
|
+
const sig = await crypto.subtle.sign('RSASSA-PKCS1-v1_5', key, new TextEncoder().encode(message));
|
|
152
|
+
const b64Sig = btoa(String.fromCharCode(...new Uint8Array(sig))).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
|
|
153
|
+
return `${message}.${b64Sig}`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// With access rules (geo-restriction)
|
|
157
|
+
const payloadWithRules = {
|
|
158
|
+
sub: videoId, kid: keyId, exp: now + 3600, nbf: now,
|
|
159
|
+
accessRules: [{ type: 'ip.geoip.country', action: 'allow', country: ['US'] }]
|
|
160
|
+
};
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Best Practices
|
|
164
|
+
|
|
165
|
+
- **Use Direct Creator Uploads** - Avoid proxying through servers
|
|
166
|
+
- **Enable requireSignedURLs** - Control private content access
|
|
167
|
+
- **Self-sign tokens at scale** - Use signing keys for >1k/day
|
|
168
|
+
- **Set allowedOrigins** - Prevent hotlinking
|
|
169
|
+
- **Use webhooks over polling** - Efficient status updates
|
|
170
|
+
- **Set maxDurationSeconds** - Prevent abuse
|
|
171
|
+
- **Enable live recordings** - Auto VOD after stream
|
|
172
|
+
|
|
173
|
+
## In This Reference
|
|
174
|
+
|
|
175
|
+
- [README.md](./README.md) - Overview and quick start
|
|
176
|
+
- [configuration.md](./configuration.md) - Setup and config
|
|
177
|
+
- [api.md](./api.md) - On-demand video APIs
|
|
178
|
+
- [api-live.md](./api-live.md) - Live streaming APIs
|
|
179
|
+
- [gotchas.md](./gotchas.md) - Error codes, troubleshooting
|
|
180
|
+
|
|
181
|
+
## See Also
|
|
182
|
+
|
|
183
|
+
- [workers](../workers/) - Deploy Stream APIs in Workers
|
|
184
|
+
- [pages](../pages/) - Integrate Stream with Pages
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Cloudflare Tail Workers
|
|
2
|
+
|
|
3
|
+
Specialized Workers that consume execution events from producer Workers for logging, debugging, analytics, and observability.
|
|
4
|
+
|
|
5
|
+
## When to Use This Reference
|
|
6
|
+
|
|
7
|
+
- Implementing observability/logging for Cloudflare Workers
|
|
8
|
+
- Processing Worker execution events, logs, exceptions
|
|
9
|
+
- Building custom analytics or error tracking
|
|
10
|
+
- Configuring real-time event streaming
|
|
11
|
+
- Working with tail handlers or tail consumers
|
|
12
|
+
|
|
13
|
+
## Core Concepts
|
|
14
|
+
|
|
15
|
+
### What Are Tail Workers?
|
|
16
|
+
|
|
17
|
+
Tail Workers automatically process events from producer Workers (the Workers being monitored). They receive:
|
|
18
|
+
- HTTP request/response info
|
|
19
|
+
- Console logs (`console.log/error/warn/debug`)
|
|
20
|
+
- Uncaught exceptions
|
|
21
|
+
- Execution outcomes (`ok`, `exception`, `exceededCpu`, etc.)
|
|
22
|
+
- Diagnostic channel events
|
|
23
|
+
|
|
24
|
+
**Key characteristics:**
|
|
25
|
+
- Invoked AFTER producer finishes executing
|
|
26
|
+
- Capture entire request lifecycle including Service Bindings and Dynamic Dispatch sub-requests
|
|
27
|
+
- Billed by CPU time, not request count
|
|
28
|
+
- Available on Workers Paid and Enterprise tiers
|
|
29
|
+
|
|
30
|
+
### Alternative: OpenTelemetry Export
|
|
31
|
+
|
|
32
|
+
**Before using Tail Workers, consider OpenTelemetry:**
|
|
33
|
+
|
|
34
|
+
For batch exports to observability tools (Sentry, Grafana, Honeycomb):
|
|
35
|
+
- OTEL export sends logs/traces in batches (more efficient)
|
|
36
|
+
- Built-in integrations with popular platforms
|
|
37
|
+
- Lower overhead than Tail Workers
|
|
38
|
+
- **Use Tail Workers only for custom real-time processing**
|
|
39
|
+
|
|
40
|
+
## Decision Tree
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Need observability for Workers?
|
|
44
|
+
├─ Batch export to known tools (Sentry/Grafana/Honeycomb)?
|
|
45
|
+
│ └─ Use OpenTelemetry export (not Tail Workers)
|
|
46
|
+
├─ Custom real-time processing needed?
|
|
47
|
+
│ ├─ Aggregated metrics?
|
|
48
|
+
│ │ └─ Use Tail Worker + Analytics Engine
|
|
49
|
+
│ ├─ Error tracking?
|
|
50
|
+
│ │ └─ Use Tail Worker + external service
|
|
51
|
+
│ ├─ Custom logging/debugging?
|
|
52
|
+
│ │ └─ Use Tail Worker + KV/HTTP endpoint
|
|
53
|
+
│ └─ Complex event processing?
|
|
54
|
+
│ └─ Use Tail Worker + Durable Objects
|
|
55
|
+
└─ Quick debugging?
|
|
56
|
+
└─ Use `wrangler tail` (different from Tail Workers)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Reading Order
|
|
60
|
+
|
|
61
|
+
1. **[configuration.md](configuration.md)** - Set up Tail Workers
|
|
62
|
+
2. **[api.md](api.md)** - Handler signature, types, redaction
|
|
63
|
+
3. **[patterns.md](patterns.md)** - Common use cases and integrations
|
|
64
|
+
4. **[gotchas.md](gotchas.md)** - Pitfalls and debugging tips
|
|
65
|
+
|
|
66
|
+
## Quick Example
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
export default {
|
|
70
|
+
async tail(events, env, ctx) {
|
|
71
|
+
// Process events from producer Worker
|
|
72
|
+
ctx.waitUntil(
|
|
73
|
+
fetch(env.LOG_ENDPOINT, {
|
|
74
|
+
method: "POST",
|
|
75
|
+
headers: { "Content-Type": "application/json" },
|
|
76
|
+
body: JSON.stringify(events),
|
|
77
|
+
})
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Related Skills
|
|
84
|
+
|
|
85
|
+
- **observability** - General Workers observability patterns, OTEL export
|
|
86
|
+
- **analytics-engine** - Aggregated metrics storage for tail event data
|
|
87
|
+
- **durable-objects** - Stateful event processing, batching tail events
|
|
88
|
+
- **logpush** - Alternative for batch log export (non-real-time)
|
|
89
|
+
- **workers-for-platforms** - Dynamic dispatch with tail consumers
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Tail Workers API Reference
|
|
2
|
+
|
|
3
|
+
## Handler Signature
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
export default {
|
|
7
|
+
async tail(
|
|
8
|
+
events: TraceItem[],
|
|
9
|
+
env: Env,
|
|
10
|
+
ctx: ExecutionContext
|
|
11
|
+
): Promise<void> {
|
|
12
|
+
// Process events
|
|
13
|
+
}
|
|
14
|
+
} satisfies ExportedHandler<Env>;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Parameters:**
|
|
18
|
+
- `events`: Array of `TraceItem` objects (one per producer invocation)
|
|
19
|
+
- `env`: Bindings (KV, D1, R2, env vars, etc.)
|
|
20
|
+
- `ctx`: Context with `waitUntil()` for async work
|
|
21
|
+
|
|
22
|
+
**CRITICAL:** Tail handlers don't return values. Use `ctx.waitUntil()` for async operations.
|
|
23
|
+
|
|
24
|
+
## TraceItem Type
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
interface TraceItem {
|
|
28
|
+
scriptName: string; // Producer Worker name
|
|
29
|
+
eventTimestamp: number; // Epoch milliseconds
|
|
30
|
+
outcome: 'ok' | 'exception' | 'exceededCpu' | 'exceededMemory'
|
|
31
|
+
| 'canceled' | 'scriptNotFound' | 'responseStreamDisconnected' | 'unknown';
|
|
32
|
+
|
|
33
|
+
event?: {
|
|
34
|
+
request?: {
|
|
35
|
+
url: string; // Redacted by default
|
|
36
|
+
method: string;
|
|
37
|
+
headers: Record<string, string>; // Sensitive headers redacted
|
|
38
|
+
cf?: IncomingRequestCfProperties;
|
|
39
|
+
getUnredacted(): TraceRequest; // Bypass redaction (use carefully)
|
|
40
|
+
};
|
|
41
|
+
response?: {
|
|
42
|
+
status: number;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
logs: Array<{
|
|
47
|
+
timestamp: number; // Epoch milliseconds
|
|
48
|
+
level: 'debug' | 'info' | 'log' | 'warn' | 'error';
|
|
49
|
+
message: unknown[]; // Args passed to console function
|
|
50
|
+
}>;
|
|
51
|
+
|
|
52
|
+
exceptions: Array<{
|
|
53
|
+
timestamp: number; // Epoch milliseconds
|
|
54
|
+
name: string; // Error type (Error, TypeError, etc.)
|
|
55
|
+
message: string; // Error description
|
|
56
|
+
}>;
|
|
57
|
+
|
|
58
|
+
diagnosticsChannelEvents: Array<{
|
|
59
|
+
channel: string;
|
|
60
|
+
message: unknown;
|
|
61
|
+
timestamp: number; // Epoch milliseconds
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Note:** Official SDK uses `TraceItem`, not `TailItem`. Use `@cloudflare/workers-types` for accurate types.
|
|
67
|
+
|
|
68
|
+
## Timestamp Handling
|
|
69
|
+
|
|
70
|
+
All timestamps are **epoch milliseconds**, not seconds:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// ✅ CORRECT - use directly with Date
|
|
74
|
+
const date = new Date(event.eventTimestamp);
|
|
75
|
+
|
|
76
|
+
// ❌ WRONG - don't multiply by 1000
|
|
77
|
+
const date = new Date(event.eventTimestamp * 1000);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Automatic Redaction
|
|
81
|
+
|
|
82
|
+
By default, sensitive data is redacted from `TraceRequest`:
|
|
83
|
+
|
|
84
|
+
### Header Redaction
|
|
85
|
+
|
|
86
|
+
Headers containing these substrings (case-insensitive):
|
|
87
|
+
- `auth`, `key`, `secret`, `token`, `jwt`
|
|
88
|
+
- `cookie`, `set-cookie`
|
|
89
|
+
|
|
90
|
+
Redacted values show as `"REDACTED"`.
|
|
91
|
+
|
|
92
|
+
### URL Redaction
|
|
93
|
+
|
|
94
|
+
- **Hex IDs:** 32+ hex digits → `"REDACTED"`
|
|
95
|
+
- **Base-64 IDs:** 21+ chars with 2+ upper, 2+ lower, 2+ digits → `"REDACTED"`
|
|
96
|
+
|
|
97
|
+
## Bypassing Redaction
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
export default {
|
|
101
|
+
async tail(events, env, ctx) {
|
|
102
|
+
for (const event of events) {
|
|
103
|
+
// ⚠️ Use with extreme caution
|
|
104
|
+
const unredacted = event.event?.request?.getUnredacted();
|
|
105
|
+
// unredacted.url and unredacted.headers contain raw values
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Best practices:**
|
|
112
|
+
- Only call `getUnredacted()` when absolutely necessary
|
|
113
|
+
- Never log unredacted sensitive data
|
|
114
|
+
- Implement additional filtering before external transmission
|
|
115
|
+
- Use environment variables for API keys, never hardcode
|
|
116
|
+
|
|
117
|
+
## Type-Safe Handler
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
interface Env {
|
|
121
|
+
LOGS_KV: KVNamespace;
|
|
122
|
+
ANALYTICS: AnalyticsEngineDataset;
|
|
123
|
+
LOG_ENDPOINT: string;
|
|
124
|
+
API_TOKEN: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default {
|
|
128
|
+
async tail(
|
|
129
|
+
events: TraceItem[],
|
|
130
|
+
env: Env,
|
|
131
|
+
ctx: ExecutionContext
|
|
132
|
+
): Promise<void> {
|
|
133
|
+
const payload = events.map(event => ({
|
|
134
|
+
script: event.scriptName,
|
|
135
|
+
timestamp: event.eventTimestamp,
|
|
136
|
+
outcome: event.outcome,
|
|
137
|
+
url: event.event?.request?.url,
|
|
138
|
+
status: event.event?.response?.status,
|
|
139
|
+
}));
|
|
140
|
+
|
|
141
|
+
ctx.waitUntil(
|
|
142
|
+
fetch(env.LOG_ENDPOINT, {
|
|
143
|
+
method: "POST",
|
|
144
|
+
headers: { "Content-Type": "application/json" },
|
|
145
|
+
body: JSON.stringify(payload),
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
} satisfies ExportedHandler<Env>;
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Outcome vs HTTP Status
|
|
153
|
+
|
|
154
|
+
**IMPORTANT:** `outcome` is script execution status, NOT HTTP status.
|
|
155
|
+
|
|
156
|
+
- Worker returns 500 → `outcome='ok'` if script completed successfully
|
|
157
|
+
- Uncaught exception → `outcome='exception'` regardless of HTTP status
|
|
158
|
+
- CPU limit exceeded → `outcome='exceededCpu'`
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// ✅ Check outcome for script execution status
|
|
162
|
+
if (event.outcome === 'exception') {
|
|
163
|
+
// Script threw uncaught exception
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ✅ Check HTTP status separately
|
|
167
|
+
if (event.event?.response?.status === 500) {
|
|
168
|
+
// HTTP 500 returned (script may have handled error)
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Serialization Considerations
|
|
173
|
+
|
|
174
|
+
`log.message` is `unknown[]` and may contain non-serializable objects:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// ❌ May fail with circular references or BigInt
|
|
178
|
+
JSON.stringify(events);
|
|
179
|
+
|
|
180
|
+
// ✅ Safe serialization
|
|
181
|
+
const safePayload = events.map(event => ({
|
|
182
|
+
...event,
|
|
183
|
+
logs: event.logs.map(log => ({
|
|
184
|
+
...log,
|
|
185
|
+
message: log.message.map(m => {
|
|
186
|
+
try {
|
|
187
|
+
return JSON.parse(JSON.stringify(m));
|
|
188
|
+
} catch {
|
|
189
|
+
return String(m);
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
}))
|
|
193
|
+
}));
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Common serialization issues:**
|
|
197
|
+
- Circular references in logged objects
|
|
198
|
+
- `BigInt` values (not JSON-serializable)
|
|
199
|
+
- Functions or symbols in console.log arguments
|
|
200
|
+
- Large objects exceeding body size limits
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Tail Workers Configuration
|
|
2
|
+
|
|
3
|
+
## Setup Steps
|
|
4
|
+
|
|
5
|
+
### 1. Create Tail Worker
|
|
6
|
+
|
|
7
|
+
Create a Worker with a `tail()` handler:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export default {
|
|
11
|
+
async tail(events, env, ctx) {
|
|
12
|
+
// Process events from producer Worker
|
|
13
|
+
ctx.waitUntil(
|
|
14
|
+
fetch(env.LOG_ENDPOINT, {
|
|
15
|
+
method: "POST",
|
|
16
|
+
body: JSON.stringify(events),
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 2. Configure Producer Worker
|
|
24
|
+
|
|
25
|
+
In producer's `wrangler.jsonc`:
|
|
26
|
+
|
|
27
|
+
```jsonc
|
|
28
|
+
{
|
|
29
|
+
"name": "my-producer-worker",
|
|
30
|
+
"tail_consumers": [
|
|
31
|
+
{
|
|
32
|
+
"service": "my-tail-worker"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 3. Deploy Both Workers
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Deploy Tail Worker first
|
|
42
|
+
cd tail-worker
|
|
43
|
+
wrangler deploy
|
|
44
|
+
|
|
45
|
+
# Then deploy producer Worker
|
|
46
|
+
cd ../producer-worker
|
|
47
|
+
wrangler deploy
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Wrangler Configuration
|
|
51
|
+
|
|
52
|
+
### Single Tail Consumer
|
|
53
|
+
|
|
54
|
+
```jsonc
|
|
55
|
+
{
|
|
56
|
+
"name": "producer-worker",
|
|
57
|
+
"tail_consumers": [
|
|
58
|
+
{
|
|
59
|
+
"service": "logging-tail-worker"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Multiple Tail Consumers
|
|
66
|
+
|
|
67
|
+
```jsonc
|
|
68
|
+
{
|
|
69
|
+
"name": "producer-worker",
|
|
70
|
+
"tail_consumers": [
|
|
71
|
+
{
|
|
72
|
+
"service": "logging-tail-worker"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"service": "metrics-tail-worker"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Note:** Each consumer receives ALL events independently.
|
|
82
|
+
|
|
83
|
+
### Remove Tail Consumer
|
|
84
|
+
|
|
85
|
+
```jsonc
|
|
86
|
+
{
|
|
87
|
+
"tail_consumers": []
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Then redeploy producer Worker.
|
|
92
|
+
|
|
93
|
+
## Environment Variables
|
|
94
|
+
|
|
95
|
+
Tail Workers use same binding syntax as regular Workers:
|
|
96
|
+
|
|
97
|
+
```jsonc
|
|
98
|
+
{
|
|
99
|
+
"name": "my-tail-worker",
|
|
100
|
+
"vars": {
|
|
101
|
+
"LOG_ENDPOINT": "https://logs.example.com/ingest"
|
|
102
|
+
},
|
|
103
|
+
"kv_namespaces": [
|
|
104
|
+
{
|
|
105
|
+
"binding": "LOGS_KV",
|
|
106
|
+
"id": "abc123..."
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Testing & Development
|
|
113
|
+
|
|
114
|
+
### Local Testing
|
|
115
|
+
|
|
116
|
+
**Tail Workers cannot be fully tested with `wrangler dev`.** Deploy to staging environment for testing.
|
|
117
|
+
|
|
118
|
+
### Testing Strategy
|
|
119
|
+
|
|
120
|
+
1. Deploy producer Worker to staging
|
|
121
|
+
2. Deploy Tail Worker to staging
|
|
122
|
+
3. Configure `tail_consumers` in producer
|
|
123
|
+
4. Trigger producer Worker requests
|
|
124
|
+
5. Verify Tail Worker receives events (check destination logs/storage)
|
|
125
|
+
|
|
126
|
+
### Wrangler Tail Command
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Stream logs to terminal (NOT Tail Workers)
|
|
130
|
+
wrangler tail my-producer-worker
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**This is different from Tail Workers:**
|
|
134
|
+
- `wrangler tail` streams logs to your terminal
|
|
135
|
+
- Tail Workers are Workers that process events programmatically
|
|
136
|
+
|
|
137
|
+
## Deployment Checklist
|
|
138
|
+
|
|
139
|
+
- [ ] Tail Worker has `tail()` handler
|
|
140
|
+
- [ ] Tail Worker deployed before producer
|
|
141
|
+
- [ ] Producer's `wrangler.jsonc` has correct `tail_consumers`
|
|
142
|
+
- [ ] Environment variables configured
|
|
143
|
+
- [ ] Tested with staging environment
|
|
144
|
+
- [ ] Monitoring configured for Tail Worker itself
|
|
145
|
+
|
|
146
|
+
## Limits
|
|
147
|
+
|
|
148
|
+
| Limit | Value | Notes |
|
|
149
|
+
|-------|-------|-------|
|
|
150
|
+
| Max tail consumers per producer | 10 | Each receives all events independently |
|
|
151
|
+
| Events batch size | Up to 100 events per invocation | Larger batches split across invocations |
|
|
152
|
+
| Tail Worker CPU time | Same as regular Workers | 10ms (free), 30s default / 5min max (paid) |
|
|
153
|
+
| Pricing tier | Workers Paid or Enterprise | Not available on free plan |
|
|
154
|
+
| Request body size | 100 MB max | When sending to external endpoints |
|
|
155
|
+
| Event retention | None | Events not retried if tail handler fails |
|
|
156
|
+
|
|
157
|
+
## Workers for Platforms
|
|
158
|
+
|
|
159
|
+
For dynamic dispatch Workers, both dispatch and user Worker events sent to tail consumer:
|
|
160
|
+
|
|
161
|
+
```jsonc
|
|
162
|
+
{
|
|
163
|
+
"name": "dispatch-worker",
|
|
164
|
+
"tail_consumers": [
|
|
165
|
+
{
|
|
166
|
+
"service": "platform-tail-worker"
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Tail Worker receives TWO `TraceItem` elements per request:
|
|
173
|
+
1. Dynamic dispatch Worker event
|
|
174
|
+
2. User Worker event
|
|
175
|
+
|
|
176
|
+
See [patterns.md](patterns.md) for handling.
|