@better-fullstack/types 1.4.6 → 1.4.7

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/index.mjs CHANGED
@@ -1,5 +1,197 @@
1
- import { $ as FrontendSchema, $t as SEARCH_VALUES, A as DATABASE_SETUP_VALUES, At as ProjectNameSchema, B as EcosystemSchema, Bt as RUST_CLI_VALUES, C as CLIInputSchema, Cn as UILibrarySchema, Ct as PYTHON_QUALITY_VALUES, D as CSS_FRAMEWORK_VALUES, Dn as WEB_DEPLOY_VALUES, Dt as PackageManagerSchema, E as CSSFrameworkSchema, En as ValidationSchema, Et as PYTHON_WEB_FRAMEWORK_VALUES, F as DirectoryConflictSchema, Ft as PythonValidationSchema, G as FILE_STORAGE_VALUES, Gt as RealtimeSchema, H as EmailSchema, Ht as RUST_LIBRARIES_VALUES, I as ECOSYSTEM_VALUES, It as PythonWebFrameworkSchema, J as FRONTEND_VALUES, Jt as RustCliSchema, K as FILE_UPLOAD_VALUES, Kt as RuntimeSchema, L as EFFECT_VALUES, Lt as REALTIME_VALUES, M as DIRECTORY_CONFLICT_VALUES, Mt as PythonOrmSchema, N as DatabaseSchema, Nt as PythonQualitySchema, O as CachingSchema, On as WebDeploySchema, Ot as PaymentsSchema, P as DatabaseSetupSchema, Pt as PythonTaskQueueSchema, Q as FormsSchema, Qt as RustWebFrameworkSchema, R as EMAIL_VALUES, Rt as RUNTIME_VALUES, S as CACHING_VALUES, Sn as TestingSchema, St as PYTHON_ORM_VALUES, T as CMS_VALUES, Tn as VALIDATION_VALUES, Tt as PYTHON_VALIDATION_VALUES, U as ExamplesSchema, Ut as RUST_ORM_VALUES, V as EffectSchema, Vt as RUST_FRONTEND_VALUES, W as FEATURE_FLAGS_VALUES, Wt as RUST_WEB_FRAMEWORK_VALUES, X as FileStorageSchema, Xt as RustLibrariesSchema, Y as FeatureFlagsSchema, Yt as RustFrontendSchema, Z as FileUploadSchema, Zt as RustOrmSchema, _ as AuthSchema, _n as ShadcnStyleSchema, _t as ORM_VALUES, a as ANALYTICS_VALUES, an as SHADCN_ICON_LIBRARY_VALUES, at as GoApiSchema, b as BetterTStackConfigFileSchema, bn as TESTING_VALUES, bt as PAYMENTS_VALUES, c as API_VALUES, cn as STATE_MANAGEMENT_VALUES, ct as GoOrmSchema, d as AddInputSchema, dn as ShadcnBaseColorSchema, dt as JOB_QUEUE_VALUES, en as SERVER_DEPLOY_VALUES, et as GO_API_VALUES, f as AddonsSchema, fn as ShadcnBaseSchema, ft as JobQueueSchema, g as AstroIntegrationSchema, gn as ShadcnRadiusSchema, gt as ORMSchema, h as AnimationSchema, hn as ShadcnIconLibrarySchema, ht as OBSERVABILITY_VALUES, i as AI_VALUES, in as SHADCN_FONT_VALUES, it as GO_WEB_FRAMEWORK_VALUES, j as DATABASE_VALUES, jt as PythonAiSchema, k as CreateInputSchema, kt as ProjectConfigSchema, l as ASTRO_INTEGRATION_VALUES, ln as SearchSchema, lt as GoWebFrameworkSchema, m as AnalyticsSchema, mn as ShadcnFontSchema, mt as LoggingSchema, n as AISchema, nn as SHADCN_BASE_VALUES, nt as GO_LOGGING_VALUES, o as ANIMATION_VALUES, on as SHADCN_RADIUS_VALUES, ot as GoCliSchema, p as AiDocsSchema, pn as ShadcnColorThemeSchema, pt as LOGGING_VALUES, q as FORMS_VALUES, qt as RustApiSchema, r as AI_DOCS_VALUES, rn as SHADCN_COLOR_THEME_VALUES, rt as GO_ORM_VALUES, s as APISchema, sn as SHADCN_STYLE_VALUES, st as GoLoggingSchema, t as ADDONS_VALUES, tn as SHADCN_BASE_COLOR_VALUES, tt as GO_CLI_VALUES, u as AUTH_VALUES, un as ServerDeploySchema, ut as InitResultSchema, v as BACKEND_VALUES, vn as StateManagementSchema, vt as ObservabilitySchema, w as CMSSchema, wn as UI_LIBRARY_VALUES, wt as PYTHON_TASK_QUEUE_VALUES, x as BetterTStackConfigSchema, xn as TemplateSchema, xt as PYTHON_AI_VALUES, y as BackendSchema, yn as TEMPLATE_VALUES, yt as PACKAGE_MANAGER_VALUES, z as EXAMPLES_VALUES, zt as RUST_API_VALUES } from "./schemas-CeI8AFSL.mjs";
1
+ import { $ as FrontendSchema, $t as SEARCH_VALUES, A as DATABASE_SETUP_VALUES, At as ProjectNameSchema, B as EcosystemSchema, Bt as RUST_CLI_VALUES, C as CLIInputSchema, Cn as UILibrarySchema, Ct as PYTHON_QUALITY_VALUES, D as CSS_FRAMEWORK_VALUES, Dn as WEB_DEPLOY_VALUES, Dt as PackageManagerSchema, E as CSSFrameworkSchema, En as ValidationSchema, Et as PYTHON_WEB_FRAMEWORK_VALUES, F as DirectoryConflictSchema, Ft as PythonValidationSchema, G as FILE_STORAGE_VALUES, Gt as RealtimeSchema, H as EmailSchema, Ht as RUST_LIBRARIES_VALUES, I as ECOSYSTEM_VALUES, It as PythonWebFrameworkSchema, J as FRONTEND_VALUES, Jt as RustCliSchema, K as FILE_UPLOAD_VALUES, Kt as RuntimeSchema, L as EFFECT_VALUES, Lt as REALTIME_VALUES, M as DIRECTORY_CONFLICT_VALUES, Mt as PythonOrmSchema, N as DatabaseSchema, Nt as PythonQualitySchema, O as CachingSchema, On as WebDeploySchema, Ot as PaymentsSchema, P as DatabaseSetupSchema, Pt as PythonTaskQueueSchema, Q as FormsSchema, Qt as RustWebFrameworkSchema, R as EMAIL_VALUES, Rt as RUNTIME_VALUES, S as CACHING_VALUES, Sn as TestingSchema, St as PYTHON_ORM_VALUES, T as CMS_VALUES, Tn as VALIDATION_VALUES, Tt as PYTHON_VALIDATION_VALUES, U as ExamplesSchema, Ut as RUST_ORM_VALUES, V as EffectSchema, Vt as RUST_FRONTEND_VALUES, W as FEATURE_FLAGS_VALUES, Wt as RUST_WEB_FRAMEWORK_VALUES, X as FileStorageSchema, Xt as RustLibrariesSchema, Y as FeatureFlagsSchema, Yt as RustFrontendSchema, Z as FileUploadSchema, Zt as RustOrmSchema, _ as AuthSchema, _n as ShadcnStyleSchema, _t as ORM_VALUES, a as ANALYTICS_VALUES, an as SHADCN_ICON_LIBRARY_VALUES, at as GoApiSchema, b as BetterTStackConfigFileSchema, bn as TESTING_VALUES, bt as PAYMENTS_VALUES, c as API_VALUES, cn as STATE_MANAGEMENT_VALUES, ct as GoOrmSchema, d as AddInputSchema, dn as ShadcnBaseColorSchema, dt as JOB_QUEUE_VALUES, en as SERVER_DEPLOY_VALUES, et as GO_API_VALUES, f as AddonsSchema, fn as ShadcnBaseSchema, ft as JobQueueSchema, g as AstroIntegrationSchema, gn as ShadcnRadiusSchema, gt as ORMSchema, h as AnimationSchema, hn as ShadcnIconLibrarySchema, ht as OBSERVABILITY_VALUES, i as AI_VALUES, in as SHADCN_FONT_VALUES, it as GO_WEB_FRAMEWORK_VALUES, j as DATABASE_VALUES, jt as PythonAiSchema, k as CreateInputSchema, kt as ProjectConfigSchema, l as ASTRO_INTEGRATION_VALUES, ln as SearchSchema, lt as GoWebFrameworkSchema, m as AnalyticsSchema, mn as ShadcnFontSchema, mt as LoggingSchema, n as AISchema, nn as SHADCN_BASE_VALUES, nt as GO_LOGGING_VALUES, o as ANIMATION_VALUES, on as SHADCN_RADIUS_VALUES, ot as GoCliSchema, p as AiDocsSchema, pn as ShadcnColorThemeSchema, pt as LOGGING_VALUES, q as FORMS_VALUES, qt as RustApiSchema, r as AI_DOCS_VALUES, rn as SHADCN_COLOR_THEME_VALUES, rt as GO_ORM_VALUES, s as APISchema, sn as SHADCN_STYLE_VALUES, st as GoLoggingSchema, t as ADDONS_VALUES, tn as SHADCN_BASE_COLOR_VALUES, tt as GO_CLI_VALUES, u as AUTH_VALUES, un as ServerDeploySchema, ut as InitResultSchema, v as BACKEND_VALUES, vn as StateManagementSchema, vt as ObservabilitySchema, w as CMSSchema, wn as UI_LIBRARY_VALUES, wt as PYTHON_TASK_QUEUE_VALUES, x as BetterTStackConfigSchema, xn as TemplateSchema, xt as PYTHON_AI_VALUES, y as BackendSchema, yn as TEMPLATE_VALUES, yt as PACKAGE_MANAGER_VALUES, z as EXAMPLES_VALUES, zt as RUST_API_VALUES } from "./schemas-CdFUciyW.mjs";
2
2
 
