create-better-t-stack 3.7.3-canary.8e4d5716 → 3.7.3-canary.98ba1e7a

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/dist/cli.d.ts +1 -0
  2. package/dist/cli.js +8 -0
  3. package/dist/index.d.ts +347 -0
  4. package/dist/index.js +4 -0
  5. package/dist/src-yXf02Wox.js +7077 -0
  6. package/package.json +11 -7
  7. package/src/cli.ts +0 -3
  8. package/src/constants.ts +0 -188
  9. package/src/helpers/addons/addons-setup.ts +0 -226
  10. package/src/helpers/addons/examples-setup.ts +0 -104
  11. package/src/helpers/addons/fumadocs-setup.ts +0 -103
  12. package/src/helpers/addons/ruler-setup.ts +0 -139
  13. package/src/helpers/addons/starlight-setup.ts +0 -51
  14. package/src/helpers/addons/tauri-setup.ts +0 -96
  15. package/src/helpers/addons/ultracite-setup.ts +0 -232
  16. package/src/helpers/addons/vite-pwa-setup.ts +0 -59
  17. package/src/helpers/core/add-addons.ts +0 -85
  18. package/src/helpers/core/add-deployment.ts +0 -102
  19. package/src/helpers/core/api-setup.ts +0 -280
  20. package/src/helpers/core/auth-setup.ts +0 -203
  21. package/src/helpers/core/backend-setup.ts +0 -73
  22. package/src/helpers/core/command-handlers.ts +0 -354
  23. package/src/helpers/core/convex-codegen.ts +0 -14
  24. package/src/helpers/core/create-project.ts +0 -133
  25. package/src/helpers/core/create-readme.ts +0 -687
  26. package/src/helpers/core/db-setup.ts +0 -184
  27. package/src/helpers/core/detect-project-config.ts +0 -41
  28. package/src/helpers/core/env-setup.ts +0 -449
  29. package/src/helpers/core/git.ts +0 -31
  30. package/src/helpers/core/install-dependencies.ts +0 -32
  31. package/src/helpers/core/payments-setup.ts +0 -48
  32. package/src/helpers/core/post-installation.ts +0 -383
  33. package/src/helpers/core/project-config.ts +0 -246
  34. package/src/helpers/core/runtime-setup.ts +0 -76
  35. package/src/helpers/core/template-manager.ts +0 -917
  36. package/src/helpers/core/workspace-setup.ts +0 -184
  37. package/src/helpers/database-providers/d1-setup.ts +0 -28
  38. package/src/helpers/database-providers/docker-compose-setup.ts +0 -50
  39. package/src/helpers/database-providers/mongodb-atlas-setup.ts +0 -186
  40. package/src/helpers/database-providers/neon-setup.ts +0 -243
  41. package/src/helpers/database-providers/planetscale-setup.ts +0 -78
  42. package/src/helpers/database-providers/prisma-postgres-setup.ts +0 -196
  43. package/src/helpers/database-providers/supabase-setup.ts +0 -218
  44. package/src/helpers/database-providers/turso-setup.ts +0 -309
  45. package/src/helpers/deployment/alchemy/alchemy-combined-setup.ts +0 -80
  46. package/src/helpers/deployment/alchemy/alchemy-next-setup.ts +0 -51
  47. package/src/helpers/deployment/alchemy/alchemy-nuxt-setup.ts +0 -104
  48. package/src/helpers/deployment/alchemy/alchemy-react-router-setup.ts +0 -32
  49. package/src/helpers/deployment/alchemy/alchemy-solid-setup.ts +0 -32
  50. package/src/helpers/deployment/alchemy/alchemy-svelte-setup.ts +0 -98
  51. package/src/helpers/deployment/alchemy/alchemy-tanstack-router-setup.ts +0 -33
  52. package/src/helpers/deployment/alchemy/alchemy-tanstack-start-setup.ts +0 -98
  53. package/src/helpers/deployment/alchemy/env-dts-setup.ts +0 -76
  54. package/src/helpers/deployment/alchemy/index.ts +0 -7
  55. package/src/helpers/deployment/server-deploy-setup.ts +0 -55
  56. package/src/helpers/deployment/web-deploy-setup.ts +0 -58
  57. package/src/index.ts +0 -253
  58. package/src/prompts/addons.ts +0 -178
  59. package/src/prompts/api.ts +0 -49
  60. package/src/prompts/auth.ts +0 -84
  61. package/src/prompts/backend.ts +0 -83
  62. package/src/prompts/config-prompts.ts +0 -138
  63. package/src/prompts/database-setup.ts +0 -112
  64. package/src/prompts/database.ts +0 -57
  65. package/src/prompts/examples.ts +0 -64
  66. package/src/prompts/frontend.ts +0 -118
  67. package/src/prompts/git.ts +0 -16
  68. package/src/prompts/install.ts +0 -16
  69. package/src/prompts/orm.ts +0 -53
  70. package/src/prompts/package-manager.ts +0 -32
  71. package/src/prompts/payments.ts +0 -50
  72. package/src/prompts/project-name.ts +0 -86
  73. package/src/prompts/runtime.ts +0 -47
  74. package/src/prompts/server-deploy.ts +0 -91
  75. package/src/prompts/web-deploy.ts +0 -107
  76. package/src/types.ts +0 -2
  77. package/src/utils/add-package-deps.ts +0 -57
  78. package/src/utils/analytics.ts +0 -39
  79. package/src/utils/better-auth-plugin-setup.ts +0 -71
  80. package/src/utils/biome-formatter.ts +0 -82
  81. package/src/utils/bts-config.ts +0 -122
  82. package/src/utils/command-exists.ts +0 -16
  83. package/src/utils/compatibility-rules.ts +0 -319
  84. package/src/utils/compatibility.ts +0 -11
  85. package/src/utils/config-processing.ts +0 -130
  86. package/src/utils/config-validation.ts +0 -470
  87. package/src/utils/display-config.ts +0 -96
  88. package/src/utils/docker-utils.ts +0 -70
  89. package/src/utils/errors.ts +0 -32
  90. package/src/utils/generate-reproducible-command.ts +0 -53
  91. package/src/utils/get-latest-cli-version.ts +0 -11
  92. package/src/utils/get-package-manager.ts +0 -13
  93. package/src/utils/open-url.ts +0 -25
  94. package/src/utils/package-runner.ts +0 -23
  95. package/src/utils/project-directory.ts +0 -102
  96. package/src/utils/project-name-validation.ts +0 -43
  97. package/src/utils/render-title.ts +0 -48
  98. package/src/utils/setup-catalogs.ts +0 -192
  99. package/src/utils/sponsors.ts +0 -101
  100. package/src/utils/telemetry.ts +0 -19
  101. package/src/utils/template-processor.ts +0 -64
  102. package/src/utils/templates.ts +0 -94
  103. package/src/utils/ts-morph.ts +0 -26
  104. package/src/validation.ts +0 -117
