memory-journal-mcp 7.7.0 → 8.0.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/README.md +126 -56
- package/dist/chunk-6OHRCNYW.js +3231 -0
- package/dist/chunk-JFMITANR.js +5168 -0
- package/dist/{chunk-QCQPAF4I.js → chunk-MWNLAEHR.js} +301 -4321
- package/dist/{chunk-ARLYSFSI.js → chunk-UHSO65A4.js} +4242 -6092
- package/dist/cli.js +21 -3
- package/dist/index.d.ts +16 -13
- package/dist/index.js +4 -2
- package/dist/resources-IJVKDFGS.js +2 -0
- package/dist/tools-44DGXE3V.js +2 -0
- package/dist/worker-script.js +201 -20
- package/package.json +7 -4
- package/skills/README.md +62 -25
- package/skills/adversarial-performance/SKILL.md +139 -0
- package/skills/adversarial-performance/references/audit-categories.md +462 -0
- package/skills/adversarial-performance/references/copilot-performance-prompts.md +44 -0
- package/skills/adversarial-performance/references/copilot-usage.md +16 -0
- package/skills/adversarial-performance/references/feedback-loop.md +177 -0
- package/skills/adversarial-performance/references/multi-pass-performance-protocol.md +398 -0
- package/skills/adversarial-planner/SKILL.md +23 -54
- package/skills/adversarial-planner/references/copilot-integration.md +25 -40
- package/skills/adversarial-planner/references/copilot-usage.md +16 -0
- package/skills/adversarial-planner/references/multi-pass-protocol.md +4 -0
- package/skills/adversarial-security/SKILL.md +149 -0
- package/skills/adversarial-security/references/adversarial-base-protocol.md +44 -0
- package/skills/adversarial-security/references/audit-categories.md +723 -0
- package/skills/adversarial-security/references/copilot-security-prompts.md +142 -0
- package/skills/adversarial-security/references/copilot-usage.md +16 -0
- package/skills/adversarial-security/references/feedback-loop.md +206 -0
- package/skills/adversarial-security/references/journal-opt-out.md +7 -0
- package/skills/adversarial-security/references/multi-pass-security-protocol.md +403 -0
- package/skills/adversarial-skill-audit/SKILL.md +118 -0
- package/skills/adversarial-skill-audit/references/audit-categories.md +308 -0
- package/skills/adversarial-skill-audit/references/copilot-skill-prompts.md +68 -0
- package/skills/adversarial-skill-audit/references/copilot-usage.md +16 -0
- package/skills/adversarial-skill-audit/references/feedback-loop.md +155 -0
- package/skills/adversarial-skill-audit/references/multi-pass-skill-protocol.md +367 -0
- package/skills/adversarial-skill-audit/scripts/check-skills.ps1 +48 -0
- package/skills/adversarial-skill-audit/scripts/run-copilot.ps1 +52 -0
- package/skills/adversarial-workflow-audit/SKILL.md +82 -0
- package/skills/adversarial-workflow-audit/references/audit-categories.md +28 -0
- package/skills/adversarial-workflow-audit/references/copilot-usage.md +16 -0
- package/skills/adversarial-workflow-audit/scripts/check-workflows.ps1 +24 -0
- package/skills/agents-sdk/SKILL.md +220 -0
- package/skills/agents-sdk/references/callable.md +92 -0
- package/skills/agents-sdk/references/codemode.md +209 -0
- package/skills/agents-sdk/references/email.md +144 -0
- package/skills/agents-sdk/references/mcp/SKILL.md +65 -0
- package/skills/agents-sdk/references/mcp/code-mode-reference.md +245 -0
- package/skills/agents-sdk/references/mcp/oauth-reference.md +359 -0
- package/skills/agents-sdk/references/mcp/references/architecture-reference.md +208 -0
- package/skills/agents-sdk/references/mcp/references/cloudflare-quickstart.md +156 -0
- package/skills/agents-sdk/references/mcp/references/error-handling.md +343 -0
- package/skills/agents-sdk/references/mcp/references/http-security.md +164 -0
- package/skills/agents-sdk/references/mcp/references/implementation-guide.md +507 -0
- package/skills/agents-sdk/references/mcp/references/testing-reference.md +171 -0
- package/skills/agents-sdk/references/mcp.md +157 -0
- package/skills/agents-sdk/references/state-scheduling.md +164 -0
- package/skills/agents-sdk/references/streaming-chat.md +168 -0
- package/skills/agents-sdk/references/workflows.md +136 -0
- package/skills/auth-identity/SKILL.md +48 -0
- package/skills/autonomous-dev/SKILL.md +46 -23
- package/skills/autonomous-dev/references/workflow_orchestration.md +22 -0
- package/skills/aws/SKILL.md +39 -0
- package/skills/azure/SKILL.md +38 -0
- package/skills/bin/sync.js +7 -1
- package/skills/biome/SKILL.md +59 -0
- package/skills/bun/SKILL.md +8 -2
- package/skills/cloudflare/SKILL.md +37 -0
- package/skills/cloudflare/references/agents-sdk/README.md +95 -0
- package/skills/cloudflare/references/agents-sdk/api.md +195 -0
- package/skills/cloudflare/references/agents-sdk/configuration.md +178 -0
- package/skills/cloudflare/references/agents-sdk/gotchas.md +173 -0
- package/skills/cloudflare/references/agents-sdk/patterns.md +215 -0
- package/skills/cloudflare/references/ai-gateway/README.md +176 -0
- package/skills/cloudflare/references/ai-gateway/configuration.md +117 -0
- package/skills/cloudflare/references/ai-gateway/dynamic-routing.md +88 -0
- package/skills/cloudflare/references/ai-gateway/features.md +96 -0
- package/skills/cloudflare/references/ai-gateway/sdk-integration.md +110 -0
- package/skills/cloudflare/references/ai-gateway/troubleshooting.md +90 -0
- package/skills/cloudflare/references/ai-search/README.md +145 -0
- package/skills/cloudflare/references/ai-search/api.md +87 -0
- package/skills/cloudflare/references/ai-search/configuration.md +91 -0
- package/skills/cloudflare/references/ai-search/gotchas.md +92 -0
- package/skills/cloudflare/references/ai-search/patterns.md +87 -0
- package/skills/cloudflare/references/analytics-engine/README.md +96 -0
- package/skills/cloudflare/references/analytics-engine/api.md +112 -0
- package/skills/cloudflare/references/analytics-engine/configuration.md +107 -0
- package/skills/cloudflare/references/analytics-engine/gotchas.md +87 -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 +205 -0
- package/skills/cloudflare/references/api/configuration.md +158 -0
- package/skills/cloudflare/references/api/gotchas.md +231 -0
- package/skills/cloudflare/references/api/patterns.md +208 -0
- package/skills/cloudflare/references/api-shield/README.md +44 -0
- package/skills/cloudflare/references/api-shield/api.md +153 -0
- package/skills/cloudflare/references/api-shield/configuration.md +210 -0
- package/skills/cloudflare/references/api-shield/gotchas.md +132 -0
- package/skills/cloudflare/references/api-shield/patterns.md +185 -0
- package/skills/cloudflare/references/argo-smart-routing/README.md +96 -0
- package/skills/cloudflare/references/argo-smart-routing/api.md +253 -0
- package/skills/cloudflare/references/argo-smart-routing/configuration.md +205 -0
- package/skills/cloudflare/references/argo-smart-routing/gotchas.md +115 -0
- package/skills/cloudflare/references/argo-smart-routing/patterns.md +107 -0
- package/skills/cloudflare/references/bindings/README.md +127 -0
- package/skills/cloudflare/references/bindings/api.md +214 -0
- package/skills/cloudflare/references/bindings/configuration.md +200 -0
- package/skills/cloudflare/references/bindings/gotchas.md +210 -0
- package/skills/cloudflare/references/bindings/patterns.md +205 -0
- package/skills/cloudflare/references/bot-management/README.md +95 -0
- package/skills/cloudflare/references/bot-management/api.md +175 -0
- package/skills/cloudflare/references/bot-management/configuration.md +175 -0
- package/skills/cloudflare/references/bot-management/gotchas.md +116 -0
- package/skills/cloudflare/references/bot-management/patterns.md +181 -0
- package/skills/cloudflare/references/browser-rendering/README.md +84 -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 +91 -0
- package/skills/cloudflare/references/browser-rendering/patterns.md +93 -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 +85 -0
- package/skills/cloudflare/references/c3/gotchas.md +97 -0
- package/skills/cloudflare/references/c3/patterns.md +84 -0
- package/skills/cloudflare/references/cache-reserve/README.md +150 -0
- package/skills/cloudflare/references/cache-reserve/api.md +184 -0
- package/skills/cloudflare/references/cache-reserve/configuration.md +170 -0
- package/skills/cloudflare/references/cache-reserve/gotchas.md +136 -0
- package/skills/cloudflare/references/cache-reserve/patterns.md +197 -0
- package/skills/cloudflare/references/containers/README.md +87 -0
- package/skills/cloudflare/references/containers/api.md +197 -0
- package/skills/cloudflare/references/containers/configuration.md +191 -0
- package/skills/cloudflare/references/containers/gotchas.md +182 -0
- package/skills/cloudflare/references/containers/patterns.md +204 -0
- package/skills/cloudflare/references/cron-triggers/README.md +101 -0
- package/skills/cloudflare/references/cron-triggers/api.md +224 -0
- package/skills/cloudflare/references/cron-triggers/configuration.md +190 -0
- package/skills/cloudflare/references/cron-triggers/gotchas.md +207 -0
- package/skills/cloudflare/references/cron-triggers/patterns.md +274 -0
- package/skills/cloudflare/references/d1/README.md +137 -0
- package/skills/cloudflare/references/d1/api.md +213 -0
- package/skills/cloudflare/references/d1/configuration.md +198 -0
- package/skills/cloudflare/references/d1/gotchas.md +98 -0
- package/skills/cloudflare/references/d1/patterns.md +240 -0
- package/skills/cloudflare/references/ddos/README.md +42 -0
- package/skills/cloudflare/references/ddos/api.md +158 -0
- package/skills/cloudflare/references/ddos/configuration.md +94 -0
- package/skills/cloudflare/references/ddos/gotchas.md +114 -0
- package/skills/cloudflare/references/ddos/patterns.md +220 -0
- package/skills/cloudflare/references/decision-trees.md +95 -0
- package/skills/cloudflare/references/do-storage/README.md +79 -0
- package/skills/cloudflare/references/do-storage/api.md +107 -0
- package/skills/cloudflare/references/do-storage/configuration.md +114 -0
- package/skills/cloudflare/references/do-storage/gotchas.md +153 -0
- package/skills/cloudflare/references/do-storage/patterns.md +210 -0
- package/skills/cloudflare/references/do-storage/testing.md +186 -0
- package/skills/cloudflare/references/durable-objects/README.md +194 -0
- package/skills/cloudflare/references/durable-objects/api.md +205 -0
- package/skills/cloudflare/references/durable-objects/configuration.md +160 -0
- package/skills/cloudflare/references/durable-objects/gotchas.md +200 -0
- package/skills/cloudflare/references/durable-objects/patterns.md +205 -0
- package/skills/cloudflare/references/email-routing/README.md +89 -0
- package/skills/cloudflare/references/email-routing/api.md +192 -0
- package/skills/cloudflare/references/email-routing/configuration.md +187 -0
- package/skills/cloudflare/references/email-routing/gotchas.md +203 -0
- package/skills/cloudflare/references/email-routing/patterns.md +241 -0
- package/skills/cloudflare/references/email-workers/README.md +153 -0
- package/skills/cloudflare/references/email-workers/api.md +227 -0
- package/skills/cloudflare/references/email-workers/configuration.md +115 -0
- package/skills/cloudflare/references/email-workers/gotchas.md +133 -0
- package/skills/cloudflare/references/email-workers/patterns.md +108 -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 +151 -0
- package/skills/cloudflare/references/graphql-api/gotchas.md +111 -0
- package/skills/cloudflare/references/graphql-api/patterns.md +276 -0
- package/skills/cloudflare/references/hyperdrive/README.md +84 -0
- package/skills/cloudflare/references/hyperdrive/api.md +149 -0
- package/skills/cloudflare/references/hyperdrive/configuration.md +166 -0
- package/skills/cloudflare/references/hyperdrive/gotchas.md +77 -0
- package/skills/cloudflare/references/hyperdrive/patterns.md +203 -0
- package/skills/cloudflare/references/images/README.md +65 -0
- package/skills/cloudflare/references/images/api.md +101 -0
- package/skills/cloudflare/references/images/configuration.md +206 -0
- package/skills/cloudflare/references/images/gotchas.md +106 -0
- package/skills/cloudflare/references/images/patterns.md +126 -0
- package/skills/cloudflare/references/kv/README.md +90 -0
- package/skills/cloudflare/references/kv/api.md +163 -0
- package/skills/cloudflare/references/kv/configuration.md +148 -0
- package/skills/cloudflare/references/kv/gotchas.md +133 -0
- package/skills/cloudflare/references/kv/patterns.md +195 -0
- package/skills/cloudflare/references/miniflare/README.md +113 -0
- package/skills/cloudflare/references/miniflare/api.md +204 -0
- package/skills/cloudflare/references/miniflare/configuration.md +174 -0
- package/skills/cloudflare/references/miniflare/gotchas.md +179 -0
- package/skills/cloudflare/references/miniflare/patterns.md +187 -0
- package/skills/cloudflare/references/network-interconnect/README.md +104 -0
- package/skills/cloudflare/references/network-interconnect/api.md +220 -0
- package/skills/cloudflare/references/network-interconnect/configuration.md +123 -0
- package/skills/cloudflare/references/network-interconnect/gotchas.md +175 -0
- package/skills/cloudflare/references/network-interconnect/patterns.md +174 -0
- package/skills/cloudflare/references/observability/README.md +93 -0
- package/skills/cloudflare/references/observability/api.md +168 -0
- package/skills/cloudflare/references/observability/configuration.md +178 -0
- package/skills/cloudflare/references/observability/gotchas.md +125 -0
- package/skills/cloudflare/references/observability/patterns.md +105 -0
- package/skills/cloudflare/references/pages/README.md +92 -0
- package/skills/cloudflare/references/pages/api.md +205 -0
- package/skills/cloudflare/references/pages/configuration.md +216 -0
- package/skills/cloudflare/references/pages/gotchas.md +218 -0
- package/skills/cloudflare/references/pages/patterns.md +215 -0
- package/skills/cloudflare/references/pages-functions/README.md +104 -0
- package/skills/cloudflare/references/pages-functions/api.md +159 -0
- package/skills/cloudflare/references/pages-functions/configuration.md +130 -0
- package/skills/cloudflare/references/pages-functions/gotchas.md +102 -0
- package/skills/cloudflare/references/pages-functions/patterns.md +148 -0
- package/skills/cloudflare/references/pipelines/README.md +109 -0
- package/skills/cloudflare/references/pipelines/api.md +214 -0
- package/skills/cloudflare/references/pipelines/configuration.md +98 -0
- package/skills/cloudflare/references/pipelines/gotchas.md +84 -0
- package/skills/cloudflare/references/pipelines/patterns.md +87 -0
- package/skills/cloudflare/references/product-index.md +112 -0
- package/skills/cloudflare/references/pulumi/README.md +113 -0
- package/skills/cloudflare/references/pulumi/api.md +230 -0
- package/skills/cloudflare/references/pulumi/configuration.md +213 -0
- package/skills/cloudflare/references/pulumi/gotchas.md +205 -0
- package/skills/cloudflare/references/pulumi/patterns.md +260 -0
- package/skills/cloudflare/references/queues/README.md +99 -0
- package/skills/cloudflare/references/queues/api.md +211 -0
- package/skills/cloudflare/references/queues/configuration.md +151 -0
- package/skills/cloudflare/references/queues/gotchas.md +210 -0
- package/skills/cloudflare/references/queues/patterns.md +220 -0
- package/skills/cloudflare/references/r2/README.md +97 -0
- package/skills/cloudflare/references/r2/api.md +235 -0
- package/skills/cloudflare/references/r2/configuration.md +176 -0
- package/skills/cloudflare/references/r2/gotchas.md +190 -0
- package/skills/cloudflare/references/r2/patterns.md +203 -0
- package/skills/cloudflare/references/r2-data-catalog/README.md +157 -0
- package/skills/cloudflare/references/r2-data-catalog/api.md +199 -0
- package/skills/cloudflare/references/r2-data-catalog/configuration.md +205 -0
- package/skills/cloudflare/references/r2-data-catalog/gotchas.md +170 -0
- package/skills/cloudflare/references/r2-data-catalog/patterns.md +191 -0
- package/skills/cloudflare/references/r2-sql/README.md +138 -0
- package/skills/cloudflare/references/r2-sql/SKILL.md.backup +512 -0
- package/skills/cloudflare/references/r2-sql/api.md +159 -0
- package/skills/cloudflare/references/r2-sql/configuration.md +152 -0
- package/skills/cloudflare/references/r2-sql/gotchas.md +228 -0
- package/skills/cloudflare/references/r2-sql/patterns.md +230 -0
- package/skills/cloudflare/references/realtime-sfu/README.md +66 -0
- package/skills/cloudflare/references/realtime-sfu/api.md +164 -0
- package/skills/cloudflare/references/realtime-sfu/configuration.md +141 -0
- package/skills/cloudflare/references/realtime-sfu/gotchas.md +138 -0
- package/skills/cloudflare/references/realtime-sfu/patterns.md +187 -0
- package/skills/cloudflare/references/realtimekit/README.md +118 -0
- package/skills/cloudflare/references/realtimekit/api.md +234 -0
- package/skills/cloudflare/references/realtimekit/configuration.md +226 -0
- package/skills/cloudflare/references/realtimekit/gotchas.md +206 -0
- package/skills/cloudflare/references/realtimekit/patterns.md +240 -0
- package/skills/cloudflare/references/sandbox/README.md +104 -0
- package/skills/cloudflare/references/sandbox/api.md +200 -0
- package/skills/cloudflare/references/sandbox/configuration.md +154 -0
- package/skills/cloudflare/references/sandbox/gotchas.md +201 -0
- package/skills/cloudflare/references/sandbox/patterns.md +195 -0
- package/skills/cloudflare/references/secrets-store/README.md +77 -0
- package/skills/cloudflare/references/secrets-store/api.md +199 -0
- package/skills/cloudflare/references/secrets-store/configuration.md +187 -0
- package/skills/cloudflare/references/secrets-store/gotchas.md +97 -0
- package/skills/cloudflare/references/secrets-store/patterns.md +218 -0
- package/skills/cloudflare/references/smart-placement/README.md +143 -0
- package/skills/cloudflare/references/smart-placement/api.md +192 -0
- package/skills/cloudflare/references/smart-placement/configuration.md +202 -0
- package/skills/cloudflare/references/smart-placement/gotchas.md +180 -0
- package/skills/cloudflare/references/smart-placement/patterns.md +190 -0
- package/skills/cloudflare/references/snippets/README.md +74 -0
- package/skills/cloudflare/references/snippets/api.md +214 -0
- package/skills/cloudflare/references/snippets/configuration.md +239 -0
- package/skills/cloudflare/references/snippets/gotchas.md +104 -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 +184 -0
- package/skills/cloudflare/references/spectrum/configuration.md +203 -0
- package/skills/cloudflare/references/spectrum/gotchas.md +155 -0
- package/skills/cloudflare/references/spectrum/patterns.md +206 -0
- package/skills/cloudflare/references/static-assets/README.md +65 -0
- package/skills/cloudflare/references/static-assets/api.md +201 -0
- package/skills/cloudflare/references/static-assets/configuration.md +186 -0
- package/skills/cloudflare/references/static-assets/gotchas.md +164 -0
- package/skills/cloudflare/references/static-assets/patterns.md +189 -0
- package/skills/cloudflare/references/stream/README.md +123 -0
- package/skills/cloudflare/references/stream/api-live.md +202 -0
- package/skills/cloudflare/references/stream/api.md +206 -0
- package/skills/cloudflare/references/stream/configuration.md +151 -0
- package/skills/cloudflare/references/stream/gotchas.md +139 -0
- package/skills/cloudflare/references/stream/patterns.md +217 -0
- package/skills/cloudflare/references/tail-workers/README.md +92 -0
- package/skills/cloudflare/references/tail-workers/api.md +203 -0
- package/skills/cloudflare/references/tail-workers/configuration.md +178 -0
- package/skills/cloudflare/references/tail-workers/gotchas.md +206 -0
- package/skills/cloudflare/references/tail-workers/patterns.md +190 -0
- package/skills/cloudflare/references/terraform/README.md +100 -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 +137 -0
- package/skills/cloudflare/references/tunnel/api.md +205 -0
- package/skills/cloudflare/references/tunnel/configuration.md +163 -0
- package/skills/cloudflare/references/tunnel/gotchas.md +159 -0
- package/skills/cloudflare/references/tunnel/networking.md +174 -0
- package/skills/cloudflare/references/tunnel/patterns.md +199 -0
- package/skills/cloudflare/references/turn/README.md +86 -0
- package/skills/cloudflare/references/turn/api.md +236 -0
- package/skills/cloudflare/references/turn/configuration.md +181 -0
- package/skills/cloudflare/references/turn/gotchas.md +236 -0
- package/skills/cloudflare/references/turn/patterns.md +228 -0
- package/skills/cloudflare/references/turnstile/README.md +102 -0
- package/skills/cloudflare/references/turnstile/api.md +253 -0
- package/skills/cloudflare/references/turnstile/configuration.md +242 -0
- package/skills/cloudflare/references/turnstile/gotchas.md +253 -0
- package/skills/cloudflare/references/turnstile/patterns.md +195 -0
- package/skills/cloudflare/references/vectorize/README.md +133 -0
- package/skills/cloudflare/references/vectorize/api.md +89 -0
- package/skills/cloudflare/references/vectorize/configuration.md +91 -0
- package/skills/cloudflare/references/vectorize/gotchas.md +83 -0
- package/skills/cloudflare/references/vectorize/patterns.md +92 -0
- package/skills/cloudflare/references/waf/README.md +125 -0
- package/skills/cloudflare/references/waf/api.md +203 -0
- package/skills/cloudflare/references/waf/configuration.md +215 -0
- package/skills/cloudflare/references/waf/gotchas.md +208 -0
- package/skills/cloudflare/references/waf/patterns.md +236 -0
- package/skills/cloudflare/references/web-analytics/README.md +149 -0
- package/skills/cloudflare/references/web-analytics/configuration.md +81 -0
- package/skills/cloudflare/references/web-analytics/gotchas.md +86 -0
- package/skills/cloudflare/references/web-analytics/integration.md +63 -0
- package/skills/cloudflare/references/web-analytics/patterns.md +98 -0
- package/skills/cloudflare/references/workerd/README.md +85 -0
- package/skills/cloudflare/references/workerd/api.md +219 -0
- package/skills/cloudflare/references/workerd/configuration.md +200 -0
- package/skills/cloudflare/references/workerd/gotchas.md +151 -0
- package/skills/cloudflare/references/workerd/patterns.md +205 -0
- package/skills/cloudflare/references/workers/README.md +110 -0
- package/skills/cloudflare/references/workers/api.md +197 -0
- package/skills/cloudflare/references/workers/configuration.md +184 -0
- package/skills/cloudflare/references/workers/frameworks.md +200 -0
- package/skills/cloudflare/references/workers/gotchas.md +145 -0
- package/skills/cloudflare/references/workers/patterns.md +220 -0
- package/skills/cloudflare/references/workers-ai/README.md +206 -0
- package/skills/cloudflare/references/workers-ai/api.md +115 -0
- package/skills/cloudflare/references/workers-ai/configuration.md +98 -0
- package/skills/cloudflare/references/workers-ai/gotchas.md +130 -0
- package/skills/cloudflare/references/workers-ai/patterns.md +122 -0
- package/skills/cloudflare/references/workers-for-platforms/README.md +95 -0
- package/skills/cloudflare/references/workers-for-platforms/api.md +212 -0
- package/skills/cloudflare/references/workers-for-platforms/configuration.md +178 -0
- package/skills/cloudflare/references/workers-for-platforms/gotchas.md +134 -0
- package/skills/cloudflare/references/workers-for-platforms/patterns.md +210 -0
- package/skills/cloudflare/references/workers-playground/README.md +131 -0
- package/skills/cloudflare/references/workers-playground/api.md +101 -0
- package/skills/cloudflare/references/workers-playground/configuration.md +169 -0
- package/skills/cloudflare/references/workers-playground/gotchas.md +88 -0
- package/skills/cloudflare/references/workers-playground/patterns.md +134 -0
- package/skills/cloudflare/references/workers-vpc/README.md +130 -0
- package/skills/cloudflare/references/workers-vpc/api.md +196 -0
- package/skills/cloudflare/references/workers-vpc/configuration.md +151 -0
- package/skills/cloudflare/references/workers-vpc/gotchas.md +171 -0
- package/skills/cloudflare/references/workers-vpc/patterns.md +235 -0
- package/skills/cloudflare/references/workflows/README.md +72 -0
- package/skills/cloudflare/references/workflows/api.md +237 -0
- package/skills/cloudflare/references/workflows/configuration.md +158 -0
- package/skills/cloudflare/references/workflows/gotchas.md +97 -0
- package/skills/cloudflare/references/workflows/patterns.md +245 -0
- package/skills/cloudflare/references/wrangler/README.md +143 -0
- package/skills/cloudflare/references/wrangler/api.md +188 -0
- package/skills/cloudflare/references/wrangler/configuration.md +198 -0
- package/skills/cloudflare/references/wrangler/gotchas.md +212 -0
- package/skills/cloudflare/references/wrangler/patterns.md +211 -0
- package/skills/cloudflare/references/zaraz/IMPLEMENTATION_SUMMARY.md +131 -0
- package/skills/cloudflare/references/zaraz/README.md +114 -0
- package/skills/cloudflare/references/zaraz/api.md +118 -0
- package/skills/cloudflare/references/zaraz/configuration.md +94 -0
- package/skills/cloudflare/references/zaraz/gotchas.md +88 -0
- package/skills/cloudflare/references/zaraz/patterns.md +77 -0
- package/skills/docker/SKILL.md +7 -101
- package/skills/docker/references/advanced-examples.md +71 -0
- package/skills/docker/references/templates.md +34 -0
- package/skills/docs-marketer/SKILL.md +178 -0
- package/skills/docs-marketer/references/audit-categories.md +328 -0
- package/skills/docs-marketer/references/copilot-docs-prompts.md +88 -0
- package/skills/docs-marketer/references/copilot-usage.md +16 -0
- package/skills/docs-marketer/references/feedback-loop.md +155 -0
- package/skills/docs-marketer/references/multi-pass-docs-protocol.md +410 -0
- package/skills/drizzle-orm/SKILL.md +82 -0
- package/skills/durable-objects/SKILL.md +167 -0
- package/skills/durable-objects/references/advanced_features.md +29 -0
- package/skills/durable-objects/references/rules.md +300 -0
- package/skills/durable-objects/references/testing.md +261 -0
- package/skills/durable-objects/references/workers.md +336 -0
- package/skills/gcp/SKILL.md +37 -0
- package/skills/github-actions/SKILL.md +5 -58
- package/skills/github-actions/references/templates.md +65 -0
- package/skills/github-commander/SKILL.md +13 -21
- package/skills/github-commander/workflows/copilot-audit.md +12 -12
- package/skills/github-copilot-cli/SKILL.md +21 -26
- package/skills/github-repo-setup/SKILL.md +136 -0
- package/skills/github-repo-setup/references/community-standards.md +136 -0
- package/skills/github-repo-setup/references/github-automation.md +490 -0
- package/skills/github-repo-setup/references/inline-templates.md +205 -0
- package/skills/github-repo-setup/references/project-config.md +320 -0
- package/skills/gitlab/SKILL.md +7 -2
- package/skills/gitlab/package-lock.json +389 -389
- package/skills/golang/SKILL.md +8 -1
- package/skills/graphql/SKILL.md +30 -0
- package/skills/hono/SKILL.md +82 -0
- package/skills/journal-optimizer/SKILL.md +206 -0
- package/skills/journal-optimizer/references/optimizer-scripts.md +169 -0
- package/skills/llm-app-engineering/SKILL.md +18 -0
- package/skills/monorepo/SKILL.md +56 -0
- package/skills/multi-agent-orchestration/SKILL.md +14 -0
- package/skills/mysql/SKILL.md +6 -2
- package/skills/next-best-practices/SKILL.md +86 -0
- package/skills/next-best-practices/references/cache-components-examples.md +234 -0
- package/skills/next-best-practices/references/cache-components.md +210 -0
- package/skills/next-best-practices/references/upgrade-decision-tree.md +33 -0
- package/skills/next-best-practices/references/upgrade.md +43 -0
- package/skills/next-cache-components/SKILL.md +441 -0
- package/skills/next-upgrade/SKILL.md +43 -0
- package/skills/next-upgrade/references/decision-tree.md +33 -0
- package/skills/nodejs/SKILL.md +46 -0
- package/skills/opentelemetry/SKILL.md +62 -0
- package/skills/package.json +39 -4
- package/skills/playwright-standard/SKILL.md +6 -11
- package/skills/playwright-standard/references/locators.md +7 -0
- package/skills/postgres/SKILL.md +6 -1
- package/skills/python/SKILL.md +8 -70
- package/skills/python/references/advanced-patterns.md +37 -0
- package/skills/python/references/config-templates.md +48 -0
- package/skills/rag-pipelines/SKILL.md +14 -0
- package/skills/redis/SKILL.md +31 -0
- package/skills/render/SKILL.md +35 -0
- package/skills/rust/SKILL.md +15 -25
- package/skills/rust/references/borrow-checker.md +13 -0
- package/skills/rust/references/ecosystem.md +11 -0
- package/skills/sandbox-sdk/SKILL.md +186 -0
- package/skills/sandbox-sdk/references/api-quick-ref.md +113 -0
- package/skills/sandbox-sdk/references/examples.md +52 -0
- package/skills/shadcn-ui/SKILL.md +22 -57
- package/skills/skill-builder/SKILL.md +23 -424
- package/skills/skill-builder/references/tutorial.md +457 -0
- package/skills/sqlite/SKILL.md +16 -5
- package/skills/table.md +59 -0
- package/skills/tailwind-css/SKILL.md +11 -60
- package/skills/tailwind-css/references/component-patterns.md +52 -0
- package/skills/trpc/SKILL.md +56 -0
- package/skills/typescript/SKILL.md +30 -433
- package/skills/typescript/references/tutorial.md +453 -0
- package/skills/vercel-ai-sdk/SKILL.md +48 -0
- package/skills/vitest-standard/SKILL.md +5 -11
- package/skills/vitest-standard/references/assertions.md +11 -0
- package/skills/web-perf/SKILL.md +207 -0
- package/skills/workers-best-practices/SKILL.md +120 -0
- package/skills/workers-best-practices/references/anti-patterns.md +18 -0
- package/skills/workers-best-practices/references/review.md +174 -0
- package/skills/workers-best-practices/references/rules.md +485 -0
- package/skills/wrangler/SKILL.md +43 -0
- package/skills/wrangler/references/cli-commands.md +861 -0
- package/skills/zod/SKILL.md +48 -0
- package/dist/tools-P4VGG4FH.js +0 -1
- package/skills/react-best-practices/AGENTS.md +0 -2883
- package/skills/react-best-practices/SKILL.md +0 -138
- /package/skills/{react-best-practices → next-best-practices}/README.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/metadata.json +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/_sections.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/_template.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/advanced-event-handler-refs.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/advanced-init-once.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/advanced-use-latest.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-api-routes.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-defer-await.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-dependencies.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-parallel.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-suspense-boundaries.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-barrel-imports.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-conditional.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-defer-third-party.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-dynamic-imports.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-preload.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-event-listeners.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-localstorage-schema.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-passive-event-listeners.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-swr-dedup.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-batch-dom-css.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-cache-function-results.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-cache-property-access.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-cache-storage.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-combine-iterations.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-early-exit.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-hoist-regexp.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-index-maps.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-length-check-first.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-min-max-loop.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-set-map-lookups.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-tosorted-immutable.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-activity.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-animate-svg-wrapper.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-conditional-render.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-content-visibility.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-hoist-jsx.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-hydration-no-flicker.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-hydration-suppress-warning.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-svg-precision.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-usetransition-loading.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-defer-reads.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-dependencies.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-derived-state-no-effect.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-derived-state.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-functional-setstate.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-lazy-state-init.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-memo-with-default-value.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-memo.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-move-effect-to-event.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-simple-expression-in-memo.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-transitions.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-use-ref-transient-values.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-after-nonblocking.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-auth-actions.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-cache-lru.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-cache-react.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-dedup-props.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-parallel-fetching.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-serialization.md +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Stream API Reference
|
|
2
|
+
|
|
3
|
+
Upload, playback, live streaming, and management APIs.
|
|
4
|
+
|
|
5
|
+
## Upload APIs
|
|
6
|
+
|
|
7
|
+
### Direct Creator Upload (Recommended)
|
|
8
|
+
|
|
9
|
+
**Backend: Create upload URL (SDK)**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import Cloudflare from 'cloudflare'
|
|
13
|
+
|
|
14
|
+
const client = new Cloudflare({ apiToken: env.CF_API_TOKEN })
|
|
15
|
+
|
|
16
|
+
const uploadData = await client.stream.directUpload.create({
|
|
17
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
18
|
+
maxDurationSeconds: 3600,
|
|
19
|
+
requireSignedURLs: true,
|
|
20
|
+
meta: { creator: 'user-123' },
|
|
21
|
+
})
|
|
22
|
+
// Returns: { uploadURL: string, uid: string }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Frontend: Upload file**
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
async function uploadVideo(file: File, uploadURL: string) {
|
|
29
|
+
const formData = new FormData()
|
|
30
|
+
formData.append('file', file)
|
|
31
|
+
return fetch(uploadURL, { method: 'POST', body: formData }).then((r) => r.json())
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Upload from URL
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const video = await client.stream.copy.create({
|
|
39
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
40
|
+
url: 'https://example.com/video.mp4',
|
|
41
|
+
meta: { name: 'My Video' },
|
|
42
|
+
requireSignedURLs: false,
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Playback APIs
|
|
47
|
+
|
|
48
|
+
### Embed Player (iframe)
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<iframe
|
|
52
|
+
src="https://customer-<CODE>.cloudflarestream.com/<VIDEO_ID>/iframe?autoplay=true&muted=true"
|
|
53
|
+
style="border: none;"
|
|
54
|
+
height="720"
|
|
55
|
+
width="1280"
|
|
56
|
+
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
|
|
57
|
+
allowfullscreen="true"
|
|
58
|
+
></iframe>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### HLS/DASH Manifest URLs
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// HLS
|
|
65
|
+
const hlsUrl = `https://customer-<CODE>.cloudflarestream.com/${videoId}/manifest/video.m3u8`
|
|
66
|
+
|
|
67
|
+
// DASH
|
|
68
|
+
const dashUrl = `https://customer-<CODE>.cloudflarestream.com/${videoId}/manifest/video.mpd`
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Thumbnails
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// At specific time (seconds)
|
|
75
|
+
const thumb = `https://customer-<CODE>.cloudflarestream.com/${videoId}/thumbnails/thumbnail.jpg?time=10s`
|
|
76
|
+
|
|
77
|
+
// By percentage
|
|
78
|
+
const thumbPct = `https://customer-<CODE>.cloudflarestream.com/${videoId}/thumbnails/thumbnail.jpg?time=50%`
|
|
79
|
+
|
|
80
|
+
// Animated GIF
|
|
81
|
+
const gif = `https://customer-<CODE>.cloudflarestream.com/${videoId}/thumbnails/thumbnail.gif`
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Signed URLs
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// Low volume (<1k/day): Use API
|
|
88
|
+
async function getSignedToken(accountId: string, videoId: string, apiToken: string) {
|
|
89
|
+
const response = await fetch(
|
|
90
|
+
`https://api.cloudflare.com/client/v4/accounts/${accountId}/stream/${videoId}/token`,
|
|
91
|
+
{
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: { Authorization: `Bearer ${apiToken}`, 'Content-Type': 'application/json' },
|
|
94
|
+
body: JSON.stringify({
|
|
95
|
+
exp: Math.floor(Date.now() / 1000) + 3600,
|
|
96
|
+
accessRules: [{ type: 'ip.geoip.country', action: 'allow', country: ['US'] }],
|
|
97
|
+
}),
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
return (await response.json()).result.token
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// High volume: Self-sign with RS256 JWT (see "Self-Sign JWT" in patterns.md)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Captions & Clips
|
|
107
|
+
|
|
108
|
+
### Upload Captions
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
async function uploadCaption(
|
|
112
|
+
accountId: string,
|
|
113
|
+
videoId: string,
|
|
114
|
+
apiToken: string,
|
|
115
|
+
language: string,
|
|
116
|
+
captionFile: File
|
|
117
|
+
) {
|
|
118
|
+
const formData = new FormData()
|
|
119
|
+
formData.append('file', captionFile)
|
|
120
|
+
return fetch(
|
|
121
|
+
`https://api.cloudflare.com/client/v4/accounts/${accountId}/stream/${videoId}/captions/${language}`,
|
|
122
|
+
{
|
|
123
|
+
method: 'PUT',
|
|
124
|
+
headers: { Authorization: `Bearer ${apiToken}` },
|
|
125
|
+
body: formData,
|
|
126
|
+
}
|
|
127
|
+
).then((r) => r.json())
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Generate AI Captions
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// TODO: Requires Workers AI integration - see workers-ai reference
|
|
135
|
+
async function generateAICaptions(accountId: string, videoId: string, apiToken: string) {
|
|
136
|
+
return fetch(
|
|
137
|
+
`https://api.cloudflare.com/client/v4/accounts/${accountId}/stream/${videoId}/captions/generate`,
|
|
138
|
+
{
|
|
139
|
+
method: 'POST',
|
|
140
|
+
headers: { Authorization: `Bearer ${apiToken}`, 'Content-Type': 'application/json' },
|
|
141
|
+
body: JSON.stringify({ language: 'en' }),
|
|
142
|
+
}
|
|
143
|
+
).then((r) => r.json())
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Clip Video
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
async function clipVideo(
|
|
151
|
+
accountId: string,
|
|
152
|
+
videoId: string,
|
|
153
|
+
apiToken: string,
|
|
154
|
+
startTime: number,
|
|
155
|
+
endTime: number
|
|
156
|
+
) {
|
|
157
|
+
return fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/stream/clip`, {
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: { Authorization: `Bearer ${apiToken}`, 'Content-Type': 'application/json' },
|
|
160
|
+
body: JSON.stringify({
|
|
161
|
+
clippedFromVideoUID: videoId,
|
|
162
|
+
startTimeSeconds: startTime,
|
|
163
|
+
endTimeSeconds: endTime,
|
|
164
|
+
}),
|
|
165
|
+
}).then((r) => r.json())
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Video Management
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// List videos
|
|
173
|
+
const videos = await client.stream.videos.list({
|
|
174
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
175
|
+
search: 'keyword', // optional
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
// Get video details
|
|
179
|
+
const video = await client.stream.videos.get(videoId, {
|
|
180
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
// Update video
|
|
184
|
+
await client.stream.videos.update(videoId, {
|
|
185
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
186
|
+
meta: { title: 'New Title' },
|
|
187
|
+
requireSignedURLs: true,
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// Delete video
|
|
191
|
+
await client.stream.videos.delete(videoId, {
|
|
192
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
193
|
+
})
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## In This Reference
|
|
197
|
+
|
|
198
|
+
- [README.md](./README.md) - Overview and quick start
|
|
199
|
+
- [configuration.md](./configuration.md) - Setup and config
|
|
200
|
+
- [api-live.md](./api-live.md) - Live streaming APIs (RTMPS/SRT/WebRTC)
|
|
201
|
+
- [patterns.md](./patterns.md) - Full-stack flows, best practices
|
|
202
|
+
- [gotchas.md](./gotchas.md) - Error codes, troubleshooting
|
|
203
|
+
|
|
204
|
+
## See Also
|
|
205
|
+
|
|
206
|
+
- [workers](../workers/) - Deploy Stream APIs in Workers
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Stream Configuration
|
|
2
|
+
|
|
3
|
+
Setup, environment variables, and wrangler configuration.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Official Cloudflare SDK (Node.js, Workers, Pages)
|
|
9
|
+
npm install cloudflare
|
|
10
|
+
|
|
11
|
+
# React component library
|
|
12
|
+
npm install @cloudflare/stream-react
|
|
13
|
+
|
|
14
|
+
# TUS resumable uploads (large files)
|
|
15
|
+
npm install tus-js-client
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Environment Variables
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Required
|
|
22
|
+
CF_ACCOUNT_ID=your-account-id
|
|
23
|
+
CF_API_TOKEN=your-api-token
|
|
24
|
+
|
|
25
|
+
# For signed URLs (high volume)
|
|
26
|
+
STREAM_KEY_ID=your-key-id
|
|
27
|
+
STREAM_JWK=base64-encoded-jwk
|
|
28
|
+
|
|
29
|
+
# For webhooks
|
|
30
|
+
WEBHOOK_SECRET=your-webhook-secret
|
|
31
|
+
|
|
32
|
+
# Customer subdomain (from dashboard)
|
|
33
|
+
STREAM_CUSTOMER_CODE=your-customer-code
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Wrangler Configuration
|
|
37
|
+
|
|
38
|
+
```jsonc
|
|
39
|
+
{
|
|
40
|
+
"name": "stream-worker",
|
|
41
|
+
"main": "src/index.ts",
|
|
42
|
+
"compatibility_date": "2025-01-01", // Use current date for new projects
|
|
43
|
+
"vars": {
|
|
44
|
+
"CF_ACCOUNT_ID": "your-account-id",
|
|
45
|
+
},
|
|
46
|
+
// Store secrets: wrangler secret put CF_API_TOKEN
|
|
47
|
+
// wrangler secret put STREAM_KEY_ID
|
|
48
|
+
// wrangler secret put STREAM_JWK
|
|
49
|
+
// wrangler secret put WEBHOOK_SECRET
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Signing Keys (High Volume)
|
|
54
|
+
|
|
55
|
+
Create once for self-signing tokens (thousands of daily users).
|
|
56
|
+
|
|
57
|
+
**Create key**
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
curl -X POST \
|
|
61
|
+
"https://api.cloudflare.com/client/v4/accounts/{account_id}/stream/keys" \
|
|
62
|
+
-H "Authorization: Bearer <API_TOKEN>"
|
|
63
|
+
|
|
64
|
+
# Save `id` and `jwk` (base64) from response
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Store in secrets**
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
wrangler secret put STREAM_KEY_ID
|
|
71
|
+
wrangler secret put STREAM_JWK
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Webhooks
|
|
75
|
+
|
|
76
|
+
**Setup webhook URL**
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
curl -X PUT \
|
|
80
|
+
"https://api.cloudflare.com/client/v4/accounts/{account_id}/stream/webhook" \
|
|
81
|
+
-H "Authorization: Bearer <API_TOKEN>" \
|
|
82
|
+
-H "Content-Type: application/json" \
|
|
83
|
+
-d '{"notificationUrl": "https://your-worker.workers.dev/webhook"}'
|
|
84
|
+
|
|
85
|
+
# Save the returned `secret` for signature verification
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Store secret**
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
wrangler secret put WEBHOOK_SECRET
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Direct Upload / Live / Watermark Config
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// Direct upload
|
|
98
|
+
const uploadConfig = {
|
|
99
|
+
maxDurationSeconds: 3600,
|
|
100
|
+
expiry: new Date(Date.now() + 3600000).toISOString(),
|
|
101
|
+
requireSignedURLs: true,
|
|
102
|
+
allowedOrigins: ['https://yourdomain.com'],
|
|
103
|
+
meta: { creator: 'user-123' },
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Live input
|
|
107
|
+
const liveConfig = {
|
|
108
|
+
recording: { mode: 'automatic', timeoutSeconds: 30 },
|
|
109
|
+
deleteRecordingAfterDays: 30,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Watermark
|
|
113
|
+
const watermark = {
|
|
114
|
+
name: 'Logo',
|
|
115
|
+
opacity: 0.7,
|
|
116
|
+
padding: 20,
|
|
117
|
+
position: 'lowerRight',
|
|
118
|
+
scale: 0.15,
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Access Rules & Player Config
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Access rules: allow US/CA, block CN/RU, or IP allowlist
|
|
126
|
+
const geoRestrict = [
|
|
127
|
+
{ type: 'ip.geoip.country', action: 'allow', country: ['US', 'CA'] },
|
|
128
|
+
{ type: 'any', action: 'block' },
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
// Player params for iframe
|
|
132
|
+
const playerParams = new URLSearchParams({
|
|
133
|
+
autoplay: 'true',
|
|
134
|
+
muted: 'true',
|
|
135
|
+
preload: 'auto',
|
|
136
|
+
defaultTextTrack: 'en',
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## In This Reference
|
|
141
|
+
|
|
142
|
+
- [README.md](./README.md) - Overview and quick start
|
|
143
|
+
- [api.md](./api.md) - On-demand video APIs
|
|
144
|
+
- [api-live.md](./api-live.md) - Live streaming APIs
|
|
145
|
+
- [patterns.md](./patterns.md) - Full-stack flows, best practices
|
|
146
|
+
- [gotchas.md](./gotchas.md) - Error codes, troubleshooting
|
|
147
|
+
|
|
148
|
+
## See Also
|
|
149
|
+
|
|
150
|
+
- [wrangler](../wrangler/) - Wrangler CLI and configuration
|
|
151
|
+
- [workers](../workers/) - Deploy Stream APIs in Workers
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Stream Gotchas
|
|
2
|
+
|
|
3
|
+
## Common Errors
|
|
4
|
+
|
|
5
|
+
### "ERR_NON_VIDEO"
|
|
6
|
+
|
|
7
|
+
**Cause:** Uploaded file is not a valid video format
|
|
8
|
+
**Solution:** Ensure file is in supported format (MP4, MKV, MOV, AVI, FLV, MPEG-2 TS/PS, MXF, LXF, GXF, 3GP, WebM, MPG, QuickTime)
|
|
9
|
+
|
|
10
|
+
### "ERR_DURATION_EXCEED_CONSTRAINT"
|
|
11
|
+
|
|
12
|
+
**Cause:** Video duration exceeds `maxDurationSeconds` constraint
|
|
13
|
+
**Solution:** Increase `maxDurationSeconds` in direct upload config or trim video before upload
|
|
14
|
+
|
|
15
|
+
### "ERR_FETCH_ORIGIN_ERROR"
|
|
16
|
+
|
|
17
|
+
**Cause:** Failed to download video from URL (upload from URL)
|
|
18
|
+
**Solution:** Ensure URL is publicly accessible, uses HTTPS, and video file is available
|
|
19
|
+
|
|
20
|
+
### "ERR_MALFORMED_VIDEO"
|
|
21
|
+
|
|
22
|
+
**Cause:** Video file is corrupted or improperly encoded
|
|
23
|
+
**Solution:** Re-encode video using FFmpeg or check source file integrity
|
|
24
|
+
|
|
25
|
+
### "ERR_DURATION_TOO_SHORT"
|
|
26
|
+
|
|
27
|
+
**Cause:** Video must be at least 0.1 seconds long
|
|
28
|
+
**Solution:** Ensure video has valid duration (not a single frame)
|
|
29
|
+
|
|
30
|
+
## Troubleshooting
|
|
31
|
+
|
|
32
|
+
### Video stuck in "inprogress" state
|
|
33
|
+
|
|
34
|
+
- **Cause**: Processing large/complex video
|
|
35
|
+
- **Solution**: Wait up to 5 minutes for processing; use webhooks instead of polling
|
|
36
|
+
|
|
37
|
+
### Signed URL returns 403
|
|
38
|
+
|
|
39
|
+
- **Cause**: Token expired or invalid signature
|
|
40
|
+
- **Solution**: Check expiration timestamp, verify JWK is correct, ensure clock sync
|
|
41
|
+
|
|
42
|
+
### Live stream not connecting
|
|
43
|
+
|
|
44
|
+
- **Cause**: Invalid RTMPS URL or stream key
|
|
45
|
+
- **Solution**: Use exact URL/key from API, ensure firewall allows outbound 443
|
|
46
|
+
|
|
47
|
+
### Webhook signature verification fails
|
|
48
|
+
|
|
49
|
+
- **Cause**: Incorrect secret or timestamp window
|
|
50
|
+
- **Solution**: Use exact secret from webhook setup, allow 5-minute timestamp drift
|
|
51
|
+
|
|
52
|
+
### Video uploads but isn't visible
|
|
53
|
+
|
|
54
|
+
- **Cause**: `requireSignedURLs` enabled without providing token
|
|
55
|
+
- **Solution**: Generate signed token or set `requireSignedURLs: false` for public videos
|
|
56
|
+
|
|
57
|
+
### Player shows infinite loading
|
|
58
|
+
|
|
59
|
+
- **Cause**: CORS issue with allowedOrigins
|
|
60
|
+
- **Solution**: Add your domain to `allowedOrigins` array
|
|
61
|
+
|
|
62
|
+
## Limits
|
|
63
|
+
|
|
64
|
+
| Resource | Limit |
|
|
65
|
+
| ------------------------------- | --------------------------------------------------- |
|
|
66
|
+
| Max file size | 30 GB |
|
|
67
|
+
| Max frame rate | 60 fps (recommended) |
|
|
68
|
+
| Max duration per direct upload | Configurable via `maxDurationSeconds` |
|
|
69
|
+
| Token generation (API endpoint) | 1,000/day recommended (use signing keys for higher) |
|
|
70
|
+
| Live input outputs (simulcast) | 5 per live input |
|
|
71
|
+
| Webhook retry attempts | 5 (exponential backoff) |
|
|
72
|
+
| Webhook timeout | 30 seconds |
|
|
73
|
+
| Caption file size | 5 MB |
|
|
74
|
+
| Watermark image size | 2 MB |
|
|
75
|
+
| Metadata keys per video | Unlimited |
|
|
76
|
+
| Search results per page | Max 1,000 |
|
|
77
|
+
|
|
78
|
+
## Performance Issues
|
|
79
|
+
|
|
80
|
+
### Upload is slow
|
|
81
|
+
|
|
82
|
+
- **Cause**: Large file size or network constraints
|
|
83
|
+
- **Solution**: Use TUS resumable upload, compress video before upload, check bandwidth
|
|
84
|
+
|
|
85
|
+
### Playback buffering
|
|
86
|
+
|
|
87
|
+
- **Cause**: Network congestion or low bandwidth
|
|
88
|
+
- **Solution**: Use ABR (adaptive bitrate) with HLS/DASH, reduce max bitrate
|
|
89
|
+
|
|
90
|
+
### High processing time
|
|
91
|
+
|
|
92
|
+
- **Cause**: Complex video codec, high resolution
|
|
93
|
+
- **Solution**: Pre-encode with H.264 (most efficient), reduce resolution
|
|
94
|
+
|
|
95
|
+
## Type Safety
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// Error response type
|
|
99
|
+
interface StreamError {
|
|
100
|
+
success: false
|
|
101
|
+
errors: Array<{
|
|
102
|
+
code: number
|
|
103
|
+
message: string
|
|
104
|
+
}>
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Handle errors
|
|
108
|
+
async function uploadWithErrorHandling(url: string, file: File) {
|
|
109
|
+
const formData = new FormData()
|
|
110
|
+
formData.append('file', file)
|
|
111
|
+
const response = await fetch(url, { method: 'POST', body: formData })
|
|
112
|
+
const result = await response.json()
|
|
113
|
+
|
|
114
|
+
if (!result.success) {
|
|
115
|
+
throw new Error(result.errors[0]?.message || 'Upload failed')
|
|
116
|
+
}
|
|
117
|
+
return result
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Security Gotchas
|
|
122
|
+
|
|
123
|
+
1. **Never expose API token in frontend** - Use direct creator uploads
|
|
124
|
+
2. **Always verify webhook signatures** - Prevent spoofed notifications
|
|
125
|
+
3. **Set appropriate token expiration** - Short-lived for security
|
|
126
|
+
4. **Use requireSignedURLs for private content** - Prevent unauthorized access
|
|
127
|
+
5. **Whitelist allowedOrigins** - Prevent hotlinking/embedding on unauthorized sites
|
|
128
|
+
|
|
129
|
+
## In This Reference
|
|
130
|
+
|
|
131
|
+
- [README.md](./README.md) - Overview and quick start
|
|
132
|
+
- [configuration.md](./configuration.md) - Setup and config
|
|
133
|
+
- [api.md](./api.md) - On-demand video APIs
|
|
134
|
+
- [api-live.md](./api-live.md) - Live streaming APIs
|
|
135
|
+
- [patterns.md](./patterns.md) - Full-stack flows, best practices
|
|
136
|
+
|
|
137
|
+
## See Also
|
|
138
|
+
|
|
139
|
+
- [workers](../workers/) - Deploy Stream APIs securely
|
|
@@ -0,0 +1,217 @@
|
|
|
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
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import Cloudflare from 'cloudflare'
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
26
|
+
const { videoName } = await request.json()
|
|
27
|
+
const client = new Cloudflare({ apiToken: env.CF_API_TOKEN })
|
|
28
|
+
const { uploadURL, uid } = await client.stream.directUpload.create({
|
|
29
|
+
account_id: env.CF_ACCOUNT_ID,
|
|
30
|
+
maxDurationSeconds: 3600,
|
|
31
|
+
requireSignedURLs: true,
|
|
32
|
+
meta: { name: videoName },
|
|
33
|
+
})
|
|
34
|
+
return Response.json({ uploadURL, uid })
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Frontend component**
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { useState } from 'react'
|
|
43
|
+
|
|
44
|
+
export function VideoUploader() {
|
|
45
|
+
const [uploading, setUploading] = useState(false)
|
|
46
|
+
const [progress, setProgress] = useState(0)
|
|
47
|
+
|
|
48
|
+
async function handleUpload(file: File) {
|
|
49
|
+
setUploading(true)
|
|
50
|
+
const { uploadURL, uid } = await fetch('/api/upload-url', {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
body: JSON.stringify({ videoName: file.name }),
|
|
53
|
+
}).then((r) => r.json())
|
|
54
|
+
|
|
55
|
+
const xhr = new XMLHttpRequest()
|
|
56
|
+
xhr.upload.onprogress = (e) => setProgress((e.loaded / e.total) * 100)
|
|
57
|
+
xhr.onload = () => {
|
|
58
|
+
setUploading(false)
|
|
59
|
+
window.location.href = `/videos/${uid}`
|
|
60
|
+
}
|
|
61
|
+
xhr.open('POST', uploadURL)
|
|
62
|
+
const formData = new FormData()
|
|
63
|
+
formData.append('file', file)
|
|
64
|
+
xhr.send(formData)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div>
|
|
69
|
+
<input
|
|
70
|
+
type="file"
|
|
71
|
+
accept="video/*"
|
|
72
|
+
onChange={(e) => e.target.files?.[0] && handleUpload(e.target.files[0])}
|
|
73
|
+
disabled={uploading}
|
|
74
|
+
/>
|
|
75
|
+
{uploading && <progress value={progress} max={100} />}
|
|
76
|
+
</div>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## TUS Resumable Upload
|
|
82
|
+
|
|
83
|
+
For large files (>500MB). `npm install tus-js-client`
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import * as tus from 'tus-js-client'
|
|
87
|
+
|
|
88
|
+
async function uploadWithTUS(file: File, uploadURL: string, onProgress?: (pct: number) => void) {
|
|
89
|
+
return new Promise<string>((resolve, reject) => {
|
|
90
|
+
const upload = new tus.Upload(file, {
|
|
91
|
+
endpoint: uploadURL,
|
|
92
|
+
retryDelays: [0, 3000, 5000, 10000, 20000],
|
|
93
|
+
chunkSize: 50 * 1024 * 1024,
|
|
94
|
+
metadata: { filename: file.name, filetype: file.type },
|
|
95
|
+
onError: reject,
|
|
96
|
+
onProgress: (up, total) => onProgress?.((up / total) * 100),
|
|
97
|
+
onSuccess: () => resolve(upload.url?.split('/').pop() || ''),
|
|
98
|
+
})
|
|
99
|
+
upload.start()
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Video State Polling
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
async function waitForVideoReady(client: Cloudflare, accountId: string, videoId: string) {
|
|
108
|
+
for (let i = 0; i < 60; i++) {
|
|
109
|
+
const video = await client.stream.videos.get(videoId, { account_id: accountId })
|
|
110
|
+
if (video.readyToStream || video.status.state === 'error') return video
|
|
111
|
+
await new Promise((resolve) => setTimeout(resolve, 5000))
|
|
112
|
+
}
|
|
113
|
+
throw new Error('Video processing timeout')
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Webhook Handler
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
export default {
|
|
121
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
122
|
+
const signature = request.headers.get('Webhook-Signature')
|
|
123
|
+
const body = await request.text()
|
|
124
|
+
if (!signature || !(await verifyWebhook(signature, body, env.WEBHOOK_SECRET))) {
|
|
125
|
+
return new Response('Unauthorized', { status: 401 })
|
|
126
|
+
}
|
|
127
|
+
const payload = JSON.parse(body)
|
|
128
|
+
if (payload.readyToStream) console.log(`Video ${payload.uid} ready`)
|
|
129
|
+
return new Response('OK')
|
|
130
|
+
},
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function verifyWebhook(sig: string, body: string, secret: string): Promise<boolean> {
|
|
134
|
+
const parts = Object.fromEntries(sig.split(',').map((p) => p.split('=')))
|
|
135
|
+
const timestamp = parseInt(parts.time || '0', 10)
|
|
136
|
+
if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false
|
|
137
|
+
|
|
138
|
+
const key = await crypto.subtle.importKey(
|
|
139
|
+
'raw',
|
|
140
|
+
new TextEncoder().encode(secret),
|
|
141
|
+
{ name: 'HMAC', hash: 'SHA-256' },
|
|
142
|
+
false,
|
|
143
|
+
['sign']
|
|
144
|
+
)
|
|
145
|
+
const computed = await crypto.subtle.sign(
|
|
146
|
+
'HMAC',
|
|
147
|
+
key,
|
|
148
|
+
new TextEncoder().encode(`${timestamp}.${body}`)
|
|
149
|
+
)
|
|
150
|
+
const hex = Array.from(new Uint8Array(computed), (b) => b.toString(16).padStart(2, '0')).join('')
|
|
151
|
+
return hex === parts.sig1
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Self-Sign JWT (High Volume Tokens)
|
|
156
|
+
|
|
157
|
+
For >1k tokens/day. Prerequisites: Create signing key (see configuration.md).
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
async function selfSignToken(keyId: string, jwkBase64: string, videoId: string, expiresIn = 3600) {
|
|
161
|
+
const key = await crypto.subtle.importKey(
|
|
162
|
+
'jwk',
|
|
163
|
+
JSON.parse(atob(jwkBase64)),
|
|
164
|
+
{ name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },
|
|
165
|
+
false,
|
|
166
|
+
['sign']
|
|
167
|
+
)
|
|
168
|
+
const now = Math.floor(Date.now() / 1000)
|
|
169
|
+
const header = btoa(JSON.stringify({ alg: 'RS256', kid: keyId }))
|
|
170
|
+
.replace(/=/g, '')
|
|
171
|
+
.replace(/\+/g, '-')
|
|
172
|
+
.replace(/\//g, '_')
|
|
173
|
+
const payload = btoa(JSON.stringify({ sub: videoId, kid: keyId, exp: now + expiresIn, nbf: now }))
|
|
174
|
+
.replace(/=/g, '')
|
|
175
|
+
.replace(/\+/g, '-')
|
|
176
|
+
.replace(/\//g, '_')
|
|
177
|
+
const message = `${header}.${payload}`
|
|
178
|
+
const sig = await crypto.subtle.sign('RSASSA-PKCS1-v1_5', key, new TextEncoder().encode(message))
|
|
179
|
+
const b64Sig = btoa(String.fromCharCode(...new Uint8Array(sig)))
|
|
180
|
+
.replace(/=/g, '')
|
|
181
|
+
.replace(/\+/g, '-')
|
|
182
|
+
.replace(/\//g, '_')
|
|
183
|
+
return `${message}.${b64Sig}`
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// With access rules (geo-restriction)
|
|
187
|
+
const payloadWithRules = {
|
|
188
|
+
sub: videoId,
|
|
189
|
+
kid: keyId,
|
|
190
|
+
exp: now + 3600,
|
|
191
|
+
nbf: now,
|
|
192
|
+
accessRules: [{ type: 'ip.geoip.country', action: 'allow', country: ['US'] }],
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Best Practices
|
|
197
|
+
|
|
198
|
+
- **Use Direct Creator Uploads** - Avoid proxying through servers
|
|
199
|
+
- **Enable requireSignedURLs** - Control private content access
|
|
200
|
+
- **Self-sign tokens at scale** - Use signing keys for >1k/day
|
|
201
|
+
- **Set allowedOrigins** - Prevent hotlinking
|
|
202
|
+
- **Use webhooks over polling** - Efficient status updates
|
|
203
|
+
- **Set maxDurationSeconds** - Prevent abuse
|
|
204
|
+
- **Enable live recordings** - Auto VOD after stream
|
|
205
|
+
|
|
206
|
+
## In This Reference
|
|
207
|
+
|
|
208
|
+
- [README.md](./README.md) - Overview and quick start
|
|
209
|
+
- [configuration.md](./configuration.md) - Setup and config
|
|
210
|
+
- [api.md](./api.md) - On-demand video APIs
|
|
211
|
+
- [api-live.md](./api-live.md) - Live streaming APIs
|
|
212
|
+
- [gotchas.md](./gotchas.md) - Error codes, troubleshooting
|
|
213
|
+
|
|
214
|
+
## See Also
|
|
215
|
+
|
|
216
|
+
- [workers](../workers/) - Deploy Stream APIs in Workers
|
|
217
|
+
- [pages](../pages/) - Integrate Stream with Pages
|