create-better-fullstack 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import "./bts-config-CSvxsFML.mjs";
3
+ import { i as setupLefthook, n as setupBiome, r as setupHusky, t as setupAddons } from "./addons-setup-DqVFXnDv.mjs";
4
+
5
+ export { setupAddons };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { m as dependencyVersionMap, t as readBtsConfig } from "./bts-config-BMniWIbd.mjs";
2
+ import { m as dependencyVersionMap, t as readBtsConfig } from "./bts-config-CSvxsFML.mjs";
3
3
  import { autocompleteMultiselect, cancel, group, isCancel, log, multiselect, select, spinner } from "@clack/prompts";
4
4
  import pc from "picocolors";
5
5
  import fs from "fs-extra";
@@ -179,7 +179,8 @@ function getGraphSummary(config) {
179
179
  const database = getPrimaryGraphPart(config, "database");
180
180
  const orm = selectedParts.find((part) => part.role === "orm");
181
181
  const segments = [labelFor(frontend), labelFor(backend)].filter(Boolean);
182
- const dataLabel = [labelFor(orm), labelFor(database)].filter(Boolean).join("/");
182
+ const databaseLabel = backend?.ecosystem === "java" && orm?.toolId === "spring-data-jpa" ? "H2 dev database" : labelFor(database);
183
+ const dataLabel = [labelFor(orm), databaseLabel].filter(Boolean).join("/");
183
184
  if (dataLabel) segments.push(dataLabel);
184
185
  return segments.length > 0 ? segments.join(" + ") : selectedParts.map((part) => (0, types_exports.formatStackPartSpec)(part, selectedParts)).join(" + ");
185
186
  }
