claudeinone-cli 1.0.1 → 1.0.3
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/dist/index.js +16 -1
- package/kit/.claude/.ck.json +9 -0
- package/kit/.claude/.ckignore +12 -0
- package/kit/.claude/agents/accessibility-auditor.md +46 -0
- package/kit/.claude/agents/api-designer.md +43 -0
- package/kit/.claude/agents/backend-developer.md +54 -0
- package/kit/.claude/agents/brainstormer.md +33 -0
- package/kit/.claude/agents/campaign-manager.md +36 -0
- package/kit/.claude/agents/code-reviewer.md +39 -0
- package/kit/.claude/agents/content-creator.md +38 -0
- package/kit/.claude/agents/copywriter.md +42 -0
- package/kit/.claude/agents/database-admin.md +37 -0
- package/kit/.claude/agents/debugger.md +46 -0
- package/kit/.claude/agents/devops-engineer.md +41 -0
- package/kit/.claude/agents/docs-manager.md +33 -0
- package/kit/.claude/agents/email-wizard.md +40 -0
- package/kit/.claude/agents/frontend-developer.md +52 -0
- package/kit/.claude/agents/fullstack-developer.md +55 -0
- package/kit/.claude/agents/git-manager.md +40 -0
- package/kit/.claude/agents/i18n-specialist.md +46 -0
- package/kit/.claude/agents/integration-specialist.md +48 -0
- package/kit/.claude/agents/journal-writer.md +39 -0
- package/kit/.claude/agents/mcp-manager.md +57 -0
- package/kit/.claude/agents/mobile-developer.md +38 -0
- package/kit/.claude/agents/performance-optimizer.md +38 -0
- package/kit/.claude/agents/planner.md +56 -0
- package/kit/.claude/agents/project-manager.md +34 -0
- package/kit/.claude/agents/refactorer.md +43 -0
- package/kit/.claude/agents/researcher.md +45 -0
- package/kit/.claude/agents/risk-analyst.md +33 -0
- package/kit/.claude/agents/scalability-consultant.md +39 -0
- package/kit/.claude/agents/scout.md +25 -0
- package/kit/.claude/agents/security-auditor.md +42 -0
- package/kit/.claude/agents/seo-specialist.md +44 -0
- package/kit/.claude/agents/skill-creator.md +64 -0
- package/kit/.claude/agents/social-media-manager.md +35 -0
- package/kit/.claude/agents/systems-designer.md +35 -0
- package/kit/.claude/agents/technology-strategist.md +43 -0
- package/kit/.claude/agents/tester.md +40 -0
- package/kit/.claude/agents/ui-ux-designer.md +40 -0
- package/kit/.claude/commands/co/ask.md +29 -0
- package/kit/.claude/commands/co/bootstrap-auto-fast.md +28 -0
- package/kit/.claude/commands/co/bootstrap-auto-parallel.md +29 -0
- package/kit/.claude/commands/co/bootstrap-auto.md +30 -0
- package/kit/.claude/commands/co/bootstrap.md +31 -0
- package/kit/.claude/commands/co/brainstorm.md +27 -0
- package/kit/.claude/commands/co/campaign.md +28 -0
- package/kit/.claude/commands/co/changelog.md +25 -0
- package/kit/.claude/commands/co/checkpoint.md +25 -0
- package/kit/.claude/commands/co/ci.md +26 -0
- package/kit/.claude/commands/co/ck-help.md +24 -0
- package/kit/.claude/commands/co/coding-level.md +24 -0
- package/kit/.claude/commands/co/content-cro.md +26 -0
- package/kit/.claude/commands/co/content-enhance.md +26 -0
- package/kit/.claude/commands/co/content-fast.md +24 -0
- package/kit/.claude/commands/co/content-good.md +26 -0
- package/kit/.claude/commands/co/cook.md +33 -0
- package/kit/.claude/commands/co/debug.md +26 -0
- package/kit/.claude/commands/co/deploy.md +25 -0
- package/kit/.claude/commands/co/design-3d.md +27 -0
- package/kit/.claude/commands/co/design-describe.md +25 -0
- package/kit/.claude/commands/co/design-fast.md +25 -0
- package/kit/.claude/commands/co/design-good.md +28 -0
- package/kit/.claude/commands/co/design-screenshot.md +26 -0
- package/kit/.claude/commands/co/design-video.md +26 -0
- package/kit/.claude/commands/co/docker.md +24 -0
- package/kit/.claude/commands/co/docs-api.md +25 -0
- package/kit/.claude/commands/co/docs-init.md +26 -0
- package/kit/.claude/commands/co/docs-readme.md +24 -0
- package/kit/.claude/commands/co/docs-summarize.md +25 -0
- package/kit/.claude/commands/co/docs-update.md +25 -0
- package/kit/.claude/commands/co/env-check.md +25 -0
- package/kit/.claude/commands/co/fix-ci.md +29 -0
- package/kit/.claude/commands/co/fix-fast.md +28 -0
- package/kit/.claude/commands/co/fix-hard.md +33 -0
- package/kit/.claude/commands/co/fix-logs.md +28 -0
- package/kit/.claude/commands/co/fix-types.md +28 -0
- package/kit/.claude/commands/co/fix-ui.md +28 -0
- package/kit/.claude/commands/co/fix.md +27 -0
- package/kit/.claude/commands/co/git-cm.md +26 -0
- package/kit/.claude/commands/co/git-cp.md +26 -0
- package/kit/.claude/commands/co/git-pr.md +26 -0
- package/kit/.claude/commands/co/index.md +24 -0
- package/kit/.claude/commands/co/integrate-polar.md +29 -0
- package/kit/.claude/commands/co/integrate-sepay.md +29 -0
- package/kit/.claude/commands/co/journal.md +27 -0
- package/kit/.claude/commands/co/k8s.md +24 -0
- package/kit/.claude/commands/co/kanban.md +25 -0
- package/kit/.claude/commands/co/lint-fix.md +24 -0
- package/kit/.claude/commands/co/load.md +25 -0
- package/kit/.claude/commands/co/migrate.md +28 -0
- package/kit/.claude/commands/co/mock.md +26 -0
- package/kit/.claude/commands/co/mode.md +24 -0
- package/kit/.claude/commands/co/monitor.md +25 -0
- package/kit/.claude/commands/co/new-feature.md +27 -0
- package/kit/.claude/commands/co/optimize.md +26 -0
- package/kit/.claude/commands/co/plan-archive.md +24 -0
- package/kit/.claude/commands/co/plan-ci.md +28 -0
- package/kit/.claude/commands/co/plan-cro.md +27 -0
- package/kit/.claude/commands/co/plan-fast.md +24 -0
- package/kit/.claude/commands/co/plan-hard.md +27 -0
- package/kit/.claude/commands/co/plan-parallel.md +25 -0
- package/kit/.claude/commands/co/plan-two.md +29 -0
- package/kit/.claude/commands/co/plan-validate.md +27 -0
- package/kit/.claude/commands/co/plan.md +27 -0
- package/kit/.claude/commands/co/pr.md +25 -0
- package/kit/.claude/commands/co/preview.md +26 -0
- package/kit/.claude/commands/co/refactor.md +25 -0
- package/kit/.claude/commands/co/release.md +25 -0
- package/kit/.claude/commands/co/review-a11y.md +24 -0
- package/kit/.claude/commands/co/review-codebase-parallel.md +27 -0
- package/kit/.claude/commands/co/review-codebase.md +27 -0
- package/kit/.claude/commands/co/review-perf.md +24 -0
- package/kit/.claude/commands/co/review-security.md +25 -0
- package/kit/.claude/commands/co/scaffold.md +25 -0
- package/kit/.claude/commands/co/scout.md +26 -0
- package/kit/.claude/commands/co/secure.md +26 -0
- package/kit/.claude/commands/co/seed.md +25 -0
- package/kit/.claude/commands/co/seo-audit.md +24 -0
- package/kit/.claude/commands/co/seo-keywords.md +25 -0
- package/kit/.claude/commands/co/skill-create.md +29 -0
- package/kit/.claude/commands/co/skill-fix-logs.md +28 -0
- package/kit/.claude/commands/co/slide-create.md +24 -0
- package/kit/.claude/commands/co/spawn.md +24 -0
- package/kit/.claude/commands/co/terraform.md +24 -0
- package/kit/.claude/commands/co/test-gen.md +24 -0
- package/kit/.claude/commands/co/test-ui.md +27 -0
- package/kit/.claude/commands/co/test.md +26 -0
- package/kit/.claude/commands/co/use-mcp.md +25 -0
- package/kit/.claude/commands/co/video-script.md +25 -0
- package/kit/.claude/commands/co/watzup.md +25 -0
- package/kit/.claude/commands/co/worktree.md +25 -0
- package/kit/.claude/commands/co/write-blog.md +25 -0
- package/kit/.claude/commands/co/write-copy.md +24 -0
- package/kit/.claude/commands/co/write-email.md +25 -0
- package/kit/.claude/commands/content/content-cro.md +26 -0
- package/kit/.claude/commands/content/content-enhance.md +26 -0
- package/kit/.claude/commands/content/content-fast.md +24 -0
- package/kit/.claude/commands/content/content-good.md +26 -0
- package/kit/.claude/commands/content/enhance.md +26 -0
- package/kit/.claude/commands/content/good.md +26 -0
- package/kit/.claude/commands/core/ask.md +29 -0
- package/kit/.claude/commands/core/bootstrap-auto-fast.md +28 -0
- package/kit/.claude/commands/core/bootstrap-auto-parallel.md +29 -0
- package/kit/.claude/commands/core/bootstrap-auto.md +30 -0
- package/kit/.claude/commands/core/bootstrap.md +31 -0
- package/kit/.claude/commands/core/ck-help.md +24 -0
- package/kit/.claude/commands/core/coding-level.md +24 -0
- package/kit/.claude/commands/core/cook.md +33 -0
- package/kit/.claude/commands/core/debug.md +26 -0
- package/kit/.claude/commands/core/journal.md +27 -0
- package/kit/.claude/commands/core/kanban.md +25 -0
- package/kit/.claude/commands/core/preview.md +26 -0
- package/kit/.claude/commands/core/scout.md +26 -0
- package/kit/.claude/commands/core/test-ui.md +27 -0
- package/kit/.claude/commands/core/test.md +26 -0
- package/kit/.claude/commands/core/use-mcp.md +25 -0
- package/kit/.claude/commands/core/watzup.md +25 -0
- package/kit/.claude/commands/core/worktree.md +25 -0
- package/kit/.claude/commands/design/3d.md +27 -0
- package/kit/.claude/commands/design/design-3d.md +27 -0
- package/kit/.claude/commands/design/design-describe.md +25 -0
- package/kit/.claude/commands/design/design-fast.md +25 -0
- package/kit/.claude/commands/design/design-good.md +28 -0
- package/kit/.claude/commands/design/design-screenshot.md +26 -0
- package/kit/.claude/commands/design/design-video.md +26 -0
- package/kit/.claude/commands/design/good.md +28 -0
- package/kit/.claude/commands/design/video.md +26 -0
- package/kit/.claude/commands/docs/docs-init.md +26 -0
- package/kit/.claude/commands/docs/docs-summarize.md +25 -0
- package/kit/.claude/commands/docs/docs-update.md +25 -0
- package/kit/.claude/commands/docs/init.md +26 -0
- package/kit/.claude/commands/docs/summarize.md +25 -0
- package/kit/.claude/commands/fix/ci.md +29 -0
- package/kit/.claude/commands/fix/fast.md +28 -0
- package/kit/.claude/commands/fix/fix-ci.md +29 -0
- package/kit/.claude/commands/fix/fix-fast.md +28 -0
- package/kit/.claude/commands/fix/fix-hard.md +33 -0
- package/kit/.claude/commands/fix/fix-logs.md +28 -0
- package/kit/.claude/commands/fix/fix-types.md +28 -0
- package/kit/.claude/commands/fix/fix-ui.md +28 -0
- package/kit/.claude/commands/fix/hard.md +33 -0
- package/kit/.claude/commands/fix/logs.md +28 -0
- package/kit/.claude/commands/fix/types.md +28 -0
- package/kit/.claude/commands/fix/ui.md +28 -0
- package/kit/.claude/commands/git/cp.md +26 -0
- package/kit/.claude/commands/git/git-cm.md +26 -0
- package/kit/.claude/commands/git/git-cp.md +26 -0
- package/kit/.claude/commands/git/git-pr.md +26 -0
- package/kit/.claude/commands/integrate/integrate-polar.md +29 -0
- package/kit/.claude/commands/integrate/integrate-sepay.md +29 -0
- package/kit/.claude/commands/integrate/sepay.md +29 -0
- package/kit/.claude/commands/plan/ci.md +28 -0
- package/kit/.claude/commands/plan/cro.md +27 -0
- package/kit/.claude/commands/plan/hard.md +27 -0
- package/kit/.claude/commands/plan/plan-archive.md +24 -0
- package/kit/.claude/commands/plan/plan-ci.md +28 -0
- package/kit/.claude/commands/plan/plan-cro.md +27 -0
- package/kit/.claude/commands/plan/plan-fast.md +24 -0
- package/kit/.claude/commands/plan/plan-hard.md +27 -0
- package/kit/.claude/commands/plan/plan-parallel.md +25 -0
- package/kit/.claude/commands/plan/plan-two.md +29 -0
- package/kit/.claude/commands/plan/plan-validate.md +27 -0
- package/kit/.claude/commands/plan/plan.md +27 -0
- package/kit/.claude/commands/plan/validate.md +27 -0
- package/kit/.claude/commands/skill/fix-logs.md +28 -0
- package/kit/.claude/commands/skill/skill-create.md +29 -0
- package/kit/.claude/commands/skill/skill-fix-logs.md +28 -0
- package/kit/.claude/settings.json +16 -0
- package/kit/.claude/skills/ai-anthropic.md +100 -0
- package/kit/.claude/skills/ai-context-engineering.md +113 -0
- package/kit/.claude/skills/ai-gemini.md +152 -0
- package/kit/.claude/skills/ai-langchain.md +93 -0
- package/kit/.claude/skills/ai-llamaindex.md +179 -0
- package/kit/.claude/skills/ai-mcp-builder.md +101 -0
- package/kit/.claude/skills/ai-openai.md +250 -0
- package/kit/.claude/skills/ai-prompt-engineering.md +173 -0
- package/kit/.claude/skills/ai-rag.md +91 -0
- package/kit/.claude/skills/ai-vectordb.md +215 -0
- package/kit/.claude/skills/analytics-segment.md +161 -0
- package/kit/.claude/skills/api-caching.md +103 -0
- package/kit/.claude/skills/api-documentation.md +50 -0
- package/kit/.claude/skills/api-graphql.md +234 -0
- package/kit/.claude/skills/api-openapi.md +116 -0
- package/kit/.claude/skills/api-pagination-filtering.md +239 -0
- package/kit/.claude/skills/api-rate-limiting.md +179 -0
- package/kit/.claude/skills/api-rest-advanced.md +50 -0
- package/kit/.claude/skills/api-rest.md +217 -0
- package/kit/.claude/skills/api-trpc.md +173 -0
- package/kit/.claude/skills/api-versioning.md +70 -0
- package/kit/.claude/skills/api-webhooks.md +226 -0
- package/kit/.claude/skills/arch-clean-code.md +226 -0
- package/kit/.claude/skills/arch-clean.md +91 -0
- package/kit/.claude/skills/arch-cqrs.md +229 -0
- package/kit/.claude/skills/arch-ddd.md +85 -0
- package/kit/.claude/skills/arch-event-driven.md +189 -0
- package/kit/.claude/skills/arch-microservices.md +80 -0
- package/kit/.claude/skills/arch-monorepo.md +87 -0
- package/kit/.claude/skills/arch-multi-tenant.md +81 -0
- package/kit/.claude/skills/arch-serverless.md +86 -0
- package/kit/.claude/skills/auth-clerk.md +97 -0
- package/kit/.claude/skills/auth-jwt.md +143 -0
- package/kit/.claude/skills/auth-lucia.md +93 -0
- package/kit/.claude/skills/auth-nextauth.md +446 -0
- package/kit/.claude/skills/auth-oauth.md +208 -0
- package/kit/.claude/skills/auth-oauth2.md +110 -0
- package/kit/.claude/skills/auth-passkeys.md +109 -0
- package/kit/.claude/skills/auth-session.md +88 -0
- package/kit/.claude/skills/backend-dotnet.md +414 -0
- package/kit/.claude/skills/backend-express.md +129 -0
- package/kit/.claude/skills/backend-fastify.md +104 -0
- package/kit/.claude/skills/backend-go.md +205 -0
- package/kit/.claude/skills/backend-graphql.md +149 -0
- package/kit/.claude/skills/backend-grpc.md +382 -0
- package/kit/.claude/skills/backend-hono.md +95 -0
- package/kit/.claude/skills/backend-java-spring.md +198 -0
- package/kit/.claude/skills/backend-nodejs-express.md +165 -0
- package/kit/.claude/skills/backend-nodejs.md +143 -0
- package/kit/.claude/skills/backend-php-laravel.md +156 -0
- package/kit/.claude/skills/backend-python-django.md +200 -0
- package/kit/.claude/skills/backend-python-fastapi.md +169 -0
- package/kit/.claude/skills/backend-ruby-rails.md +190 -0
- package/kit/.claude/skills/backend-rust.md +182 -0
- package/kit/.claude/skills/backend-websockets.md +392 -0
- package/kit/.claude/skills/cache-redis.md +195 -0
- package/kit/.claude/skills/caching-strategies.md +100 -0
- package/kit/.claude/skills/cloud-aws.md +165 -0
- package/kit/.claude/skills/cloud-azure.md +187 -0
- package/kit/.claude/skills/cloud-cloudflare.md +74 -0
- package/kit/.claude/skills/cloud-fly.md +94 -0
- package/kit/.claude/skills/cloud-gcp.md +160 -0
- package/kit/.claude/skills/cloud-railway.md +92 -0
- package/kit/.claude/skills/cloud-render.md +70 -0
- package/kit/.claude/skills/cloud-serverless.md +68 -0
- package/kit/.claude/skills/cloud-vercel.md +76 -0
- package/kit/.claude/skills/component-patterns.md +50 -0
- package/kit/.claude/skills/content-management.md +197 -0
- package/kit/.claude/skills/cors-security.md +50 -0
- package/kit/.claude/skills/data-csv-excel.md +210 -0
- package/kit/.claude/skills/database-optimization.md +196 -0
- package/kit/.claude/skills/databases-transactions.md +68 -0
- package/kit/.claude/skills/db-cassandra.md +89 -0
- package/kit/.claude/skills/db-drizzle.md +363 -0
- package/kit/.claude/skills/db-dynamodb.md +83 -0
- package/kit/.claude/skills/db-elasticsearch.md +105 -0
- package/kit/.claude/skills/db-firebase-firestore.md +191 -0
- package/kit/.claude/skills/db-mongodb.md +198 -0
- package/kit/.claude/skills/db-mysql.md +50 -0
- package/kit/.claude/skills/db-neon.md +72 -0
- package/kit/.claude/skills/db-planetscale.md +76 -0
- package/kit/.claude/skills/db-postgresql.md +50 -0
- package/kit/.claude/skills/db-prisma.md +414 -0
- package/kit/.claude/skills/db-redis.md +50 -0
- package/kit/.claude/skills/db-sqlite.md +149 -0
- package/kit/.claude/skills/db-supabase.md +445 -0
- package/kit/.claude/skills/devops-ci-cd.md +271 -0
- package/kit/.claude/skills/devops-database-backup.md +77 -0
- package/kit/.claude/skills/devops-docker.md +93 -0
- package/kit/.claude/skills/devops-github-actions.md +82 -0
- package/kit/.claude/skills/devops-health-checks.md +50 -0
- package/kit/.claude/skills/devops-kubernetes.md +109 -0
- package/kit/.claude/skills/devops-logging.md +163 -0
- package/kit/.claude/skills/devops-monitoring.md +203 -0
- package/kit/.claude/skills/devops-pulumi.md +94 -0
- package/kit/.claude/skills/devops-secrets.md +166 -0
- package/kit/.claude/skills/devops-terraform.md +226 -0
- package/kit/.claude/skills/error-boundaries.md +84 -0
- package/kit/.claude/skills/file-storage.md +50 -0
- package/kit/.claude/skills/frontend-angular.md +104 -0
- package/kit/.claude/skills/frontend-astro.md +94 -0
- package/kit/.claude/skills/frontend-bundle-analysis.md +147 -0
- package/kit/.claude/skills/frontend-forms.md +134 -0
- package/kit/.claude/skills/frontend-htmx.md +86 -0
- package/kit/.claude/skills/frontend-nextjs.md +188 -0
- package/kit/.claude/skills/frontend-pwa.md +105 -0
- package/kit/.claude/skills/frontend-react-hooks.md +238 -0
- package/kit/.claude/skills/frontend-react.md +129 -0
- package/kit/.claude/skills/frontend-remix-advanced.md +106 -0
- package/kit/.claude/skills/frontend-remix.md +101 -0
- package/kit/.claude/skills/frontend-solid.md +99 -0
- package/kit/.claude/skills/frontend-state-management.md +134 -0
- package/kit/.claude/skills/frontend-state.md +106 -0
- package/kit/.claude/skills/frontend-svelte.md +121 -0
- package/kit/.claude/skills/frontend-testing.md +100 -0
- package/kit/.claude/skills/frontend-vite.md +94 -0
- package/kit/.claude/skills/frontend-vue.md +133 -0
- package/kit/.claude/skills/frontend-webpack.md +93 -0
- package/kit/.claude/skills/functional-programming.md +50 -0
- package/kit/.claude/skills/hooks-custom.md +50 -0
- package/kit/.claude/skills/http-server.md +50 -0
- package/kit/.claude/skills/i18n-general.md +89 -0
- package/kit/.claude/skills/i18n-localization.md +191 -0
- package/kit/.claude/skills/i18n-nextjs.md +127 -0
- package/kit/.claude/skills/infrastructure-docker-compose.md +77 -0
- package/kit/.claude/skills/infrastructure-serverless.md +177 -0
- package/kit/.claude/skills/jwt-tokens.md +50 -0
- package/kit/.claude/skills/logging-winston.md +106 -0
- package/kit/.claude/skills/messaging-kafka.md +102 -0
- package/kit/.claude/skills/messaging-rabbitmq.md +50 -0
- package/kit/.claude/skills/mobile-capacitor.md +109 -0
- package/kit/.claude/skills/mobile-expo.md +101 -0
- package/kit/.claude/skills/mobile-flutter.md +259 -0
- package/kit/.claude/skills/mobile-react-native.md +238 -0
- package/kit/.claude/skills/monitoring-apm.md +50 -0
- package/kit/.claude/skills/monitoring-error-tracking.md +217 -0
- package/kit/.claude/skills/nodejs-streams.md +168 -0
- package/kit/.claude/skills/oauth-integration.md +50 -0
- package/kit/.claude/skills/patterns-dependency-injection.md +218 -0
- package/kit/.claude/skills/patterns-factory-singleton.md +209 -0
- package/kit/.claude/skills/patterns-observer-pubsub.md +210 -0
- package/kit/.claude/skills/payment-lemonsqueezy.md +101 -0
- package/kit/.claude/skills/payment-square.md +178 -0
- package/kit/.claude/skills/payment-stripe.md +206 -0
- package/kit/.claude/skills/perf-bundle.md +100 -0
- package/kit/.claude/skills/perf-web-vitals.md +102 -0
- package/kit/.claude/skills/performance-database-connection-pooling.md +67 -0
- package/kit/.claude/skills/performance-metrics.md +73 -0
- package/kit/.claude/skills/performance-optimization.md +208 -0
- package/kit/.claude/skills/performance-web-vitals.md +169 -0
- package/kit/.claude/skills/rate-limiting.md +77 -0
- package/kit/.claude/skills/reactive-programming.md +50 -0
- package/kit/.claude/skills/realtime-database.md +50 -0
- package/kit/.claude/skills/realtime-subscriptions.md +218 -0
- package/kit/.claude/skills/saas-ab-testing.md +90 -0
- package/kit/.claude/skills/saas-analytics.md +113 -0
- package/kit/.claude/skills/saas-billing.md +106 -0
- package/kit/.claude/skills/saas-email.md +88 -0
- package/kit/.claude/skills/saas-feature-flags.md +83 -0
- package/kit/.claude/skills/saas-onboarding.md +96 -0
- package/kit/.claude/skills/saas-user-onboarding.md +207 -0
- package/kit/.claude/skills/security-encryption.md +216 -0
- package/kit/.claude/skills/security-owasp.md +212 -0
- package/kit/.claude/skills/security-secrets-rotation.md +64 -0
- package/kit/.claude/skills/seo-content.md +94 -0
- package/kit/.claude/skills/seo-technical.md +101 -0
- package/kit/.claude/skills/serverless-framework.md +151 -0
- package/kit/.claude/skills/sharding-scaling.md +50 -0
- package/kit/.claude/skills/styling-css-modules.md +219 -0
- package/kit/.claude/skills/styling-styled-components.md +206 -0
- package/kit/.claude/skills/styling-tailwind.md +206 -0
- package/kit/.claude/skills/test-e2e.md +86 -0
- package/kit/.claude/skills/test-integration.md +216 -0
- package/kit/.claude/skills/test-performance.md +162 -0
- package/kit/.claude/skills/test-tdd.md +170 -0
- package/kit/.claude/skills/test-unit.md +301 -0
- package/kit/.claude/skills/testing-accessibility.md +117 -0
- package/kit/.claude/skills/testing-contract.md +75 -0
- package/kit/.claude/skills/testing-e2e-advanced.md +50 -0
- package/kit/.claude/skills/testing-load-stress.md +79 -0
- package/kit/.claude/skills/testing-mutation.md +92 -0
- package/kit/.claude/skills/testing-snapshot.md +50 -0
- package/kit/.claude/skills/testing-vitest.md +172 -0
- package/kit/.claude/skills/tooling-biome.md +91 -0
- package/kit/.claude/skills/tooling-build-tools.md +166 -0
- package/kit/.claude/skills/tooling-bun.md +94 -0
- package/kit/.claude/skills/tooling-eslint.md +103 -0
- package/kit/.claude/skills/tooling-git.md +79 -0
- package/kit/.claude/skills/tooling-monorepo.md +162 -0
- package/kit/.claude/skills/tooling-testing-frameworks.md +207 -0
- package/kit/.claude/skills/tooling-typescript.md +156 -0
- package/kit/.claude/skills/ui-a11y.md +106 -0
- package/kit/.claude/skills/ui-framer.md +106 -0
- package/kit/.claude/skills/ui-gsap.md +102 -0
- package/kit/.claude/skills/ui-radix.md +82 -0
- package/kit/.claude/skills/ui-shadcn.md +463 -0
- package/kit/.claude/skills/ui-tailwind.md +98 -0
- package/kit/.claude/skills/ui-threejs.md +110 -0
- package/kit/.claude/skills/ui-tokens.md +97 -0
- package/kit/.claude/skills/utilities-date-time.md +170 -0
- package/kit/.claude/skills/validation-schemas.md +110 -0
- package/kit/.claude/skills/version-control-git.md +144 -0
- package/kit/.claude/skills/web-accessibility-wcag.md +102 -0
- package/kit/.claude/skills/web-astro.md +197 -0
- package/kit/.claude/skills/web-html-css.md +224 -0
- package/kit/.claude/skills/web-htmx.md +99 -0
- package/kit/.claude/skills/web-nextjs-advanced.md +202 -0
- package/kit/.claude/skills/web-remix.md +194 -0
- package/kit/.claude/skills/web-seo.md +99 -0
- package/kit/.claude/skills/web-svelte.md +234 -0
- package/kit/.claude/skills/websocket-server.md +50 -0
- package/kit/.claude/skills/writing-marketing.md +89 -0
- package/kit/.claude/skills/writing-technical.md +119 -0
- package/kit/CLAUDE.md +206 -0
- package/kit/README.md +150 -0
- package/kit/SKILLS_INDEX.md +188 -0
- package/kit/docs/README.md +3 -0
- package/kit/journals/README.md +3 -0
- package/kit/plans/README.md +3 -0
- package/package.json +3 -1
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# GraphQL
|
|
2
|
+
|
|
3
|
+
Query language for APIs with strong typing and efficient data fetching.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install apollo-server graphql
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Schema Definition
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { gql } from 'apollo-server';
|
|
15
|
+
|
|
16
|
+
const typeDefs = gql`
|
|
17
|
+
type User {
|
|
18
|
+
id: ID!
|
|
19
|
+
email: String!
|
|
20
|
+
name: String!
|
|
21
|
+
posts: [Post!]!
|
|
22
|
+
createdAt: String!
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type Post {
|
|
26
|
+
id: ID!
|
|
27
|
+
title: String!
|
|
28
|
+
content: String!
|
|
29
|
+
author: User!
|
|
30
|
+
createdAt: String!
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type Query {
|
|
34
|
+
user(id: ID!): User
|
|
35
|
+
users(limit: Int = 10, offset: Int = 0): [User!]!
|
|
36
|
+
post(id: ID!): Post
|
|
37
|
+
searchPosts(query: String!): [Post!]!
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type Mutation {
|
|
41
|
+
createUser(email: String!, name: String!): User!
|
|
42
|
+
updateUser(id: ID!, name: String): User
|
|
43
|
+
deleteUser(id: ID!): Boolean!
|
|
44
|
+
|
|
45
|
+
createPost(title: String!, content: String!): Post!
|
|
46
|
+
updatePost(id: ID!, title: String, content: String): Post
|
|
47
|
+
deletePost(id: ID!): Boolean!
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type Subscription {
|
|
51
|
+
userCreated: User!
|
|
52
|
+
postCreated: Post!
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Resolvers
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const resolvers = {
|
|
61
|
+
Query: {
|
|
62
|
+
user: async (_, { id }) => {
|
|
63
|
+
return await userRepository.findById(id);
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
users: async (_, { limit, offset }) => {
|
|
67
|
+
return await userRepository.find()
|
|
68
|
+
.limit(limit)
|
|
69
|
+
.offset(offset);
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
searchPosts: async (_, { query }) => {
|
|
73
|
+
return await db('posts')
|
|
74
|
+
.whereRaw('MATCH(title, content) AGAINST(? IN BOOLEAN MODE)', [query]);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
Mutation: {
|
|
79
|
+
createUser: async (_, { email, name }, context) => {
|
|
80
|
+
// Verify auth
|
|
81
|
+
if (!context.user) throw new Error('Unauthorized');
|
|
82
|
+
|
|
83
|
+
const user = await userRepository.create({ email, name });
|
|
84
|
+
eventBus.emit('user:created', user);
|
|
85
|
+
return user;
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
updatePost: async (_, { id, title, content }, context) => {
|
|
89
|
+
const post = await postRepository.findById(id);
|
|
90
|
+
|
|
91
|
+
// Verify ownership
|
|
92
|
+
if (post.authorId !== context.user.id) {
|
|
93
|
+
throw new Error('Forbidden');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return await postRepository.update(id, { title, content });
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
Subscription: {
|
|
101
|
+
userCreated: {
|
|
102
|
+
subscribe: () => pubSub.asyncIterator(['USER_CREATED'])
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// Field resolvers
|
|
107
|
+
User: {
|
|
108
|
+
posts: async (user) => {
|
|
109
|
+
return await postRepository.findByUserId(user.id);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
Post: {
|
|
114
|
+
author: async (post) => {
|
|
115
|
+
return await userRepository.findById(post.authorId);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Apollo Server Setup
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { ApolloServer } from 'apollo-server-express';
|
|
125
|
+
import express from 'express';
|
|
126
|
+
|
|
127
|
+
const app = express();
|
|
128
|
+
|
|
129
|
+
const server = new ApolloServer({
|
|
130
|
+
typeDefs,
|
|
131
|
+
resolvers,
|
|
132
|
+
context: ({ req }) => ({
|
|
133
|
+
user: req.user,
|
|
134
|
+
loaders: createDataLoaders()
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
await server.start();
|
|
139
|
+
server.applyMiddleware({ app });
|
|
140
|
+
|
|
141
|
+
app.listen(4000, () => {
|
|
142
|
+
console.log('GraphQL server running on http://localhost:4000/graphql');
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Data Loaders (N+1 Prevention)
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import DataLoader from 'dataloader';
|
|
150
|
+
|
|
151
|
+
function createDataLoaders() {
|
|
152
|
+
const userLoader = new DataLoader(async (userIds) => {
|
|
153
|
+
return await userRepository.findByIds(userIds);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const postLoader = new DataLoader(async (postIds) => {
|
|
157
|
+
return await postRepository.findByIds(postIds);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return { userLoader, postLoader };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Use in resolvers
|
|
164
|
+
Post: {
|
|
165
|
+
author: (post, _, { loaders }) => {
|
|
166
|
+
return loaders.userLoader.load(post.authorId);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Client Usage
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { gql, useMutation, useQuery } from '@apollo/client';
|
|
175
|
+
|
|
176
|
+
const GET_USER = gql`
|
|
177
|
+
query GetUser($id: ID!) {
|
|
178
|
+
user(id: $id) {
|
|
179
|
+
id
|
|
180
|
+
email
|
|
181
|
+
name
|
|
182
|
+
posts {
|
|
183
|
+
id
|
|
184
|
+
title
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
`;
|
|
189
|
+
|
|
190
|
+
const CREATE_POST = gql`
|
|
191
|
+
mutation CreatePost($title: String!, $content: String!) {
|
|
192
|
+
createPost(title: $title, content: $content) {
|
|
193
|
+
id
|
|
194
|
+
title
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
`;
|
|
198
|
+
|
|
199
|
+
function UserProfile({ userId }) {
|
|
200
|
+
const { data, loading } = useQuery(GET_USER, {
|
|
201
|
+
variables: { id: userId }
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const [createPost] = useMutation(CREATE_POST);
|
|
205
|
+
|
|
206
|
+
const handleCreate = async (title, content) => {
|
|
207
|
+
await createPost({ variables: { title, content } });
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
if (loading) return <div>Loading...</div>;
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<div>
|
|
214
|
+
<h1>{data.user.name}</h1>
|
|
215
|
+
<button onClick={() => handleCreate('New Post', 'Content')}>
|
|
216
|
+
Create Post
|
|
217
|
+
</button>
|
|
218
|
+
</div>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Best Practices
|
|
224
|
+
|
|
225
|
+
✅ **Validate input** - Use custom scalar types
|
|
226
|
+
✅ **Batch queries** - Use DataLoaders for N+1 prevention
|
|
227
|
+
✅ **Rate limiting** - Protect against expensive queries
|
|
228
|
+
✅ **Error handling** - Return meaningful errors
|
|
229
|
+
✅ **Caching** - Use APQ (Automatic Persisted Queries)
|
|
230
|
+
|
|
231
|
+
## Resources
|
|
232
|
+
|
|
233
|
+
- [GraphQL Official](https://graphql.org/)
|
|
234
|
+
- [Apollo Server Docs](https://www.apollographql.com/docs/apollo-server/)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# OpenAPI / Swagger
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Document REST APIs with OpenAPI 3.x specs for auto-generated clients, validation, and interactive docs.
|
|
5
|
+
|
|
6
|
+
## Setup with Swagger UI (Express)
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install swagger-ui-express @asteasolutions/zod-to-openapi
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import swaggerUi from 'swagger-ui-express';
|
|
14
|
+
import { OpenAPIRegistry, OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi';
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
|
|
17
|
+
const registry = new OpenAPIRegistry();
|
|
18
|
+
|
|
19
|
+
// Define schemas
|
|
20
|
+
const UserSchema = registry.register('User', z.object({
|
|
21
|
+
id: z.string().uuid(),
|
|
22
|
+
email: z.string().email(),
|
|
23
|
+
name: z.string(),
|
|
24
|
+
createdAt: z.string().datetime(),
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
// Register paths
|
|
28
|
+
registry.registerPath({
|
|
29
|
+
method: 'get',
|
|
30
|
+
path: '/api/users/{id}',
|
|
31
|
+
tags: ['Users'],
|
|
32
|
+
summary: 'Get user by ID',
|
|
33
|
+
request: {
|
|
34
|
+
params: z.object({ id: z.string().uuid() }),
|
|
35
|
+
},
|
|
36
|
+
responses: {
|
|
37
|
+
200: {
|
|
38
|
+
description: 'User found',
|
|
39
|
+
content: { 'application/json': { schema: UserSchema } },
|
|
40
|
+
},
|
|
41
|
+
404: { description: 'User not found' },
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Generate spec
|
|
46
|
+
const generator = new OpenApiGeneratorV3(registry.definitions);
|
|
47
|
+
const spec = generator.generateDocument({
|
|
48
|
+
openapi: '3.0.0',
|
|
49
|
+
info: { title: 'My API', version: '1.0.0' },
|
|
50
|
+
servers: [{ url: 'https://api.example.com' }],
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
app.use('/api/docs', swaggerUi.serve, swaggerUi.setup(spec));
|
|
54
|
+
app.get('/api/openapi.json', (req, res) => res.json(spec));
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Next.js with next-swagger-doc
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install next-swagger-doc swagger-ui-react
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// pages/api/doc.ts
|
|
65
|
+
import { withSwagger } from 'next-swagger-doc';
|
|
66
|
+
|
|
67
|
+
const swaggerHandler = withSwagger({
|
|
68
|
+
definition: {
|
|
69
|
+
openapi: '3.0.0',
|
|
70
|
+
info: { title: 'Next.js API', version: '0.1.0' },
|
|
71
|
+
},
|
|
72
|
+
apiFolder: 'pages/api',
|
|
73
|
+
});
|
|
74
|
+
export default swaggerHandler;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## JSDoc Annotations
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
/**
|
|
81
|
+
* @swagger
|
|
82
|
+
* /api/users:
|
|
83
|
+
* post:
|
|
84
|
+
* tags: [Users]
|
|
85
|
+
* summary: Create a user
|
|
86
|
+
* requestBody:
|
|
87
|
+
* required: true
|
|
88
|
+
* content:
|
|
89
|
+
* application/json:
|
|
90
|
+
* schema:
|
|
91
|
+
* type: object
|
|
92
|
+
* required: [email, name]
|
|
93
|
+
* properties:
|
|
94
|
+
* email:
|
|
95
|
+
* type: string
|
|
96
|
+
* format: email
|
|
97
|
+
* name:
|
|
98
|
+
* type: string
|
|
99
|
+
* responses:
|
|
100
|
+
* 201:
|
|
101
|
+
* description: Created
|
|
102
|
+
*/
|
|
103
|
+
export async function POST(req: Request) {
|
|
104
|
+
// handler...
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Best Practices
|
|
109
|
+
- Generate spec from code (not hand-write YAML) to keep it in sync
|
|
110
|
+
- Use `zod-to-openapi` to reuse validation schemas as OpenAPI models
|
|
111
|
+
- Document all error responses, not just success
|
|
112
|
+
- Version the spec URL: `/api/v1/openapi.json`
|
|
113
|
+
|
|
114
|
+
## Resources
|
|
115
|
+
- [OpenAPI Specification](https://spec.openapis.org/oas/v3.0.0)
|
|
116
|
+
- [zod-to-openapi](https://github.com/asteasolutions/zod-to-openapi)
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Pagination & Filtering
|
|
2
|
+
|
|
3
|
+
Techniques for handling large datasets efficiently.
|
|
4
|
+
|
|
5
|
+
## Cursor-Based Pagination
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// More efficient for large datasets
|
|
9
|
+
interface PaginationResult<T> {
|
|
10
|
+
items: T[];
|
|
11
|
+
nextCursor?: string;
|
|
12
|
+
prevCursor?: string;
|
|
13
|
+
hasMore: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function getCursorPaginatedUsers(
|
|
17
|
+
cursor?: string,
|
|
18
|
+
limit: number = 20
|
|
19
|
+
): Promise<PaginationResult<User>> {
|
|
20
|
+
let query = db.users.orderBy('id', 'asc');
|
|
21
|
+
|
|
22
|
+
// Fetch one extra to know if there are more
|
|
23
|
+
const pageSize = limit + 1;
|
|
24
|
+
|
|
25
|
+
if (cursor) {
|
|
26
|
+
// Decode cursor (base64 encoded id)
|
|
27
|
+
const decodedCursor = Buffer.from(cursor, 'base64').toString();
|
|
28
|
+
query = query.where('id', '>', decodedCursor);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const items = await query.limit(pageSize).toArray();
|
|
32
|
+
|
|
33
|
+
const hasMore = items.length > limit;
|
|
34
|
+
const results = items.slice(0, limit);
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
items: results,
|
|
38
|
+
nextCursor: hasMore ? Buffer.from(results[results.length - 1].id).toString('base64') : undefined,
|
|
39
|
+
hasMore
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Offset-Based Pagination
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// Simple but less efficient for large offsets
|
|
48
|
+
async function getOffsetPaginatedUsers(page: number = 1, pageSize: number = 20) {
|
|
49
|
+
const offset = (page - 1) * pageSize;
|
|
50
|
+
|
|
51
|
+
const [items, total] = await Promise.all([
|
|
52
|
+
db.users.offset(offset).limit(pageSize).toArray(),
|
|
53
|
+
db.users.count()
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
items,
|
|
58
|
+
pagination: {
|
|
59
|
+
page,
|
|
60
|
+
pageSize,
|
|
61
|
+
total,
|
|
62
|
+
totalPages: Math.ceil(total / pageSize),
|
|
63
|
+
hasNextPage: page < Math.ceil(total / pageSize),
|
|
64
|
+
hasPrevPage: page > 1
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Filtering
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
interface FilterOptions {
|
|
74
|
+
role?: string;
|
|
75
|
+
status?: string;
|
|
76
|
+
createdAfter?: Date;
|
|
77
|
+
createdBefore?: Date;
|
|
78
|
+
search?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function filterUsers(filters: FilterOptions, limit: number = 20) {
|
|
82
|
+
let query = db.users;
|
|
83
|
+
|
|
84
|
+
if (filters.role) {
|
|
85
|
+
query = query.where('role', filters.role);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (filters.status) {
|
|
89
|
+
query = query.where('status', filters.status);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (filters.createdAfter) {
|
|
93
|
+
query = query.where('createdAt', '>=', filters.createdAfter);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (filters.createdBefore) {
|
|
97
|
+
query = query.where('createdAt', '<=', filters.createdBefore);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (filters.search) {
|
|
101
|
+
query = query.whereRaw('CONCAT(firstName, lastName) LIKE ?', [`%${filters.search}%`]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return await query.limit(limit).toArray();
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Sorting
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
type SortOrder = 'asc' | 'desc';
|
|
112
|
+
|
|
113
|
+
interface SortOption {
|
|
114
|
+
field: string;
|
|
115
|
+
order: SortOrder;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function getSortedUsers(sort: SortOption, limit: number = 20) {
|
|
119
|
+
// Whitelist allowed sort fields
|
|
120
|
+
const allowedFields = ['id', 'name', 'email', 'createdAt'];
|
|
121
|
+
|
|
122
|
+
if (!allowedFields.includes(sort.field)) {
|
|
123
|
+
throw new Error(`Invalid sort field: ${sort.field}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return await db.users
|
|
127
|
+
.orderBy(sort.field, sort.order)
|
|
128
|
+
.limit(limit)
|
|
129
|
+
.toArray();
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Combined Filtering, Sorting, Pagination
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface QueryOptions {
|
|
137
|
+
page?: number;
|
|
138
|
+
limit?: number;
|
|
139
|
+
sortBy?: string;
|
|
140
|
+
order?: 'asc' | 'desc';
|
|
141
|
+
role?: string;
|
|
142
|
+
status?: string;
|
|
143
|
+
search?: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function queryUsers(options: QueryOptions) {
|
|
147
|
+
let query = db.users;
|
|
148
|
+
|
|
149
|
+
// Apply filters
|
|
150
|
+
if (options.role) {
|
|
151
|
+
query = query.where('role', options.role);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (options.status) {
|
|
155
|
+
query = query.where('status', options.status);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (options.search) {
|
|
159
|
+
query = query.whereRaw(
|
|
160
|
+
'CONCAT(firstName, lastName) LIKE ?',
|
|
161
|
+
[`%${options.search}%`]
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Apply sorting
|
|
166
|
+
const sortBy = options.sortBy || 'createdAt';
|
|
167
|
+
const order = options.order || 'desc';
|
|
168
|
+
query = query.orderBy(sortBy, order);
|
|
169
|
+
|
|
170
|
+
// Apply pagination
|
|
171
|
+
const page = options.page || 1;
|
|
172
|
+
const limit = Math.min(options.limit || 20, 100); // Max 100 items
|
|
173
|
+
const offset = (page - 1) * limit;
|
|
174
|
+
|
|
175
|
+
const [items, total] = await Promise.all([
|
|
176
|
+
query.offset(offset).limit(limit).toArray(),
|
|
177
|
+
query.count()
|
|
178
|
+
]);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
data: items,
|
|
182
|
+
meta: {
|
|
183
|
+
page,
|
|
184
|
+
limit,
|
|
185
|
+
total,
|
|
186
|
+
pages: Math.ceil(total / limit)
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Search Implementation
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// Full-text search
|
|
196
|
+
async function searchUsers(query: string) {
|
|
197
|
+
// MySQL FULLTEXT search
|
|
198
|
+
return await db.users
|
|
199
|
+
.whereRaw(
|
|
200
|
+
'MATCH(firstName, lastName, email) AGAINST(? IN BOOLEAN MODE)',
|
|
201
|
+
[query]
|
|
202
|
+
)
|
|
203
|
+
.toArray();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Elasticsearch integration
|
|
207
|
+
import { Client } from '@elastic/elasticsearch';
|
|
208
|
+
|
|
209
|
+
const client = new Client({ node: 'http://localhost:9200' });
|
|
210
|
+
|
|
211
|
+
async function searchUsersES(query: string) {
|
|
212
|
+
const response = await client.search({
|
|
213
|
+
index: 'users',
|
|
214
|
+
body: {
|
|
215
|
+
query: {
|
|
216
|
+
multi_match: {
|
|
217
|
+
query,
|
|
218
|
+
fields: ['firstName', 'lastName', 'email']
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
return response.body.hits.hits;
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Best Practices
|
|
229
|
+
|
|
230
|
+
✅ **Cursor pagination** - For large datasets
|
|
231
|
+
✅ **Limit results** - Cap maximum page size
|
|
232
|
+
✅ **Index columns** - For fast filtering/sorting
|
|
233
|
+
✅ **Whitelist fields** - Prevent injection
|
|
234
|
+
✅ **Cache frequently used** - Popular filters/sorts
|
|
235
|
+
|
|
236
|
+
## Resources
|
|
237
|
+
|
|
238
|
+
- [Pagination Patterns](https://slack.engineering/a-method-for-pagination/)
|
|
239
|
+
- [Elasticsearch Documentation](https://www.elastic.co/guide/index.html)
|