@better-fullstack/types 1.7.1 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{defaults-Ra4H-o6R.d.mts → defaults-05kDqAVs.d.mts} +2 -2
- package/dist/defaults-05kDqAVs.d.mts.map +1 -0
- package/dist/{defaults-DtBqH42_.mjs → defaults-D23vxGYl.mjs} +23 -1
- package/dist/defaults-D23vxGYl.mjs.map +1 -0
- package/dist/defaults.d.mts +3 -3
- package/dist/defaults.mjs +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +4 -4
- package/dist/json-schema.d.mts +2992 -318
- package/dist/json-schema.d.mts.map +1 -1
- package/dist/json-schema.mjs +66 -2
- package/dist/json-schema.mjs.map +1 -1
- package/dist/{schemas-CC-_Vkoh.d.mts → schemas-CUFM_Cdl.d.mts} +2428 -22
- package/dist/schemas-CUFM_Cdl.d.mts.map +1 -0
- package/dist/{schemas-B2DBDBdl.mjs → schemas-Hj_Gbdf0.mjs} +201 -5
- package/dist/schemas-Hj_Gbdf0.mjs.map +1 -0
- package/dist/schemas.d.mts +2 -2
- package/dist/schemas.mjs +2 -2
- package/dist/{stack-translation-Bag2NJRD.mjs → stack-translation-BpsvxDrw.mjs} +899 -25
- package/dist/stack-translation-BpsvxDrw.mjs.map +1 -0
- package/dist/{stack-translation-B8OgQLwv.d.mts → stack-translation-D7H3h8Vs.d.mts} +51 -7
- package/dist/stack-translation-D7H3h8Vs.d.mts.map +1 -0
- package/dist/stack-translation.d.mts +4 -4
- package/dist/stack-translation.mjs +2 -2
- package/dist/types-C0KHWyJI.d.mts +119 -0
- package/dist/types-C0KHWyJI.d.mts.map +1 -0
- package/dist/types.d.mts +3 -3
- package/package.json +2 -2
- package/dist/defaults-DtBqH42_.mjs.map +0 -1
- package/dist/defaults-Ra4H-o6R.d.mts.map +0 -1
- package/dist/schemas-B2DBDBdl.mjs.map +0 -1
- package/dist/schemas-CC-_Vkoh.d.mts.map +0 -1
- package/dist/stack-translation-B8OgQLwv.d.mts.map +0 -1
- package/dist/stack-translation-Bag2NJRD.mjs.map +0 -1
- package/dist/types-Cd8oAhRY.d.mts +0 -96
- package/dist/types-Cd8oAhRY.d.mts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as createCliDefaultProjectConfigBase } from "./defaults-
|
|
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-Hj_Gbdf0.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
|
-
|
|
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,8 +953,272 @@ 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 + StyleSheet' (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",
|
|
1221
|
+
"shadcn-svelte",
|
|
898
1222
|
"daisyui",
|
|
899
1223
|
"nextui"
|
|
900
1224
|
].includes(nextStack.uiLibrary) && nextStack.cssFramework !== "tailwind") {
|
|
@@ -918,7 +1242,8 @@ const analyzeStackCompatibility = (stack) => {
|
|
|
918
1242
|
"react-router",
|
|
919
1243
|
"react-vite",
|
|
920
1244
|
"tanstack-start",
|
|
921
|
-
"next"
|
|
1245
|
+
"next",
|
|
1246
|
+
"vinext"
|
|
922
1247
|
];
|
|
923
1248
|
if (reactOnlyLibraries.includes(nextStack.uiLibrary)) {
|
|
924
1249
|
const hasReactFrontend = nextStack.webFrontend.some((f) => reactFrontends.includes(f));
|
|
@@ -932,6 +1257,18 @@ const analyzeStackCompatibility = (stack) => {
|
|
|
932
1257
|
});
|
|
933
1258
|
}
|
|
934
1259
|
}
|
|
1260
|
+
if (nextStack.uiLibrary === "shadcn-svelte") {
|
|
1261
|
+
const hasSvelteFrontend = nextStack.webFrontend.includes("svelte");
|
|
1262
|
+
const hasAstroSvelte = nextStack.webFrontend.includes("astro") && nextStack.astroIntegration === "svelte";
|
|
1263
|
+
if (!hasSvelteFrontend && !hasAstroSvelte && nextStack.webFrontend.some((f) => f !== "none")) {
|
|
1264
|
+
nextStack.uiLibrary = "daisyui";
|
|
1265
|
+
changed = true;
|
|
1266
|
+
changes.push({
|
|
1267
|
+
category: "uiLibrary",
|
|
1268
|
+
message: "UI library changed to 'daisyUI' (shadcn-svelte requires SvelteKit or Astro + Svelte)"
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
935
1272
|
if (nextStack.uiLibrary === "headless-ui") {
|
|
936
1273
|
const hasReactFrontend = nextStack.webFrontend.some((f) => reactFrontends.includes(f));
|
|
937
1274
|
const hasVueFrontend = nextStack.webFrontend.includes("nuxt");
|
|
@@ -1137,6 +1474,66 @@ const analyzeStackCompatibility = (stack) => {
|
|
|
1137
1474
|
}
|
|
1138
1475
|
}
|
|
1139
1476
|
}
|
|
1477
|
+
if (nextStack.ecosystem === "elixir") {
|
|
1478
|
+
if (nextStack.elixirWebFramework === "none") for (const key of [
|
|
1479
|
+
"elixirAuth",
|
|
1480
|
+
"elixirApi",
|
|
1481
|
+
"elixirRealtime",
|
|
1482
|
+
"elixirObservability"
|
|
1483
|
+
]) {
|
|
1484
|
+
const value = nextStack[key];
|
|
1485
|
+
if (key !== "elixirObservability" ? value !== "none" : value === "phoenix-telemetry") {
|
|
1486
|
+
nextStack[key] = "none";
|
|
1487
|
+
changed = true;
|
|
1488
|
+
changes.push({
|
|
1489
|
+
category: "elixirWebFramework",
|
|
1490
|
+
message: `${getCategoryDisplayName(key)} set to 'None' (requires Phoenix)`
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
if (nextStack.elixirWebFramework === "phoenix-live-view" && nextStack.elixirApi === "none") {
|
|
1495
|
+
nextStack.elixirRealtime = "live-view-streams";
|
|
1496
|
+
changed = true;
|
|
1497
|
+
changes.push({
|
|
1498
|
+
category: "elixirRealtime",
|
|
1499
|
+
message: "Elixir realtime set to 'LiveView Streams' (Phoenix LiveView selected)"
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
if (nextStack.elixirOrm === "none") {
|
|
1503
|
+
if (nextStack.elixirJobs === "oban") {
|
|
1504
|
+
nextStack.elixirJobs = "none";
|
|
1505
|
+
changed = true;
|
|
1506
|
+
changes.push({
|
|
1507
|
+
category: "elixirOrm",
|
|
1508
|
+
message: "Elixir jobs set to 'None' (Oban requires Ecto SQL with PostgreSQL)"
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
if (nextStack.elixirAuth === "phx-gen-auth") {
|
|
1512
|
+
nextStack.elixirAuth = "none";
|
|
1513
|
+
changed = true;
|
|
1514
|
+
changes.push({
|
|
1515
|
+
category: "elixirOrm",
|
|
1516
|
+
message: "Elixir auth set to 'None' (phx.gen.auth requires Ecto)"
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
if (nextStack.elixirApi === "absinthe") {
|
|
1520
|
+
nextStack.elixirApi = "rest";
|
|
1521
|
+
changed = true;
|
|
1522
|
+
changes.push({
|
|
1523
|
+
category: "elixirOrm",
|
|
1524
|
+
message: "Elixir API set to 'REST' (the generated Absinthe resolver needs Ecto)"
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
if (nextStack.elixirJobs === "oban" && nextStack.elixirOrm !== "ecto-sql") {
|
|
1529
|
+
nextStack.elixirJobs = "none";
|
|
1530
|
+
changed = true;
|
|
1531
|
+
changes.push({
|
|
1532
|
+
category: "elixirJobs",
|
|
1533
|
+
message: "Elixir jobs set to 'None' (Oban requires Ecto SQL with PostgreSQL)"
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1140
1537
|
if (nextStack.webDeploy !== "none" && !nextStack.webFrontend.some((f) => f !== "none")) {
|
|
1141
1538
|
nextStack.webDeploy = "none";
|
|
1142
1539
|
changed = true;
|
|
@@ -1159,6 +1556,7 @@ const analyzeStackCompatibility = (stack) => {
|
|
|
1159
1556
|
"none",
|
|
1160
1557
|
"convex",
|
|
1161
1558
|
"self-next",
|
|
1559
|
+
"self-vinext",
|
|
1162
1560
|
"self-tanstack-start",
|
|
1163
1561
|
"self-astro",
|
|
1164
1562
|
"self-nuxt",
|
|
@@ -1210,6 +1608,23 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1210
1608
|
].includes(f))})`;
|
|
1211
1609
|
}
|
|
1212
1610
|
}
|
|
1611
|
+
if (currentStack.ecosystem === "react-native") {
|
|
1612
|
+
if (!new Set([
|
|
1613
|
+
"nativeFrontend",
|
|
1614
|
+
"mobileNavigation",
|
|
1615
|
+
"mobileUI",
|
|
1616
|
+
"mobileStorage",
|
|
1617
|
+
"mobileTesting",
|
|
1618
|
+
"mobilePush",
|
|
1619
|
+
"mobileOTA",
|
|
1620
|
+
"mobileDeepLinking",
|
|
1621
|
+
"auth",
|
|
1622
|
+
"packageManager",
|
|
1623
|
+
"aiDocs",
|
|
1624
|
+
"git",
|
|
1625
|
+
"install"
|
|
1626
|
+
]).has(category) && optionId !== "none" && optionId !== "false") return "React Native ecosystem only supports native mobile options";
|
|
1627
|
+
}
|
|
1213
1628
|
if (currentStack.backend === "none") {
|
|
1214
1629
|
if (category === "runtime" && optionId !== "none") return "No backend selected";
|
|
1215
1630
|
if (category === "database" && optionId !== "none") return "No backend selected";
|
|
@@ -1227,6 +1642,11 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1227
1642
|
if (category === "webFrontend" && optionId !== "next" && optionId !== "none") return "Next.js fullstack requires Next.js frontend";
|
|
1228
1643
|
if (category === "serverDeploy" && optionId !== "none") return "Fullstack uses frontend deployment";
|
|
1229
1644
|
}
|
|
1645
|
+
if (currentStack.backend === "self-vinext") {
|
|
1646
|
+
if (category === "runtime" && optionId !== "none") return "Vinext fullstack uses built-in API routes";
|
|
1647
|
+
if (category === "webFrontend" && optionId !== "vinext" && optionId !== "none") return "Vinext fullstack requires Vinext frontend";
|
|
1648
|
+
if (category === "serverDeploy" && optionId !== "none") return "Fullstack uses frontend deployment";
|
|
1649
|
+
}
|
|
1230
1650
|
if (currentStack.backend === "self-tanstack-start") {
|
|
1231
1651
|
if (category === "runtime" && optionId !== "none") return "TanStack Start fullstack uses built-in API routes";
|
|
1232
1652
|
if (category === "webFrontend" && optionId !== "tanstack-start" && optionId !== "none") return "TanStack Start fullstack requires TanStack Start frontend";
|
|
@@ -1254,6 +1674,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1254
1674
|
}
|
|
1255
1675
|
if (category === "backend") {
|
|
1256
1676
|
if (optionId === "self-next" && !currentStack.webFrontend.includes("next")) return "Requires Next.js frontend";
|
|
1677
|
+
if (optionId === "self-vinext" && !currentStack.webFrontend.includes("vinext")) return "Requires Vinext frontend";
|
|
1257
1678
|
if (optionId === "self-tanstack-start" && !currentStack.webFrontend.includes("tanstack-start")) return "Requires TanStack Start frontend";
|
|
1258
1679
|
if (optionId === "self-astro" && !currentStack.webFrontend.includes("astro")) return "Requires Astro frontend";
|
|
1259
1680
|
if (optionId === "self-nuxt" && !currentStack.webFrontend.includes("nuxt")) return "Requires Nuxt frontend";
|
|
@@ -1271,6 +1692,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1271
1692
|
"convex",
|
|
1272
1693
|
"none",
|
|
1273
1694
|
"self-next",
|
|
1695
|
+
"self-vinext",
|
|
1274
1696
|
"self-tanstack-start",
|
|
1275
1697
|
"self-astro",
|
|
1276
1698
|
"self-nuxt",
|
|
@@ -1384,7 +1806,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1384
1806
|
if (!currentStack.webFrontend.some((f) => compatibleFrontends.includes(f))) return "TanStack AI requires React or Solid frontend (no Vue/Svelte/Angular adapter yet)";
|
|
1385
1807
|
}
|
|
1386
1808
|
if (category === "appPlatforms") {
|
|
1387
|
-
if (optionId === "pwa" && !hasPWACompatibleFrontend(currentStack.webFrontend)) return "PWA requires TanStack Router, React Router, Solid, Next.js, or Astro";
|
|
1809
|
+
if (optionId === "pwa" && !hasPWACompatibleFrontend(currentStack.webFrontend)) return "PWA requires TanStack Router, React Router, Solid, Next.js, Vinext, or Astro";
|
|
1388
1810
|
if (optionId === "tauri" && !hasTauriCompatibleFrontend(currentStack.webFrontend)) return "Tauri requires TanStack Router, React Router, Nuxt, Svelte, Solid, Next.js, or Astro";
|
|
1389
1811
|
if (optionId === "docker-compose") {
|
|
1390
1812
|
if (currentStack.backend === "convex") return "Docker Compose is not compatible with Convex backend (managed service)";
|
|
@@ -1416,7 +1838,7 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1416
1838
|
if (currentStack.ecosystem !== "typescript") return "Chat SDK example is currently available only for TypeScript stacks";
|
|
1417
1839
|
if (currentStack.backend === "convex") return "Chat SDK example is not supported with Convex backend in v1";
|
|
1418
1840
|
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;
|
|
1841
|
+
if (currentStack.backend === "self-next" || currentStack.backend === "self-vinext" || currentStack.backend === "self-tanstack-start") return null;
|
|
1420
1842
|
if (currentStack.backend === "self-nuxt") return null;
|
|
1421
1843
|
if (currentStack.backend === "hono") {
|
|
1422
1844
|
if (currentStack.runtime !== "node") return "Chat SDK Hono profile requires Node runtime in v1";
|
|
@@ -1440,9 +1862,28 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1440
1862
|
}
|
|
1441
1863
|
if ([
|
|
1442
1864
|
"shadcn-ui",
|
|
1865
|
+
"shadcn-svelte",
|
|
1443
1866
|
"daisyui",
|
|
1444
1867
|
"nextui"
|
|
1445
|
-
].includes(currentStack.uiLibrary) && optionId !== "tailwind") return `${currentStack.uiLibrary === "shadcn-ui" ? "shadcn/ui" : currentStack.uiLibrary === "daisyui" ? "daisyUI" : "NextUI"} requires Tailwind CSS`;
|
|
1868
|
+
].includes(currentStack.uiLibrary) && optionId !== "tailwind") return `${currentStack.uiLibrary === "shadcn-ui" ? "shadcn/ui" : currentStack.uiLibrary === "shadcn-svelte" ? "shadcn-svelte" : currentStack.uiLibrary === "daisyui" ? "daisyUI" : "NextUI"} requires Tailwind CSS`;
|
|
1869
|
+
}
|
|
1870
|
+
if (new Set([
|
|
1871
|
+
"mobileNavigation",
|
|
1872
|
+
"mobileUI",
|
|
1873
|
+
"mobileStorage",
|
|
1874
|
+
"mobileTesting",
|
|
1875
|
+
"mobilePush",
|
|
1876
|
+
"mobileOTA",
|
|
1877
|
+
"mobileDeepLinking"
|
|
1878
|
+
]).has(category)) {
|
|
1879
|
+
if (!currentStack.nativeFrontend.some((f) => f !== "none") && optionId !== "none") return `${getCategoryDisplayName(category)} requires a native Expo frontend`;
|
|
1880
|
+
if (category === "mobileNavigation" && optionId === "react-navigation") return null;
|
|
1881
|
+
if (category === "mobileUI") {
|
|
1882
|
+
if (optionId === "uniwind" && !currentStack.nativeFrontend.includes("native-uniwind")) return "Uniwind mobile UI requires Expo + Uniwind frontend";
|
|
1883
|
+
if (optionId === "unistyles" && !currentStack.nativeFrontend.includes("native-unistyles")) return "Unistyles mobile UI requires Expo + Unistyles frontend";
|
|
1884
|
+
if (["tamagui", "gluestack-ui"].includes(optionId) && currentStack.nativeFrontend.some((f) => ["native-uniwind", "native-unistyles"].includes(f))) return "Tamagui and Gluestack UI require Expo + StyleSheet to avoid conflicting styling setup";
|
|
1885
|
+
}
|
|
1886
|
+
if (category === "mobilePush" && optionId === "expo-notifications" || category === "mobileOTA" && optionId === "expo-updates" || category === "mobileDeepLinking" && optionId === "expo-linking") return null;
|
|
1446
1887
|
}
|
|
1447
1888
|
if (category === "uiLibrary") {
|
|
1448
1889
|
if (!currentStack.webFrontend.some((f) => f !== "none")) {
|
|
@@ -1468,6 +1909,11 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1468
1909
|
const hasAstroReact = currentStack.webFrontend.includes("astro") && currentStack.astroIntegration === "react";
|
|
1469
1910
|
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`;
|
|
1470
1911
|
}
|
|
1912
|
+
if (optionId === "shadcn-svelte") {
|
|
1913
|
+
const hasSvelteFrontend = currentStack.webFrontend.includes("svelte");
|
|
1914
|
+
const hasAstroSvelte = currentStack.webFrontend.includes("astro") && currentStack.astroIntegration === "svelte";
|
|
1915
|
+
if (!hasSvelteFrontend && !hasAstroSvelte) return "shadcn-svelte requires SvelteKit or Astro with Svelte integration";
|
|
1916
|
+
}
|
|
1471
1917
|
if (optionId === "headless-ui") {
|
|
1472
1918
|
const hasReactFrontend = currentStack.webFrontend.some((f) => reactFrontends.includes(f));
|
|
1473
1919
|
const hasVueFrontend = currentStack.webFrontend.includes("nuxt");
|
|
@@ -1488,10 +1934,11 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1488
1934
|
}
|
|
1489
1935
|
if ([
|
|
1490
1936
|
"shadcn-ui",
|
|
1937
|
+
"shadcn-svelte",
|
|
1491
1938
|
"daisyui",
|
|
1492
1939
|
"nextui"
|
|
1493
1940
|
].includes(optionId)) {
|
|
1494
|
-
if (currentStack.cssFramework !== "tailwind") return `${optionId === "shadcn-ui" ? "shadcn/ui" : optionId === "daisyui" ? "daisyUI" : "NextUI"} requires Tailwind CSS`;
|
|
1941
|
+
if (currentStack.cssFramework !== "tailwind") return `${optionId === "shadcn-ui" ? "shadcn/ui" : optionId === "shadcn-svelte" ? "shadcn-svelte" : optionId === "daisyui" ? "daisyUI" : "NextUI"} requires Tailwind CSS`;
|
|
1495
1942
|
}
|
|
1496
1943
|
}
|
|
1497
1944
|
if (category === "webDeploy" && optionId !== "none") {
|
|
@@ -1562,6 +2009,62 @@ const getDisabledReason = (currentStack, category, optionId) => {
|
|
|
1562
2009
|
if (category === "javaTestingLibraries") {
|
|
1563
2010
|
if (optionId !== "none" && currentStack.javaBuildTool === "none") return "Java testing libraries require Maven or Gradle";
|
|
1564
2011
|
}
|
|
2012
|
+
if (new Set([
|
|
2013
|
+
"elixirOrm",
|
|
2014
|
+
"elixirAuth",
|
|
2015
|
+
"elixirApi",
|
|
2016
|
+
"elixirRealtime",
|
|
2017
|
+
"elixirJobs",
|
|
2018
|
+
"elixirValidation",
|
|
2019
|
+
"elixirHttp",
|
|
2020
|
+
"elixirJson",
|
|
2021
|
+
"elixirEmail",
|
|
2022
|
+
"elixirCaching",
|
|
2023
|
+
"elixirObservability",
|
|
2024
|
+
"elixirTesting",
|
|
2025
|
+
"elixirQuality",
|
|
2026
|
+
"elixirDeploy"
|
|
2027
|
+
]).has(category) && optionId !== "none") {
|
|
2028
|
+
if (currentStack.ecosystem !== "elixir") return "Elixir options only apply when the Elixir ecosystem is selected";
|
|
2029
|
+
}
|
|
2030
|
+
if (category === "elixirWebFramework" && optionId !== "none" && currentStack.ecosystem !== "elixir") return "Elixir web frameworks are available only in the Elixir ecosystem";
|
|
2031
|
+
const unsupportedElixirReason = {
|
|
2032
|
+
elixirOrm: { ecto: "Use Ecto SQL for generated Repo, migrations, schemas, and PostgreSQL wiring" },
|
|
2033
|
+
elixirAuth: {
|
|
2034
|
+
ueberauth: "Ueberauth is not generated yet; use phx.gen.auth or no auth",
|
|
2035
|
+
guardian: "Guardian JWT wiring is not generated yet; use phx.gen.auth or no auth"
|
|
2036
|
+
},
|
|
2037
|
+
elixirValidation: { "nimble-options": "NimbleOptions is not generated yet; use Ecto Changesets or no extra validation" },
|
|
2038
|
+
elixirCaching: { nebulex: "Nebulex cache modules are not generated yet; use Cachex or no cache" },
|
|
2039
|
+
elixirObservability: {
|
|
2040
|
+
opentelemetry: "OpenTelemetry setup is not generated yet; use Phoenix telemetry or no extra observability",
|
|
2041
|
+
prom_ex: "PromEx setup is not generated yet; use Phoenix telemetry or no extra observability"
|
|
2042
|
+
},
|
|
2043
|
+
elixirTesting: {
|
|
2044
|
+
mox: "Mox-specific test boundaries are not generated yet; use ExUnit",
|
|
2045
|
+
bypass: "Bypass-specific HTTP tests are not generated yet; use ExUnit",
|
|
2046
|
+
wallaby: "Wallaby browser tests are not generated yet; use ExUnit"
|
|
2047
|
+
},
|
|
2048
|
+
elixirDeploy: {
|
|
2049
|
+
fly: "Fly.io config is not generated yet; use Docker or mix releases",
|
|
2050
|
+
gigalixir: "Gigalixir config is not generated yet; use Docker or mix releases"
|
|
2051
|
+
}
|
|
2052
|
+
}[category]?.[optionId];
|
|
2053
|
+
if (currentStack.ecosystem === "elixir" && unsupportedElixirReason) return unsupportedElixirReason;
|
|
2054
|
+
if (currentStack.ecosystem === "elixir" && currentStack.elixirWebFramework === "none") {
|
|
2055
|
+
if (category === "elixirAuth" && optionId !== "none") return "Elixir auth scaffolds require Phoenix";
|
|
2056
|
+
if (category === "elixirApi" && optionId !== "none") return "Elixir API scaffolds require Phoenix";
|
|
2057
|
+
if (category === "elixirRealtime" && optionId !== "none") return "Elixir realtime scaffolds require Phoenix";
|
|
2058
|
+
if (category === "elixirObservability" && optionId === "phoenix-telemetry") return "Phoenix telemetry requires Phoenix";
|
|
2059
|
+
}
|
|
2060
|
+
if (category === "elixirJson" && optionId === "none" && currentStack.ecosystem === "elixir" && currentStack.elixirWebFramework !== "none") return "Phoenix JSON scaffolds require Jason";
|
|
2061
|
+
if (category === "elixirAuth") {
|
|
2062
|
+
if (optionId === "phx-gen-auth" && currentStack.elixirOrm === "none") return "phx.gen.auth requires Ecto";
|
|
2063
|
+
if ((optionId === "ueberauth" || optionId === "guardian") && currentStack.elixirWebFramework === "none") return "Elixir auth libraries require Phoenix";
|
|
2064
|
+
}
|
|
2065
|
+
if (category === "elixirJobs" && optionId === "oban" && currentStack.elixirOrm !== "ecto-sql") return "Oban requires Ecto SQL with PostgreSQL in the current Phoenix scaffold";
|
|
2066
|
+
if (category === "elixirApi" && optionId === "absinthe" && currentStack.elixirOrm === "none") return "Absinthe GraphQL requires Ecto in the current Phoenix scaffold";
|
|
2067
|
+
if (category === "elixirRealtime" && optionId === "live-view-streams" && currentStack.elixirWebFramework !== "phoenix-live-view") return "LiveView Streams require Phoenix LiveView";
|
|
1565
2068
|
return null;
|
|
1566
2069
|
};
|
|
1567
2070
|
const isOptionCompatible = (currentStack, category, optionId) => {
|
|
@@ -1574,6 +2077,7 @@ const WEB_FRAMEWORKS = [
|
|
|
1574
2077
|
"react-vite",
|
|
1575
2078
|
"tanstack-start",
|
|
1576
2079
|
"next",
|
|
2080
|
+
"vinext",
|
|
1577
2081
|
"nuxt",
|
|
1578
2082
|
"svelte",
|
|
1579
2083
|
"solid",
|
|
@@ -1593,10 +2097,15 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1593
2097
|
"react-vite",
|
|
1594
2098
|
"tanstack-start",
|
|
1595
2099
|
"next",
|
|
2100
|
+
"vinext",
|
|
1596
2101
|
"astro"
|
|
1597
2102
|
],
|
|
1598
2103
|
cssFrameworks: ["tailwind"]
|
|
1599
2104
|
},
|
|
2105
|
+
"shadcn-svelte": {
|
|
2106
|
+
frontends: ["svelte", "astro"],
|
|
2107
|
+
cssFrameworks: ["tailwind"]
|
|
2108
|
+
},
|
|
1600
2109
|
daisyui: {
|
|
1601
2110
|
frontends: [
|
|
1602
2111
|
"tanstack-router",
|
|
@@ -1604,6 +2113,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1604
2113
|
"react-vite",
|
|
1605
2114
|
"tanstack-start",
|
|
1606
2115
|
"next",
|
|
2116
|
+
"vinext",
|
|
1607
2117
|
"nuxt",
|
|
1608
2118
|
"svelte",
|
|
1609
2119
|
"solid",
|
|
@@ -1623,6 +2133,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1623
2133
|
"react-vite",
|
|
1624
2134
|
"tanstack-start",
|
|
1625
2135
|
"next",
|
|
2136
|
+
"vinext",
|
|
1626
2137
|
"astro"
|
|
1627
2138
|
],
|
|
1628
2139
|
cssFrameworks: [
|
|
@@ -1640,6 +2151,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1640
2151
|
"react-vite",
|
|
1641
2152
|
"tanstack-start",
|
|
1642
2153
|
"next",
|
|
2154
|
+
"vinext",
|
|
1643
2155
|
"nuxt",
|
|
1644
2156
|
"astro"
|
|
1645
2157
|
],
|
|
@@ -1658,6 +2170,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1658
2170
|
"react-vite",
|
|
1659
2171
|
"tanstack-start",
|
|
1660
2172
|
"next",
|
|
2173
|
+
"vinext",
|
|
1661
2174
|
"nuxt",
|
|
1662
2175
|
"solid",
|
|
1663
2176
|
"solid-start",
|
|
@@ -1677,6 +2190,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1677
2190
|
"react-vite",
|
|
1678
2191
|
"tanstack-start",
|
|
1679
2192
|
"next",
|
|
2193
|
+
"vinext",
|
|
1680
2194
|
"astro"
|
|
1681
2195
|
],
|
|
1682
2196
|
cssFrameworks: [
|
|
@@ -1694,6 +2208,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1694
2208
|
"react-vite",
|
|
1695
2209
|
"tanstack-start",
|
|
1696
2210
|
"next",
|
|
2211
|
+
"vinext",
|
|
1697
2212
|
"astro"
|
|
1698
2213
|
],
|
|
1699
2214
|
cssFrameworks: ["tailwind"]
|
|
@@ -1705,6 +2220,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1705
2220
|
"react-vite",
|
|
1706
2221
|
"tanstack-start",
|
|
1707
2222
|
"next",
|
|
2223
|
+
"vinext",
|
|
1708
2224
|
"astro"
|
|
1709
2225
|
],
|
|
1710
2226
|
cssFrameworks: [
|
|
@@ -1756,6 +2272,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1756
2272
|
"react-vite",
|
|
1757
2273
|
"tanstack-start",
|
|
1758
2274
|
"next",
|
|
2275
|
+
"vinext",
|
|
1759
2276
|
"astro"
|
|
1760
2277
|
],
|
|
1761
2278
|
cssFrameworks: [
|
|
@@ -1772,6 +2289,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1772
2289
|
"react-router",
|
|
1773
2290
|
"tanstack-start",
|
|
1774
2291
|
"next",
|
|
2292
|
+
"vinext",
|
|
1775
2293
|
"nuxt",
|
|
1776
2294
|
"svelte",
|
|
1777
2295
|
"solid",
|
|
@@ -1793,6 +2311,7 @@ const UI_LIBRARY_COMPATIBILITY = {
|
|
|
1793
2311
|
"react-vite",
|
|
1794
2312
|
"tanstack-start",
|
|
1795
2313
|
"next",
|
|
2314
|
+
"vinext",
|
|
1796
2315
|
"astro"
|
|
1797
2316
|
],
|
|
1798
2317
|
cssFrameworks: [
|
|
@@ -1821,6 +2340,7 @@ const ADDON_COMPATIBILITY = {
|
|
|
1821
2340
|
"react-vite",
|
|
1822
2341
|
"solid",
|
|
1823
2342
|
"next",
|
|
2343
|
+
"vinext",
|
|
1824
2344
|
"astro",
|
|
1825
2345
|
"qwik",
|
|
1826
2346
|
"angular",
|
|
@@ -1864,6 +2384,16 @@ const ADDON_COMPATIBILITY = {
|
|
|
1864
2384
|
"svelte",
|
|
1865
2385
|
"solid"
|
|
1866
2386
|
],
|
|
2387
|
+
swr: [
|
|
2388
|
+
"tanstack-router",
|
|
2389
|
+
"react-router",
|
|
2390
|
+
"react-vite",
|
|
2391
|
+
"tanstack-start",
|
|
2392
|
+
"next",
|
|
2393
|
+
"vinext",
|
|
2394
|
+
"astro",
|
|
2395
|
+
"redwood"
|
|
2396
|
+
],
|
|
1867
2397
|
"tanstack-query": [
|
|
1868
2398
|
"tanstack-router",
|
|
1869
2399
|
"react-router",
|
|
@@ -2251,7 +2781,22 @@ function evaluateCompatibility(input) {
|
|
|
2251
2781
|
["javaWebFramework", input.javaWebFramework],
|
|
2252
2782
|
["javaBuildTool", input.javaBuildTool],
|
|
2253
2783
|
["javaOrm", input.javaOrm],
|
|
2254
|
-
["javaAuth", input.javaAuth]
|
|
2784
|
+
["javaAuth", input.javaAuth],
|
|
2785
|
+
["elixirWebFramework", input.elixirWebFramework],
|
|
2786
|
+
["elixirOrm", input.elixirOrm],
|
|
2787
|
+
["elixirAuth", input.elixirAuth],
|
|
2788
|
+
["elixirApi", input.elixirApi],
|
|
2789
|
+
["elixirRealtime", input.elixirRealtime],
|
|
2790
|
+
["elixirJobs", input.elixirJobs],
|
|
2791
|
+
["elixirValidation", input.elixirValidation],
|
|
2792
|
+
["elixirHttp", input.elixirHttp],
|
|
2793
|
+
["elixirJson", input.elixirJson],
|
|
2794
|
+
["elixirEmail", input.elixirEmail],
|
|
2795
|
+
["elixirCaching", input.elixirCaching],
|
|
2796
|
+
["elixirObservability", input.elixirObservability],
|
|
2797
|
+
["elixirTesting", input.elixirTesting],
|
|
2798
|
+
["elixirQuality", input.elixirQuality],
|
|
2799
|
+
["elixirDeploy", input.elixirDeploy]
|
|
2255
2800
|
];
|
|
2256
2801
|
for (const [category, optionId] of scalarChecks) {
|
|
2257
2802
|
const reason = getDisabledReason(input, category, optionId);
|
|
@@ -2326,6 +2871,7 @@ const WEB_FRONTEND_VALUES = [
|
|
|
2326
2871
|
"react-vite",
|
|
2327
2872
|
"tanstack-start",
|
|
2328
2873
|
"next",
|
|
2874
|
+
"vinext",
|
|
2329
2875
|
"nuxt",
|
|
2330
2876
|
"svelte",
|
|
2331
2877
|
"solid",
|
|
@@ -2355,6 +2901,7 @@ const BACKEND_BUILDER_VALUES = [
|
|
|
2355
2901
|
"encore",
|
|
2356
2902
|
"convex",
|
|
2357
2903
|
"self-next",
|
|
2904
|
+
"self-vinext",
|
|
2358
2905
|
"self-tanstack-start",
|
|
2359
2906
|
"self-astro",
|
|
2360
2907
|
"self-nuxt",
|
|
@@ -2381,6 +2928,7 @@ const APP_PLATFORM_VALUES = [
|
|
|
2381
2928
|
"skills",
|
|
2382
2929
|
"msw",
|
|
2383
2930
|
"storybook",
|
|
2931
|
+
"swr",
|
|
2384
2932
|
"tanstack-query",
|
|
2385
2933
|
"tanstack-table",
|
|
2386
2934
|
"tanstack-virtual",
|
|
@@ -2438,6 +2986,13 @@ const CATEGORY_VALUE_IDS = {
|
|
|
2438
2986
|
cms: CMS_VALUES,
|
|
2439
2987
|
featureFlags: FEATURE_FLAGS_VALUES,
|
|
2440
2988
|
analytics: ANALYTICS_VALUES,
|
|
2989
|
+
mobileNavigation: MOBILE_NAVIGATION_VALUES,
|
|
2990
|
+
mobileUI: MOBILE_UI_VALUES,
|
|
2991
|
+
mobileStorage: MOBILE_STORAGE_VALUES,
|
|
2992
|
+
mobileTesting: MOBILE_TESTING_VALUES,
|
|
2993
|
+
mobilePush: MOBILE_PUSH_VALUES,
|
|
2994
|
+
mobileOTA: MOBILE_OTA_VALUES,
|
|
2995
|
+
mobileDeepLinking: MOBILE_DEEP_LINKING_VALUES,
|
|
2441
2996
|
codeQuality: CODE_QUALITY_VALUES,
|
|
2442
2997
|
documentation: DOCUMENTATION_VALUES,
|
|
2443
2998
|
appPlatforms: APP_PLATFORM_VALUES,
|
|
@@ -2486,7 +3041,22 @@ const CATEGORY_VALUE_IDS = {
|
|
|
2486
3041
|
javaOrm: JAVA_ORM_VALUES,
|
|
2487
3042
|
javaAuth: JAVA_AUTH_VALUES,
|
|
2488
3043
|
javaLibraries: JAVA_LIBRARIES_VALUES,
|
|
2489
|
-
javaTestingLibraries: JAVA_TESTING_LIBRARIES_VALUES
|
|
3044
|
+
javaTestingLibraries: JAVA_TESTING_LIBRARIES_VALUES,
|
|
3045
|
+
elixirWebFramework: ELIXIR_WEB_FRAMEWORK_VALUES,
|
|
3046
|
+
elixirOrm: ELIXIR_ORM_VALUES,
|
|
3047
|
+
elixirAuth: ELIXIR_AUTH_VALUES,
|
|
3048
|
+
elixirApi: ELIXIR_API_VALUES,
|
|
3049
|
+
elixirRealtime: ELIXIR_REALTIME_VALUES,
|
|
3050
|
+
elixirJobs: ELIXIR_JOBS_VALUES,
|
|
3051
|
+
elixirValidation: ELIXIR_VALIDATION_VALUES,
|
|
3052
|
+
elixirHttp: ELIXIR_HTTP_VALUES,
|
|
3053
|
+
elixirJson: ELIXIR_JSON_VALUES,
|
|
3054
|
+
elixirEmail: ELIXIR_EMAIL_VALUES,
|
|
3055
|
+
elixirCaching: ELIXIR_CACHING_VALUES,
|
|
3056
|
+
elixirObservability: ELIXIR_OBSERVABILITY_VALUES,
|
|
3057
|
+
elixirTesting: ELIXIR_TESTING_VALUES,
|
|
3058
|
+
elixirQuality: ELIXIR_QUALITY_VALUES,
|
|
3059
|
+
elixirDeploy: ELIXIR_DEPLOY_VALUES
|
|
2490
3060
|
};
|
|
2491
3061
|
const EXACT_LABEL_OVERRIDES = {
|
|
2492
3062
|
api: {
|
|
@@ -2496,12 +3066,13 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2496
3066
|
},
|
|
2497
3067
|
webFrontend: {
|
|
2498
3068
|
next: "Next.js",
|
|
3069
|
+
vinext: "Vinext",
|
|
2499
3070
|
"react-vite": "React + Vite",
|
|
2500
3071
|
svelte: "SvelteKit",
|
|
2501
3072
|
redwood: "RedwoodJS"
|
|
2502
3073
|
},
|
|
2503
3074
|
nativeFrontend: {
|
|
2504
|
-
"native-bare": "Expo +
|
|
3075
|
+
"native-bare": "Expo + StyleSheet",
|
|
2505
3076
|
"native-uniwind": "Expo + Uniwind",
|
|
2506
3077
|
"native-unistyles": "Expo + Unistyles"
|
|
2507
3078
|
},
|
|
@@ -2514,6 +3085,7 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2514
3085
|
nestjs: "NestJS",
|
|
2515
3086
|
encore: "Encore.ts",
|
|
2516
3087
|
"self-next": "Fullstack Next.js",
|
|
3088
|
+
"self-vinext": "Fullstack Vinext",
|
|
2517
3089
|
"self-tanstack-start": "Fullstack TanStack Start",
|
|
2518
3090
|
"self-astro": "Fullstack Astro",
|
|
2519
3091
|
"self-nuxt": "Fullstack Nuxt",
|
|
@@ -2549,7 +3121,10 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2549
3121
|
sst: "SST",
|
|
2550
3122
|
vercel: "Vercel"
|
|
2551
3123
|
},
|
|
2552
|
-
cms: {
|
|
3124
|
+
cms: {
|
|
3125
|
+
tinacms: "TinaCMS",
|
|
3126
|
+
directus: "Directus"
|
|
3127
|
+
},
|
|
2553
3128
|
auth: {},
|
|
2554
3129
|
payments: {
|
|
2555
3130
|
"lemon-squeezy": "Lemon Squeezy",
|
|
@@ -2605,6 +3180,12 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2605
3180
|
elasticsearch: "Elasticsearch",
|
|
2606
3181
|
algolia: "Algolia"
|
|
2607
3182
|
},
|
|
3183
|
+
fileStorage: {
|
|
3184
|
+
s3: "AWS S3",
|
|
3185
|
+
r2: "Cloudflare R2",
|
|
3186
|
+
cloudinary: "Cloudinary"
|
|
3187
|
+
},
|
|
3188
|
+
logging: { evlog: "evlog" },
|
|
2608
3189
|
cssFramework: {
|
|
2609
3190
|
tailwind: "Tailwind CSS",
|
|
2610
3191
|
scss: "SCSS",
|
|
@@ -2612,6 +3193,7 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2612
3193
|
},
|
|
2613
3194
|
uiLibrary: {
|
|
2614
3195
|
"shadcn-ui": "shadcn/ui",
|
|
3196
|
+
"shadcn-svelte": "shadcn-svelte",
|
|
2615
3197
|
daisyui: "daisyUI",
|
|
2616
3198
|
"radix-ui": "Radix UI",
|
|
2617
3199
|
"headless-ui": "Headless UI",
|
|
@@ -2635,6 +3217,25 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2635
3217
|
plausible: "Plausible",
|
|
2636
3218
|
umami: "Umami"
|
|
2637
3219
|
},
|
|
3220
|
+
mobileNavigation: {
|
|
3221
|
+
"expo-router": "Expo Router",
|
|
3222
|
+
"react-navigation": "React Navigation"
|
|
3223
|
+
},
|
|
3224
|
+
mobileUI: {
|
|
3225
|
+
tamagui: "Tamagui",
|
|
3226
|
+
"gluestack-ui": "Gluestack UI",
|
|
3227
|
+
uniwind: "Uniwind",
|
|
3228
|
+
unistyles: "Unistyles"
|
|
3229
|
+
},
|
|
3230
|
+
mobileStorage: { mmkv: "MMKV" },
|
|
3231
|
+
mobileTesting: {
|
|
3232
|
+
maestro: "Maestro",
|
|
3233
|
+
"react-native-testing-library": "React Native Testing Library",
|
|
3234
|
+
"maestro-react-native-testing-library": "Maestro + RN Testing Library"
|
|
3235
|
+
},
|
|
3236
|
+
mobilePush: { "expo-notifications": "Expo Notifications" },
|
|
3237
|
+
mobileOTA: { "expo-updates": "Expo Updates" },
|
|
3238
|
+
mobileDeepLinking: { "expo-linking": "Expo Linking" },
|
|
2638
3239
|
codeQuality: {
|
|
2639
3240
|
biome: "Biome",
|
|
2640
3241
|
oxlint: "Oxlint",
|
|
@@ -2653,6 +3254,7 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2653
3254
|
opentui: "OpenTUI",
|
|
2654
3255
|
mcp: "MCP",
|
|
2655
3256
|
msw: "MSW",
|
|
3257
|
+
swr: "SWR",
|
|
2656
3258
|
"tanstack-query": "TanStack Query",
|
|
2657
3259
|
"tanstack-table": "TanStack Table",
|
|
2658
3260
|
"tanstack-virtual": "TanStack Virtual",
|
|
@@ -2897,6 +3499,69 @@ const EXACT_LABEL_OVERRIDES = {
|
|
|
2897
3499
|
awaitility: "Awaitility",
|
|
2898
3500
|
archunit: "ArchUnit",
|
|
2899
3501
|
jqwik: "jqwik"
|
|
3502
|
+
},
|
|
3503
|
+
elixirWebFramework: {
|
|
3504
|
+
phoenix: "Phoenix",
|
|
3505
|
+
"phoenix-live-view": "Phoenix LiveView"
|
|
3506
|
+
},
|
|
3507
|
+
elixirOrm: {
|
|
3508
|
+
ecto: "Ecto",
|
|
3509
|
+
"ecto-sql": "Ecto SQL"
|
|
3510
|
+
},
|
|
3511
|
+
elixirAuth: {
|
|
3512
|
+
"phx-gen-auth": "phx.gen.auth",
|
|
3513
|
+
ueberauth: "Ueberauth",
|
|
3514
|
+
guardian: "Guardian"
|
|
3515
|
+
},
|
|
3516
|
+
elixirApi: {
|
|
3517
|
+
rest: "Phoenix REST",
|
|
3518
|
+
absinthe: "Absinthe GraphQL"
|
|
3519
|
+
},
|
|
3520
|
+
elixirRealtime: {
|
|
3521
|
+
channels: "Phoenix Channels",
|
|
3522
|
+
presence: "Phoenix Presence",
|
|
3523
|
+
pubsub: "Phoenix PubSub",
|
|
3524
|
+
"live-view-streams": "LiveView Streams"
|
|
3525
|
+
},
|
|
3526
|
+
elixirJobs: {
|
|
3527
|
+
oban: "Oban",
|
|
3528
|
+
quantum: "Quantum"
|
|
3529
|
+
},
|
|
3530
|
+
elixirValidation: {
|
|
3531
|
+
"ecto-changesets": "Ecto Changesets",
|
|
3532
|
+
"nimble-options": "NimbleOptions"
|
|
3533
|
+
},
|
|
3534
|
+
elixirHttp: {
|
|
3535
|
+
req: "Req",
|
|
3536
|
+
finch: "Finch"
|
|
3537
|
+
},
|
|
3538
|
+
elixirJson: { jason: "Jason" },
|
|
3539
|
+
elixirEmail: { swoosh: "Swoosh" },
|
|
3540
|
+
elixirCaching: {
|
|
3541
|
+
cachex: "Cachex",
|
|
3542
|
+
nebulex: "Nebulex"
|
|
3543
|
+
},
|
|
3544
|
+
elixirObservability: {
|
|
3545
|
+
telemetry: "Telemetry",
|
|
3546
|
+
opentelemetry: "OpenTelemetry",
|
|
3547
|
+
prom_ex: "PromEx"
|
|
3548
|
+
},
|
|
3549
|
+
elixirTesting: {
|
|
3550
|
+
ex_unit: "ExUnit",
|
|
3551
|
+
mox: "Mox",
|
|
3552
|
+
bypass: "Bypass",
|
|
3553
|
+
wallaby: "Wallaby"
|
|
3554
|
+
},
|
|
3555
|
+
elixirQuality: {
|
|
3556
|
+
credo: "Credo",
|
|
3557
|
+
dialyxir: "Dialyxir",
|
|
3558
|
+
sobelow: "Sobelow"
|
|
3559
|
+
},
|
|
3560
|
+
elixirDeploy: {
|
|
3561
|
+
docker: "Docker",
|
|
3562
|
+
fly: "Fly.io",
|
|
3563
|
+
gigalixir: "Gigalixir",
|
|
3564
|
+
"mix-release": "Mix Release"
|
|
2900
3565
|
}
|
|
2901
3566
|
};
|
|
2902
3567
|
const OPTION_ALIASES = {
|
|
@@ -2905,6 +3570,7 @@ const OPTION_ALIASES = {
|
|
|
2905
3570
|
};
|
|
2906
3571
|
const CLI_VALUE_OVERRIDES = { backend: {
|
|
2907
3572
|
"self-next": "self",
|
|
3573
|
+
"self-vinext": "self",
|
|
2908
3574
|
"self-tanstack-start": "self",
|
|
2909
3575
|
"self-astro": "self",
|
|
2910
3576
|
"self-nuxt": "self",
|
|
@@ -2991,6 +3657,13 @@ const OPTION_CATEGORY_METADATA = {
|
|
|
2991
3657
|
cms: buildCategoryMetadata("cms"),
|
|
2992
3658
|
featureFlags: buildCategoryMetadata("featureFlags"),
|
|
2993
3659
|
analytics: buildCategoryMetadata("analytics"),
|
|
3660
|
+
mobileNavigation: buildCategoryMetadata("mobileNavigation"),
|
|
3661
|
+
mobileUI: buildCategoryMetadata("mobileUI"),
|
|
3662
|
+
mobileStorage: buildCategoryMetadata("mobileStorage"),
|
|
3663
|
+
mobileTesting: buildCategoryMetadata("mobileTesting"),
|
|
3664
|
+
mobilePush: buildCategoryMetadata("mobilePush"),
|
|
3665
|
+
mobileOTA: buildCategoryMetadata("mobileOTA"),
|
|
3666
|
+
mobileDeepLinking: buildCategoryMetadata("mobileDeepLinking"),
|
|
2994
3667
|
codeQuality: buildCategoryMetadata("codeQuality"),
|
|
2995
3668
|
documentation: buildCategoryMetadata("documentation"),
|
|
2996
3669
|
appPlatforms: buildCategoryMetadata("appPlatforms"),
|
|
@@ -3039,7 +3712,22 @@ const OPTION_CATEGORY_METADATA = {
|
|
|
3039
3712
|
javaOrm: buildCategoryMetadata("javaOrm"),
|
|
3040
3713
|
javaAuth: buildCategoryMetadata("javaAuth"),
|
|
3041
3714
|
javaLibraries: buildCategoryMetadata("javaLibraries"),
|
|
3042
|
-
javaTestingLibraries: buildCategoryMetadata("javaTestingLibraries")
|
|
3715
|
+
javaTestingLibraries: buildCategoryMetadata("javaTestingLibraries"),
|
|
3716
|
+
elixirWebFramework: buildCategoryMetadata("elixirWebFramework"),
|
|
3717
|
+
elixirOrm: buildCategoryMetadata("elixirOrm"),
|
|
3718
|
+
elixirAuth: buildCategoryMetadata("elixirAuth"),
|
|
3719
|
+
elixirApi: buildCategoryMetadata("elixirApi"),
|
|
3720
|
+
elixirRealtime: buildCategoryMetadata("elixirRealtime"),
|
|
3721
|
+
elixirJobs: buildCategoryMetadata("elixirJobs"),
|
|
3722
|
+
elixirValidation: buildCategoryMetadata("elixirValidation"),
|
|
3723
|
+
elixirHttp: buildCategoryMetadata("elixirHttp"),
|
|
3724
|
+
elixirJson: buildCategoryMetadata("elixirJson"),
|
|
3725
|
+
elixirEmail: buildCategoryMetadata("elixirEmail"),
|
|
3726
|
+
elixirCaching: buildCategoryMetadata("elixirCaching"),
|
|
3727
|
+
elixirObservability: buildCategoryMetadata("elixirObservability"),
|
|
3728
|
+
elixirTesting: buildCategoryMetadata("elixirTesting"),
|
|
3729
|
+
elixirQuality: buildCategoryMetadata("elixirQuality"),
|
|
3730
|
+
elixirDeploy: buildCategoryMetadata("elixirDeploy")
|
|
3043
3731
|
};
|
|
3044
3732
|
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
3733
|
function isMultiSelectCategory(category) {
|
|
@@ -3079,6 +3767,13 @@ const DEFAULT_STACK_SELECTION = {
|
|
|
3079
3767
|
observability: "none",
|
|
3080
3768
|
featureFlags: "none",
|
|
3081
3769
|
analytics: "none",
|
|
3770
|
+
mobileNavigation: "none",
|
|
3771
|
+
mobileUI: "none",
|
|
3772
|
+
mobileStorage: "none",
|
|
3773
|
+
mobileTesting: "none",
|
|
3774
|
+
mobilePush: "none",
|
|
3775
|
+
mobileOTA: "none",
|
|
3776
|
+
mobileDeepLinking: "none",
|
|
3082
3777
|
backendLibraries: "none",
|
|
3083
3778
|
stateManagement: "none",
|
|
3084
3779
|
forms: "react-hook-form",
|
|
@@ -3145,7 +3840,22 @@ const DEFAULT_STACK_SELECTION = {
|
|
|
3145
3840
|
javaOrm: "none",
|
|
3146
3841
|
javaAuth: "none",
|
|
3147
3842
|
javaLibraries: [],
|
|
3148
|
-
javaTestingLibraries: ["junit5"]
|
|
3843
|
+
javaTestingLibraries: ["junit5"],
|
|
3844
|
+
elixirWebFramework: "phoenix",
|
|
3845
|
+
elixirOrm: "ecto-sql",
|
|
3846
|
+
elixirAuth: "none",
|
|
3847
|
+
elixirApi: "rest",
|
|
3848
|
+
elixirRealtime: "channels",
|
|
3849
|
+
elixirJobs: "none",
|
|
3850
|
+
elixirValidation: "ecto-changesets",
|
|
3851
|
+
elixirHttp: "req",
|
|
3852
|
+
elixirJson: "jason",
|
|
3853
|
+
elixirEmail: "none",
|
|
3854
|
+
elixirCaching: "none",
|
|
3855
|
+
elixirObservability: "telemetry",
|
|
3856
|
+
elixirTesting: "ex_unit",
|
|
3857
|
+
elixirQuality: "credo",
|
|
3858
|
+
elixirDeploy: "none"
|
|
3149
3859
|
};
|
|
3150
3860
|
const NON_OPTION_STACK_SELECTION_KEYS = [
|
|
3151
3861
|
"ecosystem",
|
|
@@ -3169,6 +3879,13 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
|
|
|
3169
3879
|
observability: "observability",
|
|
3170
3880
|
featureFlags: "featureFlags",
|
|
3171
3881
|
analytics: "analytics",
|
|
3882
|
+
mobileNavigation: "mobileNavigation",
|
|
3883
|
+
mobileUI: "mobileUI",
|
|
3884
|
+
mobileStorage: "mobileStorage",
|
|
3885
|
+
mobileTesting: "mobileTesting",
|
|
3886
|
+
mobilePush: "mobilePush",
|
|
3887
|
+
mobileOTA: "mobileOTA",
|
|
3888
|
+
mobileDeepLinking: "mobileDeepLinking",
|
|
3172
3889
|
backendLibraries: "backendLibraries",
|
|
3173
3890
|
stateManagement: "stateManagement",
|
|
3174
3891
|
forms: "forms",
|
|
@@ -3234,7 +3951,22 @@ const STACK_SELECTION_OPTION_CATEGORY_BY_KEY = {
|
|
|
3234
3951
|
javaOrm: "javaOrm",
|
|
3235
3952
|
javaAuth: "javaAuth",
|
|
3236
3953
|
javaLibraries: "javaLibraries",
|
|
3237
|
-
javaTestingLibraries: "javaTestingLibraries"
|
|
3954
|
+
javaTestingLibraries: "javaTestingLibraries",
|
|
3955
|
+
elixirWebFramework: "elixirWebFramework",
|
|
3956
|
+
elixirOrm: "elixirOrm",
|
|
3957
|
+
elixirAuth: "elixirAuth",
|
|
3958
|
+
elixirApi: "elixirApi",
|
|
3959
|
+
elixirRealtime: "elixirRealtime",
|
|
3960
|
+
elixirJobs: "elixirJobs",
|
|
3961
|
+
elixirValidation: "elixirValidation",
|
|
3962
|
+
elixirHttp: "elixirHttp",
|
|
3963
|
+
elixirJson: "elixirJson",
|
|
3964
|
+
elixirEmail: "elixirEmail",
|
|
3965
|
+
elixirCaching: "elixirCaching",
|
|
3966
|
+
elixirObservability: "elixirObservability",
|
|
3967
|
+
elixirTesting: "elixirTesting",
|
|
3968
|
+
elixirQuality: "elixirQuality",
|
|
3969
|
+
elixirDeploy: "elixirDeploy"
|
|
3238
3970
|
};
|
|
3239
3971
|
const VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS = [
|
|
3240
3972
|
"rustLibraries",
|
|
@@ -3265,6 +3997,13 @@ const STACK_SELECTION_URL_KEYS = {
|
|
|
3265
3997
|
observability: "obs",
|
|
3266
3998
|
featureFlags: "ff",
|
|
3267
3999
|
analytics: "an",
|
|
4000
|
+
mobileNavigation: "mn",
|
|
4001
|
+
mobileUI: "mui",
|
|
4002
|
+
mobileStorage: "mst",
|
|
4003
|
+
mobileTesting: "mte",
|
|
4004
|
+
mobilePush: "mpu",
|
|
4005
|
+
mobileOTA: "mota",
|
|
4006
|
+
mobileDeepLinking: "mdl",
|
|
3268
4007
|
backendLibraries: "bl",
|
|
3269
4008
|
stateManagement: "sm",
|
|
3270
4009
|
forms: "frm",
|
|
@@ -3331,7 +4070,22 @@ const STACK_SELECTION_URL_KEYS = {
|
|
|
3331
4070
|
javaOrm: "jorm",
|
|
3332
4071
|
javaAuth: "jauth",
|
|
3333
4072
|
javaLibraries: "jlib",
|
|
3334
|
-
javaTestingLibraries: "jtest"
|
|
4073
|
+
javaTestingLibraries: "jtest",
|
|
4074
|
+
elixirWebFramework: "ewf",
|
|
4075
|
+
elixirOrm: "eorm",
|
|
4076
|
+
elixirAuth: "eauth",
|
|
4077
|
+
elixirApi: "eapi",
|
|
4078
|
+
elixirRealtime: "ert",
|
|
4079
|
+
elixirJobs: "ejob",
|
|
4080
|
+
elixirValidation: "eval",
|
|
4081
|
+
elixirHttp: "ehttp",
|
|
4082
|
+
elixirJson: "ejson",
|
|
4083
|
+
elixirEmail: "emailx",
|
|
4084
|
+
elixirCaching: "ecache",
|
|
4085
|
+
elixirObservability: "eobs",
|
|
4086
|
+
elixirTesting: "etest",
|
|
4087
|
+
elixirQuality: "eq",
|
|
4088
|
+
elixirDeploy: "edeploy"
|
|
3335
4089
|
};
|
|
3336
4090
|
const STACK_SELECTION_KEYS = Object.keys(STACK_SELECTION_URL_KEYS);
|
|
3337
4091
|
const stackSelectionArrayKeySet = new Set(STACK_SELECTION_KEYS.filter((key) => Array.isArray(DEFAULT_STACK_SELECTION[key])));
|
|
@@ -3453,6 +4207,13 @@ const CLI_SCALAR_CONFIG_FIELDS = [
|
|
|
3453
4207
|
["search", "search"],
|
|
3454
4208
|
["fileStorage", "fileStorage"],
|
|
3455
4209
|
["analytics", "analytics"],
|
|
4210
|
+
["mobileNavigation", "mobileNavigation"],
|
|
4211
|
+
["mobileUI", "mobileUI"],
|
|
4212
|
+
["mobileStorage", "mobileStorage"],
|
|
4213
|
+
["mobileTesting", "mobileTesting"],
|
|
4214
|
+
["mobilePush", "mobilePush"],
|
|
4215
|
+
["mobileOTA", "mobileOTA"],
|
|
4216
|
+
["mobileDeepLinking", "mobileDeepLinking"],
|
|
3456
4217
|
["featureFlags", "featureFlags"],
|
|
3457
4218
|
["fileUpload", "fileUpload"],
|
|
3458
4219
|
["git", "git"],
|
|
@@ -3499,7 +4260,22 @@ const CLI_SCALAR_CONFIG_FIELDS = [
|
|
|
3499
4260
|
["javaWebFramework", "javaWebFramework"],
|
|
3500
4261
|
["javaBuildTool", "javaBuildTool"],
|
|
3501
4262
|
["javaOrm", "javaOrm"],
|
|
3502
|
-
["javaAuth", "javaAuth"]
|
|
4263
|
+
["javaAuth", "javaAuth"],
|
|
4264
|
+
["elixirWebFramework", "elixirWebFramework"],
|
|
4265
|
+
["elixirOrm", "elixirOrm"],
|
|
4266
|
+
["elixirAuth", "elixirAuth"],
|
|
4267
|
+
["elixirApi", "elixirApi"],
|
|
4268
|
+
["elixirRealtime", "elixirRealtime"],
|
|
4269
|
+
["elixirJobs", "elixirJobs"],
|
|
4270
|
+
["elixirValidation", "elixirValidation"],
|
|
4271
|
+
["elixirHttp", "elixirHttp"],
|
|
4272
|
+
["elixirJson", "elixirJson"],
|
|
4273
|
+
["elixirEmail", "elixirEmail"],
|
|
4274
|
+
["elixirCaching", "elixirCaching"],
|
|
4275
|
+
["elixirObservability", "elixirObservability"],
|
|
4276
|
+
["elixirTesting", "elixirTesting"],
|
|
4277
|
+
["elixirQuality", "elixirQuality"],
|
|
4278
|
+
["elixirDeploy", "elixirDeploy"]
|
|
3503
4279
|
];
|
|
3504
4280
|
const CLI_NON_EMPTY_ARRAY_CONFIG_FIELDS = [
|
|
3505
4281
|
["frontend", "frontend"],
|
|
@@ -3525,7 +4301,8 @@ const SELF_BACKENDS = new Set([
|
|
|
3525
4301
|
"self-astro",
|
|
3526
4302
|
"self-nuxt",
|
|
3527
4303
|
"self-svelte",
|
|
3528
|
-
"self-solid-start"
|
|
4304
|
+
"self-solid-start",
|
|
4305
|
+
"self-vinext"
|
|
3529
4306
|
]);
|
|
3530
4307
|
const RUST_CONFIG_KEYS = [
|
|
3531
4308
|
"rustWebFramework",
|
|
@@ -3566,6 +4343,32 @@ const JAVA_CONFIG_KEYS = [
|
|
|
3566
4343
|
"javaLibraries",
|
|
3567
4344
|
"javaTestingLibraries"
|
|
3568
4345
|
];
|
|
4346
|
+
const ELIXIR_CONFIG_KEYS = [
|
|
4347
|
+
"elixirWebFramework",
|
|
4348
|
+
"elixirOrm",
|
|
4349
|
+
"elixirAuth",
|
|
4350
|
+
"elixirApi",
|
|
4351
|
+
"elixirRealtime",
|
|
4352
|
+
"elixirJobs",
|
|
4353
|
+
"elixirValidation",
|
|
4354
|
+
"elixirHttp",
|
|
4355
|
+
"elixirJson",
|
|
4356
|
+
"elixirEmail",
|
|
4357
|
+
"elixirCaching",
|
|
4358
|
+
"elixirObservability",
|
|
4359
|
+
"elixirTesting",
|
|
4360
|
+
"elixirQuality",
|
|
4361
|
+
"elixirDeploy"
|
|
4362
|
+
];
|
|
4363
|
+
const REACT_NATIVE_CONFIG_KEYS = [
|
|
4364
|
+
"mobileNavigation",
|
|
4365
|
+
"mobileUI",
|
|
4366
|
+
"mobileStorage",
|
|
4367
|
+
"mobileTesting",
|
|
4368
|
+
"mobilePush",
|
|
4369
|
+
"mobileOTA",
|
|
4370
|
+
"mobileDeepLinking"
|
|
4371
|
+
];
|
|
3569
4372
|
const COMMAND_ADDONS = new Set([
|
|
3570
4373
|
"pwa",
|
|
3571
4374
|
"tauri",
|
|
@@ -3585,6 +4388,7 @@ const COMMAND_ADDONS = new Set([
|
|
|
3585
4388
|
"wxt",
|
|
3586
4389
|
"msw",
|
|
3587
4390
|
"storybook",
|
|
4391
|
+
"swr",
|
|
3588
4392
|
"tanstack-query",
|
|
3589
4393
|
"tanstack-table",
|
|
3590
4394
|
"tanstack-virtual",
|
|
@@ -3712,6 +4516,13 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
|
|
|
3712
4516
|
observability: stack.observability,
|
|
3713
4517
|
featureFlags: stack.featureFlags,
|
|
3714
4518
|
analytics: stack.analytics,
|
|
4519
|
+
mobileNavigation: stack.mobileNavigation,
|
|
4520
|
+
mobileUI: stack.mobileUI,
|
|
4521
|
+
mobileStorage: stack.mobileStorage,
|
|
4522
|
+
mobileTesting: stack.mobileTesting,
|
|
4523
|
+
mobilePush: stack.mobilePush,
|
|
4524
|
+
mobileOTA: stack.mobileOTA,
|
|
4525
|
+
mobileDeepLinking: stack.mobileDeepLinking,
|
|
3715
4526
|
cms: stack.cms,
|
|
3716
4527
|
caching: stack.caching,
|
|
3717
4528
|
i18n: stack.i18n,
|
|
@@ -3748,6 +4559,21 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
|
|
|
3748
4559
|
javaAuth: stack.javaAuth,
|
|
3749
4560
|
javaLibraries: toUniqueNonNoneArray(stack.javaLibraries),
|
|
3750
4561
|
javaTestingLibraries: toUniqueNonNoneArray(stack.javaTestingLibraries),
|
|
4562
|
+
elixirWebFramework: stack.elixirWebFramework,
|
|
4563
|
+
elixirOrm: stack.elixirOrm,
|
|
4564
|
+
elixirAuth: stack.elixirAuth,
|
|
4565
|
+
elixirApi: stack.elixirApi,
|
|
4566
|
+
elixirRealtime: stack.elixirRealtime,
|
|
4567
|
+
elixirJobs: stack.elixirJobs,
|
|
4568
|
+
elixirValidation: stack.elixirValidation,
|
|
4569
|
+
elixirHttp: stack.elixirHttp,
|
|
4570
|
+
elixirJson: stack.elixirJson,
|
|
4571
|
+
elixirEmail: stack.elixirEmail,
|
|
4572
|
+
elixirCaching: stack.elixirCaching,
|
|
4573
|
+
elixirObservability: stack.elixirObservability,
|
|
4574
|
+
elixirTesting: stack.elixirTesting,
|
|
4575
|
+
elixirQuality: stack.elixirQuality,
|
|
4576
|
+
elixirDeploy: stack.elixirDeploy,
|
|
3751
4577
|
aiDocs: toUniqueNonNoneArray(stack.aiDocs)
|
|
3752
4578
|
};
|
|
3753
4579
|
}
|
|
@@ -3769,11 +4595,13 @@ function isCliDefaultStackSelection(selection, projectName = getProjectName(sele
|
|
|
3769
4595
|
projectName,
|
|
3770
4596
|
relativePath: projectName
|
|
3771
4597
|
};
|
|
3772
|
-
const ignoredKeys = selection.ecosystem === "typescript" ? new Set([
|
|
4598
|
+
const ignoredKeys = selection.ecosystem === "typescript" || selection.ecosystem === "react-native" ? new Set([
|
|
3773
4599
|
...RUST_CONFIG_KEYS,
|
|
3774
4600
|
...PYTHON_CONFIG_KEYS,
|
|
3775
4601
|
...GO_CONFIG_KEYS,
|
|
3776
|
-
...JAVA_CONFIG_KEYS
|
|
4602
|
+
...JAVA_CONFIG_KEYS,
|
|
4603
|
+
...ELIXIR_CONFIG_KEYS,
|
|
4604
|
+
...selection.ecosystem === "typescript" ? REACT_NATIVE_CONFIG_KEYS : []
|
|
3777
4605
|
]) : /* @__PURE__ */ new Set();
|
|
3778
4606
|
return Object.keys(cliDefaults).every((key) => {
|
|
3779
4607
|
if (ignoredKeys.has(key)) return true;
|
|
@@ -3845,6 +4673,26 @@ function generateTypeScriptCommand(selection, projectName) {
|
|
|
3845
4673
|
if (selection.yolo === "true") flags.push("--yolo");
|
|
3846
4674
|
return `${base} ${projectName} ${flags.join(" ")}`;
|
|
3847
4675
|
}
|
|
4676
|
+
function generateReactNativeCommand(selection, projectName) {
|
|
4677
|
+
const flags = [
|
|
4678
|
+
"--ecosystem react-native",
|
|
4679
|
+
`--frontend ${selection.nativeFrontend.filter((value, _, values) => value !== "none" || values.length === 1).join(" ") || "native-bare"}`,
|
|
4680
|
+
`--auth ${selection.auth}`,
|
|
4681
|
+
`--mobile-navigation ${selection.mobileNavigation}`,
|
|
4682
|
+
`--mobile-ui ${selection.mobileUI}`,
|
|
4683
|
+
`--mobile-storage ${selection.mobileStorage}`,
|
|
4684
|
+
`--mobile-testing ${selection.mobileTesting}`,
|
|
4685
|
+
`--mobile-push ${selection.mobilePush}`,
|
|
4686
|
+
`--mobile-ota ${selection.mobileOTA}`,
|
|
4687
|
+
`--mobile-deep-linking ${selection.mobileDeepLinking}`,
|
|
4688
|
+
`--package-manager ${selection.packageManager}`,
|
|
4689
|
+
selection.git === "false" ? "--no-git" : "--git",
|
|
4690
|
+
selection.install === "false" ? "--no-install" : "--install",
|
|
4691
|
+
formatArrayFlag("ai-docs", selection.aiDocs)
|
|
4692
|
+
];
|
|
4693
|
+
if (selection.yolo === "true") flags.push("--yolo");
|
|
4694
|
+
return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
|
|
4695
|
+
}
|
|
3848
4696
|
function generateRustCommand(selection, projectName) {
|
|
3849
4697
|
const flags = [
|
|
3850
4698
|
"--ecosystem rust",
|
|
@@ -3929,13 +4777,39 @@ function generateJavaCommand(selection, projectName) {
|
|
|
3929
4777
|
if (selection.install === "false") flags.push("--no-install");
|
|
3930
4778
|
return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
|
|
3931
4779
|
}
|
|
4780
|
+
function generateElixirCommand(selection, projectName) {
|
|
4781
|
+
const flags = [
|
|
4782
|
+
"--ecosystem elixir",
|
|
4783
|
+
`--elixir-web-framework ${selection.elixirWebFramework}`,
|
|
4784
|
+
`--elixir-orm ${selection.elixirOrm}`,
|
|
4785
|
+
`--elixir-auth ${selection.elixirAuth}`,
|
|
4786
|
+
`--elixir-api ${selection.elixirApi}`,
|
|
4787
|
+
`--elixir-realtime ${selection.elixirRealtime}`,
|
|
4788
|
+
`--elixir-jobs ${selection.elixirJobs}`,
|
|
4789
|
+
`--elixir-validation ${selection.elixirValidation}`,
|
|
4790
|
+
`--elixir-http ${selection.elixirHttp}`,
|
|
4791
|
+
`--elixir-json ${selection.elixirJson}`,
|
|
4792
|
+
`--elixir-email ${selection.elixirEmail}`,
|
|
4793
|
+
`--elixir-caching ${selection.elixirCaching}`,
|
|
4794
|
+
`--elixir-observability ${selection.elixirObservability}`,
|
|
4795
|
+
`--elixir-testing ${selection.elixirTesting}`,
|
|
4796
|
+
`--elixir-quality ${selection.elixirQuality}`,
|
|
4797
|
+
`--elixir-deploy ${selection.elixirDeploy}`,
|
|
4798
|
+
formatArrayFlag("ai-docs", selection.aiDocs)
|
|
4799
|
+
];
|
|
4800
|
+
if (selection.git === "false") flags.push("--no-git");
|
|
4801
|
+
if (selection.install === "false") flags.push("--no-install");
|
|
4802
|
+
return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
|
|
4803
|
+
}
|
|
3932
4804
|
function generateStackSelectionCommand(selection) {
|
|
3933
4805
|
const projectName = getProjectName(selection);
|
|
3934
4806
|
switch (selection.ecosystem) {
|
|
4807
|
+
case "react-native": return generateReactNativeCommand(selection, projectName);
|
|
3935
4808
|
case "rust": return generateRustCommand(selection, projectName);
|
|
3936
4809
|
case "python": return generatePythonCommand(selection, projectName);
|
|
3937
4810
|
case "go": return generateGoCommand(selection, projectName);
|
|
3938
4811
|
case "java": return generateJavaCommand(selection, projectName);
|
|
4812
|
+
case "elixir": return generateElixirCommand(selection, projectName);
|
|
3939
4813
|
case "typescript":
|
|
3940
4814
|
default: return generateTypeScriptCommand(selection, projectName);
|
|
3941
4815
|
}
|
|
@@ -3943,4 +4817,4 @@ function generateStackSelectionCommand(selection) {
|
|
|
3943
4817
|
|
|
3944
4818
|
//#endregion
|
|
3945
4819
|
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-
|
|
4820
|
+
//# sourceMappingURL=stack-translation-BpsvxDrw.mjs.map
|