create-better-fullstack 1.5.1 → 1.5.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,5 @@
1
+ #!/usr/bin/env node
2
+ import "./bts-config-BCe8SqYV.mjs";
3
+ import { i as setupLefthook, n as setupBiome, r as setupHusky, t as setupAddons } from "./addons-setup-1jZXP0D3.mjs";
4
+
5
+ export { setupAddons };
@@ -0,0 +1,308 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs-extra";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { dependencyVersionMap } from "@better-fullstack/template-generator";
6
+ import * as JSONC from "jsonc-parser";
7
+
8
+ //#region src/utils/get-package-manager.ts
9
+ const getUserPkgManager = () => {
10
+ const userAgent = process.env.npm_config_user_agent;
11
+ if (userAgent?.startsWith("pnpm")) return "pnpm";
12
+ if (userAgent?.startsWith("bun")) return "bun";
13
+ return "npm";
14
+ };
15
+
16
+ //#endregion
17
+ //#region src/constants.ts
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const distPath = path.dirname(__filename);
20
+ const PKG_ROOT = path.join(distPath, "../");
21
+ const DEFAULT_CONFIG_BASE = {
22
+ projectName: "my-app",
23
+ relativePath: "my-app",
24
+ ecosystem: "typescript",
25
+ frontend: ["tanstack-router"],
26
+ database: "sqlite",
27
+ orm: "drizzle",
28
+ auth: "better-auth",
29
+ payments: "none",
30
+ email: "none",
31
+ fileUpload: "none",
32
+ effect: "none",
33
+ stateManagement: "none",
34
+ validation: "zod",
35
+ forms: "react-hook-form",
36
+ testing: "vitest",
37
+ ai: "none",
38
+ realtime: "none",
39
+ jobQueue: "none",
40
+ caching: "none",
41
+ search: "none",
42
+ fileStorage: "none",
43
+ animation: "none",
44
+ logging: "none",
45
+ observability: "none",
46
+ featureFlags: "none",
47
+ analytics: "none",
48
+ cms: "none",
49
+ addons: ["turborepo"],
50
+ examples: [],
51
+ git: true,
52
+ install: true,
53
+ versionChannel: "stable",
54
+ dbSetup: "none",
55
+ backend: "hono",
56
+ runtime: "bun",
57
+ api: "trpc",
58
+ webDeploy: "none",
59
+ serverDeploy: "none",
60
+ cssFramework: "tailwind",
61
+ uiLibrary: "shadcn-ui",
62
+ shadcnBase: "radix",
63
+ shadcnStyle: "nova",
64
+ shadcnIconLibrary: "lucide",
65
+ shadcnColorTheme: "neutral",
66
+ shadcnBaseColor: "neutral",
67
+ shadcnFont: "inter",
68
+ shadcnRadius: "default",
69
+ rustWebFramework: "none",
70
+ rustFrontend: "none",
71
+ rustOrm: "none",
72
+ rustApi: "none",
73
+ rustCli: "none",
74
+ rustLibraries: [],
75
+ pythonWebFramework: "fastapi",
76
+ pythonOrm: "sqlalchemy",
77
+ pythonValidation: "pydantic",
78
+ pythonAi: [],
79
+ pythonTaskQueue: "none",
80
+ pythonQuality: "ruff",
81
+ goWebFramework: "gin",
82
+ goOrm: "gorm",
83
+ goApi: "none",
84
+ goCli: "none",
85
+ goLogging: "zap",
86
+ aiDocs: ["claude-md"]
87
+ };
88
+ function getDefaultConfig() {
89
+ return {
90
+ ...DEFAULT_CONFIG_BASE,
91
+ projectDir: path.resolve(process.cwd(), DEFAULT_CONFIG_BASE.projectName),
92
+ packageManager: getUserPkgManager(),
93
+ frontend: [...DEFAULT_CONFIG_BASE.frontend],
94
+ addons: [...DEFAULT_CONFIG_BASE.addons],
95
+ examples: [...DEFAULT_CONFIG_BASE.examples],
96
+ rustLibraries: [...DEFAULT_CONFIG_BASE.rustLibraries],
97
+ pythonAi: [...DEFAULT_CONFIG_BASE.pythonAi],
98
+ aiDocs: [...DEFAULT_CONFIG_BASE.aiDocs]
99
+ };
100
+ }
101
+ const DEFAULT_CONFIG = getDefaultConfig();
102
+ /**
103
+ * Default UI library for each frontend framework
104
+ * Falls back based on what's compatible
105
+ */
106
+ const DEFAULT_UI_LIBRARY_BY_FRONTEND = {
107
+ "tanstack-router": "shadcn-ui",
108
+ "react-router": "shadcn-ui",
109
+ "react-vite": "shadcn-ui",
110
+ "tanstack-start": "shadcn-ui",
111
+ next: "shadcn-ui",
112
+ nuxt: "daisyui",
113
+ svelte: "daisyui",
114
+ solid: "daisyui",
115
+ "solid-start": "daisyui",
116
+ astro: "daisyui",
117
+ qwik: "daisyui",
118
+ angular: "daisyui",
119
+ redwood: "daisyui",
120
+ fresh: "daisyui",
121
+ "native-bare": "none",
122
+ "native-uniwind": "none",
123
+ "native-unistyles": "none",
124
+ none: "none"
125
+ };
126
+
127
+ //#endregion
128
+ //#region src/utils/get-latest-cli-version.ts
129
+ const getLatestCLIVersion = () => {
130
+ const packageJsonPath = path.join(PKG_ROOT, "package.json");
131
+ return fs.readJSONSync(packageJsonPath).version ?? "1.0.0";
132
+ };
133
+
134
+ //#endregion
135
+ //#region src/utils/bts-config.ts
136
+ const BTS_CONFIG_FILE = "bts.jsonc";
137
+ async function writeBtsConfig(projectConfig) {
138
+ const btsConfig = {
139
+ version: getLatestCLIVersion(),
140
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
141
+ ecosystem: projectConfig.ecosystem,
142
+ database: projectConfig.database,
143
+ orm: projectConfig.orm,
144
+ backend: projectConfig.backend,
145
+ runtime: projectConfig.runtime,
146
+ frontend: projectConfig.frontend,
147
+ addons: projectConfig.addons,
148
+ examples: projectConfig.examples,
149
+ auth: projectConfig.auth,
150
+ payments: projectConfig.payments,
151
+ email: projectConfig.email,
152
+ fileUpload: projectConfig.fileUpload,
153
+ effect: projectConfig.effect,
154
+ ai: projectConfig.ai,
155
+ stateManagement: projectConfig.stateManagement,
156
+ validation: projectConfig.validation,
157
+ forms: projectConfig.forms,
158
+ testing: projectConfig.testing,
159
+ packageManager: projectConfig.packageManager,
160
+ versionChannel: projectConfig.versionChannel,
161
+ dbSetup: projectConfig.dbSetup,
162
+ api: projectConfig.api,
163
+ webDeploy: projectConfig.webDeploy,
164
+ serverDeploy: projectConfig.serverDeploy,
165
+ cssFramework: projectConfig.cssFramework,
166
+ uiLibrary: projectConfig.uiLibrary,
167
+ realtime: projectConfig.realtime,
168
+ jobQueue: projectConfig.jobQueue,
169
+ animation: projectConfig.animation,
170
+ logging: projectConfig.logging,
171
+ observability: projectConfig.observability,
172
+ featureFlags: projectConfig.featureFlags,
173
+ analytics: projectConfig.analytics,
174
+ cms: projectConfig.cms,
175
+ caching: projectConfig.caching,
176
+ search: projectConfig.search,
177
+ fileStorage: projectConfig.fileStorage,
178
+ rustWebFramework: projectConfig.rustWebFramework,
179
+ rustFrontend: projectConfig.rustFrontend,
180
+ rustOrm: projectConfig.rustOrm,
181
+ rustApi: projectConfig.rustApi,
182
+ rustCli: projectConfig.rustCli,
183
+ rustLibraries: projectConfig.rustLibraries,
184
+ pythonWebFramework: projectConfig.pythonWebFramework,
185
+ pythonOrm: projectConfig.pythonOrm,
186
+ pythonValidation: projectConfig.pythonValidation,
187
+ pythonAi: projectConfig.pythonAi,
188
+ pythonTaskQueue: projectConfig.pythonTaskQueue,
189
+ pythonQuality: projectConfig.pythonQuality,
190
+ goWebFramework: projectConfig.goWebFramework,
191
+ goOrm: projectConfig.goOrm,
192
+ goApi: projectConfig.goApi,
193
+ goCli: projectConfig.goCli,
194
+ goLogging: projectConfig.goLogging,
195
+ aiDocs: projectConfig.aiDocs
196
+ };
197
+ const baseContent = {
198
+ $schema: "https://better-fullstack-web.vercel.app/schema.json",
199
+ version: btsConfig.version,
200
+ createdAt: btsConfig.createdAt,
201
+ ecosystem: btsConfig.ecosystem,
202
+ database: btsConfig.database,
203
+ orm: btsConfig.orm,
204
+ backend: btsConfig.backend,
205
+ runtime: btsConfig.runtime,
206
+ frontend: btsConfig.frontend,
207
+ addons: btsConfig.addons,
208
+ examples: btsConfig.examples,
209
+ auth: btsConfig.auth,
210
+ payments: btsConfig.payments,
211
+ email: btsConfig.email,
212
+ fileUpload: btsConfig.fileUpload,
213
+ effect: btsConfig.effect,
214
+ ai: btsConfig.ai,
215
+ stateManagement: btsConfig.stateManagement,
216
+ validation: btsConfig.validation,
217
+ forms: btsConfig.forms,
218
+ testing: btsConfig.testing,
219
+ packageManager: btsConfig.packageManager,
220
+ versionChannel: btsConfig.versionChannel,
221
+ dbSetup: btsConfig.dbSetup,
222
+ api: btsConfig.api,
223
+ webDeploy: btsConfig.webDeploy,
224
+ serverDeploy: btsConfig.serverDeploy,
225
+ cssFramework: btsConfig.cssFramework,
226
+ uiLibrary: btsConfig.uiLibrary,
227
+ realtime: btsConfig.realtime,
228
+ jobQueue: btsConfig.jobQueue,
229
+ animation: btsConfig.animation,
230
+ logging: btsConfig.logging,
231
+ observability: btsConfig.observability,
232
+ featureFlags: btsConfig.featureFlags,
233
+ analytics: btsConfig.analytics,
234
+ cms: btsConfig.cms,
235
+ caching: btsConfig.caching,
236
+ search: btsConfig.search,
237
+ fileStorage: btsConfig.fileStorage,
238
+ rustWebFramework: btsConfig.rustWebFramework,
239
+ rustFrontend: btsConfig.rustFrontend,
240
+ rustOrm: btsConfig.rustOrm,
241
+ rustApi: btsConfig.rustApi,
242
+ rustCli: btsConfig.rustCli,
243
+ rustLibraries: btsConfig.rustLibraries,
244
+ pythonWebFramework: btsConfig.pythonWebFramework,
245
+ pythonOrm: btsConfig.pythonOrm,
246
+ pythonValidation: btsConfig.pythonValidation,
247
+ pythonAi: btsConfig.pythonAi,
248
+ pythonTaskQueue: btsConfig.pythonTaskQueue,
249
+ pythonQuality: btsConfig.pythonQuality,
250
+ goWebFramework: btsConfig.goWebFramework,
251
+ goOrm: btsConfig.goOrm,
252
+ goApi: btsConfig.goApi,
253
+ goCli: btsConfig.goCli,
254
+ goLogging: btsConfig.goLogging,
255
+ aiDocs: btsConfig.aiDocs
256
+ };
257
+ let configContent = JSON.stringify(baseContent);
258
+ const formatResult = JSONC.format(configContent, void 0, {
259
+ tabSize: 2,
260
+ insertSpaces: true,
261
+ eol: "\n"
262
+ });
263
+ configContent = JSONC.applyEdits(configContent, formatResult);
264
+ const finalContent = `// Better Fullstack configuration file
265
+ // safe to delete
266
+
267
+ ${configContent}`;
268
+ const configPath = path.join(projectConfig.projectDir, BTS_CONFIG_FILE);
269
+ await fs.writeFile(configPath, finalContent, "utf-8");
270
+ }
271
+ async function readBtsConfig(projectDir) {
272
+ try {
273
+ const configPath = path.join(projectDir, BTS_CONFIG_FILE);
274
+ if (!await fs.pathExists(configPath)) return null;
275
+ const configContent = await fs.readFile(configPath, "utf-8");
276
+ const errors = [];
277
+ const config = JSONC.parse(configContent, errors, {
278
+ allowTrailingComma: true,
279
+ disallowComments: false
280
+ });
281
+ if (errors.length > 0) {
282
+ console.warn("Warning: Found errors parsing bts.jsonc:", errors);
283
+ return null;
284
+ }
285
+ return config;
286
+ } catch {
287
+ return null;
288
+ }
289
+ }
290
+ async function updateBtsConfig(projectDir, updates) {
291
+ try {
292
+ const configPath = path.join(projectDir, BTS_CONFIG_FILE);
293
+ if (!await fs.pathExists(configPath)) return;
294
+ let modifiedContent = await fs.readFile(configPath, "utf-8");
295
+ for (const [key, value] of Object.entries(updates)) {
296
+ const editResult = JSONC.modify(modifiedContent, [key], value, { formattingOptions: {
297
+ tabSize: 2,
298
+ insertSpaces: true,
299
+ eol: "\n"
300
+ } });
301
+ modifiedContent = JSONC.applyEdits(modifiedContent, editResult);
302
+ }
303
+ await fs.writeFile(configPath, modifiedContent, "utf-8");
304
+ } catch {}
305
+ }
306
+
307
+ //#endregion
308
+ export { DEFAULT_CONFIG as a, getDefaultConfig as c, getLatestCLIVersion as i, getUserPkgManager as l, updateBtsConfig as n, DEFAULT_UI_LIBRARY_BY_FRONTEND as o, writeBtsConfig as r, dependencyVersionMap as s, readBtsConfig as t };
package/dist/cli.mjs CHANGED
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { s as createBtsCli } from "./src-hfdQPH0o.mjs";
3
-
4
2
  //#region src/cli.ts
