@better-fullstack/types 1.7.0 → 1.8.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 (36) hide show
  1. package/dist/{defaults-DYWPNKDb.d.mts → defaults-CFAJhN--.d.mts} +2 -2
  2. package/dist/defaults-CFAJhN--.d.mts.map +1 -0
  3. package/dist/{defaults-DnrxiPa9.mjs → defaults-D23vxGYl.mjs} +24 -1
  4. package/dist/defaults-D23vxGYl.mjs.map +1 -0
  5. package/dist/defaults.d.mts +3 -3
  6. package/dist/defaults.mjs +1 -1
  7. package/dist/index.d.mts +5 -5
  8. package/dist/index.mjs +4 -4
  9. package/dist/json-schema.d.mts +3318 -334
  10. package/dist/json-schema.d.mts.map +1 -1
  11. package/dist/json-schema.mjs +66 -2
  12. package/dist/json-schema.mjs.map +1 -1
  13. package/dist/{schemas-DDTcRKek.mjs → schemas-BHCZL3uR.mjs} +260 -10
  14. package/dist/schemas-BHCZL3uR.mjs.map +1 -0
  15. package/dist/{schemas-9siFEKYg.d.mts → schemas-Bs_n2xLj.d.mts} +2712 -50
  16. package/dist/schemas-Bs_n2xLj.d.mts.map +1 -0
  17. package/dist/schemas.d.mts +2 -2
  18. package/dist/schemas.mjs +2 -2
  19. package/dist/{stack-translation-CUd4T2bV.mjs → stack-translation-_uOX-Io0.mjs} +1013 -38
  20. package/dist/stack-translation-_uOX-Io0.mjs.map +1 -0
  21. package/dist/{stack-translation-Ct4UaQX9.d.mts → stack-translation-xj8JvbAI.d.mts} +52 -6
  22. package/dist/stack-translation-xj8JvbAI.d.mts.map +1 -0
  23. package/dist/stack-translation.d.mts +4 -4
  24. package/dist/stack-translation.mjs +2 -2
  25. package/dist/types-DwFVhx5c.d.mts +119 -0
  26. package/dist/types-DwFVhx5c.d.mts.map +1 -0
  27. package/dist/types.d.mts +3 -3
  28. package/package.json +2 -2
  29. package/dist/defaults-DYWPNKDb.d.mts.map +0 -1
  30. package/dist/defaults-DnrxiPa9.mjs.map +0 -1
  31. package/dist/schemas-9siFEKYg.d.mts.map +0 -1
  32. package/dist/schemas-DDTcRKek.mjs.map +0 -1
  33. package/dist/stack-translation-CUd4T2bV.mjs.map +0 -1
  34. package/dist/stack-translation-Ct4UaQX9.d.mts.map +0 -1
  35. package/dist/types-Do72vki5.d.mts +0 -95
  36. package/dist/types-Do72vki5.d.mts.map +0 -1
@@ -1,5 +1,5 @@
1
- import { $n as VALIDATION_VALUES, A as DATABASE_SETUP_VALUES, An as SHADCN_BASE_VALUES, Bt as PYTHON_ORM_VALUES, D as CSS_FRAMEWORK_VALUES, Dn as SEARCH_VALUES, Fn as SHADCN_STYLE_VALUES, Ft as PACKAGE_MANAGER_VALUES, G as FILE_STORAGE_VALUES, Ht as PYTHON_TASK_QUEUE_VALUES, In as STATE_MANAGEMENT_VALUES, It as PAYMENTS_VALUES, Jn as TESTING_VALUES, K as FILE_UPLOAD_VALUES, L as EFFECT_VALUES, Lt as PYTHON_AI_VALUES, Mn as SHADCN_FONT_VALUES, Nn as SHADCN_ICON_LIBRARY_VALUES, Nt as ORM_VALUES, On as SERVER_DEPLOY_VALUES, Pn as SHADCN_RADIUS_VALUES, Qn as UI_LIBRARY_VALUES, R as EMAIL_VALUES, Rt as PYTHON_AUTH_VALUES, S as CACHING_VALUES, T as CMS_VALUES, Ut as PYTHON_VALIDATION_VALUES, Vt as PYTHON_QUALITY_VALUES, W as FEATURE_FLAGS_VALUES, Wt as PYTHON_WEB_FRAMEWORK_VALUES, _t as JAVA_LIBRARIES_VALUES, a as ANALYTICS_VALUES, an as RUST_API_VALUES, at as GO_WEB_FRAMEWORK_VALUES, bt as JAVA_WEB_FRAMEWORK_VALUES, c as API_VALUES, cn as RUST_CLI_VALUES, dn as RUST_LIBRARIES_VALUES, er as VERSION_CHANNEL_VALUES, et as GO_API_VALUES, fn as RUST_LOGGING_VALUES, ft as I18N_VALUES, gt as JAVA_BUILD_TOOL_VALUES, ht as JAVA_AUTH_VALUES, i as AI_VALUES, in as RUNTIME_VALUES, it as GO_ORM_VALUES, j as DATABASE_VALUES, jn as SHADCN_COLOR_THEME_VALUES, jt as OBSERVABILITY_VALUES, kn as SHADCN_BASE_COLOR_VALUES, kt as LOGGING_VALUES, l as ASTRO_INTEGRATION_VALUES, ln as RUST_ERROR_HANDLING_VALUES, mn as RUST_WEB_FRAMEWORK_VALUES, nt as GO_CLI_VALUES, o as ANIMATION_VALUES, on as RUST_AUTH_VALUES, pn as RUST_ORM_VALUES, q as FORMS_VALUES, r as AI_DOCS_VALUES, rn as REALTIME_VALUES, rr as WEB_DEPLOY_VALUES, rt as GO_LOGGING_VALUES, sn as RUST_CACHING_VALUES, tt as GO_AUTH_VALUES, u as AUTH_VALUES, un as RUST_FRONTEND_VALUES, vt as JAVA_ORM_VALUES, xt as JOB_QUEUE_VALUES, yt as JAVA_TESTING_LIBRARIES_VALUES, zt as PYTHON_GRAPHQL_VALUES } from "./schemas-DDTcRKek.mjs";
2
- import { t as createCliDefaultProjectConfigBase } from "./defaults-DnrxiPa9.mjs";
1
+ import { $ as ELIXIR_VALIDATION_VALUES, $n as RUST_API_VALUES, $t as JOB_QUEUE_VALUES, An as PYTHON_API_VALUES, Ar as STATE_MANAGEMENT_VALUES, B as ELIXIR_API_VALUES, Cn as OBSERVABILITY_VALUES, Cr as SHADCN_BASE_COLOR_VALUES, Ct as FILE_STORAGE_VALUES, D as CMS_VALUES, Dn as PACKAGE_MANAGER_VALUES, Dr as SHADCN_ICON_LIBRARY_VALUES, Er as SHADCN_FONT_VALUES, Fn as PYTHON_TASK_QUEUE_VALUES, Ft as GO_LOGGING_VALUES, G as ELIXIR_HTTP_VALUES, H as ELIXIR_CACHING_VALUES, Hr as TESTING_VALUES, In as PYTHON_VALIDATION_VALUES, It as GO_ORM_VALUES, J as ELIXIR_OBSERVABILITY_VALUES, Jr as VERSION_CHANNEL_VALUES, Jt as JAVA_BUILD_TOOL_VALUES, K as ELIXIR_JOBS_VALUES, Kr as UI_LIBRARY_VALUES, Ln as PYTHON_WEB_FRAMEWORK_VALUES, Lt as GO_WEB_FRAMEWORK_VALUES, M as DATABASE_SETUP_VALUES, Mn as PYTHON_GRAPHQL_VALUES, Mt as GO_API_VALUES, N as DATABASE_VALUES, Nn as PYTHON_ORM_VALUES, Nt as GO_AUTH_VALUES, On as PAYMENTS_VALUES, Or as SHADCN_RADIUS_VALUES, Pn as PYTHON_QUALITY_VALUES, Pt as GO_CLI_VALUES, Q as ELIXIR_TESTING_VALUES, Qn as RUNTIME_VALUES, Qt as JAVA_WEB_FRAMEWORK_VALUES, Sr as SERVER_DEPLOY_VALUES, St as FEATURE_FLAGS_VALUES, Tn as ORM_VALUES, Tr as SHADCN_COLOR_THEME_VALUES, Tt as FORMS_VALUES, U as ELIXIR_DEPLOY_VALUES, V as ELIXIR_AUTH_VALUES, W as ELIXIR_EMAIL_VALUES, Wt as I18N_VALUES, X as ELIXIR_QUALITY_VALUES, Xt as JAVA_ORM_VALUES, Y as ELIXIR_ORM_VALUES, Yt as JAVA_LIBRARIES_VALUES, Z as ELIXIR_REALTIME_VALUES, Zn as REALTIME_VALUES, Zr as WEB_DEPLOY_VALUES, Zt as JAVA_TESTING_LIBRARIES_VALUES, a as ANALYTICS_VALUES, ar as RUST_LIBRARIES_VALUES, c as API_VALUES, cr as RUST_WEB_FRAMEWORK_VALUES, dn as MOBILE_OTA_VALUES, er as RUST_AUTH_VALUES, et as ELIXIR_WEB_FRAMEWORK_VALUES, fn as MOBILE_PUSH_VALUES, hn as MOBILE_UI_VALUES, i as AI_VALUES, ir as RUST_FRONTEND_VALUES, jn as PYTHON_AUTH_VALUES, k as CSS_FRAMEWORK_VALUES, kn as PYTHON_AI_VALUES, kr as SHADCN_STYLE_VALUES, l as ASTRO_INTEGRATION_VALUES, ln as MOBILE_DEEP_LINKING_VALUES, mn as MOBILE_TESTING_VALUES, nr as RUST_CLI_VALUES, o as ANIMATION_VALUES, or as RUST_LOGGING_VALUES, pn as MOBILE_STORAGE_VALUES, q as ELIXIR_JSON_VALUES, qr as VALIDATION_VALUES, qt as JAVA_AUTH_VALUES, r as AI_DOCS_VALUES, rr as RUST_ERROR_HANDLING_VALUES, sn as LOGGING_VALUES, sr as RUST_ORM_VALUES, tr as RUST_CACHING_VALUES, tt as EMAIL_VALUES, u as AUTH_VALUES, un as MOBILE_NAVIGATION_VALUES, w as CACHING_VALUES, wr as SHADCN_BASE_VALUES, wt as FILE_UPLOAD_VALUES, xr as SEARCH_VALUES, z as EFFECT_VALUES } from "./schemas-BHCZL3uR.mjs";
2
+ import { t as createCliDefaultProjectConfigBase } from "./defaults-D23vxGYl.mjs";
3
3
 
4
4
  //#region src/capabilities.ts
5
5
  const CAPABILITY_DEFINITIONS = { auth: [
@@ -231,6 +231,13 @@ const CATEGORY_ORDER = [
231
231
  "i18n",
232
232
  "search",
233
233
  "fileStorage",
234
+ "mobileNavigation",
235
+ "mobileUI",
236
+ "mobileStorage",
237
+ "mobileTesting",
238
+ "mobilePush",
239
+ "mobileOTA",
240
+ "mobileDeepLinking",
234
241
  "animation",
235
242
  "cms",
236
243
  "codeQuality",
@@ -254,6 +261,7 @@ const CATEGORY_ORDER = [
254
261
  "pythonValidation",
255
262
  "pythonAi",
256
263
  "pythonAuth",
264
+ "pythonApi",
257
265
  "pythonTaskQueue",
258
266
  "pythonGraphql",
259
267
  "pythonQuality",
@@ -268,7 +276,22 @@ const CATEGORY_ORDER = [
268
276
  "javaOrm",
269
277
  "javaAuth",
270
278
  "javaLibraries",
271
- "javaTestingLibraries"
279
+ "javaTestingLibraries",
280
+ "elixirWebFramework",
281
+ "elixirOrm",
282
+ "elixirAuth",
283
+ "elixirApi",
284
+ "elixirRealtime",
285
+ "elixirJobs",
286
+ "elixirValidation",
287
+ "elixirHttp",
288
+ "elixirJson",
289
+ "elixirEmail",
290
+ "elixirCaching",
291
+ "elixirObservability",
292
+ "elixirTesting",
293
+ "elixirQuality",
294
+ "elixirDeploy"
272
295
  ];
273
296
  const DEFAULT_RUNTIME = "bun";
274
297
  function validateProjectName(name) {
@@ -297,6 +320,7 @@ const hasPWACompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
297
320
  "react-vite",
298
321
  "solid",
299
322
  "next",
323
+ "vinext",
300
324
  "astro"
301
325
  ].includes(f));
302
326
  const hasTauriCompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
@@ -307,6 +331,7 @@ const hasTauriCompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
307
331
  "svelte",
308
332
  "solid",
309
333
  "next",
334
+ "vinext",
310
335
  "astro"
311
336
  ].includes(f));
312
337
  const hasDockerComposeCompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
@@ -315,11 +340,12 @@ const hasDockerComposeCompatibleFrontend = (webFrontend) => webFrontend.some((f)
315
340
  "react-vite",
316
341
  "solid",
317
342
  "next",
343
+ "vinext",
318
344
  "astro"
319
345
  ].includes(f));
