create-better-t-stack 3.7.3-canary.8e47571f → 3.7.3-canary.8e4d5716

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.
Files changed (104) hide show
  1. package/package.json +19 -23
  2. package/src/cli.ts +3 -0
  3. package/src/constants.ts +188 -0
  4. package/src/helpers/addons/addons-setup.ts +226 -0
  5. package/src/helpers/addons/examples-setup.ts +104 -0
  6. package/src/helpers/addons/fumadocs-setup.ts +103 -0
  7. package/src/helpers/addons/ruler-setup.ts +139 -0
  8. package/src/helpers/addons/starlight-setup.ts +51 -0
  9. package/src/helpers/addons/tauri-setup.ts +96 -0
  10. package/src/helpers/addons/ultracite-setup.ts +232 -0
  11. package/src/helpers/addons/vite-pwa-setup.ts +59 -0
  12. package/src/helpers/core/add-addons.ts +85 -0
  13. package/src/helpers/core/add-deployment.ts +102 -0
  14. package/src/helpers/core/api-setup.ts +280 -0
  15. package/src/helpers/core/auth-setup.ts +203 -0
  16. package/src/helpers/core/backend-setup.ts +73 -0
  17. package/src/helpers/core/command-handlers.ts +354 -0
  18. package/src/helpers/core/convex-codegen.ts +14 -0
  19. package/src/helpers/core/create-project.ts +133 -0
  20. package/src/helpers/core/create-readme.ts +687 -0
  21. package/src/helpers/core/db-setup.ts +184 -0
  22. package/src/helpers/core/detect-project-config.ts +41 -0
  23. package/src/helpers/core/env-setup.ts +449 -0
  24. package/src/helpers/core/git.ts +31 -0
  25. package/src/helpers/core/install-dependencies.ts +32 -0
  26. package/src/helpers/core/payments-setup.ts +48 -0
  27. package/src/helpers/core/post-installation.ts +383 -0
  28. package/src/helpers/core/project-config.ts +246 -0
  29. package/src/helpers/core/runtime-setup.ts +76 -0
  30. package/src/helpers/core/template-manager.ts +917 -0
  31. package/src/helpers/core/workspace-setup.ts +184 -0
  32. package/src/helpers/database-providers/d1-setup.ts +28 -0
  33. package/src/helpers/database-providers/docker-compose-setup.ts +50 -0
  34. package/src/helpers/database-providers/mongodb-atlas-setup.ts +186 -0
  35. package/src/helpers/database-providers/neon-setup.ts +243 -0
  36. package/src/helpers/database-providers/planetscale-setup.ts +78 -0
  37. package/src/helpers/database-providers/prisma-postgres-setup.ts +196 -0
  38. package/src/helpers/database-providers/supabase-setup.ts +218 -0
  39. package/src/helpers/database-providers/turso-setup.ts +309 -0
  40. package/src/helpers/deployment/alchemy/alchemy-combined-setup.ts +80 -0
  41. package/src/helpers/deployment/alchemy/alchemy-next-setup.ts +51 -0
  42. package/src/helpers/deployment/alchemy/alchemy-nuxt-setup.ts +104 -0
  43. package/src/helpers/deployment/alchemy/alchemy-react-router-setup.ts +32 -0
  44. package/src/helpers/deployment/alchemy/alchemy-solid-setup.ts +32 -0
  45. package/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts +98 -0
  46. package/src/helpers/deployment/alchemy/alchemy-tanstack-router-setup.ts +33 -0
  47. package/src/helpers/deployment/alchemy/alchemy-tanstack-start-setup.ts +98 -0
  48. package/src/helpers/deployment/alchemy/env-dts-setup.ts +76 -0
  49. package/src/helpers/deployment/alchemy/index.ts +7 -0
  50. package/src/helpers/deployment/server-deploy-setup.ts +55 -0
  51. package/src/helpers/deployment/web-deploy-setup.ts +58 -0
  52. package/src/index.ts +253 -0
  53. package/src/prompts/addons.ts +178 -0
  54. package/src/prompts/api.ts +49 -0
  55. package/src/prompts/auth.ts +84 -0
  56. package/src/prompts/backend.ts +83 -0
  57. package/src/prompts/config-prompts.ts +138 -0
  58. package/src/prompts/database-setup.ts +112 -0
  59. package/src/prompts/database.ts +57 -0
  60. package/src/prompts/examples.ts +64 -0
  61. package/src/prompts/frontend.ts +118 -0
  62. package/src/prompts/git.ts +16 -0
  63. package/src/prompts/install.ts +16 -0
  64. package/src/prompts/orm.ts +53 -0
  65. package/src/prompts/package-manager.ts +32 -0
  66. package/src/prompts/payments.ts +50 -0
  67. package/src/prompts/project-name.ts +86 -0
  68. package/src/prompts/runtime.ts +47 -0
  69. package/src/prompts/server-deploy.ts +91 -0
  70. package/src/prompts/web-deploy.ts +107 -0
  71. package/src/types.ts +2 -0
  72. package/src/utils/add-package-deps.ts +57 -0
  73. package/src/utils/analytics.ts +39 -0
  74. package/src/utils/better-auth-plugin-setup.ts +71 -0
  75. package/src/utils/biome-formatter.ts +82 -0
  76. package/src/utils/bts-config.ts +122 -0
  77. package/src/utils/command-exists.ts +16 -0
  78. package/src/utils/compatibility-rules.ts +319 -0
  79. package/src/utils/compatibility.ts +11 -0
  80. package/src/utils/config-processing.ts +130 -0
  81. package/src/utils/config-validation.ts +470 -0
  82. package/src/utils/display-config.ts +96 -0
  83. package/src/utils/docker-utils.ts +70 -0
  84. package/src/utils/errors.ts +32 -0
  85. package/src/utils/generate-reproducible-command.ts +53 -0
  86. package/src/utils/get-latest-cli-version.ts +11 -0
  87. package/src/utils/get-package-manager.ts +13 -0
  88. package/src/utils/open-url.ts +25 -0
  89. package/src/utils/package-runner.ts +23 -0
  90. package/src/utils/project-directory.ts +102 -0
  91. package/src/utils/project-name-validation.ts +43 -0
  92. package/src/utils/render-title.ts +48 -0
  93. package/src/utils/setup-catalogs.ts +192 -0
  94. package/src/utils/sponsors.ts +101 -0
  95. package/src/utils/telemetry.ts +19 -0
  96. package/src/utils/template-processor.ts +64 -0
  97. package/src/utils/templates.ts +94 -0
  98. package/src/utils/ts-morph.ts +26 -0
  99. package/src/validation.ts +117 -0
  100. package/dist/cli.d.mts +0 -1
  101. package/dist/cli.mjs +0 -8
  102. package/dist/index.d.mts +0 -347
  103. package/dist/index.mjs +0 -4
  104. package/dist/src-CxVxLS85.mjs +0 -7077
