@better-fullstack/types 2.1.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{defaults-BxirxtSa.d.mts → defaults-azh56xa4.d.mts} +2 -2
  2. package/dist/defaults-azh56xa4.d.mts.map +1 -0
  3. package/dist/defaults.d.mts +3 -3
  4. package/dist/index.d.mts +5 -5
  5. package/dist/index.d.mts.map +1 -1
  6. package/dist/index.mjs +3 -3
  7. package/dist/json-schema.d.mts +32 -0
  8. package/dist/json-schema.d.mts.map +1 -1
  9. package/dist/json-schema.mjs +1 -1
  10. package/dist/{schemas-O8yu_3Hd.d.mts → schemas-C3iF9TRm.d.mts} +975 -51
  11. package/dist/schemas-C3iF9TRm.d.mts.map +1 -0
  12. package/dist/{schemas-Cg75ZlzB.mjs → schemas-ZxRzd5TP.mjs} +18 -9
  13. package/dist/schemas-ZxRzd5TP.mjs.map +1 -0
  14. package/dist/schemas.d.mts +1 -1
  15. package/dist/schemas.mjs +1 -1
  16. package/dist/{stack-graph-Q0PrewPk.mjs → stack-graph-BwtoYnJg.mjs} +171 -9
  17. package/dist/stack-graph-BwtoYnJg.mjs.map +1 -0
  18. package/dist/{stack-graph-BuxVyZ3J.d.mts → stack-graph-CiXONkqh.d.mts} +4 -3
  19. package/dist/stack-graph-CiXONkqh.d.mts.map +1 -0
  20. package/dist/stack-graph.d.mts +3 -3
  21. package/dist/stack-graph.mjs +2 -2
  22. package/dist/{stack-translation-DkyErnfx.d.mts → stack-translation-BNwlAM1B.d.mts} +3 -3
  23. package/dist/{stack-translation-DkyErnfx.d.mts.map → stack-translation-BNwlAM1B.d.mts.map} +1 -1
  24. package/dist/{stack-translation-gNYPvlYt.mjs → stack-translation-DNT-iMAE.mjs} +255 -111
  25. package/dist/stack-translation-DNT-iMAE.mjs.map +1 -0
  26. package/dist/stack-translation.d.mts +4 -4
  27. package/dist/stack-translation.mjs +3 -3
  28. package/dist/{types-CkvXj6HM.d.mts → types-BG-DsHQ9.d.mts} +2 -2
  29. package/dist/{types-CkvXj6HM.d.mts.map → types-BG-DsHQ9.d.mts.map} +1 -1
  30. package/dist/types.d.mts +2 -2
  31. package/package.json +1 -1
  32. package/dist/defaults-BxirxtSa.d.mts.map +0 -1
  33. package/dist/schemas-Cg75ZlzB.mjs.map +0 -1
  34. package/dist/schemas-O8yu_3Hd.d.mts.map +0 -1
  35. package/dist/stack-graph-BuxVyZ3J.d.mts.map +0 -1
  36. package/dist/stack-graph-Q0PrewPk.mjs.map +0 -1
  37. package/dist/stack-translation-gNYPvlYt.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { $n as MOBILE_STORAGE_VALUES, $r as RUST_CLI_VALUES, Ai as SHADCN_BASE_VALUES, An as JAVA_AUTH_VALUES, B as DOTNET_OBSERVABILITY_VALUES, Cr as PYTHON_QUALITY_VALUES, Ct as ELIXIR_WEB_FRAMEWORK_VALUES, D as CMS_VALUES, Di as SEARCH_VALUES, Dr as PYTHON_VALIDATION_VALUES, En as I18N_VALUES, Er as PYTHON_TESTING_VALUES, F as DOTNET_API_VALUES, Fi as SHADCN_STYLE_VALUES, Fn as JAVA_TESTING_LIBRARIES_VALUES, G as DOTNET_WEB_FRAMEWORK_VALUES, H as DOTNET_REALTIME_VALUES, I as DOTNET_AUTH_VALUES, Ii as STATE_MANAGEMENT_VALUES, In as JAVA_WEB_FRAMEWORK_VALUES, Jr as REALTIME_VALUES, Jt as FILE_UPLOAD_VALUES, Kt as FEATURE_FLAGS_VALUES, L as DOTNET_CACHING_VALUES, Ln as JOB_QUEUE_VALUES, M as DATABASE_SETUP_VALUES, Mi as SHADCN_FONT_VALUES, Mn as JAVA_LIBRARIES_VALUES, N as DATABASE_VALUES, Ni as SHADCN_ICON_LIBRARY_VALUES, Nn as JAVA_LOGGING_VALUES, Oi as SERVER_DEPLOY_VALUES, Or as PYTHON_WEB_FRAMEWORK_VALUES, Pi as SHADCN_RADIUS_VALUES, Pn as JAVA_ORM_VALUES, Qi as TESTING_VALUES, Qn as MOBILE_PUSH_VALUES, Qr as RUST_CACHING_VALUES, R as DOTNET_DEPLOY_VALUES, Sr as PYTHON_ORM_VALUES, St as ELIXIR_VALIDATION_VALUES, Tr as PYTHON_TASK_QUEUE_VALUES, U as DOTNET_TESTING_VALUES, V as DOTNET_ORM_VALUES, W as DOTNET_VALIDATION_VALUES, Xn as MOBILE_NAVIGATION_VALUES, Xr as RUST_API_VALUES, Yn as MOBILE_DEEP_LINKING_VALUES, Yr as RUNTIME_VALUES, Yt as FORMS_VALUES, Zn as MOBILE_OTA_VALUES, Zr as RUST_AUTH_VALUES, _r as PYTHON_AUTH_VALUES, _t as ELIXIR_OBSERVABILITY_VALUES, a as ANALYTICS_VALUES, aa as VERSION_CHANNEL_VALUES, ai as RUST_OBSERVABILITY_VALUES, an as GO_CLI_VALUES, br as PYTHON_GRAPHQL_VALUES, bt as ELIXIR_REALTIME_VALUES, c as API_VALUES, ci as RUST_TEMPLATING_VALUES, cn as GO_MESSAGE_QUEUE_VALUES, ct as ELIXIR_API_VALUES, dn as GO_REALTIME_VALUES, dr as ORM_VALUES, dt as ELIXIR_DEPLOY_VALUES, ei as RUST_ERROR_HANDLING_VALUES, er as MOBILE_TESTING_VALUES, fn as GO_TESTING_VALUES, ft as ELIXIR_EMAIL_VALUES, gr as PYTHON_API_VALUES, gt as ELIXIR_LIBRARIES_VALUES, hr as PYTHON_AI_VALUES, ht as ELIXIR_JSON_VALUES, i as AI_VALUES, ia as VECTOR_DB_VALUES, ii as RUST_MESSAGE_QUEUE_VALUES, in as GO_CACHING_VALUES, ji as SHADCN_COLOR_THEME_VALUES, jn as JAVA_BUILD_TOOL_VALUES, k as CSS_FRAMEWORK_VALUES, ki as SHADCN_BASE_COLOR_VALUES, kn as JAVA_API_VALUES, l as ASTRO_INTEGRATION_VALUES, la as WEB_DEPLOY_VALUES, li as RUST_WEB_FRAMEWORK_VALUES, ln as GO_OBSERVABILITY_VALUES, lr as OBSERVABILITY_VALUES, lt as ELIXIR_AUTH_VALUES, mr as PAYMENTS_VALUES, mt as ELIXIR_JOBS_VALUES, na as UI_LIBRARY_VALUES, ni as RUST_LIBRARIES_VALUES, nn as GO_API_VALUES, o as ANIMATION_VALUES, oi as RUST_ORM_VALUES, on as GO_CONFIG_VALUES, pn as GO_WEB_FRAMEWORK_VALUES, pr as PACKAGE_MANAGER_VALUES, pt as ELIXIR_HTTP_VALUES, qn as LOGGING_VALUES, qr as RATE_LIMIT_VALUES, qt as FILE_STORAGE_VALUES, r as AI_DOCS_VALUES, ra as VALIDATION_VALUES, ri as RUST_LOGGING_VALUES, rn as GO_AUTH_VALUES, si as RUST_REALTIME_VALUES, sn as GO_LOGGING_VALUES, st as EFFECT_VALUES, ti as RUST_FRONTEND_VALUES, tr as MOBILE_UI_VALUES, u as AUTH_VALUES, un as GO_ORM_VALUES, ut as ELIXIR_CACHING_VALUES, vr as PYTHON_CACHING_VALUES, vt as ELIXIR_ORM_VALUES, w as CACHING_VALUES, wr as PYTHON_REALTIME_VALUES, wt as EMAIL_VALUES, xr as PYTHON_OBSERVABILITY_VALUES, xt as ELIXIR_TESTING_VALUES, yr as PYTHON_CLI_VALUES, yt as ELIXIR_QUALITY_VALUES, z as DOTNET_JOB_QUEUE_VALUES } from "./schemas-Cg75ZlzB.mjs";
