create-better-fullstack 2.1.7 → 2.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  //#region src/cli.ts
3
3
  if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-492OkjcS.mjs").then((m) => m.startMcpServer());
4
- else import("./run-buK4aZS8.mjs").then((m) => m.createBtsCli().run());
4
+ else import("./run-CD8f7PHh.mjs").then((m) => m.createBtsCli().run());
5
5
 
6
6
  //#endregion
7
7
  export { };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import "./bts-config-DQVWvPDs.mjs";
3
- import { a as createBtsCli, c as history, d as telemetry, f as update, i as create, l as router, n as builder, o as docs, r as check, s as doctor, t as add, u as sponsors } from "./run-D9I7NdES.mjs";
3
+ import { a as createBtsCli, c as history, d as telemetry, f as update, i as create, l as router, n as builder, o as docs, r as check, s as doctor, t as add, u as sponsors } from "./run-T6g1jkfy.mjs";
4
4
  import "./render-title-zvyKC1ej.mjs";
5
5
  import "./errors-ns_o2OKg.mjs";
6
6
  import "./prompt-environment-BR0Kkw2W.mjs";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import "./bts-config-DQVWvPDs.mjs";
3
- import { a as createBtsCli, c as history, d as telemetry, f as update, i as create, l as router, n as builder, o as docs, r as check, s as doctor, t as add, u as sponsors } from "./run-D9I7NdES.mjs";
3
+ import { a as createBtsCli, c as history, d as telemetry, f as update, i as create, l as router, n as builder, o as docs, r as check, s as doctor, t as add, u as sponsors } from "./run-T6g1jkfy.mjs";
4
4
  import "./render-title-zvyKC1ej.mjs";
5
5
  import "./errors-ns_o2OKg.mjs";
6
6
  import "./prompt-environment-BR0Kkw2W.mjs";
@@ -3698,11 +3698,11 @@ async function getJavaLanguageChoice(javaLanguage) {
3698
3698
  if (isCancel$1(response)) return exitCancelled("Operation cancelled");
3699
3699
  return response;
3700
3700
  }
