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,81 @@
|
|
|
1
|
+
# Multi-Tenancy
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Multi-tenancy serves multiple organizations from a single application with isolated data.
|
|
5
|
+
|
|
6
|
+
## Strategies
|
|
7
|
+
| Strategy | Isolation | Complexity | Cost |
|
|
8
|
+
|----------|-----------|------------|------|
|
|
9
|
+
| Row-level (shared DB) | Low | Low | Low |
|
|
10
|
+
| Schema-per-tenant | Medium | Medium | Medium |
|
|
11
|
+
| Database-per-tenant | High | High | High |
|
|
12
|
+
|
|
13
|
+
## Row-Level Isolation (Most Common)
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// Every query scoped by tenantId
|
|
17
|
+
const posts = await prisma.post.findMany({
|
|
18
|
+
where: { tenantId: req.tenant.id },
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Middleware to inject tenant into every request
|
|
22
|
+
export async function tenantMiddleware(req: Request, res: Response, next: NextFunction) {
|
|
23
|
+
const subdomain = req.hostname.split('.')[0];
|
|
24
|
+
const tenant = await prisma.tenant.findUnique({ where: { subdomain } });
|
|
25
|
+
if (!tenant) return res.status(404).json({ error: 'Tenant not found' });
|
|
26
|
+
req.tenant = tenant;
|
|
27
|
+
next();
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Prisma Extension for Automatic Tenant Scoping
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { PrismaClient } from '@prisma/client';
|
|
35
|
+
|
|
36
|
+
export function createTenantClient(tenantId: string) {
|
|
37
|
+
return new PrismaClient().$extends({
|
|
38
|
+
query: {
|
|
39
|
+
$allModels: {
|
|
40
|
+
async findMany({ args, query }) {
|
|
41
|
+
args.where = { ...args.where, tenantId };
|
|
42
|
+
return query(args);
|
|
43
|
+
},
|
|
44
|
+
async create({ args, query }) {
|
|
45
|
+
args.data = { ...args.data, tenantId };
|
|
46
|
+
return query(args);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Usage
|
|
54
|
+
const db = createTenantClient(req.tenant.id);
|
|
55
|
+
const users = await db.user.findMany(); // automatically scoped
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Tenant Resolution from Subdomain
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// middleware.ts (Next.js)
|
|
62
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
63
|
+
|
|
64
|
+
export function middleware(req: NextRequest) {
|
|
65
|
+
const hostname = req.headers.get('host') ?? '';
|
|
66
|
+
const subdomain = hostname.replace(`.${process.env.ROOT_DOMAIN}`, '');
|
|
67
|
+
|
|
68
|
+
if (subdomain && subdomain !== www) {
|
|
69
|
+
return NextResponse.rewrite(new URL(`/t/${subdomain}${req.nextUrl.pathname}`, req.url));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Best Practices
|
|
75
|
+
- Add `tenantId` index on every multi-tenant table
|
|
76
|
+
- Validate tenant access on every query (defense in depth)
|
|
77
|
+
- Use Prisma extensions or middleware to enforce scoping automatically
|
|
78
|
+
- Rate limit per tenant to prevent noisy-neighbor problems
|
|
79
|
+
|
|
80
|
+
## Resources
|
|
81
|
+
- [Prisma multi-tenancy guide](https://www.prisma.io/docs/guides/other/multi-tenancy)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Serverless Patterns
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Design patterns for building reliable serverless applications on AWS Lambda, Vercel, and Cloudflare.
|
|
5
|
+
|
|
6
|
+
## Lambda Handler Pattern
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
|
10
|
+
|
|
11
|
+
// Initialize once outside handler
|
|
12
|
+
const db = DynamoDBDocumentClient.from(new DynamoDBClient({}));
|
|
13
|
+
|
|
14
|
+
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
|
15
|
+
try {
|
|
16
|
+
const body = event.body ? JSON.parse(event.body) : {};
|
|
17
|
+
const result = await processRequest(body, db);
|
|
18
|
+
return { statusCode: 200, body: JSON.stringify(result) };
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error('Handler error:', error);
|
|
21
|
+
return { statusCode: 500, body: JSON.stringify({ error: 'Internal server error' }) };
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## SQS Queue Consumer
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { SQSEvent } from 'aws-lambda';
|
|
30
|
+
|
|
31
|
+
export const handler = async (event: SQSEvent): Promise<void> => {
|
|
32
|
+
for (const record of event.Records) {
|
|
33
|
+
try {
|
|
34
|
+
const message = JSON.parse(record.body);
|
|
35
|
+
await processMessage(message);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('Failed to process message:', record.messageId, error);
|
|
38
|
+
// Throw to move to DLQ after max retries
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Vercel Edge Function
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// app/api/edge/route.ts
|
|
49
|
+
export const runtime = 'edge';
|
|
50
|
+
|
|
51
|
+
export async function GET(req: Request) {
|
|
52
|
+
const country = req.headers.get('x-vercel-ip-country') ?? 'US';
|
|
53
|
+
const { searchParams } = new URL(req.url);
|
|
54
|
+
return Response.json({ country, q: searchParams.get('q') });
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Cloudflare Durable Objects (Stateful Serverless)
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
export class Counter implements DurableObject {
|
|
62
|
+
private count = 0;
|
|
63
|
+
constructor(state: DurableObjectState) {
|
|
64
|
+
state.blockConcurrencyWhile(async () => {
|
|
65
|
+
this.count = (await state.storage.get<number>('count')) ?? 0;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async fetch(req: Request) {
|
|
70
|
+
this.count++;
|
|
71
|
+
await (this as any).state.storage.put('count', this.count);
|
|
72
|
+
return Response.json({ count: this.count });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Best Practices
|
|
78
|
+
- Initialize clients outside handler (reused on warm invocations)
|
|
79
|
+
- Use SQS/EventBridge for async processing — don't block the function
|
|
80
|
+
- Implement idempotency — Lambda can execute twice on retry
|
|
81
|
+
- Set function timeout to 10-30s maximum; use queues for longer work
|
|
82
|
+
- Use Lambda Layers for large shared dependencies
|
|
83
|
+
|
|
84
|
+
## Resources
|
|
85
|
+
- [AWS Lambda best practices](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html)
|
|
86
|
+
- [Serverless Land patterns](https://serverlessland.com/patterns)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Clerk Authentication
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Clerk provides drop-in auth with React components, Next.js middleware, and a full user management dashboard.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @clerk/nextjs
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```env
|
|
13
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
|
|
14
|
+
CLERK_SECRET_KEY=sk_test_...
|
|
15
|
+
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
|
16
|
+
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
|
17
|
+
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Middleware
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// middleware.ts
|
|
24
|
+
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
|
|
25
|
+
|
|
26
|
+
const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)', '/api/webhooks(.*)']);
|
|
27
|
+
|
|
28
|
+
export default clerkMiddleware(async (auth, req) => {
|
|
29
|
+
if (!isPublicRoute(req)) await auth.protect();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const config = { matcher: ['/((?!.*\..*|_next).*)', '/', '/(api|trpc)(.*)'] };
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Root Layout
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
// app/layout.tsx
|
|
39
|
+
import { ClerkProvider } from '@clerk/nextjs';
|
|
40
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
41
|
+
return <ClerkProvider><html lang="en"><body>{children}</body></html></ClerkProvider>;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Navbar with Auth Buttons
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { SignInButton, SignedIn, SignedOut, UserButton } from '@clerk/nextjs';
|
|
49
|
+
|
|
50
|
+
export function Navbar() {
|
|
51
|
+
return (
|
|
52
|
+
<nav>
|
|
53
|
+
<SignedOut><SignInButton mode="modal" /></SignedOut>
|
|
54
|
+
<SignedIn><UserButton afterSignOutUrl="/" /></SignedIn>
|
|
55
|
+
</nav>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Server Component Auth
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { auth, currentUser } from '@clerk/nextjs/server';
|
|
64
|
+
import { redirect } from 'next/navigation';
|
|
65
|
+
|
|
66
|
+
export default async function Dashboard() {
|
|
67
|
+
const { userId } = await auth();
|
|
68
|
+
if (!userId) redirect('/sign-in');
|
|
69
|
+
const user = await currentUser();
|
|
70
|
+
return <h1>Welcome, {user?.firstName}</h1>;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Sync to Database via Webhooks
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// app/api/webhooks/clerk/route.ts
|
|
78
|
+
import { Webhook } from 'svix';
|
|
79
|
+
import { WebhookEvent } from '@clerk/nextjs/server';
|
|
80
|
+
|
|
81
|
+
export async function POST(req: Request) {
|
|
82
|
+
const wh = new Webhook(process.env.CLERK_WEBHOOK_SECRET!);
|
|
83
|
+
const payload = await req.text();
|
|
84
|
+
const headers = Object.fromEntries(['svix-id','svix-timestamp','svix-signature'].map(h => [h, req.headers.get(h)!]));
|
|
85
|
+
const evt = wh.verify(payload, headers) as WebhookEvent;
|
|
86
|
+
|
|
87
|
+
if (evt.type === 'user.created') {
|
|
88
|
+
await prisma.user.create({
|
|
89
|
+
data: { clerkId: evt.data.id, email: evt.data.email_addresses[0].email_address }
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return Response.json({ received: true });
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Resources
|
|
97
|
+
- [Clerk Next.js quickstart](https://clerk.com/docs/quickstarts/nextjs)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# JWT (JSON Web Tokens)
|
|
2
|
+
|
|
3
|
+
Stateless authentication using digitally signed tokens.
|
|
4
|
+
|
|
5
|
+
## Token Structure
|
|
6
|
+
|
|
7
|
+
JWTs consist of 3 parts separated by dots: `header.payload.signature`
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
|
|
11
|
+
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
|
|
12
|
+
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Header
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"alg": "HS256",
|
|
19
|
+
"typ": "JWT"
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Payload
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"sub": "1234567890",
|
|
27
|
+
"name": "John Doe",
|
|
28
|
+
"iat": 1516239022,
|
|
29
|
+
"exp": 1516242622,
|
|
30
|
+
"roles": ["user", "admin"]
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Signature
|
|
35
|
+
```
|
|
36
|
+
HMACSHA256(
|
|
37
|
+
base64UrlEncode(header) + "." +
|
|
38
|
+
base64UrlEncode(payload),
|
|
39
|
+
secret
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Implementation (Node.js + Express)
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import jwt from 'jsonwebtoken';
|
|
47
|
+
|
|
48
|
+
const SECRET = process.env.JWT_SECRET!;
|
|
49
|
+
|
|
50
|
+
// Create token
|
|
51
|
+
function createToken(userId: string): string {
|
|
52
|
+
return jwt.sign(
|
|
53
|
+
{ sub: userId, role: 'user' },
|
|
54
|
+
SECRET,
|
|
55
|
+
{ expiresIn: '24h' }
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Verify token (middleware)
|
|
60
|
+
function verifyToken(token: string) {
|
|
61
|
+
try {
|
|
62
|
+
return jwt.verify(token, SECRET);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
throw new Error('Invalid token');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Express middleware
|
|
69
|
+
function authMiddleware(req, res, next) {
|
|
70
|
+
const token = req.headers.authorization?.split(' ')[1];
|
|
71
|
+
if (!token) return res.status(401).json({ error: 'No token' });
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
req.user = jwt.verify(token, SECRET);
|
|
75
|
+
next();
|
|
76
|
+
} catch (err) {
|
|
77
|
+
res.status(401).json({ error: 'Invalid token' });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Route
|
|
82
|
+
app.get('/profile', authMiddleware, (req, res) => {
|
|
83
|
+
res.json({ user_id: req.user.sub });
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Refresh Tokens
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Issue refresh token with longer expiry
|
|
91
|
+
const refreshToken = jwt.sign(
|
|
92
|
+
{ sub: userId },
|
|
93
|
+
REFRESH_SECRET,
|
|
94
|
+
{ expiresIn: '7d' }
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// Use refresh token to get new access token
|
|
98
|
+
app.post('/refresh', (req, res) => {
|
|
99
|
+
const { refreshToken } = req.body;
|
|
100
|
+
try {
|
|
101
|
+
const decoded = jwt.verify(refreshToken, REFRESH_SECRET);
|
|
102
|
+
const newAccessToken = jwt.sign(
|
|
103
|
+
{ sub: decoded.sub },
|
|
104
|
+
SECRET,
|
|
105
|
+
{ expiresIn: '1h' }
|
|
106
|
+
);
|
|
107
|
+
res.json({ accessToken: newAccessToken });
|
|
108
|
+
} catch (err) {
|
|
109
|
+
res.status(401).json({ error: 'Invalid refresh token' });
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Best Practices
|
|
115
|
+
|
|
116
|
+
1. **Sign with strong secret**: Use environment variable, min 32 characters
|
|
117
|
+
2. **Short expiry**: 15min - 1hr for access tokens
|
|
118
|
+
3. **Refresh tokens**: Separate longer-lived tokens for token refresh
|
|
119
|
+
4. **Always HTTPS**: Never transmit JWT over unencrypted connection
|
|
120
|
+
5. **HttpOnly cookies**: Store tokens in httpOnly cookies if possible
|
|
121
|
+
6. **Validate claims**: Check exp, iat, and custom claims
|
|
122
|
+
7. **Revocation**: Maintain blacklist of invalidated tokens
|
|
123
|
+
8. **RSA for microservices**: Use asymmetric crypto for inter-service auth
|
|
124
|
+
|
|
125
|
+
## Claims (Standard)
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"iss": "issuer",
|
|
130
|
+
"sub": "subject (usually user ID)",
|
|
131
|
+
"aud": "audience",
|
|
132
|
+
"exp": 1516242622,
|
|
133
|
+
"nbf": 1516239022,
|
|
134
|
+
"iat": 1516239022,
|
|
135
|
+
"jti": "unique token ID"
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Resources
|
|
140
|
+
|
|
141
|
+
- [JWT.io](https://jwt.io/)
|
|
142
|
+
- [RFC 7519 - JSON Web Token](https://tools.ietf.org/html/rfc7519)
|
|
143
|
+
- [jsonwebtoken npm](https://www.npmjs.com/package/jsonwebtoken)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Lucia Auth
|
|
2
|
+
|
|
3
|
+
Simple and flexible authentication library for SvelteKit, Astro, and other frameworks.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install lucia @lucia-auth/adapter-prisma
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Prisma Schema
|
|
12
|
+
|
|
13
|
+
```prisma
|
|
14
|
+
model User {
|
|
15
|
+
id String @id @unique
|
|
16
|
+
primary_email String
|
|
17
|
+
created_at DateTime @default(now())
|
|
18
|
+
|
|
19
|
+
auth_session AuthSession[]
|
|
20
|
+
auth_key AuthKey[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
model AuthSession {
|
|
24
|
+
id String @id @unique
|
|
25
|
+
user_id String @unique
|
|
26
|
+
user User @relation(references: [id], fields: [user_id], onDelete: Cascade)
|
|
27
|
+
active_expires BigInt
|
|
28
|
+
idle_expires BigInt
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
model AuthKey {
|
|
32
|
+
id String @id @unique
|
|
33
|
+
hashed_password String?
|
|
34
|
+
user_id String
|
|
35
|
+
user User @relation(references: [id], fields: [user_id], onDelete: Cascade)
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Lucia Configuration
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import lucia from 'lucia';
|
|
43
|
+
import { sveltekit } from 'lucia/middleware';
|
|
44
|
+
import { prisma } from '@lucia-auth/adapter-prisma';
|
|
45
|
+
import { dev } from '$app/environment';
|
|
46
|
+
|
|
47
|
+
export const auth = lucia({
|
|
48
|
+
env: dev ? 'DEV' : 'PROD',
|
|
49
|
+
middleware: sveltekit(),
|
|
50
|
+
adapter: prisma(db),
|
|
51
|
+
getUserAttributes: (data) => {
|
|
52
|
+
return { email: data.primary_email };
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Login/Signup
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Sign up
|
|
61
|
+
const user = await auth.createUser({
|
|
62
|
+
key: {
|
|
63
|
+
providerId: 'email',
|
|
64
|
+
providerUserId: email,
|
|
65
|
+
password: hashedPassword
|
|
66
|
+
},
|
|
67
|
+
attributes: { primary_email: email }
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Create session
|
|
71
|
+
const session = await auth.createSession({ userId: user.userId });
|
|
72
|
+
|
|
73
|
+
// Login
|
|
74
|
+
const key = await auth.useKey('email', email, password);
|
|
75
|
+
const session = await auth.createSession({ userId: key.userId });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Session Management
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// Get session
|
|
82
|
+
const { session, user } = await auth.validateSession(sessionId);
|
|
83
|
+
|
|
84
|
+
// Invalidate session
|
|
85
|
+
await auth.invalidateSession(sessionId);
|
|
86
|
+
|
|
87
|
+
// Update session
|
|
88
|
+
await auth.updateUserAttributes(userId, { primary_email: newEmail });
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Resources
|
|
92
|
+
|
|
93
|
+
- [Lucia Docs](https://lucia-auth.com/)
|