vibecarbon 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +663 -0
- package/README.md +188 -0
- package/carbon/.claude/hooks/task-completed-gate.sh +19 -0
- package/carbon/.claude/hooks/teammate-idle-gate.sh +29 -0
- package/carbon/.claude/settings.json +29 -0
- package/carbon/.cursor/rules/vibecarbon.mdc +6 -0
- package/carbon/.dockerignore +57 -0
- package/carbon/.env.example +219 -0
- package/carbon/.github/copilot-instructions.md +3 -0
- package/carbon/.github/workflows/deploy.yml +346 -0
- package/carbon/.github/workflows/vibecarbon-build.yml +81 -0
- package/carbon/.windsurfrules +74 -0
- package/carbon/AGENTS.md +422 -0
- package/carbon/CLAUDE.md +3 -0
- package/carbon/DEVELOPMENT.md +187 -0
- package/carbon/Dockerfile +98 -0
- package/carbon/LICENSE +21 -0
- package/carbon/PRODUCTION.md +364 -0
- package/carbon/README.md +193 -0
- package/carbon/TESTING.md +138 -0
- package/carbon/backup/Dockerfile +75 -0
- package/carbon/backup/backup.sh +95 -0
- package/carbon/backup/compose-backup.sh +140 -0
- package/carbon/biome.json +83 -0
- package/carbon/cloud-init/docker-ce-setup.yaml +55 -0
- package/carbon/cloud-init/k3s/master-init.sh +215 -0
- package/carbon/cloud-init/k3s/supabase-init.sh +167 -0
- package/carbon/cloud-init/k3s/worker-init.sh +147 -0
- package/carbon/components.json +24 -0
- package/carbon/content/blog/authentication-guide.mdx +34 -0
- package/carbon/content/blog/getting-started.mdx +41 -0
- package/carbon/content/changelog/v0-1-0.mdx +40 -0
- package/carbon/content/docs/analytics.mdx +90 -0
- package/carbon/content/docs/authentication.mdx +231 -0
- package/carbon/content/docs/background-jobs.mdx +116 -0
- package/carbon/content/docs/cli.mdx +630 -0
- package/carbon/content/docs/database.mdx +236 -0
- package/carbon/content/docs/deployment.mdx +227 -0
- package/carbon/content/docs/development.mdx +238 -0
- package/carbon/content/docs/environments.mdx +84 -0
- package/carbon/content/docs/getting-started.mdx +112 -0
- package/carbon/content/docs/legal/privacy-policy.mdx +89 -0
- package/carbon/content/docs/legal/terms-of-service.mdx +99 -0
- package/carbon/content/docs/optional-services.mdx +160 -0
- package/carbon/db/Dockerfile +23 -0
- package/carbon/docker-compose.dev-init.yml +5 -0
- package/carbon/docker-compose.metabase.override.yml +14 -0
- package/carbon/docker-compose.metabase.prod.yml +28 -0
- package/carbon/docker-compose.metabase.yml +84 -0
- package/carbon/docker-compose.n8n.override.yml +14 -0
- package/carbon/docker-compose.n8n.prod.yml +31 -0
- package/carbon/docker-compose.n8n.yml +97 -0
- package/carbon/docker-compose.observability.override.yml +18 -0
- package/carbon/docker-compose.observability.prod.yml +28 -0
- package/carbon/docker-compose.observability.yml +125 -0
- package/carbon/docker-compose.override.yml +28 -0
- package/carbon/docker-compose.prod.yml +294 -0
- package/carbon/docker-compose.yml +508 -0
- package/carbon/docker-entrypoint.sh +12 -0
- package/carbon/ha/activate-standby.sh +52 -0
- package/carbon/ha/primary-init.sql +36 -0
- package/carbon/ha/standby-init.sh +74 -0
- package/carbon/k8s/LICENSE +99 -0
- package/carbon/k8s/README.md +272 -0
- package/carbon/k8s/base/app/deployment.yaml +130 -0
- package/carbon/k8s/base/app/hpa.yaml +44 -0
- package/carbon/k8s/base/app/kustomization.yaml +10 -0
- package/carbon/k8s/base/app/network-policy.yaml +124 -0
- package/carbon/k8s/base/app/pdb.yaml +14 -0
- package/carbon/k8s/base/app/rbac.yaml +36 -0
- package/carbon/k8s/base/app/service.yaml +16 -0
- package/carbon/k8s/base/backup/cronjob.yaml +120 -0
- package/carbon/k8s/base/backup/kustomization.yaml +7 -0
- package/carbon/k8s/base/backup/network-policy.yaml +31 -0
- package/carbon/k8s/base/backup/rbac.yaml +7 -0
- package/carbon/k8s/base/cluster-autoscaler/deployment.yaml +103 -0
- package/carbon/k8s/base/cluster-autoscaler/kustomization.yaml +17 -0
- package/carbon/k8s/base/cluster-autoscaler/rbac.yaml +109 -0
- package/carbon/k8s/base/config/configmap.yaml +48 -0
- package/carbon/k8s/base/config/kustomization.yaml +8 -0
- package/carbon/k8s/base/hetzner-ccm/kustomization.yaml +9 -0
- package/carbon/k8s/base/hetzner-csi/kustomization.yaml +9 -0
- package/carbon/k8s/base/kustomization.yaml +43 -0
- package/carbon/k8s/base/namespace.yaml +7 -0
- package/carbon/k8s/base/network-policies.yaml +95 -0
- package/carbon/k8s/base/registry/kustomization.yaml +5 -0
- package/carbon/k8s/base/registry/local-registry.yaml +193 -0
- package/carbon/k8s/base/traefik/certificate.yaml +21 -0
- package/carbon/k8s/base/traefik/configmap.yaml +13 -0
- package/carbon/k8s/base/traefik/deployment.yaml +165 -0
- package/carbon/k8s/base/traefik/ingressroute.yaml +141 -0
- package/carbon/k8s/base/traefik/kustomization.yaml +11 -0
- package/carbon/k8s/base/traefik/middleware.yaml +109 -0
- package/carbon/k8s/base/traefik/network-policy.yaml +92 -0
- package/carbon/k8s/base/traefik/service.yaml +38 -0
- package/carbon/k8s/flux/README.md +49 -0
- package/carbon/k8s/flux/clusters/primary/vibecarbon.yaml +128 -0
- package/carbon/k8s/flux/clusters/standby/vibecarbon.yaml +83 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-release.yaml +38 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-repository.yaml +16 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/kustomization.yaml +10 -0
- package/carbon/k8s/gitops/supabase/helm-release.yaml +66 -0
- package/carbon/k8s/gitops/supabase/helm-repository.yaml +18 -0
- package/carbon/k8s/gitops/supabase/kustomization.yaml +33 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-cloudflare.yaml +51 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-hetzner.yaml +59 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-manual.yaml +43 -0
- package/carbon/k8s/infra/cert-manager-resources/kustomization.yaml +15 -0
- package/carbon/k8s/infra/kustomization.yaml +21 -0
- package/carbon/k8s/infra/traefik-crds/kustomization.yaml +10 -0
- package/carbon/k8s/overlays/local/configmap.yaml +23 -0
- package/carbon/k8s/overlays/local/ingressroute-studio.yaml +104 -0
- package/carbon/k8s/overlays/local/kustomization.yaml +215 -0
- package/carbon/k8s/overlays/local/namespace.yaml +8 -0
- package/carbon/k8s/overlays/local/secrets.yaml +32 -0
- package/carbon/k8s/overlays/production/kustomization.yaml +34 -0
- package/carbon/k8s/test-local.sh +318 -0
- package/carbon/k8s/values/supabase.values.yaml +133 -0
- package/carbon/package.json +154 -0
- package/carbon/runtime.Dockerfile +17 -0
- package/carbon/scripts/_dev-jwt.mjs +45 -0
- package/carbon/scripts/check-rls.ts +53 -0
- package/carbon/scripts/dev-init.js +191 -0
- package/carbon/scripts/dev.js +191 -0
- package/carbon/scripts/docker-down.js +63 -0
- package/carbon/scripts/docker-logs.js +59 -0
- package/carbon/scripts/docker-up.js +222 -0
- package/carbon/scripts/generate-dev-configs.sh +131 -0
- package/carbon/scripts/generate-rss.ts +116 -0
- package/carbon/scripts/generate-sitemap.ts +102 -0
- package/carbon/scripts/k8s-apply.js +71 -0
- package/carbon/scripts/k8s-delete.js +75 -0
- package/carbon/scripts/lib/manifest.js +176 -0
- package/carbon/scripts/secret-scan.mjs +278 -0
- package/carbon/scripts/validate-dev-configs.sh +101 -0
- package/carbon/src/client/App.tsx +202 -0
- package/carbon/src/client/assets/hyperformant-dark.svg +29 -0
- package/carbon/src/client/assets/hyperformant-light.svg +29 -0
- package/carbon/src/client/assets/logos/aider.svg +1 -0
- package/carbon/src/client/assets/logos/antigravity.svg +1 -0
- package/carbon/src/client/assets/logos/bolt.svg +1 -0
- package/carbon/src/client/assets/logos/claude-code.svg +1 -0
- package/carbon/src/client/assets/logos/copilot.svg +1 -0
- package/carbon/src/client/assets/logos/cursor.svg +1 -0
- package/carbon/src/client/assets/logos/gemini-cli.svg +1 -0
- package/carbon/src/client/assets/logos/lovable.svg +1 -0
- package/carbon/src/client/assets/logos/openai-codex.svg +1 -0
- package/carbon/src/client/assets/logos/v0.svg +1 -0
- package/carbon/src/client/assets/logos/windsurf.svg +1 -0
- package/carbon/src/client/assets/vibecarbon-icon.svg +19 -0
- package/carbon/src/client/assets/vibecarbon-logo-dark.svg +29 -0
- package/carbon/src/client/assets/vibecarbon-logo-light.svg +29 -0
- package/carbon/src/client/components/AIIntegrationSection.tsx +120 -0
- package/carbon/src/client/components/AppSidebar.tsx +760 -0
- package/carbon/src/client/components/ArchitectureSection.tsx +46 -0
- package/carbon/src/client/components/CTAFooter.tsx +59 -0
- package/carbon/src/client/components/ComparisonSection.tsx +132 -0
- package/carbon/src/client/components/ContentPanel.tsx +66 -0
- package/carbon/src/client/components/ContentSkeleton.tsx +21 -0
- package/carbon/src/client/components/ErrorBoundary.tsx +46 -0
- package/carbon/src/client/components/FAQSection.tsx +76 -0
- package/carbon/src/client/components/FileUpload.tsx +210 -0
- package/carbon/src/client/components/HeaderActions.tsx +17 -0
- package/carbon/src/client/components/Hero.tsx +608 -0
- package/carbon/src/client/components/ImpersonationBanner.tsx +31 -0
- package/carbon/src/client/components/LanguageSwitcher.tsx +67 -0
- package/carbon/src/client/components/Logo.tsx +87 -0
- package/carbon/src/client/components/LogoStrip.tsx +76 -0
- package/carbon/src/client/components/MetricsStrip.tsx +48 -0
- package/carbon/src/client/components/Nav.tsx +195 -0
- package/carbon/src/client/components/NewsletterSignup.tsx +147 -0
- package/carbon/src/client/components/NotificationDrawer.tsx +171 -0
- package/carbon/src/client/components/PageHeader.tsx +24 -0
- package/carbon/src/client/components/PlanGate.tsx +36 -0
- package/carbon/src/client/components/PricingSection.tsx +371 -0
- package/carbon/src/client/components/SEO.tsx +34 -0
- package/carbon/src/client/components/SmoothScroll.tsx +45 -0
- package/carbon/src/client/components/TechStackSection.tsx +165 -0
- package/carbon/src/client/components/WorkflowSection.tsx +604 -0
- package/carbon/src/client/components/admin/DockerLogs.tsx +276 -0
- package/carbon/src/client/components/admin/PerformanceMetrics.tsx +230 -0
- package/carbon/src/client/components/admin/ServiceCard.tsx +45 -0
- package/carbon/src/client/components/admin/ServicesStatus.tsx +296 -0
- package/carbon/src/client/components/architecture/ArchitectureDiagram.tsx +413 -0
- package/carbon/src/client/components/auth/AuthProvider.tsx +466 -0
- package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +35 -0
- package/carbon/src/client/components/effects/FresnelEdge.tsx +49 -0
- package/carbon/src/client/components/effects/GlowTracker.tsx +46 -0
- package/carbon/src/client/components/effects/SparkBurst.tsx +145 -0
- package/carbon/src/client/components/effects/VGlowEffect.tsx +83 -0
- package/carbon/src/client/components/effects/index.ts +2 -0
- package/carbon/src/client/components/layouts/SidebarLayout.tsx +20 -0
- package/carbon/src/client/components/scroll/ScrollSection.tsx +76 -0
- package/carbon/src/client/components/scroll/ScrollytellingProvider.tsx +81 -0
- package/carbon/src/client/components/scroll/index.ts +2 -0
- package/carbon/src/client/components/ui/accordion.tsx +71 -0
- package/carbon/src/client/components/ui/alert-dialog.tsx +162 -0
- package/carbon/src/client/components/ui/alert.tsx +73 -0
- package/carbon/src/client/components/ui/aspect-ratio.tsx +22 -0
- package/carbon/src/client/components/ui/avatar.tsx +91 -0
- package/carbon/src/client/components/ui/badge.tsx +50 -0
- package/carbon/src/client/components/ui/breadcrumb.tsx +100 -0
- package/carbon/src/client/components/ui/button-group.tsx +78 -0
- package/carbon/src/client/components/ui/button.tsx +120 -0
- package/carbon/src/client/components/ui/calendar.tsx +182 -0
- package/carbon/src/client/components/ui/card.tsx +85 -0
- package/carbon/src/client/components/ui/carousel.tsx +227 -0
- package/carbon/src/client/components/ui/chart.tsx +357 -0
- package/carbon/src/client/components/ui/checkbox.tsx +27 -0
- package/carbon/src/client/components/ui/collapsible.tsx +15 -0
- package/carbon/src/client/components/ui/command.tsx +178 -0
- package/carbon/src/client/components/ui/context-menu.tsx +233 -0
- package/carbon/src/client/components/ui/dialog.tsx +132 -0
- package/carbon/src/client/components/ui/drawer.tsx +118 -0
- package/carbon/src/client/components/ui/dropdown-menu.tsx +242 -0
- package/carbon/src/client/components/ui/empty.tsx +94 -0
- package/carbon/src/client/components/ui/field.tsx +226 -0
- package/carbon/src/client/components/ui/hover-card.tsx +44 -0
- package/carbon/src/client/components/ui/input-group.tsx +146 -0
- package/carbon/src/client/components/ui/input-otp.tsx +83 -0
- package/carbon/src/client/components/ui/input.tsx +20 -0
- package/carbon/src/client/components/ui/item.tsx +188 -0
- package/carbon/src/client/components/ui/kbd.tsx +26 -0
- package/carbon/src/client/components/ui/label.tsx +21 -0
- package/carbon/src/client/components/ui/menubar.tsx +250 -0
- package/carbon/src/client/components/ui/navigation-menu.tsx +155 -0
- package/carbon/src/client/components/ui/pagination.tsx +102 -0
- package/carbon/src/client/components/ui/popover.tsx +75 -0
- package/carbon/src/client/components/ui/progress.tsx +66 -0
- package/carbon/src/client/components/ui/radio-group.tsx +36 -0
- package/carbon/src/client/components/ui/resizable.tsx +46 -0
- package/carbon/src/client/components/ui/scroll-area.tsx +48 -0
- package/carbon/src/client/components/ui/select.tsx +186 -0
- package/carbon/src/client/components/ui/separator.tsx +21 -0
- package/carbon/src/client/components/ui/sheet.tsx +124 -0
- package/carbon/src/client/components/ui/sidebar.tsx +702 -0
- package/carbon/src/client/components/ui/skeleton.tsx +13 -0
- package/carbon/src/client/components/ui/slider.tsx +57 -0
- package/carbon/src/client/components/ui/sonner.tsx +45 -0
- package/carbon/src/client/components/ui/spinner.tsx +15 -0
- package/carbon/src/client/components/ui/switch.tsx +30 -0
- package/carbon/src/client/components/ui/table.tsx +89 -0
- package/carbon/src/client/components/ui/tabs.tsx +73 -0
- package/carbon/src/client/components/ui/textarea.tsx +18 -0
- package/carbon/src/client/components/ui/toggle-group.tsx +87 -0
- package/carbon/src/client/components/ui/toggle.tsx +44 -0
- package/carbon/src/client/components/ui/tooltip.tsx +56 -0
- package/carbon/src/client/hooks/api/index.ts +14 -0
- package/carbon/src/client/hooks/api/useAuthSettings.ts +80 -0
- package/carbon/src/client/hooks/api/useSubscription.ts +87 -0
- package/carbon/src/client/hooks/use-mobile.ts +21 -0
- package/carbon/src/client/hooks/useMousePosition.ts +91 -0
- package/carbon/src/client/hooks/useNotifications.tsx +124 -0
- package/carbon/src/client/hooks/useOrganizationMembers.ts +127 -0
- package/carbon/src/client/hooks/useOrganizations.tsx +230 -0
- package/carbon/src/client/hooks/usePackageManager.ts +69 -0
- package/carbon/src/client/hooks/useReducedMotion.ts +20 -0
- package/carbon/src/client/hooks/useRunningServices.ts +114 -0
- package/carbon/src/client/hooks/useScrollProgress.ts +56 -0
- package/carbon/src/client/index.css +467 -0
- package/carbon/src/client/index.html +56 -0
- package/carbon/src/client/lib/admin-services.ts +151 -0
- package/carbon/src/client/lib/api.ts +32 -0
- package/carbon/src/client/lib/blog.ts +35 -0
- package/carbon/src/client/lib/changelog.ts +33 -0
- package/carbon/src/client/lib/docs-search.ts +101 -0
- package/carbon/src/client/lib/docs.ts +37 -0
- package/carbon/src/client/lib/i18n.ts +32 -0
- package/carbon/src/client/lib/supabase.ts +72 -0
- package/carbon/src/client/lib/tailwind-colors.ts +357 -0
- package/carbon/src/client/lib/theme.ts +117 -0
- package/carbon/src/client/lib/utils.ts +22 -0
- package/carbon/src/client/locales/de.json +529 -0
- package/carbon/src/client/locales/en.json +461 -0
- package/carbon/src/client/locales/es.json +529 -0
- package/carbon/src/client/locales/fr.json +529 -0
- package/carbon/src/client/locales/pt.json +529 -0
- package/carbon/src/client/main.tsx +56 -0
- package/carbon/src/client/mdx.d.ts +13 -0
- package/carbon/src/client/pages/ApiDocs.tsx +76 -0
- package/carbon/src/client/pages/AuthCallback.tsx +34 -0
- package/carbon/src/client/pages/Blog.tsx +167 -0
- package/carbon/src/client/pages/Changelog.tsx +171 -0
- package/carbon/src/client/pages/Charts.tsx +388 -0
- package/carbon/src/client/pages/Checkout.tsx +227 -0
- package/carbon/src/client/pages/Contact.tsx +174 -0
- package/carbon/src/client/pages/Dashboard.tsx +368 -0
- package/carbon/src/client/pages/Docs.tsx +372 -0
- package/carbon/src/client/pages/ForgotPassword.tsx +111 -0
- package/carbon/src/client/pages/Home.tsx +187 -0
- package/carbon/src/client/pages/Legal.tsx +100 -0
- package/carbon/src/client/pages/Login.tsx +408 -0
- package/carbon/src/client/pages/MFAVerify.tsx +156 -0
- package/carbon/src/client/pages/NotFound.tsx +21 -0
- package/carbon/src/client/pages/Onboarding.tsx +246 -0
- package/carbon/src/client/pages/ResetPassword.tsx +200 -0
- package/carbon/src/client/pages/UIComponents.tsx +390 -0
- package/carbon/src/client/pages/admin/ContactSubmissions.tsx +220 -0
- package/carbon/src/client/pages/admin/Dashboard.tsx +24 -0
- package/carbon/src/client/pages/admin/Infrastructure.tsx +257 -0
- package/carbon/src/client/pages/admin/Jobs.tsx +225 -0
- package/carbon/src/client/pages/admin/Logs.tsx +18 -0
- package/carbon/src/client/pages/admin/Newsletter.tsx +300 -0
- package/carbon/src/client/pages/admin/Notifications.tsx +603 -0
- package/carbon/src/client/pages/admin/Organizations.tsx +306 -0
- package/carbon/src/client/pages/admin/Settings.tsx +314 -0
- package/carbon/src/client/pages/admin/Theme.tsx +465 -0
- package/carbon/src/client/pages/admin/Users.tsx +365 -0
- package/carbon/src/client/pages/api-docs.css +156 -0
- package/carbon/src/client/pages/organizations/Details.tsx +200 -0
- package/carbon/src/client/pages/organizations/Members.tsx +402 -0
- package/carbon/src/client/pages/settings/Billing.tsx +473 -0
- package/carbon/src/client/pages/settings/Profile.tsx +160 -0
- package/carbon/src/client/pages/settings/Security.tsx +341 -0
- package/carbon/src/client/public/favicon.svg +19 -0
- package/carbon/src/client/public/robots.txt +8 -0
- package/carbon/src/server/billing/index.ts +104 -0
- package/carbon/src/server/billing/provider.ts +81 -0
- package/carbon/src/server/billing/providers/paddle.ts +314 -0
- package/carbon/src/server/billing/providers/polar.ts +325 -0
- package/carbon/src/server/billing/providers/stripe.ts +233 -0
- package/carbon/src/server/emails/templates.ts +116 -0
- package/carbon/src/server/index.ts +554 -0
- package/carbon/src/server/lib/auth.ts +6 -0
- package/carbon/src/server/lib/email.ts +64 -0
- package/carbon/src/server/lib/env.ts +112 -0
- package/carbon/src/server/lib/errors.ts +21 -0
- package/carbon/src/server/lib/logger.ts +17 -0
- package/carbon/src/server/lib/rate-limiter.ts +288 -0
- package/carbon/src/server/lib/request.ts +34 -0
- package/carbon/src/server/lib/stripe.ts +42 -0
- package/carbon/src/server/lib/supabase.ts +65 -0
- package/carbon/src/server/middleware/requirePlan.ts +80 -0
- package/carbon/src/server/routes/_internal/services-status.ts +958 -0
- package/carbon/src/server/routes/_internal/verify-role.ts +185 -0
- package/carbon/src/server/routes/health.ts +48 -0
- package/carbon/src/server/routes/v1/admin/contact.ts +128 -0
- package/carbon/src/server/routes/v1/admin/jobs.ts +171 -0
- package/carbon/src/server/routes/v1/admin/newsletter.ts +237 -0
- package/carbon/src/server/routes/v1/auth.ts +390 -0
- package/carbon/src/server/routes/v1/billing.ts +718 -0
- package/carbon/src/server/routes/v1/contact.ts +93 -0
- package/carbon/src/server/routes/v1/index.ts +1333 -0
- package/carbon/src/server/routes/v1/newsletter.ts +181 -0
- package/carbon/src/server/routes/v1/performance.ts +157 -0
- package/carbon/src/server/routes/v1/stats.ts +170 -0
- package/carbon/src/server/routes/v1/theme.ts +106 -0
- package/carbon/src/server/routes/webhooks/billing.ts +376 -0
- package/carbon/src/server/routes/webhooks/stripe.ts +276 -0
- package/carbon/src/server/types.ts +11 -0
- package/carbon/src/shared/pricing.ts +155 -0
- package/carbon/src/shared/types.ts +338 -0
- package/carbon/supabase/migrations/00001_init.sql +717 -0
- package/carbon/supabase/migrations/00002_theme_settings.sql +13 -0
- package/carbon/supabase/migrations/00003_pg_cron.sql +121 -0
- package/carbon/supabase/migrations/00004_contact_newsletter.sql +81 -0
- package/carbon/supabase/migrations/00005_localization_languages.sql +22 -0
- package/carbon/supabase/seed.sql +16 -0
- package/carbon/tests/_helpers/app.ts +45 -0
- package/carbon/tests/_helpers/env.ts +37 -0
- package/carbon/tests/_helpers/factories.ts +69 -0
- package/carbon/tests/_helpers/jwt.ts +23 -0
- package/carbon/tests/_helpers/setup-integration.ts +20 -0
- package/carbon/tests/_helpers/setup-rtl.ts +12 -0
- package/carbon/tests/component/ErrorBoundary.test.tsx +53 -0
- package/carbon/tests/component/use-auth-settings.test.tsx +119 -0
- package/carbon/tests/integration/server/routes/contact.test.ts +162 -0
- package/carbon/tests/integration/server/routes/health.test.ts +61 -0
- package/carbon/tests/structural/i18n-parity.test.ts +42 -0
- package/carbon/tests/unit/client/utils.test.ts +49 -0
- package/carbon/tests/unit/shared/pricing.test.ts +93 -0
- package/carbon/tsconfig.json +27 -0
- package/carbon/tsconfig.server.json +27 -0
- package/carbon/tsconfig.test.json +9 -0
- package/carbon/vite.config.ts +110 -0
- package/carbon/vitest.config.ts +74 -0
- package/carbon/volumes/db/jwt.sql +57 -0
- package/carbon/volumes/db/metabase-init.sh +29 -0
- package/carbon/volumes/db/n8n-init.sh +25 -0
- package/carbon/volumes/db/realtime.sql +33 -0
- package/carbon/volumes/db/roles.sql +93 -0
- package/carbon/volumes/db/set-passwords.sh +12 -0
- package/carbon/volumes/db/super-admin.dev.sql +113 -0
- package/carbon/volumes/db/super-admin.generated.sql +113 -0
- package/carbon/volumes/db/super-admin.sql +114 -0
- package/carbon/volumes/grafana/dashboards/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards/overview.json +523 -0
- package/carbon/volumes/grafana/dashboards/postgresql.json +337 -0
- package/carbon/volumes/grafana/dashboards.dev/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards.dev/overview.json +156 -0
- package/carbon/volumes/grafana/dashboards.dev/postgresql.json +337 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +16 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.yml +16 -0
- package/carbon/volumes/grafana/provisioning/datasources/datasources.yml +43 -0
- package/carbon/volumes/kong/docker-entrypoint.sh +9 -0
- package/carbon/volumes/kong/kong.yml +208 -0
- package/carbon/volumes/loki/loki-config.yml +58 -0
- package/carbon/volumes/n8n/hooks.js +131 -0
- package/carbon/volumes/n8n/scripts/setup.sh +66 -0
- package/carbon/volumes/prometheus/prometheus.yml +43 -0
- package/carbon/volumes/promtail/promtail-config.yml +64 -0
- package/carbon/volumes/traefik/middlewares.dev.yml +83 -0
- package/carbon/volumes/traefik/middlewares.yml +95 -0
- package/carbon/volumes/traefik/vite-dev.yml +20 -0
- package/package.json +95 -0
- package/src/access.js +354 -0
- package/src/activate.js +187 -0
- package/src/add.js +718 -0
- package/src/backup.js +786 -0
- package/src/cli.js +350 -0
- package/src/configure.js +967 -0
- package/src/console.js +155 -0
- package/src/create.js +1499 -0
- package/src/deploy.js +311 -0
- package/src/destroy.js +2033 -0
- package/src/diagnose.js +735 -0
- package/src/down.js +80 -0
- package/src/failover.js +1032 -0
- package/src/lib/backup-s3.js +179 -0
- package/src/lib/build.js +33 -0
- package/src/lib/checksum.js +28 -0
- package/src/lib/ci-setup.js +666 -0
- package/src/lib/cli/help.js +129 -0
- package/src/lib/cli/parse-flags.js +160 -0
- package/src/lib/cli/select-action.js +65 -0
- package/src/lib/cli/select-environment.js +108 -0
- package/src/lib/cli/tty-guard.js +75 -0
- package/src/lib/cloudflare.js +447 -0
- package/src/lib/colors.js +52 -0
- package/src/lib/command.js +361 -0
- package/src/lib/config.js +359 -0
- package/src/lib/cost.js +103 -0
- package/src/lib/deploy/bundle.js +231 -0
- package/src/lib/deploy/compose/acme-verify.js +121 -0
- package/src/lib/deploy/compose/build-args.js +78 -0
- package/src/lib/deploy/compose/ha.js +1874 -0
- package/src/lib/deploy/compose/index.js +1294 -0
- package/src/lib/deploy/compose/reconcile.js +74 -0
- package/src/lib/deploy/github.js +382 -0
- package/src/lib/deploy/image.js +191 -0
- package/src/lib/deploy/index.js +119 -0
- package/src/lib/deploy/k8s/LICENSE +99 -0
- package/src/lib/deploy/k8s/gitops-deploy.js +298 -0
- package/src/lib/deploy/k8s/ha/index.js +1000 -0
- package/src/lib/deploy/k8s/index.js +62 -0
- package/src/lib/deploy/k8s/k3s.js +2515 -0
- package/src/lib/deploy/orchestrator.js +1401 -0
- package/src/lib/deploy/prompts.js +545 -0
- package/src/lib/deploy/remote-build.js +130 -0
- package/src/lib/deploy/state.js +120 -0
- package/src/lib/deploy/utils.js +328 -0
- package/src/lib/deploy-logger.js +93 -0
- package/src/lib/dns-propagation.js +48 -0
- package/src/lib/environment.js +58 -0
- package/src/lib/fetch-retry.js +103 -0
- package/src/lib/github-environments.js +335 -0
- package/src/lib/hetzner-dns.js +377 -0
- package/src/lib/hetzner-guided-setup.js +275 -0
- package/src/lib/host-keys.js +37 -0
- package/src/lib/iac/cloud-init.js +52 -0
- package/src/lib/iac/index.js +325 -0
- package/src/lib/iac/programs/hetzner-compose.js +130 -0
- package/src/lib/iac/programs/hetzner-k8s.js +320 -0
- package/src/lib/kubectl.js +81 -0
- package/src/lib/licensing/index.js +259 -0
- package/src/lib/licensing/tiers.js +181 -0
- package/src/lib/licensing/validator.js +171 -0
- package/src/lib/merge-package-json.js +90 -0
- package/src/lib/operator-ip.js +381 -0
- package/src/lib/package-manager.js +111 -0
- package/src/lib/perf.js +71 -0
- package/src/lib/project-guard.js +39 -0
- package/src/lib/project.js +334 -0
- package/src/lib/providers/base.js +276 -0
- package/src/lib/providers/hetzner-s3.js +656 -0
- package/src/lib/providers/hetzner.js +755 -0
- package/src/lib/providers/index.js +164 -0
- package/src/lib/s3.js +510 -0
- package/src/lib/secret-scan.js +583 -0
- package/src/lib/secrets.js +63 -0
- package/src/lib/server-types.js +195 -0
- package/src/lib/shell.js +91 -0
- package/src/lib/ssh.js +241 -0
- package/src/lib/tracker.js +242 -0
- package/src/lib/upgrade-policy.js +170 -0
- package/src/lib/validators.js +105 -0
- package/src/lib/version.js +5 -0
- package/src/remove.js +292 -0
- package/src/reset.js +97 -0
- package/src/restore.js +871 -0
- package/src/scale.js +1734 -0
- package/src/shell.js +222 -0
- package/src/status.js +981 -0
- package/src/up.js +264 -0
- package/src/upgrade.js +721 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License tier definitions for Vibecarbon
|
|
3
|
+
*
|
|
4
|
+
* Graphite tier: Free local development (no license key needed)
|
|
5
|
+
* Diamond tier: Full automation for indie hackers & startups
|
|
6
|
+
* Fullerene tier: Commercial license for agencies & enterprise
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const TIERS = {
|
|
10
|
+
graphite: {
|
|
11
|
+
name: 'Graphite',
|
|
12
|
+
displayName: 'Vibecarbon Graphite',
|
|
13
|
+
features: ['local-dev', 'all-addons'],
|
|
14
|
+
providers: [],
|
|
15
|
+
maxServers: 0,
|
|
16
|
+
license: 'MIT',
|
|
17
|
+
deployFlags: [],
|
|
18
|
+
// Pricing
|
|
19
|
+
price: 0,
|
|
20
|
+
originalPrice: 0,
|
|
21
|
+
discountPercent: 0,
|
|
22
|
+
hostingCost: '$0',
|
|
23
|
+
// Marketing
|
|
24
|
+
marketingFeatures: [
|
|
25
|
+
'Create projects',
|
|
26
|
+
'Local development',
|
|
27
|
+
'Full Vibecarbon stack',
|
|
28
|
+
'All add-ons (observability, n8n, metabase, redis, CI/CD)',
|
|
29
|
+
'Community support',
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
diamond: {
|
|
33
|
+
name: 'Diamond',
|
|
34
|
+
displayName: 'Vibecarbon Diamond',
|
|
35
|
+
features: [
|
|
36
|
+
'docker-compose',
|
|
37
|
+
'kubernetes',
|
|
38
|
+
'autoscaling',
|
|
39
|
+
'single-vps',
|
|
40
|
+
'ha',
|
|
41
|
+
'multi-region',
|
|
42
|
+
'failover',
|
|
43
|
+
'advanced-monitoring',
|
|
44
|
+
'all-addons',
|
|
45
|
+
],
|
|
46
|
+
providers: ['hetzner'],
|
|
47
|
+
maxServers: Infinity,
|
|
48
|
+
license: 'AGPL-Exception',
|
|
49
|
+
deployFlags: ['--ha', '--k8s'],
|
|
50
|
+
// Pricing
|
|
51
|
+
price: 149,
|
|
52
|
+
originalPrice: 299,
|
|
53
|
+
discountPercent: 50,
|
|
54
|
+
hostingCost: '~$5-100/mo',
|
|
55
|
+
badge: 'Lifetime Access',
|
|
56
|
+
// Marketing
|
|
57
|
+
marketingFeatures: [
|
|
58
|
+
'All deployment modes (Compose, Compose HA, Kubernetes)',
|
|
59
|
+
'Single VPS, HA, or multi-VPS Kubernetes clusters',
|
|
60
|
+
'Full Vibecarbon stack',
|
|
61
|
+
'All add-ons (observability, n8n, metabase, redis, CI/CD)',
|
|
62
|
+
'PostgreSQL streaming replication (HA)',
|
|
63
|
+
'Advanced monitoring & alerting',
|
|
64
|
+
'Unlimited servers & projects',
|
|
65
|
+
'Community support',
|
|
66
|
+
'Full automation for indie hackers & startups',
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
fullerene: {
|
|
70
|
+
name: 'Fullerene',
|
|
71
|
+
displayName: 'Vibecarbon Fullerene',
|
|
72
|
+
features: [
|
|
73
|
+
'docker-compose',
|
|
74
|
+
'kubernetes',
|
|
75
|
+
'autoscaling',
|
|
76
|
+
'single-vps',
|
|
77
|
+
'ha',
|
|
78
|
+
'multi-region',
|
|
79
|
+
'failover',
|
|
80
|
+
'advanced-monitoring',
|
|
81
|
+
'all-addons',
|
|
82
|
+
'commercial-use',
|
|
83
|
+
],
|
|
84
|
+
providers: ['hetzner'],
|
|
85
|
+
maxServers: Infinity,
|
|
86
|
+
license: 'AGPL-Exception',
|
|
87
|
+
deployFlags: ['--ha', '--k8s'],
|
|
88
|
+
// Pricing
|
|
89
|
+
price: 499,
|
|
90
|
+
originalPrice: 999,
|
|
91
|
+
discountPercent: 50,
|
|
92
|
+
hostingCost: '~$5-100/mo',
|
|
93
|
+
badge: 'Lifetime Access',
|
|
94
|
+
// Marketing
|
|
95
|
+
marketingFeatures: [
|
|
96
|
+
'Commercial use rights (AGPL exception)',
|
|
97
|
+
'Deploy for clients & organizations',
|
|
98
|
+
'All deployment modes (Compose, Compose HA, Kubernetes)',
|
|
99
|
+
'Full Vibecarbon stack',
|
|
100
|
+
'All add-ons (observability, n8n, metabase, redis, CI/CD)',
|
|
101
|
+
'Advanced monitoring & alerting',
|
|
102
|
+
'Unlimited servers & projects',
|
|
103
|
+
'Email support',
|
|
104
|
+
'Commercial license for agencies & enterprise',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get tier by name
|
|
111
|
+
* @param {string} tierName - The tier name (graphite, diamond, fullerene)
|
|
112
|
+
* @returns {object|null} The tier configuration or null if not found
|
|
113
|
+
*/
|
|
114
|
+
export function getTier(tierName) {
|
|
115
|
+
return TIERS[tierName] || null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Check if a tier has access to a specific feature
|
|
120
|
+
* @param {string} tierName - The tier name
|
|
121
|
+
* @param {string} feature - The feature to check
|
|
122
|
+
* @returns {boolean} Whether the tier has access to the feature
|
|
123
|
+
*/
|
|
124
|
+
export function hasFeature(tierName, feature) {
|
|
125
|
+
const tier = getTier(tierName);
|
|
126
|
+
return tier ? tier.features.includes(feature) : false;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Check if a tier allows a specific deployment flag
|
|
131
|
+
* @param {string} tierName - The tier name
|
|
132
|
+
* @param {string} flag - The deployment flag (e.g., '--k8s', '--ha', '--compose')
|
|
133
|
+
* @returns {boolean} Whether the tier allows the flag
|
|
134
|
+
*/
|
|
135
|
+
export function allowsFlag(tierName, _flag) {
|
|
136
|
+
// Graphite tier cannot deploy at all
|
|
137
|
+
if (tierName === 'graphite') {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Diamond and Fullerene allow all deployment flags
|
|
142
|
+
if (tierName === 'diamond' || tierName === 'fullerene') {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get the required tier for a deployment flag
|
|
151
|
+
* @param {string} flag - The deployment flag
|
|
152
|
+
* @returns {string} The minimum required tier
|
|
153
|
+
*/
|
|
154
|
+
export function getRequiredTier(flag) {
|
|
155
|
+
// All deployment flags now require only a Diamond (or higher) license
|
|
156
|
+
void flag;
|
|
157
|
+
return 'diamond';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Get all tier names
|
|
162
|
+
* @returns {string[]} Array of tier names
|
|
163
|
+
*/
|
|
164
|
+
export function getTierNames() {
|
|
165
|
+
return Object.keys(TIERS);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Compare two tiers and return which one is higher
|
|
170
|
+
* @param {string} tierA - First tier name
|
|
171
|
+
* @param {string} tierB - Second tier name
|
|
172
|
+
* @returns {number} -1 if A < B, 0 if equal, 1 if A > B
|
|
173
|
+
*/
|
|
174
|
+
export function compareTiers(tierA, tierB) {
|
|
175
|
+
const order = { graphite: 0, diamond: 1, fullerene: 2 };
|
|
176
|
+
const a = order[tierA] ?? -1;
|
|
177
|
+
const b = order[tierB] ?? -1;
|
|
178
|
+
if (a < b) return -1;
|
|
179
|
+
if (a > b) return 1;
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License key validator for Vibecarbon
|
|
3
|
+
*
|
|
4
|
+
* Key format:
|
|
5
|
+
* vc-<tier>-<customer_id>-<signature>
|
|
6
|
+
*
|
|
7
|
+
* Example: vc-d-a7f2b9c1-x8kd9mwp2v4n...
|
|
8
|
+
*
|
|
9
|
+
* - vc: prefix
|
|
10
|
+
* - tier: single character — d (Diamond) or f (Fullerene)
|
|
11
|
+
* - customer_id: 8-character hex identifier
|
|
12
|
+
* - signature: Ed25519 signature encoded as lowercase hex
|
|
13
|
+
*
|
|
14
|
+
* All licenses are lifetime (no expiration).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createPublicKey, verify } from 'node:crypto';
|
|
18
|
+
|
|
19
|
+
// Licensing is now enabled
|
|
20
|
+
const LICENSING_DISABLED = false;
|
|
21
|
+
|
|
22
|
+
// Ed25519 public key for license verification (embedded for offline validation)
|
|
23
|
+
const PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
24
|
+
MCowBQYDK2VwAyEAUrn80IKtISxTCpGjc5rf2ZZhhhu+SktK4L2GEWrjT6Q=
|
|
25
|
+
-----END PUBLIC KEY-----`;
|
|
26
|
+
|
|
27
|
+
// For development/testing - accept any key with valid format
|
|
28
|
+
const DEV_MODE = process.env.VIBECARBON_DEV_LICENSE === 'true';
|
|
29
|
+
|
|
30
|
+
// Tier character mapping
|
|
31
|
+
const TIER_MAP = { d: 'diamond', f: 'fullerene' };
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parse a license key: vc-<tier>-<customer_id>-<signature>
|
|
35
|
+
* @param {string} key - The license key string
|
|
36
|
+
* @returns {object} Parsed key components or error
|
|
37
|
+
*/
|
|
38
|
+
export function parseLicenseKey(key) {
|
|
39
|
+
if (!key || typeof key !== 'string') {
|
|
40
|
+
return { valid: false, error: 'License key is required' };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const trimmedKey = key.trim().toLowerCase();
|
|
44
|
+
const parts = trimmedKey.split('-');
|
|
45
|
+
|
|
46
|
+
// Must have at least 4 parts: vc, tier, customer_id, signature
|
|
47
|
+
if (parts.length < 4) {
|
|
48
|
+
return { valid: false, error: 'Invalid license key format' };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const [prefix, tierChar, customerId, ...signatureParts] = parts;
|
|
52
|
+
const signature = signatureParts.join('-');
|
|
53
|
+
|
|
54
|
+
// Validate prefix
|
|
55
|
+
if (prefix !== 'vc') {
|
|
56
|
+
return { valid: false, error: 'Invalid license key prefix' };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Validate tier character
|
|
60
|
+
const tier = TIER_MAP[tierChar];
|
|
61
|
+
if (!tier) {
|
|
62
|
+
return { valid: false, error: 'Invalid license tier' };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Validate customer ID (8 hex characters)
|
|
66
|
+
if (!/^[a-f0-9]{8}$/.test(customerId)) {
|
|
67
|
+
return { valid: false, error: 'Invalid customer ID format' };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Validate signature exists and has minimum length
|
|
71
|
+
if (!signature || signature.length < 10) {
|
|
72
|
+
return { valid: false, error: 'Invalid signature' };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
valid: true,
|
|
77
|
+
tier,
|
|
78
|
+
tierChar,
|
|
79
|
+
customerId,
|
|
80
|
+
isLifetime: true,
|
|
81
|
+
signature,
|
|
82
|
+
originalKey: key.trim(),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Verify the cryptographic signature of a license key
|
|
88
|
+
* @param {object} parsedKey - Parsed license key from parseLicenseKey()
|
|
89
|
+
* @returns {object} Verification result
|
|
90
|
+
*/
|
|
91
|
+
export function verifySignature(parsedKey) {
|
|
92
|
+
if (!parsedKey.valid) {
|
|
93
|
+
return { valid: false, error: parsedKey.error };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// In development mode, skip signature verification
|
|
97
|
+
if (DEV_MODE) {
|
|
98
|
+
return { valid: true, verified: false, devMode: true };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
const publicKey = createPublicKey(PUBLIC_KEY_PEM);
|
|
103
|
+
|
|
104
|
+
// Signed message: <tierChar>-<customerId>
|
|
105
|
+
const message = `${parsedKey.tierChar}-${parsedKey.customerId}`;
|
|
106
|
+
const signatureBuffer = Buffer.from(parsedKey.signature, 'hex');
|
|
107
|
+
|
|
108
|
+
const isValid = verify(null, Buffer.from(message), publicKey, signatureBuffer);
|
|
109
|
+
|
|
110
|
+
if (!isValid) {
|
|
111
|
+
return { valid: false, error: 'Invalid license signature' };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return { valid: true, verified: true };
|
|
115
|
+
} catch (error) {
|
|
116
|
+
return { valid: false, error: `Signature verification failed: ${error.message}` };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Validate a complete license key
|
|
122
|
+
* @param {string} key - The license key string
|
|
123
|
+
* @returns {object} Complete validation result
|
|
124
|
+
*/
|
|
125
|
+
export function validateLicenseKey(key) {
|
|
126
|
+
// When licensing is disabled, bypass all validation
|
|
127
|
+
if (LICENSING_DISABLED) {
|
|
128
|
+
return {
|
|
129
|
+
valid: true,
|
|
130
|
+
tier: 'fullerene',
|
|
131
|
+
customerId: 'UNLICENSED',
|
|
132
|
+
isLifetime: true,
|
|
133
|
+
verified: false,
|
|
134
|
+
devMode: false,
|
|
135
|
+
licensingDisabled: true,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Parse the key
|
|
140
|
+
const parsed = parseLicenseKey(key);
|
|
141
|
+
if (!parsed.valid) {
|
|
142
|
+
return parsed;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Verify signature
|
|
146
|
+
const signatureResult = verifySignature(parsed);
|
|
147
|
+
if (!signatureResult.valid) {
|
|
148
|
+
return signatureResult;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
valid: true,
|
|
153
|
+
tier: parsed.tier,
|
|
154
|
+
customerId: parsed.customerId,
|
|
155
|
+
isLifetime: true,
|
|
156
|
+
verified: signatureResult.verified,
|
|
157
|
+
devMode: signatureResult.devMode || false,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Generate a development license key (for testing only)
|
|
163
|
+
* @param {string} tier - 'diamond' or 'fullerene'
|
|
164
|
+
* @returns {string} A development license key
|
|
165
|
+
*/
|
|
166
|
+
export function generateDevLicenseKey(tier = 'fullerene') {
|
|
167
|
+
const tierChar = tier === 'diamond' ? 'd' : 'f';
|
|
168
|
+
const customerId = 'de000001'; // 8 hex chars
|
|
169
|
+
const signature = 'de0e0000000000000000';
|
|
170
|
+
return `vc-${tierChar}-${customerId}-${signature}`;
|
|
171
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart package.json merge for upgrades
|
|
3
|
+
*
|
|
4
|
+
* Merges the template package.json into the user's existing one:
|
|
5
|
+
* - Updates versions of shared dependencies (template wins)
|
|
6
|
+
* - Adds new template dependencies the user doesn't have
|
|
7
|
+
* - Preserves all user-added dependencies not in the template
|
|
8
|
+
* - Merges pnpm/npm config sections (overrides, etc.)
|
|
9
|
+
* - Updates scripts from template, preserves user-added scripts
|
|
10
|
+
* - Preserves other top-level fields the user may have added
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Deep-merge two plain objects. Source values win for shared keys.
|
|
15
|
+
* Arrays are replaced, not concatenated.
|
|
16
|
+
*
|
|
17
|
+
* @param {Record<string, unknown>} target
|
|
18
|
+
* @param {Record<string, unknown>} source
|
|
19
|
+
* @returns {Record<string, unknown>}
|
|
20
|
+
*/
|
|
21
|
+
function deepMerge(target, source) {
|
|
22
|
+
const result = { ...target };
|
|
23
|
+
for (const key of Object.keys(source)) {
|
|
24
|
+
if (
|
|
25
|
+
source[key] &&
|
|
26
|
+
typeof source[key] === 'object' &&
|
|
27
|
+
!Array.isArray(source[key]) &&
|
|
28
|
+
target[key] &&
|
|
29
|
+
typeof target[key] === 'object' &&
|
|
30
|
+
!Array.isArray(target[key])
|
|
31
|
+
) {
|
|
32
|
+
result[key] = deepMerge(target[key], source[key]);
|
|
33
|
+
} else {
|
|
34
|
+
result[key] = source[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Merge dependency maps: update shared deps to template versions, add new ones, keep user extras.
|
|
42
|
+
*
|
|
43
|
+
* @param {Record<string, string>} [userDeps]
|
|
44
|
+
* @param {Record<string, string>} [templateDeps]
|
|
45
|
+
* @returns {Record<string, string>}
|
|
46
|
+
*/
|
|
47
|
+
function mergeDeps(userDeps, templateDeps) {
|
|
48
|
+
if (!templateDeps) return userDeps || {};
|
|
49
|
+
if (!userDeps) return { ...templateDeps };
|
|
50
|
+
|
|
51
|
+
const merged = { ...userDeps };
|
|
52
|
+
|
|
53
|
+
for (const [pkg, version] of Object.entries(templateDeps)) {
|
|
54
|
+
// Update existing or add new — template version wins
|
|
55
|
+
merged[pkg] = version;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return merged;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Merge the user's package.json with the template's package.json.
|
|
63
|
+
*
|
|
64
|
+
* @param {object} userPkg - The user's current package.json (parsed)
|
|
65
|
+
* @param {object} templatePkg - The template's package.json (parsed)
|
|
66
|
+
* @returns {object} - The merged package.json
|
|
67
|
+
*/
|
|
68
|
+
export function mergePackageJson(userPkg, templatePkg) {
|
|
69
|
+
// Start from the user's package.json to preserve all their fields
|
|
70
|
+
const merged = { ...userPkg };
|
|
71
|
+
|
|
72
|
+
// Update dependencies (template versions win, user extras preserved)
|
|
73
|
+
merged.dependencies = mergeDeps(userPkg.dependencies, templatePkg.dependencies);
|
|
74
|
+
merged.devDependencies = mergeDeps(userPkg.devDependencies, templatePkg.devDependencies);
|
|
75
|
+
|
|
76
|
+
// Merge scripts: template scripts win, user-added scripts preserved
|
|
77
|
+
merged.scripts = { ...userPkg.scripts, ...templatePkg.scripts };
|
|
78
|
+
|
|
79
|
+
// Merge pnpm config section (overrides, onlyBuiltDependencies, etc.)
|
|
80
|
+
if (templatePkg.pnpm) {
|
|
81
|
+
merged.pnpm = deepMerge(userPkg.pnpm || {}, templatePkg.pnpm);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Update these standard fields from template
|
|
85
|
+
merged.type = templatePkg.type;
|
|
86
|
+
merged.version = templatePkg.version;
|
|
87
|
+
merged.private = templatePkg.private;
|
|
88
|
+
|
|
89
|
+
return merged;
|
|
90
|
+
}
|