3701
- function resolveJavaBuildToolPrompt(javaBuildTool) {
3702
- return createStaticSinglePromptResolution(JAVA_BUILD_TOOL_PROMPT_OPTIONS, "maven", javaBuildTool);
3701
+ function resolveJavaBuildToolPrompt(javaBuildTool, javaLanguage) {
3702
+ return createStaticSinglePromptResolution(javaLanguage === "kotlin" ? JAVA_BUILD_TOOL_PROMPT_OPTIONS.filter((option) => option.value !== "none") : JAVA_BUILD_TOOL_PROMPT_OPTIONS, "maven", javaBuildTool);
3703
3703
  }
3704
- async function getJavaBuildToolChoice(javaBuildTool) {
3705
- const resolution = resolveJavaBuildToolPrompt(javaBuildTool);
3704
+ async function getJavaBuildToolChoice(javaBuildTool, javaLanguage) {
3705
+ const resolution = resolveJavaBuildToolPrompt(javaBuildTool, javaLanguage);
3706
3706
  if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
3707
3707
  const response = await navigableSelect({
3708
3708
  message: "Select Java build tool",
@@ -3712,11 +3712,11 @@ async function getJavaBuildToolChoice(javaBuildTool) {
3712
3712
  if (isCancel$1(response)) return exitCancelled("Operation cancelled");
3713
3713
  return response;
3714
3714
  }
3715
- function resolveJavaOrmPrompt(javaOrm) {
3716
- return createStaticSinglePromptResolution(JAVA_ORM_PROMPT_OPTIONS, "none", javaOrm);
3715
+ function resolveJavaOrmPrompt(javaOrm, javaLanguage) {
3716
+ return createStaticSinglePromptResolution(javaLanguage === "kotlin" ? JAVA_ORM_PROMPT_OPTIONS.filter((option) => option.value !== "jooq" && option.value !== "mybatis") : JAVA_ORM_PROMPT_OPTIONS, "none", javaOrm);
3717
3717
  }
3718
- async function getJavaOrmChoice(javaOrm) {
3719
- const resolution = resolveJavaOrmPrompt(javaOrm);
3718
+ async function getJavaOrmChoice(javaOrm, javaLanguage) {
3719
+ const resolution = resolveJavaOrmPrompt(javaOrm, javaLanguage);
3720
3720
  if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
3721
3721
  const response = await navigableSelect({
3722
3722
  message: "Select Java ORM/database layer",
@@ -3740,11 +3740,11 @@ async function getJavaAuthChoice(javaAuth) {
3740
3740
  if (isCancel$1(response)) return exitCancelled("Operation cancelled");
3741
3741
  return response;
3742
3742
  }
3743
- function resolveJavaLibrariesPrompt(javaLibraries) {
3744
- return createStaticMultiPromptResolution(JAVA_LIBRARY_PROMPT_OPTIONS, [], javaLibraries);
3743
+ function resolveJavaLibrariesPrompt(javaLibraries, javaLanguage) {
3744
+ return createStaticMultiPromptResolution(javaLanguage === "kotlin" ? JAVA_LIBRARY_PROMPT_OPTIONS.filter((option) => !types_exports.KOTLIN_DROPPED_JAVA_LIBRARIES.has(option.value)) : JAVA_LIBRARY_PROMPT_OPTIONS, [], javaLibraries);
3745
3745
  }
3746
- async function getJavaLibrariesChoice(javaLibraries) {
3747
- const resolution = resolveJavaLibrariesPrompt(javaLibraries);
3746
+ async function getJavaLibrariesChoice(javaLibraries, javaLanguage) {
3747
+ const resolution = resolveJavaLibrariesPrompt(javaLibraries, javaLanguage);
3748
3748
  if (!resolution.shouldPrompt) return resolution.autoValue ?? [];
3749
3749
  const response = await navigableMultiselect({
3750
3750
  message: "Select Java application libraries",
@@ -3756,11 +3756,11 @@ async function getJavaLibrariesChoice(javaLibraries) {
3756
3756
  if (response.includes("none")) return [];
3757
3757
  return response;
3758
3758
  }
3759
- function resolveJavaTestingLibrariesPrompt(javaTestingLibraries) {
3760
- return createStaticMultiPromptResolution(JAVA_TESTING_LIBRARY_PROMPT_OPTIONS, ["junit5"], javaTestingLibraries);
3759
+ function resolveJavaTestingLibrariesPrompt(javaTestingLibraries, javaLanguage) {
3760
+ return createStaticMultiPromptResolution(javaLanguage === "kotlin" ? JAVA_TESTING_LIBRARY_PROMPT_OPTIONS.filter((option) => !types_exports.KOTLIN_UNSUPPORTED_JAVA_TESTING_LIBRARIES.has(option.value)) : JAVA_TESTING_LIBRARY_PROMPT_OPTIONS, ["junit5"], javaTestingLibraries);
3761
3761
  }
3762
- async function getJavaTestingLibrariesChoice(javaTestingLibraries) {
3763
- const resolution = resolveJavaTestingLibrariesPrompt(javaTestingLibraries);
3762
+ async function getJavaTestingLibrariesChoice(javaTestingLibraries, javaLanguage) {
3763
+ const resolution = resolveJavaTestingLibrariesPrompt(javaTestingLibraries, javaLanguage);
3764
3764
  if (!resolution.shouldPrompt) return resolution.autoValue ?? [];
3765
3765
  const response = await navigableMultiselect({
3766
3766
  message: "Select Java testing libraries",
@@ -3811,11 +3811,11 @@ const JAVA_LOGGING_PROMPT_OPTIONS = [
3811
3811
  hint: "Spring Boot logging defaults"
3812
3812
  }
3813
3813
  ];
3814
- function resolveJavaApiPrompt(javaApi) {
3815
- return createStaticSinglePromptResolution(JAVA_API_PROMPT_OPTIONS, "none", javaApi);
3814
+ function resolveJavaApiPrompt(javaApi, javaLanguage) {
3815
+ return createStaticSinglePromptResolution(javaLanguage === "kotlin" ? JAVA_API_PROMPT_OPTIONS.filter((option) => option.value !== "grpc" && option.value !== "openapi-generator") : JAVA_API_PROMPT_OPTIONS, "none", javaApi);
3816
3816
  }
3817
- async function getJavaApiChoice(javaApi) {
3818
- const resolution = resolveJavaApiPrompt(javaApi);
3817
+ async function getJavaApiChoice(javaApi, javaLanguage) {
3818
+ const resolution = resolveJavaApiPrompt(javaApi, javaLanguage);
3819
3819
  if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
3820
3820
  const response = await navigableSelect({
3821
3821
  message: "Select Java API layer",
@@ -6016,17 +6016,17 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
6016
6016
  if (backendEcosystem === "java") {
6017
6017
  const javaWebFramework = promptValue(await getJavaWebFrameworkChoice(flags.javaWebFramework));
6018
6018
  const javaLanguage = javaWebFramework !== "spring-boot" ? "java" : flags.javaLanguage !== void 0 ? promptValue(await getJavaLanguageChoice(flags.javaLanguage)) : flags.javaWebFramework !== void 0 ? "java" : promptValue(await getJavaLanguageChoice(flags.javaLanguage));
6019
- const javaBuildTool = promptValue(await getJavaBuildToolChoice(flags.javaBuildTool));
6019
+ const javaBuildTool = promptValue(await getJavaBuildToolChoice(flags.javaBuildTool, javaLanguage));
6020
6020
  if (javaWebFramework !== "none" && javaBuildTool !== "none") {
6021
6021
  const databaseConfig = await selectDatabaseConfig(flags);
6022
6022
  database = databaseConfig.database;
6023
6023
  dbSetup = databaseConfig.dbSetup;
6024
6024
  }
6025
- const javaOrm = database === "none" || javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaOrmChoice(flags.javaOrm));
6025
+ const javaOrm = database === "none" || javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaOrmChoice(flags.javaOrm, javaLanguage));
6026
6026
  const javaAuth = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaAuthChoice(flags.javaAuth));
6027
- const javaLibraries = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? [] : await scopedPromptValue("java", "javaLibraries", configScope, backendSections, () => getJavaLibrariesChoice(flags.javaLibraries));
6028
- const javaTestingLibraries = await scopedPromptValue("java", "javaTestingLibraries", configScope, backendSections, () => getJavaTestingLibrariesChoice(flags.javaTestingLibraries));
6029
- const javaApi = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaApiChoice(flags.javaApi));
6027
+ const javaLibraries = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? [] : await scopedPromptValue("java", "javaLibraries", configScope, backendSections, () => getJavaLibrariesChoice(flags.javaLibraries, javaLanguage));
6028
+ const javaTestingLibraries = await scopedPromptValue("java", "javaTestingLibraries", configScope, backendSections, () => getJavaTestingLibrariesChoice(flags.javaTestingLibraries, javaLanguage));
6029
+ const javaApi = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaApiChoice(flags.javaApi, javaLanguage));
6030
6030
  const javaLogging = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : await scopedPromptValue("java", "javaLogging", configScope, backendSections, () => getJavaLoggingChoice(flags.javaLogging));
6031
6031
  Object.assign(backendChoices, {
6032
6032
  javaLanguage,
@@ -8351,18 +8351,31 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
8351
8351
  javaLanguage: ({ results }) => {
8352
8352
  if (results.ecosystem !== "java") return Promise.resolve("java");
8353
8353
  if (results.javaWebFramework !== "spring-boot") return Promise.resolve("java");
8354
+ const kotlinBlocker = (0, types_exports.getKotlinJavaIncompatibilityReason)({
8355
+ javaWebFramework: results.javaWebFramework,
8356
+ javaBuildTool: "maven",
8357
+ email: results.email,
8358
+ search: results.search,
8359
+ caching: results.caching,
8360
+ observability: results.observability
8361
+ });
8362
+ if (kotlinBlocker) {
8363
+ if (flags.javaLanguage === "kotlin") log.warn(`JVM language set to Java: ${kotlinBlocker}`);
8364
+ else if (flags.javaLanguage === void 0 && flags.javaWebFramework === void 0) log.info(`Kotlin not offered: ${kotlinBlocker}`);
8365
+ return Promise.resolve("java");
8366
+ }
8354
8367
  if (flags.javaLanguage !== void 0) return getJavaLanguageChoice(flags.javaLanguage);
8355
8368
  if (flags.javaWebFramework !== void 0) return Promise.resolve("java");
8356
8369
  return getJavaLanguageChoice(flags.javaLanguage);
8357
8370
  },
8358
8371
  javaBuildTool: ({ results }) => {
8359
8372
  if (results.ecosystem !== "java") return Promise.resolve("none");
8360
- return getJavaBuildToolChoice(flags.javaBuildTool);
8373
+ return getJavaBuildToolChoice(flags.javaBuildTool, results.javaLanguage);
8361
8374
  },
8362
8375
  javaOrm: ({ results }) => {
8363
8376
  if (results.ecosystem !== "java") return Promise.resolve("none");
8364
8377
  if (results.javaWebFramework !== "spring-boot" || results.javaBuildTool === "none") return Promise.resolve("none");
8365
- return getJavaOrmChoice(flags.javaOrm);
8378
+ return getJavaOrmChoice(flags.javaOrm, results.javaLanguage);
8366
8379
  },
8367
8380
  javaAuth: ({ results }) => {
8368
8381
  if (results.ecosystem !== "java") return Promise.resolve("none");
@@ -8372,7 +8385,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
8372
8385
  javaApi: ({ results }) => {
8373
8386
  if (results.ecosystem !== "java") return Promise.resolve("none");
8374
8387
  if (results.javaWebFramework !== "spring-boot") return Promise.resolve("none");
8375
- return getJavaApiChoice(flags.javaApi);
8388
+ return getJavaApiChoice(flags.javaApi, results.javaLanguage);
8376
8389
  },
8377
8390
  javaLogging: ({ results }) => {
8378
8391
  if (results.ecosystem !== "java") return Promise.resolve("none");
@@ -8382,12 +8395,12 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
8382
8395
  javaLibraries: ({ results }) => {
8383
8396
  if (results.ecosystem !== "java") return Promise.resolve([]);
8384
8397
  if (results.javaWebFramework !== "spring-boot" || results.javaBuildTool === "none") return Promise.resolve([]);
8385
- return getJavaLibrariesChoice(flags.javaLibraries);
8398
+ return getJavaLibrariesChoice(flags.javaLibraries, results.javaLanguage);
8386
8399
  },
8387
8400
  javaTestingLibraries: ({ results }) => {
8388
8401
  if (results.ecosystem !== "java") return Promise.resolve([]);
8389
8402
  if (results.javaBuildTool === "none") return Promise.resolve([]);
8390
- return getJavaTestingLibrariesChoice(flags.javaTestingLibraries);
8403
+ return getJavaTestingLibrariesChoice(flags.javaTestingLibraries, results.javaLanguage);
8391
8404
  },
8392
8405
  dotnetWebFramework: ({ results }) => {
8393
8406
  if (results.ecosystem !== "dotnet") return Promise.resolve("none");
@@ -8945,6 +8958,17 @@ function displayConfig(config) {
8945
8958
  return configDisplay.join("\n");
8946
8959
  }
8947
8960
 
8961
+ //#endregion
8962
+ //#region src/utils/open-url.ts
8963
+ async function openUrl(url) {
8964
+ const platform = process.platform;
8965
+ if (platform === "darwin") await $({ stdio: "ignore" })`open ${url}`;
8966
+ else if (platform === "win32") {
8967
+ const escapedUrl = url.replace(/&/g, "^&");
8968
+ await $({ stdio: "ignore" })`cmd /c start "" ${escapedUrl}`;
8969
+ } else await $({ stdio: "ignore" })`xdg-open ${url}`;
8970
+ }
8971
+
8948
8972
  //#endregion
8949
8973
  //#region src/utils/preflight-display.ts
8950
8974
  function displayPreflightWarnings({ warnings }) {
@@ -9048,17 +9072,6 @@ async function setupProjectDirectory(finalPathInput, shouldClearDirectory) {
9048
9072
  };
9049
9073
  }
9050
9074
 
9051
- //#endregion
9052
- //#region src/utils/open-url.ts
9053
- async function openUrl(url) {
9054
- const platform = process.platform;
9055
- if (platform === "darwin") await $({ stdio: "ignore" })`open ${url}`;
9056
- else if (platform === "win32") {
9057
- const escapedUrl = url.replace(/&/g, "^&");
9058
- await $({ stdio: "ignore" })`cmd /c start "" ${escapedUrl}`;
9059
- } else await $({ stdio: "ignore" })`xdg-open ${url}`;
9060
- }
9061
-
9062
9075
  //#endregion
9063
9076
  //#region src/validation.ts
9064
9077
  const CORE_STACK_FLAGS = new Set([
@@ -11262,6 +11275,14 @@ function shouldPromptForVersionChannel(input, hasConfigBase) {
11262
11275
  if (input.yes || input.part?.length || hasConfigBase || input.versionChannel !== void 0 || isSilent()) return false;
11263
11276
  return canPromptInteractively();
11264
11277
  }
11278
+ function normalizeKotlinJavaSelection(config) {
11279
+ if (!config.stackParts?.some((part) => part.role === "backend" && part.ecosystem === "java" && !part.ownerPartId && part.source !== "provided") && config.ecosystem !== "java" || config.javaLanguage !== "kotlin") return;
11280
+ const kotlinBlocker = (0, types_exports.getKotlinJavaIncompatibilityReason)(config);
11281
+ if (!kotlinBlocker) return;
11282
+ config.javaLanguage = "java";
11283
+ if (config.stackParts) config.stackParts = config.stackParts.filter((part) => !(part.role === "language" && part.ecosystem === "java" && part.toolId === "kotlin" && part.source !== "provided"));
11284
+ if (!isSilent()) log.warn(pc.yellow(`JVM language set to Java: ${kotlinBlocker}`));
11285
+ }
11265
11286
  async function createProjectHandler(input, options = {}) {
11266
11287
  const { silent = false } = options;
11267
11288
  return runWithContextAsync({ silent }, async () => {
@@ -11529,6 +11550,7 @@ async function createProjectHandler(input, options = {}) {
11529
11550
  };
11530
11551
  validateConfigCompatibility(config, providedFlags, cliInput);
11531
11552
  }
11553
+ normalizeKotlinJavaSelection(config);
11532
11554
  const preflight = validatePreflightConfig(config);
11533
11555
  if (preflight.hasWarnings && !isSilent()) displayPreflightWarnings(preflight);
11534
11556
  if (input.dryRun) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-fullstack",
3
- "version": "2.1.7",
3
+ "version": "2.1.8",
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",
@@ -128,8 +128,8 @@
128
128
  "prepublishOnly": "npm run build"
129
129
  },
130
130
  "dependencies": {
131
- "@better-fullstack/template-generator": "^2.1.7",
132
- "@better-fullstack/types": "^2.1.7",
131
+ "@better-fullstack/template-generator": "^2.1.8",
132
+ "@better-fullstack/types": "^2.1.8",
133
133
  "@clack/core": "^0.5.0",
134
134
  "@clack/prompts": "^1.6.0",
135
135
  "@orpc/server": "^1.14.6",