create-better-fullstack 2.0.1 → 2.0.2

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,7 @@
1
+ #!/usr/bin/env node
2
+ import "./bts-config-Bg1Qea9Y.mjs";
3
+ import { a as docs, c as sponsors, i as createBtsCli, n as builder, o as history, r as create, s as router, t as add } from "./run-DQlymC4z.mjs";
4
+ import "./install-dependencies-D6-GO3BZ.mjs";
5
+ import "./addons-setup-HSghQS7c.mjs";
6
+
7
+ export { createBtsCli };
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env node
2
+ import { confirm, isCancel, log, select, spinner } from "@clack/prompts";
3
+ import pc from "picocolors";
4
+ import fs from "fs-extra";
5
+ import { ECOSYSTEM_GROUPS, checkAllVersions, generateCliReport, listEcosystems } from "@better-fullstack/template-generator";
6
+ import path from "path";
7
+
8
+ //#region src/commands/update-deps.ts
9
+ /**
10
+ * CLI command to check and update dependency versions
11
+ */
12
+ /**
13
+ * Format a version update for display
14
+ */
15
+ function formatUpdate(info) {
16
+ const colorFn = {
17
+ downgrade: pc.red,
18
+ major: pc.red,
19
+ minor: pc.yellow,
20
+ patch: pc.green,
21
+ none: pc.gray
22
+ }[info.updateType];
23
+ return `${colorFn(`[${info.updateType.toUpperCase()}]`.padEnd(8))} ${pc.cyan(info.name.padEnd(45))} ${pc.dim(info.current)} ${pc.dim("->")} ${pc.green(info.latest)}`;
24
+ }
25
+ /**
26
+ * Get the path to add-deps.ts
27
+ */
28
+ function getAddDepsPath() {
29
+ const possiblePaths = [
30
+ path.join(process.cwd(), "packages/template-generator/src/utils/add-deps.ts"),
31
+ path.join(process.cwd(), "../../packages/template-generator/src/utils/add-deps.ts"),
32
+ path.join(process.cwd(), "node_modules/@better-fullstack/template-generator/src/utils/add-deps.ts")
33
+ ];
34
+ for (const p of possiblePaths) if (fs.existsSync(p)) return p;
35
+ return possiblePaths[0];
36
+ }
37
+ /**
38
+ * Update the add-deps.ts file with new versions
39
+ */
40
+ async function updateAddDepsFile(updates) {
41
+ const filePath = getAddDepsPath();
42
+ if (!fs.existsSync(filePath)) {
43
+ log.error(`Could not find add-deps.ts at ${filePath}`);
44
+ return false;
45
+ }
46
+ let content = await fs.readFile(filePath, "utf-8");
47
+ let updated = false;
48
+ for (const update of updates) {
49
+ const escapedName = update.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
50
+ const pattern = new RegExp(`(["']${escapedName}["']:\\s*["'])([^"']+)(["'])`, "g");
51
+ const newContent = content.replace(pattern, `$1${update.latest}$3`);
52
+ if (newContent !== content) {
53
+ content = newContent;
54
+ updated = true;
55
+ }
56
+ }
57
+ if (updated) {
58
+ await fs.writeFile(filePath, content, "utf-8");
59
+ return true;
60
+ }
61
+ return false;
62
+ }
63
+ /**
64
+ * Interactive mode: prompt for each update
65
+ */
66
+ async function interactiveUpdate(updates) {
67
+ const toApply = [];
68
+ for (const update of updates) {
69
+ console.log("\n" + pc.bold("-----------------------------------"));
70
+ console.log(formatUpdate(update));
71
+ if (update.ecosystem) console.log(pc.dim(` Ecosystem: ${update.ecosystem}`));
72
+ if (update.updateType === "major") console.log(pc.yellow(" Warning: Breaking changes possible. Check changelog."));
73
+ else if (update.updateType === "downgrade") console.log(pc.red(" Warning: npm latest is lower than current pinned version. Review carefully."));
74
+ const action = await select({
75
+ message: "What would you like to do?",
76
+ options: [
77
+ {
78
+ value: "update",
79
+ label: "Update to latest"
80
+ },
81
+ {
82
+ value: "skip",
83
+ label: "Skip this package"
84
+ },
85
+ {
86
+ value: "quit",
87
+ label: "Quit (apply selected updates)"
88
+ }
89
+ ]
90
+ });
91
+ if (isCancel(action) || action === "quit") break;
92
+ if (action === "update") toApply.push(update);
93
+ }
94
+ return toApply;
95
+ }
96
+ /**
97
+ * Main handler for the update-deps command
98
+ */
99
+ async function updateDepsHandler(options) {
100
+ const { check = false, patch = false, all = false, ecosystem } = options;
101
+ if (ecosystem) {
102
+ const validEcosystems = listEcosystems();
103
+ if (!validEcosystems.includes(ecosystem)) {
104
+ log.error(`Invalid ecosystem: ${ecosystem}. Valid options: ${validEcosystems.join(", ")}`);
105
+ return;
106
+ }
107
+ }
108
+ const s = spinner();
109
+ s.start(ecosystem ? `Checking ${ecosystem} packages for updates...` : "Checking all packages for updates...");
110
+ let result;
111
+ try {
112
+ result = await checkAllVersions({
113
+ ecosystem,
114
+ concurrency: 5,
115
+ delayMs: 100,
116
+ onProgress: (checked, total) => {
117
+ s.message(`Checking packages (${checked}/${total})...`);
118
+ }
119
+ });
120
+ } catch (error) {
121
+ s.stop("Failed to check versions");
122
+ log.error(String(error));
123
+ return;
124
+ }
125
+ s.stop("Version check complete");
126
+ console.log(generateCliReport(result));
127
+ if (check || result.outdated.length === 0) return;
128
+ let toApply = [];
129
+ const downgradeCount = result.outdated.filter((u) => u.updateType === "downgrade").length;
130
+ if (patch) {
131
+ toApply = result.outdated.filter((u) => u.updateType === "patch" || u.updateType === "minor");
132
+ if (toApply.length === 0) {
133
+ log.info("No patch/minor updates available.");
134
+ return;
135
+ }
136
+ log.info(`Found ${toApply.length} patch/minor updates to apply automatically.`);
137
+ if (downgradeCount > 0) log.warn(`${downgradeCount} downgrade${downgradeCount === 1 ? "" : "s"} detected and excluded from --patch mode.`);
138
+ const shouldProceed = await confirm({ message: `Apply ${toApply.length} safe updates?` });
139
+ if (isCancel(shouldProceed) || !shouldProceed) {
140
+ log.info("Cancelled.");
141
+ return;
142
+ }
143
+ } else if (all) {
144
+ log.info("\nEntering interactive mode...");
145
+ toApply = await interactiveUpdate(result.outdated);
146
+ if (toApply.length === 0) {
147
+ log.info("No updates selected.");
148
+ return;
149
+ }
150
+ } else {
151
+ const shouldProceed = await confirm({ message: downgradeCount > 0 ? `Apply all ${result.outdated.length} updates (including ${downgradeCount} downgrade${downgradeCount === 1 ? "" : "s"})?` : `Apply all ${result.outdated.length} updates?` });
152
+ if (isCancel(shouldProceed) || !shouldProceed) {
153
+ log.info("Cancelled. Use --check to only view updates without prompting.");
154
+ return;
155
+ }
156
+ toApply = result.outdated;
157
+ }
158
+ const updateSpinner = spinner();
159
+ updateSpinner.start(`Applying ${toApply.length} updates...`);
160
+ try {
161
+ if (await updateAddDepsFile(toApply)) {
162
+ updateSpinner.stop("Updates applied successfully!");
163
+ console.log("\n" + pc.green("Updated packages:"));
164
+ for (const update of toApply) console.log(` ${pc.cyan(update.name)}: ${update.current} -> ${update.latest}`);
165
+ console.log("\n" + pc.yellow("Next steps:"));
166
+ console.log(" 1. Review the changes in add-deps.ts");
167
+ console.log(" 2. Run: bun run build (in packages/template-generator)");
168
+ console.log(" 3. Run tests to verify compatibility");
169
+ console.log(" 4. Update any hardcoded versions in template files");
170
+ } else {
171
+ updateSpinner.stop("No changes were made");
172
+ log.warn("Could not apply updates. The file may have changed.");
173
+ }
174
+ } catch (error) {
175
+ updateSpinner.stop("Failed to apply updates");
176
+ log.error(String(error));
177
+ }
178
+ }
179
+ /**
180
+ * Show available ecosystems
181
+ */
182
+ function showEcosystems() {
183
+ console.log("\nAvailable ecosystems:\n");
184
+ for (const [name, packages] of Object.entries(ECOSYSTEM_GROUPS)) console.log(` ${pc.cyan(name.padEnd(15))} (${packages.length} packages)`);
185
+ console.log(`\nUsage: update-deps --ecosystem <name>`);
186
+ }
187
+
188
+ //#endregion
189
+ export { showEcosystems, updateDepsHandler };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-fullstack",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
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,31 +127,28 @@
127
127
  "prepublishOnly": "npm run build"