3
+ //#region src/capabilities.ts
4
+ const CAPABILITY_DEFINITIONS = { auth: [
5
+ {
6
+ id: "better-auth",
7
+ label: "Better-Auth",
8
+ description: "The most comprehensive authentication framework for TypeScript",
9
+ promptHint: "comprehensive auth framework for TypeScript",
10
+ icon: "/icon/better-auth.svg",
11
+ color: "from-green-400 to-green-600",
12
+ default: true
13
+ },
14
+ {
15
+ id: "go-better-auth",
16
+ label: "GoBetterAuth",
17
+ description: "Embedded auth routes for Go applications",
18
+ promptHint: "embedded auth routes for Go applications",
19
+ icon: "https://cdn.simpleicons.org/go/00ADD8",
20
+ color: "from-cyan-400 to-sky-600"
21
+ },
22
+ {
23
+ id: "clerk",
24
+ label: "Clerk",
25
+ description: "More than authentication, Complete User Management",
26
+ promptHint: "More than auth, Complete User Management",
27
+ icon: "https://cdn.simpleicons.org/clerk/6C47FF",
28
+ color: "from-blue-400 to-blue-600"
29
+ },
30
+ {
31
+ id: "nextauth",
32
+ label: "Auth.js (NextAuth)",
33
+ description: "Open source authentication for Next.js",
34
+ promptHint: "Authentication for Next.js (formerly NextAuth.js)",
35
+ icon: "/icon/nextauth.png",
36
+ color: "from-orange-400 to-orange-600"
37
+ },
38
+ {
39
+ id: "stack-auth",
40
+ label: "Stack Auth",
41
+ description: "Open-source Auth0/Clerk alternative with user management",
42
+ promptHint: "Open-source Auth0/Clerk alternative",
43
+ icon: "/icon/stack-auth.svg",
44
+ color: "from-purple-400 to-purple-600"
45
+ },
46
+ {
47
+ id: "supabase-auth",
48
+ label: "Supabase Auth",
49
+ description: "Open-source Auth with Supabase platform integration",
50
+ promptHint: "Auth with Supabase platform integration",
51
+ icon: "https://cdn.simpleicons.org/supabase/3FCF8E",
52
+ color: "from-emerald-400 to-emerald-600"
53
+ },
54
+ {
55
+ id: "auth0",
56
+ label: "Auth0",
57
+ description: "Flexible identity platform for authentication and authorization",
58
+ promptHint: "Flexible identity platform for authentication",
59
+ icon: "https://cdn.simpleicons.org/auth0/EB5424",
60
+ color: "from-orange-400 to-orange-600"
61
+ },
62
+ {
63
+ id: "none",
64
+ label: "No Auth",
65
+ description: "Skip authentication",
66
+ promptHint: "No authentication",
67
+ icon: "",
68
+ color: "from-red-400 to-red-600"
69
+ }
70
+ ] };
71
+ const NATIVE_FRONTENDS = new Set([
72
+ "native-bare",
73
+ "native-uniwind",
74
+ "native-unistyles"
75
+ ]);
76
+ const CONVEX_BETTER_AUTH_WEB = new Set([
77
+ "tanstack-router",
78
+ "tanstack-start",
79
+ "next"
80
+ ]);
81
+ const CONVEX_CLERK_WEB = new Set([
82
+ "react-router",
83
+ "tanstack-router",
84
+ "tanstack-start",
85
+ "next"
86
+ ]);
87
+ function capitalizeFirst(value) {
88
+ return value.charAt(0).toUpperCase() + value.slice(1);
89
+ }
90
+ function dedupe(values) {
91
+ return [...new Set(values)];
92
+ }
93
+ function getFrontendSets(context) {
94
+ if (context.frontend) {
95
+ const webFrontend = context.frontend.filter((frontend) => !NATIVE_FRONTENDS.has(frontend));
96
+ const nativeFrontend = context.frontend.filter((frontend) => NATIVE_FRONTENDS.has(frontend));
97
+ return {
98
+ webFrontend: dedupe(webFrontend),
99
+ nativeFrontend: dedupe(nativeFrontend)
100
+ };
101
+ }
102
+ return {
103
+ webFrontend: dedupe(context.webFrontend ?? []),
104
+ nativeFrontend: dedupe(context.nativeFrontend ?? [])
105
+ };
106
+ }
107
+ function isSelfBackend(backend) {
108
+ return backend === "self" || backend?.startsWith("self-") === true;
109
+ }
110
+ function getNextOnlyAuthLabel(optionId) {
111
+ switch (optionId) {
112
+ case "nextauth": return "Auth.js (NextAuth)";
113
+ case "stack-auth": return "Stack Auth";
114
+ case "supabase-auth": return "Supabase Auth";
115
+ case "auth0": return "Auth0";
116
+ default: {
117
+ const _exhaustive = optionId;
118
+ return String(_exhaustive);
119
+ }
120
+ }
121
+ }
122
+ function getAuthDisabledReason(context, optionId) {
123
+ if (optionId === "none") return null;
124
+ const ecosystem = context.ecosystem ?? "typescript";
125
+ const backend = context.backend;
126
+ const { webFrontend, nativeFrontend } = getFrontendSets(context);
127
+ const hasNextJs = webFrontend.includes("next");
128
+ const hasTanStackStart = webFrontend.includes("tanstack-start");
129
+ const hasNativeFrontend = nativeFrontend.some((frontend) => frontend !== "none");
130
+ if (optionId === "go-better-auth") return ecosystem === "go" ? null : "GoBetterAuth is available only for Go stacks";
131
+ if (ecosystem === "go") return "Go stacks currently support GoBetterAuth only";
132
+ if (ecosystem !== "typescript") return `${capitalizeFirst(ecosystem)} stacks do not support auth integrations yet`;
133
+ if (backend === "none") return "No backend selected";
134
+ if (optionId === "better-auth") {
135
+ if (backend === "convex") {
136
+ if (!(webFrontend.some((frontend) => CONVEX_BETTER_AUTH_WEB.has(frontend)) || nativeFrontend.some((frontend) => NATIVE_FRONTENDS.has(frontend)))) return "Better-Auth with Convex requires TanStack Router, TanStack Start, Next.js, or React Native";
137
+ }
138
+ return null;
139
+ }
140
+ if (optionId === "clerk") {
141
+ if (backend === "convex") {
142
+ if (!(webFrontend.some((frontend) => CONVEX_CLERK_WEB.has(frontend)) || nativeFrontend.some((frontend) => NATIVE_FRONTENDS.has(frontend)))) return "Clerk with Convex requires React Router, TanStack Router, TanStack Start, Next.js, or React Native";
143
+ return null;
144
+ }
145
+ if (isSelfBackend(backend)) {
146
+ if ((hasNextJs || hasTanStackStart) && hasNativeFrontend) return "In Better-Fullstack, Clerk with self backend is currently supported only for web-only Next.js or TanStack Start projects (no native companion app)";
147
+ if (hasNextJs || hasTanStackStart) return null;
148
+ if (backend === "self-astro" || webFrontend.includes("astro")) return "In Better-Fullstack, Clerk is not yet supported for Astro fullstack projects";
149
+ if (backend === "self-nuxt" || webFrontend.includes("nuxt")) return "In Better-Fullstack, Clerk is not yet supported for Nuxt fullstack projects";
150
+ if (backend === "self-svelte" || webFrontend.includes("svelte")) return "In Better-Fullstack, Clerk is not yet supported for SvelteKit fullstack projects";
151
+ if (backend === "self-solid-start" || webFrontend.includes("solid-start")) return "In Better-Fullstack, Clerk is not yet supported for SolidStart fullstack projects";
152
+ return "In Better-Fullstack, Clerk is currently supported with Convex, Next.js fullstack, or TanStack Start fullstack";
153
+ }
154
+ return "In Better-Fullstack, Clerk is currently supported with Convex, Next.js fullstack, or TanStack Start fullstack";
155
+ }
156
+ const nextOnlyLabel = getNextOnlyAuthLabel(optionId);
157
+ if (backend !== "self" && backend !== "self-next") return `In Better-Fullstack, ${nextOnlyLabel} is currently supported only with the 'self' backend (fullstack Next.js)`;
158
+ if (!hasNextJs) return `In Better-Fullstack, ${nextOnlyLabel} currently requires the Next.js frontend`;
159
+ return null;
160
+ }
161
+ function getCapabilityDefinitions(capability) {
162
+ return CAPABILITY_DEFINITIONS[capability];
163
+ }
164
+ function getCapabilityDisabledReason(capability, context, optionId) {
165
+ if (capability === "auth") return getAuthDisabledReason(context, optionId);
166
+ return null;
167
+ }
168
+ function getSupportedCapabilityOptions(capability, context) {
169
+ return getCapabilityDefinitions(capability).filter((definition) => getCapabilityDisabledReason(capability, context, definition.id) === null);
170
+ }
171
+ function normalizeCapabilitySelection(capability, context, optionId) {
172
+ const fallbackValue = "none";
173
+ if (!optionId || optionId === fallbackValue) return {
174
+ value: optionId ?? fallbackValue,
175
+ normalized: false,
176
+ reason: null,
177
+ message: null
178
+ };
179
+ const reason = getCapabilityDisabledReason(capability, context, optionId);
180
+ if (!reason) return {
181
+ value: optionId,
182
+ normalized: false,
183
+ reason: null,
184
+ message: null
185
+ };
186
+ return {
187
+ value: fallbackValue,
188
+ normalized: true,
189
+ reason,
190
+ message: `${capitalizeFirst(capability)} set to 'None' (${reason})`
191
+ };
192
+ }
193
+
194
+ //#endregion
3
195
  //#region src/compatibility.ts
