create-better-fullstack 2.1.5 → 2.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-handler-BNSL6HdM.mjs → add-handler-ztNjzoMN.mjs} +52 -6
- package/dist/addons-setup-DnLjAzTw.mjs +7 -0
- package/dist/{addons-setup-CyrP1IV-.mjs → addons-setup-LaAj43NP.mjs} +10 -24
- package/dist/analytics-DVltG11u.mjs +170 -0
- package/dist/{errors-Cyol8zbN.mjs → bts-config-DQVWvPDs.mjs} +72 -149
- package/dist/cli.mjs +2 -2
- package/dist/{templates-CnTOtKjm.mjs → config-processing-D9-F2Us9.mjs} +57 -2
- package/dist/{doctor-DBoq7bZ9.mjs → doctor-a4ca3SMd.mjs} +3 -2
- package/dist/errors-ns_o2OKg.mjs +86 -0
- package/dist/{file-formatter-B3dsev2l.mjs → file-formatter-gvmrpd-g.mjs} +78 -6
- package/dist/gen-CCClL7Ve.mjs +274 -0
- package/dist/{generated-checks-C8hn9w2i.mjs → generated-checks-BV9jol5h.mjs} +1 -1
- package/dist/index.d.mts +162 -64
- package/dist/index.mjs +17 -8
- package/dist/{install-dependencies-CgNh-aOy.mjs → install-dependencies-RoUyaE8o.mjs} +80 -21
- package/dist/mcp-492OkjcS.mjs +11 -0
- package/dist/mcp-entry.mjs +205 -30
- package/dist/prompt-environment-BR0Kkw2W.mjs +26 -0
- package/dist/registry-DSf2CEaU.mjs +408 -0
- package/dist/{run-BYse4yJy.mjs → run-D9I7NdES.mjs} +2081 -464
- package/dist/run-buK4aZS8.mjs +15 -0
- package/dist/scaffold-manifest-DGRyepdb.mjs +4 -0
- package/dist/scaffold-manifest-Dyi0voqE.mjs +135 -0
- package/dist/update-DJ8CI5KW.mjs +401 -0
- package/package.json +3 -3
- package/dist/addons-setup-DyMm42a5.mjs +0 -5
- package/dist/mcp-CsW3i66c.mjs +0 -6
- package/dist/run-_cf_sFwM.mjs +0 -10
- /package/dist/{update-deps-D5OG0KmJ.mjs → update-deps-aD-iQw4U.mjs} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./
|
|
3
|
-
import { a as createBtsCli, c as history, d as telemetry, 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-
|
|
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";
|
|
4
4
|
import "./render-title-zvyKC1ej.mjs";
|
|
5
|
-
import "./
|
|
6
|
-
import "./
|
|
7
|
-
import "./
|
|
8
|
-
import "./
|
|
5
|
+
import "./errors-ns_o2OKg.mjs";
|
|
6
|
+
import "./prompt-environment-BR0Kkw2W.mjs";
|
|
7
|
+
import "./analytics-DVltG11u.mjs";
|
|
8
|
+
import "./file-formatter-gvmrpd-g.mjs";
|
|
9
|
+
import "./install-dependencies-RoUyaE8o.mjs";
|
|
10
|
+
import "./generated-checks-BV9jol5h.mjs";
|
|
11
|
+
import { t as applyEffectBackendDefaults } from "./config-processing-D9-F2Us9.mjs";
|
|
12
|
+
import "./scaffold-manifest-Dyi0voqE.mjs";
|
|
13
|
+
import "./addons-setup-LaAj43NP.mjs";
|
|
9
14
|
import { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, generateVirtualProject } from "@better-fullstack/template-generator";
|
|
10
15
|
|
|
11
16
|
//#region src/index.ts
|
|
@@ -36,6 +41,7 @@ async function createVirtual(options) {
|
|
|
36
41
|
const ecosystem = options.ecosystem || "typescript";
|
|
37
42
|
const isReactNative = ecosystem === "react-native";
|
|
38
43
|
const frontend = options.frontend || (isReactNative ? ["native-bare"] : ["tanstack-router"]);
|
|
44
|
+
const backend = options.backend || (isReactNative ? "none" : "hono");
|
|
39
45
|
const hasNativeFrontend = frontend.some((item) => item === "native-bare" || item === "native-uniwind" || item === "native-unistyles");
|
|
40
46
|
const config = {
|
|
41
47
|
ecosystem,
|
|
@@ -44,7 +50,7 @@ async function createVirtual(options) {
|
|
|
44
50
|
relativePath: "./virtual",
|
|
45
51
|
database: options.database || "none",
|
|
46
52
|
orm: options.orm || "none",
|
|
47
|
-
backend
|
|
53
|
+
backend,
|
|
48
54
|
runtime: options.runtime || (isReactNative ? "none" : "bun"),
|
|
49
55
|
frontend,
|
|
50
56
|
addons: options.addons || [],
|
|
@@ -56,6 +62,7 @@ async function createVirtual(options) {
|
|
|
56
62
|
effect: options.effect || "none",
|
|
57
63
|
git: options.git ?? false,
|
|
58
64
|
packageManager: options.packageManager || "bun",
|
|
65
|
+
workspaceShape: options.workspaceShape || "monorepo",
|
|
59
66
|
versionChannel: options.versionChannel || "stable",
|
|
60
67
|
install: false,
|
|
61
68
|
dbSetup: options.dbSetup || "none",
|
|
@@ -139,6 +146,7 @@ async function createVirtual(options) {
|
|
|
139
146
|
goConfig: options.goConfig || "none",
|
|
140
147
|
goObservability: options.goObservability || "none",
|
|
141
148
|
javaWebFramework: options.javaWebFramework || (options.ecosystem === "java" ? "spring-boot" : "none"),
|
|
149
|
+
javaLanguage: options.javaLanguage || "java",
|
|
142
150
|
javaBuildTool: options.javaBuildTool || (options.ecosystem === "java" ? "maven" : "none"),
|
|
143
151
|
javaOrm: options.javaOrm || "none",
|
|
144
152
|
javaAuth: options.javaAuth || "none",
|
|
@@ -176,6 +184,7 @@ async function createVirtual(options) {
|
|
|
176
184
|
aiDocs: options.aiDocs || ["claude-md", "agents-md"]
|
|
177
185
|
};
|
|
178
186
|
if (options.stackParts) config.stackParts = options.stackParts;
|
|
187
|
+
applyEffectBackendDefaults(config, new Set(Object.keys(options)));
|
|
179
188
|
const { generateVirtualProject: generate, EMBEDDED_TEMPLATES: EMBEDDED_TEMPLATES$2 } = await import("@better-fullstack/template-generator");
|
|
180
189
|
const result = await generate({
|
|
181
190
|
config,
|
|
@@ -198,4 +207,4 @@ async function createVirtual(options) {
|
|
|
198
207
|
}
|
|
199
208
|
|
|
200
209
|
//#endregion
|
|
201
|
-
export { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, add, builder, check, create, createBtsCli, createVirtual, docs, doctor, generateVirtualProject, history, router, sponsors, telemetry };
|
|
210
|
+
export { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, add, builder, check, create, createBtsCli, createVirtual, docs, doctor, generateVirtualProject, history, router, sponsors, telemetry, update };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { b as types_exports, g as DEFAULT_CONFIG } from "./bts-config-DQVWvPDs.mjs";
|
|
3
|
+
import { d as setLastPromptShownUI, r as exitCancelled, s as isFirstPrompt, u as setIsFirstPrompt$1 } from "./errors-ns_o2OKg.mjs";
|
|
4
|
+
import { g as validateAddonCompatibility, o as getCompatibleAddons } from "./file-formatter-gvmrpd-g.mjs";
|
|
4
5
|
import { log, spinner } from "@clack/prompts";
|
|
5
6
|
import pc from "picocolors";
|
|
6
7
|
import fs from "fs-extra";
|
|
@@ -496,6 +497,16 @@ const PRERELEASE_TAG_PRIORITY = [
|
|
|
496
497
|
];
|
|
497
498
|
const REGISTRY_FETCH_TIMEOUT_MS = 1e4;
|
|
498
499
|
const REGISTRY_CONCURRENCY = 10;
|
|
500
|
+
const SYNCHRONIZED_VERSION_FAMILIES = [{
|
|
501
|
+
name: "oRPC",
|
|
502
|
+
packages: [
|
|
503
|
+
"@orpc/server",
|
|
504
|
+
"@orpc/client",
|
|
505
|
+
"@orpc/openapi",
|
|
506
|
+
"@orpc/zod",
|
|
507
|
+
"@orpc/tanstack-query"
|
|
508
|
+
]
|
|
509
|
+
}];
|
|
499
510
|
function mapWithConcurrency(items, fn, concurrency) {
|
|
500
511
|
const results = Array.from({ length: items.length });
|
|
501
512
|
let index = 0;
|
|
@@ -507,6 +518,19 @@ function mapWithConcurrency(items, fn, concurrency) {
|
|
|
507
518
|
}
|
|
508
519
|
return Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker())).then(() => results);
|
|
509
520
|
}
|
|
521
|
+
function getVersionSections(packageJson) {
|
|
522
|
+
const sections = [];
|
|
523
|
+
for (const sectionName of ["dependencies", "devDependencies"]) {
|
|
524
|
+
const section = packageJson[sectionName];
|
|
525
|
+
if (section && typeof section === "object" && !Array.isArray(section)) sections.push(section);
|
|
526
|
+
}
|
|
527
|
+
const workspaces = packageJson.workspaces;
|
|
528
|
+
if (workspaces && typeof workspaces === "object" && !Array.isArray(workspaces)) {
|
|
529
|
+
const catalog = workspaces.catalog;
|
|
530
|
+
if (catalog && typeof catalog === "object" && !Array.isArray(catalog)) sections.push(catalog);
|
|
531
|
+
}
|
|
532
|
+
return sections;
|
|
533
|
+
}
|
|
510
534
|
function parseVersion(value) {
|
|
511
535
|
const normalized = value.replace(/^[^\d]*/, "");
|
|
512
536
|
const dashIdx = normalized.indexOf("-");
|
|
@@ -552,6 +576,10 @@ function getVersionPrefix(version) {
|
|
|
552
576
|
function applyVersionPrefix(currentVersion, resolvedVersion) {
|
|
553
577
|
return `${getVersionPrefix(currentVersion)}${resolvedVersion}`;
|
|
554
578
|
}
|
|
579
|
+
function shouldApplyResolvedVersion(currentVersion, resolvedVersion, channel) {
|
|
580
|
+
if (channel !== "beta") return true;
|
|
581
|
+
return compareVersions(resolvedVersion, currentVersion) >= 0;
|
|
582
|
+
}
|
|
555
583
|
function isRegistrySemverSpec(version) {
|
|
556
584
|
return /^[~^]?\d/.test(version);
|
|
557
585
|
}
|
|
@@ -580,10 +608,40 @@ function selectRegistryVersionForChannel(packageInfo, channel) {
|
|
|
580
608
|
if (prereleases.length > 0) return prereleases.sort((left, right) => compareVersions(right, left))[0] ?? null;
|
|
581
609
|
return tags.latest ?? null;
|
|
582
610
|
}
|
|
583
|
-
|
|
584
|
-
const
|
|
585
|
-
if (
|
|
586
|
-
|
|
611
|
+
function getVersionsForChannel(packageInfo, channel) {
|
|
612
|
+
const versions = Object.keys(packageInfo.versions ?? {});
|
|
613
|
+
if (channel === "latest") return versions.filter((version) => !isPrerelease(version));
|
|
614
|
+
const prereleases = versions.filter(isPrerelease);
|
|
615
|
+
return prereleases.length > 0 ? prereleases : versions.filter((version) => !isPrerelease(version));
|
|
616
|
+
}
|
|
617
|
+
function resolveSharedFamilyVersion(packageInfos, channel) {
|
|
618
|
+
if (packageInfos.length === 0) return null;
|
|
619
|
+
const firstInfo = packageInfos[0];
|
|
620
|
+
if (!firstInfo) return null;
|
|
621
|
+
let commonVersions = new Set(getVersionsForChannel(firstInfo, channel));
|
|
622
|
+
const remainingInfos = packageInfos.slice(1);
|
|
623
|
+
for (const packageInfo of remainingInfos) {
|
|
624
|
+
const availableVersions = new Set(getVersionsForChannel(packageInfo, channel));
|
|
625
|
+
commonVersions = new Set([...commonVersions].filter((version) => availableVersions.has(version)));
|
|
626
|
+
}
|
|
627
|
+
return [...commonVersions].sort((left, right) => compareVersions(right, left))[0] ?? null;
|
|
628
|
+
}
|
|
629
|
+
function applySynchronizedFamilyVersions(resolvedVersions, packageInfos, channel) {
|
|
630
|
+
for (const family of SYNCHRONIZED_VERSION_FAMILIES) {
|
|
631
|
+
const selectedPackages = family.packages.filter((packageName) => resolvedVersions.has(packageName));
|
|
632
|
+
if (selectedPackages.length < 2) continue;
|
|
633
|
+
const selectedPackageInfos = selectedPackages.flatMap((packageName) => {
|
|
634
|
+
const packageInfo = packageInfos.get(packageName);
|
|
635
|
+
return packageInfo ? [packageInfo] : [];
|
|
636
|
+
});
|
|
637
|
+
if (selectedPackageInfos.length !== selectedPackages.length) continue;
|
|
638
|
+
const sharedVersion = resolveSharedFamilyVersion(selectedPackageInfos, channel);
|
|
639
|
+
if (!sharedVersion) {
|
|
640
|
+
log.warn(`Failed to resolve shared ${channel} version for ${family.name} packages`);
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
643
|
+
for (const packageName of selectedPackages) resolvedVersions.set(packageName, sharedVersion);
|
|
644
|
+
}
|
|
587
645
|
}
|
|
588
646
|
async function collectPackageJsonPaths(projectDir) {
|
|
589
647
|
const results = [];
|
|
@@ -609,35 +667,36 @@ async function applyDependencyVersionChannel(projectDir, channel) {
|
|
|
609
667
|
const packageNames = /* @__PURE__ */ new Set();
|
|
610
668
|
for (const packageJsonPath of packageJsonPaths) {
|
|
611
669
|
const packageJson = await fs.readJson(packageJsonPath);
|
|
612
|
-
for (const [depName, depVersion] of Object.entries(
|
|
613
|
-
for (const [depName, depVersion] of Object.entries(packageJson.devDependencies ?? {})) if (typeof depVersion === "string" && isRegistrySemverSpec(depVersion)) packageNames.add(depName);
|
|
670
|
+
for (const section of getVersionSections(packageJson)) for (const [depName, depVersion] of Object.entries(section)) if (typeof depVersion === "string" && isRegistrySemverSpec(depVersion)) packageNames.add(depName);
|
|
614
671
|
}
|
|
615
672
|
if (packageNames.size === 0) return;
|
|
616
673
|
const resolvedVersions = /* @__PURE__ */ new Map();
|
|
674
|
+
const packageInfos = /* @__PURE__ */ new Map();
|
|
617
675
|
await mapWithConcurrency([...packageNames], async (packageName) => {
|
|
618
676
|
try {
|
|
619
|
-
const
|
|
677
|
+
const packageInfo = await fetchPackageInfo(packageName);
|
|
678
|
+
const resolvedVersion = selectRegistryVersionForChannel(packageInfo, channel);
|
|
679
|
+
if (!resolvedVersion) throw new Error(`No ${channel} version available for ${packageName}`);
|
|
680
|
+
packageInfos.set(packageName, packageInfo);
|
|
620
681
|
resolvedVersions.set(packageName, resolvedVersion);
|
|
621
682
|
} catch (error) {
|
|
622
683
|
log.warn(`Failed to resolve ${channel} version for ${packageName}: ${error instanceof Error ? error.message : String(error)}`);
|
|
623
684
|
}
|
|
624
685
|
}, REGISTRY_CONCURRENCY);
|
|
625
686
|
if (resolvedVersions.size === 0) return;
|
|
687
|
+
applySynchronizedFamilyVersions(resolvedVersions, packageInfos, channel);
|
|
626
688
|
for (const packageJsonPath of packageJsonPaths) {
|
|
627
689
|
const packageJson = await fs.readJson(packageJsonPath);
|
|
628
690
|
let changed = false;
|
|
629
|
-
for (const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
section[packageName] = nextVersion;
|
|
639
|
-
changed = true;
|
|
640
|
-
}
|
|
691
|
+
for (const section of getVersionSections(packageJson)) for (const [packageName, currentVersion] of Object.entries(section)) {
|
|
692
|
+
if (!isRegistrySemverSpec(currentVersion)) continue;
|
|
693
|
+
const resolvedVersion = resolvedVersions.get(packageName);
|
|
694
|
+
if (!resolvedVersion) continue;
|
|
695
|
+
if (!shouldApplyResolvedVersion(currentVersion, resolvedVersion, channel)) continue;
|
|
696
|
+
const nextVersion = applyVersionPrefix(currentVersion, resolvedVersion);
|
|
697
|
+
if (nextVersion !== currentVersion) {
|
|
698
|
+
section[packageName] = nextVersion;
|
|
699
|
+
changed = true;
|
|
641
700
|
}
|
|
642
701
|
}
|
|
643
702
|
if (changed) await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "./bts-config-DQVWvPDs.mjs";
|
|
3
|
+
import "./errors-ns_o2OKg.mjs";
|
|
4
|
+
import "./prompt-environment-BR0Kkw2W.mjs";
|
|
5
|
+
import "./analytics-DVltG11u.mjs";
|
|
6
|
+
import "./file-formatter-gvmrpd-g.mjs";
|
|
7
|
+
import "./config-processing-D9-F2Us9.mjs";
|
|
8
|
+
import "./scaffold-manifest-Dyi0voqE.mjs";
|
|
9
|
+
import { a as startMcpServer, i as recommendStackFromBrief, n as MCP_STACK_UPDATE_SCHEMA, r as getMcpGraphPreview, t as MCP_PLAN_CREATE_SCHEMA } from "./mcp-entry.mjs";
|
|
10
|
+
|
|
11
|
+
export { recommendStackFromBrief, startMcpServer };
|