320
346
  const isChatSdkExampleSupported = (stack) => {
321
347
  if (stack.ecosystem !== "typescript") return false;
322
- if (stack.backend === "self-next" || stack.backend === "self-tanstack-start") return true;
348
+ if (stack.backend === "self-next" || stack.backend === "self-vinext" || stack.backend === "self-tanstack-start") return true;
323
349
  if (stack.backend === "self-nuxt") return true;
324
350
  if (stack.backend === "hono") return stack.runtime === "node";
325
351
  return false;
@@ -346,6 +372,7 @@ const getCategoryDisplayName = (categoryKey) => {
346
372
  pythonValidation: "Python Validation",
347
373
  pythonAi: "Python AI / ML",
348
374
  pythonAuth: "Python Auth",
375
+ pythonApi: "Python API Framework",
349
376
  pythonTaskQueue: "Python Task Queue",
350
377
  pythonGraphql: "Python GraphQL",
351
378
  pythonQuality: "Python Code Quality"
@@ -366,11 +393,38 @@ const getCategoryDisplayName = (categoryKey) => {
366
393
  javaLibraries: "Java Libraries",
367
394
  javaTestingLibraries: "Java Testing Libraries"
368
395
  };
396
+ const elixirCategoryNames = {
397
+ elixirWebFramework: "Elixir Web Framework",
398
+ elixirOrm: "Elixir ORM / Database",
399
+ elixirAuth: "Elixir Auth",
400
+ elixirApi: "Elixir API Layer",
401
+ elixirRealtime: "Elixir Realtime",
402
+ elixirJobs: "Elixir Jobs",
403
+ elixirValidation: "Elixir Validation",
404
+ elixirHttp: "Elixir HTTP Client",
405
+ elixirJson: "Elixir JSON",
406
+ elixirEmail: "Elixir Email",
407
+ elixirCaching: "Elixir Caching",
408
+ elixirObservability: "Elixir Observability",
409
+ elixirTesting: "Elixir Testing",
410
+ elixirQuality: "Elixir Code Quality",
411
+ elixirDeploy: "Elixir Deploy"
412
+ };
369
413
  if (rustCategoryNames[categoryKey]) return rustCategoryNames[categoryKey];
370
414
  if (pythonCategoryNames[categoryKey]) return pythonCategoryNames[categoryKey];
371
415
  if (goCategoryNames[categoryKey]) return goCategoryNames[categoryKey];
372
416
  if (javaCategoryNames[categoryKey]) return javaCategoryNames[categoryKey];
373
- const tsCategoryNames = { i18n: "Internationalization (i18n)" };
417
+ if (elixirCategoryNames[categoryKey]) return elixirCategoryNames[categoryKey];
418
+ const tsCategoryNames = {
419
+ i18n: "Internationalization (i18n)",
420
+ mobileNavigation: "Mobile Navigation",
421
+ mobileUI: "Mobile UI",
422
+ mobileStorage: "Mobile Storage",
423
+ mobileTesting: "Mobile Testing",
424
+ mobilePush: "Mobile Push",
425
+ mobileOTA: "Mobile OTA",
426
+ mobileDeepLinking: "Mobile Deep Linking"
427
+ };
374
428
  if (tsCategoryNames[categoryKey]) return tsCategoryNames[categoryKey];
375
429
  const result = categoryKey.replace(/([A-Z])/g, " $1");
376
430
  return result.charAt(0).toUpperCase() + result.slice(1);
@@ -492,7 +546,7 @@ const analyzeStackCompatibility = (stack) => {
492
546
  });
493
547
  }
494
548
  }
495
- if (nextStack.backend === "self-next" || nextStack.backend === "self-tanstack-start" || nextStack.backend === "self-astro" || nextStack.backend === "self-nuxt" || nextStack.backend === "self-svelte" || nextStack.backend === "self-solid-start") {
549
+ if (nextStack.backend === "self-next" || nextStack.backend === "self-vinext" || nextStack.backend === "self-tanstack-start" || nextStack.backend === "self-astro" || nextStack.backend === "self-nuxt" || nextStack.backend === "self-svelte" || nextStack.backend === "self-solid-start") {
496
550
  if (nextStack.runtime !== "none") {
497
551
  nextStack.runtime = "none";
498
552
  changed = true;
@@ -517,6 +571,14 @@ const analyzeStackCompatibility = (stack) => {
517
571
  message: "Frontend set to 'Next.js' (required for Next.js fullstack)"
518
572
  });
519
573
  }
574
+ if (nextStack.backend === "self-vinext" && !nextStack.webFrontend.includes("vinext")) {
575
+ nextStack.webFrontend = ["vinext"];
576
+ changed = true;
577
+ changes.push({
578
+ category: "backend",
579
+ message: "Frontend set to 'Vinext' (required for Vinext fullstack)"
580
+ });
581
+ }
520
582
  if (nextStack.backend === "self-tanstack-start" && !nextStack.webFrontend.includes("tanstack-start")) {
521
583
  nextStack.webFrontend = ["tanstack-start"];
522
584
  changed = true;
@@ -585,7 +647,7 @@ const analyzeStackCompatibility = (stack) => {
585
647
  message: "Database changed to SQLite with D1 (Better-Fullstack doesn't support MongoDB with Workers)"
586
648
  });
587
649
  }
