@better-fullstack/types 1.7.1 → 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-Ra4H-o6R.d.mts → defaults-CFAJhN--.d.mts} +2 -2
  2. package/dist/defaults-CFAJhN--.d.mts.map +1 -0
  3. package/dist/{defaults-DtBqH42_.mjs → defaults-D23vxGYl.mjs} +23 -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 +2938 -316
  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-B2DBDBdl.mjs → schemas-BHCZL3uR.mjs} +195 -4
  14. package/dist/schemas-BHCZL3uR.mjs.map +1 -0
  15. package/dist/{schemas-CC-_Vkoh.d.mts → schemas-Bs_n2xLj.d.mts} +2405 -45
  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-Bag2NJRD.mjs → stack-translation-_uOX-Io0.mjs} +848 -21
  20. package/dist/stack-translation-_uOX-Io0.mjs.map +1 -0
  21. package/dist/{stack-translation-B8OgQLwv.d.mts → stack-translation-xj8JvbAI.d.mts} +50 -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-DtBqH42_.mjs.map +0 -1
  30. package/dist/defaults-Ra4H-o6R.d.mts.map +0 -1
  31. package/dist/schemas-B2DBDBdl.mjs.map +0 -1
  32. package/dist/schemas-CC-_Vkoh.d.mts.map +0 -1
  33. package/dist/stack-translation-B8OgQLwv.d.mts.map +0 -1
  34. package/dist/stack-translation-Bag2NJRD.mjs.map +0 -1
  35. package/dist/types-Cd8oAhRY.d.mts +0 -96
  36. package/dist/types-Cd8oAhRY.d.mts.map +0 -1
@@ -1,5 +1,5 @@
1
- import { A as DATABASE_SETUP_VALUES, An as SERVER_DEPLOY_VALUES, Bt as PYTHON_GRAPHQL_VALUES, D as CSS_FRAMEWORK_VALUES, Fn as SHADCN_ICON_LIBRARY_VALUES, Ft as PACKAGE_MANAGER_VALUES, G as FILE_STORAGE_VALUES, Gt as PYTHON_WEB_FRAMEWORK_VALUES, Ht as PYTHON_QUALITY_VALUES, In as SHADCN_RADIUS_VALUES, It as PAYMENTS_VALUES, K as FILE_UPLOAD_VALUES, L as EFFECT_VALUES, Ln as SHADCN_STYLE_VALUES, Lt as PYTHON_AI_VALUES, Mn as SHADCN_BASE_VALUES, Nn as SHADCN_COLOR_THEME_VALUES, Nt as ORM_VALUES, Pn as SHADCN_FONT_VALUES, R as EMAIL_VALUES, Rn as STATE_MANAGEMENT_VALUES, Rt as PYTHON_API_VALUES, S as CACHING_VALUES, T as CMS_VALUES, Ut as PYTHON_TASK_QUEUE_VALUES, Vt as PYTHON_ORM_VALUES, W as FEATURE_FLAGS_VALUES, Wt as PYTHON_VALIDATION_VALUES, Xn as TESTING_VALUES, _t as JAVA_LIBRARIES_VALUES, a as ANALYTICS_VALUES, an as REALTIME_VALUES, ar as WEB_DEPLOY_VALUES, at as GO_WEB_FRAMEWORK_VALUES, bt as JAVA_WEB_FRAMEWORK_VALUES, c as API_VALUES, cn as RUST_AUTH_VALUES, dn as RUST_ERROR_HANDLING_VALUES, er as UI_LIBRARY_VALUES, et as GO_API_VALUES, fn as RUST_FRONTEND_VALUES, ft as I18N_VALUES, gn as RUST_WEB_FRAMEWORK_VALUES, gt as JAVA_BUILD_TOOL_VALUES, hn as RUST_ORM_VALUES, ht as JAVA_AUTH_VALUES, i as AI_VALUES, it as GO_ORM_VALUES, j as DATABASE_VALUES, jn as SHADCN_BASE_COLOR_VALUES, jt as OBSERVABILITY_VALUES, kn as SEARCH_VALUES, kt as LOGGING_VALUES, l as ASTRO_INTEGRATION_VALUES, ln as RUST_CACHING_VALUES, mn as RUST_LOGGING_VALUES, nr as VERSION_CHANNEL_VALUES, nt as GO_CLI_VALUES, o as ANIMATION_VALUES, on as RUNTIME_VALUES, pn as RUST_LIBRARIES_VALUES, q as FORMS_VALUES, r as AI_DOCS_VALUES, rt as GO_LOGGING_VALUES, sn as RUST_API_VALUES, tr as VALIDATION_VALUES, tt as GO_AUTH_VALUES, u as AUTH_VALUES, un as RUST_CLI_VALUES, vt as JAVA_ORM_VALUES, xt as JOB_QUEUE_VALUES, yt as JAVA_TESTING_LIBRARIES_VALUES, zt as PYTHON_AUTH_VALUES } from "./schemas-B2DBDBdl.mjs";
2
- import { t as createCliDefaultProjectConfigBase } from "./defaults-DtBqH42_.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",
@@ -269,7 +276,22 @@ const CATEGORY_ORDER = [
269
276
  "javaOrm",
270
277
  "javaAuth",
271
278
  "javaLibraries",
272
- "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"
273
295
  ];
