@better-fullstack/types 2.1.8 → 2.2.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.
Files changed (44) hide show
  1. package/dist/{defaults-DNnZX9er.mjs → defaults-DgL5YPQY.mjs} +12 -1
  2. package/dist/defaults-DgL5YPQY.mjs.map +1 -0
  3. package/dist/{defaults-Cpkx-Eu7.d.mts → defaults-DyNR1d-V.d.mts} +2 -2
  4. package/dist/defaults-DyNR1d-V.d.mts.map +1 -0
  5. package/dist/defaults.d.mts +3 -3
  6. package/dist/defaults.mjs +1 -1
  7. package/dist/index.d.mts +7 -7
  8. package/dist/index.d.mts.map +1 -1
  9. package/dist/index.mjs +110 -5
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/json-schema.d.mts +1814 -362
  12. package/dist/json-schema.d.mts.map +1 -1
  13. package/dist/json-schema.mjs +94 -2
  14. package/dist/json-schema.mjs.map +1 -1
  15. package/dist/{schemas-DOb4t_el.d.mts → schemas-D9kkuJz7.d.mts} +1811 -645
  16. package/dist/schemas-D9kkuJz7.d.mts.map +1 -0
  17. package/dist/{schemas-BXDvWDRp.mjs → schemas-l7hOhH8U.mjs} +161 -6
  18. package/dist/schemas-l7hOhH8U.mjs.map +1 -0
  19. package/dist/schemas.d.mts +2 -2
  20. package/dist/schemas.mjs +2 -2
  21. package/dist/{stack-graph-BAad0vv4.mjs → stack-graph-C8r3fTh4.mjs} +180 -27
  22. package/dist/stack-graph-C8r3fTh4.mjs.map +1 -0
  23. package/dist/{stack-graph-0MDSuSPQ.d.mts → stack-graph-F6UKYYR0.d.mts} +2 -2
  24. package/dist/{stack-graph-0MDSuSPQ.d.mts.map → stack-graph-F6UKYYR0.d.mts.map} +1 -1
  25. package/dist/stack-graph.d.mts +3 -3
  26. package/dist/stack-graph.mjs +2 -2
  27. package/dist/{stack-translation-CnNmU8Z5.d.mts → stack-translation-BNHNx5_b.d.mts} +31 -9
  28. package/dist/stack-translation-BNHNx5_b.d.mts.map +1 -0
  29. package/dist/{stack-translation-DwSS9Vc2.mjs → stack-translation-Kr0TyRAm.mjs} +703 -81
  30. package/dist/stack-translation-Kr0TyRAm.mjs.map +1 -0
  31. package/dist/stack-translation.d.mts +4 -4
  32. package/dist/stack-translation.mjs +3 -3
  33. package/dist/{types-CcWal512.d.mts → types-C7RpHf2e.d.mts} +14 -3
  34. package/dist/types-C7RpHf2e.d.mts.map +1 -0
  35. package/dist/types.d.mts +3 -3
  36. package/package.json +2 -2
  37. package/dist/defaults-Cpkx-Eu7.d.mts.map +0 -1
  38. package/dist/defaults-DNnZX9er.mjs.map +0 -1
  39. package/dist/schemas-BXDvWDRp.mjs.map +0 -1
  40. package/dist/schemas-DOb4t_el.d.mts.map +0 -1
  41. package/dist/stack-graph-BAad0vv4.mjs.map +0 -1
  42. package/dist/stack-translation-CnNmU8Z5.d.mts.map +0 -1
  43. package/dist/stack-translation-DwSS9Vc2.mjs.map +0 -1
  44. package/dist/types-CcWal512.d.mts.map +0 -1
@@ -1,6 +1,6 @@
1
- import { $n as MOBILE_OTA_VALUES, $r as RUST_AUTH_VALUES, Ai as SERVER_DEPLOY_VALUES, An as JAVA_AUTH_VALUES, Ar as PYTHON_WEB_FRAMEWORK_VALUES, B as DOTNET_OBSERVABILITY_VALUES, Cr as PYTHON_OBSERVABILITY_VALUES, Ct as ELIXIR_WEB_FRAMEWORK_VALUES, D as CMS_VALUES, Dr as PYTHON_TASK_QUEUE_VALUES, En as I18N_VALUES, Er as PYTHON_REALTIME_VALUES, F as DOTNET_API_VALUES, Fi as SHADCN_ICON_LIBRARY_VALUES, Fn as JAVA_ORM_VALUES, G as DOTNET_WEB_FRAMEWORK_VALUES, H as DOTNET_REALTIME_VALUES, I as DOTNET_AUTH_VALUES, Ii as SHADCN_RADIUS_VALUES, In as JAVA_TESTING_LIBRARIES_VALUES, Jt as FILE_UPLOAD_VALUES, Kt as FEATURE_FLAGS_VALUES, L as DOTNET_CACHING_VALUES, Li as SHADCN_STYLE_VALUES, Ln as JAVA_WEB_FRAMEWORK_VALUES, M as DATABASE_SETUP_VALUES, Mi as SHADCN_BASE_VALUES, Mn as JAVA_LANGUAGE_VALUES, N as DATABASE_VALUES, Ni as SHADCN_COLOR_THEME_VALUES, Nn as JAVA_LIBRARIES_VALUES, Or as PYTHON_TESTING_VALUES, Pi as SHADCN_FONT_VALUES, Pn as JAVA_LOGGING_VALUES, Qn as MOBILE_NAVIGATION_VALUES, Qr as RUST_API_VALUES, R as DOTNET_DEPLOY_VALUES, Ri as STATE_MANAGEMENT_VALUES, Rn as JOB_QUEUE_VALUES, Sr as PYTHON_GRAPHQL_VALUES, St as ELIXIR_VALIDATION_VALUES, Tr as PYTHON_QUALITY_VALUES, U as DOTNET_TESTING_VALUES, V as DOTNET_ORM_VALUES, W as DOTNET_VALIDATION_VALUES, Xr as REALTIME_VALUES, Yn as LOGGING_VALUES, Yr as RATE_LIMIT_VALUES, Yt as FORMS_VALUES, Zn as MOBILE_DEEP_LINKING_VALUES, Zr as RUNTIME_VALUES, _r as PYTHON_AI_VALUES, _t as ELIXIR_OBSERVABILITY_VALUES, a as ANALYTICS_VALUES, aa as VALIDATION_VALUES, ai as RUST_LOGGING_VALUES, an as GO_CLI_VALUES, br as PYTHON_CACHING_VALUES, bt as ELIXIR_REALTIME_VALUES, c as API_VALUES, ci as RUST_ORM_VALUES, cn as GO_MESSAGE_QUEUE_VALUES, ct as ELIXIR_API_VALUES, da as WEB_DEPLOY_VALUES, di as RUST_WEB_FRAMEWORK_VALUES, dn as GO_REALTIME_VALUES, dr as OBSERVABILITY_VALUES, dt as ELIXIR_DEPLOY_VALUES, ea as TESTING_VALUES, ei as RUST_CACHING_VALUES, er as MOBILE_PUSH_VALUES, fa as WORKSPACE_SHAPE_VALUES, fn as GO_TESTING_VALUES, ft as ELIXIR_EMAIL_VALUES, gr as PAYMENTS_VALUES, gt as ELIXIR_LIBRARIES_VALUES, hr as PACKAGE_MANAGER_VALUES, ht as ELIXIR_JSON_VALUES, i as AI_VALUES, ia as UI_LIBRARY_VALUES, ii as RUST_LIBRARIES_VALUES, in as GO_CACHING_VALUES, ji as SHADCN_BASE_COLOR_VALUES, jn as JAVA_BUILD_TOOL_VALUES, k as CSS_FRAMEWORK_VALUES, ki as SEARCH_VALUES, kn as JAVA_API_VALUES, kr as PYTHON_VALIDATION_VALUES, l as ASTRO_INTEGRATION_VALUES, li as RUST_REALTIME_VALUES, ln as GO_OBSERVABILITY_VALUES, lt as ELIXIR_AUTH_VALUES, mt as ELIXIR_JOBS_VALUES, ni as RUST_ERROR_HANDLING_VALUES, nn as GO_API_VALUES, nr as MOBILE_TESTING_VALUES, o as ANIMATION_VALUES, oa as VECTOR_DB_VALUES, oi as RUST_MESSAGE_QUEUE_VALUES, on as GO_CONFIG_VALUES, pn as GO_WEB_FRAMEWORK_VALUES, pr as ORM_VALUES, pt as ELIXIR_HTTP_VALUES, qt as FILE_STORAGE_VALUES, r as AI_DOCS_VALUES, ri as RUST_FRONTEND_VALUES, rn as GO_AUTH_VALUES, rr as MOBILE_UI_VALUES, sa as VERSION_CHANNEL_VALUES, si as RUST_OBSERVABILITY_VALUES, sn as GO_LOGGING_VALUES, st as EFFECT_VALUES, ti as RUST_CLI_VALUES, tr as MOBILE_STORAGE_VALUES, u as AUTH_VALUES, ui as RUST_TEMPLATING_VALUES, un as GO_ORM_VALUES, ut as ELIXIR_CACHING_VALUES, vr as PYTHON_API_VALUES, vt as ELIXIR_ORM_VALUES, w as CACHING_VALUES, wr as PYTHON_ORM_VALUES, wt as EMAIL_VALUES, xr as PYTHON_CLI_VALUES, xt as ELIXIR_TESTING_VALUES, yr as PYTHON_AUTH_VALUES, yt as ELIXIR_QUALITY_VALUES, z as DOTNET_JOB_QUEUE_VALUES } from "./schemas-BXDvWDRp.mjs";
2
- import { E as requiresChatSdkVercelAIForExamples, S as hasTauriCompatibleFrontend, _ as UI_LIBRARY_COMPATIBILITY, a as getAddonStackPartBinding, b as hasPWACompatibleFrontend, f as parseStackPartSpecs, h as validateStackParts, i as formatStackPartSpec, m as stackPartsToLegacyProjectConfigPartial, s as getStackPartCompatibilityIssueForPart, u as legacyProjectConfigToStackParts, v as getUnsupportedWebDeployFrontend, x as hasTanStackAICompatibleFrontend } from "./stack-graph-BAad0vv4.mjs";
3
- import { t as createCliDefaultProjectConfigBase } from "./defaults-DNnZX9er.mjs";
1
+ import { $i as SERVER_DEPLOY_VALUES, $n as JAVA_AUTH_VALUES, $r as PYTHON_WEB_FRAMEWORK_VALUES, A as CSS_FRAMEWORK_VALUES, Aa as VERSION_CHANNEL_VALUES, Ai as RUST_OBSERVABILITY_VALUES, An as GO_WEB_FRAMEWORK_VALUES, At as EMAIL_VALUES, B as DOTNET_JOB_QUEUE_VALUES, Br as PYTHON_AI_VALUES, Ca as TESTING_VALUES, Ci as RUST_CACHING_VALUES, Cn as GO_ORM_VALUES, Cr as MOBILE_PUSH_VALUES, Ct as ELIXIR_OBSERVABILITY_VALUES, Da as UI_LIBRARY_VALUES, Di as RUST_LIBRARIES_VALUES, Dn as GO_TEMPLATING_VALUES, Dt as ELIXIR_TESTING_VALUES, Ei as RUST_FRONTEND_VALUES, En as GO_REALTIME_VALUES, Er as MOBILE_UI_VALUES, Et as ELIXIR_REALTIME_VALUES, Fa as WORKSPACE_SHAPE_VALUES, G as DOTNET_VALIDATION_VALUES, Gr as PYTHON_GRAPHQL_VALUES, H as DOTNET_ORM_VALUES, Hr as PYTHON_AUTH_VALUES, I as DOTNET_API_VALUES, Ir as ORM_VALUES, Jr as PYTHON_QUALITY_VALUES, K as DOTNET_WEB_FRAMEWORK_VALUES, Kr as PYTHON_OBSERVABILITY_VALUES, L as DOTNET_AUTH_VALUES, Mi as RUST_REALTIME_VALUES, N as DATABASE_SETUP_VALUES, Ni as RUST_TEMPLATING_VALUES, O as CMS_VALUES, Oa as VALIDATION_VALUES, Oi as RUST_LOGGING_VALUES, On as GO_TESTING_VALUES, Ot as ELIXIR_VALIDATION_VALUES, P as DATABASE_VALUES, Pa as WEB_DEPLOY_VALUES, Pi as RUST_WEB_FRAMEWORK_VALUES, Pr as OBSERVABILITY_VALUES, Qi as SEARCH_VALUES, Qn as JAVA_API_VALUES, Qr as PYTHON_VALIDATION_VALUES, R as DOTNET_CACHING_VALUES, Rr as PACKAGE_MANAGER_VALUES, Si as RUST_AUTH_VALUES, Sn as GO_OBSERVABILITY_VALUES, Sr as MOBILE_OTA_VALUES, St as ELIXIR_LIBRARIES_VALUES, T as CACHING_VALUES, Ti as RUST_ERROR_HANDLING_VALUES, Tn as GO_QUALITY_VALUES, Tr as MOBILE_TESTING_VALUES, Tt as ELIXIR_QUALITY_VALUES, U as DOTNET_REALTIME_VALUES, Ur as PYTHON_CACHING_VALUES, V as DOTNET_OBSERVABILITY_VALUES, Vr as PYTHON_API_VALUES, W as DOTNET_TESTING_VALUES, Wr as PYTHON_CLI_VALUES, Xr as PYTHON_TASK_QUEUE_VALUES, Yn as I18N_VALUES, Yr as PYTHON_REALTIME_VALUES, Zr as PYTHON_TESTING_VALUES, _n as GO_CONFIG_VALUES, _t as ELIXIR_HTTP_SERVER_VALUES, a as ANALYTICS_VALUES, aa as SHADCN_RADIUS_VALUES, an as FILE_UPLOAD_VALUES, ar as JAVA_TESTING_LIBRARIES_VALUES, bi as RUNTIME_VALUES, bn as GO_MESSAGE_QUEUE_VALUES, br as MOBILE_DEEP_LINKING_VALUES, bt as ELIXIR_JOBS_VALUES, c as API_VALUES, ct as EFFECT_VALUES, d as AUTH_VALUES, dt as ELIXIR_AUTH_VALUES, ea as SHADCN_BASE_COLOR_VALUES, er as JAVA_BUILD_TOOL_VALUES, ft as ELIXIR_CACHING_VALUES, gn as GO_CLI_VALUES, gt as ELIXIR_EMAIL_VALUES, hn as GO_CACHING_VALUES, ht as ELIXIR_DOCUMENTATION_VALUES, i as AI_VALUES, ia as SHADCN_ICON_LIBRARY_VALUES, in as FILE_STORAGE_VALUES, ir as JAVA_ORM_VALUES, ji as RUST_ORM_VALUES, ka as VECTOR_DB_VALUES, ki as RUST_MESSAGE_QUEUE_VALUES, kn as GO_VALIDATION_VALUES, kt as ELIXIR_WEB_FRAMEWORK_VALUES, l as APP_PLATFORM_ADDON_VALUES, lt as ELIXIR_API_VALUES, mn as GO_AUTH_VALUES, mt as ELIXIR_DEPLOY_VALUES, na as SHADCN_COLOR_THEME_VALUES, nr as JAVA_LIBRARIES_VALUES, o as ANIMATION_VALUES, oa as SHADCN_STYLE_VALUES, on as FORMS_VALUES, or as JAVA_WEB_FRAMEWORK_VALUES, pn as GO_API_VALUES, pt as ELIXIR_CLUSTERING_VALUES, qr as PYTHON_ORM_VALUES, r as AI_DOCS_VALUES, ra as SHADCN_FONT_VALUES, rn as FEATURE_FLAGS_VALUES, rr as JAVA_LOGGING_VALUES, sa as STATE_MANAGEMENT_VALUES, sr as JOB_QUEUE_VALUES, ta as SHADCN_BASE_VALUES, tr as JAVA_LANGUAGE_VALUES, u as ASTRO_INTEGRATION_VALUES, ut as ELIXIR_APPLICATION_FRAMEWORK_VALUES, vi as RATE_LIMIT_VALUES, vn as GO_DI_VALUES, vr as LOGGING_VALUES, vt as ELIXIR_HTTP_VALUES, wi as RUST_CLI_VALUES, wn as GO_PROTO_TOOLING_VALUES, wr as MOBILE_STORAGE_VALUES, wt as ELIXIR_ORM_VALUES, xi as RUST_API_VALUES, xn as GO_MIGRATIONS_VALUES, xr as MOBILE_NAVIGATION_VALUES, xt as ELIXIR_JSON_VALUES, yi as REALTIME_VALUES, yn as GO_LOGGING_VALUES, yt as ELIXIR_I18N_VALUES, z as DOTNET_DEPLOY_VALUES, zr as PAYMENTS_VALUES } from "./schemas-l7hOhH8U.mjs";
2
+ import { E as requiresChatSdkVercelAIForExamples, S as hasTauriCompatibleFrontend, _ as UI_LIBRARY_COMPATIBILITY, a as getAddonStackPartBinding, b as hasPWACompatibleFrontend, f as parseStackPartSpecs, h as validateStackParts, i as formatStackPartSpec, m as stackPartsToLegacyProjectConfigPartial, s as getStackPartCompatibilityIssueForPart, u as legacyProjectConfigToStackParts, v as getUnsupportedWebDeployFrontend, x as hasTanStackAICompatibleFrontend } from "./stack-graph-C8r3fTh4.mjs";
3
+ import { t as createCliDefaultProjectConfigBase } from "./defaults-DgL5YPQY.mjs";
4
4
 