2
- import { C as isBackendUtilsCompatibleBackend, E as requiresChatSdkVercelAIForExamples, S as hasTauriCompatibleFrontend, _ as UI_LIBRARY_COMPATIBILITY, a as getAddonStackPartBinding, b as hasPWACompatibleFrontend, f as parseStackPartSpecs, h as validateStackParts, i as formatStackPartSpec, m as stackPartsToLegacyProjectConfigPartial, s as getStackPartCompatibilityIssueForPart, u as legacyProjectConfigToStackParts, v as getUnsupportedWebDeployFrontend, x as hasTanStackAICompatibleFrontend, y as hasDockerComposeCompatibleFrontend } from "./stack-graph-Q0PrewPk.mjs";
1
+ import { $n as MOBILE_STORAGE_VALUES, $r as RUST_CLI_VALUES, Ai as SHADCN_BASE_VALUES, An as JAVA_AUTH_VALUES, B as DOTNET_OBSERVABILITY_VALUES, Cr as PYTHON_QUALITY_VALUES, Ct as ELIXIR_WEB_FRAMEWORK_VALUES, D as CMS_VALUES, Di as SEARCH_VALUES, Dr as PYTHON_VALIDATION_VALUES, En as I18N_VALUES, Er as PYTHON_TESTING_VALUES, F as DOTNET_API_VALUES, Fi as SHADCN_STYLE_VALUES, Fn as JAVA_TESTING_LIBRARIES_VALUES, G as DOTNET_WEB_FRAMEWORK_VALUES, H as DOTNET_REALTIME_VALUES, I as DOTNET_AUTH_VALUES, Ii as STATE_MANAGEMENT_VALUES, In as JAVA_WEB_FRAMEWORK_VALUES, Jr as REALTIME_VALUES, Jt as FILE_UPLOAD_VALUES, Kt as FEATURE_FLAGS_VALUES, L as DOTNET_CACHING_VALUES, Ln as JOB_QUEUE_VALUES, M as DATABASE_SETUP_VALUES, Mi as SHADCN_FONT_VALUES, Mn as JAVA_LIBRARIES_VALUES, N as DATABASE_VALUES, Ni as SHADCN_ICON_LIBRARY_VALUES, Nn as JAVA_LOGGING_VALUES, Oi as SERVER_DEPLOY_VALUES, Or as PYTHON_WEB_FRAMEWORK_VALUES, Pi as SHADCN_RADIUS_VALUES, Pn as JAVA_ORM_VALUES, Qi as TESTING_VALUES, Qn as MOBILE_PUSH_VALUES, Qr as RUST_CACHING_VALUES, R as DOTNET_DEPLOY_VALUES, Sr as PYTHON_ORM_VALUES, St as ELIXIR_VALIDATION_VALUES, Tr as PYTHON_TASK_QUEUE_VALUES, U as DOTNET_TESTING_VALUES, V as DOTNET_ORM_VALUES, W as DOTNET_VALIDATION_VALUES, Xn as MOBILE_NAVIGATION_VALUES, Xr as RUST_API_VALUES, Yn as MOBILE_DEEP_LINKING_VALUES, Yr as RUNTIME_VALUES, Yt as FORMS_VALUES, Zn as MOBILE_OTA_VALUES, Zr as RUST_AUTH_VALUES, _r as PYTHON_AUTH_VALUES, _t as ELIXIR_OBSERVABILITY_VALUES, a as ANALYTICS_VALUES, aa as VERSION_CHANNEL_VALUES, ai as RUST_OBSERVABILITY_VALUES, an as GO_CLI_VALUES, br as PYTHON_GRAPHQL_VALUES, bt as ELIXIR_REALTIME_VALUES, c as API_VALUES, ci as RUST_TEMPLATING_VALUES, cn as GO_MESSAGE_QUEUE_VALUES, ct as ELIXIR_API_VALUES, dn as GO_REALTIME_VALUES, dr as ORM_VALUES, dt as ELIXIR_DEPLOY_VALUES, ei as RUST_ERROR_HANDLING_VALUES, er as MOBILE_TESTING_VALUES, fn as GO_TESTING_VALUES, ft as ELIXIR_EMAIL_VALUES, gr as PYTHON_API_VALUES, gt as ELIXIR_LIBRARIES_VALUES, hr as PYTHON_AI_VALUES, ht as ELIXIR_JSON_VALUES, i as AI_VALUES, ia as VECTOR_DB_VALUES, ii as RUST_MESSAGE_QUEUE_VALUES, in as GO_CACHING_VALUES, ji as SHADCN_COLOR_THEME_VALUES, jn as JAVA_BUILD_TOOL_VALUES, k as CSS_FRAMEWORK_VALUES, ki as SHADCN_BASE_COLOR_VALUES, kn as JAVA_API_VALUES, l as ASTRO_INTEGRATION_VALUES, la as WEB_DEPLOY_VALUES, li as RUST_WEB_FRAMEWORK_VALUES, ln as GO_OBSERVABILITY_VALUES, lr as OBSERVABILITY_VALUES, lt as ELIXIR_AUTH_VALUES, mr as PAYMENTS_VALUES, mt as ELIXIR_JOBS_VALUES, na as UI_LIBRARY_VALUES, ni as RUST_LIBRARIES_VALUES, nn as GO_API_VALUES, o as ANIMATION_VALUES, oi as RUST_ORM_VALUES, on as GO_CONFIG_VALUES, pn as GO_WEB_FRAMEWORK_VALUES, pr as PACKAGE_MANAGER_VALUES, pt as ELIXIR_HTTP_VALUES, qn as LOGGING_VALUES, qr as RATE_LIMIT_VALUES, qt as FILE_STORAGE_VALUES, r as AI_DOCS_VALUES, ra as VALIDATION_VALUES, ri as RUST_LOGGING_VALUES, rn as GO_AUTH_VALUES, si as RUST_REALTIME_VALUES, sn as GO_LOGGING_VALUES, st as EFFECT_VALUES, ti as RUST_FRONTEND_VALUES, tr as MOBILE_UI_VALUES, u as AUTH_VALUES, un as GO_ORM_VALUES, ut as ELIXIR_CACHING_VALUES, vr as PYTHON_CACHING_VALUES, vt as ELIXIR_ORM_VALUES, w as CACHING_VALUES, wr as PYTHON_REALTIME_VALUES, wt as EMAIL_VALUES, xr as PYTHON_OBSERVABILITY_VALUES, xt as ELIXIR_TESTING_VALUES, yr as PYTHON_CLI_VALUES, yt as ELIXIR_QUALITY_VALUES, z as DOTNET_JOB_QUEUE_VALUES } from "./schemas-ZxRzd5TP.mjs";
2
+ import { E as requiresChatSdkVercelAIForExamples, S as hasTauriCompatibleFrontend, _ as UI_LIBRARY_COMPATIBILITY, a as getAddonStackPartBinding, b as hasPWACompatibleFrontend, f as parseStackPartSpecs, h as validateStackParts, i as formatStackPartSpec, m as stackPartsToLegacyProjectConfigPartial, s as getStackPartCompatibilityIssueForPart, u as legacyProjectConfigToStackParts, v as getUnsupportedWebDeployFrontend, x as hasTanStackAICompatibleFrontend } from "./stack-graph-BwtoYnJg.mjs";
3
3
  import { t as createCliDefaultProjectConfigBase } from "./defaults-u9UAambo.mjs";