128
128
  },
129
129
  "dependencies": {
130
- "@better-fullstack/template-generator": "^2.0.1",
131
- "@better-fullstack/types": "^2.0.1",
130
+ "@better-fullstack/template-generator": "^2.0.2",
131
+ "@better-fullstack/types": "^2.0.2",
132
132
  "@clack/core": "^0.5.0",
133
- "@clack/prompts": "^1.5.0",
134
- "@orpc/server": "^1.14.4",
133
+ "@clack/prompts": "^1.5.1",
134
+ "@orpc/server": "^1.14.5",
135
135
  "consola": "^3.4.2",
136
136
  "env-paths": "^4.0.0",
137
137
  "execa": "^9.6.1",
138
138
  "fs-extra": "^11.3.5",
139
139
  "gradient-string": "^3.0.0",
140
- "handlebars": "^4.7.9",
141
140
  "jsonc-parser": "^3.3.1",
142
141
  "oxfmt": "^0.19.0",
143
142
  "picocolors": "^1.1.1",
144
- "tinyglobby": "^0.2.17",
145
143
  "@modelcontextprotocol/sdk": "^1.29.0",
146
144
  "trpc-cli": "^0.12.1",
147
- "ts-morph": "^27.0.2",
148
- "yaml": "^2.9.0",
149
145
  "zod": "4.4.3"
150
146
  },
151
147
  "devDependencies": {
152
148
  "@types/bun": "^1.3.14",
149
+ "ts-morph": "^27.0.2",
153
150
  "@types/fs-extra": "^11.0.4",
154
- "@types/node": "^25.9.1",
151
+ "@types/node": "^25.9.2",
155
152
  "publint": "^0.3.21",
156
153
  "tsdown": "^0.18.2",
157
154
  "typescript": "^5.9.3"
@@ -1,5 +0,0 @@
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 +0,0 @@
1
- #!/usr/bin/env node
2
- import "./bts-config-CSvxsFML.mjs";
3
- import { t as startMcpServer } from "./mcp-entry.mjs";
4
-
5
- export { startMcpServer };