@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.
- package/dist/{defaults-Ra4H-o6R.d.mts → defaults-CFAJhN--.d.mts} +2 -2
- package/dist/defaults-CFAJhN--.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 +2938 -316
- 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-B2DBDBdl.mjs → schemas-BHCZL3uR.mjs} +195 -4
- package/dist/schemas-BHCZL3uR.mjs.map +1 -0
- package/dist/{schemas-CC-_Vkoh.d.mts → schemas-Bs_n2xLj.d.mts} +2405 -45
- package/dist/schemas-Bs_n2xLj.d.mts.map +1 -0
- package/dist/schemas.d.mts +2 -2
- package/dist/schemas.mjs +2 -2
- package/dist/{stack-translation-Bag2NJRD.mjs → stack-translation-_uOX-Io0.mjs} +848 -21
- package/dist/stack-translation-_uOX-Io0.mjs.map +1 -0
- package/dist/{stack-translation-B8OgQLwv.d.mts → stack-translation-xj8JvbAI.d.mts} +50 -6
- package/dist/stack-translation-xj8JvbAI.d.mts.map +1 -0
- package/dist/stack-translation.d.mts +4 -4
- package/dist/stack-translation.mjs +2 -2
- package/dist/types-DwFVhx5c.d.mts +119 -0
- package/dist/types-DwFVhx5c.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-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
|
-
|
|
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-
|
|
4773
|
+
//# sourceMappingURL=stack-translation-_uOX-Io0.mjs.map
|