4
196
  const CATEGORY_ORDER = [
5
197
  ...[
@@ -222,57 +414,21 @@ const analyzeStackCompatibility = (stack) => {
222
414
  });
223
415
  }
224
416
  }
225
- if (nextStack.auth === "clerk") {
226
- if (!(nextStack.webFrontend.some((f) => [
227
- "tanstack-router",
228
- "react-router",
229
- "tanstack-start",
230
- "next"
231
- ].includes(f)) || nextStack.nativeFrontend.some((f) => [
232
- "native-bare",
233
- "native-uniwind",
234
- "native-unistyles"
235
- ].includes(f)))) {
236
- nextStack.auth = "none";
237
- changed = true;
238
- changes.push({
239
- category: "auth",
240
- message: "Auth set to 'None' (Clerk requires compatible frontend)"
241
- });
242
- }
243
- }
244
- if (nextStack.auth === "better-auth") {
245
- if (!(nextStack.webFrontend.some((f) => [
246
- "tanstack-router",
247
- "tanstack-start",
248
- "next"
249
- ].includes(f)) || nextStack.nativeFrontend.some((f) => [
250
- "native-bare",
251
- "native-uniwind",
252
- "native-unistyles"
253
- ].includes(f)))) {
254
- nextStack.auth = "none";
255
- changed = true;
256
- changes.push({
257
- category: "auth",
258
- message: "Auth set to 'None' (Better-Auth with Convex requires compatible frontend)"
259
- });
260
- }
261
- }
262
417
  }