4
4
 
5
5
  //#region src/capabilities.ts
@@ -184,6 +184,18 @@ function getAuthDisabledReason(context, optionId) {
184
184
  }
185
185
  return "In Better-Fullstack, Clerk is currently supported with Convex, Next.js fullstack, or TanStack Start fullstack";
186
186
  }
187
+ if (optionId === "supabase-auth") {
188
+ if (isSelfBackend(backend)) {
189
+ if ((hasNextJs || hasTanStackStart) && hasNativeFrontend) return "In Better-Fullstack, Supabase Auth with self backend is currently supported only for web-only Next.js or TanStack Start projects (no native companion app)";
190
+ if (hasNextJs || hasTanStackStart) return null;
191
+ if (backend === "self-astro" || webFrontend.includes("astro")) return "In Better-Fullstack, Supabase Auth is not yet supported for Astro fullstack projects";
192
+ if (backend === "self-nuxt" || webFrontend.includes("nuxt")) return "In Better-Fullstack, Supabase Auth is not yet supported for Nuxt fullstack projects";
193
+ if (backend === "self-svelte" || webFrontend.includes("svelte")) return "In Better-Fullstack, Supabase Auth is not yet supported for SvelteKit fullstack projects";
194
+ if (backend === "self-solid-start" || webFrontend.includes("solid-start")) return "In Better-Fullstack, Supabase Auth is not yet supported for SolidStart fullstack projects";
195
+ return "In Better-Fullstack, Supabase Auth is currently supported with Next.js fullstack or TanStack Start fullstack";
196
+ }
197
+ return "In Better-Fullstack, Supabase Auth is currently supported only with the 'self' backend (fullstack Next.js or TanStack Start)";
198
+ }
187
199
  const nextOnlyLabel = getNextOnlyAuthLabel(optionId);
188
200
  if (backend !== "self" && backend !== "self-next") return `In Better-Fullstack, ${nextOnlyLabel} is currently supported only with the 'self' backend (fullstack Next.js)`;
189
201
  if (!hasNextJs) return `In Better-Fullstack, ${nextOnlyLabel} currently requires the Next.js frontend`;
@@ -2917,7 +2929,8 @@ const getDisabledReason = (currentStack, category, optionId) => {
2917
2929
  if (category === "examples" && optionId !== "none") return "No backend selected";
2918
2930
  }
2919
2931
  const graphDisabledReason = getGraphDisabledReason(currentStack, category, optionId);