274
296
  const DEFAULT_RUNTIME = "bun";
275
297
  function validateProjectName(name) {
@@ -298,6 +320,7 @@ const hasPWACompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
298
320
  "react-vite",
299
321
  "solid",
300
322
  "next",
323
+ "vinext",
301
324
  "astro"
302
325
  ].includes(f));
303
326
  const hasTauriCompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
@@ -308,6 +331,7 @@ const hasTauriCompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
308
331
  "svelte",
309
332
  "solid",
310
333
  "next",
334
+ "vinext",
311
335
  "astro"
312
336
  ].includes(f));
313
337
  const hasDockerComposeCompatibleFrontend = (webFrontend) => webFrontend.some((f) => [
@@ -316,11 +340,12 @@ const hasDockerComposeCompatibleFrontend = (webFrontend) => webFrontend.some((f)
316
340
  "react-vite",
317
341
  "solid",
318
342
  "next",
343
+ "vinext",
319
344
  "astro"
320
345
  ].includes(f));
321
346
  const isChatSdkExampleSupported = (stack) => {
322
347
  if (stack.ecosystem !== "typescript") return false;
323
- 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;
324
349
  if (stack.backend === "self-nuxt") return true;
325
350
  if (stack.backend === "hono") return stack.runtime === "node";
326
351
  return false;
@@ -368,11 +393,38 @@ const getCategoryDisplayName = (categoryKey) => {
368
393
  javaLibraries: "Java Libraries",
369
394
  javaTestingLibraries: "Java Testing Libraries"
370
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
+ };
371
413
  if (rustCategoryNames[categoryKey]) return rustCategoryNames[categoryKey];
372
414
  if (pythonCategoryNames[categoryKey]) return pythonCategoryNames[categoryKey];
373
415
  if (goCategoryNames[categoryKey]) return goCategoryNames[categoryKey];
374
416
  if (javaCategoryNames[categoryKey]) return javaCategoryNames[categoryKey];
375
- 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
+ };
376
428
  if (tsCategoryNames[categoryKey]) return tsCategoryNames[categoryKey];
377
429
  const result = categoryKey.replace(/([A-Z])/g, " $1");
378
430
  return result.charAt(0).toUpperCase() + result.slice(1);
@@ -494,7 +546,7 @@ const analyzeStackCompatibility = (stack) => {
494
546
  });
495
547
  }
496
548
  }
497
- 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") {
498
550
  if (nextStack.runtime !== "none") {
499
551
  nextStack.runtime = "none";
500
552
  changed = true;
@@ -519,6 +571,14 @@ const analyzeStackCompatibility = (stack) => {
519
571
  message: "Frontend set to 'Next.js' (required for Next.js fullstack)"
520
572
  });