263
418
  if (nextStack.backend === "none") {
264
- for (const [key, value] of Object.entries({
419
+ const noneOverrides = {
265
420
  runtime: "none",
266
421
  database: "none",
267
422
  orm: "none",
268
423
  api: "none",
269
- auth: "none",
270
424
  dbSetup: "none",
271
425
  serverDeploy: "none",
272
426
  payments: "none",
273
427
  search: "none",
274
428
  fileStorage: "none"
275
- })) {
429
+ };
430
+ if (nextStack.ecosystem !== "go") noneOverrides.auth = "none";
431
+ for (const [key, value] of Object.entries(noneOverrides)) {
276
432
  const catKey = key;
277
433
  if (nextStack[catKey] !== value) {
278
434
  nextStack[catKey] = value;
@@ -595,22 +751,19 @@ const analyzeStackCompatibility = (stack) => {
595
751
  });
596
752
  }
597
753
  }
598
- if (nextStack.auth === "clerk") {
599
- if (!(nextStack.backend === "convex" || nextStack.backend === "self-next" || nextStack.backend === "self-tanstack-start")) {
600
- nextStack.auth = "none";
601
- changed = true;
602
- changes.push({
603
- category: "auth",
604
- message: "Auth set to 'None' (Better-Fullstack currently supports Clerk with Convex, Next.js fullstack, or TanStack Start fullstack)"
605
- });
606
- } else if ((nextStack.backend === "self-next" || nextStack.backend === "self-tanstack-start") && nextStack.nativeFrontend.some((f) => f !== "none")) {
607
- nextStack.auth = "none";
608
- changed = true;
609
- changes.push({
610
- category: "auth",
611
- message: "Auth set to 'None' (Better-Fullstack currently supports Clerk with self backend only for web-only Next.js/TanStack Start projects)"
612
- });
613
- }
754
+ const normalizedAuth = normalizeCapabilitySelection("auth", {
755
+ ecosystem: nextStack.ecosystem,
756
+ backend: nextStack.backend,
757
+ webFrontend: nextStack.webFrontend,
758
+ nativeFrontend: nextStack.nativeFrontend
759
+ }, nextStack.auth);
760
+ if (normalizedAuth.normalized && nextStack.auth !== normalizedAuth.value) {
761
+ nextStack.auth = normalizedAuth.value;
762
+ changed = true;
763
+ changes.push({
764
+ category: "auth",
765
+ message: normalizedAuth.message ?? "Auth set to 'None'"
766
+ });
614
767
  }
615
768
  if (nextStack.payments === "polar") {
616
769
  if (nextStack.auth !== "better-auth") {
@@ -895,17 +1048,6 @@ const getDisabledReason = (currentStack, category, optionId) => {
895
1048
  if (category === "serverDeploy" && optionId !== "none") return "Convex has its own deployment";
896
1049
  if (category === "search" && optionId !== "none") return "Search requires a standalone backend";
897
1050
  if (category === "fileStorage" && optionId !== "none") return "File storage requires a standalone backend";
898
- if (category === "auth" && optionId === "better-auth") {
899
- if (!(currentStack.webFrontend.some((f) => [
900
- "tanstack-router",
901
- "tanstack-start",
902
- "next"
903
- ].includes(f)) || currentStack.nativeFrontend.some((f) => [
904
- "native-bare",
905
- "native-uniwind",
906
- "native-unistyles"
907
- ].includes(f)))) return "Better-Auth with Convex requires TanStack Router, TanStack Start, Next.js, or React Native";
908
- }
909
1051
  if (category === "webFrontend" && optionId === "solid") return "In Better-Fullstack, the Convex backend is currently not available with Solid";
910
1052
  if (category === "webFrontend" && optionId === "astro") return "In Better-Fullstack, the Convex backend is currently not available with Astro";
911
1053
  if (category === "examples" && optionId === "ai") {
@@ -926,7 +1068,6 @@ const getDisabledReason = (currentStack, category, optionId) => {
926
1068
  if (category === "database" && optionId !== "none") return "No backend selected";
927
1069
  if (category === "orm" && optionId !== "none") return "No backend selected";
928
1070
  if (category === "api" && optionId !== "none") return "No backend selected";
929
- if (category === "auth" && optionId !== "none") return "No backend selected";
930
1071
  if (category === "dbSetup" && optionId !== "none") return "No backend selected";
931
1072
  if (category === "serverDeploy" && optionId !== "none") return "No backend selected";
932
1073
  if (category === "payments" && optionId !== "none") return "No backend selected";
@@ -1037,27 +1178,12 @@ const getDisabledReason = (currentStack, category, optionId) => {
1037
1178
  if (!currentStack.webFrontend.includes("astro") && optionId !== "none") return "Astro integration requires Astro frontend";
1038
1179
  if (currentStack.api === "trpc" && optionId !== "react" && optionId !== "none") return "tRPC requires React integration with Astro";
1039
1180
  }
1040
- if (category === "auth") {
1041
- if (optionId === "clerk") if (currentStack.backend === "convex") {
1042
- if (!(currentStack.webFrontend.some((f) => [
1043
- "react-router",
1044
- "tanstack-router",
1045
- "tanstack-start",
1046
- "next"
1047
- ].includes(f)) || currentStack.nativeFrontend.some((f) => [
1048
- "native-bare",
1049
- "native-uniwind",
1050
- "native-unistyles"
1051
- ].includes(f)))) return "Clerk with Convex requires React Router, TanStack Router, TanStack Start, Next.js, or React Native";
1052
- } else if (currentStack.backend === "self-next" || currentStack.backend === "self-tanstack-start") {
1053
- if (currentStack.nativeFrontend.some((f) => f !== "none")) return "In Better-Fullstack, Clerk with self backend is currently supported only for web-only Next.js or TanStack Start projects (no native companion app)";
1054
- } else if (currentStack.backend === "self-astro") return "In Better-Fullstack, Clerk is not yet supported for Astro fullstack projects";
1055
- else if (currentStack.backend === "self-nuxt") return "In Better-Fullstack, Clerk is not yet supported for Nuxt fullstack projects";
1056
- else if (currentStack.backend === "self-svelte") return "In Better-Fullstack, Clerk is not yet supported for SvelteKit fullstack projects";
1057
- else if (currentStack.backend === "self-solid-start") return "In Better-Fullstack, Clerk is not yet supported for SolidStart fullstack projects";
1058
- else if (currentStack.backend === "none") return "Clerk requires a backend";
1059
- else return "In Better-Fullstack, Clerk is currently supported with Convex, Next.js fullstack, or TanStack Start fullstack";
1060
- }
1181
+ if (category === "auth") return getCapabilityDisabledReason("auth", {
1182
+ ecosystem: currentStack.ecosystem,
1183
+ backend: currentStack.backend,
1184
+ webFrontend: currentStack.webFrontend,
1185
+ nativeFrontend: currentStack.nativeFrontend
1186
+ }, optionId);
1061
1187
  if (category === "payments" && optionId === "polar") {
1062
1188
  if (currentStack.auth !== "better-auth") return "Polar requires Better Auth";
1063
1189
  if (!currentStack.webFrontend.some((f) => f !== "none")) return "Polar requires a web frontend";
@@ -1478,25 +1604,11 @@ function isFrontendAllowedWithBackend(frontend, backend, auth) {
1478
1604
  if (frontend === "angular" && backend && backend !== "none") return false;
1479
1605
  if (frontend === "redwood" && backend && backend !== "none") return false;
1480
1606
  if (frontend === "fresh" && backend && backend !== "none") return false;
1481
- if (auth === "clerk" && backend === "convex") {
1482
- if ([
1483
- "nuxt",
1484
- "svelte",
1485
- "solid",
1486
- "solid-start"
1487
- ].includes(frontend)) return false;
1488
- }
1489
- if (auth === "clerk" && backend === "self") {
1490
- if (!["next", "tanstack-start"].includes(frontend)) return false;
1491
- }
1492
- if (auth === "nextauth") {
1493
- if (frontend !== "next") return false;
1494
- if (backend !== "self") return false;
1495
- }
1496
- if (auth === "supabase-auth") {
1497
- if (frontend !== "next") return false;
1498
- if (backend !== "self") return false;
1499
- }
1607
+ if (auth && auth !== "none") return getCapabilityDisabledReason("auth", {
1608
+ ecosystem: "typescript",
1609
+ backend,
1610
+ frontend: [frontend]
1611
+ }, auth) === null;
1500
1612
  return true;
1501
1613
  }
1502
1614
  function isExampleAIAllowed(backend, frontends = []) {
@@ -1663,5 +1775,576 @@ function evaluateCompatibility(input) {
1663
1775
  }
1664
1776
 
1665
1777
  //#endregion
1666
- export { ADDONS_VALUES, AISchema, AI_DOCS_VALUES, AI_VALUES, ANALYTICS_VALUES, ANIMATION_VALUES, APISchema, API_VALUES, ASTRO_INTEGRATION_VALUES, AUTH_VALUES, AddInputSchema, AddonsSchema, AiDocsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BACKEND_VALUES, BackendSchema, BetterTStackConfigFileSchema, BetterTStackConfigSchema, CACHING_VALUES, CLIInputSchema, CMSSchema, CMS_VALUES, CSSFrameworkSchema, CSS_FRAMEWORK_VALUES, CachingSchema, CreateInputSchema, DATABASE_SETUP_VALUES, DATABASE_VALUES, DIRECTORY_CONFLICT_VALUES, DatabaseSchema, DatabaseSetupSchema, DirectoryConflictSchema, ECOSYSTEM_VALUES, EFFECT_VALUES, EMAIL_VALUES, EXAMPLES_VALUES, EcosystemSchema, EffectSchema, EmailSchema, ExamplesSchema, FEATURE_FLAGS_VALUES, FILE_STORAGE_VALUES, FILE_UPLOAD_VALUES, FORMS_VALUES, FRONTEND_VALUES, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GO_API_VALUES, GO_CLI_VALUES, GO_LOGGING_VALUES, GO_ORM_VALUES, GO_WEB_FRAMEWORK_VALUES, GoApiSchema, GoCliSchema, GoLoggingSchema, GoOrmSchema, GoWebFrameworkSchema, InitResultSchema, JOB_QUEUE_VALUES, JobQueueSchema, LOGGING_VALUES, LoggingSchema, OBSERVABILITY_VALUES, ORMSchema, ORM_VALUES, ObservabilitySchema, PACKAGE_MANAGER_VALUES, PAYMENTS_VALUES, PYTHON_AI_VALUES, PYTHON_ORM_VALUES, PYTHON_QUALITY_VALUES, PYTHON_TASK_QUEUE_VALUES, PYTHON_VALIDATION_VALUES, PYTHON_WEB_FRAMEWORK_VALUES, PackageManagerSchema, PaymentsSchema, ProjectConfigSchema, ProjectNameSchema, PythonAiSchema, PythonOrmSchema, PythonQualitySchema, PythonTaskQueueSchema, PythonValidationSchema, PythonWebFrameworkSchema, REALTIME_VALUES, RUNTIME_VALUES, RUST_API_VALUES, RUST_CLI_VALUES, RUST_FRONTEND_VALUES, RUST_LIBRARIES_VALUES, RUST_ORM_VALUES, RUST_WEB_FRAMEWORK_VALUES, RealtimeSchema, RuntimeSchema, RustApiSchema, RustCliSchema, RustFrontendSchema, RustLibrariesSchema, RustOrmSchema, RustWebFrameworkSchema, SEARCH_VALUES, SERVER_DEPLOY_VALUES, SHADCN_BASE_COLOR_VALUES, SHADCN_BASE_VALUES, SHADCN_COLOR_THEME_VALUES, SHADCN_FONT_VALUES, SHADCN_ICON_LIBRARY_VALUES, SHADCN_RADIUS_VALUES, SHADCN_STYLE_VALUES, STATE_MANAGEMENT_VALUES, SearchSchema, ServerDeploySchema, ShadcnBaseColorSchema, ShadcnBaseSchema, ShadcnColorThemeSchema, ShadcnFontSchema, ShadcnIconLibrarySchema, ShadcnRadiusSchema, ShadcnStyleSchema, StateManagementSchema, TEMPLATE_VALUES, TESTING_VALUES, TemplateSchema, TestingSchema, UILibrarySchema, UI_LIBRARY_VALUES, VALIDATION_VALUES, ValidationSchema, WEB_DEPLOY_VALUES, WebDeploySchema, allowedApisForFrontends, analyzeStackCompatibility, evaluateCompatibility, getCategoryDisplayName, getCompatibleAddons, getCompatibleCSSFrameworks, getCompatibleFormLibraries, getCompatibleUILibraries, getDisabledReason, hasPWACompatibleFrontend, hasTauriCompatibleFrontend, hasWebStyling, isExampleAIAllowed, isExampleChatSdkAllowed, isFrontendAllowedWithBackend, isOptionCompatible, isWebFrontend, requiresChatSdkVercelAI, requiresChatSdkVercelAIForSelection, splitFrontends, validateAddonCompatibility, validateProjectName };
1778
+ //#region src/option-metadata.ts
1779
+ const WEB_FRONTEND_VALUES = [
1780
+ "tanstack-router",
1781
+ "react-router",
1782
+ "tanstack-start",
1783
+ "next",
1784
+ "nuxt",
1785
+ "svelte",
1786
+ "solid",
1787
+ "solid-start",
1788
+ "astro",
1789
+ "qwik",
1790
+ "angular",
1791
+ "redwood",
1792
+ "fresh",
1793
+ "none"
1794
+ ];
1795
+ const NATIVE_FRONTEND_VALUES = [
1796
+ "native-bare",
1797
+ "native-uniwind",
1798
+ "native-unistyles",
1799
+ "none"
1800
+ ];
1801
+ const BACKEND_BUILDER_VALUES = [
1802
+ "hono",
1803
+ "express",
1804
+ "fastify",
1805
+ "elysia",
1806
+ "fets",
1807
+ "nestjs",
1808
+ "adonisjs",
1809
+ "nitro",
1810
+ "encore",
1811
+ "convex",
1812
+ "self-next",
1813
+ "self-tanstack-start",
1814
+ "self-astro",
1815
+ "self-nuxt",
1816
+ "self-svelte",
1817
+ "self-solid-start",
1818
+ "none"
1819
+ ];
1820
+ const CODE_QUALITY_VALUES = [
1821
+ "biome",
1822
+ "oxlint",
1823
+ "ultracite",
1824
+ "lefthook",
1825
+ "husky",
1826
+ "ruler"
1827
+ ];
1828
+ const DOCUMENTATION_VALUES = ["starlight", "fumadocs"];
1829
+ const APP_PLATFORM_VALUES = [
1830
+ "turborepo",
1831
+ "pwa",
1832
+ "tauri",
1833
+ "wxt",
1834
+ "opentui",
1835
+ "mcp",
1836
+ "skills",
1837
+ "msw",
1838
+ "storybook"
1839
+ ];
1840
+ const EXAMPLE_VALUES = ["ai", "chat-sdk"];
1841
+ const BOOLEAN_OPTION_VALUES = ["true", "false"];
1842
+ const MULTI_SELECT_CATEGORIES = new Set([
1843
+ "webFrontend",
1844
+ "nativeFrontend",
1845
+ "codeQuality",
1846
+ "documentation",
1847
+ "appPlatforms",
1848
+ "examples",
1849
+ "aiDocs"
1850
+ ]);
1851
+ const CATEGORY_VALUE_IDS = {
1852
+ api: API_VALUES,
1853
+ webFrontend: WEB_FRONTEND_VALUES,
1854
+ nativeFrontend: NATIVE_FRONTEND_VALUES,
1855
+ astroIntegration: ASTRO_INTEGRATION_VALUES,
1856
+ runtime: RUNTIME_VALUES,
1857
+ backend: BACKEND_BUILDER_VALUES,
1858
+ database: DATABASE_VALUES,
1859
+ orm: ORM_VALUES,
1860
+ dbSetup: DATABASE_SETUP_VALUES,
1861
+ webDeploy: WEB_DEPLOY_VALUES,
1862
+ serverDeploy: SERVER_DEPLOY_VALUES,
1863
+ auth: AUTH_VALUES,
1864
+ payments: PAYMENTS_VALUES,
1865
+ email: EMAIL_VALUES,
1866
+ fileUpload: FILE_UPLOAD_VALUES,
1867
+ logging: LOGGING_VALUES,
1868
+ observability: OBSERVABILITY_VALUES,
1869
+ backendLibraries: EFFECT_VALUES,
1870
+ stateManagement: STATE_MANAGEMENT_VALUES,
1871
+ forms: FORMS_VALUES,
1872
+ validation: VALIDATION_VALUES,
1873
+ testing: TESTING_VALUES,
1874
+ realtime: REALTIME_VALUES,
1875
+ jobQueue: JOB_QUEUE_VALUES,
1876
+ caching: CACHING_VALUES,
1877
+ search: SEARCH_VALUES,
1878
+ fileStorage: FILE_STORAGE_VALUES,
1879
+ animation: ANIMATION_VALUES,
1880
+ cssFramework: CSS_FRAMEWORK_VALUES,
1881
+ uiLibrary: UI_LIBRARY_VALUES,
1882
+ cms: CMS_VALUES,
1883
+ featureFlags: FEATURE_FLAGS_VALUES,
1884
+ analytics: ANALYTICS_VALUES,
1885
+ codeQuality: CODE_QUALITY_VALUES,
1886
+ documentation: DOCUMENTATION_VALUES,
1887
+ appPlatforms: APP_PLATFORM_VALUES,
1888
+ packageManager: PACKAGE_MANAGER_VALUES,
1889
+ examples: EXAMPLE_VALUES,
1890
+ ai: AI_VALUES,
1891
+ aiDocs: AI_DOCS_VALUES,
1892
+ git: BOOLEAN_OPTION_VALUES,
1893
+ install: BOOLEAN_OPTION_VALUES,
1894
+ effect: EFFECT_VALUES,
1895
+ shadcnBase: SHADCN_BASE_VALUES,
1896
+ shadcnStyle: SHADCN_STYLE_VALUES,
1897
+ shadcnIconLibrary: SHADCN_ICON_LIBRARY_VALUES,
1898
+ shadcnColorTheme: SHADCN_COLOR_THEME_VALUES,
1899
+ shadcnBaseColor: SHADCN_BASE_COLOR_VALUES,
1900
+ shadcnFont: SHADCN_FONT_VALUES,
1901
+ shadcnRadius: SHADCN_RADIUS_VALUES,
1902
+ rustWebFramework: RUST_WEB_FRAMEWORK_VALUES,
1903
+ rustFrontend: RUST_FRONTEND_VALUES,
1904
+ rustOrm: RUST_ORM_VALUES,
1905
+ rustApi: RUST_API_VALUES,
1906
+ rustCli: RUST_CLI_VALUES,
1907
+ rustLibraries: RUST_LIBRARIES_VALUES,
1908
+ pythonWebFramework: PYTHON_WEB_FRAMEWORK_VALUES,
1909
+ pythonOrm: PYTHON_ORM_VALUES,
1910
+ pythonValidation: PYTHON_VALIDATION_VALUES,
1911
+ pythonAi: PYTHON_AI_VALUES,
1912
+ pythonTaskQueue: PYTHON_TASK_QUEUE_VALUES,
1913
+ pythonQuality: PYTHON_QUALITY_VALUES,
1914
+ goWebFramework: GO_WEB_FRAMEWORK_VALUES,
1915
+ goOrm: GO_ORM_VALUES,
1916
+ goApi: GO_API_VALUES,
1917
+ goCli: GO_CLI_VALUES,
1918
+ goLogging: GO_LOGGING_VALUES
1919
+ };
1920
+ const EXACT_LABEL_OVERRIDES = {
1921
+ api: {
1922
+ trpc: "tRPC",
1923
+ orpc: "oRPC"
1924
+ },
1925
+ webFrontend: {
1926
+ next: "Next.js",
1927
+ svelte: "SvelteKit",
1928
+ redwood: "RedwoodJS"
1929
+ },
1930
+ nativeFrontend: {
1931
+ "native-bare": "Expo + Bare",
1932
+ "native-uniwind": "Expo + Uniwind",
1933
+ "native-unistyles": "Expo + Unistyles"
1934
+ },
1935
+ runtime: {
1936
+ node: "Node.js",
1937
+ workers: "Cloudflare Workers"
1938
+ },
1939
+ backend: {
1940
+ fets: "feTS",
1941
+ nestjs: "NestJS",
1942
+ encore: "Encore.ts",
1943
+ "self-next": "Fullstack Next.js",
1944
+ "self-tanstack-start": "Fullstack TanStack Start",
1945
+ "self-astro": "Fullstack Astro",
1946
+ "self-nuxt": "Fullstack Nuxt",
1947
+ "self-svelte": "Fullstack SvelteKit",
1948
+ "self-solid-start": "Fullstack SolidStart"
1949
+ },
1950
+ database: {
1951
+ sqlite: "SQLite",
1952
+ postgres: "PostgreSQL",
1953
+ mongodb: "MongoDB",
1954
+ edgedb: "EdgeDB"
1955
+ },
1956
+ orm: {
1957
+ typeorm: "TypeORM",
1958
+ mikroorm: "MikroORM"
1959
+ },
1960
+ dbSetup: {
1961
+ d1: "Cloudflare D1",
1962
+ neon: "Neon Postgres",
1963
+ "prisma-postgres": "Prisma PostgreSQL",
1964
+ "mongodb-atlas": "MongoDB Atlas",
1965
+ planetscale: "PlanetScale"
1966
+ },
1967
+ webDeploy: {
1968
+ cloudflare: "Cloudflare",
1969
+ fly: "Fly.io",
1970
+ sst: "SST"
1971
+ },
1972
+ serverDeploy: {
1973
+ cloudflare: "Cloudflare",
1974
+ fly: "Fly.io",
1975
+ sst: "SST"
1976
+ },
1977
+ auth: {},
1978
+ payments: {
1979
+ "lemon-squeezy": "Lemon Squeezy",
1980
+ dodo: "Dodo Payments"
1981
+ },
1982
+ email: {
1983
+ "react-email": "React Email",
1984
+ sendgrid: "SendGrid",
1985
+ "aws-ses": "AWS SES"
1986
+ },
1987
+ fileUpload: {
1988
+ uploadthing: "UploadThing",
1989
+ filepond: "FilePond",
1990
+ uppy: "Uppy"
1991
+ },
1992
+ observability: { opentelemetry: "OpenTelemetry" },
1993
+ backendLibraries: {
1994
+ effect: "Effect (Core)",
1995
+ "effect-full": "Effect Full"
1996
+ },
1997
+ stateManagement: {
1998
+ "redux-toolkit": "Redux Toolkit",
1999
+ xstate: "XState"
2000
+ },
2001
+ forms: {
2002
+ "react-hook-form": "React Hook Form",
2003
+ "tanstack-form": "TanStack Form",
2004
+ "final-form": "Final Form",
2005
+ "modular-forms": "Modular Forms"
2006
+ },
2007
+ validation: {
2008
+ zod: "Zod",
2009
+ arktype: "ArkType",
2010
+ typebox: "TypeBox",
2011
+ "effect-schema": "@effect/schema"
2012
+ },
2013
+ testing: { "vitest-playwright": "Vitest + Playwright" },
2014
+ realtime: {
2015
+ "socket-io": "Socket.IO",
2016
+ yjs: "Y.js"
2017
+ },
2018
+ jobQueue: {
2019
+ bullmq: "BullMQ",
2020
+ "trigger-dev": "Trigger.dev"
2021
+ },
2022
+ cssFramework: {
2023
+ tailwind: "Tailwind CSS",
2024
+ scss: "SCSS",
2025
+ "postcss-only": "PostCSS Only"
2026
+ },
2027
+ uiLibrary: {
2028
+ "shadcn-ui": "shadcn/ui",
2029
+ daisyui: "daisyUI",
2030
+ "radix-ui": "Radix UI",
2031
+ "headless-ui": "Headless UI",
2032
+ "park-ui": "Park UI",
2033
+ "chakra-ui": "Chakra UI",
2034
+ nextui: "NextUI",
2035
+ "base-ui": "Base UI",
2036
+ "ark-ui": "Ark UI",
2037
+ "react-aria": "React Aria"
2038
+ },
2039
+ featureFlags: {
2040
+ growthbook: "GrowthBook",
2041
+ posthog: "PostHog"
2042
+ },
2043
+ analytics: {
2044
+ plausible: "Plausible",
2045
+ umami: "Umami"
2046
+ },
2047
+ codeQuality: {
2048
+ biome: "Biome",
2049
+ oxlint: "Oxlint",
2050
+ ultracite: "Ultracite",
2051
+ lefthook: "Lefthook",
2052
+ husky: "Husky",
2053
+ ruler: "Ruler"
2054
+ },
2055
+ documentation: {
2056
+ starlight: "Starlight",
2057
+ fumadocs: "Fumadocs"
2058
+ },
2059
+ appPlatforms: {
2060
+ pwa: "PWA",
2061
+ wxt: "WXT",
2062
+ opentui: "OpenTUI",
2063
+ mcp: "MCP",
2064
+ msw: "MSW"
2065
+ },
2066
+ examples: {
2067
+ ai: "AI Example",
2068
+ "chat-sdk": "Chat SDK Bots"
2069
+ },
2070
+ ai: {
2071
+ "vercel-ai": "Vercel AI SDK",
2072
+ voltagent: "VoltAgent",
2073
+ langgraph: "LangGraph.js",
2074
+ "openai-agents": "OpenAI Agents SDK",
2075
+ "google-adk": "Google ADK",
2076
+ modelfusion: "ModelFusion",
2077
+ langchain: "LangChain",
2078
+ llamaindex: "LlamaIndex"
2079
+ },
2080
+ aiDocs: {
2081
+ "claude-md": "CLAUDE.md",
2082
+ "agents-md": "Agents.md",
2083
+ cursorrules: ".cursorrules"
2084
+ },
2085
+ git: {
2086
+ true: "Git",
2087
+ false: "No Git"
2088
+ },
2089
+ install: {
2090
+ true: "Install Dependencies",
2091
+ false: "Skip Install"
2092
+ },
2093
+ effect: {
2094
+ effect: "Effect (Core)",
2095
+ "effect-full": "Effect Full"
2096
+ },
2097
+ shadcnBase: {
2098
+ radix: "Radix UI",
2099
+ base: "Base UI"
2100
+ },
2101
+ shadcnStyle: {
2102
+ vega: "Vega",
2103
+ nova: "Nova",
2104
+ maia: "Maia",
2105
+ lyra: "Lyra",
2106
+ mira: "Mira"
2107
+ },
2108
+ shadcnIconLibrary: {
2109
+ lucide: "Lucide",
2110
+ tabler: "Tabler Icons",
2111
+ hugeicons: "HugeIcons",
2112
+ phosphor: "Phosphor Icons",
2113
+ remixicon: "Remix Icon"
2114
+ },
2115
+ shadcnColorTheme: { neutral: "Neutral" },
2116
+ shadcnBaseColor: { neutral: "Neutral" },
2117
+ shadcnFont: {
2118
+ inter: "Inter",
2119
+ geist: "Geist",
2120
+ figtree: "Figtree",
2121
+ "noto-sans": "Noto Sans",
2122
+ "nunito-sans": "Nunito Sans",
2123
+ roboto: "Roboto",
2124
+ raleway: "Raleway",
2125
+ "dm-sans": "DM Sans",
2126
+ "public-sans": "Public Sans",
2127
+ outfit: "Outfit",
2128
+ "jetbrains-mono": "JetBrains Mono",
2129
+ "geist-mono": "Geist Mono"
2130
+ },
2131
+ shadcnRadius: { default: "Default" },
2132
+ rustWebFramework: {
2133
+ axum: "Axum",
2134
+ "actix-web": "Actix-web"
2135
+ },
2136
+ rustFrontend: {
2137
+ leptos: "Leptos",
2138
+ dioxus: "Dioxus"
2139
+ },
2140
+ rustOrm: {
2141
+ "sea-orm": "SeaORM",
2142
+ sqlx: "SQLx"
2143
+ },
2144
+ rustApi: {
2145
+ "async-graphql": "async-graphql",
2146
+ tonic: "Tonic"
2147
+ },
2148
+ rustCli: {
2149
+ clap: "Clap",
2150
+ ratatui: "Ratatui"
2151
+ },
2152
+ rustLibraries: {
2153
+ serde: "Serde",
2154
+ validator: "Validator",
2155
+ jsonwebtoken: "jsonwebtoken",
2156
+ argon2: "Argon2",
2157
+ "tokio-test": "Tokio Test",
2158
+ mockall: "Mockall"
2159
+ },
2160
+ pythonWebFramework: {
2161
+ fastapi: "FastAPI",
2162
+ django: "Django"
2163
+ },
2164
+ pythonOrm: {
2165
+ sqlalchemy: "SQLAlchemy",
2166
+ sqlmodel: "SQLModel"
2167
+ },
2168
+ pythonValidation: { pydantic: "Pydantic" },
2169
+ pythonAi: {
2170
+ langchain: "LangChain",
2171
+ llamaindex: "LlamaIndex",
2172
+ "openai-sdk": "OpenAI SDK",
2173
+ "anthropic-sdk": "Anthropic SDK",
2174
+ langgraph: "LangGraph",
2175
+ crewai: "CrewAI"
2176
+ },
2177
+ pythonTaskQueue: { celery: "Celery" },
2178
+ pythonQuality: { ruff: "Ruff" },
2179
+ goWebFramework: {
2180
+ gin: "Gin",
2181
+ echo: "Echo"
2182
+ },
2183
+ goOrm: {
2184
+ gorm: "GORM",
2185
+ sqlc: "sqlc"
2186
+ },
2187
+ goApi: { "grpc-go": "gRPC-Go" },
2188
+ goCli: {
2189
+ cobra: "Cobra",
2190
+ bubbletea: "Bubble Tea"
2191
+ },
2192
+ goLogging: { zap: "Zap" }
2193
+ };
2194
+ const OPTION_ALIASES = {
2195
+ webFrontend: { svelte: ["sveltekit"] },
2196
+ backend: { "self-svelte": ["self-sveltekit"] }
2197
+ };
2198
+ const CLI_VALUE_OVERRIDES = { backend: {
2199
+ "self-next": "self",
2200
+ "self-tanstack-start": "self",
2201
+ "self-astro": "self",
2202
+ "self-nuxt": "self",
2203
+ "self-svelte": "self",
2204
+ "self-solid-start": "self"
2205
+ } };
2206
+ const TOKEN_LABELS = {
2207
+ ai: "AI",
2208
+ api: "API",
2209
+ auth: "Auth",
2210
+ css: "CSS",
2211
+ db: "DB",
2212
+ graphql: "GraphQL",
2213
+ grpc: "gRPC",
2214
+ js: "JS",
2215
+ md: "MD",
2216
+ orm: "ORM",
2217
+ sdk: "SDK",
2218
+ ses: "SES",
2219
+ sql: "SQL",
2220
+ ui: "UI"
2221
+ };
2222
+ function toStartCaseToken(token) {
2223
+ const lower = token.toLowerCase();
2224
+ if (TOKEN_LABELS[lower]) return TOKEN_LABELS[lower];
2225
+ return lower.charAt(0).toUpperCase() + lower.slice(1);
2226
+ }
2227
+ function humanizeOptionId(id) {
2228
+ return id.split("-").filter(Boolean).map(toStartCaseToken).join(" ");
2229
+ }
2230
+ function getOptionLabel(category, id) {
2231
+ if (category === "auth") return getCapabilityDefinitions("auth").find((option) => option.id === id)?.label ?? humanizeOptionId(id);
2232
+ return EXACT_LABEL_OVERRIDES[category]?.[id] ?? humanizeOptionId(id);
2233
+ }
2234
+ function getOptionAliases(category, id) {
2235
+ return OPTION_ALIASES[category]?.[id] ?? [];
2236
+ }
2237
+ function getCliValue(category, id) {
2238
+ return CLI_VALUE_OVERRIDES[category]?.[id] ?? id;
2239
+ }
2240
+ function buildCategoryMetadata(category) {
2241
+ return {
2242
+ selectionMode: MULTI_SELECT_CATEGORIES.has(category) ? "multiple" : "single",
2243
+ options: CATEGORY_VALUE_IDS[category].map((id) => ({
2244
+ id,
2245
+ label: getOptionLabel(category, id),
2246
+ aliases: getOptionAliases(category, id),
2247
+ cliValue: getCliValue(category, id)
2248
+ }))
2249
+ };
2250
+ }
2251
+ const OPTION_CATEGORY_METADATA = {
2252
+ api: buildCategoryMetadata("api"),
2253
+ webFrontend: buildCategoryMetadata("webFrontend"),
2254
+ nativeFrontend: buildCategoryMetadata("nativeFrontend"),
2255
+ astroIntegration: buildCategoryMetadata("astroIntegration"),
2256
+ runtime: buildCategoryMetadata("runtime"),
2257
+ backend: buildCategoryMetadata("backend"),
2258
+ database: buildCategoryMetadata("database"),
2259
+ orm: buildCategoryMetadata("orm"),
2260
+ dbSetup: buildCategoryMetadata("dbSetup"),
2261
+ webDeploy: buildCategoryMetadata("webDeploy"),
2262
+ serverDeploy: buildCategoryMetadata("serverDeploy"),
2263
+ auth: buildCategoryMetadata("auth"),
2264
+ payments: buildCategoryMetadata("payments"),
2265
+ email: buildCategoryMetadata("email"),
2266
+ fileUpload: buildCategoryMetadata("fileUpload"),
2267
+ logging: buildCategoryMetadata("logging"),
2268
+ observability: buildCategoryMetadata("observability"),
2269
+ backendLibraries: buildCategoryMetadata("backendLibraries"),
2270
+ stateManagement: buildCategoryMetadata("stateManagement"),
2271
+ forms: buildCategoryMetadata("forms"),
2272
+ validation: buildCategoryMetadata("validation"),
2273
+ testing: buildCategoryMetadata("testing"),
2274
+ realtime: buildCategoryMetadata("realtime"),
2275
+ jobQueue: buildCategoryMetadata("jobQueue"),
2276
+ caching: buildCategoryMetadata("caching"),
2277
+ search: buildCategoryMetadata("search"),
2278
+ fileStorage: buildCategoryMetadata("fileStorage"),
2279
+ animation: buildCategoryMetadata("animation"),
2280
+ cssFramework: buildCategoryMetadata("cssFramework"),
2281
+ uiLibrary: buildCategoryMetadata("uiLibrary"),
2282
+ cms: buildCategoryMetadata("cms"),
2283
+ featureFlags: buildCategoryMetadata("featureFlags"),
2284
+ analytics: buildCategoryMetadata("analytics"),
2285
+ codeQuality: buildCategoryMetadata("codeQuality"),
2286
+ documentation: buildCategoryMetadata("documentation"),
2287
+ appPlatforms: buildCategoryMetadata("appPlatforms"),
2288
+ packageManager: buildCategoryMetadata("packageManager"),
2289
+ examples: buildCategoryMetadata("examples"),
2290
+ ai: buildCategoryMetadata("ai"),
2291
+ aiDocs: buildCategoryMetadata("aiDocs"),
2292
+ git: buildCategoryMetadata("git"),
2293
+ install: buildCategoryMetadata("install"),
2294
+ effect: buildCategoryMetadata("effect"),
2295
+ shadcnBase: buildCategoryMetadata("shadcnBase"),
2296
+ shadcnStyle: buildCategoryMetadata("shadcnStyle"),
2297
+ shadcnIconLibrary: buildCategoryMetadata("shadcnIconLibrary"),
2298
+ shadcnColorTheme: buildCategoryMetadata("shadcnColorTheme"),
2299
+ shadcnBaseColor: buildCategoryMetadata("shadcnBaseColor"),
2300
+ shadcnFont: buildCategoryMetadata("shadcnFont"),
2301
+ shadcnRadius: buildCategoryMetadata("shadcnRadius"),
2302
+ rustWebFramework: buildCategoryMetadata("rustWebFramework"),
2303
+ rustFrontend: buildCategoryMetadata("rustFrontend"),
2304
+ rustOrm: buildCategoryMetadata("rustOrm"),
2305
+ rustApi: buildCategoryMetadata("rustApi"),
2306
+ rustCli: buildCategoryMetadata("rustCli"),
2307
+ rustLibraries: buildCategoryMetadata("rustLibraries"),
2308
+ pythonWebFramework: buildCategoryMetadata("pythonWebFramework"),
2309
+ pythonOrm: buildCategoryMetadata("pythonOrm"),
2310
+ pythonValidation: buildCategoryMetadata("pythonValidation"),
2311
+ pythonAi: buildCategoryMetadata("pythonAi"),
2312
+ pythonTaskQueue: buildCategoryMetadata("pythonTaskQueue"),
2313
+ pythonQuality: buildCategoryMetadata("pythonQuality"),
2314
+ goWebFramework: buildCategoryMetadata("goWebFramework"),
2315
+ goOrm: buildCategoryMetadata("goOrm"),
2316
+ goApi: buildCategoryMetadata("goApi"),
2317
+ goCli: buildCategoryMetadata("goCli"),
2318
+ goLogging: buildCategoryMetadata("goLogging")
2319
+ };
2320
+ 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])]))]));
2321
+ function isMultiSelectCategory(category) {
2322
+ return OPTION_CATEGORY_METADATA[category].selectionMode === "multiple";
2323
+ }
2324
+ function getOptionMetadata(category, optionId) {
2325
+ return OPTION_CATEGORY_METADATA[category].options.find((option) => option.id === optionId);
2326
+ }
2327
+ function getCategoryOptionIds(category) {
2328
+ return OPTION_CATEGORY_METADATA[category].options.map((option) => option.id);
2329
+ }
2330
+ function getCategoryCliValues(category) {
2331
+ return [...new Set(OPTION_CATEGORY_METADATA[category].options.map((option) => option.cliValue))];
2332
+ }
2333
+ function normalizeOptionId(category, value) {
2334
+ return OPTION_LOOKUP[category].get(value.toLowerCase()) ?? value;
2335
+ }
2336
+
2337
+ //#endregion
2338
+ //#region src/local-dev.ts
2339
+ const VITE_WEB_FRONTENDS = new Set([
2340
+ "react-router",
2341
+ "svelte",
2342
+ "fresh"
2343
+ ]);
2344
+ function getLocalWebDevPort(frontend) {
2345
+ return frontend.some((entry) => VITE_WEB_FRONTENDS.has(entry)) ? 5173 : 3001;
2346
+ }
2347
+
2348
+ //#endregion
2349
+ export { ADDONS_VALUES, AISchema, AI_DOCS_VALUES, AI_VALUES, ANALYTICS_VALUES, ANIMATION_VALUES, APISchema, API_VALUES, ASTRO_INTEGRATION_VALUES, AUTH_VALUES, AddInputSchema, AddonsSchema, AiDocsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BACKEND_VALUES, BackendSchema, BetterTStackConfigFileSchema, BetterTStackConfigSchema, CACHING_VALUES, CLIInputSchema, CMSSchema, CMS_VALUES, CSSFrameworkSchema, CSS_FRAMEWORK_VALUES, CachingSchema, CreateInputSchema, DATABASE_SETUP_VALUES, DATABASE_VALUES, DIRECTORY_CONFLICT_VALUES, DatabaseSchema, DatabaseSetupSchema, DirectoryConflictSchema, ECOSYSTEM_VALUES, EFFECT_VALUES, EMAIL_VALUES, EXAMPLES_VALUES, EcosystemSchema, EffectSchema, EmailSchema, ExamplesSchema, FEATURE_FLAGS_VALUES, FILE_STORAGE_VALUES, FILE_UPLOAD_VALUES, FORMS_VALUES, FRONTEND_VALUES, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GO_API_VALUES, GO_CLI_VALUES, GO_LOGGING_VALUES, GO_ORM_VALUES, GO_WEB_FRAMEWORK_VALUES, GoApiSchema, GoCliSchema, GoLoggingSchema, GoOrmSchema, GoWebFrameworkSchema, InitResultSchema, JOB_QUEUE_VALUES, JobQueueSchema, LOGGING_VALUES, LoggingSchema, OBSERVABILITY_VALUES, OPTION_CATEGORY_METADATA, ORMSchema, ORM_VALUES, ObservabilitySchema, PACKAGE_MANAGER_VALUES, PAYMENTS_VALUES, PYTHON_AI_VALUES, PYTHON_ORM_VALUES, PYTHON_QUALITY_VALUES, PYTHON_TASK_QUEUE_VALUES, PYTHON_VALIDATION_VALUES, PYTHON_WEB_FRAMEWORK_VALUES, PackageManagerSchema, PaymentsSchema, ProjectConfigSchema, ProjectNameSchema, PythonAiSchema, PythonOrmSchema, PythonQualitySchema, PythonTaskQueueSchema, PythonValidationSchema, PythonWebFrameworkSchema, REALTIME_VALUES, RUNTIME_VALUES, RUST_API_VALUES, RUST_CLI_VALUES, RUST_FRONTEND_VALUES, RUST_LIBRARIES_VALUES, RUST_ORM_VALUES, RUST_WEB_FRAMEWORK_VALUES, RealtimeSchema, RuntimeSchema, RustApiSchema, RustCliSchema, RustFrontendSchema, RustLibrariesSchema, RustOrmSchema, RustWebFrameworkSchema, SEARCH_VALUES, SERVER_DEPLOY_VALUES, SHADCN_BASE_COLOR_VALUES, SHADCN_BASE_VALUES, SHADCN_COLOR_THEME_VALUES, SHADCN_FONT_VALUES, SHADCN_ICON_LIBRARY_VALUES, SHADCN_RADIUS_VALUES, SHADCN_STYLE_VALUES, STATE_MANAGEMENT_VALUES, SearchSchema, ServerDeploySchema, ShadcnBaseColorSchema, ShadcnBaseSchema, ShadcnColorThemeSchema, ShadcnFontSchema, ShadcnIconLibrarySchema, ShadcnRadiusSchema, ShadcnStyleSchema, StateManagementSchema, TEMPLATE_VALUES, TESTING_VALUES, TemplateSchema, TestingSchema, UILibrarySchema, UI_LIBRARY_VALUES, VALIDATION_VALUES, ValidationSchema, WEB_DEPLOY_VALUES, WebDeploySchema, allowedApisForFrontends, analyzeStackCompatibility, evaluateCompatibility, getCapabilityDefinitions, getCapabilityDisabledReason, getCategoryCliValues, getCategoryDisplayName, getCategoryOptionIds, getCompatibleAddons, getCompatibleCSSFrameworks, getCompatibleFormLibraries, getCompatibleUILibraries, getDisabledReason, getLocalWebDevPort, getOptionMetadata, getSupportedCapabilityOptions, hasPWACompatibleFrontend, hasTauriCompatibleFrontend, hasWebStyling, isExampleAIAllowed, isExampleChatSdkAllowed, isFrontendAllowedWithBackend, isMultiSelectCategory, isOptionCompatible, isWebFrontend, normalizeCapabilitySelection, normalizeOptionId, requiresChatSdkVercelAI, requiresChatSdkVercelAIForSelection, splitFrontends, validateAddonCompatibility, validateProjectName };
1667
2350
  //# sourceMappingURL=index.mjs.map