5
5
  //#region src/capabilities.ts
6
6
  const CAPABILITY_DEFINITIONS = { auth: [
@@ -85,6 +85,14 @@ const CAPABILITY_DEFINITIONS = { auth: [
85
85
  icon: "https://cdn.simpleicons.org/kinde/00A9FF",
86
86
  color: "from-sky-400 to-cyan-600"
87
87
  },
88
+ {
89
+ id: "passport",
90
+ label: "Passport.js",
91
+ description: "Strategy-based authentication middleware for Express applications",
92
+ promptHint: "Passport.js with GitHub OAuth for Express",
93
+ icon: "https://cdn.simpleicons.org/passport/34E27A",
94
+ color: "from-emerald-400 to-green-600"
95
+ },
88
96
  {
89
97
  id: "none",
90
98
  label: "No Auth",
@@ -160,6 +168,7 @@ function getAuthDisabledReason(context, optionId) {
160
168
  if (optionId === "go-better-auth") return ecosystem === "go" ? null : "GoBetterAuth is available only for Go stacks";
161
169
  if (ecosystem === "go") return "Go stacks currently support GoBetterAuth only";
162
170
  if (ecosystem !== "typescript") return `${capitalizeFirst(ecosystem)} stacks do not support auth integrations yet`;
171
+ if (webFrontend.some((frontend) => ["vanilla-vite", "vue"].includes(frontend))) return "Auth client integrations are not yet wired for standalone Vue or Vanilla Vite frontends";
163
172
  if (backend === "none") return "No backend selected";
164
173
  if (optionId === "better-auth" || optionId === "better-auth-organizations") {
165
174
  if (optionId === "better-auth-organizations" && backend === "convex") return "Better Auth organizations is currently generated for non-Convex Better Auth stacks";
@@ -196,6 +205,7 @@ function getAuthDisabledReason(context, optionId) {
196
205
  }
197
206
  return "In Better-Fullstack, Supabase Auth is currently supported only with the 'self' backend (fullstack Next.js or TanStack Start)";
198
207
  }
208
+ if (optionId === "passport") return backend === "express" ? null : "Passport.js is currently scaffolded for the Express backend";
199
209
  const nextOnlyLabel = getNextOnlyAuthLabel(optionId);
200
210
  if (backend !== "self" && backend !== "self-next") return `In Better-Fullstack, ${nextOnlyLabel} is currently supported only with the 'self' backend (fullstack Next.js)`;
201
211
  if (!hasNextJs) return `In Better-Fullstack, ${nextOnlyLabel} currently requires the Next.js frontend`;
@@ -239,6 +249,7 @@ function normalizeCapabilitySelection(capability, context, optionId) {
239
249
  const TYPESCRIPT_CATEGORY_ORDER = [
240
250
  "webFrontend",
241
251
  "astroIntegration",
252
+ "appShells",
242
253
  "cssFramework",
243
254
  "uiLibrary",
244
255
  "shadcnBase",
@@ -366,6 +377,12 @@ const GO_CATEGORY_ORDER = [
366
377
  "goCaching",
367
378
  "goConfig",
368
379
  "goObservability",
380
+ "goValidation",
381
+ "goQuality",
382
+ "goMigrations",
383
+ "goTemplating",
384
+ "goProtoTooling",
385
+ "goDI",
369
386
  "auth",
370
387
  "email",
371
388
  "observability",
@@ -424,6 +441,11 @@ const ELIXIR_CATEGORY_ORDER = [
424
441
  "elixirObservability",
425
442
  "elixirTesting",
426
443
  "elixirQuality",
444
+ "elixirI18n",
445
+ "elixirHttpServer",
446
+ "elixirApplicationFramework",
447
+ "elixirDocumentation",
448
+ "elixirClustering",
427
449
  "elixirDeploy",
428
450
  "elixirLibraries",
429
451
  "aiDocs",
@@ -455,6 +477,8 @@ function getCategoryOrderForEcosystem(ecosystem) {
455
477
  function getCategoryDisplayName(categoryKey) {
456
478
  const customName = {
457
479
  i18n: "Internationalization (i18n)",
480
+ appShells: "App Platforms",
481
+ appPlatforms: "Addons",
458
482
  mobileNavigation: "Mobile Navigation",
459
483
  mobileUI: "Mobile UI",
460
484
  mobileStorage: "Mobile Storage",
@@ -503,6 +527,12 @@ function getCategoryDisplayName(categoryKey) {
503
527
  goCaching: "Go Caching",
504
528
  goConfig: "Go Config",
505
529
  goObservability: "Go Observability",
530
+ goValidation: "Go Validation",
531
+ goQuality: "Go Code Quality",
532
+ goMigrations: "Go Database Migrations",
533
+ goTemplating: "Go Templating",
534
+ goProtoTooling: "Go Protobuf Tooling",
535
+ goDI: "Go Dependency Injection",
506
536
  javaLanguage: "Java Language",
507
537
  javaWebFramework: "Java Web Framework",
508
538
  javaBuildTool: "Java Build Tool",
@@ -537,6 +567,11 @@ function getCategoryDisplayName(categoryKey) {
537
567
  elixirObservability: "Elixir Observability",
538
568
  elixirTesting: "Elixir Testing",
539
569
  elixirQuality: "Elixir Code Quality",
570
+ elixirI18n: "Elixir Localization",
571
+ elixirHttpServer: "Elixir HTTP Server",
572
+ elixirApplicationFramework: "Elixir Application Framework",
573
+ elixirDocumentation: "Elixir Documentation",
574
+ elixirClustering: "Elixir Clustering",
540
575
  elixirDeploy: "Elixir Deploy",
541
576
  elixirLibraries: "Elixir Libraries"
542
577
  }[categoryKey];
@@ -548,6 +583,8 @@ const WEB_FRONTEND_VALUES = [
548
583
  "tanstack-router",
549
584
  "react-router",
550
585
  "react-vite",
586
+ "vanilla-vite",
587
+ "vue",
551
588
  "tanstack-start",
552
589
  "next",
553
590
  "vinext",
@@ -591,6 +628,8 @@ const BACKEND_BUILDER_VALUES = [
591
628
  ];
592
629
  const CODE_QUALITY_VALUES = [
593
630
  "biome",
631
+ "eslint",
632
+ "prettier",
594
633
  "oxlint",
595
634
  "ultracite",
596
635
  "lefthook",
@@ -598,13 +637,10 @@ const CODE_QUALITY_VALUES = [
598
637
  "ruler"
599
638
  ];
600
639
  const DOCUMENTATION_VALUES = ["starlight", "fumadocs"];
640
+ const APP_SHELL_VALUES = APP_PLATFORM_ADDON_VALUES;
601
641
  const APP_PLATFORM_VALUES = [
602
642
  "turborepo",
603
643
  "nx",
604
- "pwa",
605
- "tauri",
606
- "wxt",
607
- "opentui",
608
644
  "mcp",
609
645
  "skills",
610
646
  "msw",
@@ -618,7 +654,12 @@ const APP_PLATFORM_VALUES = [
618
654
  "backend-utils",
619
655
  "devcontainer",
620
656
  "docker-compose",
621
- "github-actions"
657
+ "github-actions",
658
+ "axios",
659
+ "firebase",
660
+ "graphql-codegen",
661
+ "openapi-typescript",
662
+ "apollo-client"
622
663
  ];
623
664
  const EXAMPLE_VALUES = ["ai", "chat-sdk"];
624
665
  const BOOLEAN_OPTION_VALUES = ["true", "false"];
@@ -627,6 +668,7 @@ const MULTI_SELECT_CATEGORIES = new Set([
627
668
  "nativeFrontend",
628
669
  "codeQuality",
629
670
  "documentation",
671
+ "appShells",
630
672
  "appPlatforms",
631
673
  "examples",
632
674
  "aiDocs",
@@ -687,6 +729,7 @@ const CATEGORY_VALUE_IDS = {
687
729
  mobileDeepLinking: MOBILE_DEEP_LINKING_VALUES,
688
730
  codeQuality: CODE_QUALITY_VALUES,
689
731
  documentation: DOCUMENTATION_VALUES,
732
+ appShells: APP_SHELL_VALUES,
690
733
  appPlatforms: APP_PLATFORM_VALUES,
691
734
  packageManager: PACKAGE_MANAGER_VALUES,
692
735
  workspaceShape: WORKSPACE_SHAPE_VALUES,
@@ -744,6 +787,12 @@ const CATEGORY_VALUE_IDS = {
744
787
  goCaching: GO_CACHING_VALUES,
745
788
  goConfig: GO_CONFIG_VALUES,
746
789
  goObservability: GO_OBSERVABILITY_VALUES,
790
+ goValidation: GO_VALIDATION_VALUES,
791
+ goQuality: GO_QUALITY_VALUES,
792
+ goMigrations: GO_MIGRATIONS_VALUES,
793
+ goTemplating: GO_TEMPLATING_VALUES,
794
+ goProtoTooling: GO_PROTO_TOOLING_VALUES,
795
+ goDI: GO_DI_VALUES,
747
796
  javaLanguage: JAVA_LANGUAGE_VALUES,
748
797
  javaWebFramework: JAVA_WEB_FRAMEWORK_VALUES,
749
798
  javaBuildTool: JAVA_BUILD_TOOL_VALUES,
@@ -778,6 +827,11 @@ const CATEGORY_VALUE_IDS = {
778
827
  elixirObservability: ELIXIR_OBSERVABILITY_VALUES,
779
828
  elixirTesting: ELIXIR_TESTING_VALUES,
780
829
  elixirQuality: ELIXIR_QUALITY_VALUES,
830
+ elixirI18n: ELIXIR_I18N_VALUES,
831
+ elixirHttpServer: ELIXIR_HTTP_SERVER_VALUES,
832
+ elixirApplicationFramework: ELIXIR_APPLICATION_FRAMEWORK_VALUES,
833
+ elixirDocumentation: ELIXIR_DOCUMENTATION_VALUES,
834
+ elixirClustering: ELIXIR_CLUSTERING_VALUES,
781
835
  elixirDeploy: ELIXIR_DEPLOY_VALUES,
782
836
  elixirLibraries: ELIXIR_LIBRARIES_VALUES
783
837
  };
@@ -793,6 +847,8 @@ const EXACT_LABEL_OVERRIDES = {
793
847
  next: "Next.js",
794
848
  vinext: "Vinext",
795
849
  "react-vite": "React + Vite",
850
+ "vanilla-vite": "Vite (Vanilla TypeScript)",
851
+ vue: "Vue 3 + Vite",
796
852
  svelte: "SvelteKit",
797
853
  redwood: "RedwoodJS"
798
854
  },
@@ -858,17 +914,20 @@ const EXACT_LABEL_OVERRIDES = {
858
914
  cms: {
859
915
  tinacms: "TinaCMS",
860
916
  directus: "Directus",
861
- keystatic: "Keystatic"
917
+ keystatic: "Keystatic",
918
+ contentful: "Contentful"
862
919
  },
863
920
  auth: {
864
921
  "better-auth-organizations": "Better Auth + Organizations",
865
922
  auth0: "Auth0",
866
923
  workos: "WorkOS AuthKit",
867
- kinde: "Kinde"
924
+ kinde: "Kinde",
925
+ passport: "Passport.js"
868
926
  },
869
927
  payments: {
870
928
  "lemon-squeezy": "Lemon Squeezy",
871
- dodo: "Dodo Payments"
929
+ dodo: "Dodo Payments",
930
+ paypal: "PayPal"
872
931
  },
873
932
  email: {
874
933
  "react-email": "React Email",
@@ -910,9 +969,13 @@ const EXACT_LABEL_OVERRIDES = {
910
969
  typebox: "TypeBox",
911
970
  "effect-schema": "Effect Schema"
912
971
  },
913
- testing: { "vitest-playwright": "Vitest + Playwright" },
972
+ testing: {
973
+ "vitest-playwright": "Vitest + Playwright",
974
+ mocha: "Mocha"
975
+ },
914
976
  realtime: {
915
977
  "socket-io": "Socket.IO",
978
+ ws: "ws",
916
979
  yjs: "Y.js"
917
980
  },
918
981
  jobQueue: {
@@ -947,7 +1010,8 @@ const EXACT_LABEL_OVERRIDES = {
947
1010
  cssFramework: {
948
1011
  tailwind: "Tailwind CSS",
949
1012
  scss: "SCSS",
950
- "postcss-only": "PostCSS Only"
1013
+ "postcss-only": "PostCSS Only",
1014
+ "styled-components": "styled-components"
951
1015
  },
952
1016
  uiLibrary: {
953
1017
  "shadcn-ui": "shadcn/ui",
@@ -973,7 +1037,8 @@ const EXACT_LABEL_OVERRIDES = {
973
1037
  },
974
1038
  analytics: {
975
1039
  plausible: "Plausible",
976
- umami: "Umami"
1040
+ umami: "Umami",
1041
+ ga4: "Google Analytics 4"
977
1042
  },
978
1043
  mobileNavigation: {
979
1044
  "expo-router": "Expo Router",
@@ -996,6 +1061,8 @@ const EXACT_LABEL_OVERRIDES = {
996
1061
  mobileDeepLinking: { "expo-linking": "Expo Linking" },
997
1062
  codeQuality: {
998
1063
  biome: "Biome",
1064
+ eslint: "ESLint",
1065
+ prettier: "Prettier",
999
1066
  oxlint: "Oxlint",
1000
1067
  ultracite: "Ultracite",
1001
1068
  lefthook: "Lefthook",
@@ -1006,10 +1073,15 @@ const EXACT_LABEL_OVERRIDES = {
1006
1073
  starlight: "Starlight",
1007
1074
  fumadocs: "Fumadocs"
1008
1075
  },
1009
- appPlatforms: {
1076
+ appShells: {
1010
1077
  pwa: "PWA",
1078
+ tauri: "Tauri",
1079
+ electron: "Electron",
1080
+ capacitor: "Capacitor",
1011
1081
  wxt: "WXT",
1012
- opentui: "OpenTUI",
1082
+ opentui: "OpenTUI"
1083
+ },
1084
+ appPlatforms: {
1013
1085
  mcp: "MCP",
1014
1086
  msw: "MSW",
1015
1087
  swr: "SWR",
@@ -1020,7 +1092,12 @@ const EXACT_LABEL_OVERRIDES = {
1020
1092
  "tanstack-pacer": "TanStack Pacer",
1021
1093
  devcontainer: "DevContainer",
1022
1094
  "docker-compose": "Docker Compose",
1023
- "github-actions": "GitHub Actions"
1095
+ "github-actions": "GitHub Actions",
1096
+ axios: "Axios",
1097
+ firebase: "Firebase JS SDK",
1098
+ "graphql-codegen": "GraphQL Code Generator",
1099
+ "openapi-typescript": "openapi-typescript",
1100
+ "apollo-client": "Apollo Client"
1024
1101
  },
1025
1102
  versionChannel: {
1026
1103
  stable: "Stable",
@@ -1036,6 +1113,8 @@ const EXACT_LABEL_OVERRIDES = {
1036
1113
  voltagent: "VoltAgent",
1037
1114
  langgraph: "LangGraph.js",
1038
1115
  "openai-agents": "OpenAI Agents SDK",
1116
+ "openai-sdk": "OpenAI SDK",
1117
+ "anthropic-sdk": "Anthropic SDK",
1039
1118
  "google-adk": "Google ADK",
1040
1119
  modelfusion: "ModelFusion",
1041
1120
  langchain: "LangChain",
@@ -1104,20 +1183,27 @@ const EXACT_LABEL_OVERRIDES = {
1104
1183
  "actix-web": "Actix-web",
1105
1184
  rocket: "Rocket",
1106
1185
  poem: "Poem",
1107
- loco: "Loco"
1186
+ loco: "Loco",
1187
+ warp: "Warp",
1188
+ salvo: "Salvo"
1108
1189
  },
1109
1190
  rustFrontend: {
1110
1191
  leptos: "Leptos",
1111
- dioxus: "Dioxus"
1192
+ dioxus: "Dioxus",
1193
+ yew: "Yew"
1112
1194
  },
1113
1195
  rustOrm: {
1114
1196
  "sea-orm": "SeaORM",
1115
1197
  sqlx: "SQLx",
1116
- diesel: "Diesel"
1198
+ diesel: "Diesel",
1199
+ mongodb: "MongoDB Rust Driver",
1200
+ rusqlite: "rusqlite",
1201
+ "tokio-postgres": "tokio-postgres"
1117
1202
  },
1118
1203
  rustApi: {
1119
1204
  "async-graphql": "async-graphql",
1120
- tonic: "Tonic"
1205
+ tonic: "Tonic",
1206
+ jsonrpsee: "jsonrpsee"
1121
1207
  },
1122
1208
  rustCli: {
1123
1209
  clap: "Clap",
@@ -1140,7 +1226,14 @@ const EXACT_LABEL_OVERRIDES = {
1140
1226
  "tokio-test": "Tokio Test",
1141
1227
  mockall: "Mockall",
1142
1228
  proptest: "Proptest",
1143
- insta: "Insta"
1229
+ insta: "Insta",
1230
+ rand: "rand",
1231
+ regex: "regex",
1232
+ rayon: "Rayon",
1233
+ itertools: "Itertools",
1234
+ rstest: "rstest",
1235
+ "cargo-nextest": "cargo-nextest",
1236
+ "cargo-audit": "cargo-audit"
1144
1237
  },
1145
1238
  rustLogging: {
1146
1239
  tracing: "Tracing",
@@ -1156,14 +1249,24 @@ const EXACT_LABEL_OVERRIDES = {
1156
1249
  },
1157
1250
  rustAuth: {
1158
1251
  oauth2: "OAuth2",
1159
- torii: "Torii"
1252
+ torii: "Torii",
1253
+ openidconnect: "OpenID Connect",
1254
+ "tower-sessions": "tower-sessions"
1160
1255
  },
1161
1256
  rustRealtime: { "tokio-tungstenite": "tokio-tungstenite" },
1162
- rustMessageQueue: { lapin: "Lapin (RabbitMQ)" },
1163
- rustObservability: { opentelemetry: "OpenTelemetry" },
1257
+ rustMessageQueue: {
1258
+ lapin: "Lapin (RabbitMQ)",
1259
+ rdkafka: "rdkafka (Kafka)",
1260
+ "async-nats": "async-nats"
1261
+ },
1262
+ rustObservability: {
1263
+ opentelemetry: "OpenTelemetry",
1264
+ metrics: "metrics"
1265
+ },
1164
1266
  rustTemplating: {
1165
1267
  askama: "Askama",
1166
- tera: "Tera"
1268
+ tera: "Tera",
1269
+ minijinja: "MiniJinja"
1167
1270
  },
1168
1271
  pythonWebFramework: {
1169
1272
  fastapi: "FastAPI",
@@ -1239,17 +1342,24 @@ const EXACT_LABEL_OVERRIDES = {
1239
1342
  echo: "Echo",
1240
1343
  fiber: "Fiber",
1241
1344
  chi: "Chi",
1242
- stdlib: "net/http"
1345
+ stdlib: "net/http",
1346
+ "go-zero": "go-zero",
1347
+ kratos: "Kratos",
1348
+ httprouter: "HttpRouter"
1243
1349
  },
1244
1350
  goOrm: {
1245
1351
  gorm: "GORM",
1246
1352
  sqlc: "sqlc",
1247
1353
  ent: "Ent",
1248
- bun: "Bun"
1354
+ bun: "Bun",
1355
+ sqlx: "sqlx"
1249
1356
  },
1250
1357
  goApi: {
1251
1358
  "grpc-go": "gRPC-Go",
1252
- gqlgen: "gqlgen"
1359
+ gqlgen: "gqlgen",
1360
+ "grpc-gateway": "grpc-gateway",
1361
+ "connect-go": "Connect-Go",
1362
+ "oapi-codegen": "oapi-codegen"
1253
1363
  },
1254
1364
  goCli: {
1255
1365
  cobra: "Cobra",
@@ -1265,11 +1375,15 @@ const EXACT_LABEL_OVERRIDES = {
1265
1375
  goAuth: {
1266
1376
  casbin: "Casbin",
1267
1377
  jwt: "golang-jwt",
1268
- goth: "Goth"
1378
+ goth: "Goth",
1379
+ oauth2: "golang.org/x/oauth2"
1269
1380
  },
1270
1381
  goTesting: {
1271
1382
  testify: "Testify",
1272
- gomock: "GoMock"
1383
+ gomock: "GoMock",
1384
+ testcontainers: "Testcontainers for Go",
1385
+ "ginkgo-gomega": "Ginkgo + Gomega",
1386
+ mockery: "mockery"
1273
1387
  },
1274
1388
  goRealtime: {
1275
1389
  "gorilla-websocket": "Gorilla WebSocket",
@@ -1277,7 +1391,9 @@ const EXACT_LABEL_OVERRIDES = {
1277
1391
  },
1278
1392
  goMessageQueue: {
1279
1393
  nats: "NATS",
1280
- watermill: "Watermill"
1394
+ watermill: "Watermill",
1395
+ "kafka-go": "kafka-go",
1396
+ asynq: "Asynq"
1281
1397
  },
1282
1398
  goCaching: {
1283
1399
  redis: "go-redis",
@@ -1287,7 +1403,16 @@ const EXACT_LABEL_OVERRIDES = {
1287
1403
  viper: "Viper",
1288
1404
  koanf: "Koanf"
1289
1405
  },
1290
- goObservability: { opentelemetry: "OpenTelemetry" },
1406
+ goObservability: {
1407
+ opentelemetry: "OpenTelemetry",
1408
+ prometheus: "Prometheus"
1409
+ },
1410
+ goValidation: { validator: "go-playground/validator" },
1411
+ goQuality: { "golangci-lint": "golangci-lint" },
1412
+ goMigrations: { "golang-migrate": "golang-migrate" },
1413
+ goTemplating: { templ: "templ" },
1414
+ goProtoTooling: { buf: "Buf" },
1415
+ goDI: { fx: "Uber Fx" },
1291
1416
  javaLanguage: {
1292
1417
  java: "Java",
1293
1418
  kotlin: "Kotlin"
@@ -1404,21 +1529,28 @@ const EXACT_LABEL_OVERRIDES = {
1404
1529
  },
1405
1530
  elixirOrm: {
1406
1531
  ecto: "Ecto",
1407
- "ecto-sql": "Ecto SQL"
1532
+ "ecto-sql": "Ecto SQL",
1533
+ myxql: "MyXQL",
1534
+ ecto_sqlite3: "ecto_sqlite3"
1408
1535
  },
1409
1536
  elixirAuth: {
1410
1537
  "phx-gen-auth": "phx.gen.auth",
1411
1538
  ueberauth: "Ueberauth",
1412
- guardian: "Guardian"
1539
+ guardian: "Guardian",
1540
+ pow: "Pow"
1413
1541
  },
1414
1542
  elixirApi: {
1415
1543
  rest: "Phoenix REST",
1416
1544
  absinthe: "Absinthe GraphQL",
1417
- grpc: "gRPC (grpc-elixir)"
1545
+ grpc: "gRPC (grpc-elixir)",
1546
+ open_api_spex: "OpenApiSpex"
1418
1547
  },
1419
1548
  elixirLibraries: {
1420
1549
  broadway: "Broadway",
1421
- nx: "Nx (Numerical Elixir)"
1550
+ nx: "Nx (Numerical Elixir)",
1551
+ ex_aws: "ExAws",
1552
+ floki: "Floki",
1553
+ rustler: "Rustler"
1422
1554
  },
1423
1555
  elixirRealtime: {
1424
1556
  channels: "Phoenix Channels",
@@ -1436,30 +1568,48 @@ const EXACT_LABEL_OVERRIDES = {
1436
1568
  },
1437
1569
  elixirHttp: {
1438
1570
  req: "Req",
1439
- finch: "Finch"
1571
+ finch: "Finch",
1572
+ tesla: "Tesla"
1440
1573
  },
1441
1574
  elixirJson: { jason: "Jason" },
1442
- elixirEmail: { swoosh: "Swoosh" },
1575
+ elixirEmail: {
1576
+ swoosh: "Swoosh",
1577
+ bamboo: "Bamboo"
1578
+ },
1443
1579
  elixirCaching: {
1444
1580
  cachex: "Cachex",
1445
- nebulex: "Nebulex"
1581
+ nebulex: "Nebulex",
1582
+ redix: "Redix"
1446
1583
  },
1447
1584
  elixirObservability: {
1448
1585
  telemetry: "Telemetry",
1449
1586
  opentelemetry: "OpenTelemetry",
1450
- prom_ex: "PromEx"
1587
+ prom_ex: "PromEx",
1588
+ sentry: "Sentry"
1451
1589
  },
1452
1590
  elixirTesting: {
1453
1591
  ex_unit: "ExUnit",
1454
1592
  mox: "Mox",
1455
1593
  bypass: "Bypass",
1456
- wallaby: "Wallaby"
1594
+ wallaby: "Wallaby",
1595
+ stream_data: "StreamData",
1596
+ ex_machina: "ExMachina"
1457
1597
  },
1458
1598
  elixirQuality: {
1459
1599
  credo: "Credo",
1460
1600
  dialyxir: "Dialyxir",
1461
- sobelow: "Sobelow"
1462
- },
1601
+ sobelow: "Sobelow",
1602
+ excoveralls: "ExCoveralls",
1603
+ mix_audit: "MixAudit"
1604
+ },
1605
+ elixirI18n: { gettext: "Gettext" },
1606
+ elixirHttpServer: {
1607
+ bandit: "Bandit",
1608
+ cowboy: "Cowboy"
1609
+ },
1610
+ elixirApplicationFramework: { ash: "Ash Framework" },
1611
+ elixirDocumentation: { ex_doc: "ExDoc" },
1612
+ elixirClustering: { libcluster: "libcluster" },
1463
1613
  elixirDeploy: {
1464
1614
  docker: "Docker",
1465
1615
  fly: "Fly.io",
@@ -1571,6 +1721,7 @@ const OPTION_CATEGORY_METADATA = {
1571
1721
  mobileDeepLinking: buildCategoryMetadata("mobileDeepLinking"),
1572
1722
  codeQuality: buildCategoryMetadata("codeQuality"),
1573
1723
  documentation: buildCategoryMetadata("documentation"),
1724
+ appShells: buildCategoryMetadata("appShells"),
1574
1725
  appPlatforms: buildCategoryMetadata("appPlatforms"),
1575
1726
  packageManager: buildCategoryMetadata("packageManager"),
1576
1727
  workspaceShape: buildCategoryMetadata("workspaceShape"),
@@ -1628,6 +1779,12 @@ const OPTION_CATEGORY_METADATA = {
1628
1779
  goCaching: buildCategoryMetadata("goCaching"),
1629
1780
  goConfig: buildCategoryMetadata("goConfig"),
1630
1781
  goObservability: buildCategoryMetadata("goObservability"),
1782
+ goValidation: buildCategoryMetadata("goValidation"),
1783
+ goQuality: buildCategoryMetadata("goQuality"),
1784
+ goMigrations: buildCategoryMetadata("goMigrations"),
1785
+ goTemplating: buildCategoryMetadata("goTemplating"),
1786
+ goProtoTooling: buildCategoryMetadata("goProtoTooling"),
1787
+ goDI: buildCategoryMetadata("goDI"),
1631
1788
  javaLanguage: buildCategoryMetadata("javaLanguage"),
1632
1789
  javaWebFramework: buildCategoryMetadata("javaWebFramework"),
1633
1790
  javaBuildTool: buildCategoryMetadata("javaBuildTool"),
@@ -1662,6 +1819,11 @@ const OPTION_CATEGORY_METADATA = {
1662
1819
  elixirObservability: buildCategoryMetadata("elixirObservability"),
1663
1820
  elixirTesting: buildCategoryMetadata("elixirTesting"),
1664
1821
  elixirQuality: buildCategoryMetadata("elixirQuality"),
1822
+ elixirI18n: buildCategoryMetadata("elixirI18n"),
1823
+ elixirHttpServer: buildCategoryMetadata("elixirHttpServer"),
1824
+ elixirApplicationFramework: buildCategoryMetadata("elixirApplicationFramework"),
1825
+ elixirDocumentation: buildCategoryMetadata("elixirDocumentation"),
1826
+ elixirClustering: buildCategoryMetadata("elixirClustering"),
1665
1827
  elixirDeploy: buildCategoryMetadata("elixirDeploy"),
1666
1828
  elixirLibraries: buildCategoryMetadata("elixirLibraries")
1667
1829
  };
@@ -1720,6 +1882,8 @@ const PARAGLIDE_COMPATIBLE_FRONTENDS = new Set([
1720
1882
  "tanstack-start",
1721
1883
  "react-router",
1722
1884
  "react-vite",
1885
+ "vanilla-vite",
1886
+ "vue",
1723
1887
  "svelte",
1724
1888
  "solid",
1725
1889
  "solid-start",
@@ -2237,6 +2401,19 @@ const analyzeStackCompatibility = (stack) => {
2237
2401
  }
2238
2402
  }
2239
2403
  if (nextStack.backend !== "convex" && nextStack.backend !== "none") {
2404
+ if (nextStack.webFrontend.some((frontend) => ["vanilla-vite", "vue"].includes(frontend)) && [
2405
+ "trpc",
2406
+ "orpc",
2407
+ "ts-rest",
2408
+ "garph"
2409
+ ].includes(nextStack.api)) {
2410
+ nextStack.api = "graphql-yoga";
2411
+ changed = true;
2412
+ changes.push({
2413
+ category: "api",
2414
+ message: "API set to 'GraphQL Yoga' (supported by standalone Vite frontends)"
2415
+ });
2416
+ }
2240
2417
  if (nextStack.webFrontend.some((f) => [
2241
2418
  "nuxt",
2242
2419
  "svelte",
@@ -2365,6 +2542,33 @@ const analyzeStackCompatibility = (stack) => {
2365
2542
  });
2366
2543
  }
2367
2544
  }
2545
+ if (nextStack.payments === "paypal") {
2546
+ const hasWebFrontend = nextStack.webFrontend.some((f) => f !== "none");
2547
+ if (!hasWebFrontend || ["none", "convex"].includes(nextStack.backend)) {
2548
+ nextStack.payments = "none";
2549
+ changed = true;
2550
+ changes.push({
2551
+ category: "payments",
2552
+ message: hasWebFrontend ? "Payments set to 'None' (PayPal requires a standalone or fullstack backend)" : "Payments set to 'None' (PayPal requires a web frontend)"
2553
+ });
2554
+ }
2555
+ }
2556
+ if (["openai-sdk", "anthropic-sdk"].includes(nextStack.aiSdk) && ["none", "convex"].includes(nextStack.backend)) {
2557
+ nextStack.aiSdk = "none";
2558
+ changed = true;
2559
+ changes.push({
2560
+ category: "ai",
2561
+ message: "AI SDK set to 'None' (direct provider SDKs require a backend)"
2562
+ });
2563
+ }
2564
+ if (nextStack.realtime === "ws" && nextStack.backend !== "express") {
2565
+ nextStack.realtime = "none";
2566
+ changed = true;
2567
+ changes.push({
2568
+ category: "realtime",
2569
+ message: "Realtime set to 'None' (the ws integration requires Express)"
2570
+ });
2571
+ }
2368
2572
  if (nextStack.email !== "none") {
2369
2573
  if (nextStack.backend === "convex") {
2370
2574
  nextStack.email = "none";
@@ -2668,6 +2872,23 @@ const analyzeStackCompatibility = (stack) => {
2668
2872
  });
2669
2873
  }
2670
2874
  }
2875
+ const styledComponentsFrontends = new Set([
2876
+ "tanstack-router",
2877
+ "react-router",
2878
+ "react-vite",
2879
+ "tanstack-start",
2880
+ "next",
2881
+ "vinext",
2882
+ "redwood"
2883
+ ]);
2884
+ if (nextStack.cssFramework === "styled-components" && !nextStack.webFrontend.some((frontend) => styledComponentsFrontends.has(frontend))) {
2885
+ nextStack.cssFramework = "none";
2886
+ changed = true;
2887
+ changes.push({
2888
+ category: "cssFramework",
2889
+ message: "CSS framework set to 'None' (styled-components requires a React frontend)"
2890
+ });
2891
+ }
2671
2892
  if ([
2672
2893
  "shadcn-ui",
2673
2894
  "shadcn-svelte",
@@ -2770,6 +2991,26 @@ const analyzeStackCompatibility = (stack) => {
2770
2991
  message: "Tauri removed (requires compatible frontend)"
2771
2992
  });
2772
2993
  }
2994
+ for (const platform of ["electron", "capacitor"]) if (nextStack.appPlatforms.includes(platform) && !validateAddonCompatibility(platform, nextStack.webFrontend).isCompatible) {
2995
+ nextStack.appPlatforms = nextStack.appPlatforms.filter((addon) => addon !== platform);
2996
+ changed = true;
2997
+ changes.push({
2998
+ category: "appPlatforms",
2999
+ message: `${platform === "electron" ? "Electron" : "Capacitor"} removed (requires compatible frontend)`
3000
+ });
3001
+ }
3002
+ if (nextStack.appPlatforms.includes("graphql-codegen") && ![
3003
+ "garph",
3004
+ "graphql-yoga",
3005
+ "apollo-server"
3006
+ ].includes(nextStack.api) && !nextStack.webFrontend.includes("redwood")) {
3007
+ nextStack.appPlatforms = nextStack.appPlatforms.filter((platform) => platform !== "graphql-codegen");
3008
+ changed = true;
3009
+ changes.push({
3010
+ category: "appPlatforms",
3011
+ message: "GraphQL Code Generator removed (requires a GraphQL API selection)"
3012
+ });
3013
+ }
2773
3014
  if (nextStack.examples.includes("ai")) {
2774
3015
  if (nextStack.webFrontend.includes("solid") || nextStack.webFrontend.includes("solid-start")) {
2775
3016
  nextStack.examples = nextStack.examples.filter((e) => e !== "ai");
@@ -2818,7 +3059,33 @@ const analyzeStackCompatibility = (stack) => {
2818
3059
  });
2819
3060
  }
2820
3061
  }
2821
- if (nextStack.webFrontend.includes("fresh")) {
3062
+ const isFresh = nextStack.webFrontend.includes("fresh");
3063
+ const hasStandaloneViteFrontend = nextStack.webFrontend.some((frontend) => ["vanilla-vite", "vue"].includes(frontend));
3064
+ if (hasStandaloneViteFrontend && nextStack.forms !== "none") {
3065
+ nextStack.forms = "none";
3066
+ changed = true;
3067
+ changes.push({
3068
+ category: "forms",
3069
+ message: "Forms set to 'None' (standalone Vue and Vanilla integrations are not wired yet)"
3070
+ });
3071
+ }
3072
+ if (hasStandaloneViteFrontend && nextStack.cms !== "none" && nextStack.cms !== "contentful") {
3073
+ nextStack.cms = "none";
3074
+ changed = true;
3075
+ changes.push({
3076
+ category: "cms",
3077
+ message: "CMS set to 'None' (standalone Vue and Vanilla CMS templates are not wired yet)"
3078
+ });
3079
+ }
3080
+ if (hasStandaloneViteFrontend && nextStack.featureFlags !== "none") {
3081
+ nextStack.featureFlags = "none";
3082
+ changed = true;
3083
+ changes.push({
3084
+ category: "featureFlags",
3085
+ message: "Feature flags set to 'None' (standalone Vue and Vanilla client integrations are not wired yet)"
3086
+ });
3087
+ }
3088
+ if (isFresh) {
2822
3089
  if (nextStack.forms === "tanstack-form") {
2823
3090
  nextStack.forms = "none";
2824
3091
  changed = true;
@@ -2972,7 +3239,9 @@ const analyzeStackCompatibility = (stack) => {
2972
3239
  "elixirAuth",
2973
3240
  "elixirApi",
2974
3241
  "elixirRealtime",
2975
- "elixirObservability"
3242
+ "elixirObservability",
3243
+ "elixirI18n",
3244
+ "elixirHttpServer"
2976
3245
  ]) {
2977
3246
  const value = nextStack[key];
2978
3247
  if (key !== "elixirObservability" ? value !== "none" : value === "phoenix-telemetry") {
@@ -3034,6 +3303,19 @@ const analyzeStackCompatibility = (stack) => {
3034
3303
  message: "Elixir auth set to 'None' (phx.gen.auth requires Ecto SQL with PostgreSQL)"
3035
3304
  });
3036
3305
  }
3306
+ const sqlBackedElixirOrms = new Set([
3307
+ "ecto-sql",
3308
+ "myxql",
3309
+ "ecto_sqlite3"
3310
+ ]);
3311
+ if (nextStack.elixirAuth === "pow" && !sqlBackedElixirOrms.has(nextStack.elixirOrm)) {
3312
+ nextStack.elixirAuth = "none";
3313
+ changed = true;
3314
+ changes.push({
3315
+ category: "elixirAuth",
3316
+ message: "Elixir auth set to 'None' (Pow requires an Ecto SQL repository)"
3317
+ });
3318
+ }
3037
3319
  }
3038
3320
  if (nextStack.webDeploy !== "none" && !nextStack.webFrontend.some((f) => f !== "none")) {
3039
3321
  nextStack.webDeploy = "none";
@@ -3043,6 +3325,16 @@ const analyzeStackCompatibility = (stack) => {
3043
3325
  message: "Web deploy set to 'None' (no web frontend)"
3044
3326
  });
3045
3327
  }
3328
+ const unsupportedWebDeployFrontend = getUnsupportedWebDeployFrontend(nextStack.webDeploy, nextStack.webFrontend);
3329
+ if (nextStack.webDeploy !== "none" && unsupportedWebDeployFrontend) {
3330
+ const webDeploy = nextStack.webDeploy;
3331
+ nextStack.webDeploy = "none";
3332
+ changed = true;
3333
+ changes.push({
3334
+ category: "webDeploy",
3335
+ message: `Web deploy set to 'None' ('${webDeploy}' is not wired for the '${unsupportedWebDeployFrontend}' frontend)`
3336
+ });
3337
+ }
3046
3338
  if (nextStack.serverDeploy === "cloudflare") {
3047
3339
  if (nextStack.runtime !== "workers" || nextStack.backend !== "hono") {
3048
3340
  nextStack.serverDeploy = "none";
@@ -3094,6 +3386,16 @@ const analyzeStackCompatibility = (stack) => {
3094
3386
  * - Follow CLI behavior: filter options based on UPSTREAM selections only
3095
3387
  */
3096
3388
  const getDisabledReason = (currentStack, category, optionId) => {
3389
+ const hasStandaloneViteFrontend = currentStack.webFrontend.some((frontend) => ["vanilla-vite", "vue"].includes(frontend));
3390
+ if (category === "api" && hasStandaloneViteFrontend && [
3391
+ "trpc",
3392
+ "orpc",
3393
+ "ts-rest",
3394
+ "garph"
3395
+ ].includes(optionId)) return "Standalone Vite frontends support only GraphQL and OpenAPI API integrations";
3396
+ if (category === "forms" && hasStandaloneViteFrontend && optionId !== "none") return "Form library integrations are not yet wired for standalone Vue or Vanilla Vite";
3397
+ if (category === "cms" && hasStandaloneViteFrontend && optionId !== "none" && optionId !== "contentful") return "CMS integrations other than Contentful are not yet wired for standalone Vue or Vanilla Vite";
3398
+ if (category === "featureFlags" && hasStandaloneViteFrontend && optionId !== "none") return "Feature flag client integrations are not yet wired for standalone Vue or Vanilla Vite";
3097
3399
  if (currentStack.backend === "convex") {
3098
3400
  if (category === "runtime" && optionId !== "none") return "Convex provides its own runtime";
3099
3401
  if (category === "database" && optionId !== "none") return "Convex provides its own database";
@@ -3173,6 +3475,15 @@ const getDisabledReason = (currentStack, category, optionId) => {
3173
3475
  if (category === "caching" && optionId === "upstash-redis") return "The Upstash Redis integration is Java-only in the Java ecosystem scaffold";
3174
3476
  if (category === "observability" && optionId === "sentry") return "The Sentry integration is Java-only in the Java ecosystem scaffold";
3175
3477
  }
3478
+ if (currentStack.ecosystem === "rust") {
3479
+ const filterOnlyFramework = currentStack.rustWebFramework === "warp" || currentStack.rustWebFramework === "salvo";
3480
+ if (category === "rustApi" && filterOnlyFramework && optionId !== "none" && optionId !== "jsonrpsee") return "Warp and Salvo currently support REST or the standalone jsonrpsee server";
3481
+ if (category === "rustWebFramework" && (optionId === "warp" || optionId === "salvo") && currentStack.rustApi !== "none" && currentStack.rustApi !== "jsonrpsee") return "Warp and Salvo currently support REST or the standalone jsonrpsee server";
3482
+ if (category === "rustApi" && currentStack.rustWebFramework === "loco" && optionId === "jsonrpsee") return "Loco owns the server boot sequence; jsonrpsee is available with the other Rust frameworks";
3483
+ if (category === "rustWebFramework" && optionId === "loco" && currentStack.rustApi === "jsonrpsee") return "Loco owns the server boot sequence and cannot start the generated jsonrpsee server";
3484
+ if (category === "rustAuth" && optionId === "tower-sessions" && currentStack.rustWebFramework !== "axum") return "The generated tower-sessions middleware is wired specifically for Axum";
3485
+ if (category === "rustWebFramework" && optionId !== "axum" && currentStack.rustAuth === "tower-sessions") return "tower-sessions requires the generated Axum middleware stack";
3486
+ }
3176
3487
  const graphDisabledReason = category === "payments" && optionId === "revenuecat" || category === "i18n" && optionId === "intlayer" ? {
3177
3488
  handled: false,
3178
3489
  authoritative: false,
@@ -3351,12 +3662,17 @@ const getDisabledReason = (currentStack, category, optionId) => {
3351
3662
  if (category === "payments" && optionId === "revenuecat") {
3352
3663
  if (!hasRevenueCatCompatibleNativeFrontend(currentStack.nativeFrontend)) return "RevenueCat payments requires a native frontend (native-bare, native-uniwind, or native-unistyles)";
3353
3664
  }
3665
+ if (category === "payments" && optionId === "paypal") {
3666
+ if (!currentStack.webFrontend.some((f) => f !== "none")) return "PayPal requires a web frontend";
3667
+ if (["none", "convex"].includes(currentStack.backend)) return "PayPal checkout requires a standalone or fullstack backend";
3668
+ }
3354
3669
  if (category === "cms" && optionId === "payload") {
3355
3670
  if (!currentStack.webFrontend.includes("next")) return "Payload CMS v3 requires Next.js";
3356
3671
  }
3357
3672
  if (category === "cms" && optionId === "keystatic") {
3358
3673
  if (!currentStack.webFrontend.includes("next")) return "Keystatic is currently scaffolded for Next.js only because @keystatic/astro is not Astro 7-compatible yet.";
3359
3674
  }
3675
+ if (category === "realtime" && optionId === "ws" && currentStack.backend !== "express") return "The ws integration is currently wired for the Express backend";
3360
3676
  if (category === "email" && optionId !== "none") {
3361
3677
  if (currentStack.ecosystem !== "typescript") return null;
3362
3678
  if (currentStack.backend === "convex") return "Email integration is not available with Convex backend";
@@ -3382,6 +3698,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
3382
3698
  if (currentStack.ecosystem !== "typescript") return "Vector database is only available for the TypeScript ecosystem";
3383
3699
  }
3384
3700
  if (category === "ai" && requiresChatSdkVercelAI(currentStack) && optionId !== "vercel-ai") return "Chat SDK example (Nuxt/Hono profile) requires Vercel AI SDK in v1";
3701
+ if (category === "ai" && ["openai-sdk", "anthropic-sdk"].includes(optionId) && ["none", "convex"].includes(currentStack.backend)) return "Direct AI provider SDKs require a standalone or fullstack backend";
3385
3702
  if (category === "ai" && optionId === "tanstack-ai") {
3386
3703
  const compatibleFrontends = [
3387
3704
  "tanstack-router",
@@ -3403,11 +3720,32 @@ const getDisabledReason = (currentStack, category, optionId) => {
3403
3720
  "tanstack-db",
3404
3721
  "tanstack-pacer"
3405
3722
  ].includes(optionId) && currentStack.webFrontend.length === 1 && currentStack.webFrontend[0] === "astro" && (!currentStack.astroIntegration || currentStack.astroIntegration === "none")) return "TanStack libraries with Astro require a UI framework integration (React, Vue, Svelte, or Solid)";
3723
+ if (optionId === "graphql-codegen" && ![
3724
+ "garph",
3725
+ "graphql-yoga",
3726
+ "apollo-server"
3727
+ ].includes(currentStack.api) && !currentStack.webFrontend.includes("redwood")) return "GraphQL Code Generator requires a GraphQL API selection";
3728
+ if (optionId === "openapi-typescript" && currentStack.api !== "openapi") return "openapi-typescript requires the OpenAPI API selection";
3729
+ if (optionId === "openapi-typescript" && currentStack.backend === "self") return "openapi-typescript requires a standalone backend that exposes an OpenAPI schema";
3730
+ if (optionId === "apollo-client" && ![
3731
+ "garph",
3732
+ "graphql-yoga",
3733
+ "apollo-server"
3734
+ ].includes(currentStack.api)) return "Apollo Client requires a GraphQL API selection";
3406
3735
  }
3407
3736
  if (category === "cssFramework") {
3408
3737
  if (!currentStack.webFrontend.some((f) => f !== "none")) {
3409
3738
  if (optionId !== "none") return "CSS framework requires a web frontend";
3410
3739
  }
3740
+ if (optionId === "styled-components" && !currentStack.webFrontend.some((f) => [
3741
+ "tanstack-router",
3742
+ "react-router",
3743
+ "react-vite",
3744
+ "tanstack-start",
3745
+ "next",
3746
+ "vinext",
3747
+ "redwood"
3748
+ ].includes(f))) return "styled-components requires a React frontend";
3411
3749
  if ([
3412
3750
  "shadcn-ui",
3413
3751
  "shadcn-svelte",
@@ -3543,6 +3881,16 @@ const getDisabledReason = (currentStack, category, optionId) => {
3543
3881
  if (category === "pythonApi") {
3544
3882
  if (optionId !== "none" && currentStack.pythonWebFramework !== "django") return "Python API frameworks currently require Django";
3545
3883
  }
3884
+ if (category === "goMigrations" && optionId !== "none" && currentStack.ecosystem === "go" && ![
3885
+ "sqlite",
3886
+ "postgres",
3887
+ "mysql"
3888
+ ].includes(currentStack.database)) return "Go migrations require SQLite, PostgreSQL, or MySQL";
3889
+ if (category === "database" && currentStack.ecosystem === "go" && currentStack.goMigrations !== "none" && ![
3890
+ "sqlite",
3891
+ "postgres",
3892
+ "mysql"
3893
+ ].includes(optionId)) return "The selected Go migration tool requires SQLite, PostgreSQL, or MySQL";
3546
3894
  if (category === "javaWebFramework") {
3547
3895
  if (optionId !== "none" && currentStack.javaBuildTool === "none") return "Java web frameworks require Maven or Gradle";
3548
3896
  }
@@ -3593,11 +3941,30 @@ const getDisabledReason = (currentStack, category, optionId) => {
3593
3941
  "elixirObservability",
3594
3942
  "elixirTesting",
3595
3943
  "elixirQuality",
3944
+ "elixirI18n",
3945
+ "elixirHttpServer",
3946
+ "elixirApplicationFramework",
3947
+ "elixirDocumentation",
3948
+ "elixirClustering",
3596
3949
  "elixirDeploy"
3597
3950
  ]).has(category) && optionId !== "none") {
3598
3951
  if (currentStack.ecosystem !== "elixir") return "Elixir options only apply when the Elixir ecosystem is selected";
3599
3952
  }
3600
3953
  if (category === "elixirTesting" && optionId === "wallaby" && currentStack.ecosystem === "elixir" && currentStack.elixirWebFramework === "none") return "Wallaby browser tests require Phoenix";
3954
+ if (category === "elixirTesting" && optionId === "ex_machina" && currentStack.ecosystem === "elixir" && ![
3955
+ "ecto-sql",
3956
+ "myxql",
3957
+ "ecto_sqlite3"
3958
+ ].includes(currentStack.elixirOrm)) return "ExMachina requires an Ecto SQL repository";
3959
+ if (category === "elixirAuth" && optionId === "pow" && currentStack.ecosystem === "elixir" && (currentStack.elixirWebFramework === "none" || ![
3960
+ "ecto-sql",
3961
+ "myxql",
3962
+ "ecto_sqlite3"
3963
+ ].includes(currentStack.elixirOrm))) return "Pow requires Phoenix and an Ecto SQL repository";
3964
+ if ((category === "elixirApi" && optionId === "open_api_spex" || category === "elixirI18n" && optionId === "gettext") && currentStack.ecosystem === "elixir" && currentStack.elixirWebFramework === "none") return `${getCategoryDisplayName(category)} requires Phoenix`;
3965
+ if (category === "elixirHttpServer" && currentStack.ecosystem === "elixir" && (optionId === "none" && currentStack.elixirWebFramework !== "none" || optionId !== "none" && currentStack.elixirWebFramework === "none")) return currentStack.elixirWebFramework === "none" ? "HTTP server adapters require Phoenix" : "Phoenix requires Bandit or Cowboy";
3966
+ if (category === "elixirJobs" && optionId === "oban" && currentStack.ecosystem === "elixir" && currentStack.elixirOrm !== "ecto-sql") return "Oban requires the PostgreSQL Ecto SQL option";
3967
+ if (category === "elixirOrm" && ["myxql", "ecto_sqlite3"].includes(optionId) && currentStack.ecosystem === "elixir" && currentStack.elixirJobs === "oban") return "Oban requires PostgreSQL-backed Ecto SQL";
3601
3968
  if (category === "elixirWebFramework" && optionId !== "none" && currentStack.ecosystem !== "elixir") return "Elixir web frameworks are available only in the Elixir ecosystem";
3602
3969
  if (category === "elixirJson" && optionId === "none" && currentStack.ecosystem === "elixir" && currentStack.elixirWebFramework !== "none") return "Phoenix JSON scaffolds require Jason";
3603
3970
  return null;
@@ -3642,6 +4009,11 @@ const ELIXIR_GRAPH_DISABLED_REASON_ROLES = {
3642
4009
  elixirObservability: "observability",
3643
4010
  elixirTesting: "testing",
3644
4011
  elixirQuality: "codeQuality",
4012
+ elixirI18n: "i18n",
4013
+ elixirHttpServer: "runtime",
4014
+ elixirApplicationFramework: "libraries",
4015
+ elixirDocumentation: "documentation",
4016
+ elixirClustering: "config",
3645
4017
  elixirDeploy: "deploy"
3646
4018
  };
3647
4019
  function getElixirGraphBinding(currentStack, category) {
@@ -4030,6 +4402,54 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
4030
4402
  authoritative: true,
4031
4403
  candidateIdPrefix: "candidate:native"
4032
4404
  },
4405
+ goValidation: {
4406
+ role: "validation",
4407
+ ecosystem: "go",
4408
+ ownerRole: "backend",
4409
+ ownerEcosystem: "go",
4410
+ currentEcosystem: "go",
4411
+ authoritative: true
4412
+ },
4413
+ goQuality: {
4414
+ role: "codeQuality",
4415
+ ecosystem: "go",
4416
+ ownerRole: "backend",
4417
+ ownerEcosystem: "go",
4418
+ currentEcosystem: "go",
4419
+ authoritative: true
4420
+ },
4421
+ goMigrations: {
4422
+ role: "migrations",
4423
+ ecosystem: "go",
4424
+ ownerRole: "backend",
4425
+ ownerEcosystem: "go",
4426
+ currentEcosystem: "go",
4427
+ authoritative: true
4428
+ },
4429
+ goTemplating: {
4430
+ role: "templating",
4431
+ ecosystem: "go",
4432
+ ownerRole: "backend",
4433
+ ownerEcosystem: "go",
4434
+ currentEcosystem: "go",
4435
+ authoritative: true
4436
+ },
4437
+ goProtoTooling: {
4438
+ role: "buildTool",
4439
+ ecosystem: "go",
4440
+ ownerRole: "backend",
4441
+ ownerEcosystem: "go",
4442
+ currentEcosystem: "go",
4443
+ authoritative: true
4444
+ },
4445
+ goDI: {
4446
+ role: "libraries",
4447
+ ecosystem: "go",
4448
+ ownerRole: "backend",
4449
+ ownerEcosystem: "go",
4450
+ currentEcosystem: "go",
4451
+ authoritative: true
4452
+ },
4033
4453
  dotnetOrm: {
4034
4454
  role: "orm",
4035
4455
  ecosystem: "dotnet",
@@ -4165,6 +4585,8 @@ const WEB_FRAMEWORKS = [
4165
4585
  "tanstack-router",
4166
4586
  "react-router",
4167
4587
  "react-vite",
4588
+ "vanilla-vite",
4589
+ "vue",
4168
4590
  "tanstack-start",
4169
4591
  "next",
4170
4592
  "vinext",
@@ -4179,11 +4601,32 @@ const WEB_FRAMEWORKS = [
4179
4601
  "fresh",
4180
4602
  "none"
4181
4603
  ];
4604
+ const CODEGEN_COMPATIBLE_FRONTENDS = [
4605
+ "tanstack-router",
4606
+ "react-router",
4607
+ "react-vite",
4608
+ "vanilla-vite",
4609
+ "vue",
4610
+ "tanstack-start",
4611
+ "next",
4612
+ "vinext",
4613
+ "nuxt",
4614
+ "svelte",
4615
+ "solid",
4616
+ "solid-start",
4617
+ "astro",
4618
+ "qwik",
4619
+ "angular",
4620
+ "redwood",
4621
+ "fresh"
4622
+ ];
4182
4623
  const ADDON_COMPATIBILITY = {
4183
4624
  pwa: [
4184
4625
  "tanstack-router",
4185
4626
  "react-router",
4186
4627
  "react-vite",
4628
+ "vanilla-vite",
4629
+ "vue",
4187
4630
  "solid",
4188
4631
  "next",
4189
4632
  "vinext",
@@ -4197,6 +4640,8 @@ const ADDON_COMPATIBILITY = {
4197
4640
  "tanstack-router",
4198
4641
  "react-router",
4199
4642
  "react-vite",
4643
+ "vanilla-vite",
4644
+ "vue",
4200
4645
  "nuxt",
4201
4646
  "svelte",
4202
4647
  "solid",
@@ -4207,7 +4652,23 @@ const ADDON_COMPATIBILITY = {
4207
4652
  "redwood",
4208
4653
  "fresh"
4209
4654
  ],
4655
+ electron: [
4656
+ "tanstack-router",
4657
+ "react-vite",
4658
+ "vanilla-vite",
4659
+ "vue",
4660
+ "solid"
4661
+ ],
4662
+ capacitor: [
4663
+ "tanstack-router",
4664
+ "react-vite",
4665
+ "vanilla-vite",
4666
+ "vue",
4667
+ "solid"
4668
+ ],
4210
4669
  biome: [],
4670
+ eslint: [],
4671
+ prettier: [],
4211
4672
  husky: [],
4212
4673
  lefthook: [],
4213
4674
  turborepo: [],
@@ -4231,6 +4692,55 @@ const ADDON_COMPATIBILITY = {
4231
4692
  "svelte",
4232
4693
  "solid"
4233
4694
  ],
4695
+ axios: [
4696
+ "tanstack-router",
4697
+ "react-router",
4698
+ "react-vite",
4699
+ "vanilla-vite",
4700
+ "vue",
4701
+ "tanstack-start",
4702
+ "next",
4703
+ "vinext",
4704
+ "nuxt",
4705
+ "svelte",
4706
+ "solid",
4707
+ "solid-start",
4708
+ "astro",
4709
+ "qwik",
4710
+ "angular"
4711
+ ],
4712
+ firebase: [
4713
+ "tanstack-router",
4714
+ "react-router",
4715
+ "react-vite",
4716
+ "vanilla-vite",
4717
+ "vue",
4718
+ "tanstack-start",
4719
+ "next",
4720
+ "vinext",
4721
+ "nuxt",
4722
+ "svelte",
4723
+ "solid",
4724
+ "solid-start",
4725
+ "astro",
4726
+ "qwik",
4727
+ "angular"
4728
+ ],
4729
+ "graphql-codegen": CODEGEN_COMPATIBLE_FRONTENDS,
4730
+ "openapi-typescript": CODEGEN_COMPATIBLE_FRONTENDS,
4731
+ "apollo-client": [
4732
+ "tanstack-router",
4733
+ "react-router",
4734
+ "react-vite",
4735
+ "vue",
4736
+ "tanstack-start",
4737
+ "next",
4738
+ "vinext",
4739
+ "nuxt",
4740
+ "svelte",
4741
+ "solid",
4742
+ "solid-start"
4743
+ ],
4234
4744
  swr: [
4235
4745
  "tanstack-router",
4236
4746
  "react-router",
@@ -4334,6 +4844,7 @@ function allowedApisForFrontends(frontends = [], astroIntegration) {
4334
4844
  const includesAngular = frontends.includes("angular");
4335
4845
  const includesRedwood = frontends.includes("redwood");
4336
4846
  const includesFresh = frontends.includes("fresh");
4847
+ const includesStandaloneVite = frontends.includes("vanilla-vite") || frontends.includes("vue");
4337
4848
  const includesNative = frontends.some((frontend) => [
4338
4849
  "native-bare",
4339
4850
  "native-uniwind",
@@ -4356,6 +4867,12 @@ function allowedApisForFrontends(frontends = [], astroIntegration) {
4356
4867
  "garph",
4357
4868
  "none"
4358
4869
  ];
4870
+ if (includesStandaloneVite) return [
4871
+ "graphql-yoga",
4872
+ "apollo-server",
4873
+ "openapi",
4874
+ "none"
4875
+ ];
4359
4876
  if (includesQwik || includesAngular || includesRedwood || includesFresh) return ["graphql-yoga", "none"];
4360
4877
  const includesSolidStartApi = frontends.includes("solid-start");
4361
4878
  if (includesNuxt || includesSvelte || includesSolid || includesSolidStartApi) return [
@@ -4390,7 +4907,23 @@ function getApiFrontendCompatibilityIssue(api, frontends = [], astroIntegration)
4390
4907
  const includesRedwood = frontends.includes("redwood");
4391
4908
  const includesFresh = frontends.includes("fresh");
4392
4909
  const includesSolidStart = frontends.includes("solid-start");
4910
+ const includesStandaloneVite = frontends.includes("vanilla-vite") || frontends.includes("vue");
4393
4911
  const isReactOnlyApi = api === "trpc" || api === "ts-rest" || api === "garph" || api === "apollo-server";
4912
+ if (includesStandaloneVite && (api === "trpc" || api === "orpc" || api === "ts-rest" || api === "garph")) return {
4913
+ code: "STANDALONE_VITE_API_UNSUPPORTED",
4914
+ message: "Standalone Vite frontends support only GraphQL and OpenAPI API integrations.",
4915
+ category: "api",
4916
+ optionId: api,
4917
+ provided: {
4918
+ api,
4919
+ frontend: frontends.includes("vanilla-vite") ? "vanilla-vite" : "vue"
4920
+ },
4921
+ suggestions: [
4922
+ "Use --api graphql-yoga, --api apollo-server, or --api openapi",
4923
+ "Choose a React-based frontend for tRPC, oRPC, ts-rest, or garph",
4924
+ "Use --api none"
4925
+ ]
4926
+ };
4394
4927
  if ((includesNuxt || includesSvelte || includesSolid || includesSolidStart) && isReactOnlyApi) {
4395
4928
  const incompatibleFrontend = includesNuxt ? "nuxt" : includesSvelte ? "svelte" : includesSolid ? "solid" : "solid-start";
4396
4929
  return {
@@ -4558,21 +5091,33 @@ function getCompatibleUILibraries(frontends = [], astroIntegration) {
4558
5091
  return compatibility.frontends.includes(webFrontend);
4559
5092
  });
4560
5093
  }
4561
- function getCompatibleCSSFrameworks(uiLibrary) {
4562
- if (!uiLibrary || uiLibrary === "none") return [
5094
+ function getCompatibleCSSFrameworks(uiLibrary, frontends = []) {
5095
+ const frameworks = !uiLibrary || uiLibrary === "none" ? [
4563
5096
  "tailwind",
4564
5097
  "scss",
4565
5098
  "less",
4566
5099
  "postcss-only",
5100
+ "styled-components",
4567
5101
  "none"
5102
+ ] : [...UI_LIBRARY_COMPATIBILITY[uiLibrary].cssFrameworks];
5103
+ if (frontends.length === 0) return frameworks;
5104
+ const reactFrontends = [
5105
+ "tanstack-router",
5106
+ "react-router",
5107
+ "react-vite",
5108
+ "tanstack-start",
5109
+ "next",
5110
+ "vinext",
5111
+ "redwood"
4568
5112
  ];
4569
- return UI_LIBRARY_COMPATIBILITY[uiLibrary].cssFrameworks;
5113
+ return frontends.some((frontend) => reactFrontends.includes(frontend)) ? frameworks : frameworks.filter((framework) => framework !== "styled-components");
4570
5114
  }
4571
5115
  function hasWebStyling(frontends = []) {
4572
5116
  const { web } = splitFrontends(frontends);
4573
5117
  return web.length > 0;
4574
5118
  }
4575
5119
  function getCompatibleFormLibraries(frontends = []) {
5120
+ if (frontends.some((frontend) => ["vanilla-vite", "vue"].includes(frontend))) return ["none"];
4576
5121
  const hasSolid = frontends.includes("solid");
4577
5122
  const hasSolidStart = frontends.includes("solid-start");
4578
5123
  const hasQwik = frontends.includes("qwik");
@@ -4608,6 +5153,8 @@ function evaluateCompatibility(input) {
4608
5153
  ["forms", input.forms],
4609
5154
  ["stateManagement", input.stateManagement],
4610
5155
  ["animation", input.animation],
5156
+ ["cms", input.cms],
5157
+ ["featureFlags", input.featureFlags],
4611
5158
  ["pythonApi", input.pythonApi],
4612
5159
  ["javaWebFramework", input.javaWebFramework],
4613
5160
  ["javaBuildTool", input.javaBuildTool],
@@ -4635,6 +5182,11 @@ function evaluateCompatibility(input) {
4635
5182
  ["elixirObservability", input.elixirObservability],
4636
5183
  ["elixirTesting", input.elixirTesting],
4637
5184
  ["elixirQuality", input.elixirQuality],
5185
+ ["elixirI18n", input.elixirI18n],
5186
+ ["elixirHttpServer", input.elixirHttpServer],
5187
+ ["elixirApplicationFramework", input.elixirApplicationFramework],
5188
+ ["elixirDocumentation", input.elixirDocumentation],
5189
+ ["elixirClustering", input.elixirClustering],
4638
5190
  ["elixirDeploy", input.elixirDeploy]
4639
5191
  ];
4640
5192
  for (const [category, optionId] of scalarChecks) {
@@ -4829,6 +5381,12 @@ const DEFAULT_STACK_SELECTION = {
4829
5381
  goCaching: "none",
4830
5382
  goConfig: "none",
4831
5383
  goObservability: "none",
5384
+ goValidation: "none",
5385
+ goQuality: "none",
5386
+ goMigrations: "none",
5387
+ goTemplating: "none",
5388
+ goProtoTooling: "none",
5389
+ goDI: "none",
4832
5390
  javaLanguage: "java",
4833
5391
  javaWebFramework: "spring-boot",
4834
5392
  javaBuildTool: "maven",
@@ -4863,6 +5421,11 @@ const DEFAULT_STACK_SELECTION = {
4863
5421
  elixirObservability: "telemetry",
4864
5422
  elixirTesting: "ex_unit",
4865
5423
  elixirQuality: "credo",
5424
+ elixirI18n: "none",
5425
+ elixirHttpServer: "cowboy",
5426
+ elixirApplicationFramework: "none",
5427
+ elixirDocumentation: "none",
5428
+ elixirClustering: "none",
4866
5429
  elixirDeploy: "none",
4867
5430
  elixirLibraries: []
4868
5431
  };
@@ -4975,6 +5538,12 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
4975
5538
  goCaching: "goCaching",
4976
5539
  goConfig: "goConfig",
4977
5540
  goObservability: "goObservability",
5541
+ goValidation: "goValidation",
5542
+ goQuality: "goQuality",
5543
+ goMigrations: "goMigrations",
5544
+ goTemplating: "goTemplating",
5545
+ goProtoTooling: "goProtoTooling",
5546
+ goDI: "goDI",
4978
5547
  javaLanguage: "javaLanguage",
4979
5548
  javaWebFramework: "javaWebFramework",
4980
5549
  javaBuildTool: "javaBuildTool",
@@ -5009,6 +5578,11 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
5009
5578
  elixirObservability: "elixirObservability",
5010
5579
  elixirTesting: "elixirTesting",
5011
5580
  elixirQuality: "elixirQuality",
5581
+ elixirI18n: "elixirI18n",
5582
+ elixirHttpServer: "elixirHttpServer",
5583
+ elixirApplicationFramework: "elixirApplicationFramework",
5584
+ elixirDocumentation: "elixirDocumentation",
5585
+ elixirClustering: "elixirClustering",
5012
5586
  elixirDeploy: "elixirDeploy",
5013
5587
  elixirLibraries: "elixirLibraries"
5014
5588
  };
@@ -5135,6 +5709,12 @@ const STACK_SELECTION_URL_KEYS = {
5135
5709
  goCaching: "gcache",
5136
5710
  goConfig: "gcfg",
5137
5711
  goObservability: "gobs",
5712
+ goValidation: "gval",
5713
+ goQuality: "gqual",
5714
+ goMigrations: "gmig",
5715
+ goTemplating: "gtpl",
5716
+ goProtoTooling: "gproto",
5717
+ goDI: "gdi",
5138
5718
  javaLanguage: "jlang",
5139
5719
  javaWebFramework: "jwf",
5140
5720
  javaBuildTool: "jbt",
@@ -5169,6 +5749,11 @@ const STACK_SELECTION_URL_KEYS = {
5169
5749
  elixirObservability: "eobs",
5170
5750
  elixirTesting: "etest",
5171
5751
  elixirQuality: "eq",
5752
+ elixirI18n: "ei18n",
5753
+ elixirHttpServer: "ehs",
5754
+ elixirApplicationFramework: "eaf",
5755
+ elixirDocumentation: "edoc",
5756
+ elixirClustering: "ecluster",
5172
5757
  elixirDeploy: "edeploy",
5173
5758
  elixirLibraries: "elib"
5174
5759
  };
@@ -5361,6 +5946,12 @@ const CLI_SCALAR_CONFIG_FIELDS = [
5361
5946
  ["goCaching", "goCaching"],
5362
5947
  ["goConfig", "goConfig"],
5363
5948
  ["goObservability", "goObservability"],
5949
+ ["goValidation", "goValidation"],
5950
+ ["goQuality", "goQuality"],
5951
+ ["goMigrations", "goMigrations"],
5952
+ ["goTemplating", "goTemplating"],
5953
+ ["goProtoTooling", "goProtoTooling"],
5954
+ ["goDI", "goDI"],
5364
5955
  ["javaLanguage", "javaLanguage"],
5365
5956
  ["javaWebFramework", "javaWebFramework"],
5366
5957
  ["javaBuildTool", "javaBuildTool"],
@@ -5391,6 +5982,11 @@ const CLI_SCALAR_CONFIG_FIELDS = [
5391
5982
  ["elixirObservability", "elixirObservability"],
5392
5983
  ["elixirTesting", "elixirTesting"],
5393
5984
  ["elixirQuality", "elixirQuality"],
5985
+ ["elixirI18n", "elixirI18n"],
5986
+ ["elixirHttpServer", "elixirHttpServer"],
5987
+ ["elixirApplicationFramework", "elixirApplicationFramework"],
5988
+ ["elixirDocumentation", "elixirDocumentation"],
5989
+ ["elixirClustering", "elixirClustering"],
5394
5990
  ["elixirDeploy", "elixirDeploy"]
5395
5991
  ];
5396
5992
  const CLI_NON_EMPTY_ARRAY_CONFIG_FIELDS = [
@@ -5470,7 +6066,13 @@ const GO_CONFIG_KEYS = [
5470
6066
  "goMessageQueue",
5471
6067
  "goCaching",
5472
6068
  "goConfig",
5473
- "goObservability"
6069
+ "goObservability",
6070
+ "goValidation",
6071
+ "goQuality",
6072
+ "goMigrations",
6073
+ "goTemplating",
6074
+ "goProtoTooling",
6075
+ "goDI"
5474
6076
  ];
5475
6077
  const JAVA_CONFIG_KEYS = [
5476
6078
  "javaLanguage",
@@ -5511,6 +6113,11 @@ const ELIXIR_CONFIG_KEYS = [
5511
6113
  "elixirObservability",
5512
6114
  "elixirTesting",
5513
6115
  "elixirQuality",
6116
+ "elixirI18n",
6117
+ "elixirHttpServer",
6118
+ "elixirApplicationFramework",
6119
+ "elixirDocumentation",
6120
+ "elixirClustering",
5514
6121
  "elixirDeploy",
5515
6122
  "elixirLibraries"
5516
6123
  ];
@@ -5523,35 +6130,6 @@ const REACT_NATIVE_CONFIG_KEYS = [
5523
6130
  "mobileOTA",
5524
6131
  "mobileDeepLinking"
5525
6132
  ];
5526
- const COMMAND_ADDONS = new Set([
5527
- "pwa",
5528
- "tauri",
5529
- "starlight",
5530
- "biome",
5531
- "lefthook",
5532
- "husky",
5533
- "turborepo",
5534
- "nx",
5535
- "docker-compose",
5536
- "devcontainer",
5537
- "github-actions",
5538
- "ultracite",
5539
- "fumadocs",
5540
- "oxlint",
5541
- "ruler",
5542
- "opentui",
5543
- "mcp",
5544
- "skills",
5545
- "wxt",
5546
- "msw",
5547
- "storybook",
5548
- "swr",
5549
- "tanstack-query",
5550
- "tanstack-table",
5551
- "tanstack-virtual",
5552
- "tanstack-db",
5553
- "tanstack-pacer"
5554
- ]);
5555
6133
  function withoutNone(values) {
5556
6134
  return values.filter((value) => value !== "none");
5557
6135
  }
@@ -5573,7 +6151,7 @@ function formatTypeScriptAddonsFlag(selection) {
5573
6151
  ...selection.appPlatforms
5574
6152
  ];
5575
6153
  if (addons.length === 0) return "--addons none";
5576
- return `--addons ${addons.filter((addon) => COMMAND_ADDONS.has(addon)).join(" ") || "none"}`;
6154
+ return `--addons ${toUniqueNonNoneArray(addons).join(" ") || "none"}`;
5577
6155
  }
5578
6156
  const GRAPH_TYPESCRIPT_FRONTEND_FLAG_KEYS = [["validation", "validation"], ["testing", "testing"]];
5579
6157
  const GRAPH_SHADCN_FLAG_KEYS = [
@@ -5646,6 +6224,11 @@ const GRAPH_ELIXIR_BACKEND_PART_SELECTION_KEYS = [
5646
6224
  ["elixirObservability", "observability"],
5647
6225
  ["elixirTesting", "testing"],
5648
6226
  ["elixirQuality", "codeQuality"],
6227
+ ["elixirI18n", "i18n"],
6228
+ ["elixirHttpServer", "runtime"],
6229
+ ["elixirApplicationFramework", "libraries"],
6230
+ ["elixirDocumentation", "documentation"],
6231
+ ["elixirClustering", "config"],
5649
6232
  ["elixirDeploy", "deploy"]
5650
6233
  ];
5651
6234
  const GRAPH_DATABASE_PART_SELECTION_KEYS = [["dbSetup", "dbSetup"]];
@@ -5679,6 +6262,12 @@ const GRAPH_PYTHON_BACKEND_ARRAY_PART_SELECTION_KEYS = [["pythonAi", "ai"]];
5679
6262
  const GRAPH_GO_BACKEND_PART_SELECTION_KEYS = [
5680
6263
  ["goCli", "cli"],
5681
6264
  ["goLogging", "logging"],
6265
+ ["goValidation", "validation"],
6266
+ ["goQuality", "codeQuality"],
6267
+ ["goMigrations", "migrations"],
6268
+ ["goTemplating", "templating"],
6269
+ ["goProtoTooling", "buildTool"],
6270
+ ["goDI", "libraries"],
5682
6271
  ["caching", "caching"],
5683
6272
  ["search", "search"]
5684
6273
  ];
@@ -5738,6 +6327,11 @@ const GRAPH_ELIXIR_BACKEND_PART_CLI_KEYS = [
5738
6327
  ["elixirObservability", "observability"],
5739
6328
  ["elixirTesting", "testing"],
5740
6329
  ["elixirQuality", "codeQuality"],
6330
+ ["elixirI18n", "i18n"],
6331
+ ["elixirHttpServer", "runtime"],
6332
+ ["elixirApplicationFramework", "libraries"],
6333
+ ["elixirDocumentation", "documentation"],
6334
+ ["elixirClustering", "config"],
5741
6335
  ["elixirDeploy", "deploy"]
5742
6336
  ];
5743
6337
  const GRAPH_DATABASE_PART_CLI_KEYS = [["dbSetup", "dbSetup"]];
@@ -5771,6 +6365,12 @@ const GRAPH_PYTHON_BACKEND_ARRAY_PART_CLI_KEYS = [["pythonAi", "ai"]];
5771
6365
  const GRAPH_GO_BACKEND_PART_CLI_KEYS = [
5772
6366
  ["goCli", "cli"],
5773
6367
  ["goLogging", "logging"],
6368
+ ["goValidation", "validation"],
6369
+ ["goQuality", "codeQuality"],
6370
+ ["goMigrations", "migrations"],
6371
+ ["goTemplating", "templating"],
6372
+ ["goProtoTooling", "buildTool"],
6373
+ ["goDI", "libraries"],
5774
6374
  ["caching", "caching"],
5775
6375
  ["search", "search"]
5776
6376
  ];
@@ -6264,6 +6864,12 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
6264
6864
  goCaching: stack.goCaching,
6265
6865
  goConfig: stack.goConfig,
6266
6866
  goObservability: stack.goObservability,
6867
+ goValidation: stack.goValidation,
6868
+ goQuality: stack.goQuality,
6869
+ goMigrations: stack.goMigrations,
6870
+ goTemplating: stack.goTemplating,
6871
+ goProtoTooling: stack.goProtoTooling,
6872
+ goDI: stack.goDI,
6267
6873
  javaLanguage: stack.javaLanguage,
6268
6874
  javaWebFramework: stack.javaWebFramework,
6269
6875
  javaBuildTool: stack.javaBuildTool,
@@ -6298,6 +6904,11 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
6298
6904
  elixirObservability: stack.elixirObservability,
6299
6905
  elixirTesting: stack.elixirTesting,
6300
6906
  elixirQuality: stack.elixirQuality,
6907
+ elixirI18n: stack.elixirI18n,
6908
+ elixirHttpServer: stack.elixirHttpServer,
6909
+ elixirApplicationFramework: stack.elixirApplicationFramework,
6910
+ elixirDocumentation: stack.elixirDocumentation,
6911
+ elixirClustering: stack.elixirClustering,
6301
6912
  elixirDeploy: stack.elixirDeploy,
6302
6913
  elixirLibraries: toUniqueNonNoneArray(stack.elixirLibraries),
6303
6914
  aiDocs: toUniqueNonNoneArray(stack.aiDocs)
@@ -6552,6 +7163,12 @@ function generateGoCommand(selection, projectName) {
6552
7163
  `--go-caching ${selection.goCaching}`,
6553
7164
  `--go-config ${selection.goConfig}`,
6554
7165
  `--go-observability ${selection.goObservability}`,
7166
+ `--go-validation ${selection.goValidation}`,
7167
+ `--go-quality ${selection.goQuality}`,
7168
+ `--go-migrations ${selection.goMigrations}`,
7169
+ `--go-templating ${selection.goTemplating}`,
7170
+ `--go-proto-tooling ${selection.goProtoTooling}`,
7171
+ `--go-di ${selection.goDI}`,
6555
7172
  `--auth ${selection.auth}`,
6556
7173
  `--email ${selection.email}`,
6557
7174
  `--observability ${selection.observability}`,
@@ -6622,6 +7239,11 @@ function generateElixirCommand(selection, projectName) {
6622
7239
  `--elixir-observability ${selection.elixirObservability}`,
6623
7240
  `--elixir-testing ${selection.elixirTesting}`,
6624
7241
  `--elixir-quality ${selection.elixirQuality}`,
7242
+ `--elixir-i18n ${selection.elixirI18n}`,
7243
+ `--elixir-http-server ${selection.elixirHttpServer}`,
7244
+ `--elixir-application-framework ${selection.elixirApplicationFramework}`,
7245
+ `--elixir-documentation ${selection.elixirDocumentation}`,
7246
+ `--elixir-clustering ${selection.elixirClustering}`,
6625
7247
  `--elixir-deploy ${selection.elixirDeploy}`,
6626
7248
  formatArrayFlag("elixir-libraries", selection.elixirLibraries),
6627
7249
  formatArrayFlag("ai-docs", selection.aiDocs)
@@ -6648,4 +7270,4 @@ function generateStackSelectionCommand(selection) {
6648
7270
 
6649
7271
  //#endregion
6650
7272
  export { REACT_NATIVE_CATEGORY_ORDER as $, getCompatibleAddons as A, requiresChatSdkVercelAI as B, KOTLIN_DROPPED_JAVA_LIBRARIES as C, evaluateCompatibility as D, analyzeStackCompatibility as E, getKotlinJavaIncompatibilityReason as F, validateProjectName as G, splitFrontends as H, hasWebStyling as I, ELIXIR_CATEGORY_ORDER as J, CATEGORY_ORDER as K, isFrontendAllowedWithBackend as L, getCompatibleFormLibraries as M, getCompatibleUILibraries as N, getAIFrontendCompatibilityIssue as O, getDisabledReason as P, PYTHON_CATEGORY_ORDER as Q, isOptionCompatible as R, usesVirtualNoneStackSelection as S, allowedApisForFrontends as T, stackQualifiesForSingleApp as U, requiresChatSdkVercelAIForSelection as V, validateAddonCompatibility as W, JAVA_CATEGORY_ORDER as X, GO_CATEGORY_ORDER as Y, OPTION_CATEGORY_METADATA as Z, parseStackSelectionFromSearch as _, STACK_SELECTION_URL_KEYS as a, getCategoryOrderForEcosystem as at, stackSelectionToCliComparableConfig as b, cloneDefaultStackSelection as c, normalizeOptionId as ct, isArrayStackSelectionKey as d, getSupportedCapabilityOptions as dt, RUST_CATEGORY_ORDER as et, isCliDefaultStackSelection as f, normalizeCapabilitySelection as ft, normalizeStackSelectionValue as g, normalizeStackSelection as h, STACK_SELECTION_OPTION_CATEGORY_BY_KEY as i, getCategoryOptionIds as it, getCompatibleCSSFrameworks as j, getApiFrontendCompatibilityIssue as k, createStackSelectionSearchParams as l, getCapabilityDefinitions as lt, isStackSelectionDefault as m, NON_OPTION_STACK_SELECTION_KEYS as n, getCategoryCliValues as nt, VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS as o, getOptionMetadata as ot, isGraphStackSelection as p, DOTNET_CATEGORY_ORDER as q, STACK_SELECTION_KEYS as r, getCategoryDisplayName as rt, cliInputToProjectConfigPartial as s, isMultiSelectCategory as st, DEFAULT_STACK_SELECTION as t, TYPESCRIPT_CATEGORY_ORDER as tt, generateStackSelectionCommand as u, getCapabilityDisabledReason as ut, parseStackSelectionFromUrlRecord as v, KOTLIN_UNSUPPORTED_JAVA_TESTING_LIBRARIES as w, stackSelectionToProjectConfig as x, processCliArrayOption as y, isWebFrontend as z };
6651
- //# sourceMappingURL=stack-translation-DwSS9Vc2.mjs.map
7273
+ //# sourceMappingURL=stack-translation-Kr0TyRAm.mjs.map