@@ -1,319 +0,0 @@
1
- import { ADDON_COMPATIBILITY } from "../constants";
2
- import type {
3
- Addons,
4
- API,
5
- Auth,
6
- Backend,
7
- CLIInput,
8
- Frontend,
9
- Payments,
10
- ProjectConfig,
11
- ServerDeploy,
12
- WebDeploy,
13
- } from "../types";
14
- import { WEB_FRAMEWORKS } from "./compatibility";
15
- import { exitWithError } from "./errors";
16
-
17
- export function isWebFrontend(value: Frontend) {
18
- return WEB_FRAMEWORKS.includes(value);
19
- }
20
-
21
- export function splitFrontends(values: Frontend[] = []): {
22
- web: Frontend[];
23
- native: Frontend[];
24
- } {
25
- const web = values.filter((f) => isWebFrontend(f));
26
- const native = values.filter(
27
- (f) => f === "native-bare" || f === "native-uniwind" || f === "native-unistyles",
28
- );
29
- return { web, native };
30
- }
31
-
32
- export function ensureSingleWebAndNative(frontends: Frontend[]) {
33
- const { web, native } = splitFrontends(frontends);
34
- if (web.length > 1) {
35
- exitWithError(
36
- "Cannot select multiple web frameworks. Choose only one of: tanstack-router, tanstack-start, react-router, next, nuxt, svelte, solid",
37
- );
38
- }
39
- if (native.length > 1) {
40
- exitWithError(
41
- "Cannot select multiple native frameworks. Choose only one of: native-bare, native-uniwind, native-unistyles",
42
- );
43
- }
44
- }
45
-
46
- // Temporarily restrict to Next.js and TanStack Start only for backend="self"
47
- const FULLSTACK_FRONTENDS: readonly Frontend[] = [
48
- "next",
49
- "tanstack-start",
50
- // "nuxt", // TODO: Add support in future update
51
- // "svelte", // TODO: Add support in future update
52
- ] as const;
53
-
54
- export function validateSelfBackendCompatibility(
55
- providedFlags: Set<string>,
56
- options: CLIInput,
57
- config: Partial<ProjectConfig>,
58
- ) {
59
- const backend = config.backend || options.backend;
60
- const frontends = config.frontend || options.frontend || [];
61
-
62
- if (backend === "self") {
63
- const { web, native } = splitFrontends(frontends);
64
- const hasSupportedWeb = web.length === 1 && FULLSTACK_FRONTENDS.includes(web[0]);
65
-
66
- if (!hasSupportedWeb) {
67
- exitWithError(
68
- "Backend 'self' (fullstack) currently only supports Next.js and TanStack Start frontends. Please use --frontend next or --frontend tanstack-start. Support for Nuxt and SvelteKit will be added in a future update.",
69
- );
70
- }
71
-
72
- if (native.length > 1) {
73
- exitWithError(
74
- "Cannot select multiple native frameworks. Choose only one of: native-bare, native-uniwind, native-unistyles",
75
- );
76
- }
77
- }
78
-
79
- const hasFullstackFrontend = frontends.some((f) => FULLSTACK_FRONTENDS.includes(f));
80
- if (providedFlags.has("backend") && !hasFullstackFrontend && backend === "self") {
81
- exitWithError(
82
- "Backend 'self' (fullstack) currently only supports Next.js and TanStack Start frontends. Please use --frontend next or --frontend tanstack-start or choose a different backend. Support for Nuxt and SvelteKit will be added in a future update.",
83
- );
84
- }
85
- }
86
-
87
- export function validateWorkersCompatibility(
88
- providedFlags: Set<string>,
89
- options: CLIInput,
90
- config: Partial<ProjectConfig>,
91
- ) {
92
- if (
93
- providedFlags.has("runtime") &&
94
- options.runtime === "workers" &&
95
- config.backend &&
96
- config.backend !== "hono"
97
- ) {
98
- exitWithError(
99
- `Cloudflare Workers runtime (--runtime workers) is only supported with Hono backend (--backend hono). Current backend: ${config.backend}. Please use '--backend hono' or choose a different runtime.`,
100
- );
101
- }
102
-
103
- if (
104
- providedFlags.has("backend") &&
105
- config.backend &&
106
- config.backend !== "hono" &&
107
- config.runtime === "workers"
108
- ) {
109
- exitWithError(
110
- `Backend '${config.backend}' is not compatible with Cloudflare Workers runtime. Cloudflare Workers runtime is only supported with Hono backend. Please use '--backend hono' or choose a different runtime.`,
111
- );
112
- }
113
-
114
- if (
115
- providedFlags.has("runtime") &&
116
- options.runtime === "workers" &&
117
- config.database === "mongodb"
118
- ) {
119
- exitWithError(
120
- "Cloudflare Workers runtime (--runtime workers) is not compatible with MongoDB database. MongoDB requires Prisma or Mongoose ORM, but Workers runtime only supports Drizzle or Prisma ORM. Please use a different database or runtime.",
121
- );
122
- }
123
-
124
- if (
125
- providedFlags.has("runtime") &&
126
- options.runtime === "workers" &&
127
- config.dbSetup === "docker"
128
- ) {
129
- exitWithError(
130
- "Cloudflare Workers runtime (--runtime workers) is not compatible with Docker setup. Workers runtime uses serverless databases (D1) and doesn't support local Docker containers. Please use '--db-setup d1' for SQLite or choose a different runtime.",
131
- );
132
- }
133
-
134
- if (
135
- providedFlags.has("database") &&
136
- config.database === "mongodb" &&
137
- config.runtime === "workers"
138
- ) {
139
- exitWithError(
140
- "MongoDB database is not compatible with Cloudflare Workers runtime. MongoDB requires Prisma or Mongoose ORM, but Workers runtime only supports Drizzle or Prisma ORM. Please use a different database or runtime.",
141
- );
142
- }
143
- }
144
-
145
- export function validateApiFrontendCompatibility(api: API | undefined, frontends: Frontend[] = []) {
146
- const includesNuxt = frontends.includes("nuxt");
147
- const includesSvelte = frontends.includes("svelte");
148
- const includesSolid = frontends.includes("solid");
149
- if ((includesNuxt || includesSvelte || includesSolid) && api === "trpc") {
150
- exitWithError(
151
- `tRPC API is not supported with '${includesNuxt ? "nuxt" : includesSvelte ? "svelte" : "solid"}' frontend. Please use --api orpc or --api none or remove '${includesNuxt ? "nuxt" : includesSvelte ? "svelte" : "solid"}' from --frontend.`,
152
- );
153
- }
154
- }
155
-
156
- export function isFrontendAllowedWithBackend(
157
- frontend: Frontend,
158
- backend?: ProjectConfig["backend"],
159
- auth?: string,
160
- ) {
161
- if (backend === "convex" && frontend === "solid") return false;
162
-
163
- if (auth === "clerk" && backend === "convex") {
164
- const incompatibleFrontends = ["nuxt", "svelte", "solid"];
165
- if (incompatibleFrontends.includes(frontend)) return false;
166
- }
167
-
168
- return true;
169
- }
170
-
171
- export function allowedApisForFrontends(frontends: Frontend[] = []) {
172
- const includesNuxt = frontends.includes("nuxt");
173
- const includesSvelte = frontends.includes("svelte");
174
- const includesSolid = frontends.includes("solid");
175
- const base: API[] = ["trpc", "orpc", "none"];
176
- if (includesNuxt || includesSvelte || includesSolid) {
177
- return ["orpc", "none"];
178
- }
179
- return base;
180
- }
181
-
182
- export function isExampleTodoAllowed(
183
- backend?: ProjectConfig["backend"],
184
- database?: ProjectConfig["database"],
185
- ) {
186
- return !(backend !== "convex" && backend !== "none" && database === "none");
187
- }
188
-
189
- export function isExampleAIAllowed(
190
- _backend?: ProjectConfig["backend"],
191
- frontends: Frontend[] = [],
192
- ) {
193
- const includesSolid = frontends.includes("solid");
194
- if (includesSolid) return false;
195
- return true;
196
- }
197
-
198
- export function validateWebDeployRequiresWebFrontend(
199
- webDeploy: WebDeploy | undefined,
200
- hasWebFrontendFlag: boolean,
201
- ) {
202
- if (webDeploy && webDeploy !== "none" && !hasWebFrontendFlag) {
203
- exitWithError(
204
- "'--web-deploy' requires a web frontend. Please select a web frontend or set '--web-deploy none'.",
205
- );
206
- }
207
- }
208
-
209
- export function validateServerDeployRequiresBackend(
210
- serverDeploy: ServerDeploy | undefined,
211
- backend: Backend | undefined,
212
- ) {
213
- if (serverDeploy && serverDeploy !== "none" && (!backend || backend === "none")) {
214
- exitWithError(
215
- "'--server-deploy' requires a backend. Please select a backend or set '--server-deploy none'.",
216
- );
217
- }
218
- }
219
-
220
- export function validateAddonCompatibility(
221
- addon: Addons,
222
- frontend: Frontend[],
223
- _auth?: Auth,
224
- ): { isCompatible: boolean; reason?: string } {
225
- const compatibleFrontends = ADDON_COMPATIBILITY[addon];
226
-
227
- if (compatibleFrontends.length > 0) {
228
- const hasCompatibleFrontend = frontend.some((f) =>
229
- (compatibleFrontends as readonly string[]).includes(f),
230
- );
231
-
232
- if (!hasCompatibleFrontend) {
233
- const frontendList = compatibleFrontends.join(", ");
234
- return {
235
- isCompatible: false,
236
- reason: `${addon} addon requires one of these frontends: ${frontendList}`,
237
- };
238
- }
239
- }
240
-
241
- return { isCompatible: true };
242
- }
243
-
244
- export function getCompatibleAddons(
245
- allAddons: Addons[],
246
- frontend: Frontend[],
247
- existingAddons: Addons[] = [],
248
- auth?: Auth,
249
- ) {
250
- return allAddons.filter((addon) => {
251
- if (existingAddons.includes(addon)) return false;
252
-
253
- if (addon === "none") return false;
254
-
255
- const { isCompatible } = validateAddonCompatibility(addon, frontend, auth);
256
- return isCompatible;
257
- });
258
- }
259
-
260
- export function validateAddonsAgainstFrontends(
261
- addons: Addons[] = [],
262
- frontends: Frontend[] = [],
263
- auth?: Auth,
264
- ) {
265
- for (const addon of addons) {
266
- if (addon === "none") continue;
267
- const { isCompatible, reason } = validateAddonCompatibility(addon, frontends, auth);
268
- if (!isCompatible) {
269
- exitWithError(`Incompatible addon/frontend combination: ${reason}`);
270
- }
271
- }
272
- }
273
-
274
- export function validatePaymentsCompatibility(
275
- payments: Payments | undefined,
276
- auth: Auth | undefined,
277
- _backend: Backend | undefined,
278
- frontends: Frontend[] = [],
279
- ) {
280
- if (!payments || payments === "none") return;
281
-
282
- if (payments === "polar") {
283
- if (!auth || auth === "none" || auth !== "better-auth") {
284
- exitWithError(
285
- "Polar payments requires Better Auth. Please use '--auth better-auth' or choose a different payments provider.",
286
- );
287
- }
288
-
289
- const { web } = splitFrontends(frontends);
290
- if (web.length === 0 && frontends.length > 0) {
291
- exitWithError(
292
- "Polar payments requires a web frontend or no frontend. Please select a web frontend or choose a different payments provider.",
293
- );
294
- }
295
- }
296
- }
297
-
298
- export function validateExamplesCompatibility(
299
- examples: string[] | undefined,
300
- backend: ProjectConfig["backend"] | undefined,
301
- database: ProjectConfig["database"] | undefined,
302
- frontend?: Frontend[],
303
- ) {
304
- const examplesArr = examples ?? [];
305
- if (examplesArr.length === 0 || examplesArr.includes("none")) return;
306
- if (
307
- examplesArr.includes("todo") &&
308
- backend !== "convex" &&
309
- backend !== "none" &&
310
- database === "none"
311
- ) {
312
- exitWithError(
313
- "The 'todo' example requires a database if a backend (other than Convex) is present. Cannot use --examples todo when database is 'none' and a backend is selected.",
314
- );
315
- }
316
- if (examplesArr.includes("ai") && (frontend ?? []).includes("solid")) {
317
- exitWithError("The 'ai' example is not compatible with the Solid frontend.");
318
- }
319
- }
@@ -1,11 +0,0 @@
1
- import type { Frontend } from "../types";
2
-
3
- export const WEB_FRAMEWORKS: readonly Frontend[] = [
4
- "tanstack-router",
5
- "react-router",
6
- "tanstack-start",
7
- "next",
8
- "nuxt",
9
- "svelte",
10
- "solid",
11
- ] as const;
@@ -1,130 +0,0 @@
1
- import path from "node:path";
2
- import type {
3
- API,
4
- Auth,
5
- Backend,
6
- CLIInput,
7
- Database,
8
- DatabaseSetup,
9
- ORM,
10
- PackageManager,
11
- Payments,
12
- ProjectConfig,
13
- Runtime,
14
- ServerDeploy,
15
- WebDeploy,
16
- } from "../types";
17
-
18
- export function processArrayOption<T>(options: (T | "none")[] | undefined) {
19
- if (!options || options.length === 0) return [];
20
- if (options.includes("none" as T | "none")) return [];
21
- return options.filter((item): item is T => item !== "none");
22
- }
23
-
24
- export function deriveProjectName(projectName?: string, projectDirectory?: string) {
25
- if (projectName) {
26
- return projectName;
27
- }
28
- if (projectDirectory) {
29
- return path.basename(path.resolve(process.cwd(), projectDirectory));
30
- }
31
- return "";
32
- }
33
-
34
- export function processFlags(options: CLIInput, projectName?: string) {
35
- const config: Partial<ProjectConfig> = {};
36
-
37
- if (options.api) {
38
- config.api = options.api as API;
39
- }
40
-
41
- if (options.backend) {
42
- config.backend = options.backend as Backend;
43
- }
44
-
45
- if (options.database) {
46
- config.database = options.database as Database;
47
- }
48
-
49
- if (options.orm) {
50
- config.orm = options.orm as ORM;
51
- }
52
-
53
- if (options.auth !== undefined) {
54
- config.auth = options.auth as Auth;
55
- }
56
-
57
- if (options.payments !== undefined) {
58
- config.payments = options.payments as Payments;
59
- }
60
-
61
- if (options.git !== undefined) {
62
- config.git = options.git;
63
- }
64
-
65
- if (options.install !== undefined) {
66
- config.install = options.install;
67
- }
68
-
69
- if (options.runtime) {
70
- config.runtime = options.runtime as Runtime;
71
- }
72
-
73
- if (options.dbSetup) {
74
- config.dbSetup = options.dbSetup as DatabaseSetup;
75
- }
76
-
77
- if (options.packageManager) {
78
- config.packageManager = options.packageManager as PackageManager;
79
- }
80
-
81
- if (options.webDeploy) {
82
- config.webDeploy = options.webDeploy as WebDeploy;
83
- }
84
-
85
- if (options.serverDeploy) {
86
- config.serverDeploy = options.serverDeploy as ServerDeploy;
87
- }
88
-
89
- const derivedName = deriveProjectName(projectName, options.projectDirectory);
90
- if (derivedName) {
91
- config.projectName = projectName || derivedName;
92
- }
93
-
94
- if (options.frontend && options.frontend.length > 0) {
95
- config.frontend = processArrayOption(options.frontend);
96
- }
97
-
98
- if (options.addons && options.addons.length > 0) {
99
- config.addons = processArrayOption(options.addons);
100
- }
101
-
102
- if (options.examples && options.examples.length > 0) {
103
- config.examples = processArrayOption(options.examples);
104
- }
105
-
106
- return config;
107
- }
108
-
109
- export function getProvidedFlags(options: CLIInput) {
110
- return new Set(
111
- Object.keys(options).filter((key) => options[key as keyof CLIInput] !== undefined),
112
- );
113
- }
114
-
115
- export function validateNoneExclusivity<T>(
116
- options: (T | "none")[] | undefined,
117
- optionName: string,
118
- ) {
119
- if (!options || options.length === 0) return;
120
-
121
- if (options.includes("none" as T | "none") && options.length > 1) {
122
- throw new Error(`Cannot combine 'none' with other ${optionName}.`);
123
- }
124
- }
125
-
126
- export function validateArrayOptions(options: CLIInput) {
127
- validateNoneExclusivity(options.frontend, "frontend options");
128
- validateNoneExclusivity(options.addons, "addons");
129
- validateNoneExclusivity(options.examples, "examples");
130
- }