@@ -223,8 +224,75 @@ function getGraphBackendDeployInstructions(config) {
223
224
  //#endregion
224
225
  //#region src/utils/bts-config.ts
225
226
  const BTS_CONFIG_FILE = "bts.jsonc";
227
+ function normalizeGraphConfigForPersistence(projectConfig, stackParts) {
228
+ if (!stackParts) return projectConfig;
229
+ const legacyConfig = (0, types_exports.stackPartsToLegacyProjectConfigPartial)(stackParts);
230
+ const selectedEcosystems = new Set(stackParts.filter((part) => part.source !== "provided").map((part) => part.ecosystem));
231
+ const normalized = {
232
+ ...projectConfig,
233
+ ...legacyConfig
234
+ };
235
+ if (!selectedEcosystems.has("rust")) {
236
+ normalized.rustWebFramework = "none";
237
+ normalized.rustFrontend = "none";
238
+ normalized.rustOrm = "none";
239
+ normalized.rustApi = "none";
240
+ normalized.rustCli = "none";
241
+ normalized.rustLibraries = [];
242
+ normalized.rustLogging = "none";
243
+ normalized.rustErrorHandling = "none";
244
+ normalized.rustCaching = "none";
245
+ normalized.rustAuth = "none";
246
+ }
247
+ if (!selectedEcosystems.has("python")) {
248
+ normalized.pythonWebFramework = "none";
249
+ normalized.pythonOrm = "none";
250
+ normalized.pythonValidation = "none";
251
+ normalized.pythonAi = [];
252
+ normalized.pythonAuth = "none";
253
+ normalized.pythonApi = "none";
254
+ normalized.pythonTaskQueue = "none";
255
+ normalized.pythonGraphql = "none";
256
+ normalized.pythonQuality = "none";
257
+ }
258
+ if (!selectedEcosystems.has("go")) {
259
+ normalized.goWebFramework = "none";
260
+ normalized.goOrm = "none";
261
+ normalized.goApi = "none";
262
+ normalized.goCli = "none";
263
+ normalized.goLogging = "none";
264
+ normalized.goAuth = "none";
265
+ }
266
+ if (!selectedEcosystems.has("java")) {
267
+ normalized.javaWebFramework = "none";
268
+ normalized.javaBuildTool = "none";
269
+ normalized.javaOrm = "none";
270
+ normalized.javaAuth = "none";
271
+ normalized.javaLibraries = [];
272
+ normalized.javaTestingLibraries = [];
273
+ }
274
+ if (!selectedEcosystems.has("elixir")) {
275
+ normalized.elixirWebFramework = "none";
276
+ normalized.elixirOrm = "none";
277
+ normalized.elixirAuth = "none";
278
+ normalized.elixirApi = "none";
279
+ normalized.elixirRealtime = "none";
280
+ normalized.elixirJobs = "none";
281
+ normalized.elixirValidation = "none";
282
+ normalized.elixirHttp = "none";
283
+ normalized.elixirJson = "none";
284
+ normalized.elixirEmail = "none";
285
+ normalized.elixirCaching = "none";
286
+ normalized.elixirObservability = "none";
287
+ normalized.elixirTesting = "none";
288
+ normalized.elixirQuality = "none";
289
+ normalized.elixirDeploy = "none";
290
+ }
291
+ return normalized;
292
+ }
226
293
  async function writeBtsConfig(projectConfig) {
227
294
  const stackParts = projectConfig.stackParts ?? (0, types_exports.legacyProjectConfigToStackParts)(projectConfig);
295
+ const persistedConfig = normalizeGraphConfigForPersistence(projectConfig, projectConfig.stackParts);
228
296
  const graphSummary = projectConfig.stackParts ? getGraphSummary({ stackParts }) : null;
229
297
  const effectiveStack = projectConfig.stackParts ? getEffectiveStack({ stackParts }) : void 0;
230
298
  const btsConfig = {
@@ -234,98 +302,98 @@ async function writeBtsConfig(projectConfig) {
234
302
  graphSummary,
235
303
  effectiveStack
236
304
  } : {},
237
- ecosystem: projectConfig.ecosystem,
238
- database: projectConfig.database,
239
- orm: projectConfig.orm,
240
- backend: projectConfig.backend,
241
- runtime: projectConfig.runtime,
242
- frontend: projectConfig.frontend,
243
- addons: projectConfig.addons,
244
- examples: projectConfig.examples,
245
- auth: projectConfig.auth,
246
- payments: projectConfig.payments,
247
- email: projectConfig.email,
248
- fileUpload: projectConfig.fileUpload,
249
- effect: projectConfig.effect,
250
- ai: projectConfig.ai,
251
- stateManagement: projectConfig.stateManagement,
252
- validation: projectConfig.validation,
253
- forms: projectConfig.forms,
254
- testing: projectConfig.testing,
255
- packageManager: projectConfig.packageManager,
256
- versionChannel: projectConfig.versionChannel,
257
- dbSetup: projectConfig.dbSetup,
258
- api: projectConfig.api,
259
- webDeploy: projectConfig.webDeploy,
260
- serverDeploy: projectConfig.serverDeploy,
261
- cssFramework: projectConfig.cssFramework,
262
- uiLibrary: projectConfig.uiLibrary,
263
- realtime: projectConfig.realtime,
264
- jobQueue: projectConfig.jobQueue,
265
- animation: projectConfig.animation,
266
- logging: projectConfig.logging,
267
- observability: projectConfig.observability,
268
- featureFlags: projectConfig.featureFlags,
269
- analytics: projectConfig.analytics,
270
- mobileNavigation: projectConfig.mobileNavigation,
271
- mobileUI: projectConfig.mobileUI,
272
- mobileStorage: projectConfig.mobileStorage,
273
- mobileTesting: projectConfig.mobileTesting,
274
- mobilePush: projectConfig.mobilePush,
275
- mobileOTA: projectConfig.mobileOTA,
276
- mobileDeepLinking: projectConfig.mobileDeepLinking,
277
- cms: projectConfig.cms,
278
- caching: projectConfig.caching,
279
- i18n: projectConfig.i18n,
280
- search: projectConfig.search,
281
- fileStorage: projectConfig.fileStorage,
282
- rustWebFramework: projectConfig.rustWebFramework,
283
- rustFrontend: projectConfig.rustFrontend,
284
- rustOrm: projectConfig.rustOrm,
285
- rustApi: projectConfig.rustApi,
286
- rustCli: projectConfig.rustCli,
287
- rustLibraries: projectConfig.rustLibraries,
288
- rustLogging: projectConfig.rustLogging,
289
- rustErrorHandling: projectConfig.rustErrorHandling,
290
- rustCaching: projectConfig.rustCaching,
291
- rustAuth: projectConfig.rustAuth,
292
- pythonWebFramework: projectConfig.pythonWebFramework,
293
- pythonOrm: projectConfig.pythonOrm,
294
- pythonValidation: projectConfig.pythonValidation,
295
- pythonAi: projectConfig.pythonAi,
296
- pythonAuth: projectConfig.pythonAuth,
297
- pythonApi: projectConfig.pythonApi,
298
- pythonTaskQueue: projectConfig.pythonTaskQueue,
299
- pythonGraphql: projectConfig.pythonGraphql,
300
- pythonQuality: projectConfig.pythonQuality,
301
- goWebFramework: projectConfig.goWebFramework,
302
- goOrm: projectConfig.goOrm,
303
- goApi: projectConfig.goApi,
304
- goCli: projectConfig.goCli,
305
- goLogging: projectConfig.goLogging,
306
- goAuth: projectConfig.goAuth,
307
- javaWebFramework: projectConfig.javaWebFramework,
308
- javaBuildTool: projectConfig.javaBuildTool,
309
- javaOrm: projectConfig.javaOrm,
310
- javaAuth: projectConfig.javaAuth,
311
- javaLibraries: projectConfig.javaLibraries,
312
- javaTestingLibraries: projectConfig.javaTestingLibraries,
313
- elixirWebFramework: projectConfig.elixirWebFramework,
314
- elixirOrm: projectConfig.elixirOrm,
315
- elixirAuth: projectConfig.elixirAuth,
316
- elixirApi: projectConfig.elixirApi,
317
- elixirRealtime: projectConfig.elixirRealtime,
318
- elixirJobs: projectConfig.elixirJobs,
319
- elixirValidation: projectConfig.elixirValidation,
320
- elixirHttp: projectConfig.elixirHttp,
321
- elixirJson: projectConfig.elixirJson,
322
- elixirEmail: projectConfig.elixirEmail,
323
- elixirCaching: projectConfig.elixirCaching,
324
- elixirObservability: projectConfig.elixirObservability,
325
- elixirTesting: projectConfig.elixirTesting,
326
- elixirQuality: projectConfig.elixirQuality,
327
- elixirDeploy: projectConfig.elixirDeploy,
328
- aiDocs: projectConfig.aiDocs,
305
+ ecosystem: persistedConfig.ecosystem,
306
+ database: persistedConfig.database,
307
+ orm: persistedConfig.orm,
308
+ backend: persistedConfig.backend,
309
+ runtime: persistedConfig.runtime,
310
+ frontend: persistedConfig.frontend,
311
+ addons: persistedConfig.addons,
312
+ examples: persistedConfig.examples,
313
+ auth: persistedConfig.auth,
314
+ payments: persistedConfig.payments,
315
+ email: persistedConfig.email,
316
+ fileUpload: persistedConfig.fileUpload,
317
+ effect: persistedConfig.effect,
318
+ ai: persistedConfig.ai,
319
+ stateManagement: persistedConfig.stateManagement,
320
+ validation: persistedConfig.validation,
321
+ forms: persistedConfig.forms,
322
+ testing: persistedConfig.testing,
323
+ packageManager: persistedConfig.packageManager,
324
+ versionChannel: persistedConfig.versionChannel,
325
+ dbSetup: persistedConfig.dbSetup,
326
+ api: persistedConfig.api,
327
+ webDeploy: persistedConfig.webDeploy,
328
+ serverDeploy: persistedConfig.serverDeploy,
329
+ cssFramework: persistedConfig.cssFramework,
330
+ uiLibrary: persistedConfig.uiLibrary,
331
+ realtime: persistedConfig.realtime,
332
+ jobQueue: persistedConfig.jobQueue,
333
+ animation: persistedConfig.animation,
334
+ logging: persistedConfig.logging,
335
+ observability: persistedConfig.observability,
336
+ featureFlags: persistedConfig.featureFlags,
337
+ analytics: persistedConfig.analytics,
338
+ mobileNavigation: persistedConfig.mobileNavigation,
339
+ mobileUI: persistedConfig.mobileUI,
340
+ mobileStorage: persistedConfig.mobileStorage,
341
+ mobileTesting: persistedConfig.mobileTesting,
342
+ mobilePush: persistedConfig.mobilePush,
343
+ mobileOTA: persistedConfig.mobileOTA,
344
+ mobileDeepLinking: persistedConfig.mobileDeepLinking,
345
+ cms: persistedConfig.cms,
346
+ caching: persistedConfig.caching,
347
+ i18n: persistedConfig.i18n,
348
+ search: persistedConfig.search,
349
+ fileStorage: persistedConfig.fileStorage,
350
+ rustWebFramework: persistedConfig.rustWebFramework,
351
+ rustFrontend: persistedConfig.rustFrontend,
352
+ rustOrm: persistedConfig.rustOrm,
353
+ rustApi: persistedConfig.rustApi,
354
+ rustCli: persistedConfig.rustCli,
355
+ rustLibraries: persistedConfig.rustLibraries,
356
+ rustLogging: persistedConfig.rustLogging,
357
+ rustErrorHandling: persistedConfig.rustErrorHandling,
358
+ rustCaching: persistedConfig.rustCaching,
359
+ rustAuth: persistedConfig.rustAuth,
360
+ pythonWebFramework: persistedConfig.pythonWebFramework,
361
+ pythonOrm: persistedConfig.pythonOrm,
362
+ pythonValidation: persistedConfig.pythonValidation,
363
+ pythonAi: persistedConfig.pythonAi,
364
+ pythonAuth: persistedConfig.pythonAuth,
365
+ pythonApi: persistedConfig.pythonApi,
366
+ pythonTaskQueue: persistedConfig.pythonTaskQueue,
367
+ pythonGraphql: persistedConfig.pythonGraphql,
368
+ pythonQuality: persistedConfig.pythonQuality,
369
+ goWebFramework: persistedConfig.goWebFramework,
370
+ goOrm: persistedConfig.goOrm,
371
+ goApi: persistedConfig.goApi,
372
+ goCli: persistedConfig.goCli,
373
+ goLogging: persistedConfig.goLogging,
374
+ goAuth: persistedConfig.goAuth,
375
+ javaWebFramework: persistedConfig.javaWebFramework,
376
+ javaBuildTool: persistedConfig.javaBuildTool,
377
+ javaOrm: persistedConfig.javaOrm,
378
+ javaAuth: persistedConfig.javaAuth,
379
+ javaLibraries: persistedConfig.javaLibraries,
380
+ javaTestingLibraries: persistedConfig.javaTestingLibraries,
381
+ elixirWebFramework: persistedConfig.elixirWebFramework,
382
+ elixirOrm: persistedConfig.elixirOrm,
383
+ elixirAuth: persistedConfig.elixirAuth,
384
+ elixirApi: persistedConfig.elixirApi,
385
+ elixirRealtime: persistedConfig.elixirRealtime,
386
+ elixirJobs: persistedConfig.elixirJobs,
387
+ elixirValidation: persistedConfig.elixirValidation,
388
+ elixirHttp: persistedConfig.elixirHttp,
389
+ elixirJson: persistedConfig.elixirJson,
390
+ elixirEmail: persistedConfig.elixirEmail,
391
+ elixirCaching: persistedConfig.elixirCaching,
392
+ elixirObservability: persistedConfig.elixirObservability,
393
+ elixirTesting: persistedConfig.elixirTesting,
394
+ elixirQuality: persistedConfig.elixirQuality,
395
+ elixirDeploy: persistedConfig.elixirDeploy,
396
+ aiDocs: persistedConfig.aiDocs,
329
397
  stackParts
330
398
  };
331
399
  const baseContent = {
package/dist/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  //#region src/cli.ts
3
- if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-YvDMaVXB.mjs").then((m) => m.startMcpServer());
3
+ if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-DfnYbMju.mjs").then((m) => m.startMcpServer());
4
4
  else import("./index.mjs").then((m) => m.createBtsCli().run());
5
5
 
6
6
  //#endregion
package/dist/index.d.mts CHANGED
@@ -22,10 +22,10 @@ declare const router: {
22
22
  create: _orpc_server0.Procedure<_orpc_server0.MergedInitialContext<Record<never, never>, Record<never, never>, Record<never, never>>, Record<never, never>, z.ZodTuple<[z.ZodOptional<z.ZodString>, z.ZodObject<{
23
23
  template: z.ZodOptional<z.ZodEnum<{
24
24
  none: "none";
25
+ uniwind: "uniwind";
25
26
  mern: "mern";
26
27
  pern: "pern";
27
28
  t3: "t3";
28
- uniwind: "uniwind";
29
29
  }>>;
30
30
  yes: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
31
31
  yolo: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
@@ -97,8 +97,8 @@ declare const router: {
97
97
  uppy: "uppy";
98
98
  }>>;
99
99
  effect: z.ZodOptional<z.ZodEnum<{
100
- none: "none";
101
100
  effect: "effect";
101
+ none: "none";
102
102
  "effect-full": "effect-full";
103
103
  }>>;
104
104
  stateManagement: z.ZodOptional<z.ZodEnum<{
@@ -240,9 +240,9 @@ declare const router: {
240
240
  }>>;
241
241
  mobileUI: z.ZodOptional<z.ZodEnum<{
242
242
  none: "none";
243
- uniwind: "uniwind";
244
243
  tamagui: "tamagui";
245
244
  "gluestack-ui": "gluestack-ui";
245
+ uniwind: "uniwind";
246
246
  unistyles: "unistyles";
247
247
  }>>;
248
248
  mobileStorage: z.ZodOptional<z.ZodEnum<{
@@ -323,8 +323,8 @@ declare const router: {
323
323
  "docker-compose": "docker-compose";
324
324
  }>>>;
325
325
  examples: z.ZodOptional<z.ZodArray<z.ZodEnum<{
326
- none: "none";
327
326
  ai: "ai";
327
+ none: "none";
328
328
  "chat-sdk": "chat-sdk";
329
329
  "tanstack-showcase": "tanstack-showcase";
330
330
  }>>>;
@@ -389,6 +389,7 @@ declare const router: {
389
389
  "postcss-only": "postcss-only";
390
390
  }>>;
391
391
  uiLibrary: z.ZodOptional<z.ZodEnum<{
392
+ mui: "mui";
392
393
  none: "none";
393
394
  "shadcn-ui": "shadcn-ui";
394
395
  "shadcn-svelte": "shadcn-svelte";
@@ -399,7 +400,6 @@ declare const router: {
399
400
  "chakra-ui": "chakra-ui";
400
401
  nextui: "nextui";
401
402
  mantine: "mantine";
402
- mui: "mui";
403
403
  antd: "antd";
404
404
  "base-ui": "base-ui";
405
405
  "ark-ui": "ark-ui";
@@ -496,10 +496,10 @@ declare const router: {
496
496
  vercel: "vercel";
497
497
  }>>;
498
498
  directoryConflict: z.ZodOptional<z.ZodEnum<{
499
+ error: "error";
499
500
  merge: "merge";
500
501
  overwrite: "overwrite";
501
502
  increment: "increment";
502
- error: "error";
503
503
  }>>;
504
504
  renderTitle: z.ZodOptional<z.ZodBoolean>;
505
505
  disableAnalytics: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
@@ -633,8 +633,8 @@ declare const router: {
633
633
  chi: "chi";
634
634
  }>>;
635
635
  goOrm: z.ZodOptional<z.ZodEnum<{
636
- none: "none";
637
636
  gorm: "gorm";
637
+ none: "none";
638
638
  sqlc: "sqlc";
639
639
  ent: "ent";
640
640
  }>>;
@@ -828,7 +828,7 @@ declare const router: {
828
828
  testing: "none" | "vitest" | "playwright" | "vitest-playwright" | "jest" | "cypress";
829
829
  email: "none" | "react-email" | "resend" | "nodemailer" | "postmark" | "sendgrid" | "aws-ses" | "mailgun" | "plunk";
830
830
  cssFramework: "none" | "tailwind" | "scss" | "less" | "postcss-only";
831
- uiLibrary: "none" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "mui" | "antd" | "base-ui" | "ark-ui" | "react-aria";
831
+ uiLibrary: "none" | "mui" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "antd" | "base-ui" | "ark-ui" | "react-aria";
832
832
  validation: "none" | "zod" | "valibot" | "arktype" | "typebox" | "typia" | "runtypes" | "effect-schema";
833
833
  realtime: "none" | "socket-io" | "partykit" | "ably" | "pusher" | "liveblocks" | "yjs";
834
834
  jobQueue: "none" | "bullmq" | "trigger-dev" | "inngest" | "temporal";
@@ -907,7 +907,7 @@ declare const router: {
907
907
  shadcnRadius?: "default" | "none" | "small" | "medium" | "large" | undefined;
908
908
  stackParts?: {
909
909
  id: string;
910
- role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "mobile" | "deploy" | "ui" | "css" | "appPlatform";
910
+ role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "css" | "ui" | "mobile" | "deploy" | "appPlatform";
911
911
  toolId: string;
912
912
  ecosystem: "typescript" | "react-native" | "rust" | "python" | "go" | "java" | "elixir" | "universal";
913
913
  source: "selected" | "defaulted" | "provided" | "legacy" | "adjusted";
@@ -958,7 +958,7 @@ declare const router: {
958
958
  testing: "none" | "vitest" | "playwright" | "vitest-playwright" | "jest" | "cypress";
959
959
  email: "none" | "react-email" | "resend" | "nodemailer" | "postmark" | "sendgrid" | "aws-ses" | "mailgun" | "plunk";
960
960
  cssFramework: "none" | "tailwind" | "scss" | "less" | "postcss-only";
961
- uiLibrary: "none" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "mui" | "antd" | "base-ui" | "ark-ui" | "react-aria";
961
+ uiLibrary: "none" | "mui" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "antd" | "base-ui" | "ark-ui" | "react-aria";
962
962
  validation: "none" | "zod" | "valibot" | "arktype" | "typebox" | "typia" | "runtypes" | "effect-schema";
963
963
  realtime: "none" | "socket-io" | "partykit" | "ably" | "pusher" | "liveblocks" | "yjs";
964
964
  jobQueue: "none" | "bullmq" | "trigger-dev" | "inngest" | "temporal";
@@ -1037,7 +1037,7 @@ declare const router: {
1037
1037
  shadcnRadius?: "default" | "none" | "small" | "medium" | "large" | undefined;
1038
1038
  stackParts?: {
1039
1039
  id: string;
1040
- role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "mobile" | "deploy" | "ui" | "css" | "appPlatform";
1040
+ role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "css" | "ui" | "mobile" | "deploy" | "appPlatform";
1041
1041
  toolId: string;
1042
1042
  ecosystem: "typescript" | "react-native" | "rust" | "python" | "go" | "java" | "elixir" | "universal";
1043
1043
  source: "selected" | "defaulted" | "provided" | "legacy" | "adjusted";
@@ -1101,7 +1101,7 @@ declare const router: {
1101
1101
  testing: "none" | "vitest" | "playwright" | "vitest-playwright" | "jest" | "cypress";
1102
1102
  email: "none" | "react-email" | "resend" | "nodemailer" | "postmark" | "sendgrid" | "aws-ses" | "mailgun" | "plunk";
1103
1103
  cssFramework: "none" | "tailwind" | "scss" | "less" | "postcss-only";
1104
- uiLibrary: "none" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "mui" | "antd" | "base-ui" | "ark-ui" | "react-aria";
1104
+ uiLibrary: "none" | "mui" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "antd" | "base-ui" | "ark-ui" | "react-aria";
1105
1105
  validation: "none" | "zod" | "valibot" | "arktype" | "typebox" | "typia" | "runtypes" | "effect-schema";
1106
1106
  realtime: "none" | "socket-io" | "partykit" | "ably" | "pusher" | "liveblocks" | "yjs";
1107
1107
  jobQueue: "none" | "bullmq" | "trigger-dev" | "inngest" | "temporal";
@@ -1180,7 +1180,7 @@ declare const router: {
1180
1180
  shadcnRadius?: "default" | "none" | "small" | "medium" | "large" | undefined;
1181
1181
  stackParts?: {
1182
1182
  id: string;
1183
- role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "mobile" | "deploy" | "ui" | "css" | "appPlatform";
1183
+ role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "css" | "ui" | "mobile" | "deploy" | "appPlatform";
1184
1184
  toolId: string;
1185
1185
  ecosystem: "typescript" | "react-native" | "rust" | "python" | "go" | "java" | "elixir" | "universal";
1186
1186
  source: "selected" | "defaulted" | "provided" | "legacy" | "adjusted";
@@ -1231,7 +1231,7 @@ declare const router: {
1231
1231
  testing: "none" | "vitest" | "playwright" | "vitest-playwright" | "jest" | "cypress";
1232
1232
  email: "none" | "react-email" | "resend" | "nodemailer" | "postmark" | "sendgrid" | "aws-ses" | "mailgun" | "plunk";
1233
1233
  cssFramework: "none" | "tailwind" | "scss" | "less" | "postcss-only";
1234
- uiLibrary: "none" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "mui" | "antd" | "base-ui" | "ark-ui" | "react-aria";
1234
+ uiLibrary: "none" | "mui" | "shadcn-ui" | "shadcn-svelte" | "daisyui" | "radix-ui" | "headless-ui" | "park-ui" | "chakra-ui" | "nextui" | "mantine" | "antd" | "base-ui" | "ark-ui" | "react-aria";
1235
1235
  validation: "none" | "zod" | "valibot" | "arktype" | "typebox" | "typia" | "runtypes" | "effect-schema";
1236
1236
  realtime: "none" | "socket-io" | "partykit" | "ably" | "pusher" | "liveblocks" | "yjs";
1237
1237
  jobQueue: "none" | "bullmq" | "trigger-dev" | "inngest" | "temporal";
@@ -1310,7 +1310,7 @@ declare const router: {
1310
1310
  shadcnRadius?: "default" | "none" | "small" | "medium" | "large" | undefined;
1311
1311
  stackParts?: {
1312
1312
  id: string;
1313
- role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "mobile" | "deploy" | "ui" | "css" | "appPlatform";
1313
+ role: "api" | "runtime" | "backend" | "database" | "orm" | "auth" | "payments" | "email" | "logging" | "observability" | "stateManagement" | "forms" | "validation" | "testing" | "jobQueue" | "caching" | "i18n" | "search" | "fileStorage" | "cms" | "featureFlags" | "analytics" | "codeQuality" | "documentation" | "ai" | "frontend" | "css" | "ui" | "mobile" | "deploy" | "appPlatform";
1314
1314
  toolId: string;
1315
1315
  ecosystem: "typescript" | "react-native" | "rust" | "python" | "go" | "java" | "elixir" | "universal";
1316
1316
  source: "selected" | "defaulted" | "provided" | "legacy" | "adjusted";
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { a as getGraphBackendUrl, c as getPrimaryGraphPart, d as getLatestCLIVersion, f as DEFAULT_CONFIG, g as getUserPkgManager, h as getDefaultConfig, i as getGraphBackendDeployInstructions, l as hasGraphPart, n as updateBtsConfig, o as getGraphPart, p as DEFAULT_UI_LIBRARY_BY_FRONTEND, r as writeBtsConfig, s as getGraphSummary, t as readBtsConfig, u as types_exports } from "./bts-config-BMniWIbd.mjs";
3
- import { _ as setIsFirstPrompt$1, a as canPromptInteractively, c as CLIError, d as exitWithError, f as handleError, g as runWithContextAsync, h as isSilent, l as UserCancelledError, m as isFirstPrompt, o as getPackageExecutionArgs, p as didLastPromptShowUI, s as addPackageDependency, t as setupAddons, u as exitCancelled, v as setLastPromptShownUI } from "./addons-setup-DHoByttt.mjs";
2
+ import { a as getGraphBackendUrl, c as getPrimaryGraphPart, d as getLatestCLIVersion, f as DEFAULT_CONFIG, g as getUserPkgManager, h as getDefaultConfig, i as getGraphBackendDeployInstructions, l as hasGraphPart, n as updateBtsConfig, o as getGraphPart, p as DEFAULT_UI_LIBRARY_BY_FRONTEND, r as writeBtsConfig, s as getGraphSummary, t as readBtsConfig, u as types_exports } from "./bts-config-CSvxsFML.mjs";
3
+ import { _ as setIsFirstPrompt$1, a as canPromptInteractively, c as CLIError, d as exitWithError, f as handleError, g as runWithContextAsync, h as isSilent, l as UserCancelledError, m as isFirstPrompt, o as getPackageExecutionArgs, p as didLastPromptShowUI, s as addPackageDependency, t as setupAddons, u as exitCancelled, v as setLastPromptShownUI } from "./addons-setup-DqVFXnDv.mjs";
4
4
  import { cancel, confirm, intro, isCancel, log, outro, select, spinner, text } from "@clack/prompts";
5
5
  import { createRouterClient, os } from "@orpc/server";
6
6
  import pc from "picocolors";
@@ -750,9 +750,10 @@ function validateAIFrontendCompatibility(ai, frontends = []) {
750
750
  */
751
751
  function validateUILibraryFrontendCompatibility(uiLibrary, frontends = [], astroIntegration) {
752
752
  if (!uiLibrary || uiLibrary === "none") return;
753
+ const { web } = splitFrontends$1(frontends);
754
+ if (web.length === 0) return;
753
755
  const compatible = getCompatibleUILibraries(frontends, astroIntegration);
754
756
  if (!compatible.includes(uiLibrary)) {
755
- const { web } = splitFrontends$1(frontends);
756
757
  const isAstroNonReact = web.includes("astro") && astroIntegration !== "react";
757
758
  const supportsAstroReact = getCompatibleUILibraries(["astro"], "react").includes(uiLibrary);
758
759
  if (isAstroNonReact && supportsAstroReact) {
@@ -4344,6 +4345,7 @@ const MOBILE_DEEP_LINKING_OPTIONS = [{
4344
4345
  async function promptMobileOption(options, defaultValue, selected, message) {
4345
4346
  const resolution = createStaticSinglePromptResolution(options, defaultValue, selected);
4346
4347
  if (!resolution.shouldPrompt) return resolution.autoValue ?? defaultValue;
4348
+ if (!canPromptInteractively()) return defaultValue;
4347
4349
  const response = await navigableSelect({
4348
4350
  message,
4349
4351
  options: resolution.options,
@@ -4378,6 +4380,8 @@ function getMobileDeepLinkingChoice(mobileDeepLinking) {
4378
4380
  //#region src/prompts/package-manager.ts
4379
4381
  async function getPackageManagerChoice(packageManager) {
4380
4382
  if (packageManager !== void 0) return packageManager;
4383
+ const detectedPackageManager = getUserPkgManager();
4384
+ if (!canPromptInteractively()) return detectedPackageManager;
4381
4385
  const response = await navigableSelect({
4382
4386
  message: "Choose package manager",
4383
4387
  options: [
@@ -4402,7 +4406,7 @@ async function getPackageManagerChoice(packageManager) {
4402
4406
  hint: "Yarn Berry (v4) with PnP or node_modules"
4403
4407
  }
4404
4408
  ],
4405
- initialValue: getUserPkgManager()
4409
+ initialValue: detectedPackageManager
4406
4410
  });
4407
4411
  if (isCancel$1(response)) return exitCancelled("Operation cancelled");
4408
4412
  return response;
@@ -5452,14 +5456,28 @@ const SHADCN_DEFAULTS = {
5452
5456
  };
5453
5457
  async function getShadcnOptions(flags) {
5454
5458
  const fallback = (key) => isSilent() ? SHADCN_DEFAULTS[key] : void 0;
5459
+ const shadcnBase = flags.shadcnBase ?? fallback("shadcnBase") ?? await promptShadcnBase();
5460
+ if (isGoBack(shadcnBase)) return shadcnBase;
5461
+ const shadcnStyle = flags.shadcnStyle ?? fallback("shadcnStyle") ?? await promptShadcnStyle();
5462
+ if (isGoBack(shadcnStyle)) return shadcnStyle;
5463
+ const shadcnIconLibrary = flags.shadcnIconLibrary ?? fallback("shadcnIconLibrary") ?? await promptShadcnIconLibrary();
5464
+ if (isGoBack(shadcnIconLibrary)) return shadcnIconLibrary;
5465
+ const shadcnColorTheme = flags.shadcnColorTheme ?? fallback("shadcnColorTheme") ?? await promptShadcnColorTheme();
5466
+ if (isGoBack(shadcnColorTheme)) return shadcnColorTheme;
5467
+ const shadcnBaseColor = flags.shadcnBaseColor ?? fallback("shadcnBaseColor") ?? await promptShadcnBaseColor();
5468
+ if (isGoBack(shadcnBaseColor)) return shadcnBaseColor;
5469
+ const shadcnFont = flags.shadcnFont ?? fallback("shadcnFont") ?? await promptShadcnFont();
5470
+ if (isGoBack(shadcnFont)) return shadcnFont;
5471
+ const shadcnRadius = flags.shadcnRadius ?? fallback("shadcnRadius") ?? await promptShadcnRadius();
5472
+ if (isGoBack(shadcnRadius)) return shadcnRadius;
5455
5473
  return {
5456
- shadcnBase: flags.shadcnBase ?? fallback("shadcnBase") ?? await promptShadcnBase(),
5457
- shadcnStyle: flags.shadcnStyle ?? fallback("shadcnStyle") ?? await promptShadcnStyle(),
5458
- shadcnIconLibrary: flags.shadcnIconLibrary ?? fallback("shadcnIconLibrary") ?? await promptShadcnIconLibrary(),
5459
- shadcnColorTheme: flags.shadcnColorTheme ?? fallback("shadcnColorTheme") ?? await promptShadcnColorTheme(),
5460
- shadcnBaseColor: flags.shadcnBaseColor ?? fallback("shadcnBaseColor") ?? await promptShadcnBaseColor(),
5461
- shadcnFont: flags.shadcnFont ?? fallback("shadcnFont") ?? await promptShadcnFont(),
5462
- shadcnRadius: flags.shadcnRadius ?? fallback("shadcnRadius") ?? await promptShadcnRadius()
5474
+ shadcnBase,
5475
+ shadcnStyle,
5476
+ shadcnIconLibrary,
5477
+ shadcnColorTheme,
5478
+ shadcnBaseColor,
5479
+ shadcnFont,
5480
+ shadcnRadius
5463
5481
  };
5464
5482
  }
5465
5483
  async function promptShadcnBase() {
@@ -5468,6 +5486,7 @@ async function promptShadcnBase() {
5468
5486
  options: BASE_OPTIONS,
5469
5487
  initialValue: "radix"
5470
5488
  });
5489
+ if (isGoBack(selected)) return selected;
5471
5490
  if (isCancel$1(selected)) return exitCancelled("Operation cancelled");
5472
5491
  return selected;
5473
5492
  }
@@ -5477,6 +5496,7 @@ async function promptShadcnStyle() {
5477
5496
  options: STYLE_OPTIONS,
5478
5497
  initialValue: "nova"
5479
5498
  });
5499
+ if (isGoBack(selected)) return selected;
5480
5500
  if (isCancel$1(selected)) return exitCancelled("Operation cancelled");
5481
5501
  return selected;
5482
5502
  }
@@ -5486,6 +5506,7 @@ async function promptShadcnIconLibrary() {
5486
5506
  options: ICON_LIBRARY_OPTIONS,
5487
5507
  initialValue: "lucide"
5488
5508
  });
5509
+ if (isGoBack(selected)) return selected;
5489
5510
  if (isCancel$1(selected)) return exitCancelled("Operation cancelled");
5490
5511
  return selected;
5491
5512
  }
@@ -5495,6 +5516,7 @@ async function promptShadcnColorTheme() {
5495
5516
  options: COLOR_THEME_OPTIONS,
5496
5517
  initialValue: "neutral"
5497
5518
  });
5519
+ if (isGoBack(selected)) return selected;
5498
5520
  if (isCancel$1(selected)) return exitCancelled("Operation cancelled");
5499
5521
  return selected;
5500
5522
  }
@@ -5504,6 +5526,7 @@ async function promptShadcnBaseColor() {
5504
5526
  options: BASE_COLOR_OPTIONS,
5505
5527
  initialValue: "neutral"
5506
5528
  });
5529
+ if (isGoBack(selected)) return selected;
5507
5530
  if (isCancel$1(selected)) return exitCancelled("Operation cancelled");
5508
5531
  return selected;
5509
5532
  }
@@ -5513,6 +5536,7 @@ async function promptShadcnFont() {
5513
5536
  options: FONT_OPTIONS,
5514
5537
  initialValue: "inter"
5515
5538
  });
5539
+ if (isGoBack(selected)) return selected;
5516
5540
  if (isCancel$1(selected)) return exitCancelled("Operation cancelled");
5517
5541
  return selected;
5518
5542
  }
@@ -5522,6 +5546,7 @@ async function promptShadcnRadius() {
5522
5546
  options: RADIUS_OPTIONS,
5523
5547
  initialValue: "default"
5524
5548
  });
5549
+ if (isGoBack(selected)) return selected;
5525
5550
  if (isCancel$1(selected)) return exitCancelled("Operation cancelled");
5526
5551
  return selected;
5527
5552
  }
@@ -5810,7 +5835,7 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
5810
5835
  const frontendList = [frontend];
5811
5836
  const astroIntegration = frontend === "astro" ? promptValue(await getAstroIntegrationChoice(flags.astroIntegration)) : void 0;
5812
5837
  const uiLibrary = hasWebStyling$1(frontendList) ? promptValue(await getUILibraryChoice(flags.uiLibrary, frontendList, astroIntegration)) : "none";
5813
- const shadcnOptions = uiLibrary === "shadcn-ui" ? await getShadcnOptions({
5838
+ const shadcnOptions = uiLibrary === "shadcn-ui" ? promptValue(await getShadcnOptions({
5814
5839
  shadcnBase: flags.shadcnBase,
5815
5840
  shadcnStyle: flags.shadcnStyle,
5816
5841
  shadcnIconLibrary: flags.shadcnIconLibrary,
@@ -5818,7 +5843,7 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
5818
5843
  shadcnBaseColor: flags.shadcnBaseColor,
5819
5844
  shadcnFont: flags.shadcnFont,
5820
5845
  shadcnRadius: flags.shadcnRadius
5821
- }) : void 0;
5846
+ })) : void 0;
5822
5847
  const cssFramework = hasWebStyling$1(frontendList) ? promptValue(await getCSSFrameworkChoice(flags.cssFramework, uiLibrary)) : "none";
5823
5848
  const backendEcosystem = await selectBackendEcosystem();
5824
5849
  const stackPartSpecs = [`frontend:typescript:${frontend}`];
@@ -7385,7 +7410,10 @@ function displayConfig(config) {
7385
7410
  const graphOrm = config.orm === "none" ? getGraphDisplayValue(config, "orm") : null;
7386
7411
  configDisplay.push(`${pc.blue("ORM:")} ${graphOrm ?? String(config.orm)}`);
7387
7412
  }
7388
- if (config.auth !== void 0) configDisplay.push(`${pc.blue("Auth:")} ${String(config.auth)}`);
7413
+ if (config.auth !== void 0) {
7414
+ const graphAuth = config.auth === "none" ? getGraphDisplayValue(config, "auth") : null;
7415
+ configDisplay.push(`${pc.blue("Auth:")} ${graphAuth ?? String(config.auth)}`);
7416
+ }
7389
7417
  if (config.payments !== void 0) configDisplay.push(`${pc.blue("Payments:")} ${String(config.payments)}`);
7390
7418
  if (config.email !== void 0) {
7391
7419
  const graphEmail = config.email === "none" ? getGraphDisplayValue(config, "email") : null;
@@ -7522,6 +7550,9 @@ function appendChangedStringFlag(flags, flag, value, defaultValue) {
7522
7550
  function appendChangedArrayFlag(flags, flag, values, defaultValues) {
7523
7551
  if (values.length !== defaultValues.length || values.some((value, index) => value !== defaultValues[index])) flags.push(formatArrayFlag(flag, values));
7524
7552
  }
7553
+ function appendAstroIntegrationFlag(flags, config) {
7554
+ if (config.frontend.includes("astro") && config.astroIntegration !== "none") flags.push(`--astro-integration ${config.astroIntegration}`);
7555
+ }
7525
7556
  function appendGraphExtraFlags(flags, config) {
7526
7557
  appendChangedArrayFlag(flags, "addons", config.addons, ["turborepo"]);
7527
7558
  appendChangedArrayFlag(flags, "examples", config.examples, []);
@@ -7529,6 +7560,7 @@ function appendGraphExtraFlags(flags, config) {
7529
7560
  appendChangedStringFlag(flags, "web-deploy", config.webDeploy, "none");
7530
7561
  appendChangedStringFlag(flags, "server-deploy", config.serverDeploy, "none");
7531
7562
  if (hasGraphPrimaryPart(config, "frontend", "typescript")) {
7563
+ appendAstroIntegrationFlag(flags, config);
7532
7564
  appendChangedStringFlag(flags, "css-framework", config.cssFramework, "tailwind");
7533
7565
  appendChangedStringFlag(flags, "ui-library", config.uiLibrary, "shadcn-ui");
7534
7566
  if (config.uiLibrary === "shadcn-ui") {
@@ -7625,6 +7657,7 @@ function getTypeScriptFlags(config) {
7625
7657
  const flags = [];
7626
7658
  if (config.frontend && config.frontend.length > 0) flags.push(`--frontend ${config.frontend.join(" ")}`);
7627
7659
  else flags.push("--frontend none");
7660
+ appendAstroIntegrationFlag(flags, config);
7628
7661
  flags.push(`--backend ${config.backend}`);
7629
7662
  flags.push(`--runtime ${config.runtime}`);
7630
7663
  flags.push(`--database ${config.database}`);
@@ -10304,6 +10337,13 @@ async function displayPostInstallInstructions(config) {
10304
10337
  const webPort = String(getLocalWebDevPort(frontend ?? []));
10305
10338
  const betterAuthConvexInstructions = isConvex && config.auth === "better-auth" ? getBetterAuthConvexInstructions(hasWeb ?? false, webPort, packageManager) : "";
10306
10339
  const graphSummary = getGraphSummary(config);
10340
+ const graphBackendUrl = getGraphBackendUrl(config);
10341
+ const graphBackendPart = getGraphPart(config, "backend");
10342
+ const graphBackendNeedsSetup = Boolean(graphBackendUrl) && [
10343
+ "python",
10344
+ "go",
10345
+ "elixir"
10346
+ ].includes(graphBackendPart?.ecosystem ?? "");
10307
10347
  let output = graphSummary ? `${pc.bold("Generated:")} ${graphSummary}\n\n` : "";
10308
10348
  output += `${pc.bold("Next steps")}\n${pc.cyan("1.")} ${cdCmd}\n`;
10309
10349
  let stepCounter = 2;
@@ -10314,6 +10354,13 @@ async function displayPostInstallInstructions(config) {
10314
10354
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:setup\n${pc.dim(" (this will guide you through Convex project setup)")}\n`;
10315
10355
  output += `${pc.cyan(`${stepCounter++}.`)} Copy environment variables from\n${pc.white(" packages/backend/.env.local")} to ${pc.white("apps/*/.env")}\n`;
10316
10356
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n\n`;
10357
+ } else if (graphBackendUrl) {
10358
+ if (graphBackendNeedsSetup) output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} setup:server\n`;
10359
+ if (hasWeb) {
10360
+ output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:web\n`;
10361
+ output += `${pc.dim(" (run the backend in a second terminal)")}\n`;
10362
+ }
10363
+ output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:server\n`;
10317
10364
  } else if (isBackendSelf) output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
10318
10365
  else {
10319
10366
  if (runtime !== "workers") output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
@@ -10322,7 +10369,6 @@ async function displayPostInstallInstructions(config) {
10322
10369
  output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n`;
10323
10370
  }
10324
10371
  }
10325
- const graphBackendUrl = getGraphBackendUrl(config);
10326
10372
  const hasStandaloneBackend = backend !== "none" || Boolean(graphBackendUrl);
10327
10373
  if (hasWeb || hasStandaloneBackend || addons?.includes("starlight") || addons?.includes("fumadocs")) {
10328
10374
  output += `${pc.bold("Your project will be available at:")}\n`;
@@ -10439,6 +10485,7 @@ function getNoOrmWarning() {
10439
10485
  return `\n${pc.yellow("WARNING:")} Database selected without an ORM. Features requiring\n database access (e.g., examples, auth) need manual setup.`;
10440
10486
  }
10441
10487
  function getGraphDatabaseInstructions(database, ecosystem, ormTool) {
10488
+ if (ecosystem === "java" && ormTool === "spring-data-jpa") return `${pc.bold("Database setup:")}\n${pc.cyan("•")} Selected database: ${database}\n${pc.cyan("•")} ORM: ${ecosystem}:${ormTool}\n${pc.cyan("•")} The generated Spring Data JPA example uses an embedded ${pc.white("H2")} dev database. Update ${pc.white("apps/server/src/main/resources/application.yml")} when switching to external ${database}.`;
10442
10489
  return `${pc.bold("Database setup:")}\n${pc.cyan("•")} Database: ${database}\n${pc.cyan("•")} ORM: ${ecosystem}:${ormTool}\n${pc.cyan("•")} Configure ${pc.white("DATABASE_URL")} in ${pc.white("apps/server/.env")}`;
10443
10490
  }
10444
10491
  function getBunWebNativeWarning() {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import "./bts-config-BMniWIbd.mjs";
2
+ import "./bts-config-CSvxsFML.mjs";
3
3
  import { t as startMcpServer } from "./mcp-entry.mjs";
4
4
 
5
5
  export { startMcpServer };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as getLatestCLIVersion, r as writeBtsConfig, t as readBtsConfig } from "./bts-config-BMniWIbd.mjs";
2
+ import { d as getLatestCLIVersion, r as writeBtsConfig, t as readBtsConfig } from "./bts-config-CSvxsFML.mjs";
3
3
  import z from "zod";
4
4
  import { AISchema, APISchema, AddonsSchema, AnalyticsSchema, AnimationSchema, AstroIntegrationSchema, AuthSchema, BackendSchema, CMSSchema, CSSFrameworkSchema, CachingSchema, DatabaseSchema, DatabaseSetupSchema, EcosystemSchema, EffectSchema, ElixirApiSchema, ElixirAuthSchema, ElixirCachingSchema, ElixirDeploySchema, ElixirEmailSchema, ElixirHttpSchema, ElixirJobsSchema, ElixirJsonSchema, ElixirObservabilitySchema, ElixirOrmSchema, ElixirQualitySchema, ElixirRealtimeSchema, ElixirTestingSchema, ElixirValidationSchema, ElixirWebFrameworkSchema, EmailSchema, ExamplesSchema, FeatureFlagsSchema, FileStorageSchema, FileUploadSchema, FormsSchema, FrontendSchema, GoApiSchema, GoAuthSchema, GoCliSchema, GoLoggingSchema, GoOrmSchema, GoWebFrameworkSchema, I18nSchema, JavaAuthSchema, JavaBuildToolSchema, JavaLibrariesSchema, JavaOrmSchema, JavaTestingLibrariesSchema, JavaWebFrameworkSchema, JobQueueSchema, LoggingSchema, MobileDeepLinkingSchema, MobileNavigationSchema, MobileOTASchema, MobilePushSchema, MobileStorageSchema, MobileTestingSchema, MobileUISchema, OPTION_CATEGORY_METADATA, ORMSchema, ObservabilitySchema, PackageManagerSchema, PaymentsSchema, PythonAiSchema, PythonApiSchema, PythonAuthSchema, PythonGraphqlSchema, PythonOrmSchema, PythonQualitySchema, PythonTaskQueueSchema, PythonValidationSchema, PythonWebFrameworkSchema, RealtimeSchema, RuntimeSchema, RustApiSchema, RustAuthSchema, RustCachingSchema, RustCliSchema, RustErrorHandlingSchema, RustFrontendSchema, RustLibrariesSchema, RustLoggingSchema, RustOrmSchema, RustWebFrameworkSchema, SearchSchema, ServerDeploySchema, StateManagementSchema, TestingSchema, UILibrarySchema, ValidationSchema, WebDeploySchema, analyzeStackCompatibility } from "@better-fullstack/types";
5
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -1030,7 +1030,7 @@ async function startMcpServer() {
1030
1030
  await writeBtsConfig(config);
1031
1031
  let addonWarnings = [];
1032
1032
  if (config.addons.length > 0 && config.addons[0] !== "none") {
1033
- const { setupAddons } = await import("./addons-setup-Ca069cmy.mjs");
1033
+ const { setupAddons } = await import("./addons-setup-CExVq7Mg.mjs");
1034
1034
  addonWarnings = await setupAddons(config);
1035
1035
  }
1036
1036
  const installCmd = getInstallCommand(input.ecosystem ?? "typescript", projectName, input.packageManager, input.javaBuildTool, input.javaWebFramework);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-fullstack",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Scaffold production-ready fullstack apps in seconds. Pick your stack from 425 options — the CLI wires everything together.",
5
5
  "keywords": [
6
6
  "algolia",
@@ -127,8 +127,8 @@
127
127
  "prepublishOnly": "npm run build"
128
128
  },
129
129
  "dependencies": {
130
- "@better-fullstack/template-generator": "^2.0.0",
131
- "@better-fullstack/types": "^2.0.0",
130
+ "@better-fullstack/template-generator": "^2.0.1",
131
+ "@better-fullstack/types": "^2.0.1",
132
132
  "@clack/core": "^0.5.0",
133
133
  "@clack/prompts": "^1.5.0",
134
134
  "@orpc/server": "^1.14.4",
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./bts-config-BMniWIbd.mjs";
3
- import { i as setupLefthook, n as setupBiome, r as setupHusky, t as setupAddons } from "./addons-setup-DHoByttt.mjs";
4
-
5
- export { setupAddons };