@@ -0,0 +1,246 @@
1
+ import path from "node:path";
2
+ import { log } from "@clack/prompts";
3
+ import { execa } from "execa";
4
+ import fs from "fs-extra";
5
+ import type { ProjectConfig } from "../../types";
6
+ import { setupWorkspaceDependencies } from "./workspace-setup";
7
+
8
+ export async function updatePackageConfigurations(projectDir: string, options: ProjectConfig) {
9
+ await updateRootPackageJson(projectDir, options);
10
+
11
+ if (options.backend === "convex") {
12
+ await updateConvexPackageJson(projectDir, options);
13
+ } else if (options.backend !== "none") {
14
+ await updateDbPackageJson(projectDir, options);
15
+ await updateAuthPackageJson(projectDir, options);
16
+ await updateApiPackageJson(projectDir, options);
17
+
18
+ if (options.backend !== "self") {
19
+ await updateServerPackageJson(projectDir, options);
20
+ }
21
+ }
22
+
23
+ await setupWorkspaceDependencies(projectDir, options);
24
+ }
25
+
26
+ async function updateRootPackageJson(projectDir: string, options: ProjectConfig) {
27
+ const rootPackageJsonPath = path.join(projectDir, "package.json");
28
+ if (!(await fs.pathExists(rootPackageJsonPath))) return;
29
+
30
+ const packageJson = await fs.readJson(rootPackageJsonPath);
31
+ packageJson.name = options.projectName;
32
+ packageJson.scripts = packageJson.scripts || {};
33
+ packageJson.workspaces = packageJson.workspaces || [];
34
+
35
+ const scripts = packageJson.scripts;
36
+ const workspaces = packageJson.workspaces;
37
+
38
+ const { projectName, packageManager, backend, database, orm, dbSetup, serverDeploy, addons } =
39
+ options;
40
+
41
+ const backendPackageName = backend === "convex" ? `@${projectName}/backend` : "server";
42
+ const dbPackageName = `@${projectName}/db`;
43
+ const hasTurborepo = addons.includes("turborepo");
44
+
45
+ const needsDbScripts =
46
+ backend !== "convex" && database !== "none" && orm !== "none" && orm !== "mongoose";
47
+
48
+ const isD1Alchemy = dbSetup === "d1" && serverDeploy === "alchemy";
49
+
50
+ const pmConfig = getPackageManagerConfig(packageManager, hasTurborepo);
51
+
52
+ scripts.dev = pmConfig.dev;
53
+ scripts.build = pmConfig.build;
54
+ scripts["check-types"] = pmConfig.checkTypes;
55
+ scripts["dev:native"] = pmConfig.filter("native", "dev");
56
+ scripts["dev:web"] = pmConfig.filter("web", "dev");
57
+
58
+ if (backend !== "self" && backend !== "none") {
59
+ scripts["dev:server"] = pmConfig.filter(backendPackageName, "dev");
60
+ }
61
+
62
+ if (backend === "convex") {
63
+ scripts["dev:setup"] = pmConfig.filter(backendPackageName, "dev:setup");
64
+ }
65
+
66
+ if (needsDbScripts) {
67
+ scripts["db:push"] = pmConfig.filter(dbPackageName, "db:push");
68
+
69
+ if (!isD1Alchemy) {
70
+ scripts["db:studio"] = pmConfig.filter(dbPackageName, "db:studio");
71
+ }
72
+
73
+ if (orm === "prisma") {
74
+ scripts["db:generate"] = pmConfig.filter(dbPackageName, "db:generate");
75
+ scripts["db:migrate"] = pmConfig.filter(dbPackageName, "db:migrate");
76
+ } else if (orm === "drizzle") {
77
+ scripts["db:generate"] = pmConfig.filter(dbPackageName, "db:generate");
78
+ if (!isD1Alchemy) {
79
+ scripts["db:migrate"] = pmConfig.filter(dbPackageName, "db:migrate");
80
+ }
81
+ }
82
+ }
83
+
84
+ if (dbSetup === "docker") {
85
+ scripts["db:start"] = pmConfig.filter(dbPackageName, "db:start");
86
+ scripts["db:watch"] = pmConfig.filter(dbPackageName, "db:watch");
87
+ scripts["db:stop"] = pmConfig.filter(dbPackageName, "db:stop");
88
+ scripts["db:down"] = pmConfig.filter(dbPackageName, "db:down");
89
+ }
90
+
91
+ try {
92
+ const { stdout } = await execa(packageManager, ["-v"], { cwd: projectDir });
93
+ packageJson.packageManager = `${packageManager}@${stdout.trim()}`;
94
+ } catch {
95
+ log.warn(`Could not determine ${packageManager} version.`);
96
+ }
97
+
98
+ if (backend === "convex") {
99
+ if (!workspaces.includes("packages/*")) {
100
+ workspaces.push("packages/*");
101
+ }
102
+ const needsAppsDir = options.frontend.length > 0 || addons.includes("starlight");
103
+ if (needsAppsDir && !workspaces.includes("apps/*")) {
104
+ workspaces.push("apps/*");
105
+ }
106
+ } else {
107
+ if (!workspaces.includes("apps/*")) {
108
+ workspaces.push("apps/*");
109
+ }
110
+ if (!workspaces.includes("packages/*")) {
111
+ workspaces.push("packages/*");
112
+ }
113
+ }
114
+
115
+ await fs.writeJson(rootPackageJsonPath, packageJson, { spaces: 2 });
116
+ }
117
+
118
+ type PackageManagerConfig = {
119
+ dev: string;
120
+ build: string;
121
+ checkTypes: string;
122
+ filter: (workspace: string, script: string) => string;
123
+ };
124
+
125
+ function getPackageManagerConfig(
126
+ packageManager: ProjectConfig["packageManager"],
127
+ hasTurborepo: boolean,
128
+ ): PackageManagerConfig {
129
+ if (hasTurborepo) {
130
+ return {
131
+ dev: "turbo dev",
132
+ build: "turbo build",
133
+ checkTypes: "turbo check-types",
134
+ filter: (workspace, script) => `turbo -F ${workspace} ${script}`,
135
+ };
136
+ }
137
+
138
+ switch (packageManager) {
139
+ case "pnpm":
140
+ return {
141
+ dev: "pnpm -r dev",
142
+ build: "pnpm -r build",
143
+ checkTypes: "pnpm -r check-types",
144
+ filter: (workspace, script) => `pnpm --filter ${workspace} ${script}`,
145
+ };
146
+ case "npm":
147
+ return {
148
+ dev: "npm run dev --workspaces",
149
+ build: "npm run build --workspaces",
150
+ checkTypes: "npm run check-types --workspaces",
151
+ filter: (workspace, script) => `npm run ${script} --workspace ${workspace}`,
152
+ };
153
+ case "bun":
154
+ return {
155
+ dev: "bun run --filter '*' dev",
156
+ build: "bun run --filter '*' build",
157
+ checkTypes: "bun run --filter '*' check-types",
158
+ filter: (workspace, script) => `bun run --filter ${workspace} ${script}`,
159
+ };
160
+ }
161
+ }
162
+
163
+ async function updateServerPackageJson(projectDir: string, _options: ProjectConfig) {
164
+ const serverPackageJsonPath = path.join(projectDir, "apps/server/package.json");
165
+ if (!(await fs.pathExists(serverPackageJsonPath))) return;
166
+
167
+ const serverPackageJson = await fs.readJson(serverPackageJsonPath);
168
+ serverPackageJson.scripts = serverPackageJson.scripts || {};
169
+
170
+ await fs.writeJson(serverPackageJsonPath, serverPackageJson, { spaces: 2 });
171
+ }
172
+
173
+ async function updateDbPackageJson(projectDir: string, options: ProjectConfig) {
174
+ const dbPackageJsonPath = path.join(projectDir, "packages/db/package.json");
175
+ if (!(await fs.pathExists(dbPackageJsonPath))) return;
176
+
177
+ const dbPackageJson = await fs.readJson(dbPackageJsonPath);
178
+ dbPackageJson.name = `@${options.projectName}/db`;
179
+ dbPackageJson.scripts = dbPackageJson.scripts || {};
180
+
181
+ const scripts = dbPackageJson.scripts;
182
+ const { database, orm, dbSetup, serverDeploy } = options;
183
+ const isD1Alchemy = dbSetup === "d1" && serverDeploy === "alchemy";
184
+
185
+ if (database !== "none") {
186
+ if (database === "sqlite" && orm === "drizzle" && dbSetup !== "d1") {
187
+ scripts["db:local"] = "turso dev --db-file local.db";
188
+ }
189
+
190
+ if (orm === "prisma") {
191
+ scripts["db:push"] = "prisma db push";
192
+ scripts["db:generate"] = "prisma generate";
193
+ scripts["db:migrate"] = "prisma migrate dev";
194
+ if (!isD1Alchemy) {
195
+ scripts["db:studio"] = "prisma studio";
196
+ }
197
+ } else if (orm === "drizzle") {
198
+ scripts["db:push"] = "drizzle-kit push";
199
+ scripts["db:generate"] = "drizzle-kit generate";
200
+ if (!isD1Alchemy) {
201
+ scripts["db:studio"] = "drizzle-kit studio";
202
+ scripts["db:migrate"] = "drizzle-kit migrate";
203
+ }
204
+ }
205
+ }
206
+
207
+ if (dbSetup === "docker") {
208
+ scripts["db:start"] = "docker compose up -d";
209
+ scripts["db:watch"] = "docker compose up";
210
+ scripts["db:stop"] = "docker compose stop";
211
+ scripts["db:down"] = "docker compose down";
212
+ }
213
+
214
+ await fs.writeJson(dbPackageJsonPath, dbPackageJson, { spaces: 2 });
215
+ }
216
+
217
+ async function updateAuthPackageJson(projectDir: string, options: ProjectConfig) {
218
+ const authPackageJsonPath = path.join(projectDir, "packages/auth/package.json");
219
+ if (!(await fs.pathExists(authPackageJsonPath))) return;
220
+
221
+ const authPackageJson = await fs.readJson(authPackageJsonPath);
222
+ authPackageJson.name = `@${options.projectName}/auth`;
223
+
224
+ await fs.writeJson(authPackageJsonPath, authPackageJson, { spaces: 2 });
225
+ }
226
+
227
+ async function updateApiPackageJson(projectDir: string, options: ProjectConfig) {
228
+ const apiPackageJsonPath = path.join(projectDir, "packages/api/package.json");
229
+ if (!(await fs.pathExists(apiPackageJsonPath))) return;
230
+
231
+ const apiPackageJson = await fs.readJson(apiPackageJsonPath);
232
+ apiPackageJson.name = `@${options.projectName}/api`;
233
+
234
+ await fs.writeJson(apiPackageJsonPath, apiPackageJson, { spaces: 2 });
235
+ }
236
+
237
+ async function updateConvexPackageJson(projectDir: string, options: ProjectConfig) {
238
+ const convexPackageJsonPath = path.join(projectDir, "packages/backend/package.json");
239
+ if (!(await fs.pathExists(convexPackageJsonPath))) return;
240
+
241
+ const convexPackageJson = await fs.readJson(convexPackageJsonPath);
242
+ convexPackageJson.name = `@${options.projectName}/backend`;
243
+ convexPackageJson.scripts = convexPackageJson.scripts || {};
244
+
245
+ await fs.writeJson(convexPackageJsonPath, convexPackageJson, { spaces: 2 });
246
+ }
@@ -0,0 +1,76 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import type { Backend, ProjectConfig } from "../../types";
4
+ import { addPackageDependency } from "../../utils/add-package-deps";
5
+
6
+ export async function setupRuntime(config: ProjectConfig) {
7
+ const { runtime, backend, projectDir } = config;
8
+
9
+ if (backend === "convex" || backend === "self" || runtime === "none") {
10
+ return;
11
+ }
12
+
13
+ const serverDir = path.join(projectDir, "apps/server");
14
+
15
+ if (!(await fs.pathExists(serverDir))) {
16
+ return;
17
+ }
18
+
19
+ if (runtime === "bun") {
20
+ await setupBunRuntime(serverDir, backend);
21
+ } else if (runtime === "node") {
22
+ await setupNodeRuntime(serverDir, backend);
23
+ }
24
+ }
25
+
26
+ async function setupBunRuntime(serverDir: string, _backend: Backend) {
27
+ const packageJsonPath = path.join(serverDir, "package.json");
28
+ if (!(await fs.pathExists(packageJsonPath))) return;
29
+
30
+ const packageJson = await fs.readJson(packageJsonPath);
31
+
32
+ packageJson.scripts = {
33
+ ...packageJson.scripts,
34
+ dev: "bun run --hot src/index.ts",
35
+ start: "bun run dist/index.js",
36
+ };
37
+
38
+ await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
39
+
40
+ await addPackageDependency({
41
+ devDependencies: ["@types/bun"],
42
+ projectDir: serverDir,
43
+ });
44
+ }
45
+
46
+ async function setupNodeRuntime(serverDir: string, backend: Backend) {
47
+ const packageJsonPath = path.join(serverDir, "package.json");
48
+ if (!(await fs.pathExists(packageJsonPath))) return;
49
+
50
+ const packageJson = await fs.readJson(packageJsonPath);
51
+
52
+ packageJson.scripts = {
53
+ ...packageJson.scripts,
54
+ dev: "tsx watch src/index.ts",
55
+ start: "node dist/index.js",
56
+ };
57
+
58
+ await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
59
+
60
+ await addPackageDependency({
61
+ devDependencies: ["tsx", "@types/node"],
62
+ projectDir: serverDir,
63
+ });
64
+
65
+ if (backend === "hono") {
66
+ await addPackageDependency({
67
+ dependencies: ["@hono/node-server"],
68
+ projectDir: serverDir,
69
+ });
70
+ } else if (backend === "elysia") {
71
+ await addPackageDependency({
72
+ dependencies: ["@elysiajs/node"],
73
+ projectDir: serverDir,
74
+ });
75
+ }
76
+ }