521
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
+ }
522
582
  if (nextStack.backend === "self-tanstack-start" && !nextStack.webFrontend.includes("tanstack-start")) {
523
583
  nextStack.webFrontend = ["tanstack-start"];
524
584
  changed = true;
@@ -587,7 +647,7 @@ const analyzeStackCompatibility = (stack) => {
587
647
  message: "Database changed to SQLite with D1 (Better-Fullstack doesn't support MongoDB with Workers)"
588
648
  });
589
649
  }
590
- 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") {
591
651
  nextStack.runtime = DEFAULT_RUNTIME;
592
652
  changed = true;
593
653
  changes.push({
@@ -893,6 +953,269 @@ const analyzeStackCompatibility = (stack) => {
893
953
  });
894
954
  }
895
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
+ }
896
1219
  if ([
897
1220
  "shadcn-ui",
898
1221
  "daisyui",
@@ -918,7 +1241,8 @@ const analyzeStackCompatibility = (stack) => {
918
1241
  "react-router",
919
1242
  "react-vite",
920
1243
  "tanstack-start",
921
- "next"
1244
+ "next",
1245
+ "vinext"
922
1246
  ];
923
1247
  if (reactOnlyLibraries.includes(nextStack.uiLibrary)) {
924
1248
  const hasReactFrontend = nextStack.webFrontend.some((f) => reactFrontends.includes(f));
@@ -1137,6 +1461,66 @@ const analyzeStackCompatibility = (stack) => {
1137
1461
  }
1138
1462
  }
1139
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
+ }
1140
1524
  if (nextStack.webDeploy !== "none" && !nextStack.webFrontend.some((f) => f !== "none")) {
1141
1525
  nextStack.webDeploy = "none";
1142
1526
  changed = true;
@@ -1159,6 +1543,7 @@ const analyzeStackCompatibility = (stack) => {
1159
1543
  "none",
1160
1544
  "convex",
1161
1545
  "self-next",
1546
+ "self-vinext",
1162
1547
  "self-tanstack-start",
1163
1548
  "self-astro",
1164
1549
  "self-nuxt",
@@ -1210,6 +1595,23 @@ const getDisabledReason = (currentStack, category, optionId) => {
1210
1595
  ].includes(f))})`;
1211
1596
  }
1212
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
+ }
1213
1615
  if (currentStack.backend === "none") {
1214
1616
  if (category === "runtime" && optionId !== "none") return "No backend selected";
1215
1617
  if (category === "database" && optionId !== "none") return "No backend selected";
@@ -1227,6 +1629,11 @@ const getDisabledReason = (currentStack, category, optionId) => {
1227
1629
  if (category === "webFrontend" && optionId !== "next" && optionId !== "none") return "Next.js fullstack requires Next.js frontend";
1228
1630
  if (category === "serverDeploy" && optionId !== "none") return "Fullstack uses frontend deployment";
1229
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
+ }
1230
1637
  if (currentStack.backend === "self-tanstack-start") {
1231
1638
  if (category === "runtime" && optionId !== "none") return "TanStack Start fullstack uses built-in API routes";
1232
1639
  if (category === "webFrontend" && optionId !== "tanstack-start" && optionId !== "none") return "TanStack Start fullstack requires TanStack Start frontend";
@@ -1254,6 +1661,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1254
1661
  }
1255
1662
  if (category === "backend") {
1256
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";
1257
1665
  if (optionId === "self-tanstack-start" && !currentStack.webFrontend.includes("tanstack-start")) return "Requires TanStack Start frontend";
1258
1666
  if (optionId === "self-astro" && !currentStack.webFrontend.includes("astro")) return "Requires Astro frontend";
1259
1667
  if (optionId === "self-nuxt" && !currentStack.webFrontend.includes("nuxt")) return "Requires Nuxt frontend";
@@ -1271,6 +1679,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1271
1679
  "convex",
1272
1680
  "none",
1273
1681
  "self-next",
1682
+ "self-vinext",
1274
1683
  "self-tanstack-start",
1275
1684
  "self-astro",
1276
1685
  "self-nuxt",
@@ -1384,7 +1793,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1384
1793
  if (!currentStack.webFrontend.some((f) => compatibleFrontends.includes(f))) return "TanStack AI requires React or Solid frontend (no Vue/Svelte/Angular adapter yet)";
1385
1794
  }
1386
1795
  if (category === "appPlatforms") {
1387
- 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";
1388
1797
  if (optionId === "tauri" && !hasTauriCompatibleFrontend(currentStack.webFrontend)) return "Tauri requires TanStack Router, React Router, Nuxt, Svelte, Solid, Next.js, or Astro";
1389
1798
  if (optionId === "docker-compose") {
1390
1799
  if (currentStack.backend === "convex") return "Docker Compose is not compatible with Convex backend (managed service)";
@@ -1416,7 +1825,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
1416
1825
  if (currentStack.ecosystem !== "typescript") return "Chat SDK example is currently available only for TypeScript stacks";
1417
1826
  if (currentStack.backend === "convex") return "Chat SDK example is not supported with Convex backend in v1";
1418
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";
1419
- 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;
1420
1829
  if (currentStack.backend === "self-nuxt") return null;
1421
1830
  if (currentStack.backend === "hono") {
1422
1831
  if (currentStack.runtime !== "node") return "Chat SDK Hono profile requires Node runtime in v1";
@@ -1444,6 +1853,24 @@ const getDisabledReason = (currentStack, category, optionId) => {
1444
1853
  "nextui"
1445
1854
  ].includes(currentStack.uiLibrary) && optionId !== "tailwind") return `${currentStack.uiLibrary === "shadcn-ui" ? "shadcn/ui" : currentStack.uiLibrary === "daisyui" ? "daisyUI" : "NextUI"} requires Tailwind CSS`;
1446
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
+ }
1447
1874
  if (category === "uiLibrary") {
1448
1875
  if (!currentStack.webFrontend.some((f) => f !== "none")) {
1449
1876
  if (optionId !== "none") return "UI library requires a web frontend";
@@ -1562,6 +1989,62 @@ const getDisabledReason = (currentStack, category, optionId) => {
1562
1989
  if (category === "javaTestingLibraries") {
1563
1990
  if (optionId !== "none" && currentStack.javaBuildTool === "none") return "Java testing libraries require Maven or Gradle";
1564
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";
1565
2048
  return null;
1566
2049
  };
1567
2050
  const isOptionCompatible = (currentStack, category, optionId) => {
@@ -1574,6 +2057,7 @@ const WEB_FRAMEWORKS = [
1574
2057
  "react-vite",
1575
2058
  "tanstack-start",
1576
2059
  "next",
2060
+ "vinext",
1577
2061
  "nuxt",
1578
2062
  "svelte",
1579
2063
  "solid",
@@ -1593,6 +2077,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1593
2077
  "react-vite",
1594
2078
  "tanstack-start",
1595
2079
  "next",
2080
+ "vinext",
1596
2081
  "astro"
1597
2082
  ],
1598
2083
  cssFrameworks: ["tailwind"]
@@ -1604,6 +2089,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1604
2089
  "react-vite",
1605
2090
  "tanstack-start",
1606
2091
  "next",
2092
+ "vinext",
1607
2093
  "nuxt",
1608
2094
  "svelte",
1609
2095
  "solid",
@@ -1623,6 +2109,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1623
2109
  "react-vite",
1624
2110
  "tanstack-start",
1625
2111
  "next",
2112
+ "vinext",
1626
2113
  "astro"
1627
2114
  ],
1628
2115
  cssFrameworks: [
@@ -1640,6 +2127,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1640
2127
  "react-vite",
1641
2128
  "tanstack-start",
1642
2129
  "next",
2130
+ "vinext",
1643
2131
  "nuxt",
1644
2132
  "astro"
1645
2133
  ],
@@ -1658,6 +2146,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1658
2146
  "react-vite",
1659
2147
  "tanstack-start",
1660
2148
  "next",
2149
+ "vinext",
1661
2150
  "nuxt",
1662
2151
  "solid",
1663
2152
  "solid-start",
@@ -1677,6 +2166,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1677
2166
  "react-vite",
1678
2167
  "tanstack-start",
1679
2168
  "next",
2169
+ "vinext",
1680
2170
  "astro"
1681
2171
  ],
1682
2172
  cssFrameworks: [
@@ -1694,6 +2184,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1694
2184
  "react-vite",
1695
2185
  "tanstack-start",
1696
2186
  "next",
2187
+ "vinext",
1697
2188
  "astro"
1698
2189
  ],
1699
2190
  cssFrameworks: ["tailwind"]
@@ -1705,6 +2196,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1705
2196
  "react-vite",
1706
2197
  "tanstack-start",
1707
2198
  "next",
2199
+ "vinext",
1708
2200
  "astro"
1709
2201
  ],
1710
2202
  cssFrameworks: [
@@ -1756,6 +2248,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1756
2248
  "react-vite",
1757
2249
  "tanstack-start",
1758
2250
  "next",
2251
+ "vinext",
1759
2252
  "astro"
1760
2253
  ],
1761
2254
  cssFrameworks: [
@@ -1772,6 +2265,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1772
2265
  "react-router",
1773
2266
  "tanstack-start",
1774
2267
  "next",
2268
+ "vinext",
1775
2269
  "nuxt",
1776
2270
  "svelte",
1777
2271
  "solid",
@@ -1793,6 +2287,7 @@ const UI_LIBRARY_COMPATIBILITY = {
1793
2287
  "react-vite",
1794
2288
  "tanstack-start",
1795
2289
  "next",
2290
+ "vinext",
1796
2291
  "astro"
1797
2292
  ],
1798
2293
  cssFrameworks: [
@@ -1821,6 +2316,7 @@ const ADDON_COMPATIBILITY = {
1821
2316
  "react-vite",
1822
2317
  "solid",
1823
2318
  "next",
2319
+ "vinext",
1824
2320
  "astro",
1825
2321
  "qwik",
1826
2322
  "angular",
@@ -2251,7 +2747,22 @@ function evaluateCompatibility(input) {
2251
2747
  ["javaWebFramework", input.javaWebFramework],
2252
2748
  ["javaBuildTool", input.javaBuildTool],
2253
2749
  ["javaOrm", input.javaOrm],
2254
- ["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]
2255
2766
  ];
2256
2767
  for (const [category, optionId] of scalarChecks) {
2257
2768
  const reason = getDisabledReason(input, category, optionId);
@@ -2326,6 +2837,7 @@ const WEB_FRONTEND_VALUES = [
2326
2837
  "react-vite",
2327
2838
  "tanstack-start",
2328
2839
  "next",
2840
+ "vinext",
2329
2841
  "nuxt",
2330
2842
  "svelte",
2331
2843
  "solid",
@@ -2355,6 +2867,7 @@ const BACKEND_BUILDER_VALUES = [
2355
2867
  "encore",
2356
2868
  "convex",
2357
2869
  "self-next",
2870
+ "self-vinext",
2358
2871
  "self-tanstack-start",
2359
2872
  "self-astro",
2360
2873
  "self-nuxt",
@@ -2438,6 +2951,13 @@ const CATEGORY_VALUE_IDS = {
2438
2951
  cms: CMS_VALUES,
2439
2952
  featureFlags: FEATURE_FLAGS_VALUES,
2440
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,
2441
2961
  codeQuality: CODE_QUALITY_VALUES,
2442
2962
  documentation: DOCUMENTATION_VALUES,
2443
2963
  appPlatforms: APP_PLATFORM_VALUES,
@@ -2486,7 +3006,22 @@ const CATEGORY_VALUE_IDS = {
2486
3006
  javaOrm: JAVA_ORM_VALUES,
2487
3007
  javaAuth: JAVA_AUTH_VALUES,
2488
3008
  javaLibraries: JAVA_LIBRARIES_VALUES,
2489
- 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
2490
3025
  };
2491
3026
  const EXACT_LABEL_OVERRIDES = {
2492
3027
  api: {
@@ -2496,6 +3031,7 @@ const EXACT_LABEL_OVERRIDES = {
2496
3031
  },
2497
3032
  webFrontend: {
2498
3033
  next: "Next.js",
3034
+ vinext: "Vinext",
2499
3035
  "react-vite": "React + Vite",
2500
3036
  svelte: "SvelteKit",
2501
3037
  redwood: "RedwoodJS"
@@ -2514,6 +3050,7 @@ const EXACT_LABEL_OVERRIDES = {
2514
3050
  nestjs: "NestJS",
2515
3051
  encore: "Encore.ts",
2516
3052
  "self-next": "Fullstack Next.js",
3053
+ "self-vinext": "Fullstack Vinext",
2517
3054
  "self-tanstack-start": "Fullstack TanStack Start",
2518
3055
  "self-astro": "Fullstack Astro",
2519
3056
  "self-nuxt": "Fullstack Nuxt",
@@ -2635,6 +3172,25 @@ const EXACT_LABEL_OVERRIDES = {
2635
3172
  plausible: "Plausible",
2636
3173
  umami: "Umami"
2637
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" },
2638
3194
  codeQuality: {
2639
3195
  biome: "Biome",
2640
3196
  oxlint: "Oxlint",
@@ -2897,6 +3453,69 @@ const EXACT_LABEL_OVERRIDES = {
2897
3453
  awaitility: "Awaitility",
2898
3454
  archunit: "ArchUnit",
2899
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"
2900
3519
  }
2901
3520
  };
2902
3521
  const OPTION_ALIASES = {
@@ -2905,6 +3524,7 @@ const OPTION_ALIASES = {
2905
3524
  };
2906
3525
  const CLI_VALUE_OVERRIDES = { backend: {
2907
3526
  "self-next": "self",
3527
+ "self-vinext": "self",
2908
3528
  "self-tanstack-start": "self",
2909
3529
  "self-astro": "self",
2910
3530
  "self-nuxt": "self",
@@ -2991,6 +3611,13 @@ const OPTION_CATEGORY_METADATA = {
2991
3611
  cms: buildCategoryMetadata("cms"),
2992
3612
  featureFlags: buildCategoryMetadata("featureFlags"),
2993
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"),
2994
3621
  codeQuality: buildCategoryMetadata("codeQuality"),
2995
3622
  documentation: buildCategoryMetadata("documentation"),
2996
3623
  appPlatforms: buildCategoryMetadata("appPlatforms"),
@@ -3039,7 +3666,22 @@ const OPTION_CATEGORY_METADATA = {
3039
3666
  javaOrm: buildCategoryMetadata("javaOrm"),
3040
3667
  javaAuth: buildCategoryMetadata("javaAuth"),
3041
3668
  javaLibraries: buildCategoryMetadata("javaLibraries"),
3042
- 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")
3043
3685
  };
3044
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])]))]));
3045
3687
  function isMultiSelectCategory(category) {
@@ -3079,6 +3721,13 @@ const DEFAULT_STACK_SELECTION = {
3079
3721
  observability: "none",
3080
3722
  featureFlags: "none",
3081
3723
  analytics: "none",
3724
+ mobileNavigation: "none",
3725
+ mobileUI: "none",
3726
+ mobileStorage: "none",
3727
+ mobileTesting: "none",
3728
+ mobilePush: "none",
3729
+ mobileOTA: "none",
3730
+ mobileDeepLinking: "none",
3082
3731
  backendLibraries: "none",
3083
3732
  stateManagement: "none",
3084
3733
  forms: "react-hook-form",
@@ -3145,7 +3794,22 @@ const DEFAULT_STACK_SELECTION = {
3145
3794
  javaOrm: "none",
3146
3795
  javaAuth: "none",
3147
3796
  javaLibraries: [],
3148
- 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"
3149
3813
  };
3150
3814
  const NON_OPTION_STACK_SELECTION_KEYS = [
3151
3815
  "ecosystem",
@@ -3169,6 +3833,13 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
3169
3833
  observability: "observability",
3170
3834
  featureFlags: "featureFlags",
3171
3835
  analytics: "analytics",
3836
+ mobileNavigation: "mobileNavigation",
3837
+ mobileUI: "mobileUI",
3838
+ mobileStorage: "mobileStorage",
3839
+ mobileTesting: "mobileTesting",
3840
+ mobilePush: "mobilePush",
3841
+ mobileOTA: "mobileOTA",
3842
+ mobileDeepLinking: "mobileDeepLinking",
3172
3843
  backendLibraries: "backendLibraries",
3173
3844
  stateManagement: "stateManagement",
3174
3845
  forms: "forms",
@@ -3234,7 +3905,22 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
3234
3905
  javaOrm: "javaOrm",
3235
3906
  javaAuth: "javaAuth",
3236
3907
  javaLibraries: "javaLibraries",
3237
- 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"
3238
3924
  };
3239
3925
  const VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS = [
3240
3926
  "rustLibraries",
@@ -3265,6 +3951,13 @@ const STACK_SELECTION_URL_KEYS = {
3265
3951
  observability: "obs",
3266
3952
  featureFlags: "ff",
3267
3953
  analytics: "an",
3954
+ mobileNavigation: "mn",
3955
+ mobileUI: "mui",
3956
+ mobileStorage: "mst",
3957
+ mobileTesting: "mte",
3958
+ mobilePush: "mpu",
3959
+ mobileOTA: "mota",
3960
+ mobileDeepLinking: "mdl",
3268
3961
  backendLibraries: "bl",
3269
3962
  stateManagement: "sm",
3270
3963
  forms: "frm",
@@ -3331,7 +4024,22 @@ const STACK_SELECTION_URL_KEYS = {
3331
4024
  javaOrm: "jorm",
3332
4025
  javaAuth: "jauth",
3333
4026
  javaLibraries: "jlib",
3334
- 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"
3335
4043
  };
3336
4044
  const STACK_SELECTION_KEYS = Object.keys(STACK_SELECTION_URL_KEYS);
3337
4045
  const stackSelectionArrayKeySet = new Set(STACK_SELECTION_KEYS.filter((key) => Array.isArray(DEFAULT_STACK_SELECTION[key])));
@@ -3453,6 +4161,13 @@ const CLI_SCALAR_CONFIG_FIELDS = [
3453
4161
  ["search", "search"],
3454
4162
  ["fileStorage", "fileStorage"],
3455
4163
  ["analytics", "analytics"],
4164
+ ["mobileNavigation", "mobileNavigation"],
4165
+ ["mobileUI", "mobileUI"],
4166
+ ["mobileStorage", "mobileStorage"],
4167
+ ["mobileTesting", "mobileTesting"],
4168
+ ["mobilePush", "mobilePush"],
4169
+ ["mobileOTA", "mobileOTA"],
4170
+ ["mobileDeepLinking", "mobileDeepLinking"],
3456
4171
  ["featureFlags", "featureFlags"],
3457
4172
  ["fileUpload", "fileUpload"],
3458
4173
  ["git", "git"],
@@ -3499,7 +4214,22 @@ const CLI_SCALAR_CONFIG_FIELDS = [
3499
4214
  ["javaWebFramework", "javaWebFramework"],
3500
4215
  ["javaBuildTool", "javaBuildTool"],
3501
4216
  ["javaOrm", "javaOrm"],
3502
- ["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"]
3503
4233
  ];
3504
4234
  const CLI_NON_EMPTY_ARRAY_CONFIG_FIELDS = [
3505
4235
  ["frontend", "frontend"],
@@ -3525,7 +4255,8 @@ const SELF_BACKENDS = new Set([
3525
4255
  "self-astro",
3526
4256
  "self-nuxt",
3527
4257
  "self-svelte",
3528
- "self-solid-start"
4258
+ "self-solid-start",
4259
+ "self-vinext"
3529
4260
  ]);
3530
4261
  const RUST_CONFIG_KEYS = [
3531
4262
  "rustWebFramework",
@@ -3566,6 +4297,32 @@ const JAVA_CONFIG_KEYS = [
3566
4297
  "javaLibraries",
3567
4298
  "javaTestingLibraries"
3568
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
+ ];
3569
4326
  const COMMAND_ADDONS = new Set([
3570
4327
  "pwa",
3571
4328
  "tauri",
@@ -3712,6 +4469,13 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
3712
4469
  observability: stack.observability,
3713
4470
  featureFlags: stack.featureFlags,
3714
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,
3715
4479
  cms: stack.cms,
3716
4480
  caching: stack.caching,
3717
4481
  i18n: stack.i18n,
@@ -3748,6 +4512,21 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
3748
4512
  javaAuth: stack.javaAuth,
3749
4513
  javaLibraries: toUniqueNonNoneArray(stack.javaLibraries),
3750
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,
3751
4530
  aiDocs: toUniqueNonNoneArray(stack.aiDocs)
3752
4531
  };
3753
4532
  }
@@ -3769,11 +4548,13 @@ function isCliDefaultStackSelection(selection, projectName = getProjectName(sele
3769
4548
  projectName,
3770
4549
  relativePath: projectName
3771
4550
  };
3772
- const ignoredKeys = selection.ecosystem === "typescript" ? new Set([
4551
+ const ignoredKeys = selection.ecosystem === "typescript" || selection.ecosystem === "react-native" ? new Set([
3773
4552
  ...RUST_CONFIG_KEYS,
3774
4553
  ...PYTHON_CONFIG_KEYS,
3775
4554
  ...GO_CONFIG_KEYS,
3776
- ...JAVA_CONFIG_KEYS
4555
+ ...JAVA_CONFIG_KEYS,
4556
+ ...ELIXIR_CONFIG_KEYS,
4557
+ ...selection.ecosystem === "typescript" ? REACT_NATIVE_CONFIG_KEYS : []
3777
4558
  ]) : /* @__PURE__ */ new Set();
3778
4559
  return Object.keys(cliDefaults).every((key) => {
3779
4560
  if (ignoredKeys.has(key)) return true;
@@ -3845,6 +4626,26 @@ function generateTypeScriptCommand(selection, projectName) {
3845
4626
  if (selection.yolo === "true") flags.push("--yolo");
3846
4627
  return `${base} ${projectName} ${flags.join(" ")}`;
3847
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
+ }
3848
4649
  function generateRustCommand(selection, projectName) {
3849
4650
  const flags = [
3850
4651
  "--ecosystem rust",
@@ -3929,13 +4730,39 @@ function generateJavaCommand(selection, projectName) {
3929
4730
  if (selection.install === "false") flags.push("--no-install");
3930
4731
  return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
3931
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}`,
4751
+ formatArrayFlag("ai-docs", selection.aiDocs)
4752
+ ];
4753
+ if (selection.git === "false") flags.push("--no-git");
4754
+ if (selection.install === "false") flags.push("--no-install");
4755
+ return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
4756
+ }
3932
4757
  function generateStackSelectionCommand(selection) {
3933
4758
  const projectName = getProjectName(selection);
3934
4759
  switch (selection.ecosystem) {
4760
+ case "react-native": return generateReactNativeCommand(selection, projectName);
3935
4761
  case "rust": return generateRustCommand(selection, projectName);
3936
4762
  case "python": return generatePythonCommand(selection, projectName);
3937
4763
  case "go": return generateGoCommand(selection, projectName);
3938
4764
  case "java": return generateJavaCommand(selection, projectName);
4765
+ case "elixir": return generateElixirCommand(selection, projectName);
3939
4766
  case "typescript":
3940
4767
  default: return generateTypeScriptCommand(selection, projectName);
3941
4768
  }
@@ -3943,4 +4770,4 @@ function generateStackSelectionCommand(selection) {
3943
4770
 
3944
4771
  //#endregion
3945
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 };
3946
- //# sourceMappingURL=stack-translation-Bag2NJRD.mjs.map
4773
+ //# sourceMappingURL=stack-translation-_uOX-Io0.mjs.map