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