@trieungoctam/vibekit 1.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/LICENSE +21 -0
- package/README.md +85 -0
- package/agents/debugger.md +158 -0
- package/agents/docs-manager.md +220 -0
- package/agents/planner.md +129 -0
- package/agents/researcher.md +58 -0
- package/agents/reviewer.md +152 -0
- package/agents/tester.md +126 -0
- package/bin/vibekit.js +18 -0
- package/hooks/lib/ck-config-utils.cjs +831 -0
- package/hooks/lib/colors.cjs +95 -0
- package/hooks/lib/config-counter.cjs +103 -0
- package/hooks/lib/context-builder.cjs +616 -0
- package/hooks/lib/git-info-cache.cjs +143 -0
- package/hooks/lib/hook-logger.cjs +92 -0
- package/hooks/lib/privacy-checker.cjs +297 -0
- package/hooks/lib/project-detector.cjs +474 -0
- package/hooks/lib/scout-checker.cjs +263 -0
- package/hooks/lib/transcript-parser.cjs +181 -0
- package/hooks/post-edit-simplify-reminder.cjs +156 -0
- package/hooks/privacy-block.cjs +166 -0
- package/hooks/scout-block.cjs +147 -0
- package/hooks/session-init.cjs +360 -0
- package/package.json +41 -0
- package/rules/development-rules.md +52 -0
- package/rules/documentation-management.md +121 -0
- package/rules/orchestration-protocol.md +43 -0
- package/rules/primary-workflow.md +57 -0
- package/rules/team-coordination-rules.md +90 -0
- package/skills/ai/agent-browser/SKILL.md +294 -0
- package/skills/ai/agent-browser/references/.gitkeep +0 -0
- package/skills/ai/agent-browser/references/agent-browser-vs-chrome-devtools.md +112 -0
- package/skills/ai/agent-browser/references/browserbase-cloud-setup.md +161 -0
- package/skills/ai/ai-artist/SKILL.md +122 -0
- package/skills/ai/ai-artist/data/awesome-prompts.csv +3592 -0
- package/skills/ai/ai-artist/data/lighting.csv +19 -0
- package/skills/ai/ai-artist/data/nano-banana-templates.csv +17 -0
- package/skills/ai/ai-artist/data/platforms.csv +11 -0
- package/skills/ai/ai-artist/data/styles.csv +26 -0
- package/skills/ai/ai-artist/data/techniques.csv +19 -0
- package/skills/ai/ai-artist/data/use-cases.csv +16 -0
- package/skills/ai/ai-artist/references/advanced-techniques.md +184 -0
- package/skills/ai/ai-artist/references/awesome-nano-banana-pro-prompts.md +8575 -0
- package/skills/ai/ai-artist/references/domain-code.md +66 -0
- package/skills/ai/ai-artist/references/domain-data.md +72 -0
- package/skills/ai/ai-artist/references/domain-marketing.md +66 -0
- package/skills/ai/ai-artist/references/domain-patterns.md +33 -0
- package/skills/ai/ai-artist/references/domain-writing.md +68 -0
- package/skills/ai/ai-artist/references/image-prompting.md +141 -0
- package/skills/ai/ai-artist/references/llm-prompting.md +165 -0
- package/skills/ai/ai-artist/references/nano-banana.md +136 -0
- package/skills/ai/ai-artist/references/reasoning-techniques.md +201 -0
- package/skills/ai/ai-artist/references/validation-workflow.md +117 -0
- package/skills/ai/ai-artist/scripts/core.py +197 -0
- package/skills/ai/ai-artist/scripts/extract_prompts.py +102 -0
- package/skills/ai/ai-artist/scripts/generate.py +370 -0
- package/skills/ai/ai-artist/scripts/search.py +147 -0
- package/skills/ai/ai-multimodal/.env.example +204 -0
- package/skills/ai/ai-multimodal/SKILL.md +110 -0
- package/skills/ai/ai-multimodal/references/audio-processing.md +387 -0
- package/skills/ai/ai-multimodal/references/image-generation.md +939 -0
- package/skills/ai/ai-multimodal/references/music-generation.md +311 -0
- package/skills/ai/ai-multimodal/references/video-analysis.md +515 -0
- package/skills/ai/ai-multimodal/references/video-generation.md +457 -0
- package/skills/ai/ai-multimodal/references/vision-understanding.md +492 -0
- package/skills/ai/ai-multimodal/scripts/.coverage +0 -0
- package/skills/ai/ai-multimodal/scripts/check_setup.py +315 -0
- package/skills/ai/ai-multimodal/scripts/document_converter.py +395 -0
- package/skills/ai/ai-multimodal/scripts/gemini_batch_process.py +1185 -0
- package/skills/ai/ai-multimodal/scripts/media_optimizer.py +506 -0
- package/skills/ai/ai-multimodal/scripts/requirements.txt +26 -0
- package/skills/ai/ai-multimodal/scripts/tests/.coverage +0 -0
- package/skills/ai/ai-multimodal/scripts/tests/requirements.txt +20 -0
- package/skills/ai/ai-multimodal/scripts/tests/test_document_converter.py +74 -0
- package/skills/ai/ai-multimodal/scripts/tests/test_gemini_batch_process.py +362 -0
- package/skills/ai/ai-multimodal/scripts/tests/test_media_optimizer.py +373 -0
- package/skills/ai/mcp-management/README.md +219 -0
- package/skills/ai/mcp-management/SKILL.md +210 -0
- package/skills/ai/mcp-management/assets/tools.json +3146 -0
- package/skills/ai/mcp-management/references/configuration.md +114 -0
- package/skills/ai/mcp-management/references/gemini-cli-integration.md +221 -0
- package/skills/ai/mcp-management/references/mcp-protocol.md +116 -0
- package/skills/ai/mcp-management/scripts/.env.example +10 -0
- package/skills/ai/mcp-management/scripts/cli.ts +195 -0
- package/skills/ai/mcp-management/scripts/dist/analyze-tools.js +70 -0
- package/skills/ai/mcp-management/scripts/dist/cli.js +160 -0
- package/skills/ai/mcp-management/scripts/dist/mcp-client.js +183 -0
- package/skills/ai/mcp-management/scripts/mcp-client.ts +230 -0
- package/skills/ai/mcp-management/scripts/package.json +20 -0
- package/skills/ai/mcp-management/scripts/tsconfig.json +15 -0
- package/skills/core/brainstorm/SKILL.md +164 -0
- package/skills/core/brainstorm/scripts/frame-template.html +214 -0
- package/skills/core/brainstorm/scripts/helper.js +88 -0
- package/skills/core/brainstorm/scripts/server.cjs +338 -0
- package/skills/core/brainstorm/scripts/start-server.sh +153 -0
- package/skills/core/brainstorm/scripts/stop-server.sh +55 -0
- package/skills/core/brainstorm/spec-document-reviewer-prompt.md +49 -0
- package/skills/core/brainstorm/visual-companion.md +286 -0
- package/skills/core/code-review/SKILL.md +147 -0
- package/skills/core/code-review/references/code-review-reception.md +113 -0
- package/skills/core/code-review/references/codebase-scan-workflow.md +29 -0
- package/skills/core/code-review/references/edge-case-scouting.md +119 -0
- package/skills/core/code-review/references/parallel-review-workflow.md +69 -0
- package/skills/core/code-review/references/requesting-code-review.md +116 -0
- package/skills/core/code-review/references/task-management-reviews.md +140 -0
- package/skills/core/code-review/references/verification-before-completion.md +139 -0
- package/skills/core/cook/README.md +86 -0
- package/skills/core/cook/SKILL.md +113 -0
- package/skills/core/cook/references/intent-detection.md +101 -0
- package/skills/core/cook/references/review-cycle.md +75 -0
- package/skills/core/cook/references/subagent-patterns.md +75 -0
- package/skills/core/cook/references/workflow-steps.md +172 -0
- package/skills/core/debug/SKILL.md +121 -0
- package/skills/core/debug/references/defense-in-depth.md +124 -0
- package/skills/core/debug/references/frontend-verification.md +103 -0
- package/skills/core/debug/references/investigation-methodology.md +101 -0
- package/skills/core/debug/references/log-and-ci-analysis.md +97 -0
- package/skills/core/debug/references/performance-diagnostics.md +113 -0
- package/skills/core/debug/references/reporting-standards.md +122 -0
- package/skills/core/debug/references/root-cause-tracing.md +122 -0
- package/skills/core/debug/references/systematic-debugging.md +102 -0
- package/skills/core/debug/references/task-management-debugging.md +155 -0
- package/skills/core/debug/references/verification.md +123 -0
- package/skills/core/debug/scripts/find-polluter.sh +63 -0
- package/skills/core/debug/scripts/find-polluter.test.md +102 -0
- package/skills/core/execute/SKILL.md +70 -0
- package/skills/core/fix/SKILL.md +111 -0
- package/skills/core/fix/references/complexity-assessment.md +72 -0
- package/skills/core/fix/references/mode-selection.md +46 -0
- package/skills/core/fix/references/parallel-exploration.md +100 -0
- package/skills/core/fix/references/review-cycle.md +77 -0
- package/skills/core/fix/references/skill-activation-matrix.md +78 -0
- package/skills/core/fix/references/task-orchestration.md +103 -0
- package/skills/core/fix/references/workflow-ci.md +28 -0
- package/skills/core/fix/references/workflow-deep.md +122 -0
- package/skills/core/fix/references/workflow-logs.md +72 -0
- package/skills/core/fix/references/workflow-quick.md +59 -0
- package/skills/core/fix/references/workflow-standard.md +111 -0
- package/skills/core/fix/references/workflow-test.md +75 -0
- package/skills/core/fix/references/workflow-types.md +33 -0
- package/skills/core/fix/references/workflow-ui.md +75 -0
- package/skills/core/plan/SKILL.md +145 -0
- package/skills/core/plan/plan-document-reviewer-prompt.md +49 -0
- package/skills/core/subagent-dev/SKILL.md +277 -0
- package/skills/core/subagent-dev/code-quality-reviewer-prompt.md +26 -0
- package/skills/core/subagent-dev/implementer-prompt.md +113 -0
- package/skills/core/subagent-dev/spec-reviewer-prompt.md +61 -0
- package/skills/core/tdd/SKILL.md +371 -0
- package/skills/core/tdd/testing-anti-patterns.md +299 -0
- package/skills/core/test/SKILL.md +109 -0
- package/skills/core/test/references/report-format.md +58 -0
- package/skills/core/test/references/test-execution-workflow.md +103 -0
- package/skills/core/test/references/ui-testing-workflow.md +65 -0
- package/skills/core/verify/SKILL.md +139 -0
- package/skills/dev/backend-dev/SKILL.md +96 -0
- package/skills/dev/backend-dev/references/backend-api-design.md +495 -0
- package/skills/dev/backend-dev/references/backend-architecture.md +454 -0
- package/skills/dev/backend-dev/references/backend-authentication.md +338 -0
- package/skills/dev/backend-dev/references/backend-code-quality.md +659 -0
- package/skills/dev/backend-dev/references/backend-debugging.md +904 -0
- package/skills/dev/backend-dev/references/backend-devops.md +494 -0
- package/skills/dev/backend-dev/references/backend-mindset.md +387 -0
- package/skills/dev/backend-dev/references/backend-performance.md +397 -0
- package/skills/dev/backend-dev/references/backend-security.md +290 -0
- package/skills/dev/backend-dev/references/backend-technologies.md +256 -0
- package/skills/dev/backend-dev/references/backend-testing.md +429 -0
- package/skills/dev/context-engineering/SKILL.md +108 -0
- package/skills/dev/context-engineering/references/context-compression.md +84 -0
- package/skills/dev/context-engineering/references/context-degradation.md +93 -0
- package/skills/dev/context-engineering/references/context-fundamentals.md +75 -0
- package/skills/dev/context-engineering/references/context-optimization.md +82 -0
- package/skills/dev/context-engineering/references/evaluation.md +89 -0
- package/skills/dev/context-engineering/references/memory-systems.md +88 -0
- package/skills/dev/context-engineering/references/multi-agent-patterns.md +90 -0
- package/skills/dev/context-engineering/references/project-development.md +97 -0
- package/skills/dev/context-engineering/references/runtime-awareness.md +202 -0
- package/skills/dev/context-engineering/references/tool-design.md +86 -0
- package/skills/dev/context-engineering/scripts/compression_evaluator.py +349 -0
- package/skills/dev/context-engineering/scripts/context_analyzer.py +317 -0
- package/skills/dev/context-engineering/scripts/tests/test_edge_cases.py +246 -0
- package/skills/dev/databases/SKILL.md +84 -0
- package/skills/dev/databases/analytics.md +198 -0
- package/skills/dev/databases/db-design.md +188 -0
- package/skills/dev/databases/incremental-etl.md +213 -0
- package/skills/dev/databases/references/mongodb-aggregation.md +447 -0
- package/skills/dev/databases/references/mongodb-atlas.md +465 -0
- package/skills/dev/databases/references/mongodb-crud.md +408 -0
- package/skills/dev/databases/references/mongodb-indexing.md +442 -0
- package/skills/dev/databases/references/postgresql-administration.md +594 -0
- package/skills/dev/databases/references/postgresql-performance.md +527 -0
- package/skills/dev/databases/references/postgresql-psql-cli.md +467 -0
- package/skills/dev/databases/references/postgresql-queries.md +475 -0
- package/skills/dev/databases/scripts/.coverage +0 -0
- package/skills/dev/databases/scripts/db_backup.py +502 -0
- package/skills/dev/databases/scripts/db_migrate.py +426 -0
- package/skills/dev/databases/scripts/db_performance_check.py +457 -0
- package/skills/dev/databases/scripts/requirements.txt +20 -0
- package/skills/dev/databases/scripts/tests/coverage-db.json +1 -0
- package/skills/dev/databases/scripts/tests/requirements.txt +4 -0
- package/skills/dev/databases/scripts/tests/test_db_backup.py +340 -0
- package/skills/dev/databases/scripts/tests/test_db_migrate.py +277 -0
- package/skills/dev/databases/scripts/tests/test_db_performance_check.py +370 -0
- package/skills/dev/databases/stacks/bigquery.md +231 -0
- package/skills/dev/databases/stacks/d1_cloudflare.md +137 -0
- package/skills/dev/databases/stacks/mysql.md +216 -0
- package/skills/dev/databases/stacks/postgres.md +235 -0
- package/skills/dev/databases/stacks/sqlite.md +244 -0
- package/skills/dev/databases/transactional.md +176 -0
- package/skills/dev/devops/.env.example +76 -0
- package/skills/dev/devops/SKILL.md +97 -0
- package/skills/dev/devops/references/browser-rendering.md +305 -0
- package/skills/dev/devops/references/cloudflare-d1-kv.md +123 -0
- package/skills/dev/devops/references/cloudflare-platform.md +271 -0
- package/skills/dev/devops/references/cloudflare-r2-storage.md +280 -0
- package/skills/dev/devops/references/cloudflare-workers-advanced.md +312 -0
- package/skills/dev/devops/references/cloudflare-workers-apis.md +309 -0
- package/skills/dev/devops/references/cloudflare-workers-basics.md +418 -0
- package/skills/dev/devops/references/docker-basics.md +297 -0
- package/skills/dev/devops/references/docker-compose.md +292 -0
- package/skills/dev/devops/references/gcloud-platform.md +297 -0
- package/skills/dev/devops/references/gcloud-services.md +304 -0
- package/skills/dev/devops/references/kubernetes-basics.md +99 -0
- package/skills/dev/devops/references/kubernetes-helm-advanced.md +75 -0
- package/skills/dev/devops/references/kubernetes-helm.md +81 -0
- package/skills/dev/devops/references/kubernetes-kubectl.md +74 -0
- package/skills/dev/devops/references/kubernetes-security-advanced.md +98 -0
- package/skills/dev/devops/references/kubernetes-security.md +95 -0
- package/skills/dev/devops/references/kubernetes-troubleshooting-advanced.md +74 -0
- package/skills/dev/devops/references/kubernetes-troubleshooting.md +49 -0
- package/skills/dev/devops/references/kubernetes-workflows-advanced.md +75 -0
- package/skills/dev/devops/references/kubernetes-workflows.md +78 -0
- package/skills/dev/devops/scripts/cloudflare_deploy.py +269 -0
- package/skills/dev/devops/scripts/docker_optimize.py +332 -0
- package/skills/dev/devops/scripts/requirements.txt +20 -0
- package/skills/dev/devops/scripts/tests/requirements.txt +3 -0
- package/skills/dev/devops/scripts/tests/test_cloudflare_deploy.py +285 -0
- package/skills/dev/devops/scripts/tests/test_docker_optimize.py +436 -0
- package/skills/dev/frontend-design/SKILL.md +78 -0
- package/skills/dev/frontend-design/references/ai-multimodal-overview.md +165 -0
- package/skills/dev/frontend-design/references/analysis-best-practices.md +80 -0
- package/skills/dev/frontend-design/references/analysis-prompts.md +141 -0
- package/skills/dev/frontend-design/references/analysis-techniques.md +118 -0
- package/skills/dev/frontend-design/references/animejs.md +396 -0
- package/skills/dev/frontend-design/references/asset-generation.md +337 -0
- package/skills/dev/frontend-design/references/design-extraction-overview.md +71 -0
- package/skills/dev/frontend-design/references/extraction-best-practices.md +141 -0
- package/skills/dev/frontend-design/references/extraction-output-templates.md +162 -0
- package/skills/dev/frontend-design/references/extraction-prompts.md +127 -0
- package/skills/dev/frontend-design/references/technical-accessibility.md +119 -0
- package/skills/dev/frontend-design/references/technical-best-practices.md +97 -0
- package/skills/dev/frontend-design/references/technical-optimization.md +44 -0
- package/skills/dev/frontend-design/references/technical-overview.md +90 -0
- package/skills/dev/frontend-design/references/technical-workflows.md +150 -0
- package/skills/dev/frontend-design/references/visual-analysis-overview.md +95 -0
- package/skills/dev/frontend-design/references/workflow-3d.md +102 -0
- package/skills/dev/frontend-design/references/workflow-describe.md +87 -0
- package/skills/dev/frontend-design/references/workflow-immersive.md +87 -0
- package/skills/dev/frontend-design/references/workflow-quick.md +57 -0
- package/skills/dev/frontend-design/references/workflow-screenshot.md +63 -0
- package/skills/dev/frontend-design/references/workflow-video.md +74 -0
- package/skills/dev/frontend-dev/SKILL.md +400 -0
- package/skills/dev/frontend-dev/resources/common-patterns.md +331 -0
- package/skills/dev/frontend-dev/resources/complete-examples.md +872 -0
- package/skills/dev/frontend-dev/resources/component-patterns.md +502 -0
- package/skills/dev/frontend-dev/resources/data-fetching.md +767 -0
- package/skills/dev/frontend-dev/resources/file-organization.md +502 -0
- package/skills/dev/frontend-dev/resources/loading-and-error-states.md +501 -0
- package/skills/dev/frontend-dev/resources/performance.md +406 -0
- package/skills/dev/frontend-dev/resources/routing-guide.md +364 -0
- package/skills/dev/frontend-dev/resources/styling-guide.md +428 -0
- package/skills/dev/frontend-dev/resources/typescript-standards.md +418 -0
- package/skills/dev/git/SKILL.md +114 -0
- package/skills/dev/git/references/branch-management.md +88 -0
- package/skills/dev/git/references/commit-standards.md +46 -0
- package/skills/dev/git/references/gh-cli-guide.md +109 -0
- package/skills/dev/git/references/safety-protocols.md +69 -0
- package/skills/dev/git/references/workflow-commit.md +58 -0
- package/skills/dev/git/references/workflow-merge.md +48 -0
- package/skills/dev/git/references/workflow-pr.md +58 -0
- package/skills/dev/git/references/workflow-push.md +52 -0
- package/skills/dev/git-worktree/SKILL.md +218 -0
- package/skills/utils/ask/SKILL.md +58 -0
- package/skills/utils/bootstrap/SKILL.md +101 -0
- package/skills/utils/bootstrap/references/shared-phases.md +59 -0
- package/skills/utils/bootstrap/references/workflow-auto.md +52 -0
- package/skills/utils/bootstrap/references/workflow-fast.md +50 -0
- package/skills/utils/bootstrap/references/workflow-full.md +60 -0
- package/skills/utils/bootstrap/references/workflow-parallel.md +59 -0
- package/skills/utils/ck-help/SKILL.md +102 -0
- package/skills/utils/ck-help/scripts/ck-help.py +1321 -0
- package/skills/utils/ck-help/scripts/commands_data.yaml +3 -0
- package/skills/utils/ck-help/scripts/skills_data.yaml +593 -0
- package/skills/utils/copywriting/SKILL.md +94 -0
- package/skills/utils/copywriting/references/copy-formulas.md +150 -0
- package/skills/utils/copywriting/references/cta-patterns.md +168 -0
- package/skills/utils/copywriting/references/email-copy.md +193 -0
- package/skills/utils/copywriting/references/headline-templates.md +140 -0
- package/skills/utils/copywriting/references/landing-page-copy.md +175 -0
- package/skills/utils/copywriting/references/power-words.md +189 -0
- package/skills/utils/copywriting/references/social-media-copy.md +222 -0
- package/skills/utils/copywriting/references/workflow-cro.md +83 -0
- package/skills/utils/copywriting/references/workflow-enhance.md +32 -0
- package/skills/utils/copywriting/references/workflow-fast.md +29 -0
- package/skills/utils/copywriting/references/workflow-good.md +39 -0
- package/skills/utils/copywriting/references/writing-styles.md +247 -0
- package/skills/utils/copywriting/scripts/extract-writing-styles.py +308 -0
- package/skills/utils/copywriting/templates/copy-brief.md +49 -0
- package/skills/utils/docs/SKILL.md +55 -0
- package/skills/utils/docs/references/init-workflow.md +32 -0
- package/skills/utils/docs/references/summarize-workflow.md +18 -0
- package/skills/utils/docs/references/update-workflow.md +59 -0
- package/skills/utils/journal/SKILL.md +11 -0
- package/skills/utils/kanban/SKILL.md +99 -0
- package/skills/utils/preview/SKILL.md +75 -0
- package/skills/utils/preview/references/generation-modes.md +95 -0
- package/skills/utils/preview/references/view-mode.md +42 -0
- package/skills/utils/repomix/SKILL.md +248 -0
- package/skills/utils/repomix/references/configuration.md +211 -0
- package/skills/utils/repomix/references/usage-patterns.md +232 -0
- package/skills/utils/repomix/scripts/.coverage +0 -0
- package/skills/utils/repomix/scripts/README.md +179 -0
- package/skills/utils/repomix/scripts/repomix_batch.py +455 -0
- package/skills/utils/repomix/scripts/repos.example.json +15 -0
- package/skills/utils/repomix/scripts/requirements.txt +15 -0
- package/skills/utils/repomix/scripts/tests/test_repomix_batch.py +531 -0
- package/skills/utils/research/SKILL.md +171 -0
- package/skills/utils/scout/SKILL.md +89 -0
- package/skills/utils/scout/references/external-scouting.md +140 -0
- package/skills/utils/scout/references/internal-scouting.md +119 -0
- package/skills/utils/scout/references/task-management-scouting.md +125 -0
- package/skills/utils/sequential-thinking/.env.example +8 -0
- package/skills/utils/sequential-thinking/README.md +183 -0
- package/skills/utils/sequential-thinking/SKILL.md +95 -0
- package/skills/utils/sequential-thinking/package.json +31 -0
- package/skills/utils/sequential-thinking/references/advanced-strategies.md +79 -0
- package/skills/utils/sequential-thinking/references/advanced-techniques.md +76 -0
- package/skills/utils/sequential-thinking/references/core-patterns.md +95 -0
- package/skills/utils/sequential-thinking/references/examples-api.md +88 -0
- package/skills/utils/sequential-thinking/references/examples-architecture.md +94 -0
- package/skills/utils/sequential-thinking/references/examples-debug.md +90 -0
- package/skills/utils/sequential-thinking/scripts/format-thought.js +159 -0
- package/skills/utils/sequential-thinking/scripts/process-thought.js +236 -0
- package/skills/utils/sequential-thinking/tests/format-thought.test.js +133 -0
- package/skills/utils/sequential-thinking/tests/process-thought.test.js +215 -0
- package/skills/utils/write-skill/SKILL.md +655 -0
- package/skills/utils/write-skill/anthropic-best-practices.md +1150 -0
- package/skills/utils/write-skill/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/utils/write-skill/graphviz-conventions.dot +172 -0
- package/skills/utils/write-skill/persuasion-principles.md +187 -0
- package/skills/utils/write-skill/render-graphs.js +168 -0
- package/skills/utils/write-skill/testing-skills-with-subagents.md +384 -0
- package/src/commands/init.js +238 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Cloudflare Workers Runtime APIs
|
|
2
|
+
|
|
3
|
+
Key runtime APIs for Workers development.
|
|
4
|
+
|
|
5
|
+
## Fetch API
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// Subrequest
|
|
9
|
+
const response = await fetch('https://api.example.com/data', {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: { 'Content-Type': 'application/json' },
|
|
12
|
+
body: JSON.stringify({ key: 'value' }),
|
|
13
|
+
cf: {
|
|
14
|
+
cacheTtl: 3600,
|
|
15
|
+
cacheEverything: true
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const data = await response.json();
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Headers API
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// Read headers
|
|
26
|
+
const userAgent = request.headers.get('User-Agent');
|
|
27
|
+
|
|
28
|
+
// Cloudflare-specific
|
|
29
|
+
const country = request.cf?.country;
|
|
30
|
+
const colo = request.cf?.colo;
|
|
31
|
+
const clientIP = request.headers.get('CF-Connecting-IP');
|
|
32
|
+
|
|
33
|
+
// Set headers
|
|
34
|
+
const headers = new Headers();
|
|
35
|
+
headers.set('Content-Type', 'application/json');
|
|
36
|
+
headers.append('X-Custom-Header', 'value');
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## HTMLRewriter
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
export default {
|
|
43
|
+
async fetch(request: Request): Promise<Response> {
|
|
44
|
+
const response = await fetch(request);
|
|
45
|
+
|
|
46
|
+
return new HTMLRewriter()
|
|
47
|
+
.on('title', {
|
|
48
|
+
element(element) {
|
|
49
|
+
element.setInnerContent('New Title');
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
.on('a[href]', {
|
|
53
|
+
element(element) {
|
|
54
|
+
const href = element.getAttribute('href');
|
|
55
|
+
element.setAttribute('href', href.replace('http://', 'https://'));
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.transform(response);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## WebSockets
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
export default {
|
|
67
|
+
async fetch(request: Request): Promise<Response> {
|
|
68
|
+
const upgradeHeader = request.headers.get('Upgrade');
|
|
69
|
+
if (upgradeHeader !== 'websocket') {
|
|
70
|
+
return new Response('Expected WebSocket', { status: 426 });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const pair = new WebSocketPair();
|
|
74
|
+
const [client, server] = Object.values(pair);
|
|
75
|
+
|
|
76
|
+
server.accept();
|
|
77
|
+
|
|
78
|
+
server.addEventListener('message', (event) => {
|
|
79
|
+
server.send(`Echo: ${event.data}`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return new Response(null, {
|
|
83
|
+
status: 101,
|
|
84
|
+
webSocket: client
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Streams API
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const { readable, writable } = new TransformStream();
|
|
94
|
+
|
|
95
|
+
const writer = writable.getWriter();
|
|
96
|
+
writer.write(new TextEncoder().encode('chunk 1'));
|
|
97
|
+
writer.write(new TextEncoder().encode('chunk 2'));
|
|
98
|
+
writer.close();
|
|
99
|
+
|
|
100
|
+
return new Response(readable, {
|
|
101
|
+
headers: { 'Content-Type': 'text/plain' }
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Web Crypto API
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// Generate hash
|
|
109
|
+
const data = new TextEncoder().encode('message');
|
|
110
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
111
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
112
|
+
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
113
|
+
|
|
114
|
+
// HMAC signature
|
|
115
|
+
const key = await crypto.subtle.importKey(
|
|
116
|
+
'raw',
|
|
117
|
+
new TextEncoder().encode('secret'),
|
|
118
|
+
{ name: 'HMAC', hash: 'SHA-256' },
|
|
119
|
+
false,
|
|
120
|
+
['sign', 'verify']
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const signature = await crypto.subtle.sign('HMAC', key, data);
|
|
124
|
+
const valid = await crypto.subtle.verify('HMAC', key, signature, data);
|
|
125
|
+
|
|
126
|
+
// Random values
|
|
127
|
+
const randomBytes = crypto.getRandomValues(new Uint8Array(32));
|
|
128
|
+
const uuid = crypto.randomUUID();
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Encoding APIs
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// TextEncoder
|
|
135
|
+
const encoder = new TextEncoder();
|
|
136
|
+
const bytes = encoder.encode('Hello');
|
|
137
|
+
|
|
138
|
+
// TextDecoder
|
|
139
|
+
const decoder = new TextDecoder();
|
|
140
|
+
const text = decoder.decode(bytes);
|
|
141
|
+
|
|
142
|
+
// Base64
|
|
143
|
+
const base64 = btoa('Hello');
|
|
144
|
+
const decoded = atob(base64);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## URL API
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
const url = new URL(request.url);
|
|
151
|
+
const hostname = url.hostname;
|
|
152
|
+
const pathname = url.pathname;
|
|
153
|
+
const search = url.search;
|
|
154
|
+
|
|
155
|
+
// Query parameters
|
|
156
|
+
const name = url.searchParams.get('name');
|
|
157
|
+
url.searchParams.set('page', '2');
|
|
158
|
+
url.searchParams.delete('old');
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## FormData API
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// Parse form data
|
|
165
|
+
const formData = await request.formData();
|
|
166
|
+
const name = formData.get('name');
|
|
167
|
+
const file = formData.get('file');
|
|
168
|
+
|
|
169
|
+
// Create form data
|
|
170
|
+
const form = new FormData();
|
|
171
|
+
form.append('name', 'value');
|
|
172
|
+
form.append('file', blob, 'filename.txt');
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Response Types
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// Text
|
|
179
|
+
return new Response('Hello');
|
|
180
|
+
|
|
181
|
+
// JSON
|
|
182
|
+
return Response.json({ message: 'Hello' });
|
|
183
|
+
|
|
184
|
+
// Stream
|
|
185
|
+
return new Response(readable);
|
|
186
|
+
|
|
187
|
+
// Redirect
|
|
188
|
+
return Response.redirect('https://example.com', 302);
|
|
189
|
+
|
|
190
|
+
// Error
|
|
191
|
+
return new Response('Not Found', { status: 404 });
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Request Cloning
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
// Clone for multiple reads
|
|
198
|
+
const clone = request.clone();
|
|
199
|
+
const body1 = await request.json();
|
|
200
|
+
const body2 = await clone.json();
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## AbortController
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const controller = new AbortController();
|
|
207
|
+
const { signal } = controller;
|
|
208
|
+
|
|
209
|
+
setTimeout(() => controller.abort(), 5000);
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
const response = await fetch('https://slow-api.com', { signal });
|
|
213
|
+
} catch (error) {
|
|
214
|
+
if (error.name === 'AbortError') {
|
|
215
|
+
console.log('Request timed out');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Scheduling APIs
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// setTimeout
|
|
224
|
+
const timeoutId = setTimeout(() => {
|
|
225
|
+
console.log('Delayed');
|
|
226
|
+
}, 1000);
|
|
227
|
+
|
|
228
|
+
// setInterval
|
|
229
|
+
const intervalId = setInterval(() => {
|
|
230
|
+
console.log('Repeated');
|
|
231
|
+
}, 1000);
|
|
232
|
+
|
|
233
|
+
// Clear
|
|
234
|
+
clearTimeout(timeoutId);
|
|
235
|
+
clearInterval(intervalId);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Console API
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
console.log('Info message');
|
|
242
|
+
console.error('Error message');
|
|
243
|
+
console.warn('Warning message');
|
|
244
|
+
console.debug('Debug message');
|
|
245
|
+
|
|
246
|
+
// Structured logging
|
|
247
|
+
console.log(JSON.stringify({
|
|
248
|
+
level: 'info',
|
|
249
|
+
message: 'Request processed',
|
|
250
|
+
url: request.url,
|
|
251
|
+
timestamp: new Date().toISOString()
|
|
252
|
+
}));
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Performance API
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
const start = performance.now();
|
|
259
|
+
await processRequest();
|
|
260
|
+
const duration = performance.now() - start;
|
|
261
|
+
console.log(`Processed in ${duration}ms`);
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Bindings Reference
|
|
265
|
+
|
|
266
|
+
### KV Operations
|
|
267
|
+
```typescript
|
|
268
|
+
await env.KV.put(key, value, { expirationTtl: 3600, metadata: { userId: '123' } });
|
|
269
|
+
const value = await env.KV.get(key, 'json');
|
|
270
|
+
const { value, metadata } = await env.KV.getWithMetadata(key);
|
|
271
|
+
await env.KV.delete(key);
|
|
272
|
+
const list = await env.KV.list({ prefix: 'user:' });
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### D1 Operations
|
|
276
|
+
```typescript
|
|
277
|
+
const result = await env.DB.prepare('SELECT * FROM users WHERE id = ?').bind(userId).first();
|
|
278
|
+
const { results } = await env.DB.prepare('SELECT * FROM users').all();
|
|
279
|
+
await env.DB.prepare('INSERT INTO users (name) VALUES (?)').bind(name).run();
|
|
280
|
+
await env.DB.batch([stmt1, stmt2, stmt3]);
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### R2 Operations
|
|
284
|
+
```typescript
|
|
285
|
+
await env.R2.put(key, value, { httpMetadata: { contentType: 'image/jpeg' } });
|
|
286
|
+
const object = await env.R2.get(key);
|
|
287
|
+
await env.R2.delete(key);
|
|
288
|
+
const list = await env.R2.list({ prefix: 'uploads/' });
|
|
289
|
+
const multipart = await env.R2.createMultipartUpload(key);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Queue Operations
|
|
293
|
+
```typescript
|
|
294
|
+
await env.QUEUE.send({ type: 'email', to: 'user@example.com' });
|
|
295
|
+
await env.QUEUE.sendBatch([{ body: msg1 }, { body: msg2 }]);
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Workers AI
|
|
299
|
+
```typescript
|
|
300
|
+
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
|
|
301
|
+
messages: [{ role: 'user', content: 'What is edge computing?' }]
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Resources
|
|
306
|
+
|
|
307
|
+
- Runtime APIs: https://developers.cloudflare.com/workers/runtime-apis/
|
|
308
|
+
- Web Standards: https://developers.cloudflare.com/workers/runtime-apis/web-standards/
|
|
309
|
+
- Bindings: https://developers.cloudflare.com/workers/runtime-apis/bindings/
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
# Cloudflare Workers Basics
|
|
2
|
+
|
|
3
|
+
Getting started with Cloudflare Workers: serverless functions that run on edge network across 300+ cities.
|
|
4
|
+
|
|
5
|
+
## Handler Types
|
|
6
|
+
|
|
7
|
+
### Fetch Handler (HTTP Requests)
|
|
8
|
+
```typescript
|
|
9
|
+
export default {
|
|
10
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
11
|
+
return new Response('Hello World!');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Scheduled Handler (Cron Jobs)
|
|
17
|
+
```typescript
|
|
18
|
+
export default {
|
|
19
|
+
async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
|
|
20
|
+
await fetch('https://api.example.com/cleanup');
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Configure in wrangler.toml:**
|
|
26
|
+
```toml
|
|
27
|
+
[triggers]
|
|
28
|
+
crons = ["0 0 * * *"] # Daily at midnight
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Queue Handler (Message Processing)
|
|
32
|
+
```typescript
|
|
33
|
+
export default {
|
|
34
|
+
async queue(batch: MessageBatch, env: Env, ctx: ExecutionContext): Promise<void> {
|
|
35
|
+
for (const message of batch.messages) {
|
|
36
|
+
await processMessage(message.body);
|
|
37
|
+
message.ack(); // Acknowledge success
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Email Handler (Email Routing)
|
|
44
|
+
```typescript
|
|
45
|
+
export default {
|
|
46
|
+
async email(message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext): Promise<void> {
|
|
47
|
+
await message.forward('destination@example.com');
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Request/Response Basics
|
|
53
|
+
|
|
54
|
+
### Parsing Request
|
|
55
|
+
```typescript
|
|
56
|
+
const url = new URL(request.url);
|
|
57
|
+
const method = request.method;
|
|
58
|
+
const headers = request.headers;
|
|
59
|
+
|
|
60
|
+
// Query parameters
|
|
61
|
+
const name = url.searchParams.get('name');
|
|
62
|
+
|
|
63
|
+
// JSON body
|
|
64
|
+
const data = await request.json();
|
|
65
|
+
|
|
66
|
+
// Text body
|
|
67
|
+
const text = await request.text();
|
|
68
|
+
|
|
69
|
+
// Form data
|
|
70
|
+
const formData = await request.formData();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Creating Response
|
|
74
|
+
```typescript
|
|
75
|
+
// Text response
|
|
76
|
+
return new Response('Hello', { status: 200 });
|
|
77
|
+
|
|
78
|
+
// JSON response
|
|
79
|
+
return new Response(JSON.stringify({ message: 'Hello' }), {
|
|
80
|
+
status: 200,
|
|
81
|
+
headers: { 'Content-Type': 'application/json' }
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Stream response
|
|
85
|
+
return new Response(readable, {
|
|
86
|
+
headers: { 'Content-Type': 'text/plain' }
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Redirect
|
|
90
|
+
return Response.redirect('https://example.com', 302);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Routing Patterns
|
|
94
|
+
|
|
95
|
+
### URL-Based Routing
|
|
96
|
+
```typescript
|
|
97
|
+
export default {
|
|
98
|
+
async fetch(request: Request): Promise<Response> {
|
|
99
|
+
const url = new URL(request.url);
|
|
100
|
+
|
|
101
|
+
switch (url.pathname) {
|
|
102
|
+
case '/':
|
|
103
|
+
return new Response('Home');
|
|
104
|
+
case '/about':
|
|
105
|
+
return new Response('About');
|
|
106
|
+
default:
|
|
107
|
+
return new Response('Not Found', { status: 404 });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Using Hono Framework (Recommended)
|
|
114
|
+
```typescript
|
|
115
|
+
import { Hono } from 'hono';
|
|
116
|
+
|
|
117
|
+
const app = new Hono();
|
|
118
|
+
|
|
119
|
+
app.get('/', (c) => c.text('Home'));
|
|
120
|
+
app.get('/api/users/:id', async (c) => {
|
|
121
|
+
const id = c.req.param('id');
|
|
122
|
+
const user = await getUser(id);
|
|
123
|
+
return c.json(user);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export default app;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Working with Bindings
|
|
130
|
+
|
|
131
|
+
### Environment Variables
|
|
132
|
+
```toml
|
|
133
|
+
# wrangler.toml
|
|
134
|
+
[vars]
|
|
135
|
+
API_URL = "https://api.example.com"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const apiUrl = env.API_URL;
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### KV Namespace
|
|
143
|
+
```typescript
|
|
144
|
+
// Put with TTL
|
|
145
|
+
await env.KV.put('session:token', JSON.stringify(data), {
|
|
146
|
+
expirationTtl: 3600
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Get
|
|
150
|
+
const data = await env.KV.get('session:token', 'json');
|
|
151
|
+
|
|
152
|
+
// Delete
|
|
153
|
+
await env.KV.delete('session:token');
|
|
154
|
+
|
|
155
|
+
// List with prefix
|
|
156
|
+
const list = await env.KV.list({ prefix: 'user:123:' });
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### D1 Database
|
|
160
|
+
```typescript
|
|
161
|
+
// Query
|
|
162
|
+
const result = await env.DB.prepare(
|
|
163
|
+
'SELECT * FROM users WHERE id = ?'
|
|
164
|
+
).bind(userId).first();
|
|
165
|
+
|
|
166
|
+
// Insert
|
|
167
|
+
await env.DB.prepare(
|
|
168
|
+
'INSERT INTO users (name, email) VALUES (?, ?)'
|
|
169
|
+
).bind('Alice', 'alice@example.com').run();
|
|
170
|
+
|
|
171
|
+
// Batch (atomic)
|
|
172
|
+
await env.DB.batch([
|
|
173
|
+
env.DB.prepare('UPDATE accounts SET balance = balance - 100 WHERE id = ?').bind(1),
|
|
174
|
+
env.DB.prepare('UPDATE accounts SET balance = balance + 100 WHERE id = ?').bind(2)
|
|
175
|
+
]);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### R2 Bucket
|
|
179
|
+
```typescript
|
|
180
|
+
// Put object
|
|
181
|
+
await env.R2_BUCKET.put('path/to/file.jpg', fileBuffer, {
|
|
182
|
+
httpMetadata: {
|
|
183
|
+
contentType: 'image/jpeg'
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Get object
|
|
188
|
+
const object = await env.R2_BUCKET.get('path/to/file.jpg');
|
|
189
|
+
if (!object) {
|
|
190
|
+
return new Response('Not found', { status: 404 });
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Stream response
|
|
194
|
+
return new Response(object.body, {
|
|
195
|
+
headers: {
|
|
196
|
+
'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream'
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Delete
|
|
201
|
+
await env.R2_BUCKET.delete('path/to/file.jpg');
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Context API
|
|
205
|
+
|
|
206
|
+
### waitUntil (Background Tasks)
|
|
207
|
+
```typescript
|
|
208
|
+
export default {
|
|
209
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
210
|
+
// Run analytics after response sent
|
|
211
|
+
ctx.waitUntil(
|
|
212
|
+
fetch('https://analytics.example.com/log', {
|
|
213
|
+
method: 'POST',
|
|
214
|
+
body: JSON.stringify({ url: request.url })
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
return new Response('OK');
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### passThroughOnException
|
|
224
|
+
```typescript
|
|
225
|
+
// Continue to origin on error
|
|
226
|
+
ctx.passThroughOnException();
|
|
227
|
+
|
|
228
|
+
// Your code that might throw
|
|
229
|
+
const data = await riskyOperation();
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Error Handling
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
export default {
|
|
236
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
237
|
+
try {
|
|
238
|
+
const response = await processRequest(request, env);
|
|
239
|
+
return response;
|
|
240
|
+
} catch (error) {
|
|
241
|
+
console.error('Error:', error);
|
|
242
|
+
|
|
243
|
+
// Log to external service
|
|
244
|
+
ctx.waitUntil(
|
|
245
|
+
fetch('https://logging.example.com/error', {
|
|
246
|
+
method: 'POST',
|
|
247
|
+
body: JSON.stringify({
|
|
248
|
+
error: error.message,
|
|
249
|
+
url: request.url
|
|
250
|
+
})
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
return new Response('Internal Server Error', { status: 500 });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## CORS
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
function corsHeaders(origin: string) {
|
|
264
|
+
return {
|
|
265
|
+
'Access-Control-Allow-Origin': origin,
|
|
266
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
267
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
268
|
+
'Access-Control-Max-Age': '86400'
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export default {
|
|
273
|
+
async fetch(request: Request): Promise<Response> {
|
|
274
|
+
const origin = request.headers.get('Origin') || '*';
|
|
275
|
+
|
|
276
|
+
// Handle preflight
|
|
277
|
+
if (request.method === 'OPTIONS') {
|
|
278
|
+
return new Response(null, { headers: corsHeaders(origin) });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Handle request
|
|
282
|
+
const response = await handleRequest(request);
|
|
283
|
+
const headers = new Headers(response.headers);
|
|
284
|
+
Object.entries(corsHeaders(origin)).forEach(([key, value]) => {
|
|
285
|
+
headers.set(key, value);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
return new Response(response.body, {
|
|
289
|
+
status: response.status,
|
|
290
|
+
headers
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Cache API
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
export default {
|
|
300
|
+
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
|
301
|
+
const cache = caches.default;
|
|
302
|
+
const cacheKey = new Request(request.url);
|
|
303
|
+
|
|
304
|
+
// Check cache
|
|
305
|
+
let response = await cache.match(cacheKey);
|
|
306
|
+
if (response) return response;
|
|
307
|
+
|
|
308
|
+
// Fetch from origin
|
|
309
|
+
response = await fetch(request);
|
|
310
|
+
|
|
311
|
+
// Cache response
|
|
312
|
+
ctx.waitUntil(cache.put(cacheKey, response.clone()));
|
|
313
|
+
|
|
314
|
+
return response;
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Secrets Management
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Add secret
|
|
323
|
+
wrangler secret put API_KEY
|
|
324
|
+
# Enter value when prompted
|
|
325
|
+
|
|
326
|
+
# Use in Worker
|
|
327
|
+
const apiKey = env.API_KEY;
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Local Development
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# Start local dev server
|
|
334
|
+
wrangler dev
|
|
335
|
+
|
|
336
|
+
# Test with remote edge
|
|
337
|
+
wrangler dev --remote
|
|
338
|
+
|
|
339
|
+
# Custom port
|
|
340
|
+
wrangler dev --port 8080
|
|
341
|
+
|
|
342
|
+
# Access at http://localhost:8787
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Deployment
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
# Deploy to production
|
|
349
|
+
wrangler deploy
|
|
350
|
+
|
|
351
|
+
# Deploy to specific environment
|
|
352
|
+
wrangler deploy --env staging
|
|
353
|
+
|
|
354
|
+
# Preview deployment
|
|
355
|
+
wrangler deploy --dry-run
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Common Patterns
|
|
359
|
+
|
|
360
|
+
### API Gateway
|
|
361
|
+
```typescript
|
|
362
|
+
import { Hono } from 'hono';
|
|
363
|
+
|
|
364
|
+
const app = new Hono();
|
|
365
|
+
|
|
366
|
+
app.get('/api/users', async (c) => {
|
|
367
|
+
const users = await c.env.DB.prepare('SELECT * FROM users').all();
|
|
368
|
+
return c.json(users.results);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
app.post('/api/users', async (c) => {
|
|
372
|
+
const { name, email } = await c.req.json();
|
|
373
|
+
await c.env.DB.prepare(
|
|
374
|
+
'INSERT INTO users (name, email) VALUES (?, ?)'
|
|
375
|
+
).bind(name, email).run();
|
|
376
|
+
return c.json({ success: true }, 201);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
export default app;
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Rate Limiting
|
|
383
|
+
```typescript
|
|
384
|
+
async function rateLimit(ip: string, env: Env): Promise<boolean> {
|
|
385
|
+
const key = `ratelimit:${ip}`;
|
|
386
|
+
const limit = 100;
|
|
387
|
+
const window = 60;
|
|
388
|
+
|
|
389
|
+
const current = await env.KV.get(key);
|
|
390
|
+
const count = current ? parseInt(current) : 0;
|
|
391
|
+
|
|
392
|
+
if (count >= limit) return false;
|
|
393
|
+
|
|
394
|
+
await env.KV.put(key, (count + 1).toString(), {
|
|
395
|
+
expirationTtl: window
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export default {
|
|
402
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
403
|
+
const ip = request.headers.get('CF-Connecting-IP') || 'unknown';
|
|
404
|
+
|
|
405
|
+
if (!await rateLimit(ip, env)) {
|
|
406
|
+
return new Response('Rate limit exceeded', { status: 429 });
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return new Response('OK');
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Resources
|
|
415
|
+
|
|
416
|
+
- Docs: https://developers.cloudflare.com/workers/
|
|
417
|
+
- Examples: https://developers.cloudflare.com/workers/examples/
|
|
418
|
+
- Runtime APIs: https://developers.cloudflare.com/workers/runtime-apis/
|