2920
- if (graphDisabledReason) return graphDisabledReason;
2932
+ if (graphDisabledReason.reason) return graphDisabledReason.reason;
2933
+ if (graphDisabledReason.handled && graphDisabledReason.authoritative) return null;
2921
2934
  if (currentStack.backend === "self-next") {
2922
2935
  if (category === "runtime" && optionId !== "none") return "Next.js fullstack uses built-in API routes";
2923
2936
  if (category === "webFrontend" && optionId !== "next" && optionId !== "none") return "Next.js fullstack requires Next.js frontend";
@@ -3127,30 +3140,6 @@ const getDisabledReason = (currentStack, category, optionId) => {
3127
3140
  if (!currentStack.webFrontend.some((f) => compatibleFrontends.includes(f))) return "TanStack AI requires React or Solid frontend (no Vue/Svelte/Angular adapter yet)";
3128
3141
  }
3129
3142
  if (category === "appPlatforms") {
3130
- if (optionId === "pwa" && !hasPWACompatibleFrontend(currentStack.webFrontend)) return "PWA requires TanStack Router, React Router, Solid, Next.js, Vinext, or Astro";
3131
- if (optionId === "tauri" && !hasTauriCompatibleFrontend(currentStack.webFrontend)) return "Tauri requires TanStack Router, React Router, Nuxt, Svelte, Solid, Next.js, or Astro";
3132
- if (optionId === "docker-compose" || optionId === "devcontainer") {
3133
- const title = optionId === "devcontainer" ? "DevContainer" : "Docker Compose";
3134
- if (currentStack.backend === "convex") return `${title} is not compatible with Convex backend (managed service)`;
3135
- if (currentStack.runtime === "workers") return `${title} is not compatible with Cloudflare Workers runtime`;
3136
- if (![
3137
- "typescript",
3138
- "python",
3139
- "go",
3140
- "rust",
3141
- "java"
3142
- ].includes(currentStack.ecosystem)) return `${title} currently supports TypeScript, Python, Go, Rust, or Java projects`;
3143
- if (currentStack.ecosystem === "typescript" && !hasDockerComposeCompatibleFrontend(currentStack.webFrontend)) return `${title} currently supports Next.js, TanStack Router, React Router, React Vite, Solid, or Astro`;
3144
- if (currentStack.ecosystem === "typescript" && currentStack.backend === "self" && !currentStack.webFrontend.includes("next")) return `${title} self-backend support currently requires Next.js`;
3145
- if (currentStack.ecosystem === "rust" && currentStack.rustFrontend !== "none") return `${title} for Rust currently supports server-only projects`;
3146
- if (currentStack.ecosystem === "java" && currentStack.javaWebFramework !== "spring-boot") return `${title} for Java currently requires Spring Boot`;
3147
- if (currentStack.ecosystem === "python" && currentStack.database !== "none" && currentStack.database !== "sqlite" && currentStack.database !== "postgres") return `${title} for Python ORM projects currently supports SQLite defaults or Postgres`;
3148
- }
3149
- if (optionId === "backend-utils") {
3150
- if (currentStack.ecosystem !== "typescript") return "Backend Utils requires a TypeScript server stack";
3151
- if (!isBackendUtilsCompatibleBackend(currentStack.backend)) return "Backend Utils requires a Hono, Express, Fastify, Elysia, feTS, or NestJS backend";
3152
- }
3153
- if (optionId === "tanstack-query" && currentStack.api !== "none") return "TanStack Query is already included via your API layer";
3154
3143
  if ([
3155
3144
  "tanstack-query",
3156
3145
  "tanstack-table",
@@ -3159,36 +3148,6 @@ const getDisabledReason = (currentStack, category, optionId) => {
3159
3148
  "tanstack-pacer"
3160
3149
  ].includes(optionId) && currentStack.webFrontend.length === 1 && currentStack.webFrontend[0] === "astro" && (!currentStack.astroIntegration || currentStack.astroIntegration === "none")) return "TanStack libraries with Astro require a UI framework integration (React, Vue, Svelte, or Solid)";
3161
3150
  }
3162
- if (category === "examples") {
3163
- if (optionId === "ai") {
3164
- if (currentStack.webFrontend.includes("solid") || currentStack.webFrontend.includes("solid-start")) return "AI example not compatible with Solid frontend";
3165
- if (currentStack.backend === "convex") {
3166
- if (currentStack.webFrontend.some((f) => ["svelte", "nuxt"].includes(f))) return `Convex AI example only supports React-based frontends including React + Vite (not ${currentStack.webFrontend.find((f) => ["svelte", "nuxt"].includes(f))})`;
3167
- }
3168
- }
3169
- if (optionId === "chat-sdk") {
3170
- if (currentStack.webFrontend.includes("react-vite")) return "Chat SDK example is not yet supported for React + Vite projects";
3171
- if (currentStack.ecosystem !== "typescript") return "Chat SDK example is currently available only for TypeScript stacks";
3172
- if (currentStack.backend === "convex") return "Chat SDK example is not supported with Convex backend in v1";
3173
- 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";
3174
- if (currentStack.backend === "self-next" || currentStack.backend === "self-vinext" || currentStack.backend === "self-tanstack-start") return null;
3175
- if (currentStack.backend === "self-nuxt") return null;
3176
- if (currentStack.backend === "hono") {
3177
- if (currentStack.runtime !== "node") return "Chat SDK Hono profile requires Node runtime in v1";
3178
- return null;
3179
- }
3180
- if (currentStack.backend.startsWith("self-")) return "Chat SDK self backend profile supports Next.js, TanStack Start, or Nuxt in v1";
3181
- if (currentStack.backend !== "none") return "Chat SDK example is only supported for self (Next/TanStack Start/Nuxt) or Hono+Node in v1";
3182
- }
3183
- }
3184
- const isFresh = currentStack.webFrontend.includes("fresh");
3185
- if (category === "forms" && optionId === "tanstack-form" && isFresh) return "TanStack Form has no Preact adapter (Fresh uses Preact)";
3186
- if (category === "stateManagement" && isFresh) {
3187
- if (optionId === "nanostores") return "Nanostores requires @nanostores/react (no Preact support)";
3188
- if (optionId === "xstate") return "XState requires @xstate/react (no Preact support)";
3189
- if (optionId === "tanstack-store") return "TanStack Store requires @tanstack/react-store (no Preact support)";
3190
- }
3191
- if (category === "animation" && optionId === "lottie" && isFresh) return "Lottie uses lottie-react which requires React (not Preact)";
3192
3151
  if (category === "cssFramework") {
3193
3152
  if (!currentStack.webFrontend.some((f) => f !== "none")) {
3194
3153
  if (optionId !== "none") return "CSS framework requires a web frontend";
@@ -3389,6 +3348,10 @@ const SHARED_BACKEND_SERVICE_CATEGORIES = new Set([
3389
3348
  "rateLimit",
3390
3349
  "search"
3391
3350
  ]);
3351
+ const SHARED_BACKEND_SERVICE_MISSING_OWNER_REASONS = {
3352
+ email: "Email integration requires a backend",
3353
+ rateLimit: "Rate limiting requires a backend"
3354
+ };
3392
3355
  function getSharedBackendServiceGraphBinding(currentStack, category) {
3393
3356
  if (!SHARED_BACKEND_SERVICE_CATEGORIES.has(category)) return void 0;
3394
3357
  if (currentStack.ecosystem === "react-native") return void 0;
@@ -3396,7 +3359,9 @@ function getSharedBackendServiceGraphBinding(currentStack, category) {
3396
3359
  role: category,
3397
3360
  ecosystem: currentStack.ecosystem,
3398
3361
  ownerRole: "backend",
3399
- ownerEcosystem: currentStack.ecosystem
3362
+ ownerEcosystem: currentStack.ecosystem,
3363
+ authoritative: true,
3364
+ missingOwnerReason: SHARED_BACKEND_SERVICE_MISSING_OWNER_REASONS[category]
3400
3365
  };
3401
3366
  }
3402
3367
  const ELIXIR_GRAPH_DISABLED_REASON_ROLES = {
@@ -3424,15 +3389,37 @@ function getElixirGraphBinding(currentStack, category) {
3424
3389
  ownerEcosystem: "elixir",
3425
3390
  currentEcosystem: "elixir",
3426
3391
  allowOwnerlessCandidate: true,
3392
+ authoritative: true,
3427
3393
  candidateIdPrefix: "candidate:native"
3428
3394
  };
3429
3395
  }
3396
+ function getAddonOrExampleGraphBinding(category, optionId) {
3397
+ if (category === "examples") return {
3398
+ role: "examples",
3399
+ ecosystem: "universal",
3400
+ allowOwnerlessCandidate: true,
3401
+ authoritative: true
3402
+ };
3403
+ if (category !== "appPlatforms") return void 0;
3404
+ const binding = getAddonStackPartBinding(optionId);
3405
+ if (!binding) return void 0;
3406
+ return {
3407
+ role: binding.role,
3408
+ ecosystem: binding.ecosystem,
3409
+ ownerRole: binding.ownerRole,
3410
+ ownerEcosystem: binding.ownerRole ? binding.ecosystem : void 0,
3411
+ allowOwnerlessCandidate: binding.ownerRole === void 0,
3412
+ authoritative: true,
3413
+ missingOwnerReason: binding.ownerRole === "frontend" ? `${optionId} requires a web frontend` : void 0
3414
+ };
3415
+ }
3430
3416
  const GRAPH_DISABLED_REASON_BINDINGS = {
3431
3417
  cssFramework: {
3432
3418
  role: "css",
3433
3419
  ecosystem: "typescript",
3434
3420
  ownerRole: "frontend",
3435
3421
  ownerEcosystem: "typescript",
3422
+ authoritative: true,
3436
3423
  missingOwnerReason: "CSS framework requires a web frontend"
3437
3424
  },
3438
3425
  uiLibrary: {
@@ -3440,6 +3427,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3440
3427
  ecosystem: "typescript",
3441
3428
  ownerRole: "frontend",
3442
3429
  ownerEcosystem: "typescript",
3430
+ authoritative: true,
3443
3431
  missingOwnerReason: "UI library requires a web frontend"
3444
3432
  },
3445
3433
  forms: {
@@ -3447,6 +3435,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3447
3435
  ecosystem: "typescript",
3448
3436
  ownerRole: "frontend",
3449
3437
  ownerEcosystem: "typescript",
3438
+ authoritative: true,
3450
3439
  missingOwnerReason: "Forms requires a web frontend"
3451
3440
  },
3452
3441
  stateManagement: {
@@ -3454,6 +3443,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3454
3443
  ecosystem: "typescript",
3455
3444
  ownerRole: "frontend",
3456
3445
  ownerEcosystem: "typescript",
3446
+ authoritative: true,
3457
3447
  missingOwnerReason: "State management requires a web frontend"
3458
3448
  },
3459
3449
  animation: {
@@ -3461,6 +3451,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3461
3451
  ecosystem: "typescript",
3462
3452
  ownerRole: "frontend",
3463
3453
  ownerEcosystem: "typescript",
3454
+ authoritative: true,
3464
3455
  missingOwnerReason: "Animation requires a web frontend"
3465
3456
  },
3466
3457
  fileUpload: {
@@ -3468,6 +3459,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3468
3459
  ecosystem: "typescript",
3469
3460
  ownerRole: "frontend",
3470
3461
  ownerEcosystem: "typescript",
3462
+ authoritative: true,
3471
3463
  missingOwnerReason: "File upload requires a web frontend"
3472
3464
  },
3473
3465
  i18n: {
@@ -3475,6 +3467,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3475
3467
  ecosystem: "typescript",
3476
3468
  ownerRole: "frontend",
3477
3469
  ownerEcosystem: "typescript",
3470
+ authoritative: true,
3478
3471
  missingOwnerReason: "i18n requires a web frontend"
3479
3472
  },
3480
3473
  analytics: {
@@ -3482,13 +3475,23 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3482
3475
  ecosystem: "typescript",
3483
3476
  ownerRole: "frontend",
3484
3477
  ownerEcosystem: "typescript",
3478
+ authoritative: true,
3485
3479
  missingOwnerReason: "Analytics requires a web frontend"
3486
3480
  },
3481
+ webDeploy: {
3482
+ role: "deploy",
3483
+ ecosystem: "typescript",
3484
+ ownerRole: "frontend",
3485
+ ownerEcosystem: "typescript",
3486
+ authoritative: true,
3487
+ missingOwnerReason: "Web deployment requires a web frontend"
3488
+ },
3487
3489
  payments: {
3488
3490
  role: "payments",
3489
3491
  ecosystem: "typescript",
3490
3492
  ownerRole: "backend",
3491
3493
  ownerEcosystem: "typescript",
3494
+ authoritative: true,
3492
3495
  missingOwnerReason: "Payments requires a backend"
3493
3496
  },
3494
3497
  cms: {
@@ -3496,19 +3499,53 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3496
3499
  ecosystem: "typescript",
3497
3500
  ownerRole: "backend",
3498
3501
  ownerEcosystem: "typescript",
3502
+ authoritative: true,
3499
3503
  missingOwnerReason: "CMS requires a backend"
3500
3504
  },
3501
3505
  ai: {
3502
3506
  role: "ai",
3503
3507
  ecosystem: "typescript",
3504
3508
  ownerRole: "backend",
3505
- ownerEcosystem: "typescript"
3509
+ ownerEcosystem: "typescript",
3510
+ authoritative: true
3511
+ },
3512
+ vectorDb: {
3513
+ role: "vectorDb",
3514
+ ecosystem: "typescript",
3515
+ ownerRole: "backend",
3516
+ ownerEcosystem: "typescript",
3517
+ currentEcosystem: "typescript",
3518
+ authoritative: true
3519
+ },
3520
+ fileStorage: {
3521
+ role: "fileStorage",
3522
+ ecosystem: "typescript",
3523
+ ownerRole: "backend",
3524
+ ownerEcosystem: "typescript",
3525
+ currentEcosystem: "typescript",
3526
+ authoritative: true
3527
+ },
3528
+ serverDeploy: {
3529
+ role: "deploy",
3530
+ ecosystem: "typescript",
3531
+ ownerRole: "backend",
3532
+ ownerEcosystem: "typescript",
3533
+ authoritative: true
3534
+ },
3535
+ dbSetup: {
3536
+ role: "dbSetup",
3537
+ ecosystem: "universal",
3538
+ ownerRole: "database",
3539
+ ownerEcosystem: "universal",
3540
+ authoritative: true,
3541
+ missingOwnerReason: "Select a database first"
3506
3542
  },
3507
3543
  mobileNavigation: {
3508
3544
  role: "navigation",
3509
3545
  ecosystem: "react-native",
3510
3546
  ownerRole: "mobile",
3511
3547
  ownerEcosystem: "react-native",
3548
+ authoritative: true,
3512
3549
  missingOwnerReason: "Mobile navigation requires a native Expo frontend"
3513
3550
  },
3514
3551
  mobileUI: {
@@ -3516,6 +3553,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3516
3553
  ecosystem: "react-native",
3517
3554
  ownerRole: "mobile",
3518
3555
  ownerEcosystem: "react-native",
3556
+ authoritative: true,
3519
3557
  missingOwnerReason: "Mobile UI requires a native Expo frontend"
3520
3558
  },
3521
3559
  mobileStorage: {
@@ -3523,6 +3561,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3523
3561
  ecosystem: "react-native",
3524
3562
  ownerRole: "mobile",
3525
3563
  ownerEcosystem: "react-native",
3564
+ authoritative: true,
3526
3565
  missingOwnerReason: "Mobile storage requires a native Expo frontend"
3527
3566
  },
3528
3567
  mobileTesting: {
@@ -3530,15 +3569,41 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3530
3569
  ecosystem: "react-native",
3531
3570
  ownerRole: "mobile",
3532
3571
  ownerEcosystem: "react-native",
3572
+ authoritative: true,
3533
3573
  missingOwnerReason: "Mobile testing requires a native Expo frontend"
3534
3574
  },
3575
+ mobilePush: {
3576
+ role: "push",
3577
+ ecosystem: "react-native",
3578
+ ownerRole: "mobile",
3579
+ ownerEcosystem: "react-native",
3580
+ authoritative: true,
3581
+ missingOwnerReason: "Mobile push requires a native Expo frontend"
3582
+ },
3583
+ mobileOTA: {
3584
+ role: "ota",
3585
+ ecosystem: "react-native",
3586
+ ownerRole: "mobile",
3587
+ ownerEcosystem: "react-native",
3588
+ authoritative: true,
3589
+ missingOwnerReason: "Mobile OTA requires a native Expo frontend"
3590
+ },
3591
+ mobileDeepLinking: {
3592
+ role: "deepLinking",
3593
+ ecosystem: "react-native",
3594
+ ownerRole: "mobile",
3595
+ ownerEcosystem: "react-native",
3596
+ authoritative: true,
3597
+ missingOwnerReason: "Mobile deep linking requires a native Expo frontend"
3598
+ },
3535
3599
  javaBuildTool: {
3536
3600
  role: "buildTool",
3537
3601
  ecosystem: "java",
3538
3602
  ownerRole: "backend",
3539
3603
  ownerEcosystem: "java",
3540
3604
  currentEcosystem: "java",
3541
- allowNoneCandidate: true
3605
+ allowNoneCandidate: true,
3606
+ authoritative: true
3542
3607
  },
3543
3608
  javaOrm: {
3544
3609
  role: "orm",
@@ -3546,6 +3611,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3546
3611
  ownerRole: "backend",
3547
3612
  ownerEcosystem: "java",
3548
3613
  currentEcosystem: "java",
3614
+ authoritative: true,
3549
3615
  missingOwnerReason: "Java ORM support currently requires Spring Boot"
3550
3616
  },
3551
3617
  javaAuth: {
@@ -3554,6 +3620,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3554
3620
  ownerRole: "backend",
3555
3621
  ownerEcosystem: "java",
3556
3622
  currentEcosystem: "java",
3623
+ authoritative: true,
3557
3624
  missingOwnerReason: "Java auth support currently requires Spring Boot"
3558
3625
  },
3559
3626
  javaLibraries: {
@@ -3562,6 +3629,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3562
3629
  ownerRole: "backend",
3563
3630
  ownerEcosystem: "java",
3564
3631
  currentEcosystem: "java",
3632
+ authoritative: true,
3565
3633
  missingOwnerReason: "Spring libraries currently require Spring Boot in the Java scaffold"
3566
3634
  },
3567
3635
  javaTestingLibraries: {
@@ -3569,21 +3637,24 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3569
3637
  ecosystem: "java",
3570
3638
  ownerRole: "backend",
3571
3639
  ownerEcosystem: "java",
3572
- currentEcosystem: "java"
3640
+ currentEcosystem: "java",
3641
+ authoritative: true
3573
3642
  },
3574
3643
  rustRealtime: {
3575
3644
  role: "realtime",
3576
3645
  ecosystem: "rust",
3577
3646
  ownerRole: "backend",
3578
3647
  ownerEcosystem: "rust",
3579
- currentEcosystem: "rust"
3648
+ currentEcosystem: "rust",
3649
+ authoritative: true
3580
3650
  },
3581
3651
  rustMessageQueue: {
3582
3652
  role: "jobQueue",
3583
3653
  ecosystem: "rust",
3584
3654
  ownerRole: "backend",
3585
3655
  ownerEcosystem: "rust",
3586
- currentEcosystem: "rust"
3656
+ currentEcosystem: "rust",
3657
+ authoritative: true
3587
3658
  },
3588
3659
  rustObservability: {
3589
3660
  role: "observability",
@@ -3591,6 +3662,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3591
3662
  ownerRole: "backend",
3592
3663
  ownerEcosystem: "rust",
3593
3664
  currentEcosystem: "rust",
3665
+ authoritative: true,
3594
3666
  candidateIdPrefix: "candidate:native"
3595
3667
  },
3596
3668
  rustTemplating: {
@@ -3598,14 +3670,16 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3598
3670
  ecosystem: "rust",
3599
3671
  ownerRole: "backend",
3600
3672
  ownerEcosystem: "rust",
3601
- currentEcosystem: "rust"
3673
+ currentEcosystem: "rust",
3674
+ authoritative: true
3602
3675
  },
3603
3676
  pythonTesting: {
3604
3677
  role: "testing",
3605
3678
  ecosystem: "python",
3606
3679
  ownerRole: "backend",
3607
3680
  ownerEcosystem: "python",
3608
- currentEcosystem: "python"
3681
+ currentEcosystem: "python",
3682
+ authoritative: true
3609
3683
  },
3610
3684
  pythonCaching: {
3611
3685
  role: "caching",
@@ -3613,6 +3687,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3613
3687
  ownerRole: "backend",
3614
3688
  ownerEcosystem: "python",
3615
3689
  currentEcosystem: "python",
3690
+ authoritative: true,
3616
3691
  candidateIdPrefix: "candidate:native"
3617
3692
  },
3618
3693
  pythonRealtime: {
@@ -3620,7 +3695,8 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3620
3695
  ecosystem: "python",
3621
3696
  ownerRole: "backend",
3622
3697
  ownerEcosystem: "python",
3623
- currentEcosystem: "python"
3698
+ currentEcosystem: "python",
3699
+ authoritative: true
3624
3700
  },
3625
3701
  pythonObservability: {
3626
3702
  role: "observability",
@@ -3628,6 +3704,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3628
3704
  ownerRole: "backend",
3629
3705
  ownerEcosystem: "python",
3630
3706
  currentEcosystem: "python",
3707
+ authoritative: true,
3631
3708
  candidateIdPrefix: "candidate:native"
3632
3709
  },
3633
3710
  pythonCli: {
@@ -3635,28 +3712,32 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3635
3712
  ecosystem: "python",
3636
3713
  ownerRole: "backend",
3637
3714
  ownerEcosystem: "python",
3638
- currentEcosystem: "python"
3715
+ currentEcosystem: "python",
3716
+ authoritative: true
3639
3717
  },
3640
3718
  goTesting: {
3641
3719
  role: "testing",
3642
3720
  ecosystem: "go",
3643
3721
  ownerRole: "backend",
3644
3722
  ownerEcosystem: "go",
3645
- currentEcosystem: "go"
3723
+ currentEcosystem: "go",
3724
+ authoritative: true
3646
3725
  },
3647
3726
  goRealtime: {
3648
3727
  role: "realtime",
3649
3728
  ecosystem: "go",
3650
3729
  ownerRole: "backend",
3651
3730
  ownerEcosystem: "go",
3652
- currentEcosystem: "go"
3731
+ currentEcosystem: "go",
3732
+ authoritative: true
3653
3733
  },
3654
3734
  goMessageQueue: {
3655
3735
  role: "jobQueue",
3656
3736
  ecosystem: "go",
3657
3737
  ownerRole: "backend",
3658
3738
  ownerEcosystem: "go",
3659
- currentEcosystem: "go"
3739
+ currentEcosystem: "go",
3740
+ authoritative: true
3660
3741
  },
3661
3742
  goCaching: {
3662
3743
  role: "caching",
@@ -3664,6 +3745,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3664
3745
  ownerRole: "backend",
3665
3746
  ownerEcosystem: "go",
3666
3747
  currentEcosystem: "go",
3748
+ authoritative: true,
3667
3749
  candidateIdPrefix: "candidate:native"
3668
3750
  },
3669
3751
  goConfig: {
@@ -3671,7 +3753,8 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3671
3753
  ecosystem: "go",
3672
3754
  ownerRole: "backend",
3673
3755
  ownerEcosystem: "go",
3674
- currentEcosystem: "go"
3756
+ currentEcosystem: "go",
3757
+ authoritative: true
3675
3758
  },
3676
3759
  goObservability: {
3677
3760
  role: "observability",
@@ -3679,6 +3762,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3679
3762
  ownerRole: "backend",
3680
3763
  ownerEcosystem: "go",
3681
3764
  currentEcosystem: "go",
3765
+ authoritative: true,
3682
3766
  candidateIdPrefix: "candidate:native"
3683
3767
  },
3684
3768
  dotnetOrm: {
@@ -3687,6 +3771,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3687
3771
  ownerRole: "backend",
3688
3772
  ownerEcosystem: "dotnet",
3689
3773
  currentEcosystem: "dotnet",
3774
+ authoritative: true,
3690
3775
  missingOwnerReason: ".NET data access requires an ASP.NET backend"
3691
3776
  },
3692
3777
  dotnetAuth: {
@@ -3695,6 +3780,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3695
3780
  ownerRole: "backend",
3696
3781
  ownerEcosystem: "dotnet",
3697
3782
  currentEcosystem: "dotnet",
3783
+ authoritative: true,
3698
3784
  missingOwnerReason: ".NET auth requires an ASP.NET backend"
3699
3785
  },
3700
3786
  dotnetApi: {
@@ -3702,28 +3788,32 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3702
3788
  ecosystem: "dotnet",
3703
3789
  ownerRole: "backend",
3704
3790
  ownerEcosystem: "dotnet",
3705
- currentEcosystem: "dotnet"
3791
+ currentEcosystem: "dotnet",
3792
+ authoritative: true
3706
3793
  },
3707
3794
  dotnetTesting: {
3708
3795
  role: "testing",
3709
3796
  ecosystem: "dotnet",
3710
3797
  ownerRole: "backend",
3711
3798
  ownerEcosystem: "dotnet",
3712
- currentEcosystem: "dotnet"
3799
+ currentEcosystem: "dotnet",
3800
+ authoritative: true
3713
3801
  },
3714
3802
  dotnetJobQueue: {
3715
3803
  role: "jobQueue",
3716
3804
  ecosystem: "dotnet",
3717
3805
  ownerRole: "backend",
3718
3806
  ownerEcosystem: "dotnet",
3719
- currentEcosystem: "dotnet"
3807
+ currentEcosystem: "dotnet",
3808
+ authoritative: true
3720
3809
  },
3721
3810
  dotnetRealtime: {
3722
3811
  role: "realtime",
3723
3812
  ecosystem: "dotnet",
3724
3813
  ownerRole: "backend",
3725
3814
  ownerEcosystem: "dotnet",
3726
- currentEcosystem: "dotnet"
3815
+ currentEcosystem: "dotnet",
3816
+ authoritative: true
3727
3817
  },
3728
3818
  dotnetObservability: {
3729
3819
  role: "observability",
@@ -3731,6 +3821,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3731
3821
  ownerRole: "backend",
3732
3822
  ownerEcosystem: "dotnet",
3733
3823
  currentEcosystem: "dotnet",
3824
+ authoritative: true,
3734
3825
  candidateIdPrefix: "candidate:native"
3735
3826
  },
3736
3827
  dotnetCaching: {
@@ -3739,6 +3830,7 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3739
3830
  ownerRole: "backend",
3740
3831
  ownerEcosystem: "dotnet",
3741
3832
  currentEcosystem: "dotnet",
3833
+ authoritative: true,
3742
3834
  candidateIdPrefix: "candidate:native"
3743
3835
  },
3744
3836
  dotnetDeploy: {
@@ -3746,7 +3838,8 @@ const GRAPH_DISABLED_REASON_BINDINGS = {
3746
3838
  ecosystem: "dotnet",
3747
3839
  ownerRole: "backend",
3748
3840
  ownerEcosystem: "dotnet",
3749
- currentEcosystem: "dotnet"
3841
+ currentEcosystem: "dotnet",
3842
+ authoritative: true
3750
3843
  }
3751
3844
  };
3752
3845
  function compatibilityInputToGraphProjectConfig(currentStack) {
@@ -3763,27 +3856,45 @@ function compatibilityInputToGraphProjectConfig(currentStack) {
3763
3856
  };
3764
3857
  }
3765
3858
  function getGraphDisabledReason(currentStack, category, optionId) {
3766
- if (optionId === "false") return null;
3767
- const binding = getSharedBackendServiceGraphBinding(currentStack, category) ?? getElixirGraphBinding(currentStack, category) ?? GRAPH_DISABLED_REASON_BINDINGS[category];
3768
- if (!binding) return null;
3769
- if (binding.currentEcosystem && currentStack.ecosystem !== binding.currentEcosystem) return null;
3770
- if (optionId === "none" && category !== "cssFramework" && !binding.allowNoneCandidate) return null;
3859
+ const unhandled = {
3860
+ handled: false,
3861
+ authoritative: false,
3862
+ reason: null
3863
+ };
3864
+ if (optionId === "false") return unhandled;
3865
+ const binding = getAddonOrExampleGraphBinding(category, optionId) ?? getSharedBackendServiceGraphBinding(currentStack, category) ?? getElixirGraphBinding(currentStack, category) ?? GRAPH_DISABLED_REASON_BINDINGS[category];
3866
+ if (!binding) return unhandled;
3867
+ if (binding.currentEcosystem && currentStack.ecosystem !== binding.currentEcosystem) return unhandled;
3868
+ if (optionId === "none" && category !== "cssFramework" && !binding.allowNoneCandidate) return unhandled;
3771
3869
  let parts;
3772
3870
  try {
3773
3871
  parts = legacyProjectConfigToStackParts(compatibilityInputToGraphProjectConfig(currentStack));
3774
3872
  } catch {
3775
- return null;
3873
+ return unhandled;
3776
3874
  }
3777
- const owner = parts.find((part) => part.role === binding.ownerRole && !part.ownerPartId && (!binding.ownerEcosystem || part.ecosystem === binding.ownerEcosystem));
3778
- if (!owner && optionId === "none") return null;
3779
- if (!owner && !binding.allowOwnerlessCandidate) return binding.missingOwnerReason ?? null;
3780
- return getStackPartCompatibilityIssueForPart({
3875
+ const owner = binding.ownerRole ? parts.find((part) => part.role === binding.ownerRole && !part.ownerPartId && (!binding.ownerEcosystem || part.ecosystem === binding.ownerEcosystem)) : void 0;
3876
+ if (!owner && optionId === "none") return unhandled;
3877
+ if (!owner && !binding.allowOwnerlessCandidate) return {
3878
+ handled: true,
3879
+ authoritative: binding.authoritative === true,
3880
+ reason: binding.missingOwnerReason ?? null
3881
+ };
3882
+ const issue = getStackPartCompatibilityIssueForPart({
3781
3883
  id: `${binding.candidateIdPrefix ?? "candidate"}:${binding.ownerRole}.${binding.role}:${binding.ecosystem}:${optionId}`,
3782
3884
  role: binding.role,
3783
3885
  toolId: optionId,
3784
3886
  ecosystem: binding.ecosystem,
3785
- ownerPartId: owner?.id
3786
- }, parts)?.message ?? (!owner ? binding.missingOwnerReason ?? null : null);
3887
+ ownerPartId: owner?.id,
3888
+ settings: {
3889
+ astroIntegration: currentStack.astroIntegration,
3890
+ ecosystem: currentStack.ecosystem
3891
+ }
3892
+ }, parts);
3893
+ return {
3894
+ handled: true,
3895
+ authoritative: binding.authoritative === true,
3896
+ reason: issue?.message ?? (!owner ? binding.missingOwnerReason ?? null : null)
3897
+ };
3787
3898
  }
3788
3899
  const WEB_FRAMEWORKS = [
3789
3900
  "tanstack-router",
@@ -5200,11 +5311,7 @@ const GRAPH_SHADCN_FLAG_KEYS = [
5200
5311
  ["shadcnFont", "shadcn-font"],
5201
5312
  ["shadcnRadius", "shadcn-radius"]
5202
5313
  ];
5203
- const GRAPH_MOBILE_FLAG_KEYS = [
5204
- ["mobilePush", "mobile-push"],
5205
- ["mobileOTA", "mobile-ota"],
5206
- ["mobileDeepLinking", "mobile-deep-linking"]
5207
- ];
5314
+ const GRAPH_MOBILE_FLAG_KEYS = [];
5208
5315
  const GRAPH_TYPESCRIPT_BACKEND_FLAG_KEYS = [["backendLibraries", "effect"]];
5209
5316
  const GRAPH_SHARED_BACKEND_FLAG_KEYS = [
5210
5317
  ["email", "email"],
@@ -5272,24 +5379,40 @@ const GRAPH_MOBILE_PART_SELECTION_KEYS = [
5272
5379
  ["mobileNavigation", "navigation"],
5273
5380
  ["mobileUI", "ui"],
5274
5381
  ["mobileStorage", "storage"],
5275
- ["mobileTesting", "testing"]
5382
+ ["mobileTesting", "testing"],
5383
+ ["mobilePush", "push"],
5384
+ ["mobileOTA", "ota"],
5385
+ ["mobileDeepLinking", "deepLinking"]
5276
5386
  ];
5277
5387
  const GRAPH_RUST_BACKEND_PART_SELECTION_KEYS = [
5278
5388
  ["rustCli", "cli"],
5279
5389
  ["rustLogging", "logging"],
5280
5390
  ["rustErrorHandling", "errorHandling"],
5391
+ ["caching", "caching"],
5392
+ ["search", "search"],
5281
5393
  ["rustCaching", "caching"]
5282
5394
  ];
5283
5395
  const GRAPH_RUST_BACKEND_ARRAY_PART_SELECTION_KEYS = [["rustLibraries", "libraries"]];
5284
5396
  const GRAPH_PYTHON_BACKEND_PART_SELECTION_KEYS = [
5285
5397
  ["pythonValidation", "validation"],
5286
5398
  ["pythonTaskQueue", "jobQueue"],
5287
- ["pythonGraphql", "api"],
5288
- ["pythonQuality", "codeQuality"]
5399
+ ["pythonGraphql", "graphql"],
5400
+ ["pythonQuality", "codeQuality"],
5401
+ ["caching", "caching"],
5402
+ ["search", "search"]
5289
5403
  ];
5290
5404
  const GRAPH_PYTHON_BACKEND_ARRAY_PART_SELECTION_KEYS = [["pythonAi", "ai"]];
5291
- const GRAPH_GO_BACKEND_PART_SELECTION_KEYS = [["goCli", "cli"], ["goLogging", "logging"]];
5292
- const GRAPH_JAVA_BACKEND_PART_SELECTION_KEYS = [["javaBuildTool", "buildTool"]];
5405
+ const GRAPH_GO_BACKEND_PART_SELECTION_KEYS = [
5406
+ ["goCli", "cli"],
5407
+ ["goLogging", "logging"],
5408
+ ["caching", "caching"],
5409
+ ["search", "search"]
5410
+ ];
5411
+ const GRAPH_JAVA_BACKEND_PART_SELECTION_KEYS = [
5412
+ ["javaBuildTool", "buildTool"],
5413
+ ["caching", "caching"],
5414
+ ["search", "search"]
5415
+ ];
5293
5416
  const GRAPH_JAVA_BACKEND_ARRAY_PART_SELECTION_KEYS = [["javaLibraries", "libraries"], ["javaTestingLibraries", "testing"]];
5294
5417
  const GRAPH_DOTNET_BACKEND_PART_SELECTION_KEYS = [
5295
5418
  ["dotnetOrm", "orm"],
@@ -5347,24 +5470,40 @@ const GRAPH_MOBILE_PART_CLI_KEYS = [
5347
5470
  ["mobileNavigation", "navigation"],
5348
5471
  ["mobileUI", "ui"],
5349
5472
  ["mobileStorage", "storage"],
5350
- ["mobileTesting", "testing"]
5473
+ ["mobileTesting", "testing"],
5474
+ ["mobilePush", "push"],
5475
+ ["mobileOTA", "ota"],
5476
+ ["mobileDeepLinking", "deepLinking"]
5351
5477
  ];
5352
5478
  const GRAPH_RUST_BACKEND_PART_CLI_KEYS = [
5353
5479
  ["rustCli", "cli"],
5354
5480
  ["rustLogging", "logging"],
5355
5481
  ["rustErrorHandling", "errorHandling"],
5482
+ ["caching", "caching"],
5483
+ ["search", "search"],
5356
5484
  ["rustCaching", "caching"]
5357
5485
  ];
5358
5486
  const GRAPH_RUST_BACKEND_ARRAY_PART_CLI_KEYS = [["rustLibraries", "libraries"]];
5359
5487
  const GRAPH_PYTHON_BACKEND_PART_CLI_KEYS = [
5360
5488
  ["pythonValidation", "validation"],
5361
5489
  ["pythonTaskQueue", "jobQueue"],
5362
- ["pythonGraphql", "api"],
5363
- ["pythonQuality", "codeQuality"]
5490
+ ["pythonGraphql", "graphql"],
5491
+ ["pythonQuality", "codeQuality"],
5492
+ ["caching", "caching"],
5493
+ ["search", "search"]
5364
5494
  ];
5365
5495
  const GRAPH_PYTHON_BACKEND_ARRAY_PART_CLI_KEYS = [["pythonAi", "ai"]];
5366
- const GRAPH_GO_BACKEND_PART_CLI_KEYS = [["goCli", "cli"], ["goLogging", "logging"]];
5367
- const GRAPH_JAVA_BACKEND_PART_CLI_KEYS = [["javaBuildTool", "buildTool"]];
5496
+ const GRAPH_GO_BACKEND_PART_CLI_KEYS = [
5497
+ ["goCli", "cli"],
5498
+ ["goLogging", "logging"],
5499
+ ["caching", "caching"],
5500
+ ["search", "search"]
5501
+ ];
5502
+ const GRAPH_JAVA_BACKEND_PART_CLI_KEYS = [
5503
+ ["javaBuildTool", "buildTool"],
5504
+ ["caching", "caching"],
5505
+ ["search", "search"]
5506
+ ];
5368
5507
  const GRAPH_JAVA_BACKEND_ARRAY_PART_CLI_KEYS = [["javaLibraries", "libraries"], ["javaTestingLibraries", "testing"]];
5369
5508
  const GRAPH_DOTNET_BACKEND_PART_CLI_KEYS = [
5370
5509
  ["dotnetOrm", "orm"],
@@ -5629,12 +5768,16 @@ function getCliScopedPartFields(input) {
5629
5768
  function mapBackendToCli(backend) {
5630
5769
  return SELF_BACKENDS.has(backend) ? "self" : backend;
5631
5770
  }
5771
+ function getSelectableStackPartSpecs(specs) {
5772
+ return specs.filter((spec) => spec.split(":")[2] !== "none");
5773
+ }
5632
5774
  function isGraphStackSelection(selection) {
5633
- return (selection.stackMode === "multi" || String(selection.stackMode) === "graph") && selection.stackPartSpecs.length > 0;
5775
+ return (selection.stackMode === "multi" || String(selection.stackMode) === "graph") && getSelectableStackPartSpecs(selection.stackPartSpecs).length > 0;
5634
5776
  }
5635
5777
  function getGraphStackParts(selection) {
5636
- const stackParts = parseStackPartSpecs(expandScopedStackPartSpecs(selection.stackPartSpecs, getSelectionScopedPartFields(selection)), "selected");
5637
- const validation = validateStackParts(stackParts);
5778
+ const stackPartSpecs = expandScopedStackPartSpecs(selection.stackPartSpecs, getSelectionScopedPartFields(selection));
5779
+ const stackParts = parseStackPartSpecs(stackPartSpecs, "selected");
5780
+ const validation = validateStackParts(parseStackPartSpecs(getSelectableStackPartSpecs(stackPartSpecs), "selected"));
5638
5781
  if (validation.issues.length > 0) throw new Error(validation.issues.map((issue) => issue.message).join("\n"));
5639
5782
  return stackParts;
5640
5783
  }
@@ -5721,7 +5864,7 @@ function getCliGraphStackParts(input) {
5721
5864
  addScopedBackendPart("rust", "auth", input.rustAuth);
5722
5865
  addScopedBackendPart("python", "orm", input.pythonOrm);
5723
5866
  addScopedBackendPart("python", "api", input.pythonApi);
5724
- addScopedBackendPart("python", "api", input.pythonGraphql);
5867
+ addScopedBackendPart("python", "graphql", input.pythonGraphql);
5725
5868
  addScopedBackendPart("python", "auth", input.pythonAuth);
5726
5869
  addScopedBackendPart("go", "orm", input.goOrm);
5727
5870
  addScopedBackendPart("go", "api", input.goApi);
@@ -5738,6 +5881,7 @@ function getCliGraphStackParts(input) {
5738
5881
  }
5739
5882
  function buildProjectConfigBase(selection, projectName, relativePath, install) {
5740
5883
  const stack = getAdjustedSelection(selection);
5884
+ const graphStack = isGraphStackSelection(selection) ? selection : stack;
5741
5885
  const frontend = [...toUniqueNonNoneArray(stack.webFrontend), ...toUniqueNonNoneArray(stack.nativeFrontend)];
5742
5886
  const baseConfig = {
5743
5887
  projectName,
@@ -5880,8 +6024,8 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
5880
6024
  elixirLibraries: toUniqueNonNoneArray(stack.elixirLibraries),
5881
6025
  aiDocs: toUniqueNonNoneArray(stack.aiDocs)
5882
6026
  };
5883
- if (!isGraphStackSelection(stack)) return baseConfig;
5884
- const stackParts = getGraphStackParts(stack);
6027
+ if (!isGraphStackSelection(graphStack)) return baseConfig;
6028
+ const stackParts = getGraphStackParts(graphStack);
5885
6029
  const loweredGraphConfig = stackPartsToLegacyProjectConfigPartial(stackParts);
5886
6030
  return {
5887
6031
  ...baseConfig,
@@ -5954,7 +6098,7 @@ function generateGraphCommand(selection, projectName) {
5954
6098
  const hasNonTypeScriptBackend = hasRustBackend || hasPythonBackend || hasGoBackend || hasJavaBackend || hasDotnetBackend || hasElixirBackend;
5955
6099
  const hasMobile = hasGraphPrimaryPart(stackParts, "mobile");
5956
6100
  const flags = [
5957
- ...stackParts.filter((part) => part.source !== "provided").map((part) => `--part ${formatStackPartSpec(part, stackParts)}`),
6101
+ ...stackParts.filter((part) => part.source !== "provided" && part.toolId !== "none").map((part) => `--part ${formatStackPartSpec(part, stackParts)}`),
5958
6102
  ...hasTypeScriptFrontend ? formatChangedStringFlags(selection, GRAPH_TYPESCRIPT_FRONTEND_FLAG_KEYS) : [],
5959
6103
  ...hasAstroFrontend && selection.astroIntegration !== "none" ? [`--astro-integration ${selection.astroIntegration}`] : [],
5960
6104
  ...hasTypeScriptFrontend && selection.uiLibrary === "shadcn-ui" ? formatChangedStringFlags(selection, GRAPH_SHADCN_FLAG_KEYS) : [],
@@ -6216,4 +6360,4 @@ function generateStackSelectionCommand(selection) {
6216
6360
 
6217
6361
  //#endregion
6218
6362
  export { getCategoryDisplayName as $, getCompatibleFormLibraries as A, validateAddonCompatibility as B, allowedApisForFrontends as C, getApiFrontendCompatibilityIssue as D, getAIFrontendCompatibilityIssue as E, isOptionCompatible as F, GO_CATEGORY_ORDER as G, CATEGORY_ORDER as H, isWebFrontend as I, PYTHON_CATEGORY_ORDER as J, JAVA_CATEGORY_ORDER as K, requiresChatSdkVercelAI as L, getDisabledReason as M, hasWebStyling as N, getCompatibleAddons as O, isFrontendAllowedWithBackend as P, getCategoryCliValues as Q, requiresChatSdkVercelAIForSelection as R, usesVirtualNoneStackSelection as S, evaluateCompatibility as T, DOTNET_CATEGORY_ORDER as U, validateProjectName as V, ELIXIR_CATEGORY_ORDER as W, RUST_CATEGORY_ORDER as X, REACT_NATIVE_CATEGORY_ORDER as Y, TYPESCRIPT_CATEGORY_ORDER as Z, parseStackSelectionFromSearch as _, STACK_SELECTION_URL_KEYS as a, getCapabilityDefinitions as at, stackSelectionToCliComparableConfig as b, cloneDefaultStackSelection as c, normalizeCapabilitySelection as ct, isArrayStackSelectionKey as d, getCategoryOptionIds as et, isCliDefaultStackSelection as f, normalizeStackSelectionValue as g, normalizeStackSelection as h, STACK_SELECTION_OPTION_CATEGORY_BY_KEY as i, normalizeOptionId as it, getCompatibleUILibraries as j, getCompatibleCSSFrameworks as k, createStackSelectionSearchParams as l, isStackSelectionDefault as m, NON_OPTION_STACK_SELECTION_KEYS as n, getOptionMetadata as nt, VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS as o, getCapabilityDisabledReason as ot, isGraphStackSelection as p, OPTION_CATEGORY_METADATA as q, STACK_SELECTION_KEYS as r, isMultiSelectCategory as rt, cliInputToProjectConfigPartial as s, getSupportedCapabilityOptions as st, DEFAULT_STACK_SELECTION as t, getCategoryOrderForEcosystem as tt, generateStackSelectionCommand as u, parseStackSelectionFromUrlRecord as v, analyzeStackCompatibility as w, stackSelectionToProjectConfig as x, processCliArrayOption as y, splitFrontends as z };
6219
- //# sourceMappingURL=stack-translation-gNYPvlYt.mjs.map
6363
+ //# sourceMappingURL=stack-translation-DNT-iMAE.mjs.map