5
- createBtsCli().run();
3
+ if (process.argv[2] === "mcp" && process.argv.length === 3) import("./mcp-C_X1WfCg.mjs").then((m) => m.startMcpServer());
4
+ else import("./index.mjs").then((m) => m.createBtsCli().run());
6
5
 
7
6
  //#endregion
8
7
  export { };
package/dist/index.d.mts CHANGED
@@ -14,6 +14,7 @@ interface AddResult {
14
14
  addedAddons: types_d_exports.Addons[];
15
15
  projectDir: string;
16
16
  error?: string;
17
+ setupWarnings?: string[];
17
18
  }
18
19
  //#endregion
19
20
  //#region src/index.d.ts
@@ -206,6 +207,7 @@ declare const router: {
206
207
  none: "none";
207
208
  meilisearch: "meilisearch";
208
209
  typesense: "typesense";
210
+ elasticsearch: "elasticsearch";
209
211
  }>>;
210
212
  fileStorage: z.ZodOptional<z.ZodEnum<{
211
213
  none: "none";
@@ -573,7 +575,7 @@ declare const router: {
573
575
  analytics: "none" | "plausible" | "umami";
574
576
  cms: "none" | "payload" | "sanity" | "strapi" | "tinacms";
575
577
  caching: "none" | "upstash-redis";
576
- search: "none" | "meilisearch" | "typesense";
578
+ search: "none" | "meilisearch" | "typesense" | "elasticsearch";
577
579
  fileStorage: "none" | "s3" | "r2";
578
580
  rustWebFramework: "none" | "axum" | "actix-web";
579
581
  rustFrontend: "none" | "leptos" | "dioxus";
@@ -660,7 +662,7 @@ declare const router: {
660
662
  analytics: "none" | "plausible" | "umami";
661
663
  cms: "none" | "payload" | "sanity" | "strapi" | "tinacms";
662
664
  caching: "none" | "upstash-redis";
663
- search: "none" | "meilisearch" | "typesense";
665
+ search: "none" | "meilisearch" | "typesense" | "elasticsearch";
664
666
  fileStorage: "none" | "s3" | "r2";
665
667
  rustWebFramework: "none" | "axum" | "actix-web";
666
668
  rustFrontend: "none" | "leptos" | "dioxus";
@@ -771,6 +773,7 @@ declare const router: {
771
773
  ecosystem: z.ZodOptional<z.ZodString>;
772
774
  "list-ecosystems": z.ZodDefault<z.ZodBoolean>;
773
775
  }, z.core.$strip>, _orpc_server0.Schema<void, void>, _orpc_server0.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
776
+ mcp: _orpc_server0.Procedure<_orpc_server0.MergedInitialContext<Record<never, never>, Record<never, never>, Record<never, never>>, Record<never, never>, _orpc_server0.Schema<unknown, unknown>, _orpc_server0.Schema<void, void>, _orpc_server0.MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
774
777
  };
775
778
  declare function createBtsCli(): trpc_cli0.TrpcCli;
776
779
  /**