588
- if (nextStack.runtime === "none" && nextStack.backend !== "convex" && nextStack.backend !== "none" && nextStack.backend !== "self-next" && nextStack.backend !== "self-tanstack-start" && nextStack.backend !== "self-astro" && nextStack.backend !== "self-nuxt" && nextStack.backend !== "self-svelte" && nextStack.backend !== "self-solid-start") {
650
+ if (nextStack.runtime === "none" && nextStack.backend !== "convex" && nextStack.backend !== "none" && nextStack.backend !== "self-next" && nextStack.backend !== "self-vinext" && nextStack.backend !== "self-tanstack-start" && nextStack.backend !== "self-astro" && nextStack.backend !== "self-nuxt" && nextStack.backend !== "self-svelte" && nextStack.backend !== "self-solid-start") {
589
651
  nextStack.runtime = DEFAULT_RUNTIME;
590
652
  changed = true;
591
653
  changes.push({
@@ -891,6 +953,269 @@ const analyzeStackCompatibility = (stack) => {
891
953
  });
892
954
  }
893
955
  }
956
+ let hasNativeFrontend = nextStack.nativeFrontend.some((f) => f !== "none");
957
+ if (nextStack.ecosystem === "react-native") {
958
+ for (const [category, value, message] of [
959
+ [
960
+ "webFrontend",
961
+ ["none"],
962
+ "Web frontend set to 'None' (React Native ecosystem)"
963
+ ],
964
+ [
965
+ "backend",
966
+ "none",
967
+ "Backend set to 'None' (React Native ecosystem)"
968
+ ],
969
+ [
970
+ "runtime",
971
+ "none",
972
+ "Runtime set to 'None' (React Native ecosystem)"
973
+ ],
974
+ [
975
+ "api",
976
+ "none",
977
+ "API set to 'None' (React Native ecosystem)"
978
+ ],
979
+ [
980
+ "database",
981
+ "none",
982
+ "Database set to 'None' (React Native ecosystem)"
983
+ ],
984
+ [
985
+ "orm",
986
+ "none",
987
+ "ORM set to 'None' (React Native ecosystem)"
988
+ ],
989
+ [
990
+ "dbSetup",
991
+ "none",
992
+ "Database setup set to 'None' (React Native ecosystem)"
993
+ ],
994
+ [
995
+ "webDeploy",
996
+ "none",
997
+ "Web deployment set to 'None' (React Native ecosystem)"
998
+ ],
999
+ [
1000
+ "serverDeploy",
1001
+ "none",
1002
+ "Server deployment set to 'None' (React Native ecosystem)"
1003
+ ],
1004
+ [
1005
+ "cssFramework",
1006
+ "none",
1007
+ "CSS framework set to 'None' (React Native ecosystem)"
1008
+ ],
1009
+ [
1010
+ "uiLibrary",
1011
+ "none",
1012
+ "UI library set to 'None' (React Native ecosystem)"
1013
+ ],
1014
+ [
1015
+ "testing",
1016
+ "none",
1017
+ "Web testing set to 'None' (React Native ecosystem)"
1018
+ ],
1019
+ [
1020
+ "forms",
1021
+ "none",
1022
+ "Web forms set to 'None' (React Native ecosystem)"
1023
+ ],
1024
+ [
1025
+ "stateManagement",
1026
+ "none",
1027
+ "Web state management set to 'None' (React Native ecosystem)"
1028
+ ],
1029
+ [
1030
+ "animation",
1031
+ "none",
1032
+ "Web animation set to 'None' (React Native ecosystem)"
1033
+ ],
1034
+ [
1035
+ "realtime",
1036
+ "none",
1037
+ "Realtime set to 'None' (React Native ecosystem)"
1038
+ ],
1039
+ [
1040
+ "jobQueue",
1041
+ "none",
1042
+ "Job queue set to 'None' (React Native ecosystem)"
1043
+ ],
1044
+ [
1045
+ "fileUpload",
1046
+ "none",
1047
+ "File upload set to 'None' (React Native ecosystem)"
1048
+ ],
1049
+ [
1050
+ "payments",
1051
+ "none",
1052
+ "Payments set to 'None' (React Native ecosystem)"
1053
+ ],
1054
+ [
1055
+ "email",
1056
+ "none",
1057
+ "Email set to 'None' (React Native ecosystem)"
1058
+ ],
1059
+ [
1060
+ "search",
1061
+ "none",
1062
+ "Search set to 'None' (React Native ecosystem)"
1063
+ ],
1064
+ [
1065
+ "fileStorage",
1066
+ "none",
1067
+ "File storage set to 'None' (React Native ecosystem)"
1068
+ ],
1069
+ [
1070
+ "cms",
1071
+ "none",
1072
+ "CMS set to 'None' (React Native ecosystem)"
1073
+ ],
1074
+ [
1075
+ "caching",
1076
+ "none",
1077
+ "Caching set to 'None' (React Native ecosystem)"
1078
+ ],
1079
+ [
1080
+ "i18n",
1081
+ "none",
1082
+ "i18n set to 'None' (React Native ecosystem)"
1083
+ ],
1084
+ [
1085
+ "featureFlags",
1086
+ "none",
1087
+ "Feature flags set to 'None' (React Native ecosystem)"
1088
+ ],
1089
+ [
1090
+ "analytics",
1091
+ "none",
1092
+ "Analytics set to 'None' (React Native ecosystem)"
1093
+ ],
1094
+ [
1095
+ "aiSdk",
1096
+ "none",
1097
+ "AI SDK set to 'None' (React Native ecosystem)"
1098
+ ],
1099
+ [
1100
+ "backendLibraries",
1101
+ "none",
1102
+ "Backend libraries set to 'None' (React Native ecosystem)"
1103
+ ],
1104
+ [
1105
+ "examples",
1106
+ [],
1107
+ "Examples cleared (React Native ecosystem)"
1108
+ ]
1109
+ ]) {
1110
+ const currentValue = nextStack[category];
1111
+ const isSameArray = Array.isArray(currentValue) && Array.isArray(value) && currentValue.length === value.length && currentValue.every((entry, index) => entry === value[index]);
1112
+ if (Array.isArray(value) ? !isSameArray : currentValue !== value) {
1113
+ nextStack[category] = Array.isArray(value) ? [...value] : value;
1114
+ changed = true;
1115
+ changes.push({
1116
+ category,
1117
+ message
1118
+ });
1119
+ }
1120
+ }
1121
+ if (!hasNativeFrontend) {
1122
+ nextStack.nativeFrontend = ["native-bare"];
1123
+ hasNativeFrontend = true;
1124
+ changed = true;
1125
+ changes.push({
1126
+ category: "nativeFrontend",
1127
+ message: "Native frontend set to 'Expo + Bare' (React Native ecosystem)"
1128
+ });
1129
+ }
1130
+ }
1131
+ if (nextStack.ecosystem === "typescript" && nextStack.nativeFrontend.some((frontend) => frontend !== "none")) {
1132
+ nextStack.nativeFrontend = ["none"];
1133
+ hasNativeFrontend = false;
1134
+ changed = true;
1135
+ changes.push({
1136
+ category: "nativeFrontend",
1137
+ message: "Native frontend set to 'None' (use React Native ecosystem for Expo apps)"
1138
+ });
1139
+ }
1140
+ if (!hasNativeFrontend) {
1141
+ for (const [category, value, message] of [
1142
+ [
1143
+ "mobileNavigation",
1144
+ "none",
1145
+ "Mobile navigation set to 'None' (no native frontend)"
1146
+ ],
1147
+ [
1148
+ "mobileUI",
1149
+ "none",
1150
+ "Mobile UI set to 'None' (no native frontend)"
1151
+ ],
1152
+ [
1153
+ "mobileStorage",
1154
+ "none",
1155
+ "Mobile storage set to 'None' (no native frontend)"
1156
+ ],
1157
+ [
1158
+ "mobileTesting",
1159
+ "none",
1160
+ "Mobile testing set to 'None' (no native frontend)"
1161
+ ],
1162
+ [
1163
+ "mobilePush",
1164
+ "none",
1165
+ "Mobile push set to 'None' (no native frontend)"
1166
+ ],
1167
+ [
1168
+ "mobileOTA",
1169
+ "none",
1170
+ "Mobile OTA set to 'None' (no native frontend)"
1171
+ ],
1172
+ [
1173
+ "mobileDeepLinking",
1174
+ "none",
1175
+ "Mobile deep linking set to 'None' (no native frontend)"
1176
+ ]
1177
+ ]) if (nextStack[category] !== value) {
1178
+ nextStack[category] = value;
1179
+ changed = true;
1180
+ changes.push({
1181
+ category,
1182
+ message
1183
+ });
1184
+ }
1185
+ } else {
1186
+ if (nextStack.mobileNavigation === "none") {
1187
+ nextStack.mobileNavigation = "expo-router";
1188
+ changed = true;
1189
+ changes.push({
1190
+ category: "mobileNavigation",
1191
+ message: "Mobile navigation set to 'Expo Router' (native frontend selected)"
1192
+ });
1193
+ }
1194
+ if (nextStack.mobileDeepLinking === "none" && nextStack.auth !== "none") {
1195
+ nextStack.mobileDeepLinking = "expo-linking";
1196
+ changed = true;
1197
+ changes.push({
1198
+ category: "mobileDeepLinking",
1199
+ message: "Mobile deep linking set to 'Expo Linking' (required for mobile auth redirects)"
1200
+ });
1201
+ }
1202
+ if (nextStack.nativeFrontend.includes("native-uniwind") && nextStack.mobileUI !== "uniwind") {
1203
+ nextStack.mobileUI = "uniwind";
1204
+ changed = true;
1205
+ changes.push({
1206
+ category: "mobileUI",
1207
+ message: "Mobile UI set to 'Uniwind' (required by Expo + Uniwind)"
1208
+ });
1209
+ }
1210
+ if (nextStack.nativeFrontend.includes("native-unistyles") && nextStack.mobileUI !== "unistyles") {
1211
+ nextStack.mobileUI = "unistyles";
1212
+ changed = true;
1213
+ changes.push({
1214
+ category: "mobileUI",
1215
+ message: "Mobile UI set to 'Unistyles' (required by Expo + Unistyles)"
1216
+ });
1217
+ }
1218
+ }
894
1219
  if ([
895
1220
  "shadcn-ui",
896
1221
  "daisyui",
@@ -907,14 +1232,17 @@ const analyzeStackCompatibility = (stack) => {
907
1232
  "shadcn-ui",
908
1233
  "radix-ui",
909
1234
  "chakra-ui",
910
- "nextui"
1235
+ "nextui",
1236
+ "mui",
1237
+ "antd"
911
1238
  ];
912
1239
  const reactFrontends = [
913
1240
  "tanstack-router",
914
1241
  "react-router",
915
1242
  "react-vite",
916
1243
  "tanstack-start",
917
- "next"
1244
+ "next",
1245
+ "vinext"
918
1246
  ];
919
1247
  if (reactOnlyLibraries.includes(nextStack.uiLibrary)) {
920
1248
  const hasReactFrontend = nextStack.webFrontend.some((f) => reactFrontends.includes(f));
@@ -1056,6 +1384,16 @@ const analyzeStackCompatibility = (stack) => {
1056
1384
  });
1057
1385
  }
1058
1386
  }
1387
+ if (nextStack.ecosystem === "python") {
1388
+ if (nextStack.pythonWebFramework !== "django" && nextStack.pythonApi !== "none") {
1389
+ nextStack.pythonApi = "none";
1390
+ changed = true;
1391
+ changes.push({
1392
+ category: "pythonWebFramework",
1393
+ message: "Python API framework set to 'None' (DRF and Django Ninja require Django)"
1394
+ });
1395
+ }
1396
+ }
1059
1397
  if (nextStack.ecosystem === "java") {
1060
1398
  if (nextStack.javaBuildTool === "none") {
1061
1399
  if (nextStack.javaWebFramework !== "none") {
@@ -1123,6 +1461,66 @@ const analyzeStackCompatibility = (stack) => {
1123
1461
  }
1124
1462
  }
1125
1463
  }
1464
+ if (nextStack.ecosystem === "elixir") {
1465
+ if (nextStack.elixirWebFramework === "none") for (const key of [
1466
+ "elixirAuth",
1467
+ "elixirApi",
1468
+ "elixirRealtime",
1469
+ "elixirObservability"
1470
+ ]) {
1471
+ const value = nextStack[key];
1472
+ if (key !== "elixirObservability" ? value !== "none" : value === "phoenix-telemetry") {
1473
+ nextStack[key] = "none";
1474
+ changed = true;
1475
+ changes.push({
1476
+ category: "elixirWebFramework",
1477
+ message: `${getCategoryDisplayName(key)} set to 'None' (requires Phoenix)`
1478
+ });
1479
+ }
1480
+ }
1481
+ if (nextStack.elixirWebFramework === "phoenix-live-view" && nextStack.elixirApi === "none") {
1482
+ nextStack.elixirRealtime = "live-view-streams";
1483
+ changed = true;
1484
+ changes.push({
1485
+ category: "elixirRealtime",
1486
+ message: "Elixir realtime set to 'LiveView Streams' (Phoenix LiveView selected)"
1487
+ });
1488
+ }
1489
+ if (nextStack.elixirOrm === "none") {
1490
+ if (nextStack.elixirJobs === "oban") {
1491
+ nextStack.elixirJobs = "none";
1492
+ changed = true;
1493
+ changes.push({
1494
+ category: "elixirOrm",
1495
+ message: "Elixir jobs set to 'None' (Oban requires Ecto SQL with PostgreSQL)"
1496
+ });
1497
+ }
1498
+ if (nextStack.elixirAuth === "phx-gen-auth") {
1499
+ nextStack.elixirAuth = "none";
1500
+ changed = true;
1501
+ changes.push({
1502
+ category: "elixirOrm",
1503
+ message: "Elixir auth set to 'None' (phx.gen.auth requires Ecto)"
1504
+ });
1505
+ }
1506
+ if (nextStack.elixirApi === "absinthe") {
1507
+ nextStack.elixirApi = "rest";
1508
+ changed = true;
1509
+ changes.push({
1510
+ category: "elixirOrm",
1511
+ message: "Elixir API set to 'REST' (the generated Absinthe resolver needs Ecto)"
1512
+ });
1513
+ }
1514
+ }
1515
+ if (nextStack.elixirJobs === "oban" && nextStack.elixirOrm !== "ecto-sql") {
1516
+ nextStack.elixirJobs = "none";
1517
+ changed = true;
1518
+ changes.push({
1519
+ category: "elixirJobs",
1520
+ message: "Elixir jobs set to 'None' (Oban requires Ecto SQL with PostgreSQL)"
1521
+ });
1522
+ }
1523
+ }
1126
1524
  if (nextStack.webDeploy !== "none" && !nextStack.webFrontend.some((f) => f !== "none")) {
1127
1525
  nextStack.webDeploy = "none";
1128
1526
  changed = true;
@@ -1145,6 +1543,7 @@ const analyzeStackCompatibility = (stack) => {
1145
1543
  "none",
1146
1544
  "convex",
1147
1545
  "self-next",
1546
+ "self-vinext",
1148
1547
  "self-tanstack-start",
1149
1548
  "self-astro",
1150
1549
  "self-nuxt",
@@ -1196,6 +1595,23 @@ const getDisabledReason = (currentStack, category, optionId) => {
1196
1595
  ].includes(f))})`;
1197
1596
  }
1198
1597
  }
1598
+ if (currentStack.ecosystem === "react-native") {
1599
+ if (!new Set([
1600
+ "nativeFrontend",
1601
+ "mobileNavigation",
1602
+ "mobileUI",
1603
+ "mobileStorage",
1604
+ "mobileTesting",
1605
+ "mobilePush",
1606
+ "mobileOTA",
1607
+ "mobileDeepLinking",
1608
+ "auth",
1609
+ "packageManager",
1610
+ "aiDocs",
1611
+ "git",
1612
+ "install"
1613
+ ]).has(category) && optionId !== "none" && optionId !== "false") return "React Native ecosystem only supports native mobile options";
1614
+ }
1199
1615
  if (currentStack.backend === "none") {
1200
1616
  if (category === "runtime" && optionId !== "none") return "No backend selected";
1201
1617
  if (category === "database" && optionId !== "none") return "No backend selected";
@@ -1213,6 +1629,11 @@ const getDisabledReason = (currentStack, category, optionId) => {
1213
1629
  if (category === "webFrontend" && optionId !== "next" && optionId !== "none") return "Next.js fullstack requires Next.js frontend";
1214
1630
  if (category === "serverDeploy" && optionId !== "none") return "Fullstack uses frontend deployment";
1215
1631
  }
1632
+ if (currentStack.backend === "self-vinext") {
1633
+ if (category === "runtime" && optionId !== "none") return "Vinext fullstack uses built-in API routes";
1634
+ if (category === "webFrontend" && optionId !== "vinext" && optionId !== "none") return "Vinext fullstack requires Vinext frontend";
1635
+ if (category === "serverDeploy" && optionId !== "none") return "Fullstack uses frontend deployment";
1636
+ }
1216
1637
  if (currentStack.backend === "self-tanstack-start") {
1217
1638
  if (category === "runtime" && optionId !== "none") return "TanStack Start fullstack uses built-in API routes";
1218
1639
  if (category === "webFrontend" && optionId !== "tanstack-start" && optionId !== "none") return "TanStack Start fullstack requires TanStack Start frontend";
@@ -1240,6 +1661,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1240
1661
  }
1241
1662
  if (category === "backend") {
1242
1663
  if (optionId === "self-next" && !currentStack.webFrontend.includes("next")) return "Requires Next.js frontend";
1664
+ if (optionId === "self-vinext" && !currentStack.webFrontend.includes("vinext")) return "Requires Vinext frontend";
1243
1665
  if (optionId === "self-tanstack-start" && !currentStack.webFrontend.includes("tanstack-start")) return "Requires TanStack Start frontend";
1244
1666
  if (optionId === "self-astro" && !currentStack.webFrontend.includes("astro")) return "Requires Astro frontend";
1245
1667
  if (optionId === "self-nuxt" && !currentStack.webFrontend.includes("nuxt")) return "Requires Nuxt frontend";
@@ -1257,6 +1679,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1257
1679
  "convex",
1258
1680
  "none",
1259
1681
  "self-next",
1682
+ "self-vinext",
1260
1683
  "self-tanstack-start",
1261
1684
  "self-astro",
1262
1685
  "self-nuxt",
@@ -1334,9 +1757,27 @@ const getDisabledReason = (currentStack, category, optionId) => {
1334
1757
  if (!currentStack.webFrontend.includes("next")) return "Payload CMS v3 requires Next.js";
1335
1758
  }
1336
1759
  if (category === "email" && optionId !== "none") {
1760
+ if (currentStack.ecosystem !== "typescript" && optionId !== "resend") return "Only Resend email is available for non-TypeScript ecosystems";
1761
+ if (currentStack.ecosystem === "java" && currentStack.javaBuildTool === "none" && optionId === "resend") return "Resend email for Java requires Maven or Gradle to manage the SDK dependency";
1762
+ if (currentStack.ecosystem !== "typescript") return null;
1337
1763
  if (currentStack.backend === "convex") return "Email integration is not available with Convex backend";
1338
1764
  if (currentStack.backend === "none") return "Email integration requires a backend";
1339
1765
  }
1766
+ if (category === "observability" && optionId !== "none") {
1767
+ if (currentStack.ecosystem !== "typescript" && optionId !== "sentry") return "Only Sentry observability is available for non-TypeScript ecosystems";
1768
+ if (currentStack.ecosystem === "java" && currentStack.javaBuildTool === "none" && optionId === "sentry") return "Sentry observability for Java requires Maven or Gradle to manage the SDK dependency";
1769
+ if (currentStack.ecosystem !== "typescript") return null;
1770
+ }
1771
+ if (category === "caching" && optionId !== "none") {
1772
+ if (currentStack.ecosystem !== "typescript" && optionId !== "upstash-redis") return "Only Upstash Redis caching is available for non-TypeScript ecosystems";
1773
+ if (currentStack.ecosystem === "java" && currentStack.javaBuildTool === "none" && optionId === "upstash-redis") return "Upstash Redis caching for Java requires Maven or Gradle to manage the Redis client dependency";
1774
+ if (currentStack.ecosystem !== "typescript") return null;
1775
+ }
1776
+ if (category === "search" && optionId !== "none") {
1777
+ if (currentStack.ecosystem !== "typescript" && optionId !== "meilisearch") return "Only Meilisearch search is available for non-TypeScript ecosystems";
1778
+ if (currentStack.ecosystem === "java" && currentStack.javaBuildTool === "none" && optionId === "meilisearch") return "Meilisearch search for Java requires Maven or Gradle to manage the SDK dependency";
1779
+ if (currentStack.ecosystem !== "typescript") return null;
1780
+ }
1340
1781
  if (category === "ai" && requiresChatSdkVercelAI(currentStack) && optionId !== "vercel-ai") return "Chat SDK example (Nuxt/Hono profile) requires Vercel AI SDK in v1";
1341
1782
  if (category === "ai" && optionId === "tanstack-ai") {
1342
1783
  const compatibleFrontends = [
@@ -1352,7 +1793,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1352
1793
  if (!currentStack.webFrontend.some((f) => compatibleFrontends.includes(f))) return "TanStack AI requires React or Solid frontend (no Vue/Svelte/Angular adapter yet)";
1353
1794
  }
1354
1795
  if (category === "appPlatforms") {
1355
- if (optionId === "pwa" && !hasPWACompatibleFrontend(currentStack.webFrontend)) return "PWA requires TanStack Router, React Router, Solid, Next.js, or Astro";
1796
+ if (optionId === "pwa" && !hasPWACompatibleFrontend(currentStack.webFrontend)) return "PWA requires TanStack Router, React Router, Solid, Next.js, Vinext, or Astro";
1356
1797
  if (optionId === "tauri" && !hasTauriCompatibleFrontend(currentStack.webFrontend)) return "Tauri requires TanStack Router, React Router, Nuxt, Svelte, Solid, Next.js, or Astro";
1357
1798
  if (optionId === "docker-compose") {
1358
1799
  if (currentStack.backend === "convex") return "Docker Compose is not compatible with Convex backend (managed service)";
@@ -1384,7 +1825,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1384
1825
  if (currentStack.ecosystem !== "typescript") return "Chat SDK example is currently available only for TypeScript stacks";
1385
1826
  if (currentStack.backend === "convex") return "Chat SDK example is not supported with Convex backend in v1";
1386
1827
  if (currentStack.backend === "self-astro" || currentStack.backend === "self-svelte" || currentStack.backend === "self-solid-start") return "Chat SDK self backend profile supports Next.js, TanStack Start, or Nuxt in v1";
1387
- if (currentStack.backend === "self-next" || currentStack.backend === "self-tanstack-start") return null;
1828
+ if (currentStack.backend === "self-next" || currentStack.backend === "self-vinext" || currentStack.backend === "self-tanstack-start") return null;
1388
1829
  if (currentStack.backend === "self-nuxt") return null;
1389
1830
  if (currentStack.backend === "hono") {
1390
1831
  if (currentStack.runtime !== "node") return "Chat SDK Hono profile requires Node runtime in v1";
@@ -1412,6 +1853,24 @@ const getDisabledReason = (currentStack, category, optionId) => {
1412
1853
  "nextui"
1413
1854
  ].includes(currentStack.uiLibrary) && optionId !== "tailwind") return `${currentStack.uiLibrary === "shadcn-ui" ? "shadcn/ui" : currentStack.uiLibrary === "daisyui" ? "daisyUI" : "NextUI"} requires Tailwind CSS`;
1414
1855
  }
1856
+ if (new Set([
1857
+ "mobileNavigation",
1858
+ "mobileUI",
1859
+ "mobileStorage",
1860
+ "mobileTesting",
1861
+ "mobilePush",
1862
+ "mobileOTA",
1863
+ "mobileDeepLinking"
1864
+ ]).has(category)) {
1865
+ if (!currentStack.nativeFrontend.some((f) => f !== "none") && optionId !== "none") return `${getCategoryDisplayName(category)} requires a native Expo frontend`;
1866
+ if (category === "mobileNavigation" && optionId === "react-navigation") return null;
1867
+ if (category === "mobileUI") {
1868
+ if (optionId === "uniwind" && !currentStack.nativeFrontend.includes("native-uniwind")) return "Uniwind mobile UI requires Expo + Uniwind frontend";
1869
+ if (optionId === "unistyles" && !currentStack.nativeFrontend.includes("native-unistyles")) return "Unistyles mobile UI requires Expo + Unistyles frontend";
1870
+ if (["tamagui", "gluestack-ui"].includes(optionId) && currentStack.nativeFrontend.some((f) => ["native-uniwind", "native-unistyles"].includes(f))) return "Tamagui and Gluestack UI require Expo + Bare to avoid conflicting styling setup";
1871
+ }
1872
+ if (category === "mobilePush" && optionId === "expo-notifications" || category === "mobileOTA" && optionId === "expo-updates" || category === "mobileDeepLinking" && optionId === "expo-linking") return null;
1873
+ }
1415
1874
  if (category === "uiLibrary") {
1416
1875
  if (!currentStack.webFrontend.some((f) => f !== "none")) {
1417
1876
  if (optionId !== "none") return "UI library requires a web frontend";
@@ -1420,7 +1879,9 @@ const getDisabledReason = (currentStack, category, optionId) => {
1420
1879
  "shadcn-ui",
1421
1880
  "radix-ui",
1422
1881
  "chakra-ui",
1423
- "nextui"
1882
+ "nextui",
1883
+ "mui",
1884
+ "antd"
1424
1885
  ];
1425
1886
  const reactFrontends = [
1426
1887
  "tanstack-router",
@@ -1432,7 +1893,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1432
1893
  if (reactOnlyLibraries.includes(optionId)) {
1433
1894
  const hasReactFrontend = currentStack.webFrontend.some((f) => reactFrontends.includes(f));
1434
1895
  const hasAstroReact = currentStack.webFrontend.includes("astro") && currentStack.astroIntegration === "react";
1435
- if (!hasReactFrontend && !hasAstroReact) return `${optionId === "shadcn-ui" ? "shadcn/ui" : optionId === "radix-ui" ? "Radix UI" : optionId === "chakra-ui" ? "Chakra UI" : "NextUI"} requires a React-based frontend`;
1896
+ if (!hasReactFrontend && !hasAstroReact) return `${optionId === "shadcn-ui" ? "shadcn/ui" : optionId === "radix-ui" ? "Radix UI" : optionId === "chakra-ui" ? "Chakra UI" : optionId === "mui" ? "MUI" : optionId === "antd" ? "Ant Design" : "NextUI"} requires a React-based frontend`;
1436
1897
  }
1437
1898
  if (optionId === "headless-ui") {
1438
1899
  const hasReactFrontend = currentStack.webFrontend.some((f) => reactFrontends.includes(f));
@@ -1494,12 +1955,15 @@ const getDisabledReason = (currentStack, category, optionId) => {
1494
1955
  if (!currentStack.webFrontend.includes("next")) return "next-intl requires Next.js";
1495
1956
  }
1496
1957
  }
1958
+ if (category === "pythonApi") {
1959
+ if (optionId !== "none" && currentStack.pythonWebFramework !== "django") return "Python API frameworks currently require Django";
1960
+ }
1497
1961
  if (category === "javaWebFramework") {
1498
- if (optionId === "spring-boot" && currentStack.javaBuildTool === "none") return "Spring Boot requires Maven or Gradle";
1962
+ if (optionId !== "none" && currentStack.javaBuildTool === "none") return "Java web frameworks require Maven or Gradle";
1499
1963
  }
1500
1964
  if (category === "javaBuildTool") {
1501
1965
  if (optionId === "none") {
1502
- if (currentStack.javaWebFramework === "spring-boot") return "Spring Boot requires Maven or Gradle";
1966
+ if (currentStack.javaWebFramework !== "none") return "Java web frameworks require Maven or Gradle";
1503
1967
  if (currentStack.javaOrm !== "none") return "Java ORM support requires Maven or Gradle";
1504
1968
  if (currentStack.javaAuth !== "none") return "Java auth support requires Maven or Gradle";
1505
1969
  if (currentStack.javaLibraries.some((library) => library !== "none")) return "Java libraries require Maven or Gradle";
@@ -1525,6 +1989,62 @@ const getDisabledReason = (currentStack, category, optionId) => {
1525
1989
  if (category === "javaTestingLibraries") {
1526
1990
  if (optionId !== "none" && currentStack.javaBuildTool === "none") return "Java testing libraries require Maven or Gradle";
1527
1991
  }
1992
+ if (new Set([
1993
+ "elixirOrm",
1994
+ "elixirAuth",
1995
+ "elixirApi",
1996
+ "elixirRealtime",
1997
+ "elixirJobs",
1998
+ "elixirValidation",
1999
+ "elixirHttp",
2000
+ "elixirJson",
2001
+ "elixirEmail",
2002
+ "elixirCaching",
2003
+ "elixirObservability",
2004
+ "elixirTesting",
2005
+ "elixirQuality",
2006
+ "elixirDeploy"
2007
+ ]).has(category) && optionId !== "none") {
2008
+ if (currentStack.ecosystem !== "elixir") return "Elixir options only apply when the Elixir ecosystem is selected";
2009
+ }
2010
+ if (category === "elixirWebFramework" && optionId !== "none" && currentStack.ecosystem !== "elixir") return "Elixir web frameworks are available only in the Elixir ecosystem";
2011
+ const unsupportedElixirReason = {
2012
+ elixirOrm: { ecto: "Use Ecto SQL for generated Repo, migrations, schemas, and PostgreSQL wiring" },
2013
+ elixirAuth: {
2014
+ ueberauth: "Ueberauth is not generated yet; use phx.gen.auth or no auth",
2015
+ guardian: "Guardian JWT wiring is not generated yet; use phx.gen.auth or no auth"
2016
+ },
2017
+ elixirValidation: { "nimble-options": "NimbleOptions is not generated yet; use Ecto Changesets or no extra validation" },
2018
+ elixirCaching: { nebulex: "Nebulex cache modules are not generated yet; use Cachex or no cache" },
2019
+ elixirObservability: {
2020
+ opentelemetry: "OpenTelemetry setup is not generated yet; use Phoenix telemetry or no extra observability",
2021
+ prom_ex: "PromEx setup is not generated yet; use Phoenix telemetry or no extra observability"
2022
+ },
2023
+ elixirTesting: {
2024
+ mox: "Mox-specific test boundaries are not generated yet; use ExUnit",
2025
+ bypass: "Bypass-specific HTTP tests are not generated yet; use ExUnit",
2026
+ wallaby: "Wallaby browser tests are not generated yet; use ExUnit"
2027
+ },
2028
+ elixirDeploy: {
2029
+ fly: "Fly.io config is not generated yet; use Docker or mix releases",
2030
+ gigalixir: "Gigalixir config is not generated yet; use Docker or mix releases"
2031
+ }
2032
+ }[category]?.[optionId];
2033
+ if (currentStack.ecosystem === "elixir" && unsupportedElixirReason) return unsupportedElixirReason;
2034
+ if (currentStack.ecosystem === "elixir" && currentStack.elixirWebFramework === "none") {
2035
+ if (category === "elixirAuth" && optionId !== "none") return "Elixir auth scaffolds require Phoenix";
2036
+ if (category === "elixirApi" && optionId !== "none") return "Elixir API scaffolds require Phoenix";
2037
+ if (category === "elixirRealtime" && optionId !== "none") return "Elixir realtime scaffolds require Phoenix";
2038
+ if (category === "elixirObservability" && optionId === "phoenix-telemetry") return "Phoenix telemetry requires Phoenix";
2039
+ }
2040
+ if (category === "elixirJson" && optionId === "none" && currentStack.ecosystem === "elixir" && currentStack.elixirWebFramework !== "none") return "Phoenix JSON scaffolds require Jason";
2041
+ if (category === "elixirAuth") {
2042
+ if (optionId === "phx-gen-auth" && currentStack.elixirOrm === "none") return "phx.gen.auth requires Ecto";
2043
+ if ((optionId === "ueberauth" || optionId === "guardian") && currentStack.elixirWebFramework === "none") return "Elixir auth libraries require Phoenix";
2044
+ }
2045
+ if (category === "elixirJobs" && optionId === "oban" && currentStack.elixirOrm !== "ecto-sql") return "Oban requires Ecto SQL with PostgreSQL in the current Phoenix scaffold";
2046
+ if (category === "elixirApi" && optionId === "absinthe" && currentStack.elixirOrm === "none") return "Absinthe GraphQL requires Ecto in the current Phoenix scaffold";
2047
+ if (category === "elixirRealtime" && optionId === "live-view-streams" && currentStack.elixirWebFramework !== "phoenix-live-view") return "LiveView Streams require Phoenix LiveView";
1528
2048
  return null;
1529
2049
  };
1530
2050
  const isOptionCompatible = (currentStack, category, optionId) => {
@@ -1537,6 +2057,7 @@ const WEB_FRAMEWORKS = [
1537
2057
  "react-vite",
1538
2058
  "tanstack-start",
1539
2059
  "next",
2060
+ "vinext",
1540
2061
  "nuxt",
1541
2062
  "svelte",
1542
2063
  "solid",
@@ -1556,6 +2077,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1556
2077
  "react-vite",
1557
2078
  "tanstack-start",
1558
2079
  "next",
2080
+ "vinext",
1559
2081
  "astro"
1560
2082
  ],
1561
2083
  cssFrameworks: ["tailwind"]
@@ -1567,6 +2089,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1567
2089
  "react-vite",
1568
2090
  "tanstack-start",
1569
2091
  "next",
2092
+ "vinext",
1570
2093
  "nuxt",
1571
2094
  "svelte",
1572
2095
  "solid",
@@ -1586,6 +2109,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1586
2109
  "react-vite",
1587
2110
  "tanstack-start",
1588
2111
  "next",
2112
+ "vinext",
1589
2113
  "astro"
1590
2114
  ],
1591
2115
  cssFrameworks: [
@@ -1603,6 +2127,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1603
2127
  "react-vite",
1604
2128
  "tanstack-start",
1605
2129
  "next",
2130
+ "vinext",
1606
2131
  "nuxt",
1607
2132
  "astro"
1608
2133
  ],
@@ -1621,6 +2146,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1621
2146
  "react-vite",
1622
2147
  "tanstack-start",
1623
2148
  "next",
2149
+ "vinext",
1624
2150
  "nuxt",
1625
2151
  "solid",
1626
2152
  "solid-start",
@@ -1640,6 +2166,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1640
2166
  "react-vite",
1641
2167
  "tanstack-start",
1642
2168
  "next",
2169
+ "vinext",
1643
2170
  "astro"
1644
2171
  ],
1645
2172
  cssFrameworks: [
@@ -1657,11 +2184,47 @@ const UI_LIBRARY_COMPATIBILITY = {
1657
2184
  "react-vite",
1658
2185
  "tanstack-start",
1659
2186
  "next",
2187
+ "vinext",
1660
2188
  "astro"
1661
2189
  ],
1662
2190
  cssFrameworks: ["tailwind"]
1663
2191
  },
1664
2192
  mantine: {
2193
+ frontends: [
2194
+ "tanstack-router",
2195
+ "react-router",
2196
+ "react-vite",
2197
+ "tanstack-start",
2198
+ "next",
2199
+ "vinext",
2200
+ "astro"
2201
+ ],
2202
+ cssFrameworks: [
2203
+ "tailwind",
2204
+ "scss",
2205
+ "less",
2206
+ "postcss-only",
2207
+ "none"
2208
+ ]
2209
+ },
2210
+ mui: {
2211
+ frontends: [
2212
+ "tanstack-router",
2213
+ "react-router",
2214
+ "react-vite",
2215
+ "tanstack-start",
2216
+ "next",
2217
+ "astro"
2218
+ ],
2219
+ cssFrameworks: [
2220
+ "tailwind",
2221
+ "scss",
2222
+ "less",
2223
+ "postcss-only",
2224
+ "none"
2225
+ ]
2226
+ },
2227
+ antd: {
1665
2228
  frontends: [
1666
2229
  "tanstack-router",
1667
2230
  "react-router",
@@ -1685,6 +2248,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1685
2248
  "react-vite",
1686
2249
  "tanstack-start",
1687
2250
  "next",
2251
+ "vinext",
1688
2252
  "astro"
1689
2253
  ],
1690
2254
  cssFrameworks: [
@@ -1701,6 +2265,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1701
2265
  "react-router",
1702
2266
  "tanstack-start",
1703
2267
  "next",
2268
+ "vinext",
1704
2269
  "nuxt",
1705
2270
  "svelte",
1706
2271
  "solid",
@@ -1722,6 +2287,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1722
2287
  "react-vite",
1723
2288
  "tanstack-start",
1724
2289
  "next",
2290
+ "vinext",
1725
2291
  "astro"
1726
2292
  ],
1727
2293
  cssFrameworks: [
@@ -1750,6 +2316,7 @@ const ADDON_COMPATIBILITY = {
1750
2316
  "react-vite",
1751
2317
  "solid",
1752
2318
  "next",
2319
+ "vinext",
1753
2320
  "astro",
1754
2321
  "qwik",
1755
2322
  "angular",
@@ -2176,10 +2743,26 @@ function evaluateCompatibility(input) {
2176
2743
  ["forms", input.forms],
2177
2744
  ["stateManagement", input.stateManagement],
2178
2745
  ["animation", input.animation],
2746
+ ["pythonApi", input.pythonApi],
2179
2747
  ["javaWebFramework", input.javaWebFramework],
2180
2748
  ["javaBuildTool", input.javaBuildTool],
2181
2749
  ["javaOrm", input.javaOrm],
2182
- ["javaAuth", input.javaAuth]
2750
+ ["javaAuth", input.javaAuth],
2751
+ ["elixirWebFramework", input.elixirWebFramework],
2752
+ ["elixirOrm", input.elixirOrm],
2753
+ ["elixirAuth", input.elixirAuth],
2754
+ ["elixirApi", input.elixirApi],
2755
+ ["elixirRealtime", input.elixirRealtime],
2756
+ ["elixirJobs", input.elixirJobs],
2757
+ ["elixirValidation", input.elixirValidation],
2758
+ ["elixirHttp", input.elixirHttp],
2759
+ ["elixirJson", input.elixirJson],
2760
+ ["elixirEmail", input.elixirEmail],
2761
+ ["elixirCaching", input.elixirCaching],
2762
+ ["elixirObservability", input.elixirObservability],
2763
+ ["elixirTesting", input.elixirTesting],
2764
+ ["elixirQuality", input.elixirQuality],
2765
+ ["elixirDeploy", input.elixirDeploy]
2183
2766
  ];
2184
2767
  for (const [category, optionId] of scalarChecks) {
2185
2768
  const reason = getDisabledReason(input, category, optionId);
@@ -2254,6 +2837,7 @@ const WEB_FRONTEND_VALUES = [
2254
2837
  "react-vite",
2255
2838
  "tanstack-start",
2256
2839
  "next",
2840
+ "vinext",
2257
2841
  "nuxt",
2258
2842
  "svelte",
2259
2843
  "solid",
@@ -2283,6 +2867,7 @@ const BACKEND_BUILDER_VALUES = [
2283
2867
  "encore",
2284
2868
  "convex",
2285
2869
  "self-next",
2870
+ "self-vinext",
2286
2871
  "self-tanstack-start",
2287
2872
  "self-astro",
2288
2873
  "self-nuxt",
@@ -2366,6 +2951,13 @@ const CATEGORY_VALUE_IDS = {
2366
2951
  cms: CMS_VALUES,
2367
2952
  featureFlags: FEATURE_FLAGS_VALUES,
2368
2953
  analytics: ANALYTICS_VALUES,
2954
+ mobileNavigation: MOBILE_NAVIGATION_VALUES,
2955
+ mobileUI: MOBILE_UI_VALUES,
2956
+ mobileStorage: MOBILE_STORAGE_VALUES,
2957
+ mobileTesting: MOBILE_TESTING_VALUES,
2958
+ mobilePush: MOBILE_PUSH_VALUES,
2959
+ mobileOTA: MOBILE_OTA_VALUES,
2960
+ mobileDeepLinking: MOBILE_DEEP_LINKING_VALUES,
2369
2961
  codeQuality: CODE_QUALITY_VALUES,
2370
2962
  documentation: DOCUMENTATION_VALUES,
2371
2963
  appPlatforms: APP_PLATFORM_VALUES,
@@ -2399,6 +2991,7 @@ const CATEGORY_VALUE_IDS = {
2399
2991
  pythonValidation: PYTHON_VALIDATION_VALUES,
2400
2992
  pythonAi: PYTHON_AI_VALUES,
2401
2993
  pythonAuth: PYTHON_AUTH_VALUES,
2994
+ pythonApi: PYTHON_API_VALUES,
2402
2995
  pythonTaskQueue: PYTHON_TASK_QUEUE_VALUES,
2403
2996
  pythonGraphql: PYTHON_GRAPHQL_VALUES,
2404
2997
  pythonQuality: PYTHON_QUALITY_VALUES,
@@ -2413,7 +3006,22 @@ const CATEGORY_VALUE_IDS = {
2413
3006
  javaOrm: JAVA_ORM_VALUES,
2414
3007
  javaAuth: JAVA_AUTH_VALUES,
2415
3008
  javaLibraries: JAVA_LIBRARIES_VALUES,
2416
- javaTestingLibraries: JAVA_TESTING_LIBRARIES_VALUES
3009
+ javaTestingLibraries: JAVA_TESTING_LIBRARIES_VALUES,
3010
+ elixirWebFramework: ELIXIR_WEB_FRAMEWORK_VALUES,
3011
+ elixirOrm: ELIXIR_ORM_VALUES,
3012
+ elixirAuth: ELIXIR_AUTH_VALUES,
3013
+ elixirApi: ELIXIR_API_VALUES,
3014
+ elixirRealtime: ELIXIR_REALTIME_VALUES,
3015
+ elixirJobs: ELIXIR_JOBS_VALUES,
3016
+ elixirValidation: ELIXIR_VALIDATION_VALUES,
3017
+ elixirHttp: ELIXIR_HTTP_VALUES,
3018
+ elixirJson: ELIXIR_JSON_VALUES,
3019
+ elixirEmail: ELIXIR_EMAIL_VALUES,
3020
+ elixirCaching: ELIXIR_CACHING_VALUES,
3021
+ elixirObservability: ELIXIR_OBSERVABILITY_VALUES,
3022
+ elixirTesting: ELIXIR_TESTING_VALUES,
3023
+ elixirQuality: ELIXIR_QUALITY_VALUES,
3024
+ elixirDeploy: ELIXIR_DEPLOY_VALUES
2417
3025
  };
2418
3026
  const EXACT_LABEL_OVERRIDES = {
2419
3027
  api: {
@@ -2423,6 +3031,7 @@ const EXACT_LABEL_OVERRIDES = {
2423
3031
  },
2424
3032
  webFrontend: {
2425
3033
  next: "Next.js",
3034
+ vinext: "Vinext",
2426
3035
  "react-vite": "React + Vite",
2427
3036
  svelte: "SvelteKit",
2428
3037
  redwood: "RedwoodJS"
@@ -2441,6 +3050,7 @@ const EXACT_LABEL_OVERRIDES = {
2441
3050
  nestjs: "NestJS",
2442
3051
  encore: "Encore.ts",
2443
3052
  "self-next": "Fullstack Next.js",
3053
+ "self-vinext": "Fullstack Vinext",
2444
3054
  "self-tanstack-start": "Fullstack TanStack Start",
2445
3055
  "self-astro": "Fullstack Astro",
2446
3056
  "self-nuxt": "Fullstack Nuxt",
@@ -2545,18 +3155,42 @@ const EXACT_LABEL_OVERRIDES = {
2545
3155
  "park-ui": "Park UI",
2546
3156
  "chakra-ui": "Chakra UI",
2547
3157
  nextui: "NextUI",
3158
+ mui: "MUI",
3159
+ antd: "Ant Design",
2548
3160
  "base-ui": "Base UI",
2549
3161
  "ark-ui": "Ark UI",
2550
3162
  "react-aria": "React Aria"
2551
3163
  },
2552
3164
  featureFlags: {
2553
3165
  growthbook: "GrowthBook",
2554
- posthog: "PostHog"
3166
+ posthog: "PostHog",
3167
+ launchdarkly: "LaunchDarkly",
3168
+ flagsmith: "Flagsmith",
3169
+ unleash: "Unleash"
2555
3170
  },
2556
3171
  analytics: {
2557
3172
  plausible: "Plausible",
2558
3173
  umami: "Umami"
2559
3174
  },
3175
+ mobileNavigation: {
3176
+ "expo-router": "Expo Router",
3177
+ "react-navigation": "React Navigation"
3178
+ },
3179
+ mobileUI: {
3180
+ tamagui: "Tamagui",
3181
+ "gluestack-ui": "Gluestack UI",
3182
+ uniwind: "Uniwind",
3183
+ unistyles: "Unistyles"
3184
+ },
3185
+ mobileStorage: { mmkv: "MMKV" },
3186
+ mobileTesting: {
3187
+ maestro: "Maestro",
3188
+ "react-native-testing-library": "React Native Testing Library",
3189
+ "maestro-react-native-testing-library": "Maestro + RN Testing Library"
3190
+ },
3191
+ mobilePush: { "expo-notifications": "Expo Notifications" },
3192
+ mobileOTA: { "expo-updates": "Expo Updates" },
3193
+ mobileDeepLinking: { "expo-linking": "Expo Linking" },
2560
3194
  codeQuality: {
2561
3195
  biome: "Biome",
2562
3196
  oxlint: "Oxlint",
@@ -2629,14 +3263,18 @@ const EXACT_LABEL_OVERRIDES = {
2629
3263
  nova: "Nova",
2630
3264
  maia: "Maia",
2631
3265
  lyra: "Lyra",
2632
- mira: "Mira"
3266
+ mira: "Mira",
3267
+ luma: "Luma",
3268
+ sera: "Sera"
2633
3269
  },
2634
3270
  shadcnIconLibrary: {
2635
3271
  lucide: "Lucide",
2636
3272
  tabler: "Tabler Icons",
2637
3273
  hugeicons: "HugeIcons",
2638
3274
  phosphor: "Phosphor Icons",
2639
- remixicon: "Remix Icon"
3275
+ remixicon: "Remix Icon",
3276
+ heroicons: "Heroicons",
3277
+ "react-icons": "React Icons"
2640
3278
  },
2641
3279
  shadcnColorTheme: { neutral: "Neutral" },
2642
3280
  shadcnBaseColor: { neutral: "Neutral" },
@@ -2679,11 +3317,22 @@ const EXACT_LABEL_OVERRIDES = {
2679
3317
  },
2680
3318
  rustLibraries: {
2681
3319
  serde: "Serde",
3320
+ uuid: "uuid",
3321
+ chrono: "Chrono",
3322
+ reqwest: "Reqwest",
3323
+ config: "config",
3324
+ dashmap: "DashMap",
3325
+ "parking-lot": "parking_lot",
3326
+ secrecy: "Secrecy",
3327
+ "tokio-util": "Tokio Util",
3328
+ utoipa: "utoipa",
2682
3329
  validator: "Validator",
2683
3330
  jsonwebtoken: "jsonwebtoken",
2684
3331
  argon2: "Argon2",
2685
3332
  "tokio-test": "Tokio Test",
2686
- mockall: "Mockall"
3333
+ mockall: "Mockall",
3334
+ proptest: "Proptest",
3335
+ insta: "Insta"
2687
3336
  },
2688
3337
  rustLogging: {
2689
3338
  tracing: "Tracing",
@@ -2716,15 +3365,32 @@ const EXACT_LABEL_OVERRIDES = {
2716
3365
  "openai-sdk": "OpenAI SDK",
2717
3366
  "anthropic-sdk": "Anthropic SDK",
2718
3367
  langgraph: "LangGraph",
2719
- crewai: "CrewAI"
3368
+ crewai: "CrewAI",
3369
+ haystack: "Haystack"
2720
3370
  },
2721
3371
  pythonAuth: {
2722
3372
  authlib: "Authlib",
2723
3373
  jwt: "JWT (python-jose)"
2724
3374
  },
2725
- pythonTaskQueue: { celery: "Celery" },
2726
- pythonGraphql: { strawberry: "Strawberry" },
2727
- pythonQuality: { ruff: "Ruff" },
3375
+ pythonApi: {
3376
+ "django-rest-framework": "Django REST Framework",
3377
+ "django-ninja": "Django Ninja"
3378
+ },
3379
+ pythonTaskQueue: {
3380
+ celery: "Celery",
3381
+ rq: "RQ",
3382
+ dramatiq: "Dramatiq",
3383
+ huey: "Huey"
3384
+ },
3385
+ pythonGraphql: {
3386
+ strawberry: "Strawberry",
3387
+ ariadne: "Ariadne"
3388
+ },
3389
+ pythonQuality: {
3390
+ ruff: "Ruff",
3391
+ mypy: "mypy",
3392
+ pyright: "Pyright"
3393
+ },
2728
3394
  goWebFramework: {
2729
3395
  gin: "Gin",
2730
3396
  echo: "Echo",
@@ -2739,18 +3405,23 @@ const EXACT_LABEL_OVERRIDES = {
2739
3405
  goApi: { "grpc-go": "gRPC-Go" },
2740
3406
  goCli: {
2741
3407
  cobra: "Cobra",
2742
- bubbletea: "Bubble Tea"
3408
+ bubbletea: "Bubble Tea",
3409
+ "urfave-cli": "urfave/cli"
2743
3410
  },
2744
3411
  goLogging: {
2745
3412
  zap: "Zap",
2746
3413
  zerolog: "Zerolog",
2747
- slog: "slog"
3414
+ slog: "slog",
3415
+ logrus: "Logrus"
2748
3416
  },
2749
3417
  goAuth: {
2750
3418
  casbin: "Casbin",
2751
3419
  jwt: "golang-jwt"
2752
3420
  },
2753
- javaWebFramework: { "spring-boot": "Spring Boot" },
3421
+ javaWebFramework: {
3422
+ "spring-boot": "Spring Boot",
3423
+ quarkus: "Quarkus"
3424
+ },
2754
3425
  javaBuildTool: { maven: "Maven" },
2755
3426
  javaOrm: { "spring-data-jpa": "Spring Data JPA" },
2756
3427
  javaAuth: { "spring-security": "Spring Security" },
@@ -2762,7 +3433,15 @@ const EXACT_LABEL_OVERRIDES = {
2762
3433
  "springdoc-openapi": "Springdoc OpenAPI",
2763
3434
  lombok: "Lombok",
2764
3435
  mapstruct: "MapStruct",
2765
- caffeine: "Caffeine"
3436
+ caffeine: "Caffeine",
3437
+ resilience4j: "Resilience4j",
3438
+ "spring-webflux": "Spring WebFlux",
3439
+ "spring-batch": "Spring Batch",
3440
+ "spring-kafka": "Spring for Apache Kafka",
3441
+ "spring-mail": "Spring Mail",
3442
+ "spring-devtools": "Spring Boot DevTools",
3443
+ "micrometer-prometheus": "Micrometer Prometheus",
3444
+ thymeleaf: "Thymeleaf"
2766
3445
  },
2767
3446
  javaTestingLibraries: {
2768
3447
  junit5: "JUnit 5",
@@ -2774,6 +3453,69 @@ const EXACT_LABEL_OVERRIDES = {
2774
3453
  awaitility: "Awaitility",
2775
3454
  archunit: "ArchUnit",
2776
3455
  jqwik: "jqwik"
3456
+ },
3457
+ elixirWebFramework: {
3458
+ phoenix: "Phoenix",
3459
+ "phoenix-live-view": "Phoenix LiveView"
3460
+ },
3461
+ elixirOrm: {
3462
+ ecto: "Ecto",
3463
+ "ecto-sql": "Ecto SQL"
3464
+ },
3465
+ elixirAuth: {
3466
+ "phx-gen-auth": "phx.gen.auth",
3467
+ ueberauth: "Ueberauth",
3468
+ guardian: "Guardian"
3469
+ },
3470
+ elixirApi: {
3471
+ rest: "Phoenix REST",
3472
+ absinthe: "Absinthe GraphQL"
3473
+ },
3474
+ elixirRealtime: {
3475
+ channels: "Phoenix Channels",
3476
+ presence: "Phoenix Presence",
3477
+ pubsub: "Phoenix PubSub",
3478
+ "live-view-streams": "LiveView Streams"
3479
+ },
3480
+ elixirJobs: {
3481
+ oban: "Oban",
3482
+ quantum: "Quantum"
3483
+ },
3484
+ elixirValidation: {
3485
+ "ecto-changesets": "Ecto Changesets",
3486
+ "nimble-options": "NimbleOptions"
3487
+ },
3488
+ elixirHttp: {
3489
+ req: "Req",
3490
+ finch: "Finch"
3491
+ },
3492
+ elixirJson: { jason: "Jason" },
3493
+ elixirEmail: { swoosh: "Swoosh" },
3494
+ elixirCaching: {
3495
+ cachex: "Cachex",
3496
+ nebulex: "Nebulex"
3497
+ },
3498
+ elixirObservability: {
3499
+ telemetry: "Telemetry",
3500
+ opentelemetry: "OpenTelemetry",
3501
+ prom_ex: "PromEx"
3502
+ },
3503
+ elixirTesting: {
3504
+ ex_unit: "ExUnit",
3505
+ mox: "Mox",
3506
+ bypass: "Bypass",
3507
+ wallaby: "Wallaby"
3508
+ },
3509
+ elixirQuality: {
3510
+ credo: "Credo",
3511
+ dialyxir: "Dialyxir",
3512
+ sobelow: "Sobelow"
3513
+ },
3514
+ elixirDeploy: {
3515
+ docker: "Docker",
3516
+ fly: "Fly.io",
3517
+ gigalixir: "Gigalixir",
3518
+ "mix-release": "Mix Release"
2777
3519
  }
2778
3520
  };
2779
3521
  const OPTION_ALIASES = {
@@ -2782,6 +3524,7 @@ const OPTION_ALIASES = {
2782
3524
  };
2783
3525
  const CLI_VALUE_OVERRIDES = { backend: {
2784
3526
  "self-next": "self",
3527
+ "self-vinext": "self",
2785
3528
  "self-tanstack-start": "self",
2786
3529
  "self-astro": "self",
2787
3530
  "self-nuxt": "self",
@@ -2868,6 +3611,13 @@ const OPTION_CATEGORY_METADATA = {
2868
3611
  cms: buildCategoryMetadata("cms"),
2869
3612
  featureFlags: buildCategoryMetadata("featureFlags"),
2870
3613
  analytics: buildCategoryMetadata("analytics"),
3614
+ mobileNavigation: buildCategoryMetadata("mobileNavigation"),
3615
+ mobileUI: buildCategoryMetadata("mobileUI"),
3616
+ mobileStorage: buildCategoryMetadata("mobileStorage"),
3617
+ mobileTesting: buildCategoryMetadata("mobileTesting"),
3618
+ mobilePush: buildCategoryMetadata("mobilePush"),
3619
+ mobileOTA: buildCategoryMetadata("mobileOTA"),
3620
+ mobileDeepLinking: buildCategoryMetadata("mobileDeepLinking"),
2871
3621
  codeQuality: buildCategoryMetadata("codeQuality"),
2872
3622
  documentation: buildCategoryMetadata("documentation"),
2873
3623
  appPlatforms: buildCategoryMetadata("appPlatforms"),
@@ -2901,6 +3651,7 @@ const OPTION_CATEGORY_METADATA = {
2901
3651
  pythonValidation: buildCategoryMetadata("pythonValidation"),
2902
3652
  pythonAi: buildCategoryMetadata("pythonAi"),
2903
3653
  pythonAuth: buildCategoryMetadata("pythonAuth"),
3654
+ pythonApi: buildCategoryMetadata("pythonApi"),
2904
3655
  pythonTaskQueue: buildCategoryMetadata("pythonTaskQueue"),
2905
3656
  pythonGraphql: buildCategoryMetadata("pythonGraphql"),
2906
3657
  pythonQuality: buildCategoryMetadata("pythonQuality"),
@@ -2915,7 +3666,22 @@ const OPTION_CATEGORY_METADATA = {
2915
3666
  javaOrm: buildCategoryMetadata("javaOrm"),
2916
3667
  javaAuth: buildCategoryMetadata("javaAuth"),
2917
3668
  javaLibraries: buildCategoryMetadata("javaLibraries"),
2918
- javaTestingLibraries: buildCategoryMetadata("javaTestingLibraries")
3669
+ javaTestingLibraries: buildCategoryMetadata("javaTestingLibraries"),
3670
+ elixirWebFramework: buildCategoryMetadata("elixirWebFramework"),
3671
+ elixirOrm: buildCategoryMetadata("elixirOrm"),
3672
+ elixirAuth: buildCategoryMetadata("elixirAuth"),
3673
+ elixirApi: buildCategoryMetadata("elixirApi"),
3674
+ elixirRealtime: buildCategoryMetadata("elixirRealtime"),
3675
+ elixirJobs: buildCategoryMetadata("elixirJobs"),
3676
+ elixirValidation: buildCategoryMetadata("elixirValidation"),
3677
+ elixirHttp: buildCategoryMetadata("elixirHttp"),
3678
+ elixirJson: buildCategoryMetadata("elixirJson"),
3679
+ elixirEmail: buildCategoryMetadata("elixirEmail"),
3680
+ elixirCaching: buildCategoryMetadata("elixirCaching"),
3681
+ elixirObservability: buildCategoryMetadata("elixirObservability"),
3682
+ elixirTesting: buildCategoryMetadata("elixirTesting"),
3683
+ elixirQuality: buildCategoryMetadata("elixirQuality"),
3684
+ elixirDeploy: buildCategoryMetadata("elixirDeploy")
2919
3685
  };
2920
3686
  const OPTION_LOOKUP = Object.fromEntries(Object.entries(OPTION_CATEGORY_METADATA).map(([category, metadata]) => [category, new Map(metadata.options.flatMap((option) => [[option.id.toLowerCase(), option.id], ...option.aliases.map((alias) => [alias.toLowerCase(), option.id])]))]));
2921
3687
  function isMultiSelectCategory(category) {
@@ -2955,6 +3721,13 @@ const DEFAULT_STACK_SELECTION = {
2955
3721
  observability: "none",
2956
3722
  featureFlags: "none",
2957
3723
  analytics: "none",
3724
+ mobileNavigation: "none",
3725
+ mobileUI: "none",
3726
+ mobileStorage: "none",
3727
+ mobileTesting: "none",
3728
+ mobilePush: "none",
3729
+ mobileOTA: "none",
3730
+ mobileDeepLinking: "none",
2958
3731
  backendLibraries: "none",
2959
3732
  stateManagement: "none",
2960
3733
  forms: "react-hook-form",
@@ -3006,6 +3779,7 @@ const DEFAULT_STACK_SELECTION = {
3006
3779
  pythonValidation: "pydantic",
3007
3780
  pythonAi: [],
3008
3781
  pythonAuth: "none",
3782
+ pythonApi: "none",
3009
3783
  pythonTaskQueue: "none",
3010
3784
  pythonGraphql: "none",
3011
3785
  pythonQuality: "ruff",
@@ -3020,7 +3794,22 @@ const DEFAULT_STACK_SELECTION = {
3020
3794
  javaOrm: "none",
3021
3795
  javaAuth: "none",
3022
3796
  javaLibraries: [],
3023
- javaTestingLibraries: ["junit5"]
3797
+ javaTestingLibraries: ["junit5"],
3798
+ elixirWebFramework: "phoenix",
3799
+ elixirOrm: "ecto-sql",
3800
+ elixirAuth: "none",
3801
+ elixirApi: "rest",
3802
+ elixirRealtime: "channels",
3803
+ elixirJobs: "none",
3804
+ elixirValidation: "ecto-changesets",
3805
+ elixirHttp: "req",
3806
+ elixirJson: "jason",
3807
+ elixirEmail: "none",
3808
+ elixirCaching: "none",
3809
+ elixirObservability: "telemetry",
3810
+ elixirTesting: "ex_unit",
3811
+ elixirQuality: "credo",
3812
+ elixirDeploy: "none"
3024
3813
  };
3025
3814
  const NON_OPTION_STACK_SELECTION_KEYS = [
3026
3815
  "ecosystem",
@@ -3044,6 +3833,13 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
3044
3833
  observability: "observability",
3045
3834
  featureFlags: "featureFlags",
3046
3835
  analytics: "analytics",
3836
+ mobileNavigation: "mobileNavigation",
3837
+ mobileUI: "mobileUI",
3838
+ mobileStorage: "mobileStorage",
3839
+ mobileTesting: "mobileTesting",
3840
+ mobilePush: "mobilePush",
3841
+ mobileOTA: "mobileOTA",
3842
+ mobileDeepLinking: "mobileDeepLinking",
3047
3843
  backendLibraries: "backendLibraries",
3048
3844
  stateManagement: "stateManagement",
3049
3845
  forms: "forms",
@@ -3094,6 +3890,7 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
3094
3890
  pythonValidation: "pythonValidation",
3095
3891
  pythonAi: "pythonAi",
3096
3892
  pythonAuth: "pythonAuth",
3893
+ pythonApi: "pythonApi",
3097
3894
  pythonTaskQueue: "pythonTaskQueue",
3098
3895
  pythonGraphql: "pythonGraphql",
3099
3896
  pythonQuality: "pythonQuality",
@@ -3108,7 +3905,22 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
3108
3905
  javaOrm: "javaOrm",
3109
3906
  javaAuth: "javaAuth",
3110
3907
  javaLibraries: "javaLibraries",
3111
- javaTestingLibraries: "javaTestingLibraries"
3908
+ javaTestingLibraries: "javaTestingLibraries",
3909
+ elixirWebFramework: "elixirWebFramework",
3910
+ elixirOrm: "elixirOrm",
3911
+ elixirAuth: "elixirAuth",
3912
+ elixirApi: "elixirApi",
3913
+ elixirRealtime: "elixirRealtime",
3914
+ elixirJobs: "elixirJobs",
3915
+ elixirValidation: "elixirValidation",
3916
+ elixirHttp: "elixirHttp",
3917
+ elixirJson: "elixirJson",
3918
+ elixirEmail: "elixirEmail",
3919
+ elixirCaching: "elixirCaching",
3920
+ elixirObservability: "elixirObservability",
3921
+ elixirTesting: "elixirTesting",
3922
+ elixirQuality: "elixirQuality",
3923
+ elixirDeploy: "elixirDeploy"
3112
3924
  };
3113
3925
  const VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS = [
3114
3926
  "rustLibraries",
@@ -3139,6 +3951,13 @@ const STACK_SELECTION_URL_KEYS = {
3139
3951
  observability: "obs",
3140
3952
  featureFlags: "ff",
3141
3953
  analytics: "an",
3954
+ mobileNavigation: "mn",
3955
+ mobileUI: "mui",
3956
+ mobileStorage: "mst",
3957
+ mobileTesting: "mte",
3958
+ mobilePush: "mpu",
3959
+ mobileOTA: "mota",
3960
+ mobileDeepLinking: "mdl",
3142
3961
  backendLibraries: "bl",
3143
3962
  stateManagement: "sm",
3144
3963
  forms: "frm",
@@ -3190,6 +4009,7 @@ const STACK_SELECTION_URL_KEYS = {
3190
4009
  pythonValidation: "pval",
3191
4010
  pythonAi: "pai",
3192
4011
  pythonAuth: "pauth",
4012
+ pythonApi: "papi",
3193
4013
  pythonTaskQueue: "ptq",
3194
4014
  pythonGraphql: "pgql",
3195
4015
  pythonQuality: "pq",
@@ -3204,7 +4024,22 @@ const STACK_SELECTION_URL_KEYS = {
3204
4024
  javaOrm: "jorm",
3205
4025
  javaAuth: "jauth",
3206
4026
  javaLibraries: "jlib",
3207
- javaTestingLibraries: "jtest"
4027
+ javaTestingLibraries: "jtest",
4028
+ elixirWebFramework: "ewf",
4029
+ elixirOrm: "eorm",
4030
+ elixirAuth: "eauth",
4031
+ elixirApi: "eapi",
4032
+ elixirRealtime: "ert",
4033
+ elixirJobs: "ejob",
4034
+ elixirValidation: "eval",
4035
+ elixirHttp: "ehttp",
4036
+ elixirJson: "ejson",
4037
+ elixirEmail: "emailx",
4038
+ elixirCaching: "ecache",
4039
+ elixirObservability: "eobs",
4040
+ elixirTesting: "etest",
4041
+ elixirQuality: "eq",
4042
+ elixirDeploy: "edeploy"
3208
4043
  };
3209
4044
  const STACK_SELECTION_KEYS = Object.keys(STACK_SELECTION_URL_KEYS);
3210
4045
  const stackSelectionArrayKeySet = new Set(STACK_SELECTION_KEYS.filter((key) => Array.isArray(DEFAULT_STACK_SELECTION[key])));
@@ -3326,6 +4161,13 @@ const CLI_SCALAR_CONFIG_FIELDS = [
3326
4161
  ["search", "search"],
3327
4162
  ["fileStorage", "fileStorage"],
3328
4163
  ["analytics", "analytics"],
4164
+ ["mobileNavigation", "mobileNavigation"],
4165
+ ["mobileUI", "mobileUI"],
4166
+ ["mobileStorage", "mobileStorage"],
4167
+ ["mobileTesting", "mobileTesting"],
4168
+ ["mobilePush", "mobilePush"],
4169
+ ["mobileOTA", "mobileOTA"],
4170
+ ["mobileDeepLinking", "mobileDeepLinking"],
3329
4171
  ["featureFlags", "featureFlags"],
3330
4172
  ["fileUpload", "fileUpload"],
3331
4173
  ["git", "git"],
@@ -3359,6 +4201,7 @@ const CLI_SCALAR_CONFIG_FIELDS = [
3359
4201
  ["pythonOrm", "pythonOrm"],
3360
4202
  ["pythonValidation", "pythonValidation"],
3361
4203
  ["pythonAuth", "pythonAuth"],
4204
+ ["pythonApi", "pythonApi"],
3362
4205
  ["pythonTaskQueue", "pythonTaskQueue"],
3363
4206
  ["pythonGraphql", "pythonGraphql"],
3364
4207
  ["pythonQuality", "pythonQuality"],
@@ -3371,7 +4214,22 @@ const CLI_SCALAR_CONFIG_FIELDS = [
3371
4214
  ["javaWebFramework", "javaWebFramework"],
3372
4215
  ["javaBuildTool", "javaBuildTool"],
3373
4216
  ["javaOrm", "javaOrm"],
3374
- ["javaAuth", "javaAuth"]
4217
+ ["javaAuth", "javaAuth"],
4218
+ ["elixirWebFramework", "elixirWebFramework"],
4219
+ ["elixirOrm", "elixirOrm"],
4220
+ ["elixirAuth", "elixirAuth"],
4221
+ ["elixirApi", "elixirApi"],
4222
+ ["elixirRealtime", "elixirRealtime"],
4223
+ ["elixirJobs", "elixirJobs"],
4224
+ ["elixirValidation", "elixirValidation"],
4225
+ ["elixirHttp", "elixirHttp"],
4226
+ ["elixirJson", "elixirJson"],
4227
+ ["elixirEmail", "elixirEmail"],
4228
+ ["elixirCaching", "elixirCaching"],
4229
+ ["elixirObservability", "elixirObservability"],
4230
+ ["elixirTesting", "elixirTesting"],
4231
+ ["elixirQuality", "elixirQuality"],
4232
+ ["elixirDeploy", "elixirDeploy"]
3375
4233
  ];
3376
4234
  const CLI_NON_EMPTY_ARRAY_CONFIG_FIELDS = [
3377
4235
  ["frontend", "frontend"],
@@ -3397,7 +4255,8 @@ const SELF_BACKENDS = new Set([
3397
4255
  "self-astro",
3398
4256
  "self-nuxt",
3399
4257
  "self-svelte",
3400
- "self-solid-start"
4258
+ "self-solid-start",
4259
+ "self-vinext"
3401
4260
  ]);
3402
4261
  const RUST_CONFIG_KEYS = [
3403
4262
  "rustWebFramework",
@@ -3417,6 +4276,7 @@ const PYTHON_CONFIG_KEYS = [
3417
4276
  "pythonValidation",
3418
4277
  "pythonAi",
3419
4278
  "pythonAuth",
4279
+ "pythonApi",
3420
4280
  "pythonTaskQueue",
3421
4281
  "pythonGraphql",
3422
4282
  "pythonQuality"
@@ -3437,6 +4297,32 @@ const JAVA_CONFIG_KEYS = [
3437
4297
  "javaLibraries",
3438
4298
  "javaTestingLibraries"
3439
4299
  ];
4300
+ const ELIXIR_CONFIG_KEYS = [
4301
+ "elixirWebFramework",
4302
+ "elixirOrm",
4303
+ "elixirAuth",
4304
+ "elixirApi",
4305
+ "elixirRealtime",
4306
+ "elixirJobs",
4307
+ "elixirValidation",
4308
+ "elixirHttp",
4309
+ "elixirJson",
4310
+ "elixirEmail",
4311
+ "elixirCaching",
4312
+ "elixirObservability",
4313
+ "elixirTesting",
4314
+ "elixirQuality",
4315
+ "elixirDeploy"
4316
+ ];
4317
+ const REACT_NATIVE_CONFIG_KEYS = [
4318
+ "mobileNavigation",
4319
+ "mobileUI",
4320
+ "mobileStorage",
4321
+ "mobileTesting",
4322
+ "mobilePush",
4323
+ "mobileOTA",
4324
+ "mobileDeepLinking"
4325
+ ];
3440
4326
  const COMMAND_ADDONS = new Set([
3441
4327
  "pwa",
3442
4328
  "tauri",
@@ -3583,6 +4469,13 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
3583
4469
  observability: stack.observability,
3584
4470
  featureFlags: stack.featureFlags,
3585
4471
  analytics: stack.analytics,
4472
+ mobileNavigation: stack.mobileNavigation,
4473
+ mobileUI: stack.mobileUI,
4474
+ mobileStorage: stack.mobileStorage,
4475
+ mobileTesting: stack.mobileTesting,
4476
+ mobilePush: stack.mobilePush,
4477
+ mobileOTA: stack.mobileOTA,
4478
+ mobileDeepLinking: stack.mobileDeepLinking,
3586
4479
  cms: stack.cms,
3587
4480
  caching: stack.caching,
3588
4481
  i18n: stack.i18n,
@@ -3603,6 +4496,7 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
3603
4496
  pythonValidation: stack.pythonValidation,
3604
4497
  pythonAi: toUniqueNonNoneArray(stack.pythonAi),
3605
4498
  pythonAuth: stack.pythonAuth,
4499
+ pythonApi: stack.pythonApi,
3606
4500
  pythonTaskQueue: stack.pythonTaskQueue,
3607
4501
  pythonGraphql: stack.pythonGraphql,
3608
4502
  pythonQuality: stack.pythonQuality,
@@ -3618,6 +4512,21 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
3618
4512
  javaAuth: stack.javaAuth,
3619
4513
  javaLibraries: toUniqueNonNoneArray(stack.javaLibraries),
3620
4514
  javaTestingLibraries: toUniqueNonNoneArray(stack.javaTestingLibraries),
4515
+ elixirWebFramework: stack.elixirWebFramework,
4516
+ elixirOrm: stack.elixirOrm,
4517
+ elixirAuth: stack.elixirAuth,
4518
+ elixirApi: stack.elixirApi,
4519
+ elixirRealtime: stack.elixirRealtime,
4520
+ elixirJobs: stack.elixirJobs,
4521
+ elixirValidation: stack.elixirValidation,
4522
+ elixirHttp: stack.elixirHttp,
4523
+ elixirJson: stack.elixirJson,
4524
+ elixirEmail: stack.elixirEmail,
4525
+ elixirCaching: stack.elixirCaching,
4526
+ elixirObservability: stack.elixirObservability,
4527
+ elixirTesting: stack.elixirTesting,
4528
+ elixirQuality: stack.elixirQuality,
4529
+ elixirDeploy: stack.elixirDeploy,
3621
4530
  aiDocs: toUniqueNonNoneArray(stack.aiDocs)
3622
4531
  };
3623
4532
  }
@@ -3639,11 +4548,13 @@ function isCliDefaultStackSelection(selection, projectName = getProjectName(sele
3639
4548
  projectName,
3640
4549
  relativePath: projectName
3641
4550
  };
3642
- const ignoredKeys = selection.ecosystem === "typescript" ? new Set([
4551
+ const ignoredKeys = selection.ecosystem === "typescript" || selection.ecosystem === "react-native" ? new Set([
3643
4552
  ...RUST_CONFIG_KEYS,
3644
4553
  ...PYTHON_CONFIG_KEYS,
3645
4554
  ...GO_CONFIG_KEYS,
3646
- ...JAVA_CONFIG_KEYS
4555
+ ...JAVA_CONFIG_KEYS,
4556
+ ...ELIXIR_CONFIG_KEYS,
4557
+ ...selection.ecosystem === "typescript" ? REACT_NATIVE_CONFIG_KEYS : []
3647
4558
  ]) : /* @__PURE__ */ new Set();
3648
4559
  return Object.keys(cliDefaults).every((key) => {
3649
4560
  if (ignoredKeys.has(key)) return true;
@@ -3684,6 +4595,7 @@ function generateTypeScriptCommand(selection, projectName) {
3684
4595
  `--file-upload ${selection.fileUpload}`,
3685
4596
  `--logging ${selection.logging}`,
3686
4597
  `--observability ${selection.observability}`,
4598
+ `--feature-flags ${selection.featureFlags}`,
3687
4599
  `--realtime ${selection.realtime}`,
3688
4600
  `--job-queue ${selection.jobQueue}`,
3689
4601
  `--caching ${selection.caching}`,
@@ -3714,6 +4626,26 @@ function generateTypeScriptCommand(selection, projectName) {
3714
4626
  if (selection.yolo === "true") flags.push("--yolo");
3715
4627
  return `${base} ${projectName} ${flags.join(" ")}`;
3716
4628
  }
4629
+ function generateReactNativeCommand(selection, projectName) {
4630
+ const flags = [
4631
+ "--ecosystem react-native",
4632
+ `--frontend ${selection.nativeFrontend.filter((value, _, values) => value !== "none" || values.length === 1).join(" ") || "native-bare"}`,
4633
+ `--auth ${selection.auth}`,
4634
+ `--mobile-navigation ${selection.mobileNavigation}`,
4635
+ `--mobile-ui ${selection.mobileUI}`,
4636
+ `--mobile-storage ${selection.mobileStorage}`,
4637
+ `--mobile-testing ${selection.mobileTesting}`,
4638
+ `--mobile-push ${selection.mobilePush}`,
4639
+ `--mobile-ota ${selection.mobileOTA}`,
4640
+ `--mobile-deep-linking ${selection.mobileDeepLinking}`,
4641
+ `--package-manager ${selection.packageManager}`,
4642
+ selection.git === "false" ? "--no-git" : "--git",
4643
+ selection.install === "false" ? "--no-install" : "--install",
4644
+ formatArrayFlag("ai-docs", selection.aiDocs)
4645
+ ];
4646
+ if (selection.yolo === "true") flags.push("--yolo");
4647
+ return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
4648
+ }
3717
4649
  function generateRustCommand(selection, projectName) {
3718
4650
  const flags = [
3719
4651
  "--ecosystem rust",
@@ -3727,6 +4659,10 @@ function generateRustCommand(selection, projectName) {
3727
4659
  `--rust-error-handling ${selection.rustErrorHandling}`,
3728
4660
  `--rust-caching ${selection.rustCaching}`,
3729
4661
  `--rust-auth ${selection.rustAuth}`,
4662
+ `--email ${selection.email}`,
4663
+ `--observability ${selection.observability}`,
4664
+ `--caching ${selection.caching}`,
4665
+ `--search ${selection.search}`,
3730
4666
  formatArrayFlag("ai-docs", selection.aiDocs)
3731
4667
  ];
3732
4668
  if (selection.git === "false") flags.push("--no-git");
@@ -3741,9 +4677,14 @@ function generatePythonCommand(selection, projectName) {
3741
4677
  `--python-validation ${selection.pythonValidation}`,
3742
4678
  formatArrayFlag("python-ai", selection.pythonAi),
3743
4679
  `--python-auth ${selection.pythonAuth}`,
4680
+ `--python-api ${selection.pythonApi}`,
3744
4681
  `--python-task-queue ${selection.pythonTaskQueue}`,
3745
4682
  `--python-graphql ${selection.pythonGraphql}`,
3746
4683
  `--python-quality ${selection.pythonQuality}`,
4684
+ `--email ${selection.email}`,
4685
+ `--observability ${selection.observability}`,
4686
+ `--caching ${selection.caching}`,
4687
+ `--search ${selection.search}`,
3747
4688
  formatArrayFlag("ai-docs", selection.aiDocs)
3748
4689
  ];
3749
4690
  if (selection.git === "false") flags.push("--no-git");
@@ -3760,6 +4701,10 @@ function generateGoCommand(selection, projectName) {
3760
4701
  `--go-logging ${selection.goLogging}`,
3761
4702
  `--go-auth ${selection.goAuth}`,
3762
4703
  `--auth ${selection.auth}`,
4704
+ `--email ${selection.email}`,
4705
+ `--observability ${selection.observability}`,
4706
+ `--caching ${selection.caching}`,
4707
+ `--search ${selection.search}`,
3763
4708
  formatArrayFlag("ai-docs", selection.aiDocs)
3764
4709
  ];
3765
4710
  if (selection.git === "false") flags.push("--no-git");
@@ -3775,6 +4720,34 @@ function generateJavaCommand(selection, projectName) {
3775
4720
  `--java-auth ${selection.javaAuth}`,
3776
4721
  formatArrayFlag("java-libraries", selection.javaLibraries),
3777
4722
  formatArrayFlag("java-testing-libraries", selection.javaTestingLibraries),
4723
+ `--email ${selection.email}`,
4724
+ `--observability ${selection.observability}`,
4725
+ `--caching ${selection.caching}`,
4726
+ `--search ${selection.search}`,
4727
+ formatArrayFlag("ai-docs", selection.aiDocs)
4728
+ ];
4729
+ if (selection.git === "false") flags.push("--no-git");
4730
+ if (selection.install === "false") flags.push("--no-install");
4731
+ return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
4732
+ }
4733
+ function generateElixirCommand(selection, projectName) {
4734
+ const flags = [
4735
+ "--ecosystem elixir",
4736
+ `--elixir-web-framework ${selection.elixirWebFramework}`,
4737
+ `--elixir-orm ${selection.elixirOrm}`,
4738
+ `--elixir-auth ${selection.elixirAuth}`,
4739
+ `--elixir-api ${selection.elixirApi}`,
4740
+ `--elixir-realtime ${selection.elixirRealtime}`,
4741
+ `--elixir-jobs ${selection.elixirJobs}`,
4742
+ `--elixir-validation ${selection.elixirValidation}`,
4743
+ `--elixir-http ${selection.elixirHttp}`,
4744
+ `--elixir-json ${selection.elixirJson}`,
4745
+ `--elixir-email ${selection.elixirEmail}`,
4746
+ `--elixir-caching ${selection.elixirCaching}`,
4747
+ `--elixir-observability ${selection.elixirObservability}`,
4748
+ `--elixir-testing ${selection.elixirTesting}`,
4749
+ `--elixir-quality ${selection.elixirQuality}`,
4750
+ `--elixir-deploy ${selection.elixirDeploy}`,
3778
4751
  formatArrayFlag("ai-docs", selection.aiDocs)
3779
4752
  ];
3780
4753
  if (selection.git === "false") flags.push("--no-git");
@@ -3784,10 +4757,12 @@ function generateJavaCommand(selection, projectName) {
3784
4757
  function generateStackSelectionCommand(selection) {
3785
4758
  const projectName = getProjectName(selection);
3786
4759
  switch (selection.ecosystem) {
4760
+ case "react-native": return generateReactNativeCommand(selection, projectName);
3787
4761
  case "rust": return generateRustCommand(selection, projectName);
3788
4762
  case "python": return generatePythonCommand(selection, projectName);
3789
4763
  case "go": return generateGoCommand(selection, projectName);
3790
4764
  case "java": return generateJavaCommand(selection, projectName);
4765
+ case "elixir": return generateElixirCommand(selection, projectName);
3791
4766
  case "typescript":
3792
4767
  default: return generateTypeScriptCommand(selection, projectName);
3793
4768
  }
@@ -3795,4 +4770,4 @@ function generateStackSelectionCommand(selection) {
3795
4770
 
3796
4771
  //#endregion
3797
4772
  export { getCapabilityDefinitions as $, evaluateCompatibility as A, hasPWACompatibleFrontend as B, getCategoryCliValues as C, normalizeOptionId as D, isMultiSelectCategory as E, getCompatibleCSSFrameworks as F, isFrontendAllowedWithBackend as G, hasWebStyling as H, getCompatibleFormLibraries as I, requiresChatSdkVercelAI as J, isOptionCompatible as K, getCompatibleUILibraries as L, getApiFrontendCompatibilityIssue as M, getCategoryDisplayName as N, allowedApisForFrontends as O, getCompatibleAddons as P, validateProjectName as Q, getDisabledReason as R, OPTION_CATEGORY_METADATA as S, getOptionMetadata as T, isExampleAIAllowed as U, hasTauriCompatibleFrontend as V, isExampleChatSdkAllowed as W, splitFrontends as X, requiresChatSdkVercelAIForSelection as Y, validateAddonCompatibility as Z, parseStackSelectionFromUrlRecord as _, STACK_SELECTION_URL_KEYS as a, stackSelectionToProjectConfig as b, cloneDefaultStackSelection as c, isArrayStackSelectionKey as d, getCapabilityDisabledReason as et, isCliDefaultStackSelection as f, parseStackSelectionFromSearch as g, normalizeStackSelectionValue as h, STACK_SELECTION_OPTION_CATEGORY_BY_KEY as i, getAIFrontendCompatibilityIssue as j, analyzeStackCompatibility as k, createStackSelectionSearchParams as l, normalizeStackSelection as m, NON_OPTION_STACK_SELECTION_KEYS as n, normalizeCapabilitySelection as nt, VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS as o, isStackSelectionDefault as p, isWebFrontend as q, STACK_SELECTION_KEYS as r, cliInputToProjectConfigPartial as s, DEFAULT_STACK_SELECTION as t, getSupportedCapabilityOptions as tt, generateStackSelectionCommand as u, processCliArrayOption as v, getCategoryOptionIds as w, usesVirtualNoneStackSelection as x, stackSelectionToCliComparableConfig as y, hasDockerComposeCompatibleFrontend as z };
3798
- //# sourceMappingURL=stack-translation-CUd4T2bV.mjs.map
4773
+ //# sourceMappingURL=stack-translation-_uOX-Io0.mjs.map